mirror of
https://github.com/containers/skopeo.git
synced 2025-06-28 15:47:34 +00:00
commit
696eb74918
57
docker.go
57
docker.go
@ -31,9 +31,9 @@ const (
|
|||||||
dockerCfgObsolete = ".dockercfg"
|
dockerCfgObsolete = ".dockercfg"
|
||||||
|
|
||||||
baseURL = "%s://%s/v2/"
|
baseURL = "%s://%s/v2/"
|
||||||
tagsURL = baseURL + "%s/tags/list"
|
tagsURL = "%s/tags/list"
|
||||||
manifestURL = baseURL + "%s/manifests/%s"
|
manifestURL = "%s/manifests/%s"
|
||||||
blobsURL = baseURL + "%s/blobs/%s"
|
blobsURL = "%s/blobs/%s"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -86,8 +86,8 @@ func (i *dockerImage) Manifest() (types.ImageManifest, error) {
|
|||||||
|
|
||||||
func (i *dockerImage) getTags() ([]string, error) {
|
func (i *dockerImage) getTags() ([]string, error) {
|
||||||
// FIXME? Breaking the abstraction.
|
// FIXME? Breaking the abstraction.
|
||||||
url := fmt.Sprintf(tagsURL, i.src.scheme, i.src.registry, i.src.ref.RemoteName())
|
url := fmt.Sprintf(tagsURL, i.src.ref.RemoteName())
|
||||||
res, err := i.src.makeRequest("GET", url, i.src.WWWAuthenticate != "", nil)
|
res, err := i.src.makeRequest("GET", url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -188,22 +188,16 @@ type dockerImageSource struct {
|
|||||||
registry string
|
registry string
|
||||||
username string
|
username string
|
||||||
password string
|
password string
|
||||||
WWWAuthenticate string // Obtained by s.ping()
|
wwwAuthenticate string // Cache of a value set by ping() if scheme is not empty
|
||||||
scheme string // Obtained by s.ping()
|
scheme string // Cache of a value returned by a successful ping() if not empty
|
||||||
transport *http.Transport
|
transport *http.Transport
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *dockerImageSource) GetManifest() (manifest []byte, unverifiedCanonicalDigest string, err error) {
|
func (s *dockerImageSource) GetManifest() (manifest []byte, unverifiedCanonicalDigest string, err error) {
|
||||||
pr, err := s.ping()
|
url := fmt.Sprintf(manifestURL, s.ref.RemoteName(), s.tag)
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
s.WWWAuthenticate = pr.WWWAuthenticate
|
|
||||||
s.scheme = pr.scheme
|
|
||||||
url := fmt.Sprintf(manifestURL, s.scheme, s.registry, s.ref.RemoteName(), s.tag)
|
|
||||||
// TODO(runcom) set manifest version header! schema1 for now - then schema2 etc etc and v1
|
// TODO(runcom) set manifest version header! schema1 for now - then schema2 etc etc and v1
|
||||||
// TODO(runcom) NO, switch on the resulter manifest like Docker is doing
|
// TODO(runcom) NO, switch on the resulter manifest like Docker is doing
|
||||||
res, err := s.makeRequest("GET", url, pr.needsAuth(), nil)
|
res, err := s.makeRequest("GET", url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
@ -219,9 +213,9 @@ func (s *dockerImageSource) GetManifest() (manifest []byte, unverifiedCanonicalD
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *dockerImageSource) GetLayer(digest string) (io.ReadCloser, error) {
|
func (s *dockerImageSource) GetLayer(digest string) (io.ReadCloser, error) {
|
||||||
url := fmt.Sprintf(blobsURL, s.scheme, s.registry, s.ref.RemoteName(), digest)
|
url := fmt.Sprintf(blobsURL, s.ref.RemoteName(), digest)
|
||||||
logrus.Infof("Downloading %s", url)
|
logrus.Infof("Downloading %s", url)
|
||||||
res, err := s.makeRequest("GET", url, s.WWWAuthenticate != "", nil)
|
res, err := s.makeRequest("GET", url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -236,8 +230,18 @@ func (s *dockerImageSource) GetSignatures() ([][]byte, error) {
|
|||||||
return [][]byte{}, nil
|
return [][]byte{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *dockerImageSource) makeRequest(method, url string, auth bool, headers map[string]string) (*http.Response, error) {
|
func (s *dockerImageSource) makeRequest(method, url string, headers map[string]string) (*http.Response, error) {
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
if s.scheme == "" {
|
||||||
|
pr, err := s.ping()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.wwwAuthenticate = pr.WWWAuthenticate
|
||||||
|
s.scheme = pr.scheme
|
||||||
|
}
|
||||||
|
|
||||||
|
url = fmt.Sprintf(baseURL, s.scheme, s.registry) + url
|
||||||
|
req, err := http.NewRequest(method, url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -245,7 +249,7 @@ func (s *dockerImageSource) makeRequest(method, url string, auth bool, headers m
|
|||||||
for n, h := range headers {
|
for n, h := range headers {
|
||||||
req.Header.Add(n, h)
|
req.Header.Add(n, h)
|
||||||
}
|
}
|
||||||
if auth {
|
if s.wwwAuthenticate != "" {
|
||||||
if err := s.setupRequestAuth(req); err != nil {
|
if err := s.setupRequestAuth(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -262,9 +266,9 @@ func (s *dockerImageSource) makeRequest(method, url string, auth bool, headers m
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *dockerImageSource) setupRequestAuth(req *http.Request) error {
|
func (s *dockerImageSource) setupRequestAuth(req *http.Request) error {
|
||||||
tokens := strings.SplitN(strings.TrimSpace(s.WWWAuthenticate), " ", 2)
|
tokens := strings.SplitN(strings.TrimSpace(s.wwwAuthenticate), " ", 2)
|
||||||
if len(tokens) != 2 {
|
if len(tokens) != 2 {
|
||||||
return fmt.Errorf("expected 2 tokens in WWW-Authenticate: %d, %s", len(tokens), s.WWWAuthenticate)
|
return fmt.Errorf("expected 2 tokens in WWW-Authenticate: %d, %s", len(tokens), s.wwwAuthenticate)
|
||||||
}
|
}
|
||||||
switch tokens[0] {
|
switch tokens[0] {
|
||||||
case "Basic":
|
case "Basic":
|
||||||
@ -473,15 +477,16 @@ func newDockerImageSource(img, certPath string, tlsVerify bool) (*dockerImageSou
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var tr *http.Transport
|
var tr *http.Transport
|
||||||
if certPath != "" {
|
if certPath != "" || !tlsVerify {
|
||||||
tlsc := &tls.Config{}
|
tlsc := &tls.Config{}
|
||||||
|
|
||||||
|
if certPath != "" {
|
||||||
cert, err := tls.LoadX509KeyPair(filepath.Join(certPath, "cert.pem"), filepath.Join(certPath, "key.pem"))
|
cert, err := tls.LoadX509KeyPair(filepath.Join(certPath, "cert.pem"), filepath.Join(certPath, "key.pem"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error loading x509 key pair: %s", err)
|
return nil, fmt.Errorf("Error loading x509 key pair: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsc.Certificates = append(tlsc.Certificates, cert)
|
tlsc.Certificates = append(tlsc.Certificates, cert)
|
||||||
|
}
|
||||||
tlsc.InsecureSkipVerify = !tlsVerify
|
tlsc.InsecureSkipVerify = !tlsVerify
|
||||||
tr = &http.Transport{
|
tr = &http.Transport{
|
||||||
TLSClientConfig: tlsc,
|
TLSClientConfig: tlsc,
|
||||||
@ -600,10 +605,6 @@ type pingResponse struct {
|
|||||||
errors []apiErr
|
errors []apiErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *pingResponse) needsAuth() bool {
|
|
||||||
return pr.WWWAuthenticate != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *dockerImageSource) ping() (*pingResponse, error) {
|
func (s *dockerImageSource) ping() (*pingResponse, error) {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
if s.transport != nil {
|
if s.transport != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user