Skip to content

Commit 5141daf

Browse files
authored
Merge pull request #308 from concourse/fallback-on-get
check: use GET if if HEAD doesnt return digest
2 parents 08cb8fe + c42285d commit 5141daf

1 file changed

Lines changed: 35 additions & 2 deletions

File tree

cmd/check/main.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"crypto/x509"
66
"encoding/json"
77
"fmt"
8+
"io/ioutil"
89
"net"
910
"net/http"
1011
"net/url"
@@ -19,6 +20,7 @@ import (
1920
ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login"
2021
ecrapi "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api"
2122
"github.com/concourse/retryhttp"
23+
"github.com/docker/distribution"
2224
"github.com/docker/distribution/digest"
2325
_ "github.com/docker/distribution/manifest/schema1"
2426
_ "github.com/docker/distribution/manifest/schema2"
@@ -112,7 +114,7 @@ func main() {
112114
json.NewEncoder(os.Stdout).Encode(response)
113115
}
114116

115-
func fetchDigest(client *http.Client, manifestURL, repository, tag string) (string, bool) {
117+
func headDigest(client *http.Client, manifestURL, repository, tag string) (string, bool) {
116118
manifestRequest, err := http.NewRequest("HEAD", manifestURL, nil)
117119
fatalIf("failed to build manifest request", err)
118120
manifestRequest.Header.Add("Accept", "application/vnd.docker.distribution.manifest.v2+json")
@@ -122,6 +124,7 @@ func fetchDigest(client *http.Client, manifestURL, repository, tag string) (stri
122124
fatalIf("failed to fetch manifest", err)
123125

124126
defer manifestResponse.Body.Close()
127+
125128
if manifestResponse.StatusCode == http.StatusNotFound {
126129
return "", false
127130
}
@@ -132,12 +135,42 @@ func fetchDigest(client *http.Client, manifestURL, repository, tag string) (stri
132135

133136
digest := manifestResponse.Header.Get("Docker-Content-Digest")
134137
if digest == "" {
135-
fatal("no digest header returned")
138+
return fetchDigest(client, manifestURL, repository, tag)
136139
}
137140

138141
return digest, true
139142
}
140143

144+
func fetchDigest(client *http.Client, manifestURL, repository, tag string) (string, bool) {
145+
manifestRequest, err := http.NewRequest("GET", manifestURL, nil)
146+
fatalIf("failed to build manifest request", err)
147+
manifestRequest.Header.Add("Accept", "application/vnd.docker.distribution.manifest.v2+json")
148+
manifestRequest.Header.Add("Accept", "application/json")
149+
150+
manifestResponse, err := client.Do(manifestRequest)
151+
fatalIf("failed to fetch manifest", err)
152+
153+
defer manifestResponse.Body.Close()
154+
155+
if manifestResponse.StatusCode == http.StatusNotFound {
156+
return "", false
157+
}
158+
159+
if manifestResponse.StatusCode != http.StatusOK {
160+
fatal(fmt.Sprintf("failed to fetch digest for image '%s:%s': %s\ndoes the image exist?", repository, tag, manifestResponse.Status))
161+
}
162+
163+
ctHeader := manifestResponse.Header.Get("Content-Type")
164+
165+
bytes, err := ioutil.ReadAll(manifestResponse.Body)
166+
fatalIf("failed to read response body", err)
167+
168+
_, desc, err := distribution.UnmarshalManifest(ctHeader, bytes)
169+
fatalIf("failed to unmarshal manifest", err)
170+
171+
return string(desc.Digest), true
172+
}
173+
141174
func makeTransport(logger lager.Logger, request CheckRequest, registryHost string, repository string) (http.RoundTripper, string) {
142175
// for non self-signed registries, caCertPool must be nil in order to use the system certs
143176
var caCertPool *x509.CertPool

0 commit comments

Comments
 (0)