/
image_push.go
147 lines (129 loc) · 5.41 KB
/
image_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
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"github.com/containerd/nerdctl/v2/pkg/api/types"
"github.com/containerd/nerdctl/v2/pkg/clientutil"
"github.com/containerd/nerdctl/v2/pkg/cmd/image"
"github.com/spf13/cobra"
)
const (
allowNonDistFlag = "allow-nondistributable-artifacts"
)
func newPushCommand() *cobra.Command {
var pushCommand = &cobra.Command{
Use: "push [flags] NAME[:TAG]",
Short: "Push an image or a repository to a registry. Optionally specify \"ipfs://\" or \"ipns://\" scheme to push image to IPFS.",
Args: IsExactArgs(1),
RunE: pushAction,
ValidArgsFunction: pushShellComplete,
SilenceUsage: true,
SilenceErrors: true,
}
// #region platform flags
// platform is defined as StringSlice, not StringArray, to allow specifying "--platform=amd64,arm64"
pushCommand.Flags().StringSlice("platform", []string{}, "Push content for a specific platform")
pushCommand.RegisterFlagCompletionFunc("platform", shellCompletePlatforms)
pushCommand.Flags().Bool("all-platforms", false, "Push content for all platforms")
// #endregion
pushCommand.Flags().Bool("estargz", false, "Convert the image into eStargz")
pushCommand.Flags().Bool("ipfs-ensure-image", true, "Ensure the entire contents of the image is locally available before push")
pushCommand.Flags().String("ipfs-address", "", "multiaddr of IPFS API (default uses $IPFS_PATH env variable if defined or local directory ~/.ipfs)")
// #region sign flags
pushCommand.Flags().String("sign", "none", "Sign the image (none|cosign|notation")
pushCommand.RegisterFlagCompletionFunc("sign", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"none", "cosign", "notation"}, cobra.ShellCompDirectiveNoFileComp
})
pushCommand.Flags().String("cosign-key", "", "Path to the private key file, KMS URI or Kubernetes Secret for --sign=cosign")
pushCommand.Flags().String("notation-key-name", "", "Signing key name for a key previously added to notation's key list for --sign=notation")
// #endregion
// #region soci flags
pushCommand.Flags().Int64("soci-span-size", -1, "Span size that soci index uses to segment layer data. Default is 4 MiB.")
pushCommand.Flags().Int64("soci-min-layer-size", -1, "Minimum layer size to build zTOC for. Smaller layers won't have zTOC and not lazy pulled. Default is 10 MiB.")
// #endregion
pushCommand.Flags().BoolP("quiet", "q", false, "Suppress verbose output")
pushCommand.Flags().Bool(allowNonDistFlag, false, "Allow pushing images with non-distributable blobs")
return pushCommand
}
func processImagePushOptions(cmd *cobra.Command) (types.ImagePushOptions, error) {
globalOptions, err := processRootCmdFlags(cmd)
if err != nil {
return types.ImagePushOptions{}, err
}
platform, err := cmd.Flags().GetStringSlice("platform")
if err != nil {
return types.ImagePushOptions{}, err
}
allPlatforms, err := cmd.Flags().GetBool("all-platforms")
if err != nil {
return types.ImagePushOptions{}, err
}
estargz, err := cmd.Flags().GetBool("estargz")
if err != nil {
return types.ImagePushOptions{}, err
}
ipfsEnsureImage, err := cmd.Flags().GetBool("ipfs-ensure-image")
if err != nil {
return types.ImagePushOptions{}, err
}
ipfsAddress, err := cmd.Flags().GetString("ipfs-address")
if err != nil {
return types.ImagePushOptions{}, err
}
quiet, err := cmd.Flags().GetBool("quiet")
if err != nil {
return types.ImagePushOptions{}, err
}
allowNonDist, err := cmd.Flags().GetBool(allowNonDistFlag)
if err != nil {
return types.ImagePushOptions{}, err
}
signOptions, err := processImageSignOptions(cmd)
if err != nil {
return types.ImagePushOptions{}, err
}
sociOptions, err := processSociOptions(cmd)
if err != nil {
return types.ImagePushOptions{}, err
}
return types.ImagePushOptions{
GOptions: globalOptions,
SignOptions: signOptions,
SociOptions: sociOptions,
Platforms: platform,
AllPlatforms: allPlatforms,
Estargz: estargz,
IpfsEnsureImage: ipfsEnsureImage,
IpfsAddress: ipfsAddress,
Quiet: quiet,
AllowNondistributableArtifacts: allowNonDist,
Stdout: cmd.OutOrStdout(),
}, nil
}
func pushAction(cmd *cobra.Command, args []string) error {
options, err := processImagePushOptions(cmd)
if err != nil {
return err
}
rawRef := args[0]
client, ctx, cancel, err := clientutil.NewClient(cmd.Context(), options.GOptions.Namespace, options.GOptions.Address)
if err != nil {
return err
}
defer cancel()
return image.Push(ctx, client, rawRef, options)
}
func pushShellComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
// show image names
return shellCompleteImageNames(cmd)
}