forked from containers/buildah
/
push.go
153 lines (136 loc) · 3.77 KB
/
push.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package main
import (
"fmt"
"os"
"strings"
"github.com/containers/image/manifest"
"github.com/containers/image/transports"
"github.com/containers/image/transports/alltransports"
"github.com/containers/storage/pkg/archive"
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/projectatomic/buildah"
"github.com/projectatomic/buildah/util"
"github.com/urfave/cli"
)
var (
pushFlags = []cli.Flag{
cli.StringFlag{
Name: "authfile",
Usage: "path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json",
},
cli.StringFlag{
Name: "cert-dir",
Value: "",
Usage: "use certificates at the specified path to access the registry",
},
cli.StringFlag{
Name: "creds",
Value: "",
Usage: "use `[username[:password]]` for accessing the registry",
},
cli.BoolFlag{
Name: "disable-compression, D",
Usage: "don't compress layers",
},
cli.StringFlag{
Name: "format, f",
Usage: "manifest type (oci, v2s1, or v2s2) to use when saving image using the 'dir:' transport (default is manifest type of source)",
},
cli.BoolFlag{
Name: "quiet, q",
Usage: "don't output progress information when pushing images",
},
cli.StringFlag{
Name: "signature-policy",
Usage: "`pathname` of signature policy file (not usually used)",
},
cli.BoolTFlag{
Name: "tls-verify",
Usage: "require HTTPS and verify certificates when accessing the registry",
},
}
pushDescription = fmt.Sprintf(`
Pushes an image to a specified location.
The Image "DESTINATION" uses a "transport":"details" format.
Supported transports:
%s
See buildah-push(1) section "DESTINATION" for the expected format
`, strings.Join(transports.ListNames(), ", "))
pushCommand = cli.Command{
Name: "push",
Usage: "Push an image to a specified destination",
Description: pushDescription,
Flags: pushFlags,
Action: pushCmd,
ArgsUsage: "IMAGE DESTINATION",
SkipArgReorder: true,
}
)
func pushCmd(c *cli.Context) error {
args := c.Args()
if len(args) < 2 {
return errors.New("source and destination image IDs must be specified")
}
if err := validateFlags(c, pushFlags); err != nil {
return err
}
src := args[0]
destSpec := args[1]
compress := archive.Gzip
if c.Bool("disable-compression") {
compress = archive.Uncompressed
}
store, err := getStore(c)
if err != nil {
return err
}
dest, err := alltransports.ParseImageName(destSpec)
// add the docker:// transport to see if they neglected it.
if err != nil {
if strings.Contains(destSpec, "://") {
return err
}
destSpec = "docker://" + destSpec
dest2, err2 := alltransports.ParseImageName(destSpec)
if err2 != nil {
return err
}
dest = dest2
}
systemContext, err := systemContextFromOptions(c)
if err != nil {
return errors.Wrapf(err, "error building system context")
}
var manifestType string
if c.IsSet("format") {
switch c.String("format") {
case "oci":
manifestType = imgspecv1.MediaTypeImageManifest
case "v2s1":
manifestType = manifest.DockerV2Schema1SignedMediaType
case "v2s2", "docker":
manifestType = manifest.DockerV2Schema2MediaType
default:
return fmt.Errorf("unknown format %q. Choose on of the supported formats: 'oci', 'v2s1', or 'v2s2'", c.String("format"))
}
}
options := buildah.PushOptions{
Compression: compress,
ManifestType: manifestType,
SignaturePolicyPath: c.String("signature-policy"),
Store: store,
SystemContext: systemContext,
}
if !c.Bool("quiet") {
options.ReportWriter = os.Stderr
}
err = buildah.Push(src, dest, options)
if err != nil {
return util.GetFailureCause(
err,
errors.Wrapf(err, "error pushing image %q to %q", src, destSpec),
)
}
return nil
}