c8d/push: Support pushing all tags
Implement missing feature that pushes all tags from the provided local repository. Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
parent
01cc1cc923
commit
babf907bfd
1 changed files with 39 additions and 7 deletions
|
@ -4,6 +4,8 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
|
@ -27,7 +29,8 @@ import (
|
|||
"golang.org/x/sync/semaphore"
|
||||
)
|
||||
|
||||
// PushImage initiates a push operation of the image pointed to by targetRef.
|
||||
// PushImage initiates a push operation of the image pointed to by sourceRef.
|
||||
// If reference is untagged, all tags from the reference repository are pushed.
|
||||
// Image manifest (or index) is pushed as is, which will probably fail if you
|
||||
// don't have all content referenced by the index.
|
||||
// Cross-repo mounts will be attempted for non-existing blobs.
|
||||
|
@ -36,13 +39,44 @@ import (
|
|||
// pointing to the new target repository. This will allow subsequent pushes
|
||||
// to perform cross-repo mounts of the shared content when pushing to a different
|
||||
// repository on the same registry.
|
||||
func (i *ImageService) PushImage(ctx context.Context, targetRef reference.Named, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) (retErr error) {
|
||||
if _, tagged := targetRef.(reference.Tagged); !tagged {
|
||||
if _, digested := targetRef.(reference.Digested); !digested {
|
||||
return errdefs.NotImplemented(errors.New("push all tags is not implemented"))
|
||||
func (i *ImageService) PushImage(ctx context.Context, sourceRef reference.Named, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) (retErr error) {
|
||||
out := streamformatter.NewJSONProgressOutput(outStream, false)
|
||||
|
||||
if _, tagged := sourceRef.(reference.Tagged); !tagged {
|
||||
if _, digested := sourceRef.(reference.Digested); !digested {
|
||||
// Image is not tagged nor digested, that means all tags push was requested.
|
||||
|
||||
// Find all images with the same repository.
|
||||
nameFilter := "^" + regexp.QuoteMeta(sourceRef.Name()) + ":" + reference.TagRegexp.String() + "$"
|
||||
imgs, err := i.client.ImageService().List(ctx, "name~="+strconv.Quote(nameFilter))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, img := range imgs {
|
||||
named, err := reference.ParseNamed(img.Name)
|
||||
if err != nil {
|
||||
// This shouldn't happen, but log a warning just in case.
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"image": img.Name,
|
||||
"sourceRef": sourceRef,
|
||||
}).Warn("refusing to push an invalid tag")
|
||||
continue
|
||||
}
|
||||
|
||||
if err := i.pushRef(ctx, named, metaHeaders, authConfig, out); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return i.pushRef(ctx, sourceRef, metaHeaders, authConfig, out)
|
||||
}
|
||||
|
||||
func (i *ImageService) pushRef(ctx context.Context, targetRef reference.Named, metaHeaders map[string][]string, authConfig *registry.AuthConfig, out progress.Output) (retErr error) {
|
||||
leasedCtx, release, err := i.client.WithLease(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -53,8 +87,6 @@ func (i *ImageService) PushImage(ctx context.Context, targetRef reference.Named,
|
|||
}
|
||||
}()
|
||||
|
||||
out := streamformatter.NewJSONProgressOutput(outStream, false)
|
||||
|
||||
img, err := i.client.ImageService().Get(ctx, targetRef.String())
|
||||
if err != nil {
|
||||
return errdefs.NotFound(err)
|
||||
|
|
Loading…
Reference in a new issue