|
17 | 17 | package helpers
|
18 | 18 |
|
19 | 19 | import (
|
20 |
| - "context" |
21 |
| - "fmt" |
22 |
| - "net" |
23 | 20 | "os"
|
24 |
| - "os/exec" |
25 | 21 | "path/filepath"
|
26 |
| - "strings" |
27 | 22 | "testing"
|
28 | 23 |
|
29 | 24 | "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" |
36 | 25 | )
|
37 | 26 |
|
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 |
| - |
137 | 27 | func CreateBuildContext(t *testing.T, dockerfile string) string {
|
138 | 28 | tmpDir := t.TempDir()
|
139 | 29 | err := os.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644)
|
140 | 30 | assert.NilError(t, err)
|
141 | 31 | return tmpDir
|
142 | 32 | }
|
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