podman

Форк
0
/
pull_test.go 
696 строк · 29.5 Кб
1
package integration
2

3
import (
4
	"fmt"
5
	"os"
6
	"path/filepath"
7
	"runtime"
8

9
	. "github.com/containers/podman/v5/test/utils"
10
	. "github.com/onsi/ginkgo/v2"
11
	. "github.com/onsi/gomega"
12
	. "github.com/onsi/gomega/gexec"
13
)
14

15
var _ = Describe("Podman pull", func() {
16

17
	It("podman pull multiple images with/without tag/digest", func() {
18
		session := podmanTest.Podman([]string{"pull", "-q", "busybox:musl", "alpine", "alpine:latest", "quay.io/libpod/cirros", "quay.io/libpod/testdigest_v2s2@sha256:755f4d90b3716e2bf57060d249e2cd61c9ac089b1233465c5c2cb2d7ee550fdb"})
19
		session.WaitWithDefaultTimeout()
20
		Expect(session).Should(ExitCleanly())
21

22
		session = podmanTest.Podman([]string{"pull", "busybox:latest", "docker.io/library/ibetthisdoesnotexistfr:random", "alpine"})
23
		session.WaitWithDefaultTimeout()
24
		Expect(session).Should(Exit(125))
25
		expectedError := "initializing source docker://ibetthisdoesnotexistfr:random"
26
		Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
27

28
		session = podmanTest.Podman([]string{"rmi", "busybox:musl", "alpine", "quay.io/libpod/cirros", "testdigest_v2s2@sha256:755f4d90b3716e2bf57060d249e2cd61c9ac089b1233465c5c2cb2d7ee550fdb"})
29
		session.WaitWithDefaultTimeout()
30
		Expect(session).Should(ExitCleanly())
31
	})
32

33
	It("podman pull bogus image", func() {
34
		session := podmanTest.Podman([]string{"pull", "quay.io/libpod/ibetthisdoesntexist:there"})
35
		session.WaitWithDefaultTimeout()
36
		Expect(session).To(ExitWithError())
37
		// "Not authorized", not "Not Found", because that's how registries roll??
38
		Expect(session.ErrorToString()).To(ContainSubstring("unauthorized: access to the requested resource is not authorized"))
39
	})
40

41
	It("podman pull with tag --quiet", func() {
42
		session := podmanTest.Podman([]string{"pull", "-q", "quay.io/libpod/testdigest_v2s2:20200210"})
43
		session.WaitWithDefaultTimeout()
44
		Expect(session).Should(ExitCleanly())
45
		quietOutput := session.OutputToString()
46

47
		session = podmanTest.Podman([]string{"inspect", "testdigest_v2s2:20200210", "--format", "{{.ID}}"})
48
		session.WaitWithDefaultTimeout()
49
		Expect(session).Should(ExitCleanly())
50
		Expect(session.OutputToString()).To(Equal(quietOutput))
51

52
		session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2:20200210"})
53
		session.WaitWithDefaultTimeout()
54
		Expect(session).Should(ExitCleanly())
55
	})
56

57
	It("podman pull without tag", func() {
58
		session := podmanTest.Podman([]string{"pull", "-q", "quay.io/libpod/testdigest_v2s2"})
59
		session.WaitWithDefaultTimeout()
60
		Expect(session).Should(ExitCleanly())
61

62
		session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2"})
63
		session.WaitWithDefaultTimeout()
64
		Expect(session).Should(ExitCleanly())
65
	})
66

67
	It("podman pull and run on split imagestore", func() {
68
		SkipIfRemote("podman-remote does not support setting external imagestore")
69
		imgName := "splitstoretest"
70

71
		// Make alpine write-able
72
		session := podmanTest.Podman([]string{"build", "--pull=never", "--tag", imgName, "build/basicalpine"})
73
		session.WaitWithDefaultTimeout()
74
		Expect(session).Should(ExitCleanly())
75

76
		tmpDir := filepath.Join(podmanTest.TempDir, "splitstore")
77
		outfile := filepath.Join(podmanTest.TempDir, "image.tar")
78

79
		save := podmanTest.Podman([]string{"save", "-q", "-o", outfile, "--format", "oci-archive", imgName})
80
		save.WaitWithDefaultTimeout()
81
		Expect(save).Should(ExitCleanly())
82

83
		rmi := podmanTest.Podman([]string{"rmi", imgName})
84
		rmi.WaitWithDefaultTimeout()
85
		Expect(rmi).Should(ExitCleanly())
86

87
		// load to splitstore
88
		result := podmanTest.Podman([]string{"load", "-q", "--imagestore", tmpDir, "-q", "-i", outfile})
89
		result.WaitWithDefaultTimeout()
90
		Expect(result).Should(ExitCleanly())
91

92
		// tag busybox to busybox-test in graphroot since we can delete readonly busybox
93
		session = podmanTest.Podman([]string{"tag", "quay.io/libpod/busybox:latest", "busybox-test"})
94
		session.WaitWithDefaultTimeout()
95
		Expect(session).Should(ExitCleanly())
96

97
		session = podmanTest.Podman([]string{"images", "--imagestore", tmpDir})
98
		session.WaitWithDefaultTimeout()
99
		Expect(session).Should(ExitCleanly())
100
		Expect(session.OutputToString()).To(ContainSubstring(imgName))
101
		Expect(session.OutputToString()).To(ContainSubstring("busybox-test"))
102

103
		// Test deleting image in graphroot even when `--imagestore` is set
104
		session = podmanTest.Podman([]string{"rmi", "--imagestore", tmpDir, "busybox-test"})
105
		session.WaitWithDefaultTimeout()
106
		Expect(session).Should(ExitCleanly())
107

108
		// Images without --imagestore should not contain alpine
109
		session = podmanTest.Podman([]string{"images"})
110
		session.WaitWithDefaultTimeout()
111
		Expect(session).Should(ExitCleanly())
112
		Expect(session.OutputToString()).To(Not(ContainSubstring(imgName)))
113

114
		// Set `imagestore` in `storage.conf` and container should run.
115
		configPath := filepath.Join(podmanTest.TempDir, ".config", "containers", "storage.conf")
116
		os.Setenv("CONTAINERS_STORAGE_CONF", configPath)
117
		defer func() {
118
			os.Unsetenv("CONTAINERS_STORAGE_CONF")
119
		}()
120

121
		err = os.MkdirAll(filepath.Dir(configPath), os.ModePerm)
122
		Expect(err).ToNot(HaveOccurred())
123
		storageConf := []byte(fmt.Sprintf("[storage]\nimagestore=\"%s\"", tmpDir))
124
		err = os.WriteFile(configPath, storageConf, os.ModePerm)
125
		Expect(err).ToNot(HaveOccurred())
126

127
		session = podmanTest.Podman([]string{"run", "--name", "test", "--rm",
128
			imgName, "echo", "helloworld"})
129
		session.WaitWithDefaultTimeout()
130
		Expect(session).Should(Exit(0))
131
		Expect(session.OutputToString()).To(ContainSubstring("helloworld"))
132
		Expect(session.ErrorToString()).To(ContainSubstring("The storage 'driver' option should be set in "))
133
		Expect(session.ErrorToString()).To(ContainSubstring("A driver was picked automatically."))
134
	})
135

136
	It("podman pull by digest", func() {
137
		session := podmanTest.Podman([]string{"pull", "-q", "quay.io/libpod/testdigest_v2s2@sha256:755f4d90b3716e2bf57060d249e2cd61c9ac089b1233465c5c2cb2d7ee550fdb"})
138
		session.WaitWithDefaultTimeout()
139
		Expect(session).Should(ExitCleanly())
140

141
		// Without a tag/digest the input is normalized with the "latest" tag, see #11964
142
		session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2"})
143
		session.WaitWithDefaultTimeout()
144
		Expect(session).Should(Exit(1))
145

146
		session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2@sha256:755f4d90b3716e2bf57060d249e2cd61c9ac089b1233465c5c2cb2d7ee550fdb"})
147
		session.WaitWithDefaultTimeout()
148
		Expect(session).Should(ExitCleanly())
149
	})
150

151
	It("podman pull check all tags", func() {
152
		session := podmanTest.Podman([]string{"pull", "-q", "--all-tags", "quay.io/libpod/testdigest_v2s2"})
153
		session.WaitWithDefaultTimeout()
154
		Expect(session).Should(ExitCleanly())
155

156
		session = podmanTest.Podman([]string{"images"})
157
		session.WaitWithDefaultTimeout()
158
		Expect(session).Should(ExitCleanly())
159
		Expect(len(session.OutputToStringArray())).To(BeNumerically(">=", 2), "Expected at least two images")
160

161
		session = podmanTest.Podman([]string{"pull", "-q", "-a", "quay.io/libpod/testdigest_v2s2"})
162
		session.WaitWithDefaultTimeout()
163
		Expect(session).Should(ExitCleanly())
164

165
		session = podmanTest.Podman([]string{"images"})
166
		session.WaitWithDefaultTimeout()
167
		Expect(session).Should(ExitCleanly())
168
		Expect(len(session.OutputToStringArray())).To(BeNumerically(">=", 2), "Expected at least two images")
169
	})
170

171
	It("podman pull from docker with nonexistent --authfile", func() {
172
		session := podmanTest.Podman([]string{"pull", "-q", "--authfile", "/tmp/nonexistent", ALPINE})
173
		session.WaitWithDefaultTimeout()
174
		Expect(session).To(ExitWithError())
175
		Expect(session.ErrorToString()).To(Equal("Error: credential file is not accessible: faccessat /tmp/nonexistent: no such file or directory"))
176
	})
177

178
	It("podman pull by digest (image list)", func() {
179
		session := podmanTest.Podman([]string{"pull", "-q", "--arch=arm64", ALPINELISTDIGEST})
180
		session.WaitWithDefaultTimeout()
181
		Expect(session).Should(ExitCleanly())
182
		// inspect using the digest of the list
183
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINELISTDIGEST})
184
		session.WaitWithDefaultTimeout()
185
		Expect(session).Should(ExitCleanly())
186
		Expect(string(session.Out.Contents())).To(HavePrefix("[]"))
187
		// inspect using the digest of the list
188
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINELISTDIGEST})
189
		session.WaitWithDefaultTimeout()
190
		Expect(session).Should(ExitCleanly())
191
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
192
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
193
		// inspect using the digest of the arch-specific image's manifest
194
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64DIGEST})
195
		session.WaitWithDefaultTimeout()
196
		Expect(session).Should(ExitCleanly())
197
		Expect(string(session.Out.Contents())).To(HavePrefix("[]"))
198
		// inspect using the digest of the arch-specific image's manifest
199
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64DIGEST})
200
		session.WaitWithDefaultTimeout()
201
		Expect(session).Should(ExitCleanly())
202
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
203
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
204
		// inspect using the image ID
205
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64ID})
206
		session.WaitWithDefaultTimeout()
207
		Expect(session).Should(ExitCleanly())
208
		Expect(string(session.Out.Contents())).To(HavePrefix("[]"))
209
		// inspect using the image ID
210
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64ID})
211
		session.WaitWithDefaultTimeout()
212
		Expect(session).Should(ExitCleanly())
213
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
214
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
215
		// remove using the digest of the list
216
		session = podmanTest.Podman([]string{"rmi", ALPINELISTDIGEST})
217
		session.WaitWithDefaultTimeout()
218
		Expect(session).Should(ExitCleanly())
219
	})
220

221
	It("podman pull by instance digest (image list)", func() {
222
		session := podmanTest.Podman([]string{"pull", "-q", "--arch=arm64", ALPINEARM64DIGEST})
223
		session.WaitWithDefaultTimeout()
224
		Expect(session).Should(ExitCleanly())
225
		// inspect using the digest of the list
226
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINELISTDIGEST})
227
		session.WaitWithDefaultTimeout()
228
		Expect(session).To(ExitWithError())
229
		// inspect using the digest of the list
230
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINELISTDIGEST})
231
		session.WaitWithDefaultTimeout()
232
		Expect(session).To(ExitWithError())
233
		// inspect using the digest of the arch-specific image's manifest
234
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64DIGEST})
235
		session.WaitWithDefaultTimeout()
236
		Expect(session).Should(ExitCleanly())
237
		Expect(string(session.Out.Contents())).To(HavePrefix("[]"))
238
		// inspect using the digest of the arch-specific image's manifest
239
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64DIGEST})
240
		session.WaitWithDefaultTimeout()
241
		Expect(session).Should(ExitCleanly())
242
		Expect(string(session.Out.Contents())).To(Not(ContainSubstring(ALPINELISTDIGEST)))
243
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
244
		// inspect using the image ID
245
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64ID})
246
		session.WaitWithDefaultTimeout()
247
		Expect(session).Should(ExitCleanly())
248
		Expect(string(session.Out.Contents())).To(HavePrefix("[]"))
249
		// inspect using the image ID
250
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64ID})
251
		session.WaitWithDefaultTimeout()
252
		Expect(session).Should(ExitCleanly())
253
		Expect(string(session.Out.Contents())).To(Not(ContainSubstring(ALPINELISTDIGEST)))
254
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
255
		// remove using the digest of the instance
256
		session = podmanTest.Podman([]string{"rmi", ALPINEARM64DIGEST})
257
		session.WaitWithDefaultTimeout()
258
		Expect(session).Should(ExitCleanly())
259
	})
260

261
	It("podman pull by tag (image list)", func() {
262
		session := podmanTest.Podman([]string{"pull", "-q", "--arch=arm64", ALPINELISTTAG})
263
		session.WaitWithDefaultTimeout()
264
		Expect(session).Should(ExitCleanly())
265
		// inspect using the tag we used for pulling
266
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINELISTTAG})
267
		session.WaitWithDefaultTimeout()
268
		Expect(session).Should(ExitCleanly())
269
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG))
270
		// inspect using the tag we used for pulling
271
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINELISTTAG})
272
		session.WaitWithDefaultTimeout()
273
		Expect(session).Should(ExitCleanly())
274
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
275
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
276
		// inspect using the digest of the list
277
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINELISTDIGEST})
278
		session.WaitWithDefaultTimeout()
279
		Expect(session).Should(ExitCleanly())
280
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG))
281
		// inspect using the digest of the list
282
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINELISTDIGEST})
283
		session.WaitWithDefaultTimeout()
284
		Expect(session).Should(ExitCleanly())
285
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
286
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
287
		// inspect using the digest of the arch-specific image's manifest
288
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64DIGEST})
289
		session.WaitWithDefaultTimeout()
290
		Expect(session).Should(ExitCleanly())
291
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG))
292
		// inspect using the digest of the arch-specific image's manifest
293
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64DIGEST})
294
		session.WaitWithDefaultTimeout()
295
		Expect(session).Should(ExitCleanly())
296
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
297
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
298
		// inspect using the image ID
299
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64ID})
300
		session.WaitWithDefaultTimeout()
301
		Expect(session).Should(ExitCleanly())
302
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG))
303
		// inspect using the image ID
304
		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64ID})
305
		session.WaitWithDefaultTimeout()
306
		Expect(session).Should(ExitCleanly())
307
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
308
		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
309
		// remove using the tag
310
		session = podmanTest.Podman([]string{"rmi", ALPINELISTTAG})
311
		session.WaitWithDefaultTimeout()
312
		Expect(session).Should(ExitCleanly())
313
	})
314

315
	It("podman pull from docker-archive", func() {
316
		SkipIfRemote("podman-remote does not support pulling from docker-archive")
317

318
		podmanTest.AddImageToRWStore(CIRROS_IMAGE)
319
		tarfn := filepath.Join(podmanTest.TempDir, "cirros.tar")
320
		session := podmanTest.Podman([]string{"save", "-q", "-o", tarfn, "cirros"})
321
		session.WaitWithDefaultTimeout()
322

323
		Expect(session).Should(ExitCleanly())
324
		session = podmanTest.Podman([]string{"rmi", "cirros"})
325
		session.WaitWithDefaultTimeout()
326
		Expect(session).Should(ExitCleanly())
327
		session = podmanTest.Podman([]string{"pull", "-q", fmt.Sprintf("docker-archive:%s", tarfn)})
328
		session.WaitWithDefaultTimeout()
329
		Expect(session).Should(ExitCleanly())
330
		session = podmanTest.Podman([]string{"rmi", "cirros"})
331
		session.WaitWithDefaultTimeout()
332
		Expect(session).Should(ExitCleanly())
333

334
		// Pulling a multi-image archive without further specifying
335
		// which image _must_ error out. Pulling is restricted to one
336
		// image.
337
		session = podmanTest.Podman([]string{"pull", "-q", "docker-archive:./testdata/docker-two-images.tar.xz"})
338
		session.WaitWithDefaultTimeout()
339
		Expect(session).Should(Exit(125))
340
		expectedError := "Unexpected tar manifest.json: expected 1 item, got 2"
341
		Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
342

343
		// Now pull _one_ image from a multi-image archive via the name
344
		// and index syntax.
345
		session = podmanTest.Podman([]string{"pull", "-q", "docker-archive:./testdata/docker-two-images.tar.xz:@0"})
346
		session.WaitWithDefaultTimeout()
347
		Expect(session).Should(ExitCleanly())
348

349
		session = podmanTest.Podman([]string{"pull", "-q", "docker-archive:./testdata/docker-two-images.tar.xz:example.com/empty:latest"})
350
		session.WaitWithDefaultTimeout()
351
		Expect(session).Should(ExitCleanly())
352

353
		session = podmanTest.Podman([]string{"pull", "-q", "docker-archive:./testdata/docker-two-images.tar.xz:@1"})
354
		session.WaitWithDefaultTimeout()
355
		Expect(session).Should(ExitCleanly())
356

357
		session = podmanTest.Podman([]string{"pull", "-q", "docker-archive:./testdata/docker-two-images.tar.xz:example.com/empty/but:different"})
358
		session.WaitWithDefaultTimeout()
359
		Expect(session).Should(ExitCleanly())
360

361
		// Now check for some errors.
362
		session = podmanTest.Podman([]string{"pull", "-q", "docker-archive:./testdata/docker-two-images.tar.xz:foo.com/does/not/exist:latest"})
363
		session.WaitWithDefaultTimeout()
364
		Expect(session).Should(Exit(125))
365
		expectedError = "Tag \"foo.com/does/not/exist:latest\" not found"
366
		Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
367

368
		session = podmanTest.Podman([]string{"pull", "-q", "docker-archive:./testdata/docker-two-images.tar.xz:@2"})
369
		session.WaitWithDefaultTimeout()
370
		Expect(session).Should(Exit(125))
371
		expectedError = "Invalid source index @2, only 2 manifest items available"
372
		Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
373
	})
374

375
	It("podman pull from oci-archive", func() {
376
		SkipIfRemote("podman-remote does not support pulling from oci-archive")
377

378
		podmanTest.AddImageToRWStore(CIRROS_IMAGE)
379
		tarfn := filepath.Join(podmanTest.TempDir, "oci-cirrus.tar")
380
		session := podmanTest.Podman([]string{"save", "-q", "--format", "oci-archive", "-o", tarfn, "cirros"})
381
		session.WaitWithDefaultTimeout()
382

383
		Expect(session).Should(ExitCleanly())
384
		session = podmanTest.Podman([]string{"rmi", "cirros"})
385
		session.WaitWithDefaultTimeout()
386
		Expect(session).Should(ExitCleanly())
387
		session = podmanTest.Podman([]string{"pull", "-q", fmt.Sprintf("oci-archive:%s", tarfn)})
388
		session.WaitWithDefaultTimeout()
389
		Expect(session).Should(ExitCleanly())
390
		session = podmanTest.Podman([]string{"rmi", "cirros"})
391
		session.WaitWithDefaultTimeout()
392
		Expect(session).Should(ExitCleanly())
393
	})
394

395
	It("podman pull from local directory", func() {
396
		SkipIfRemote("podman-remote does not support pulling from local directory")
397

398
		podmanTest.AddImageToRWStore(CIRROS_IMAGE)
399
		dirpath := filepath.Join(podmanTest.TempDir, "cirros")
400
		err = os.MkdirAll(dirpath, os.ModePerm)
401
		Expect(err).ToNot(HaveOccurred())
402
		imgPath := fmt.Sprintf("dir:%s", dirpath)
403

404
		session := podmanTest.Podman([]string{"push", "-q", "cirros", imgPath})
405
		session.WaitWithDefaultTimeout()
406
		Expect(session).Should(ExitCleanly())
407
		session = podmanTest.Podman([]string{"rmi", "cirros"})
408
		session.WaitWithDefaultTimeout()
409
		Expect(session).Should(ExitCleanly())
410
		session = podmanTest.Podman([]string{"run", imgPath, "ls"})
411
		session.WaitWithDefaultTimeout()
412
		Expect(session).Should(Exit(0))
413
		Expect(session.ErrorToString()).To(ContainSubstring("Copying blob"), "Image is pulled on run")
414

415
		// Note that reference is not preserved in dir.
416
		session = podmanTest.Podman([]string{"image", "exists", "cirros"})
417
		session.WaitWithDefaultTimeout()
418
		Expect(session).Should(Exit(1))
419
	})
420

421
	It("podman pull from local OCI directory", func() {
422
		SkipIfRemote("podman-remote does not support pulling from OCI directory")
423

424
		podmanTest.AddImageToRWStore(CIRROS_IMAGE)
425
		dirpath := filepath.Join(podmanTest.TempDir, "cirros")
426
		err = os.MkdirAll(dirpath, os.ModePerm)
427
		Expect(err).ToNot(HaveOccurred())
428
		imgName := "localhost/name:tag"
429
		imgPath := fmt.Sprintf("oci:%s:%s", dirpath, imgName)
430

431
		session := podmanTest.Podman([]string{"push", "-q", "cirros", imgPath})
432
		session.WaitWithDefaultTimeout()
433
		Expect(session).Should(ExitCleanly())
434
		session = podmanTest.Podman([]string{"rmi", "cirros"})
435
		session.WaitWithDefaultTimeout()
436
		Expect(session).Should(ExitCleanly())
437
		session = podmanTest.Podman([]string{"pull", "-q", imgPath})
438
		session.WaitWithDefaultTimeout()
439
		Expect(session).Should(ExitCleanly())
440
		session = podmanTest.Podman([]string{"image", "exists", imgName})
441
		session.WaitWithDefaultTimeout()
442
		Expect(session).Should(ExitCleanly())
443
	})
444

445
	It("podman pull + inspect from unqualified-search registry", func() {
446
		// Regression test for #6381:
447
		// Make sure that `pull shortname` and `inspect shortname`
448
		// refer to the same image.
449

450
		// We already tested pulling, so we can save some energy and
451
		// just restore local artifacts and tag them.
452
		err := podmanTest.RestoreArtifact(ALPINE)
453
		Expect(err).ToNot(HaveOccurred())
454
		err = podmanTest.RestoreArtifact(BB)
455
		Expect(err).ToNot(HaveOccurred())
456

457
		// What we want is at least two images which have the same name
458
		// and are prefixed with two different unqualified-search
459
		// registries from ../registries.conf.
460
		//
461
		// A `podman inspect $name` must yield the one from the _first_
462
		// matching registry in the registries.conf.
463
		getID := func(image string) string {
464
			setup := podmanTest.Podman([]string{"image", "inspect", image})
465
			setup.WaitWithDefaultTimeout()
466
			Expect(setup).Should(ExitCleanly())
467

468
			data := setup.InspectImageJSON() // returns []inspect.ImageData
469
			Expect(data).To(HaveLen(1))
470
			return data[0].ID
471
		}
472

473
		untag := func(image string) {
474
			setup := podmanTest.Podman([]string{"untag", image})
475
			setup.WaitWithDefaultTimeout()
476
			Expect(setup).Should(ExitCleanly())
477

478
			setup = podmanTest.Podman([]string{"image", "inspect", image})
479
			setup.WaitWithDefaultTimeout()
480
			Expect(setup).Should(ExitCleanly())
481

482
			data := setup.InspectImageJSON() // returns []inspect.ImageData
483
			Expect(data).To(HaveLen(1))
484
			Expect(data[0].RepoTags).To(BeEmpty())
485
		}
486

487
		tag := func(image, tag string) {
488
			setup := podmanTest.Podman([]string{"tag", image, tag})
489
			setup.WaitWithDefaultTimeout()
490
			Expect(setup).Should(ExitCleanly())
491
			setup = podmanTest.Podman([]string{"image", "exists", tag})
492
			setup.WaitWithDefaultTimeout()
493
			Expect(setup).Should(ExitCleanly())
494
		}
495

496
		image1 := getID(ALPINE)
497
		image2 := getID(BB)
498

499
		// $ head -n2 ../registries.conf
500
		// [registries.search]
501
		// registries = ['docker.io', 'quay.io', 'registry.fedoraproject.org']
502
		registries := []string{"docker.io", "quay.io", "registry.fedoraproject.org"}
503
		name := "foo/test:tag"
504
		tests := []struct {
505
			// tag1 has precedence (see list above) over tag2 when
506
			// doing an inspect on "test:tag".
507
			tag1, tag2 string
508
		}{
509
			{
510
				fmt.Sprintf("%s/%s", registries[0], name),
511
				fmt.Sprintf("%s/%s", registries[1], name),
512
			},
513
			{
514
				fmt.Sprintf("%s/%s", registries[0], name),
515
				fmt.Sprintf("%s/%s", registries[2], name),
516
			},
517
			{
518
				fmt.Sprintf("%s/%s", registries[1], name),
519
				fmt.Sprintf("%s/%s", registries[2], name),
520
			},
521
		}
522

523
		for _, t := range tests {
524
			// 1) untag both images
525
			// 2) tag them according to `t`
526
			// 3) make sure that an inspect of `name` returns `image1` with `tag1`
527
			untag(image1)
528
			untag(image2)
529
			tag(image1, t.tag1)
530
			tag(image2, t.tag2)
531

532
			setup := podmanTest.Podman([]string{"image", "inspect", name})
533
			setup.WaitWithDefaultTimeout()
534
			Expect(setup).Should(ExitCleanly())
535

536
			data := setup.InspectImageJSON() // returns []inspect.ImageData
537
			Expect(data).To(HaveLen(1))
538
			Expect(data[0].RepoTags).To(HaveLen(1))
539
			Expect(data[0].RepoTags[0]).To(Equal(t.tag1))
540
			Expect(data[0]).To(HaveField("ID", image1))
541
		}
542
	})
543

544
	It("podman pull --platform", func() {
545
		session := podmanTest.Podman([]string{"pull", "-q", "--platform=linux/bogus", ALPINE})
546
		session.WaitWithDefaultTimeout()
547
		Expect(session).Should(Exit(125))
548
		expectedError := "no image found in manifest list for architecture bogus"
549
		Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
550

551
		session = podmanTest.Podman([]string{"pull", "-q", "--platform=linux/arm64", "--os", "windows", ALPINE})
552
		session.WaitWithDefaultTimeout()
553
		Expect(session).Should(Exit(125))
554
		expectedError = "--platform option can not be specified with --arch or --os"
555
		Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
556

557
		session = podmanTest.Podman([]string{"pull", "-q", "--platform=linux/arm64", ALPINE})
558
		session.WaitWithDefaultTimeout()
559
		Expect(session).Should(ExitCleanly())
560

561
		setup := podmanTest.Podman([]string{"image", "inspect", session.OutputToString()})
562
		setup.WaitWithDefaultTimeout()
563
		Expect(setup).Should(ExitCleanly())
564

565
		data := setup.InspectImageJSON() // returns []inspect.ImageData
566
		Expect(data).To(HaveLen(1))
567
		Expect(data[0]).To(HaveField("Os", runtime.GOOS))
568
		Expect(data[0]).To(HaveField("Architecture", "arm64"))
569
	})
570

571
	It("podman pull --arch", func() {
572
		session := podmanTest.Podman([]string{"pull", "-q", "--arch=bogus", ALPINE})
573
		session.WaitWithDefaultTimeout()
574
		Expect(session).Should(Exit(125))
575
		expectedError := "no image found in manifest list for architecture bogus"
576
		Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
577

578
		session = podmanTest.Podman([]string{"pull", "-q", "--arch=arm64", "--os", "windows", ALPINE})
579
		session.WaitWithDefaultTimeout()
580
		Expect(session).Should(Exit(125))
581
		expectedError = "no image found in manifest list for architecture"
582
		Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
583

584
		session = podmanTest.Podman([]string{"pull", "-q", "--arch=arm64", ALPINE})
585
		session.WaitWithDefaultTimeout()
586
		Expect(session).Should(ExitCleanly())
587

588
		setup := podmanTest.Podman([]string{"image", "inspect", session.OutputToString()})
589
		setup.WaitWithDefaultTimeout()
590
		Expect(setup).Should(ExitCleanly())
591

592
		data := setup.InspectImageJSON() // returns []inspect.ImageData
593
		Expect(data).To(HaveLen(1))
594
		Expect(data[0]).To(HaveField("Os", runtime.GOOS))
595
		Expect(data[0]).To(HaveField("Architecture", "arm64"))
596
	})
597

598
	It("podman pull progress", func() {
599
		session := podmanTest.Podman([]string{"pull", ALPINE})
600
		session.WaitWithDefaultTimeout()
601
		Expect(session).Should(Exit(0))
602
		output := session.ErrorToString()
603
		Expect(output).To(ContainSubstring("Getting image source signatures"))
604
		Expect(output).To(ContainSubstring("Copying blob "))
605

606
		session = podmanTest.Podman([]string{"pull", "-q", ALPINE})
607
		session.WaitWithDefaultTimeout()
608
		Expect(session).Should(ExitCleanly())
609
	})
610

611
	Describe("podman pull and decrypt", func() {
612

613
		decryptionTestHelper := func(imgPath string) *PodmanSessionIntegration {
614
			bitSize := 1024
615
			keyFileName := filepath.Join(podmanTest.TempDir, "key,withcomma")
616
			publicKeyFileName, privateKeyFileName, err := WriteRSAKeyPair(keyFileName, bitSize)
617
			Expect(err).ToNot(HaveOccurred())
618

619
			wrongKeyFileName := filepath.Join(podmanTest.TempDir, "wrong_key")
620
			_, wrongPrivateKeyFileName, err := WriteRSAKeyPair(wrongKeyFileName, bitSize)
621
			Expect(err).ToNot(HaveOccurred())
622

623
			session := podmanTest.Podman([]string{"push", "-q", "--encryption-key", "jwe:" + publicKeyFileName, "--tls-verify=false", "--remove-signatures", ALPINE, imgPath})
624
			session.WaitWithDefaultTimeout()
625

626
			session = podmanTest.Podman([]string{"rmi", ALPINE})
627
			session.WaitWithDefaultTimeout()
628
			Expect(session).Should(ExitCleanly())
629

630
			// Pulling encrypted image without key should fail
631
			session = podmanTest.Podman([]string{"pull", imgPath})
632
			session.WaitWithDefaultTimeout()
633
			Expect(session).Should(Exit(125))
634

635
			// Pulling encrypted image with wrong key should fail
636
			session = podmanTest.Podman([]string{"pull", "-q", "--decryption-key", wrongPrivateKeyFileName, "--tls-verify=false", imgPath})
637
			session.WaitWithDefaultTimeout()
638
			Expect(session).Should(Exit(125))
639

640
			// Pulling encrypted image with correct key should pass
641
			session = podmanTest.Podman([]string{"pull", "-q", "--decryption-key", privateKeyFileName, "--tls-verify=false", imgPath})
642
			session.WaitWithDefaultTimeout()
643
			Expect(session).Should(ExitCleanly())
644
			session = podmanTest.Podman([]string{"images"})
645
			session.WaitWithDefaultTimeout()
646
			Expect(session).Should(ExitCleanly())
647

648
			return session
649
		}
650

651
		It("From oci", func() {
652
			SkipIfRemote("Remote pull neither supports oci transport, nor decryption")
653

654
			podmanTest.AddImageToRWStore(ALPINE)
655

656
			bbdir := filepath.Join(podmanTest.TempDir, "busybox-oci")
657
			imgName := "localhost/name:tag"
658
			imgPath := fmt.Sprintf("oci:%s:%s", bbdir, imgName)
659

660
			session := decryptionTestHelper(imgPath)
661

662
			Expect(session.LineInOutputContainsTag("localhost/name", "tag")).To(BeTrue())
663
		})
664

665
		It("From local registry", func() {
666
			SkipIfRemote("Remote pull does not support decryption")
667

668
			if podmanTest.Host.Arch == "ppc64le" {
669
				Skip("No registry image for ppc64le")
670
			}
671

672
			podmanTest.AddImageToRWStore(ALPINE)
673

674
			if isRootless() {
675
				err := podmanTest.RestoreArtifact(REGISTRY_IMAGE)
676
				Expect(err).ToNot(HaveOccurred())
677
			}
678
			lock := GetPortLock("5012")
679
			defer lock.Unlock()
680
			session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5012:5000", REGISTRY_IMAGE, "/entrypoint.sh", "/etc/docker/registry/config.yml"})
681
			session.WaitWithDefaultTimeout()
682
			Expect(session).Should(ExitCleanly())
683

684
			if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) {
685
				Skip("Cannot start docker registry.")
686
			}
687

688
			imgPath := "localhost:5012/my-alpine"
689

690
			session = decryptionTestHelper(imgPath)
691

692
			Expect(session.LineInOutputContainsTag(imgPath, "latest")).To(BeTrue())
693
		})
694
	})
695

696
})
697

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.