github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/test/e2e/pull_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"runtime"
     8  
     9  	. "github.com/hanks177/podman/v4/test/utils"
    10  	. "github.com/onsi/ginkgo"
    11  	. "github.com/onsi/gomega"
    12  	. "github.com/onsi/gomega/gexec"
    13  )
    14  
    15  var _ = Describe("Podman pull", func() {
    16  	var (
    17  		tempdir    string
    18  		err        error
    19  		podmanTest *PodmanTestIntegration
    20  	)
    21  
    22  	BeforeEach(func() {
    23  		tempdir, err = CreateTempDirInTempDir()
    24  		if err != nil {
    25  			os.Exit(1)
    26  		}
    27  		podmanTest = PodmanTestCreate(tempdir)
    28  		podmanTest.Setup()
    29  	})
    30  
    31  	AfterEach(func() {
    32  		podmanTest.Cleanup()
    33  		f := CurrentGinkgoTestDescription()
    34  		processTestResult(f)
    35  
    36  	})
    37  
    38  	It("podman pull multiple images with/without tag/digest", func() {
    39  		session := podmanTest.Podman([]string{"pull", "busybox:musl", "alpine", "alpine:latest", "quay.io/libpod/cirros", "quay.io/libpod/testdigest_v2s2@sha256:755f4d90b3716e2bf57060d249e2cd61c9ac089b1233465c5c2cb2d7ee550fdb"})
    40  		session.WaitWithDefaultTimeout()
    41  		Expect(session).Should(Exit(0))
    42  
    43  		session = podmanTest.Podman([]string{"pull", "busybox:latest", "docker.io/library/ibetthisdoesnotexistfr:random", "alpine"})
    44  		session.WaitWithDefaultTimeout()
    45  		Expect(session).Should(Exit(125))
    46  		expectedError := "initializing source docker://ibetthisdoesnotexistfr:random"
    47  		found, _ := session.ErrorGrepString(expectedError)
    48  		Expect(found).To(Equal(true))
    49  
    50  		session = podmanTest.Podman([]string{"rmi", "busybox:musl", "alpine", "quay.io/libpod/cirros", "testdigest_v2s2@sha256:755f4d90b3716e2bf57060d249e2cd61c9ac089b1233465c5c2cb2d7ee550fdb"})
    51  		session.WaitWithDefaultTimeout()
    52  		Expect(session).Should(Exit(0))
    53  	})
    54  
    55  	It("podman pull bogus image", func() {
    56  		session := podmanTest.Podman([]string{"pull", "quay.io/ibetthis/doesntexistthere:foo"})
    57  		session.WaitWithDefaultTimeout()
    58  		Expect(session).To(ExitWithError())
    59  	})
    60  
    61  	It("podman pull with tag --quiet", func() {
    62  		session := podmanTest.Podman([]string{"pull", "-q", "quay.io/libpod/testdigest_v2s2:20200210"})
    63  		session.WaitWithDefaultTimeout()
    64  		Expect(session).Should(Exit(0))
    65  		quietOutput := session.OutputToString()
    66  
    67  		session = podmanTest.Podman([]string{"inspect", "testdigest_v2s2:20200210", "--format", "{{.ID}}"})
    68  		session.WaitWithDefaultTimeout()
    69  		Expect(session).Should(Exit(0))
    70  		Expect(session.OutputToString()).To(Equal(quietOutput))
    71  
    72  		session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2:20200210"})
    73  		session.WaitWithDefaultTimeout()
    74  		Expect(session).Should(Exit(0))
    75  	})
    76  
    77  	It("podman pull without tag", func() {
    78  		session := podmanTest.Podman([]string{"pull", "quay.io/libpod/testdigest_v2s2"})
    79  		session.WaitWithDefaultTimeout()
    80  		Expect(session).Should(Exit(0))
    81  
    82  		session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2"})
    83  		session.WaitWithDefaultTimeout()
    84  		Expect(session).Should(Exit(0))
    85  	})
    86  
    87  	It("podman pull by digest", func() {
    88  		session := podmanTest.Podman([]string{"pull", "quay.io/libpod/testdigest_v2s2@sha256:755f4d90b3716e2bf57060d249e2cd61c9ac089b1233465c5c2cb2d7ee550fdb"})
    89  		session.WaitWithDefaultTimeout()
    90  		Expect(session).Should(Exit(0))
    91  
    92  		// Without a tag/digest the input is normalized with the "latest" tag, see #11964
    93  		session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2"})
    94  		session.WaitWithDefaultTimeout()
    95  		Expect(session).Should(Exit(1))
    96  
    97  		session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2@sha256:755f4d90b3716e2bf57060d249e2cd61c9ac089b1233465c5c2cb2d7ee550fdb"})
    98  		session.WaitWithDefaultTimeout()
    99  		Expect(session).Should(Exit(0))
   100  	})
   101  
   102  	It("podman pull check all tags", func() {
   103  		session := podmanTest.Podman([]string{"pull", "--all-tags", "quay.io/libpod/testdigest_v2s2"})
   104  		session.WaitWithDefaultTimeout()
   105  		Expect(session).Should(Exit(0))
   106  
   107  		session = podmanTest.Podman([]string{"images"})
   108  		session.WaitWithDefaultTimeout()
   109  		Expect(session).Should(Exit(0))
   110  		Expect(len(session.OutputToStringArray())).To(BeNumerically(">=", 2), "Expected at least two images")
   111  	})
   112  
   113  	It("podman pull from docker with nonexistent --authfile", func() {
   114  		session := podmanTest.Podman([]string{"pull", "--authfile", "/tmp/nonexistent", ALPINE})
   115  		session.WaitWithDefaultTimeout()
   116  		Expect(session).To(ExitWithError())
   117  	})
   118  
   119  	It("podman pull by digest (image list)", func() {
   120  		session := podmanTest.Podman([]string{"pull", "--arch=arm64", ALPINELISTDIGEST})
   121  		session.WaitWithDefaultTimeout()
   122  		Expect(session).Should(Exit(0))
   123  		// inspect using the digest of the list
   124  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINELISTDIGEST})
   125  		session.WaitWithDefaultTimeout()
   126  		Expect(session).Should(Exit(0))
   127  		Expect(string(session.Out.Contents())).To(HavePrefix("[]"))
   128  		// inspect using the digest of the list
   129  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINELISTDIGEST})
   130  		session.WaitWithDefaultTimeout()
   131  		Expect(session).Should(Exit(0))
   132  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
   133  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
   134  		// inspect using the digest of the arch-specific image's manifest
   135  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64DIGEST})
   136  		session.WaitWithDefaultTimeout()
   137  		Expect(session).Should(Exit(0))
   138  		Expect(string(session.Out.Contents())).To(HavePrefix("[]"))
   139  		// inspect using the digest of the arch-specific image's manifest
   140  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64DIGEST})
   141  		session.WaitWithDefaultTimeout()
   142  		Expect(session).Should(Exit(0))
   143  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
   144  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
   145  		// inspect using the image ID
   146  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64ID})
   147  		session.WaitWithDefaultTimeout()
   148  		Expect(session).Should(Exit(0))
   149  		Expect(string(session.Out.Contents())).To(HavePrefix("[]"))
   150  		// inspect using the image ID
   151  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64ID})
   152  		session.WaitWithDefaultTimeout()
   153  		Expect(session).Should(Exit(0))
   154  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
   155  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
   156  		// remove using the digest of the list
   157  		session = podmanTest.Podman([]string{"rmi", ALPINELISTDIGEST})
   158  		session.WaitWithDefaultTimeout()
   159  		Expect(session).Should(Exit(0))
   160  	})
   161  
   162  	It("podman pull by instance digest (image list)", func() {
   163  		session := podmanTest.Podman([]string{"pull", "--arch=arm64", ALPINEARM64DIGEST})
   164  		session.WaitWithDefaultTimeout()
   165  		Expect(session).Should(Exit(0))
   166  		// inspect using the digest of the list
   167  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINELISTDIGEST})
   168  		session.WaitWithDefaultTimeout()
   169  		Expect(session).To(ExitWithError())
   170  		// inspect using the digest of the list
   171  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINELISTDIGEST})
   172  		session.WaitWithDefaultTimeout()
   173  		Expect(session).To(ExitWithError())
   174  		// inspect using the digest of the arch-specific image's manifest
   175  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64DIGEST})
   176  		session.WaitWithDefaultTimeout()
   177  		Expect(session).Should(Exit(0))
   178  		Expect(string(session.Out.Contents())).To(HavePrefix("[]"))
   179  		// inspect using the digest of the arch-specific image's manifest
   180  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64DIGEST})
   181  		session.WaitWithDefaultTimeout()
   182  		Expect(session).Should(Exit(0))
   183  		Expect(string(session.Out.Contents())).To(Not(ContainSubstring(ALPINELISTDIGEST)))
   184  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
   185  		// inspect using the image ID
   186  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64ID})
   187  		session.WaitWithDefaultTimeout()
   188  		Expect(session).Should(Exit(0))
   189  		Expect(string(session.Out.Contents())).To(HavePrefix("[]"))
   190  		// inspect using the image ID
   191  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64ID})
   192  		session.WaitWithDefaultTimeout()
   193  		Expect(session).Should(Exit(0))
   194  		Expect(string(session.Out.Contents())).To(Not(ContainSubstring(ALPINELISTDIGEST)))
   195  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
   196  		// remove using the digest of the instance
   197  		session = podmanTest.Podman([]string{"rmi", ALPINEARM64DIGEST})
   198  		session.WaitWithDefaultTimeout()
   199  		Expect(session).Should(Exit(0))
   200  	})
   201  
   202  	It("podman pull by tag (image list)", func() {
   203  		session := podmanTest.Podman([]string{"pull", "--arch=arm64", ALPINELISTTAG})
   204  		session.WaitWithDefaultTimeout()
   205  		Expect(session).Should(Exit(0))
   206  		// inspect using the tag we used for pulling
   207  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINELISTTAG})
   208  		session.WaitWithDefaultTimeout()
   209  		Expect(session).Should(Exit(0))
   210  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG))
   211  		// inspect using the tag we used for pulling
   212  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINELISTTAG})
   213  		session.WaitWithDefaultTimeout()
   214  		Expect(session).Should(Exit(0))
   215  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
   216  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
   217  		// inspect using the digest of the list
   218  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINELISTDIGEST})
   219  		session.WaitWithDefaultTimeout()
   220  		Expect(session).Should(Exit(0))
   221  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG))
   222  		// inspect using the digest of the list
   223  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINELISTDIGEST})
   224  		session.WaitWithDefaultTimeout()
   225  		Expect(session).Should(Exit(0))
   226  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
   227  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
   228  		// inspect using the digest of the arch-specific image's manifest
   229  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64DIGEST})
   230  		session.WaitWithDefaultTimeout()
   231  		Expect(session).Should(Exit(0))
   232  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG))
   233  		// inspect using the digest of the arch-specific image's manifest
   234  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64DIGEST})
   235  		session.WaitWithDefaultTimeout()
   236  		Expect(session).Should(Exit(0))
   237  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
   238  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
   239  		// inspect using the image ID
   240  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoTags}}", ALPINEARM64ID})
   241  		session.WaitWithDefaultTimeout()
   242  		Expect(session).Should(Exit(0))
   243  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG))
   244  		// inspect using the image ID
   245  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RepoDigests}}", ALPINEARM64ID})
   246  		session.WaitWithDefaultTimeout()
   247  		Expect(session).Should(Exit(0))
   248  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST))
   249  		Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST))
   250  		// remove using the tag
   251  		session = podmanTest.Podman([]string{"rmi", ALPINELISTTAG})
   252  		session.WaitWithDefaultTimeout()
   253  		Expect(session).Should(Exit(0))
   254  	})
   255  
   256  	It("podman pull from docker-archive", func() {
   257  		SkipIfRemote("podman-remote does not support pulling from docker-archive")
   258  
   259  		podmanTest.AddImageToRWStore(cirros)
   260  		tarfn := filepath.Join(podmanTest.TempDir, "cirros.tar")
   261  		session := podmanTest.Podman([]string{"save", "-o", tarfn, "cirros"})
   262  		session.WaitWithDefaultTimeout()
   263  
   264  		Expect(session).Should(Exit(0))
   265  		session = podmanTest.Podman([]string{"rmi", "cirros"})
   266  		session.WaitWithDefaultTimeout()
   267  		Expect(session).Should(Exit(0))
   268  		session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:%s", tarfn)})
   269  		session.WaitWithDefaultTimeout()
   270  		Expect(session).Should(Exit(0))
   271  		session = podmanTest.Podman([]string{"rmi", "cirros"})
   272  		session.WaitWithDefaultTimeout()
   273  		Expect(session).Should(Exit(0))
   274  
   275  		// Pulling a multi-image archive without further specifying
   276  		// which image _must_ error out. Pulling is restricted to one
   277  		// image.
   278  		session = podmanTest.Podman([]string{"pull", "docker-archive:./testdata/docker-two-images.tar.xz"})
   279  		session.WaitWithDefaultTimeout()
   280  		Expect(session).Should(Exit(125))
   281  		expectedError := "Unexpected tar manifest.json: expected 1 item, got 2"
   282  		found, _ := session.ErrorGrepString(expectedError)
   283  		Expect(found).To(Equal(true))
   284  
   285  		// Now pull _one_ image from a multi-image archive via the name
   286  		// and index syntax.
   287  		session = podmanTest.Podman([]string{"pull", "docker-archive:./testdata/docker-two-images.tar.xz:@0"})
   288  		session.WaitWithDefaultTimeout()
   289  		Expect(session).Should(Exit(0))
   290  
   291  		session = podmanTest.Podman([]string{"pull", "docker-archive:./testdata/docker-two-images.tar.xz:example.com/empty:latest"})
   292  		session.WaitWithDefaultTimeout()
   293  		Expect(session).Should(Exit(0))
   294  
   295  		session = podmanTest.Podman([]string{"pull", "docker-archive:./testdata/docker-two-images.tar.xz:@1"})
   296  		session.WaitWithDefaultTimeout()
   297  		Expect(session).Should(Exit(0))
   298  
   299  		session = podmanTest.Podman([]string{"pull", "docker-archive:./testdata/docker-two-images.tar.xz:example.com/empty/but:different"})
   300  		session.WaitWithDefaultTimeout()
   301  		Expect(session).Should(Exit(0))
   302  
   303  		// Now check for some errors.
   304  		session = podmanTest.Podman([]string{"pull", "docker-archive:./testdata/docker-two-images.tar.xz:foo.com/does/not/exist:latest"})
   305  		session.WaitWithDefaultTimeout()
   306  		Expect(session).Should(Exit(125))
   307  		expectedError = "Tag \"foo.com/does/not/exist:latest\" not found"
   308  		found, _ = session.ErrorGrepString(expectedError)
   309  		Expect(found).To(Equal(true))
   310  
   311  		session = podmanTest.Podman([]string{"pull", "docker-archive:./testdata/docker-two-images.tar.xz:@2"})
   312  		session.WaitWithDefaultTimeout()
   313  		Expect(session).Should(Exit(125))
   314  		expectedError = "Invalid source index @2, only 2 manifest items available"
   315  		found, _ = session.ErrorGrepString(expectedError)
   316  		Expect(found).To(Equal(true))
   317  	})
   318  
   319  	It("podman pull from oci-archive", func() {
   320  		SkipIfRemote("podman-remote does not support pulling from oci-archive")
   321  
   322  		podmanTest.AddImageToRWStore(cirros)
   323  		tarfn := filepath.Join(podmanTest.TempDir, "oci-cirrus.tar")
   324  		session := podmanTest.Podman([]string{"save", "--format", "oci-archive", "-o", tarfn, "cirros"})
   325  		session.WaitWithDefaultTimeout()
   326  
   327  		Expect(session).Should(Exit(0))
   328  		session = podmanTest.Podman([]string{"rmi", "cirros"})
   329  		session.WaitWithDefaultTimeout()
   330  		Expect(session).Should(Exit(0))
   331  		session = podmanTest.Podman([]string{"pull", fmt.Sprintf("oci-archive:%s", tarfn)})
   332  		session.WaitWithDefaultTimeout()
   333  		Expect(session).Should(Exit(0))
   334  		session = podmanTest.Podman([]string{"rmi", "cirros"})
   335  		session.WaitWithDefaultTimeout()
   336  		Expect(session).Should(Exit(0))
   337  	})
   338  
   339  	It("podman pull from local directory", func() {
   340  		SkipIfRemote("podman-remote does not support pulling from local directory")
   341  
   342  		podmanTest.AddImageToRWStore(cirros)
   343  		dirpath := filepath.Join(podmanTest.TempDir, "cirros")
   344  		err = os.MkdirAll(dirpath, os.ModePerm)
   345  		Expect(err).ToNot(HaveOccurred())
   346  		imgPath := fmt.Sprintf("dir:%s", dirpath)
   347  
   348  		session := podmanTest.Podman([]string{"push", "cirros", imgPath})
   349  		session.WaitWithDefaultTimeout()
   350  		Expect(session).Should(Exit(0))
   351  		session = podmanTest.Podman([]string{"rmi", "cirros"})
   352  		session.WaitWithDefaultTimeout()
   353  		Expect(session).Should(Exit(0))
   354  		session = podmanTest.Podman([]string{"run", imgPath, "ls"})
   355  		session.WaitWithDefaultTimeout()
   356  		Expect(session).Should(Exit(0))
   357  		// Note that reference is not preserved in dir.
   358  		session = podmanTest.Podman([]string{"image", "exists", "cirros"})
   359  		session.WaitWithDefaultTimeout()
   360  		Expect(session).Should(Exit(1))
   361  	})
   362  
   363  	It("podman pull from local OCI directory", func() {
   364  		SkipIfRemote("podman-remote does not support pulling from OCI directory")
   365  
   366  		podmanTest.AddImageToRWStore(cirros)
   367  		dirpath := filepath.Join(podmanTest.TempDir, "cirros")
   368  		err = os.MkdirAll(dirpath, os.ModePerm)
   369  		Expect(err).ToNot(HaveOccurred())
   370  		imgPath := fmt.Sprintf("oci:%s", dirpath)
   371  
   372  		session := podmanTest.Podman([]string{"push", "cirros", imgPath})
   373  		session.WaitWithDefaultTimeout()
   374  		Expect(session).Should(Exit(0))
   375  		session = podmanTest.Podman([]string{"rmi", "cirros"})
   376  		session.WaitWithDefaultTimeout()
   377  		Expect(session).Should(Exit(0))
   378  		session = podmanTest.Podman([]string{"pull", imgPath})
   379  		session.WaitWithDefaultTimeout()
   380  		Expect(session).Should(Exit(0))
   381  		session = podmanTest.Podman([]string{"images"})
   382  		session.WaitWithDefaultTimeout()
   383  		Expect(session).Should(Exit(0))
   384  		Expect(session.LineInOutputContainsTag(filepath.Join("localhost", dirpath), "latest")).To(BeTrue())
   385  	})
   386  
   387  	It("podman pull + inspect from unqualified-search registry", func() {
   388  		// Regression test for #6381:
   389  		// Make sure that `pull shortname` and `inspect shortname`
   390  		// refer to the same image.
   391  
   392  		// We already tested pulling, so we can save some energy and
   393  		// just restore local artifacts and tag them.
   394  		err := podmanTest.RestoreArtifact(ALPINE)
   395  		Expect(err).ToNot(HaveOccurred())
   396  		err = podmanTest.RestoreArtifact(BB)
   397  		Expect(err).ToNot(HaveOccurred())
   398  
   399  		// What we want is at least two images which have the same name
   400  		// and are prefixed with two different unqualified-search
   401  		// registries from ../registries.conf.
   402  		//
   403  		// A `podman inspect $name` must yield the one from the _first_
   404  		// matching registry in the registries.conf.
   405  		getID := func(image string) string {
   406  			setup := podmanTest.Podman([]string{"image", "inspect", image})
   407  			setup.WaitWithDefaultTimeout()
   408  			Expect(setup).Should(Exit(0))
   409  
   410  			data := setup.InspectImageJSON() // returns []inspect.ImageData
   411  			Expect(data).To(HaveLen(1))
   412  			return data[0].ID
   413  		}
   414  
   415  		untag := func(image string) {
   416  			setup := podmanTest.Podman([]string{"untag", image})
   417  			setup.WaitWithDefaultTimeout()
   418  			Expect(setup).Should(Exit(0))
   419  
   420  			setup = podmanTest.Podman([]string{"image", "inspect", image})
   421  			setup.WaitWithDefaultTimeout()
   422  			Expect(setup).Should(Exit(0))
   423  
   424  			data := setup.InspectImageJSON() // returns []inspect.ImageData
   425  			Expect(data).To(HaveLen(1))
   426  			Expect(data[0].RepoTags).To(BeEmpty())
   427  		}
   428  
   429  		tag := func(image, tag string) {
   430  			setup := podmanTest.Podman([]string{"tag", image, tag})
   431  			setup.WaitWithDefaultTimeout()
   432  			Expect(setup).Should(Exit(0))
   433  			setup = podmanTest.Podman([]string{"image", "exists", tag})
   434  			setup.WaitWithDefaultTimeout()
   435  			Expect(setup).Should(Exit(0))
   436  		}
   437  
   438  		image1 := getID(ALPINE)
   439  		image2 := getID(BB)
   440  
   441  		// $ head -n2 ../registries.conf
   442  		// [registries.search]
   443  		// registries = ['docker.io', 'quay.io', 'registry.fedoraproject.org']
   444  		registries := []string{"docker.io", "quay.io", "registry.fedoraproject.org"}
   445  		name := "foo/test:tag"
   446  		tests := []struct {
   447  			// tag1 has precedence (see list above) over tag2 when
   448  			// doing an inspect on "test:tag".
   449  			tag1, tag2 string
   450  		}{
   451  			{
   452  				fmt.Sprintf("%s/%s", registries[0], name),
   453  				fmt.Sprintf("%s/%s", registries[1], name),
   454  			},
   455  			{
   456  				fmt.Sprintf("%s/%s", registries[0], name),
   457  				fmt.Sprintf("%s/%s", registries[2], name),
   458  			},
   459  			{
   460  				fmt.Sprintf("%s/%s", registries[1], name),
   461  				fmt.Sprintf("%s/%s", registries[2], name),
   462  			},
   463  		}
   464  
   465  		for _, t := range tests {
   466  			// 1) untag both images
   467  			// 2) tag them according to `t`
   468  			// 3) make sure that an inspect of `name` returns `image1` with `tag1`
   469  			untag(image1)
   470  			untag(image2)
   471  			tag(image1, t.tag1)
   472  			tag(image2, t.tag2)
   473  
   474  			setup := podmanTest.Podman([]string{"image", "inspect", name})
   475  			setup.WaitWithDefaultTimeout()
   476  			Expect(setup).Should(Exit(0))
   477  
   478  			data := setup.InspectImageJSON() // returns []inspect.ImageData
   479  			Expect(data).To(HaveLen(1))
   480  			Expect(data[0].RepoTags).To(HaveLen(1))
   481  			Expect(data[0].RepoTags[0]).To(Equal(t.tag1))
   482  			Expect(data[0]).To(HaveField("ID", image1))
   483  		}
   484  	})
   485  
   486  	It("podman pull --platform", func() {
   487  		session := podmanTest.Podman([]string{"pull", "--platform=linux/bogus", ALPINE})
   488  		session.WaitWithDefaultTimeout()
   489  		Expect(session).Should(Exit(125))
   490  		expectedError := "no image found in manifest list for architecture bogus"
   491  		Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
   492  
   493  		session = podmanTest.Podman([]string{"pull", "--platform=linux/arm64", "--os", "windows", ALPINE})
   494  		session.WaitWithDefaultTimeout()
   495  		Expect(session).Should(Exit(125))
   496  		expectedError = "--platform option can not be specified with --arch or --os"
   497  		Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
   498  
   499  		session = podmanTest.Podman([]string{"pull", "-q", "--platform=linux/arm64", ALPINE})
   500  		session.WaitWithDefaultTimeout()
   501  		Expect(session).Should(Exit(0))
   502  
   503  		setup := podmanTest.Podman([]string{"image", "inspect", session.OutputToString()})
   504  		setup.WaitWithDefaultTimeout()
   505  		Expect(setup).Should(Exit(0))
   506  
   507  		data := setup.InspectImageJSON() // returns []inspect.ImageData
   508  		Expect(data).To(HaveLen(1))
   509  		Expect(data[0]).To(HaveField("Os", runtime.GOOS))
   510  		Expect(data[0]).To(HaveField("Architecture", "arm64"))
   511  	})
   512  
   513  	It("podman pull --arch", func() {
   514  		session := podmanTest.Podman([]string{"pull", "--arch=bogus", ALPINE})
   515  		session.WaitWithDefaultTimeout()
   516  		Expect(session).Should(Exit(125))
   517  		expectedError := "no image found in manifest list for architecture bogus"
   518  		Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
   519  
   520  		session = podmanTest.Podman([]string{"pull", "--arch=arm64", "--os", "windows", ALPINE})
   521  		session.WaitWithDefaultTimeout()
   522  		Expect(session).Should(Exit(125))
   523  		expectedError = "no image found in manifest list for architecture"
   524  		Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
   525  
   526  		session = podmanTest.Podman([]string{"pull", "-q", "--arch=arm64", ALPINE})
   527  		session.WaitWithDefaultTimeout()
   528  		Expect(session).Should(Exit(0))
   529  
   530  		setup := podmanTest.Podman([]string{"image", "inspect", session.OutputToString()})
   531  		setup.WaitWithDefaultTimeout()
   532  		Expect(setup).Should(Exit(0))
   533  
   534  		data := setup.InspectImageJSON() // returns []inspect.ImageData
   535  		Expect(data).To(HaveLen(1))
   536  		Expect(data[0]).To(HaveField("Os", runtime.GOOS))
   537  		Expect(data[0]).To(HaveField("Architecture", "arm64"))
   538  	})
   539  })