From 2fcd1d7b4dca2619277607da7c8d22e9ec7620a2 Mon Sep 17 00:00:00 2001 From: Qi Wang Date: Sun, 13 Sep 2020 15:40:41 -0400 Subject: Supports import&run--signature-policy Enables podman create, pull, run, import to use --signature-policy option. Set it as hidden flag to be consistent with other commands. Signed-off-by: Qi Wang --- cmd/podman/common/create.go | 5 +++++ cmd/podman/common/create_opts.go | 1 + cmd/podman/containers/create.go | 2 ++ cmd/podman/containers/run.go | 1 + cmd/podman/images/import.go | 2 ++ libpod/image/image.go | 2 +- libpod/image/pull.go | 3 +++ libpod/runtime_img.go | 3 ++- pkg/api/handlers/compat/images.go | 2 +- pkg/api/handlers/libpod/images.go | 2 +- pkg/domain/entities/images.go | 13 +++++++------ pkg/domain/infra/abi/images.go | 2 +- test/e2e/create_test.go | 11 +++++++++++ test/e2e/import_test.go | 17 +++++++++++++++++ test/e2e/run_test.go | 11 +++++++++++ 15 files changed, 66 insertions(+), 11 deletions(-) diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go index 2b6f9348e..cfbcf6140 100644 --- a/cmd/podman/common/create.go +++ b/cmd/podman/common/create.go @@ -415,6 +415,11 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { "shm-size", containerConfig.ShmSize(), "Size of /dev/shm "+sizeWithUnitFormat, ) + createFlags.StringVar( + &cf.SignaturePolicy, + "signature-policy", "", + "`Pathname` of signature policy file (not usually used)", + ) createFlags.StringVar( &cf.StopSignal, "stop-signal", "", diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go index 1b0e64590..83a25f4ab 100644 --- a/cmd/podman/common/create_opts.go +++ b/cmd/podman/common/create_opts.go @@ -84,6 +84,7 @@ type ContainerCLIOpts struct { SecurityOpt []string SdNotifyMode string ShmSize string + SignaturePolicy string StopSignal string StopTimeout uint StoreageOpt []string diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go index f9d33a223..795b56d6a 100644 --- a/cmd/podman/containers/create.go +++ b/cmd/podman/containers/create.go @@ -61,6 +61,7 @@ func createFlags(flags *pflag.FlagSet) { flags.AddFlagSet(common.GetNetFlags()) flags.SetNormalizeFunc(utils.AliasFlags) + _ = flags.MarkHidden("signature-policy") if registry.IsRemote() { _ = flags.MarkHidden("authfile") _ = flags.MarkHidden("env-host") @@ -256,6 +257,7 @@ func pullImage(imageName string) (string, error) { OverrideArch: cliVals.OverrideArch, OverrideOS: cliVals.OverrideOS, OverrideVariant: cliVals.OverrideVariant, + SignaturePolicy: cliVals.SignaturePolicy, }) if pullErr != nil { return "", pullErr diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go index 34eea14e1..ce144a32d 100644 --- a/cmd/podman/containers/run.go +++ b/cmd/podman/containers/run.go @@ -64,6 +64,7 @@ func runFlags(flags *pflag.FlagSet) { flags.BoolVar(&runRmi, "rmi", false, "Remove container image unless used by other containers") flags.UintVar(&runOpts.PreserveFDs, "preserve-fds", 0, "Pass a number of additional file descriptors into the container") + _ = flags.MarkHidden("signature-policy") if registry.IsRemote() { _ = flags.MarkHidden("authfile") _ = flags.MarkHidden("env-host") diff --git a/cmd/podman/images/import.go b/cmd/podman/images/import.go index e605ddfc6..1c234e743 100644 --- a/cmd/podman/images/import.go +++ b/cmd/podman/images/import.go @@ -63,6 +63,8 @@ func importFlags(flags *pflag.FlagSet) { flags.StringArrayVarP(&importOpts.Changes, "change", "c", []string{}, "Apply the following possible instructions to the created image (default []): CMD | ENTRYPOINT | ENV | EXPOSE | LABEL | STOPSIGNAL | USER | VOLUME | WORKDIR") flags.StringVarP(&importOpts.Message, "message", "m", "", "Set commit message for imported image") flags.BoolVarP(&importOpts.Quiet, "quiet", "q", false, "Suppress output") + flags.StringVar(&importOpts.SignaturePolicy, "signature-policy", "", "Path to a signature-policy file") + _ = flags.MarkHidden("signature-policy") } func importCon(cmd *cobra.Command, args []string) error { diff --git a/libpod/image/image.go b/libpod/image/image.go index 850a48eae..5dfb33afb 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -1284,7 +1284,7 @@ func (ir *Runtime) Import(ctx context.Context, path, reference string, writer io return nil, errors.Wrapf(err, "error updating image config") } - sc := GetSystemContext("", "", false) + sc := GetSystemContext(ir.SignaturePolicyPath, "", false) // if reference not given, get the image digest if reference == "" { diff --git a/libpod/image/pull.go b/libpod/image/pull.go index 94d6af4c2..65acdf427 100644 --- a/libpod/image/pull.go +++ b/libpod/image/pull.go @@ -255,6 +255,9 @@ func (ir *Runtime) pullImageFromHeuristicSource(ctx context.Context, inputName s sc.ArchitectureChoice = dockerOptions.ArchitectureChoice sc.VariantChoice = dockerOptions.VariantChoice } + if signaturePolicyPath == "" { + sc.SignaturePolicyPath = ir.SignaturePolicyPath + } sc.BlobInfoCacheDir = filepath.Join(ir.store.GraphRoot(), "cache") srcRef, err := alltransports.ParseImageName(inputName) if err != nil { diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index eb4512f8d..e57890fa2 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -174,7 +174,7 @@ func (r *Runtime) Build(ctx context.Context, options imagebuildah.BuildOptions, } // Import is called as an intermediary to the image library Import -func (r *Runtime) Import(ctx context.Context, source string, reference string, changes []string, history string, quiet bool) (string, error) { +func (r *Runtime) Import(ctx context.Context, source, reference, signaturePolicyPath string, changes []string, history string, quiet bool) (string, error) { var ( writer io.Writer err error @@ -223,6 +223,7 @@ func (r *Runtime) Import(ctx context.Context, source string, reference string, c source = file } + r.imageRuntime.SignaturePolicyPath = signaturePolicyPath newImage, err := r.imageRuntime.Import(ctx, source, reference, writer, image.SigningOptions{}, config) if err != nil { return "", err diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index 8765e20ca..c1ba9ca66 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -205,7 +205,7 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file")) } } - iid, err := runtime.Import(r.Context(), source, "", query.Changes, "", false) + iid, err := runtime.Import(r.Context(), source, "", "", query.Changes, "", false) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to import tarball")) return diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index 85f7903dc..1da41ad88 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -391,7 +391,7 @@ func ImagesImport(w http.ResponseWriter, r *http.Request) { tmpfile.Close() source = tmpfile.Name() } - importedImage, err := runtime.Import(context.Background(), source, query.Reference, query.Changes, query.Message, true) + importedImage, err := runtime.Import(context.Background(), source, query.Reference, "", query.Changes, query.Message, true) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to import image")) return diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index 2a8133680..3a2e762d6 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -259,12 +259,13 @@ type ImageLoadReport struct { } type ImageImportOptions struct { - Changes []string - Message string - Quiet bool - Reference string - Source string - SourceIsURL bool + Changes []string + Message string + Quiet bool + Reference string + SignaturePolicy string + Source string + SourceIsURL bool } type ImageImportReport struct { diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index cc3ec37fb..cc62c3f27 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -467,7 +467,7 @@ func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions) } func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOptions) (*entities.ImageImportReport, error) { - id, err := ir.Libpod.Import(ctx, opts.Source, opts.Reference, opts.Changes, opts.Message, opts.Quiet) + id, err := ir.Libpod.Import(ctx, opts.Source, opts.Reference, opts.SignaturePolicy, opts.Changes, opts.Message, opts.Quiet) if err != nil { return nil, err } diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index 9cfed263a..6022be5f6 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -345,6 +345,17 @@ var _ = Describe("Podman create", func() { Expect(session).To(Not(Equal(0))) }) + It("podman create --signature-policy", func() { + SkipIfRemote() // SigPolicy not handled by remote + session := podmanTest.Podman([]string{"create", "--pull=always", "--signature-policy", "/no/such/file", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Not(Equal(0))) + + session = podmanTest.Podman([]string{"create", "--pull=always", "--signature-policy", "/etc/containers/policy.json", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + }) + It("podman create with unset label", func() { // Alpine is assumed to have no labels here, which seems safe ctrName := "testctr" diff --git a/test/e2e/import_test.go b/test/e2e/import_test.go index feedb2a31..9c6f4381d 100644 --- a/test/e2e/import_test.go +++ b/test/e2e/import_test.go @@ -152,4 +152,21 @@ var _ = Describe("Podman import", func() { Expect(imageData[0].Config.Cmd[0]).To(Equal("/bin/bash")) }) + It("podman import with signature", func() { + outfile := filepath.Join(podmanTest.TempDir, "container.tar") + _, ec, cid := podmanTest.RunLsContainer("") + Expect(ec).To(Equal(0)) + + export := podmanTest.Podman([]string{"export", "-o", outfile, cid}) + export.WaitWithDefaultTimeout() + Expect(export.ExitCode()).To(Equal(0)) + + importImage := podmanTest.Podman([]string{"import", "--signature-policy", "/no/such/file", outfile}) + importImage.WaitWithDefaultTimeout() + Expect(importImage.ExitCode()).To(Not(Equal(0))) + + result := podmanTest.Podman([]string{"import", "--signature-policy", "/etc/containers/policy.json", outfile}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + }) }) diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index a67f7df92..cbfb6bf59 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -58,6 +58,17 @@ var _ = Describe("Podman run", func() { Expect(session.ExitCode()).To(Equal(0)) }) + It("podman run --signature-policy", func() { + SkipIfRemote() // SigPolicy not handled by remote + session := podmanTest.Podman([]string{"run", "--pull=always", "--signature-policy", "/no/such/file", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Not(Equal(0))) + + session = podmanTest.Podman([]string{"run", "--pull=always", "--signature-policy", "/etc/containers/policy.json", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + }) + It("podman run a container based on on a short name with localhost", func() { tag := podmanTest.Podman([]string{"tag", nginx, "localhost/libpod/alpine_nginx:latest"}) tag.WaitWithDefaultTimeout() -- cgit v1.2.3-54-g00ecf