diff options
-rw-r--r-- | cmd/podman/containers/clone.go | 2 | ||||
-rw-r--r-- | cmd/podman/containers/create.go | 5 | ||||
-rw-r--r-- | cmd/podman/containers/run.go | 5 | ||||
-rw-r--r-- | pkg/specgen/generate/container.go | 11 | ||||
-rw-r--r-- | pkg/specgen/specgen.go | 6 | ||||
-rw-r--r-- | test/e2e/build/Containerfile.with-platform | 1 | ||||
-rw-r--r-- | test/e2e/run_test.go | 22 |
7 files changed, 47 insertions, 5 deletions
diff --git a/cmd/podman/containers/clone.go b/cmd/podman/containers/clone.go index f8d5a2d80..9881a791c 100644 --- a/cmd/podman/containers/clone.go +++ b/cmd/podman/containers/clone.go @@ -63,7 +63,7 @@ func clone(cmd *cobra.Command, args []string) error { ctrClone.Image = args[2] if !cliVals.RootFS { rawImageName := args[0] - name, err := PullImage(ctrClone.Image, ctrClone.CreateOpts) + name, err := PullImage(ctrClone.Image, &ctrClone.CreateOpts) if err != nil { return err } diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go index aa7040bcc..05a59ce7b 100644 --- a/cmd/podman/containers/create.go +++ b/cmd/podman/containers/create.go @@ -141,7 +141,7 @@ func create(cmd *cobra.Command, args []string) error { rawImageName := "" if !cliVals.RootFS { rawImageName = args[0] - name, err := PullImage(args[0], cliVals) + name, err := PullImage(args[0], &cliVals) if err != nil { return err } @@ -305,7 +305,8 @@ func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra return vals, nil } -func PullImage(imageName string, cliVals entities.ContainerCreateOptions) (string, error) { +// Pulls image if any also parses and populates OS, Arch and Variant in specified container create options +func PullImage(imageName string, cliVals *entities.ContainerCreateOptions) (string, error) { pullPolicy, err := config.ParsePullPolicy(cliVals.Pull) if err != nil { return "", err diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go index 1176b866d..ef13ea95e 100644 --- a/cmd/podman/containers/run.go +++ b/cmd/podman/containers/run.go @@ -141,7 +141,7 @@ func run(cmd *cobra.Command, args []string) error { rawImageName := "" if !cliVals.RootFS { rawImageName = args[0] - name, err := PullImage(args[0], cliVals) + name, err := PullImage(args[0], &cliVals) if err != nil { return err } @@ -192,6 +192,9 @@ func run(cmd *cobra.Command, args []string) error { return err } s.RawImageName = rawImageName + s.ImageOS = cliVals.OS + s.ImageArch = cliVals.Arch + s.ImageVariant = cliVals.Variant s.Passwd = &runOpts.Passwd runOpts.Spec = s diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go index 30c759495..8fdd87adf 100644 --- a/pkg/specgen/generate/container.go +++ b/pkg/specgen/generate/container.go @@ -38,10 +38,19 @@ func getImageFromSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGen } // Need to look up image. - image, resolvedName, err := r.LibimageRuntime().LookupImage(s.Image, nil) + lookupOptions := &libimage.LookupImageOptions{ManifestList: true} + image, resolvedName, err := r.LibimageRuntime().LookupImage(s.Image, lookupOptions) if err != nil { return nil, "", nil, err } + manifestList, err := image.ToManifestList() + // only process if manifest list found otherwise expect it to be regular image + if err == nil { + image, err = manifestList.LookupInstance(ctx, s.ImageArch, s.ImageOS, s.ImageVariant) + if err != nil { + return nil, "", nil, err + } + } s.SetImage(image, resolvedName) inspectData, err := image.Inspect(ctx, nil) if err != nil { diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go index 79e20667b..42b89ece1 100644 --- a/pkg/specgen/specgen.go +++ b/pkg/specgen/specgen.go @@ -103,6 +103,12 @@ type ContainerBasicConfig struct { // RawImageName is the user-specified and unprocessed input referring // to a local or a remote image. RawImageName string `json:"raw_image_name,omitempty"` + // ImageOS is the user-specified image OS + ImageOS string `json:"image_os,omitempty"` + // ImageArch is the user-specified image architecture + ImageArch string `json:"image_arch,omitempty"` + // ImageVariant is the user-specified image variant + ImageVariant string `json:"image_variant,omitempty"` // RestartPolicy is the container's restart policy - an action which // will be taken when the container exits. // If not given, the default policy, which does nothing, will be used. diff --git a/test/e2e/build/Containerfile.with-platform b/test/e2e/build/Containerfile.with-platform new file mode 100644 index 000000000..3bb585a0a --- /dev/null +++ b/test/e2e/build/Containerfile.with-platform @@ -0,0 +1 @@ +FROM --platform=$TARGETPLATFORM alpine diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 42b01bdcc..2aa5a78db 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -73,6 +73,28 @@ var _ = Describe("Podman run", func() { Expect(session.OutputToString()).To(ContainSubstring("graphRootMounted=1")) }) + It("podman run from manifest list", func() { + session := podmanTest.Podman([]string{"manifest", "create", "localhost/test:latest"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"build", "-f", "build/Containerfile.with-platform", "--platform", "linux/amd64,linux/arm64", "--manifest", "localhost/test:latest"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"run", "--platform", "linux/arm64", "localhost/test", "uname", "-a"}) + session.WaitWithDefaultTimeout() + exitCode := session.ExitCode() + // CI could either support requested platform or not, if it supports then output should contain `aarch64` + // if not run should fail with a very specific error i.e `Exec format error` anything other than this should + // be marked as failure of test. + if exitCode == 0 { + Expect(session.OutputToString()).To(ContainSubstring("aarch64")) + } else { + Expect(session.ErrorToString()).To(ContainSubstring("Exec format error")) + } + }) + It("podman run a container based on a complex local image name", func() { imageName := strings.TrimPrefix(nginx, "quay.io/") session := podmanTest.Podman([]string{"run", imageName, "ls"}) |