/
pkg_remotetag.go
74 lines (67 loc) · 2.43 KB
/
pkg_remotetag.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package main
import (
"fmt"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/crane"
namepkg "github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/linuxkit/linuxkit/src/cmd/linuxkit/util"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
func pkgRemoteTagCmd() *cobra.Command {
var release string
cmd := &cobra.Command{
Use: "remote-tag",
Short: "tag a package in a remote registry with another tag",
Long: `Tag a package in a remote registry with another tag, without downloading or pulling.
Will simply tag using the identical descriptor.
First argument is "from" tag, second is "to" tag.
If the "to" and "from" repositories are the same, then it is a simple tag operation.
If they are not, then the "from" image is pulled and pushed to the "to" repository.
`,
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
var finalErr error
from := args[0]
to := args[1]
remoteOptions := []remote.Option{remote.WithAuthFromKeychain(authn.DefaultKeychain)}
fromFullname := util.ReferenceExpand(from, util.ReferenceWithTag())
toFullname := util.ReferenceExpand(to, util.ReferenceWithTag())
fromRef, err := namepkg.ParseReference(fromFullname)
if err != nil {
return err
}
toRef, err := namepkg.ParseReference(toFullname)
if err != nil {
return err
}
fromDesc, err := remote.Get(fromRef, remoteOptions...)
if err != nil {
return fmt.Errorf("error getting manifest for from image %s: %v", fromFullname, err)
}
toDesc, err := remote.Get(toRef, remoteOptions...)
if err == nil {
if toDesc.Digest == fromDesc.Digest {
log.Infof("image %s already exists in the registry, identical to %s, skipping", toFullname, fromFullname)
return nil
}
log.Infof("image %s already exists in the registry, but is different from %s, overwriting", toFullname, fromFullname)
}
// see if they are from the same sources
if fromRef.Context().String() == toRef.Context().String() {
toTag, err := namepkg.NewTag(toFullname)
if err != nil {
return err
}
finalErr = remote.Tag(toTag, fromDesc, remoteOptions...)
} else {
// different, so need to copy
finalErr = crane.Copy(fromFullname, toFullname)
}
return finalErr
},
}
cmd.Flags().StringVar(&release, "release", "", "Release the given version")
return cmd
}