From 1766f61aed3fccd60a108df0b82e8df137935ac4 Mon Sep 17 00:00:00 2001 From: Avi Deitcher Date: Wed, 28 Feb 2024 16:26:37 +0200 Subject: [PATCH] option to push local image to somewhere else Signed-off-by: Avi Deitcher --- src/cmd/linuxkit/cache/push.go | 23 ++++++++++++++--------- src/cmd/linuxkit/cache_push.go | 4 +++- src/cmd/linuxkit/pkglib/build.go | 4 ++-- src/cmd/linuxkit/pkglib/build_test.go | 2 +- src/cmd/linuxkit/spec/cache.go | 4 +++- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/cmd/linuxkit/cache/push.go b/src/cmd/linuxkit/cache/push.go index bd8f3bf55..3462619d1 100644 --- a/src/cmd/linuxkit/cache/push.go +++ b/src/cmd/linuxkit/cache/push.go @@ -13,17 +13,22 @@ import ( ) // Push push an image along with a multi-arch index. -func (p *Provider) Push(name string, withManifest bool) error { +// name is the name as referenced in the local cache, remoteName is the name to give it remotely. +// If remoteName is empty, it is the same as name. +func (p *Provider) Push(name, remoteName string, withManifest bool) error { var ( err error options []remote.Option ) - ref, err := namepkg.ParseReference(name) + if remoteName == "" { + remoteName = name + } + ref, err := namepkg.ParseReference(remoteName) if err != nil { return err } - fmt.Printf("Pushing %s\n", name) + fmt.Printf("Pushing local %s as %s\n", name, remoteName) // do we even have the given one? root, err := p.FindRoot(name) if err != nil { @@ -40,14 +45,14 @@ func (p *Provider) Push(name string, withManifest bool) error { case err1 == nil: dig, err := img.Digest() if err != nil { - return fmt.Errorf("could not get digest for image %s: %v", name, err) + return fmt.Errorf("could not get digest for local image %s: %v", name, err) } desc, err := remote.Get(ref, remoteOptions...) if err == nil && desc != nil && dig == desc.Digest { - fmt.Printf("%s image already available on remote registry, skipping push", name) + fmt.Printf("%s image already available on remote registry, skipping push", remoteName) return nil } - log.Debugf("pushing image %s", name) + log.Debugf("pushing image %s as %s", name, remoteName) if err := remote.Write(ref, img, options...); err != nil { return err } @@ -66,7 +71,7 @@ func (p *Provider) Push(name string, withManifest bool) error { desc, err := remote.Get(ref, remoteOptions...) if err == nil && desc != nil { if dig == desc.Digest { - fmt.Printf("%s index already available on remote registry, skipping push", name) + fmt.Printf("%s index already available on remote registry, skipping push", remoteName) return nil } // we have a different index, need to cross-reference and only override relevant stuff @@ -78,7 +83,7 @@ func (p *Provider) Push(name string, withManifest bool) error { } } } - log.Debugf("pushing index %s", name) + log.Debugf("pushing local index %s as %s", name, remoteName) // this is an index, so we not only want to write the index, but tags for each arch-specific image in it if err := remote.WriteIndex(ref, ii, options...); err != nil { return err @@ -89,7 +94,7 @@ func (p *Provider) Push(name string, withManifest bool) error { if m.Platform == nil || m.Platform.Architecture == "" { continue } - archTag := fmt.Sprintf("%s-%s", name, m.Platform.Architecture) + archTag := fmt.Sprintf("%s-%s", remoteName, m.Platform.Architecture) tag, err := namepkg.NewTag(archTag) if err != nil { return fmt.Errorf("could not create a valid arch-specific tag %s: %v", archTag, err) diff --git a/src/cmd/linuxkit/cache_push.go b/src/cmd/linuxkit/cache_push.go index 533167761..9229495d1 100644 --- a/src/cmd/linuxkit/cache_push.go +++ b/src/cmd/linuxkit/cache_push.go @@ -8,6 +8,7 @@ import ( ) func cachePushCmd() *cobra.Command { + var remoteName string cmd := &cobra.Command{ Use: "push", Short: "push images from the linuxkit cache", @@ -25,13 +26,14 @@ func cachePushCmd() *cobra.Command { log.Fatalf("unable to read a local cache: %v", err) } - if err := p.Push(fullname, true); err != nil { + if err := p.Push(fullname, remoteName, true); err != nil { log.Fatalf("unable to push image named %s: %v", name, err) } } return nil }, } + cmd.Flags().StringVar(&remoteName, "remote-name", "", "Push it under a different name, e.g. push local image foo/bar:mine as baz/bee:yours. If blank, uses same local name.") return cmd } diff --git a/src/cmd/linuxkit/pkglib/build.go b/src/cmd/linuxkit/pkglib/build.go index 8c138f6a7..0486e2554 100644 --- a/src/cmd/linuxkit/pkglib/build.go +++ b/src/cmd/linuxkit/pkglib/build.go @@ -513,7 +513,7 @@ func (p Pkg) Build(bos ...BuildOpt) error { } // push the manifest - if err := c.Push(p.FullTag(), bo.manifest); err != nil { + if err := c.Push(p.FullTag(), "", bo.manifest); err != nil { return err } @@ -535,7 +535,7 @@ func (p Pkg) Build(bos ...BuildOpt) error { if _, err := c.DescriptorWrite(&ref, *desc); err != nil { return err } - if err := c.Push(fullRelTag, bo.manifest); err != nil { + if err := c.Push(fullRelTag, "", bo.manifest); err != nil { return err } diff --git a/src/cmd/linuxkit/pkglib/build_test.go b/src/cmd/linuxkit/pkglib/build_test.go index c558f0c89..a511df4a8 100644 --- a/src/cmd/linuxkit/pkglib/build_test.go +++ b/src/cmd/linuxkit/pkglib/build_test.go @@ -392,7 +392,7 @@ func (c *cacheMocker) IndexWrite(ref *reference.Spec, descriptors ...registry.De return c.NewSource(ref, "", &desc), nil } -func (c *cacheMocker) Push(name string, withManifest bool) error { +func (c *cacheMocker) Push(name, remoteName string, withManifest bool) error { if !c.enablePush { return errors.New("push disabled") } diff --git a/src/cmd/linuxkit/spec/cache.go b/src/cmd/linuxkit/spec/cache.go index a3c8d1e68..9b6295631 100644 --- a/src/cmd/linuxkit/spec/cache.go +++ b/src/cmd/linuxkit/spec/cache.go @@ -38,8 +38,10 @@ type CacheProvider interface { // and replaces any existing one DescriptorWrite(ref *reference.Spec, descriptors v1.Descriptor) (ImageSource, error) // Push an image along with a multi-arch index from local cache to remote registry. + // name is the name as referenced in the local cache, remoteName is the name to give it remotely. + // If remoteName is empty, it is the same as name. // if withManifest defined will push a multi-arch manifest - Push(name string, withManifest bool) error + Push(name, remoteName string, withManifest bool) error // NewSource return an ImageSource for a specific ref and architecture in the cache. NewSource(ref *reference.Spec, architecture string, descriptor *v1.Descriptor) ImageSource // GetContent returns an io.Reader to the provided content as is, given a specific digest. It is