From 6b0864434ad2780160c06ba607c76b0325b60175 Mon Sep 17 00:00:00 2001 From: Qi Wang Date: Fri, 21 Aug 2020 13:56:50 -0400 Subject: [PATCH] Add global options --runtime-flags Add global options --runtime-flags for setting options to container runtime. Signed-off-by: Qi Wang --- cmd/podman/images/build.go | 3 +++ cmd/podman/root.go | 1 + docs/source/markdown/podman-build.1.md | 10 ---------- docs/source/markdown/podman.1.md | 12 +++++++++++- libpod/oci_conmon_linux.go | 25 ++++++++++++++++++------- libpod/oci_conmon_unsupported.go | 2 +- libpod/options.go | 11 +++++++++++ libpod/runtime.go | 5 +++-- pkg/domain/entities/engine.go | 1 + pkg/domain/infra/runtime_libpod.go | 8 ++++++++ test/system/030-run.bats | 6 ++++++ test/system/070-build.bats | 19 ++++++++++++++++++- 12 files changed, 81 insertions(+), 22 deletions(-) diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go index 400f960cce..6b8b5cedfd 100644 --- a/cmd/podman/images/build.go +++ b/cmd/podman/images/build.go @@ -382,6 +382,9 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil } containerConfig := registry.PodmanConfig() + for _, arg := range containerConfig.RuntimeFlags { + runtimeFlags = append(runtimeFlags, "--"+arg) + } if containerConfig.Engine.CgroupManager == config.SystemdCgroupsManager { runtimeFlags = append(runtimeFlags, "--systemd-cgroup") } diff --git a/cmd/podman/root.go b/cmd/podman/root.go index 749a5fbe73..a55239a3e3 100644 --- a/cmd/podman/root.go +++ b/cmd/podman/root.go @@ -273,6 +273,7 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) { pFlags.StringVar(&opts.RegistriesConf, "registries-conf", "", "Path to a registries.conf to use for image processing") pFlags.StringVar(&opts.Runroot, "runroot", "", "Path to the 'run directory' where all state information is stored") pFlags.StringVar(&opts.RuntimePath, "runtime", "", "Path to the OCI-compatible binary used to run containers, default is /usr/bin/runc") + pFlags.StringArrayVar(&opts.RuntimeFlags, "runtime-flag", []string{}, "add global flags for the container runtime") // -s is deprecated due to conflict with -s on subcommands pFlags.StringVar(&opts.StorageDriver, "storage-driver", "", "Select which storage driver is used to manage storage of images and containers (default is overlay)") pFlags.StringArrayVar(&opts.StorageOpts, "storage-opt", []string{}, "Used to pass an option to the storage driver") diff --git a/docs/source/markdown/podman-build.1.md b/docs/source/markdown/podman-build.1.md index 6618df1b96..4f94a53f1f 100644 --- a/docs/source/markdown/podman-build.1.md +++ b/docs/source/markdown/podman-build.1.md @@ -420,16 +420,6 @@ commands specified by the **RUN** instruction. Note: You can also override the default runtime by setting the BUILDAH\_RUNTIME environment variable. `export BUILDAH_RUNTIME=/usr/local/bin/runc` -**--runtime-flag**=*flag* - -Adds global flags for the container runtime. To list the supported flags, please -consult the manpages of the selected container runtime (`runc` is the default -runtime, the manpage to consult is `runc(8)`. When the machine is configured -for cgroup V2, the default runtime is `crun`, the manpage to consult is `crun(8)`.). - -Note: Do not pass the leading `--` to the flag. To pass the runc flag `--log-format json` -to podman build, the option given would be `--runtime-flag log-format=json`. - **--security-opt**=*option* Security Options diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/podman.1.md index c53da6b5f8..2dc6b13bfc 100644 --- a/docs/source/markdown/podman.1.md +++ b/docs/source/markdown/podman.1.md @@ -99,6 +99,16 @@ Default state dir configured in `/etc/containers/storage.conf`. Name of the OCI runtime as specified in containers.conf or absolute path to the OCI compatible binary used to run containers. +**--runtime-flag**=*flag* + +Adds global flags for the container runtime. To list the supported flags, please +consult the manpages of the selected container runtime (`runc` is the default +runtime, the manpage to consult is `runc(8)`. When the machine is configured +for cgroup V2, the default runtime is `crun`, the manpage to consult is `crun(8)`.). + +Note: Do not pass the leading `--` to the flag. To pass the runc flag `--log-format json` +to podman build, the option given would be `--runtime-flag log-format=json`. + **--storage-driver**=*value* Storage driver. The default storage driver for UID 0 is configured in /etc/containers/storage.conf (`$HOME/.config/containers/storage.conf` in rootless mode), and is *vfs* for non-root users when *fuse-overlayfs* is not available. The `STORAGE_DRIVER` environment variable overrides the default. The --storage-driver specified driver overrides all. @@ -285,7 +295,7 @@ The Network File System (NFS) and other distributed file systems (for example: L For more information, please refer to the [Podman Troubleshooting Page](https://github.com/containers/podman/blob/master/troubleshooting.md). ## SEE ALSO -`containers-mounts.conf(5)`, `containers-registries.conf(5)`, `containers-storage.conf(5)`, `buildah(1)`, `containers.conf(5)`, `oci-hooks(5)`, `containers-policy.json(5)`, `subuid(5)`, `subgid(5)`, `slirp4netns(1)` +`containers-mounts.conf(5)`, `containers-registries.conf(5)`, `containers-storage.conf(5)`, `buildah(1)`, `containers.conf(5)`, `oci-hooks(5)`, `containers-policy.json(5)`, `crun(8)`, `runc(8)`, `subuid(5)`, `subgid(5)`, `slirp4netns(1)` ## HISTORY Dec 2016, Originally compiled by Dan Walsh diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index f66835771f..23b020faaa 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -64,6 +64,7 @@ type ConmonOCIRuntime struct { logSizeMax int64 noPivot bool reservePorts bool + runtimeFlags []string supportsJSON bool supportsKVM bool supportsNoCgroups bool @@ -76,7 +77,7 @@ type ConmonOCIRuntime struct { // The first path that points to a valid executable will be used. // Deliberately private. Someone should not be able to construct this outside of // libpod. -func newConmonOCIRuntime(name string, paths []string, conmonPath string, runtimeCfg *config.Config) (OCIRuntime, error) { +func newConmonOCIRuntime(name string, paths []string, conmonPath string, runtimeFlags []string, runtimeCfg *config.Config) (OCIRuntime, error) { if name == "" { return nil, errors.Wrapf(define.ErrInvalidArg, "the OCI runtime must be provided a non-empty name") } @@ -98,6 +99,7 @@ func newConmonOCIRuntime(name string, paths []string, conmonPath string, runtime runtime := new(ConmonOCIRuntime) runtime.name = name runtime.conmonPath = conmonPath + runtime.runtimeFlags = runtimeFlags runtime.conmonEnv = runtimeCfg.Engine.ConmonEnvVars runtime.cgroupManager = runtimeCfg.Engine.CgroupManager @@ -378,7 +380,7 @@ func (r *ConmonOCIRuntime) StartContainer(ctr *Container) error { if path, ok := os.LookupEnv("PATH"); ok { env = append(env, fmt.Sprintf("PATH=%s", path)) } - if err := utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, "start", ctr.ID()); err != nil { + if err := utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, append(r.runtimeFlags, "start", ctr.ID())...); err != nil { return err } @@ -398,10 +400,11 @@ func (r *ConmonOCIRuntime) KillContainer(ctr *Container, signal uint, all bool) } env := []string{fmt.Sprintf("XDG_RUNTIME_DIR=%s", runtimeDir)} var args []string + args = append(args, r.runtimeFlags...) if all { - args = []string{"kill", "--all", ctr.ID(), fmt.Sprintf("%d", signal)} + args = append(args, "kill", "--all", ctr.ID(), fmt.Sprintf("%d", signal)) } else { - args = []string{"kill", ctr.ID(), fmt.Sprintf("%d", signal)} + args = append(args, "kill", ctr.ID(), fmt.Sprintf("%d", signal)) } if err := utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, args...); err != nil { return errors.Wrapf(err, "error sending signal to container %s", ctr.ID()) @@ -478,7 +481,7 @@ func (r *ConmonOCIRuntime) DeleteContainer(ctr *Container) error { return err } env := []string{fmt.Sprintf("XDG_RUNTIME_DIR=%s", runtimeDir)} - return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, "delete", "--force", ctr.ID()) + return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, append(r.runtimeFlags, "delete", "--force", ctr.ID())...) } // PauseContainer pauses the given container. @@ -488,7 +491,7 @@ func (r *ConmonOCIRuntime) PauseContainer(ctr *Container) error { return err } env := []string{fmt.Sprintf("XDG_RUNTIME_DIR=%s", runtimeDir)} - return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, "pause", ctr.ID()) + return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, append(r.runtimeFlags, "pause", ctr.ID())...) } // UnpauseContainer unpauses the given container. @@ -498,7 +501,7 @@ func (r *ConmonOCIRuntime) UnpauseContainer(ctr *Container) error { return err } env := []string{fmt.Sprintf("XDG_RUNTIME_DIR=%s", runtimeDir)} - return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, "resume", ctr.ID()) + return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, append(r.runtimeFlags, "resume", ctr.ID())...) } // HTTPAttach performs an attach for the HTTP API. @@ -765,6 +768,7 @@ func (r *ConmonOCIRuntime) CheckpointContainer(ctr *Container, options Container logrus.Debugf("Writing checkpoint to %s", imagePath) logrus.Debugf("Writing checkpoint logs to %s", workPath) args := []string{} + args = append(args, r.runtimeFlags...) args = append(args, "checkpoint") args = append(args, "--image-path") args = append(args, imagePath) @@ -1310,6 +1314,13 @@ func (r *ConmonOCIRuntime) sharedConmonArgs(ctr *Container, cuuid, bundlePath, p "--exit-dir", exitDir, "--socket-dir-path", r.socketsDir, } + if len(r.runtimeFlags) > 0 { + rFlags := []string{} + for _, arg := range r.runtimeFlags { + rFlags = append(rFlags, "--runtime-arg", arg) + } + args = append(args, rFlags...) + } if r.cgroupManager == config.SystemdCgroupsManager && !ctr.config.NoCgroups && ctr.config.CgroupsMode != cgroupSplit { args = append(args, "-s") diff --git a/libpod/oci_conmon_unsupported.go b/libpod/oci_conmon_unsupported.go index 28d6ef12f0..2504c31f0e 100644 --- a/libpod/oci_conmon_unsupported.go +++ b/libpod/oci_conmon_unsupported.go @@ -17,7 +17,7 @@ type ConmonOCIRuntime struct { } // newConmonOCIRuntime is not supported on this OS. -func newConmonOCIRuntime(name string, paths []string, conmonPath string, runtimeCfg *config.Config) (OCIRuntime, error) { +func newConmonOCIRuntime(name string, paths []string, conmonPath string, runtimeFlags []string, runtimeCfg *config.Config) (OCIRuntime, error) { return nil, define.ErrNotImplemented } diff --git a/libpod/options.go b/libpod/options.go index dccbb87418..577c03810f 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -529,6 +529,17 @@ func WithEnableSDNotify() RuntimeOption { } } +// WithRuntimeFlags adds the global runtime flags to the container config +func WithRuntimeFlags(runtimeFlags []string) RuntimeOption { + return func(rt *Runtime) error { + if rt.valid { + return define.ErrRuntimeFinalized + } + rt.runtimeFlags = runtimeFlags + return nil + } +} + // Container Creation Options // WithShmDir sets the directory that should be mounted on /dev/shm. diff --git a/libpod/runtime.go b/libpod/runtime.go index 1d2e624d88..fdd9ebcc8d 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -53,6 +53,7 @@ type Runtime struct { imageContext *types.SystemContext defaultOCIRuntime OCIRuntime ociRuntimes map[string]OCIRuntime + runtimeFlags []string netPlugin ocicni.CNIPlugin conmonPath string imageRuntime *image.Runtime @@ -365,7 +366,7 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) { // Initialize remaining OCI runtimes for name, paths := range runtime.config.Engine.OCIRuntimes { - ociRuntime, err := newConmonOCIRuntime(name, paths, runtime.conmonPath, runtime.config) + ociRuntime, err := newConmonOCIRuntime(name, paths, runtime.conmonPath, runtime.runtimeFlags, runtime.config) if err != nil { // Don't fatally error. // This will allow us to ship configs including optional @@ -385,7 +386,7 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) { if strings.HasPrefix(runtime.config.Engine.OCIRuntime, "/") { name := filepath.Base(runtime.config.Engine.OCIRuntime) - ociRuntime, err := newConmonOCIRuntime(name, []string{runtime.config.Engine.OCIRuntime}, runtime.conmonPath, runtime.config) + ociRuntime, err := newConmonOCIRuntime(name, []string{runtime.config.Engine.OCIRuntime}, runtime.conmonPath, runtime.runtimeFlags, runtime.config) if err != nil { return err } diff --git a/pkg/domain/entities/engine.go b/pkg/domain/entities/engine.go index 6776d09e92..f23d964e58 100644 --- a/pkg/domain/entities/engine.go +++ b/pkg/domain/entities/engine.go @@ -46,6 +46,7 @@ type PodmanConfig struct { RegistriesConf string // allows for specifying a custom registries.conf Remote bool // Connection to Podman API Service will use RESTful API RuntimePath string // --runtime flag will set Engine.RuntimePath + RuntimeFlags []string // global flags for the container runtime Span opentracing.Span // tracing object SpanCloser io.Closer // Close() for tracing object SpanCtx context.Context // context to use when tracing diff --git a/pkg/domain/infra/runtime_libpod.go b/pkg/domain/infra/runtime_libpod.go index a88347e24c..f9b8106efc 100644 --- a/pkg/domain/infra/runtime_libpod.go +++ b/pkg/domain/infra/runtime_libpod.go @@ -156,6 +156,14 @@ func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpo options = append(options, libpod.WithRenumber()) } + if len(cfg.RuntimeFlags) > 0 { + runtimeFlags := []string{} + for _, arg := range cfg.RuntimeFlags { + runtimeFlags = append(runtimeFlags, "--"+arg) + } + options = append(options, libpod.WithRuntimeFlags(runtimeFlags)) + } + // Only set this if the user changes storage config on the command line if storageSet { options = append(options, libpod.WithStorageConfig(storageOpts)) diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 198c8881d7..5491dcc82b 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -61,6 +61,12 @@ echo $rand | 0 | $rand is "$tests_run" "$(grep . <<<$tests | wc -l)" "Ran the full set of tests" } +@test "podman run - globle runtime option" { + skip_if_remote "runtime flag is not passing over remote" + run_podman 126 --runtime-flag invalidflag run --rm $IMAGE + is "$output" ".*invalidflag" "failed when passing undefined flags to the runtime" +} + # 'run --preserve-fds' passes a number of additional file descriptors into the container @test "podman run --preserve-fds" { skip_if_remote "preserve-fds is meaningless over remote" diff --git a/test/system/070-build.bats b/test/system/070-build.bats index 997699ecb6..1d757bbc72 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -30,9 +30,26 @@ EOF run_podman rmi -f build_test } +@test "podman build - global runtime flags test" { + skip_if_remote "FIXME: pending #7136" + + rand_content=$(random_string 50) + + tmpdir=$PODMAN_TMPDIR/build-test + run mkdir -p $tmpdir + containerfile=$tmpdir/Containerfile + cat >$containerfile <