Skip to content

Commit

Permalink
Minor cleanup, post-refactoring of cmd
Browse files Browse the repository at this point in the history
Signed-off-by: apostasie <[email protected]>
  • Loading branch information
apostasie committed Sep 2, 2024
1 parent b02b8f2 commit 4e89ddf
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 264 deletions.
88 changes: 88 additions & 0 deletions cmd/nerdctl/helpers/cobra.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,91 @@ func AddPersistentStringArrayFlag(cmd *cobra.Command, name string, aliases, nonP
}
}
}

// AddPersistentStringFlag is similar to AddStringFlag but persistent.
// See https://github.com/spf13/cobra/blob/main/user_guide.md#persistent-flags to learn what is "persistent".
func AddPersistentStringFlag(cmd *cobra.Command, name string, aliases, localAliases, persistentAliases []string, aliasToBeInherited *pflag.FlagSet, value string, env, usage string) {
if env != "" {
usage = fmt.Sprintf("%s [$%s]", usage, env)
}
if envV, ok := os.LookupEnv(env); ok {
value = envV
}
aliasesUsage := fmt.Sprintf("Alias of --%s", name)
p := new(string)

// flags is full set of flag(s)
// flags can redefine alias already used in subcommands
flags := cmd.Flags()
for _, a := range aliases {
if len(a) == 1 {
// pflag doesn't support short-only flags, so we have to register long one as well here
flags.StringVarP(p, a, a, value, aliasesUsage)
} else {
flags.StringVar(p, a, value, aliasesUsage)
}
// non-persistent flags are not added to the InheritedFlags, so we should add them manually
f := flags.Lookup(a)
aliasToBeInherited.AddFlag(f)
}

// localFlags are local to the rootCmd
localFlags := cmd.LocalFlags()
for _, a := range localAliases {
if len(a) == 1 {
// pflag doesn't support short-only flags, so we have to register long one as well here
localFlags.StringVarP(p, a, a, value, aliasesUsage)
} else {
localFlags.StringVar(p, a, value, aliasesUsage)
}
}

// persistentFlags cannot redefine alias already used in subcommands
persistentFlags := cmd.PersistentFlags()
persistentFlags.StringVar(p, name, value, usage)
for _, a := range persistentAliases {
if len(a) == 1 {
// pflag doesn't support short-only flags, so we have to register long one as well here
persistentFlags.StringVarP(p, a, a, value, aliasesUsage)
} else {
persistentFlags.StringVar(p, a, value, aliasesUsage)
}
}
}

// AddPersistentBoolFlag is similar to AddBoolFlag but persistent.
// See https://github.com/spf13/cobra/blob/main/user_guide.md#persistent-flags to learn what is "persistent".
func AddPersistentBoolFlag(cmd *cobra.Command, name string, aliases, nonPersistentAliases []string, value bool, env, usage string) {
if env != "" {
usage = fmt.Sprintf("%s [$%s]", usage, env)
}
if envV, ok := os.LookupEnv(env); ok {
var err error
value, err = strconv.ParseBool(envV)
if err != nil {
log.L.WithError(err).Warnf("Invalid boolean value for `%s`", env)
}
}
aliasesUsage := fmt.Sprintf("Alias of --%s", name)
p := new(bool)
flags := cmd.Flags()
for _, a := range nonPersistentAliases {
if len(a) == 1 {
// pflag doesn't support short-only flags, so we have to register long one as well here
flags.BoolVarP(p, a, a, value, aliasesUsage)
} else {
flags.BoolVar(p, a, value, aliasesUsage)
}
}

persistentFlags := cmd.PersistentFlags()
persistentFlags.BoolVar(p, name, value, usage)
for _, a := range aliases {
if len(a) == 1 {
// pflag doesn't support short-only flags, so we have to register long one as well here
persistentFlags.BoolVarP(p, a, a, value, aliasesUsage)
} else {
persistentFlags.BoolVar(p, a, value, aliasesUsage)
}
}
}
149 changes: 0 additions & 149 deletions cmd/nerdctl/helpers/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,165 +17,16 @@
package helpers

import (
"context"
"fmt"
"net"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"

"gotest.tools/v3/assert"

containerd "github.com/containerd/containerd/v2/client"
"github.com/containerd/containerd/v2/core/content"

"github.com/containerd/nerdctl/v2/pkg/buildkitutil"
"github.com/containerd/nerdctl/v2/pkg/testutil"
)

func FindIPv6(output string) net.IP {
var ipv6 string
lines := strings.Split(output, "\n")
for _, line := range lines {
if strings.Contains(line, "inet6") {
fields := strings.Fields(line)
if len(fields) > 1 {
ipv6 = strings.Split(fields[1], "/")[0]
break
}
}
}
return net.ParseIP(ipv6)
}

func RequiresStargz(base *testutil.Base) {
info := base.Info()
for _, p := range info.Plugins.Storage {
if p == "stargz" {
return
}
}
base.T.Skip("test requires stargz")
}

type JweKeyPair struct {
Prv string
Pub string
Cleanup func()
}

func NewJWEKeyPair(t testing.TB) *JweKeyPair {
testutil.RequireExecutable(t, "openssl")
td, err := os.MkdirTemp(t.TempDir(), "jwe-key-pair")
assert.NilError(t, err)
prv := filepath.Join(td, "mykey.pem")
pub := filepath.Join(td, "mypubkey.pem")
cmds := [][]string{
// Exec openssl commands to ensure that nerdctl is compatible with the output of openssl commands.
// Do NOT refactor this function to use "crypto/rsa" stdlib.
{"openssl", "genrsa", "-out", prv},
{"openssl", "rsa", "-in", prv, "-pubout", "-out", pub},
}
for _, f := range cmds {
cmd := exec.Command(f[0], f[1:]...)
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("failed to run %v: %v (%q)", cmd.Args, err, string(out))
}
}
return &JweKeyPair{
Prv: prv,
Pub: pub,
Cleanup: func() {
_ = os.RemoveAll(td)
},
}
}

func RmiAll(base *testutil.Base) {
base.T.Logf("Pruning images")
imageIDs := base.Cmd("images", "--no-trunc", "-a", "-q").OutLines()
// remove empty output line at the end
imageIDs = imageIDs[:len(imageIDs)-1]
// use `Run` on purpose (same below) because `rmi all` may fail on individual
// image id that has an expected running container (e.g. a registry)
base.Cmd(append([]string{"rmi", "-f"}, imageIDs...)...).Run()

base.T.Logf("Pruning build caches")
if _, err := buildkitutil.GetBuildkitHost(testutil.Namespace); err == nil {
base.Cmd("builder", "prune", "--force").AssertOK()
}

// For BuildKit >= 0.11, pruning cache isn't enough to remove manifest blobs that are referred by build history blobs
// https://github.com/containerd/nerdctl/pull/1833
if base.Target == testutil.Nerdctl {
base.T.Logf("Pruning all content blobs")
addr := base.ContainerdAddress()
client, err := containerd.New(addr, containerd.WithDefaultNamespace(testutil.Namespace))
assert.NilError(base.T, err)
cs := client.ContentStore()
ctx := context.TODO()
wf := func(info content.Info) error {
base.T.Logf("Pruning blob %+v", info)
if err := cs.Delete(ctx, info.Digest); err != nil {
base.T.Log(err)
}
return nil
}
if err := cs.Walk(ctx, wf); err != nil {
base.T.Log(err)
}

base.T.Logf("Pruning all images (again?)")
imageIDs = base.Cmd("images", "--no-trunc", "-a", "-q").OutLines()
base.T.Logf("pruning following images: %+v", imageIDs)
base.Cmd(append([]string{"rmi", "-f"}, imageIDs...)...).Run()
}
}

func CreateBuildContext(t *testing.T, dockerfile string) string {
tmpDir := t.TempDir()
err := os.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644)
assert.NilError(t, err)
return tmpDir
}

func RequiresSoci(base *testutil.Base) {
info := base.Info()
for _, p := range info.Plugins.Storage {
if p == "soci" {
return
}
}
base.T.Skip("test requires soci")
}

type CosignKeyPair struct {
PublicKey string
PrivateKey string
Cleanup func()
}

func NewCosignKeyPair(t testing.TB, path string, password string) *CosignKeyPair {
td, err := os.MkdirTemp(t.TempDir(), path)
assert.NilError(t, err)

cmd := exec.Command("cosign", "generate-key-pair")
cmd.Dir = td
cmd.Env = append(cmd.Env, fmt.Sprintf("COSIGN_PASSWORD=%s", password))
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("failed to run %v: %v (%q)", cmd.Args, err, string(out))
}

publicKey := filepath.Join(td, "cosign.pub")
privateKey := filepath.Join(td, "cosign.key")

return &CosignKeyPair{
PublicKey: publicKey,
PrivateKey: privateKey,
Cleanup: func() {
_ = os.RemoveAll(td)
},
}
}
Loading

0 comments on commit 4e89ddf

Please sign in to comment.