Merge pull request #3972 from fuweid/me-fix-3937

Pull: create image record after blobs download
This commit is contained in:
Derek McGowan 2020-01-30 10:56:59 -08:00 committed by GitHub
commit 12cb1554be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 5 deletions

View File

@ -390,7 +390,11 @@ func (c *Client) Fetch(ctx context.Context, ref string, opts ...RemoteOpt) (imag
}
defer done(ctx)
return c.fetch(ctx, fetchCtx, ref, 0)
img, err := c.fetch(ctx, fetchCtx, ref, 0)
if err != nil {
return images.Image{}, err
}
return c.createNewImage(ctx, img)
}
// Push uploads the provided content to a remote resource

28
pull.go
View File

@ -27,6 +27,7 @@ import (
"github.com/containerd/containerd/remotes/docker/schema1"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
"golang.org/x/sync/semaphore"
)
@ -62,15 +63,18 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima
defer done(ctx)
var unpacks int32
var unpackEg *errgroup.Group
var unpackWrapper func(f images.Handler) images.Handler
if pullCtx.Unpack {
// unpacker only supports schema 2 image, for schema 1 this is noop.
u, err := c.newUnpacker(ctx, pullCtx)
if err != nil {
return nil, errors.Wrap(err, "create unpacker")
}
unpackWrapper, eg := u.handlerWrapper(ctx, &unpacks)
unpackWrapper, unpackEg = u.handlerWrapper(ctx, &unpacks)
defer func() {
if err := eg.Wait(); err != nil {
if err := unpackEg.Wait(); err != nil {
if retErr == nil {
retErr = errors.Wrap(err, "unpack")
}
@ -90,6 +94,22 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima
return nil, err
}
// NOTE(fuweid): unpacker defers blobs download. before create image
// record in ImageService, should wait for unpacking(including blobs
// download).
if pullCtx.Unpack {
if unpackEg != nil {
if err := unpackEg.Wait(); err != nil {
return nil, err
}
}
}
img, err = c.createNewImage(ctx, img)
if err != nil {
return nil, err
}
i := NewImageWithPlatform(c, img, pullCtx.PlatformMatcher)
if pullCtx.Unpack {
@ -201,12 +221,14 @@ func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, lim
}
}
img := images.Image{
return images.Image{
Name: name,
Target: desc,
Labels: rCtx.Labels,
}, nil
}
func (c *Client) createNewImage(ctx context.Context, img images.Image) (images.Image, error) {
is := c.ImageService()
for {
if created, err := is.Create(ctx, img); err != nil {