aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--OWNERS14
-rw-r--r--cmd/podman/images/build.go3
-rw-r--r--cmd/podman/root.go1
-rw-r--r--docs/source/markdown/podman-build.1.md10
-rw-r--r--docs/source/markdown/podman.1.md12
-rw-r--r--libpod/oci_conmon_linux.go25
-rw-r--r--libpod/oci_conmon_unsupported.go2
-rw-r--r--libpod/options.go11
-rw-r--r--libpod/runtime.go5
-rw-r--r--pkg/domain/entities/engine.go1
-rw-r--r--pkg/domain/infra/runtime_libpod.go8
-rw-r--r--pkg/domain/infra/tunnel/containers.go7
-rw-r--r--pkg/errorhandling/errorhandling.go8
-rw-r--r--test/system/030-run.bats6
-rw-r--r--test/system/070-build.bats19
-rw-r--r--troubleshooting.md29
16 files changed, 129 insertions, 32 deletions
diff --git a/OWNERS b/OWNERS
index 227c97d6a..9bd9eaac4 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,20 +1,22 @@
approvers:
- - mheon
- baude
+ - edsantiago
+ - giuseppe
+ - jwhonce
+ - mheon
- mrunalp
- rhatdan
- TomSweeneyRedHat
- umohnani8
- - giuseppe
- vrothberg
- - jwhonce
reviewers:
- - mheon
- baude
+ - edsantiago
+ - giuseppe
+ - jwhonce
+ - mheon
- mrunalp
- rhatdan
- TomSweeneyRedHat
- umohnani8
- - giuseppe
- vrothberg
- - jwhonce
diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go
index 923109b15..ff5c6ec09 100644
--- a/cmd/podman/images/build.go
+++ b/cmd/podman/images/build.go
@@ -386,6 +386,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 6cf369f0a..60725b111 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 c38424a11..e30c2a5ef 100644
--- a/docs/source/markdown/podman-build.1.md
+++ b/docs/source/markdown/podman-build.1.md
@@ -422,16 +422,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 c53da6b5f..2dc6b13bf 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 <dwalsh@redhat.com>
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index bb138ca14..5769e5580 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 28d6ef12f..2504c31f0 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 eb7f1b4f1..d592124bc 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -530,6 +530,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 1d2e624d8..fdd9ebcc8 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 6776d09e9..f23d964e5 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 a88347e24..f9b8106ef 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/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 062b38a70..35550b9be 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -19,6 +19,7 @@ import (
"github.com/containers/podman/v2/pkg/bindings"
"github.com/containers/podman/v2/pkg/bindings/containers"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/errorhandling"
"github.com/containers/podman/v2/pkg/specgen"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -537,8 +538,8 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
// de-spaghetti the code.
defer func() {
if err := containers.Remove(ic.ClientCxt, con.ID, bindings.PFalse, bindings.PTrue); err != nil {
- if errors.Cause(err) == define.ErrNoSuchCtr ||
- errors.Cause(err) == define.ErrCtrRemoved {
+ if errorhandling.Contains(err, define.ErrNoSuchCtr) ||
+ errorhandling.Contains(err, define.ErrCtrRemoved) {
logrus.Warnf("Container %s does not exist: %v", con.ID, err)
} else {
logrus.Errorf("Error removing container %s: %v", con.ID, err)
@@ -556,7 +557,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
// Determine why the wait failed. If the container doesn't exist,
// consult the events.
- if !strings.Contains(waitErr.Error(), define.ErrNoSuchCtr.Error()) {
+ if !errorhandling.Contains(waitErr, define.ErrNoSuchCtr) {
return &report, waitErr
}
diff --git a/pkg/errorhandling/errorhandling.go b/pkg/errorhandling/errorhandling.go
index 3117b0ca4..ca6b60bc5 100644
--- a/pkg/errorhandling/errorhandling.go
+++ b/pkg/errorhandling/errorhandling.go
@@ -57,3 +57,11 @@ func CloseQuiet(f *os.File) {
logrus.Errorf("unable to close file %s: %q", f.Name(), err)
}
}
+
+// Contains checks if err's message contains sub's message. Contains should be
+// used iff either err or sub has lost type information (e.g., due to
+// marshaling). For typed errors, please use `errors.Contains(...)` or `Is()`
+// in recent version of Go.
+func Contains(err error, sub error) bool {
+ return strings.Contains(err.Error(), sub.Error())
+}
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index 4e518c571..518d902a7 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 75947e1cd..66f6610ea 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 <<EOF
+FROM $IMAGE
+RUN echo $rand_content
+EOF
+
+ run_podman 125 --runtime-flag invalidflag build -t build_test $tmpdir
+ is "$output" ".*invalidflag" "failed when passing undefined flags to the runtime"
+}
+
# Regression from v1.5.0. This test passes fine in v1.5.0, fails in 1.6
@test "podman build - cache (#3920)" {
- skip_if_remote "FIXME: pending #7136"
+ skip_if_remote "FIXME: pending #7136, runtime flag is not passing over remote"
if is_remote && is_rootless; then
skip "unreliable with podman-remote and rootless; #2972"
fi
diff --git a/troubleshooting.md b/troubleshooting.md
index 2de94f668..4b0f2e1e4 100644
--- a/troubleshooting.md
+++ b/troubleshooting.md
@@ -546,7 +546,7 @@ podman run -ti --detach-keys ctrl-q,ctrl-q fedora sh
```
To make this change the default for all containers, users can modify the
-containers.conf file. This can be done simply in your homedir, but adding the
+containers.conf file. This can be done simply in your home directory, but adding the
following lines to users containers.conf
```
@@ -617,3 +617,30 @@ If you encounter a `fuse: device not found` error when running the container ima
the fuse kernel module has not been loaded on your host system. Use the command `modprobe fuse` to load the
module and then run the container image afterwards. To enable this automatically at boot time, you can add a configuration
file to `/etc/modules.load.d`. See `man modules-load.d` for more details.
+
+### 25) podman run --rootfs link/to//read/only/dir does not work
+
+An error such as "OCI runtime error" on a read-only filesystem or the error "{image} is not an absolute path or is a symlink" are often times indicators for this issue. For more details, review this [issue](
+https://github.com/containers/podman/issues/5895).
+
+#### Symptom
+
+Rootless Podman requires certain files to exist in a file system in order to run.
+Podman will create /etc/resolv.conf, /etc/hosts and other file descriptors on the rootfs in order
+to mount volumes on them.
+
+#### Solution
+
+Run the container once in read/write mode, Podman will generate all of the FDs on the rootfs, and
+from that point forward you can run with a read-only rootfs.
+
+$ podman run --rm --rootfs /path/to/rootfs true
+
+The command above will create all the missing directories needed to run the container.
+
+After that, it can be used in read only mode, by multiple containers at the same time:
+
+$ podman run --read-only --rootfs /path/to/rootfs ....
+
+Another option would be to create an overlay file system on the directory as a lower and then
+then allow podman to create the files on the upper.