1
0
Fork 0
mirror of https://github.com/imjasonh/kontain.me synced 2026-07-08 09:04:54 +00:00

Support HEAD requests for mirror

This commit is contained in:
Jason Hall 2021-01-28 21:46:31 -05:00
parent abbb5079e1
commit fed10b0b5f
6 changed files with 40 additions and 12 deletions

View file

@ -126,7 +126,7 @@ func (s *server) serveBuildpackManifest(w http.ResponseWriter, r *http.Request)
// image tag.
if commitRE.MatchString(revision) {
ck := cacheKey(path, revision)
if err := s.storage.BlobExists(ctx, ck); err == nil {
if _, err := s.storage.BlobExists(ctx, ck); err == nil {
s.info.Println("serving cached manifest:", ck)
serve.Blob(w, r, ck)
return
@ -231,7 +231,7 @@ func (s *server) prepareWorkspace() (string, string, error) {
}
func (s *server) fetchAndBuild(src, layers, ghOwner, ghRepo, revision, path string) (string, error) {
image := fmt.Sprintf("gcr.io/%s/built-%d", projectID, time.Now().Unix)
image := fmt.Sprintf("gcr.io/%s/built-%d", projectID, time.Now().Unix())
source := fmt.Sprintf("https://github.com/%s/%s/archive/%s.tar.gz", ghOwner, ghRepo, revision)
if resp, err := http.Head(source); err != nil {

View file

@ -108,7 +108,7 @@ func (s *server) serveFlattenManifest(w http.ResponseWriter, r *http.Request) {
// Check if we have a flattened manifest cached, and if so serve it
// directly.
ck := cacheKey(d.Digest.String())
if err := s.storage.BlobExists(ctx, ck); err == nil {
if _, err := s.storage.BlobExists(ctx, ck); err == nil {
s.info.Println("serving cached manifest:", ck)
serve.Blob(w, r, ck)
return

View file

@ -119,7 +119,7 @@ func (s *server) serveKanikoManifest(w http.ResponseWriter, r *http.Request) {
// image tag.
if commitRE.MatchString(revision) {
ck := cacheKey(path, revision)
if err := s.storage.BlobExists(ctx, ck); err == nil {
if _, err := s.storage.BlobExists(ctx, ck); err == nil {
s.info.Println("serving cached manifest:", ck)
serve.Blob(w, r, ck)
return
@ -223,7 +223,7 @@ func (s *server) prepareWorkspace() error {
}
func (s *server) fetchAndBuild(ghOwner, ghRepo, revision, path string) (string, error) {
image := fmt.Sprintf("gcr.io/%s/built-%d", projectID, time.Now().Unix)
image := fmt.Sprintf("gcr.io/%s/built-%d", projectID, time.Now().Unix())
source := fmt.Sprintf("https://github.com/%s/%s/archive/%s.tar.gz", ghOwner, ghRepo, revision)
if resp, err := http.Head(source); err != nil {

View file

@ -89,6 +89,21 @@ func (s *server) serveMirrorManifest(w http.ResponseWriter, r *http.Request) {
return
}
// If it's a HEAD request, and request was by digest, and we have that
// manifest mirrored by digest already, serve HEAD response from GCS.
// If it's a HEAD request and the other conditions aren't met, we'll
// handle this later by consulting the real registry.
if r.Method == http.MethodHead {
if d, ok := ref.(name.Digest); ok {
if desc, err := s.storage.BlobExists(ctx, d.DigestStr()); err == nil {
w.Header().Set("Docker-Content-Digest", d.DigestStr())
w.Header().Set("Content-Type", string(desc.MediaType))
w.Header().Set("Content-Length", fmt.Sprintf("%d", desc.Size))
return
}
}
}
// Get the original image's digest, and check if we have that manifest
// blob.
d, err := remote.Head(ref, remote.WithContext(ctx))
@ -97,7 +112,13 @@ func (s *server) serveMirrorManifest(w http.ResponseWriter, r *http.Request) {
serve.Error(w, err)
return
}
if err := s.storage.BlobExists(ctx, d.Digest.String()); err == nil {
if r.Method == http.MethodHead {
w.Header().Set("Docker-Content-Digest", d.Digest.String())
w.Header().Set("Content-Type", string(d.MediaType))
w.Header().Set("Content-Length", fmt.Sprintf("%d", d.Size))
return
}
if _, err := s.storage.BlobExists(ctx, d.Digest.String()); err == nil {
serve.Blob(w, r, d.Digest.String())
return
} else {

View file

@ -86,7 +86,7 @@ func (s *server) serveWaitManifest(w http.ResponseWriter, r *http.Request) {
// The image has already been built; serve it.
ck := cacheKey(name)
if err := s.storage.BlobExists(ctx, ck); err == nil {
if _, err := s.storage.BlobExists(ctx, ck); err == nil {
s.info.Printf("blob %q exists, serving", ck)
serve.Blob(w, r, ck)
return
@ -95,7 +95,7 @@ func (s *server) serveWaitManifest(w http.ResponseWriter, r *http.Request) {
// If a placeholder exists, a wait is ongoing; serve the placeholder
// contents.
phn := fmt.Sprintf("placeholder-%s", ck)
if err := s.storage.BlobExists(ctx, phn); err == nil {
if _, err := s.storage.BlobExists(ctx, phn); err == nil {
s.info.Printf("placeholder %q exists", phn)
serve.Error(w, fmt.Errorf("waiting for image..."))
return
@ -143,7 +143,7 @@ const size = 100
const num = 10
var laterFunc = delay.Func("later", func(ctx context.Context, ck string) error {
log.Println("generating random image for cache key %q", ck)
log.Printf("generating random image for cache key %q", ck)
img, err := random.Image(size, num)
if err != nil {
return err

View file

@ -13,6 +13,7 @@ import (
"cloud.google.com/go/storage"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/types"
"golang.org/x/sync/errgroup"
"google.golang.org/api/googleapi"
)
@ -36,9 +37,15 @@ func NewStorage(ctx context.Context) (*Storage, error) {
return &Storage{client}, nil
}
func (s *Storage) BlobExists(ctx context.Context, name string) error {
_, err := s.client.Bucket(bucket).Object(fmt.Sprintf("blobs/%s", name)).Attrs(ctx)
return err
func (s *Storage) BlobExists(ctx context.Context, name string) (v1.Descriptor, error) {
obj, err := s.client.Bucket(bucket).Object(fmt.Sprintf("blobs/%s", name)).Attrs(ctx)
if err != nil {
return v1.Descriptor{}, err
}
return v1.Descriptor{
MediaType: types.MediaType(obj.ContentType),
Size: obj.Size,
}, nil
}
func (s *Storage) WriteObject(ctx context.Context, name, contents string) error {