Skip to content

Commit 4e89ddf

Browse files
committed
Minor cleanup, post-refactoring of cmd
Signed-off-by: apostasie <[email protected]>
1 parent b02b8f2 commit 4e89ddf

File tree

5 files changed

+241
-264
lines changed

5 files changed

+241
-264
lines changed

cmd/nerdctl/helpers/cobra.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,91 @@ func AddPersistentStringArrayFlag(cmd *cobra.Command, name string, aliases, nonP
195195
}
196196
}
197197
}
198+
199+
// AddPersistentStringFlag is similar to AddStringFlag but persistent.
200+
// See https://github.com/spf13/cobra/blob/main/user_guide.md#persistent-flags to learn what is "persistent".
201+
func AddPersistentStringFlag(cmd *cobra.Command, name string, aliases, localAliases, persistentAliases []string, aliasToBeInherited *pflag.FlagSet, value string, env, usage string) {
202+
if env != "" {
203+
usage = fmt.Sprintf("%s [$%s]", usage, env)
204+
}
205+
if envV, ok := os.LookupEnv(env); ok {
206+
value = envV
207+
}
208+
aliasesUsage := fmt.Sprintf("Alias of --%s", name)
209+
p := new(string)
210+
211+
// flags is full set of flag(s)
212+
// flags can redefine alias already used in subcommands
213+
flags := cmd.Flags()
214+
for _, a := range aliases {
215+
if len(a) == 1 {
216+
// pflag doesn't support short-only flags, so we have to register long one as well here
217+
flags.StringVarP(p, a, a, value, aliasesUsage)
218+
} else {
219+
flags.StringVar(p, a, value, aliasesUsage)
220+
}
221+
// non-persistent flags are not added to the InheritedFlags, so we should add them manually
222+
f := flags.Lookup(a)
223+
aliasToBeInherited.AddFlag(f)
224+
}
225+
226+
// localFlags are local to the rootCmd
227+
localFlags := cmd.LocalFlags()
228+
for _, a := range localAliases {
229+
if len(a) == 1 {
230+
// pflag doesn't support short-only flags, so we have to register long one as well here
231+
localFlags.StringVarP(p, a, a, value, aliasesUsage)
232+
} else {
233+
localFlags.StringVar(p, a, value, aliasesUsage)
234+
}
235+
}
236+
237+
// persistentFlags cannot redefine alias already used in subcommands
238+
persistentFlags := cmd.PersistentFlags()
239+
persistentFlags.StringVar(p, name, value, usage)
240+
for _, a := range persistentAliases {
241+
if len(a) == 1 {
242+
// pflag doesn't support short-only flags, so we have to register long one as well here
243+
persistentFlags.StringVarP(p, a, a, value, aliasesUsage)
244+
} else {
245+
persistentFlags.StringVar(p, a, value, aliasesUsage)
246+
}
247+
}
248+
}
249+
250+
// AddPersistentBoolFlag is similar to AddBoolFlag but persistent.
251+
// See https://github.com/spf13/cobra/blob/main/user_guide.md#persistent-flags to learn what is "persistent".
252+
func AddPersistentBoolFlag(cmd *cobra.Command, name string, aliases, nonPersistentAliases []string, value bool, env, usage string) {
253+
if env != "" {
254+
usage = fmt.Sprintf("%s [$%s]", usage, env)
255+
}
256+
if envV, ok := os.LookupEnv(env); ok {
257+
var err error
258+
value, err = strconv.ParseBool(envV)
259+
if err != nil {
260+
log.L.WithError(err).Warnf("Invalid boolean value for `%s`", env)
261+
}
262+
}
263+
aliasesUsage := fmt.Sprintf("Alias of --%s", name)
264+
p := new(bool)
265+
flags := cmd.Flags()
266+
for _, a := range nonPersistentAliases {
267+
if len(a) == 1 {
268+
// pflag doesn't support short-only flags, so we have to register long one as well here
269+
flags.BoolVarP(p, a, a, value, aliasesUsage)
270+
} else {
271+
flags.BoolVar(p, a, value, aliasesUsage)
272+
}
273+
}
274+
275+
persistentFlags := cmd.PersistentFlags()
276+
persistentFlags.BoolVar(p, name, value, usage)
277+
for _, a := range aliases {
278+
if len(a) == 1 {
279+
// pflag doesn't support short-only flags, so we have to register long one as well here
280+
persistentFlags.BoolVarP(p, a, a, value, aliasesUsage)
281+
} else {
282+
persistentFlags.BoolVar(p, a, value, aliasesUsage)
283+
}
284+
}
285+
}

cmd/nerdctl/helpers/testing.go

Lines changed: 0 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -17,165 +17,16 @@
1717
package helpers
1818

1919
import (
20-
"context"
21-
"fmt"
22-
"net"
2320
"os"
24-
"os/exec"
2521
"path/filepath"
26-
"strings"
2722
"testing"
2823

2924
"gotest.tools/v3/assert"
30-
31-
containerd "github.com/containerd/containerd/v2/client"
32-
"github.com/containerd/containerd/v2/core/content"
33-
34-
"github.com/containerd/nerdctl/v2/pkg/buildkitutil"
35-
"github.com/containerd/nerdctl/v2/pkg/testutil"
3625
)
3726

38-
func FindIPv6(output string) net.IP {
39-
var ipv6 string
40-
lines := strings.Split(output, "\n")
41-
for _, line := range lines {
42-
if strings.Contains(line, "inet6") {
43-
fields := strings.Fields(line)
44-
if len(fields) > 1 {
45-
ipv6 = strings.Split(fields[1], "/")[0]
46-
break
47-
}
48-
}
49-
}
50-
return net.ParseIP(ipv6)
51-
}
52-
53-
func RequiresStargz(base *testutil.Base) {
54-
info := base.Info()
55-
for _, p := range info.Plugins.Storage {
56-
if p == "stargz" {
57-
return
58-
}
59-
}
60-
base.T.Skip("test requires stargz")
61-
}
62-
63-
type JweKeyPair struct {
64-
Prv string
65-
Pub string
66-
Cleanup func()
67-
}
68-
69-
func NewJWEKeyPair(t testing.TB) *JweKeyPair {
70-
testutil.RequireExecutable(t, "openssl")
71-
td, err := os.MkdirTemp(t.TempDir(), "jwe-key-pair")
72-
assert.NilError(t, err)
73-
prv := filepath.Join(td, "mykey.pem")
74-
pub := filepath.Join(td, "mypubkey.pem")
75-
cmds := [][]string{
76-
// Exec openssl commands to ensure that nerdctl is compatible with the output of openssl commands.
77-
// Do NOT refactor this function to use "crypto/rsa" stdlib.
78-
{"openssl", "genrsa", "-out", prv},
79-
{"openssl", "rsa", "-in", prv, "-pubout", "-out", pub},
80-
}
81-
for _, f := range cmds {
82-
cmd := exec.Command(f[0], f[1:]...)
83-
if out, err := cmd.CombinedOutput(); err != nil {
84-
t.Fatalf("failed to run %v: %v (%q)", cmd.Args, err, string(out))
85-
}
86-
}
87-
return &JweKeyPair{
88-
Prv: prv,
89-
Pub: pub,
90-
Cleanup: func() {
91-
_ = os.RemoveAll(td)
92-
},
93-
}
94-
}
95-
96-
func RmiAll(base *testutil.Base) {
97-
base.T.Logf("Pruning images")
98-
imageIDs := base.Cmd("images", "--no-trunc", "-a", "-q").OutLines()
99-
// remove empty output line at the end
100-
imageIDs = imageIDs[:len(imageIDs)-1]
101-
// use `Run` on purpose (same below) because `rmi all` may fail on individual
102-
// image id that has an expected running container (e.g. a registry)
103-
base.Cmd(append([]string{"rmi", "-f"}, imageIDs...)...).Run()
104-
105-
base.T.Logf("Pruning build caches")
106-
if _, err := buildkitutil.GetBuildkitHost(testutil.Namespace); err == nil {
107-
base.Cmd("builder", "prune", "--force").AssertOK()
108-
}
109-
110-
// For BuildKit >= 0.11, pruning cache isn't enough to remove manifest blobs that are referred by build history blobs
111-
// https://github.com/containerd/nerdctl/pull/1833
112-
if base.Target == testutil.Nerdctl {
113-
base.T.Logf("Pruning all content blobs")
114-
addr := base.ContainerdAddress()
115-
client, err := containerd.New(addr, containerd.WithDefaultNamespace(testutil.Namespace))
116-
assert.NilError(base.T, err)
117-
cs := client.ContentStore()
118-
ctx := context.TODO()
119-
wf := func(info content.Info) error {
120-
base.T.Logf("Pruning blob %+v", info)
121-
if err := cs.Delete(ctx, info.Digest); err != nil {
122-
base.T.Log(err)
123-
}
124-
return nil
125-
}
126-
if err := cs.Walk(ctx, wf); err != nil {
127-
base.T.Log(err)
128-
}
129-
130-
base.T.Logf("Pruning all images (again?)")
131-
imageIDs = base.Cmd("images", "--no-trunc", "-a", "-q").OutLines()
132-
base.T.Logf("pruning following images: %+v", imageIDs)
133-
base.Cmd(append([]string{"rmi", "-f"}, imageIDs...)...).Run()
134-
}
135-
}
136-
13727
func CreateBuildContext(t *testing.T, dockerfile string) string {
13828
tmpDir := t.TempDir()
13929
err := os.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644)
14030
assert.NilError(t, err)
14131
return tmpDir
14232
}
143-
144-
func RequiresSoci(base *testutil.Base) {
145-
info := base.Info()
146-
for _, p := range info.Plugins.Storage {
147-
if p == "soci" {
148-
return
149-
}
150-
}
151-
base.T.Skip("test requires soci")
152-
}
153-
154-
type CosignKeyPair struct {
155-
PublicKey string
156-
PrivateKey string
157-
Cleanup func()
158-
}
159-
160-
func NewCosignKeyPair(t testing.TB, path string, password string) *CosignKeyPair {
161-
td, err := os.MkdirTemp(t.TempDir(), path)
162-
assert.NilError(t, err)
163-
164-
cmd := exec.Command("cosign", "generate-key-pair")
165-
cmd.Dir = td
166-
cmd.Env = append(cmd.Env, fmt.Sprintf("COSIGN_PASSWORD=%s", password))
167-
if out, err := cmd.CombinedOutput(); err != nil {
168-
t.Fatalf("failed to run %v: %v (%q)", cmd.Args, err, string(out))
169-
}
170-
171-
publicKey := filepath.Join(td, "cosign.pub")
172-
privateKey := filepath.Join(td, "cosign.key")
173-
174-
return &CosignKeyPair{
175-
PublicKey: publicKey,
176-
PrivateKey: privateKey,
177-
Cleanup: func() {
178-
_ = os.RemoveAll(td)
179-
},
180-
}
181-
}

0 commit comments

Comments
 (0)