Push push an image along with a multi-arch index. 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 withArchSpecificTags is true, it will push all arch-specific images in the index, each as their own tag
(name, remoteName string, withArchSpecificTags, override bool)
| 23 | // their own tag with the same name as the index, but with the architecture appended, e.g. |
| 24 | // image:foo will have image:foo-amd64, image:foo-arm64, image:foo-riscv64, etc. |
| 25 | func (p *Provider) Push(name, remoteName string, withArchSpecificTags, override bool) error { |
| 26 | var ( |
| 27 | err error |
| 28 | options []remote.Option |
| 29 | ) |
| 30 | if remoteName == "" { |
| 31 | remoteName = name |
| 32 | } |
| 33 | ref, err := namepkg.ParseReference(remoteName) |
| 34 | if err != nil { |
| 35 | return err |
| 36 | } |
| 37 | options = append(options, remote.WithAuthFromKeychain(authn.DefaultKeychain)) |
| 38 | |
| 39 | fmt.Printf("Pushing local %s as %s\n", name, remoteName) |
| 40 | |
| 41 | // check if it already exists, unless override is explicit |
| 42 | if !override { |
| 43 | if _, err := registry.GetRemote().Get(ref, options...); err == nil { |
| 44 | log.Infof("image %s already exists in the registry, skipping", remoteName) |
| 45 | return nil |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | // if we made it this far, either we had a specific override, or we do not have the image remotely |
| 50 | |
| 51 | // do we even have the given one? |
| 52 | root, err := p.FindRoot(name) |
| 53 | if err != nil { |
| 54 | return err |
| 55 | } |
| 56 | |
| 57 | img, err1 := root.Image() |
| 58 | ii, err2 := root.ImageIndex() |
| 59 | // before we even try to push, let us see if it exists remotely |
| 60 | remoteOptions := []remote.Option{remote.WithAuthFromKeychain(authn.DefaultKeychain)} |
| 61 | |
| 62 | switch { |
| 63 | case err1 == nil: |
| 64 | dig, err := img.Digest() |
| 65 | if err != nil { |
| 66 | return fmt.Errorf("could not get digest for local image %s: %v", name, err) |
| 67 | } |
| 68 | desc, err := registry.GetRemote().Get(ref, remoteOptions...) |
| 69 | if err == nil && desc != nil && dig == desc.Digest { |
| 70 | fmt.Printf("%s image already available on remote registry, skipping push\n", remoteName) |
| 71 | return nil |
| 72 | } |
| 73 | log.Debugf("pushing image %s as %s", name, remoteName) |
| 74 | if err := remote.Write(ref, img, options...); err != nil { |
| 75 | return err |
| 76 | } |
| 77 | fmt.Printf("Pushed image %s\n", name) |
| 78 | case err2 == nil: |
| 79 | dig, err := ii.Digest() |
| 80 | if err != nil { |
| 81 | return fmt.Errorf("could not get digest for index %s: %v", name, err) |
| 82 | } |
no test coverage detected