aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/create.go1416
-rw-r--r--cmd/podman/common/create_opts.go120
-rw-r--r--cmd/podman/common/netflags.go102
-rw-r--r--cmd/podman/containers/create.go211
-rw-r--r--cmd/podman/containers/prune.go3
-rw-r--r--cmd/podman/containers/restore.go3
-rw-r--r--cmd/podman/containers/run.go19
-rw-r--r--cmd/podman/images/prune.go3
-rw-r--r--cmd/podman/networks/prune.go3
-rw-r--r--cmd/podman/pods/create.go155
-rw-r--r--cmd/podman/pods/rm.go3
-rw-r--r--cmd/podman/pods/start.go3
-rw-r--r--cmd/podman/pods/stop.go3
-rw-r--r--docs/source/markdown/podman-pod-create.1.md21
-rw-r--r--libpod/container_internal.go3
-rw-r--r--libpod/kube.go4
-rw-r--r--libpod/networking_linux.go1
-rw-r--r--libpod/options.go480
-rw-r--r--libpod/pod.go169
-rw-r--r--libpod/pod_api.go53
-rw-r--r--libpod/pod_internal.go2
-rw-r--r--libpod/runtime_ctr.go26
-rw-r--r--libpod/runtime_pod_infra_linux.go284
-rw-r--r--libpod/runtime_pod_linux.go57
-rw-r--r--pkg/api/handlers/compat/containers_create.go3
-rw-r--r--pkg/api/handlers/libpod/containers_create.go7
-rw-r--r--pkg/api/handlers/libpod/pods.go65
-rw-r--r--pkg/api/handlers/types/types.go4
-rw-r--r--pkg/bindings/pods/pods.go12
-rw-r--r--pkg/bindings/test/pods_test.go7
-rw-r--r--pkg/domain/entities/engine_container.go2
-rw-r--r--pkg/domain/entities/pods.go183
-rw-r--r--pkg/domain/entities/types.go38
-rw-r--r--pkg/domain/infra/abi/containers.go12
-rw-r--r--pkg/domain/infra/abi/generate.go4
-rw-r--r--pkg/domain/infra/abi/play.go250
-rw-r--r--pkg/domain/infra/abi/pods.go9
-rw-r--r--pkg/domain/infra/tunnel/events.go1
-rw-r--r--pkg/domain/infra/tunnel/pods.go7
-rw-r--r--pkg/specgen/generate/container_create.go63
-rw-r--r--pkg/specgen/generate/kube/kube.go32
-rw-r--r--pkg/specgen/generate/namespaces.go2
-rw-r--r--pkg/specgen/generate/oci.go3
-rw-r--r--pkg/specgen/generate/pod_create.go214
-rw-r--r--pkg/specgen/podspecgen.go3
-rw-r--r--pkg/specgenutil/createparse.go (renamed from cmd/podman/common/createparse.go)11
-rw-r--r--pkg/specgenutil/ports.go (renamed from cmd/podman/common/ports.go)2
-rw-r--r--pkg/specgenutil/specgen.go (renamed from cmd/podman/common/specgen.go)104
-rw-r--r--pkg/specgenutil/util.go (renamed from cmd/podman/common/util.go)2
-rw-r--r--pkg/specgenutil/volumes.go (renamed from cmd/podman/common/volumes.go)2
-rw-r--r--test/e2e/pod_create_test.go12
51 files changed, 1925 insertions, 2273 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index 401cf2e09..325c1dc69 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -7,6 +7,7 @@ import (
"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/libpod/define"
+ "github.com/containers/podman/v3/pkg/domain/entities"
"github.com/spf13/cobra"
)
@@ -14,663 +15,714 @@ const sizeWithUnitFormat = "(format: `<number>[<unit>]`, where unit = b (bytes),
var containerConfig = registry.PodmanConfig()
-func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
+func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions, isInfra bool) {
createFlags := cmd.Flags()
- annotationFlagName := "annotation"
- createFlags.StringSliceVar(
- &cf.Annotation,
- annotationFlagName, []string{},
- "Add annotations to container (key:value)",
- )
- _ = cmd.RegisterFlagCompletionFunc(annotationFlagName, completion.AutocompleteNone)
+ if !isInfra {
+ annotationFlagName := "annotation"
+ createFlags.StringSliceVar(
+ &cf.Annotation,
+ annotationFlagName, []string{},
+ "Add annotations to container (key:value)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(annotationFlagName, completion.AutocompleteNone)
- attachFlagName := "attach"
- createFlags.StringSliceVarP(
- &cf.Attach,
- attachFlagName, "a", []string{},
- "Attach to STDIN, STDOUT or STDERR",
- )
- _ = cmd.RegisterFlagCompletionFunc(attachFlagName, AutocompleteCreateAttach)
+ attachFlagName := "attach"
+ createFlags.StringSliceVarP(
+ &cf.Attach,
+ attachFlagName, "a", []string{},
+ "Attach to STDIN, STDOUT or STDERR",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(attachFlagName, AutocompleteCreateAttach)
- authfileFlagName := "authfile"
- createFlags.StringVar(
- &cf.Authfile,
- authfileFlagName, auth.GetDefaultAuthFile(),
- "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override",
- )
- _ = cmd.RegisterFlagCompletionFunc(authfileFlagName, completion.AutocompleteDefault)
+ authfileFlagName := "authfile"
+ createFlags.StringVar(
+ &cf.Authfile,
+ authfileFlagName, auth.GetDefaultAuthFile(),
+ "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(authfileFlagName, completion.AutocompleteDefault)
- blkioWeightFlagName := "blkio-weight"
- createFlags.StringVar(
- &cf.BlkIOWeight,
- blkioWeightFlagName, "",
- "Block IO weight (relative weight) accepts a weight value between 10 and 1000.",
- )
- _ = cmd.RegisterFlagCompletionFunc(blkioWeightFlagName, completion.AutocompleteNone)
+ blkioWeightFlagName := "blkio-weight"
+ createFlags.StringVar(
+ &cf.BlkIOWeight,
+ blkioWeightFlagName, "",
+ "Block IO weight (relative weight) accepts a weight value between 10 and 1000.",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(blkioWeightFlagName, completion.AutocompleteNone)
- blkioWeightDeviceFlagName := "blkio-weight-device"
- createFlags.StringSliceVar(
- &cf.BlkIOWeightDevice,
- blkioWeightDeviceFlagName, []string{},
- "Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`)",
- )
- _ = cmd.RegisterFlagCompletionFunc(blkioWeightDeviceFlagName, completion.AutocompleteDefault)
+ blkioWeightDeviceFlagName := "blkio-weight-device"
+ createFlags.StringSliceVar(
+ &cf.BlkIOWeightDevice,
+ blkioWeightDeviceFlagName, []string{},
+ "Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(blkioWeightDeviceFlagName, completion.AutocompleteDefault)
- capAddFlagName := "cap-add"
- createFlags.StringSliceVar(
- &cf.CapAdd,
- capAddFlagName, []string{},
- "Add capabilities to the container",
- )
- _ = cmd.RegisterFlagCompletionFunc(capAddFlagName, completion.AutocompleteCapabilities)
+ capAddFlagName := "cap-add"
+ createFlags.StringSliceVar(
+ &cf.CapAdd,
+ capAddFlagName, []string{},
+ "Add capabilities to the container",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(capAddFlagName, completion.AutocompleteCapabilities)
- capDropFlagName := "cap-drop"
- createFlags.StringSliceVar(
- &cf.CapDrop,
- capDropFlagName, []string{},
- "Drop capabilities from the container",
- )
- _ = cmd.RegisterFlagCompletionFunc(capDropFlagName, completion.AutocompleteCapabilities)
+ capDropFlagName := "cap-drop"
+ createFlags.StringSliceVar(
+ &cf.CapDrop,
+ capDropFlagName, []string{},
+ "Drop capabilities from the container",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(capDropFlagName, completion.AutocompleteCapabilities)
- cgroupnsFlagName := "cgroupns"
- createFlags.String(
- cgroupnsFlagName, "",
- "cgroup namespace to use",
- )
- _ = cmd.RegisterFlagCompletionFunc(cgroupnsFlagName, AutocompleteNamespace)
+ cgroupnsFlagName := "cgroupns"
+ createFlags.String(
+ cgroupnsFlagName, "",
+ "cgroup namespace to use",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(cgroupnsFlagName, AutocompleteNamespace)
- cgroupsFlagName := "cgroups"
- createFlags.StringVar(
- &cf.CGroupsMode,
- cgroupsFlagName, cgroupConfig(),
- `control container cgroup configuration ("enabled"|"disabled"|"no-conmon"|"split")`,
- )
- _ = cmd.RegisterFlagCompletionFunc(cgroupsFlagName, AutocompleteCgroupMode)
+ cgroupsFlagName := "cgroups"
+ createFlags.StringVar(
+ &cf.CGroupsMode,
+ cgroupsFlagName, cgroupConfig(),
+ `control container cgroup configuration ("enabled"|"disabled"|"no-conmon"|"split")`,
+ )
+ _ = cmd.RegisterFlagCompletionFunc(cgroupsFlagName, AutocompleteCgroupMode)
- cgroupParentFlagName := "cgroup-parent"
- createFlags.StringVar(
- &cf.CGroupParent,
- cgroupParentFlagName, "",
- "Optional parent cgroup for the container",
- )
- _ = cmd.RegisterFlagCompletionFunc(cgroupParentFlagName, completion.AutocompleteDefault)
+ cpuPeriodFlagName := "cpu-period"
+ createFlags.Uint64Var(
+ &cf.CPUPeriod,
+ cpuPeriodFlagName, 0,
+ "Limit the CPU CFS (Completely Fair Scheduler) period",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(cpuPeriodFlagName, completion.AutocompleteNone)
- cidfileFlagName := "cidfile"
- createFlags.StringVar(
- &cf.CIDFile,
- cidfileFlagName, "",
- "Write the container ID to the file",
- )
- _ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault)
+ cpuQuotaFlagName := "cpu-quota"
+ createFlags.Int64Var(
+ &cf.CPUQuota,
+ cpuQuotaFlagName, 0,
+ "Limit the CPU CFS (Completely Fair Scheduler) quota",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(cpuQuotaFlagName, completion.AutocompleteNone)
- conmonPidfileFlagName := "conmon-pidfile"
- createFlags.StringVar(
- &cf.ConmonPIDFile,
- conmonPidfileFlagName, "",
- "Path to the file that will receive the PID of conmon",
- )
- _ = cmd.RegisterFlagCompletionFunc(conmonPidfileFlagName, completion.AutocompleteDefault)
+ cpuRtPeriodFlagName := "cpu-rt-period"
+ createFlags.Uint64Var(
+ &cf.CPURTPeriod,
+ cpuRtPeriodFlagName, 0,
+ "Limit the CPU real-time period in microseconds",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(cpuRtPeriodFlagName, completion.AutocompleteNone)
- cpuPeriodFlagName := "cpu-period"
- createFlags.Uint64Var(
- &cf.CPUPeriod,
- cpuPeriodFlagName, 0,
- "Limit the CPU CFS (Completely Fair Scheduler) period",
- )
- _ = cmd.RegisterFlagCompletionFunc(cpuPeriodFlagName, completion.AutocompleteNone)
+ cpuRtRuntimeFlagName := "cpu-rt-runtime"
+ createFlags.Int64Var(
+ &cf.CPURTRuntime,
+ cpuRtRuntimeFlagName, 0,
+ "Limit the CPU real-time runtime in microseconds",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(cpuRtRuntimeFlagName, completion.AutocompleteNone)
- cpuQuotaFlagName := "cpu-quota"
- createFlags.Int64Var(
- &cf.CPUQuota,
- cpuQuotaFlagName, 0,
- "Limit the CPU CFS (Completely Fair Scheduler) quota",
- )
- _ = cmd.RegisterFlagCompletionFunc(cpuQuotaFlagName, completion.AutocompleteNone)
+ cpuSharesFlagName := "cpu-shares"
+ createFlags.Uint64Var(
+ &cf.CPUShares,
+ cpuSharesFlagName, 0,
+ "CPU shares (relative weight)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(cpuSharesFlagName, completion.AutocompleteNone)
+ cidfileFlagName := "cidfile"
+ createFlags.StringVar(
+ &cf.CIDFile,
+ cidfileFlagName, "",
+ "Write the container ID to the file",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault)
+ cpusetMemsFlagName := "cpuset-mems"
+ createFlags.StringVar(
+ &cf.CPUSetMems,
+ cpusetMemsFlagName, "",
+ "Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(cpusetMemsFlagName, completion.AutocompleteNone)
- cpuRtPeriodFlagName := "cpu-rt-period"
- createFlags.Uint64Var(
- &cf.CPURTPeriod,
- cpuRtPeriodFlagName, 0,
- "Limit the CPU real-time period in microseconds",
- )
- _ = cmd.RegisterFlagCompletionFunc(cpuRtPeriodFlagName, completion.AutocompleteNone)
+ deviceFlagName := "device"
+ createFlags.StringSliceVar(
+ &cf.Devices,
+ deviceFlagName, devices(),
+ "Add a host device to the container",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(deviceFlagName, completion.AutocompleteDefault)
- cpuRtRuntimeFlagName := "cpu-rt-runtime"
- createFlags.Int64Var(
- &cf.CPURTRuntime,
- cpuRtRuntimeFlagName, 0,
- "Limit the CPU real-time runtime in microseconds",
- )
- _ = cmd.RegisterFlagCompletionFunc(cpuRtRuntimeFlagName, completion.AutocompleteNone)
+ deviceCgroupRuleFlagName := "device-cgroup-rule"
+ createFlags.StringSliceVar(
+ &cf.DeviceCGroupRule,
+ deviceCgroupRuleFlagName, []string{},
+ "Add a rule to the cgroup allowed devices list",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(deviceCgroupRuleFlagName, completion.AutocompleteNone)
- cpuSharesFlagName := "cpu-shares"
- createFlags.Uint64Var(
- &cf.CPUShares,
- cpuSharesFlagName, 0,
- "CPU shares (relative weight)",
- )
- _ = cmd.RegisterFlagCompletionFunc(cpuSharesFlagName, completion.AutocompleteNone)
+ deviceReadBpsFlagName := "device-read-bps"
+ createFlags.StringSliceVar(
+ &cf.DeviceReadBPs,
+ deviceReadBpsFlagName, []string{},
+ "Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(deviceReadBpsFlagName, completion.AutocompleteDefault)
- cpusFlagName := "cpus"
- createFlags.Float64Var(
- &cf.CPUS,
- cpusFlagName, 0,
- "Number of CPUs. The default is 0.000 which means no limit",
- )
- _ = cmd.RegisterFlagCompletionFunc(cpusFlagName, completion.AutocompleteNone)
+ deviceReadIopsFlagName := "device-read-iops"
+ createFlags.StringSliceVar(
+ &cf.DeviceReadIOPs,
+ deviceReadIopsFlagName, []string{},
+ "Limit read rate (IO per second) from a device (e.g. --device-read-iops=/dev/sda:1000)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(deviceReadIopsFlagName, completion.AutocompleteDefault)
- cpusetCpusFlagName := "cpuset-cpus"
- createFlags.StringVar(
- &cf.CPUSetCPUs,
- cpusetCpusFlagName, "",
- "CPUs in which to allow execution (0-3, 0,1)",
- )
- _ = cmd.RegisterFlagCompletionFunc(cpusetCpusFlagName, completion.AutocompleteNone)
+ deviceWriteBpsFlagName := "device-write-bps"
+ createFlags.StringSliceVar(
+ &cf.DeviceWriteBPs,
+ deviceWriteBpsFlagName, []string{},
+ "Limit write rate (bytes per second) to a device (e.g. --device-write-bps=/dev/sda:1mb)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(deviceWriteBpsFlagName, completion.AutocompleteDefault)
- cpusetMemsFlagName := "cpuset-mems"
- createFlags.StringVar(
- &cf.CPUSetMems,
- cpusetMemsFlagName, "",
- "Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.",
- )
- _ = cmd.RegisterFlagCompletionFunc(cpusetMemsFlagName, completion.AutocompleteNone)
+ deviceWriteIopsFlagName := "device-write-iops"
+ createFlags.StringSliceVar(
+ &cf.DeviceWriteIOPs,
+ deviceWriteIopsFlagName, []string{},
+ "Limit write rate (IO per second) to a device (e.g. --device-write-iops=/dev/sda:1000)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(deviceWriteIopsFlagName, completion.AutocompleteDefault)
- deviceFlagName := "device"
- createFlags.StringSliceVar(
- &cf.Devices,
- deviceFlagName, devices(),
- "Add a host device to the container",
- )
- _ = cmd.RegisterFlagCompletionFunc(deviceFlagName, completion.AutocompleteDefault)
+ createFlags.Bool(
+ "disable-content-trust", false,
+ "This is a Docker specific option and is a NOOP",
+ )
- deviceCgroupRuleFlagName := "device-cgroup-rule"
- createFlags.StringSliceVar(
- &cf.DeviceCGroupRule,
- deviceCgroupRuleFlagName, []string{},
- "Add a rule to the cgroup allowed devices list",
- )
- _ = cmd.RegisterFlagCompletionFunc(deviceCgroupRuleFlagName, completion.AutocompleteNone)
+ envFlagName := "env"
+ createFlags.StringArrayP(
+ envFlagName, "e", env(),
+ "Set environment variables in container",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(envFlagName, completion.AutocompleteNone)
+
+ if !registry.IsRemote() {
+ createFlags.BoolVar(
+ &cf.EnvHost,
+ "env-host", false, "Use all current host environment variables in container",
+ )
+ }
+
+ envFileFlagName := "env-file"
+ createFlags.StringSliceVar(
+ &cf.EnvFile,
+ envFileFlagName, []string{},
+ "Read in a file of environment variables",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(envFileFlagName, completion.AutocompleteDefault)
- deviceReadBpsFlagName := "device-read-bps"
- createFlags.StringSliceVar(
- &cf.DeviceReadBPs,
- deviceReadBpsFlagName, []string{},
- "Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)",
- )
- _ = cmd.RegisterFlagCompletionFunc(deviceReadBpsFlagName, completion.AutocompleteDefault)
+ exposeFlagName := "expose"
+ createFlags.StringSliceVar(
+ &cf.Expose,
+ exposeFlagName, []string{},
+ "Expose a port or a range of ports",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(exposeFlagName, completion.AutocompleteNone)
- deviceReadIopsFlagName := "device-read-iops"
- createFlags.StringSliceVar(
- &cf.DeviceReadIOPs,
- deviceReadIopsFlagName, []string{},
- "Limit read rate (IO per second) from a device (e.g. --device-read-iops=/dev/sda:1000)",
- )
- _ = cmd.RegisterFlagCompletionFunc(deviceReadIopsFlagName, completion.AutocompleteDefault)
+ groupAddFlagName := "group-add"
+ createFlags.StringSliceVar(
+ &cf.GroupAdd,
+ groupAddFlagName, []string{},
+ "Add additional groups to the primary container process. 'keep-groups' allows container processes to use supplementary groups.",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(groupAddFlagName, completion.AutocompleteNone)
- deviceWriteBpsFlagName := "device-write-bps"
- createFlags.StringSliceVar(
- &cf.DeviceWriteBPs,
- deviceWriteBpsFlagName, []string{},
- "Limit write rate (bytes per second) to a device (e.g. --device-write-bps=/dev/sda:1mb)",
- )
- _ = cmd.RegisterFlagCompletionFunc(deviceWriteBpsFlagName, completion.AutocompleteDefault)
+ healthCmdFlagName := "health-cmd"
+ createFlags.StringVar(
+ &cf.HealthCmd,
+ healthCmdFlagName, "",
+ "set a healthcheck command for the container ('none' disables the existing healthcheck)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(healthCmdFlagName, completion.AutocompleteNone)
- deviceWriteIopsFlagName := "device-write-iops"
- createFlags.StringSliceVar(
- &cf.DeviceWriteIOPs,
- deviceWriteIopsFlagName, []string{},
- "Limit write rate (IO per second) to a device (e.g. --device-write-iops=/dev/sda:1000)",
- )
- _ = cmd.RegisterFlagCompletionFunc(deviceWriteIopsFlagName, completion.AutocompleteDefault)
+ healthIntervalFlagName := "health-interval"
+ createFlags.StringVar(
+ &cf.HealthInterval,
+ healthIntervalFlagName, DefaultHealthCheckInterval,
+ "set an interval for the healthchecks (a value of disable results in no automatic timer setup)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(healthIntervalFlagName, completion.AutocompleteNone)
- createFlags.Bool(
- "disable-content-trust", false,
- "This is a Docker specific option and is a NOOP",
- )
+ healthRetriesFlagName := "health-retries"
+ createFlags.UintVar(
+ &cf.HealthRetries,
+ healthRetriesFlagName, DefaultHealthCheckRetries,
+ "the number of retries allowed before a healthcheck is considered to be unhealthy",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(healthRetriesFlagName, completion.AutocompleteNone)
- entrypointFlagName := "entrypoint"
- createFlags.String(entrypointFlagName, "",
- "Overwrite the default ENTRYPOINT of the image",
- )
- _ = cmd.RegisterFlagCompletionFunc(entrypointFlagName, completion.AutocompleteNone)
+ healthStartPeriodFlagName := "health-start-period"
+ createFlags.StringVar(
+ &cf.HealthStartPeriod,
+ healthStartPeriodFlagName, DefaultHealthCheckStartPeriod,
+ "the initialization time needed for a container to bootstrap",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(healthStartPeriodFlagName, completion.AutocompleteNone)
- envFlagName := "env"
- createFlags.StringArrayP(
- envFlagName, "e", env(),
- "Set environment variables in container",
- )
- _ = cmd.RegisterFlagCompletionFunc(envFlagName, completion.AutocompleteNone)
+ healthTimeoutFlagName := "health-timeout"
+ createFlags.StringVar(
+ &cf.HealthTimeout,
+ healthTimeoutFlagName, DefaultHealthCheckTimeout,
+ "the maximum time allowed to complete the healthcheck before an interval is considered failed",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(healthTimeoutFlagName, completion.AutocompleteNone)
- if !registry.IsRemote() {
createFlags.BoolVar(
- &cf.EnvHost,
- "env-host", false, "Use all current host environment variables in container",
+ &cf.HTTPProxy,
+ "http-proxy", containerConfig.Containers.HTTPProxy,
+ "Set proxy environment variables in the container based on the host proxy vars",
)
- }
-
- envFileFlagName := "env-file"
- createFlags.StringSliceVar(
- &cf.EnvFile,
- envFileFlagName, []string{},
- "Read in a file of environment variables",
- )
- _ = cmd.RegisterFlagCompletionFunc(envFileFlagName, completion.AutocompleteDefault)
-
- exposeFlagName := "expose"
- createFlags.StringSliceVar(
- &cf.Expose,
- exposeFlagName, []string{},
- "Expose a port or a range of ports",
- )
- _ = cmd.RegisterFlagCompletionFunc(exposeFlagName, completion.AutocompleteNone)
- gidmapFlagName := "gidmap"
- createFlags.StringSliceVar(
- &cf.GIDMap,
- gidmapFlagName, []string{},
- "GID map to use for the user namespace",
- )
- _ = cmd.RegisterFlagCompletionFunc(gidmapFlagName, completion.AutocompleteNone)
+ imageVolumeFlagName := "image-volume"
+ createFlags.StringVar(
+ &cf.ImageVolume,
+ imageVolumeFlagName, DefaultImageVolume,
+ `Tells podman how to handle the builtin image volumes ("bind"|"tmpfs"|"ignore")`,
+ )
+ _ = cmd.RegisterFlagCompletionFunc(imageVolumeFlagName, AutocompleteImageVolume)
- groupAddFlagName := "group-add"
- createFlags.StringSliceVar(
- &cf.GroupAdd,
- groupAddFlagName, []string{},
- "Add additional groups to the primary container process. 'keep-groups' allows container processes to use supplementary groups.",
- )
- _ = cmd.RegisterFlagCompletionFunc(groupAddFlagName, completion.AutocompleteNone)
+ createFlags.BoolVar(
+ &cf.Init,
+ "init", false,
+ "Run an init binary inside the container that forwards signals and reaps processes",
+ )
- createFlags.Bool(
- "help", false, "",
- )
+ initPathFlagName := "init-path"
+ createFlags.StringVar(
+ &cf.InitPath,
+ initPathFlagName, initPath(),
+ // Do not use the Value field for setting the default value to determine user input (i.e., non-empty string)
+ "Path to the container-init binary",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(initPathFlagName, completion.AutocompleteDefault)
- healthCmdFlagName := "health-cmd"
- createFlags.StringVar(
- &cf.HealthCmd,
- healthCmdFlagName, "",
- "set a healthcheck command for the container ('none' disables the existing healthcheck)",
- )
- _ = cmd.RegisterFlagCompletionFunc(healthCmdFlagName, completion.AutocompleteNone)
+ createFlags.BoolVarP(
+ &cf.Interactive,
+ "interactive", "i", false,
+ "Keep STDIN open even if not attached",
+ )
+ ipcFlagName := "ipc"
+ createFlags.String(
+ ipcFlagName, "",
+ "IPC namespace to use",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(ipcFlagName, AutocompleteNamespace)
- healthIntervalFlagName := "health-interval"
- createFlags.StringVar(
- &cf.HealthInterval,
- healthIntervalFlagName, DefaultHealthCheckInterval,
- "set an interval for the healthchecks (a value of disable results in no automatic timer setup)",
- )
- _ = cmd.RegisterFlagCompletionFunc(healthIntervalFlagName, completion.AutocompleteNone)
+ kernelMemoryFlagName := "kernel-memory"
+ createFlags.StringVar(
+ &cf.KernelMemory,
+ kernelMemoryFlagName, "",
+ "Kernel memory limit "+sizeWithUnitFormat,
+ )
+ _ = cmd.RegisterFlagCompletionFunc(kernelMemoryFlagName, completion.AutocompleteNone)
+ logDriverFlagName := "log-driver"
+ createFlags.StringVar(
+ &cf.LogDriver,
+ logDriverFlagName, logDriver(),
+ "Logging driver for the container",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(logDriverFlagName, AutocompleteLogDriver)
- healthRetriesFlagName := "health-retries"
- createFlags.UintVar(
- &cf.HealthRetries,
- healthRetriesFlagName, DefaultHealthCheckRetries,
- "the number of retries allowed before a healthcheck is considered to be unhealthy",
- )
- _ = cmd.RegisterFlagCompletionFunc(healthRetriesFlagName, completion.AutocompleteNone)
+ logOptFlagName := "log-opt"
+ createFlags.StringSliceVar(
+ &cf.LogOptions,
+ logOptFlagName, []string{},
+ "Logging driver options",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(logOptFlagName, AutocompleteLogOpt)
- healthStartPeriodFlagName := "health-start-period"
- createFlags.StringVar(
- &cf.HealthStartPeriod,
- healthStartPeriodFlagName, DefaultHealthCheckStartPeriod,
- "the initialization time needed for a container to bootstrap",
- )
- _ = cmd.RegisterFlagCompletionFunc(healthStartPeriodFlagName, completion.AutocompleteNone)
+ memoryFlagName := "memory"
+ createFlags.StringVarP(
+ &cf.Memory,
+ memoryFlagName, "m", "",
+ "Memory limit "+sizeWithUnitFormat,
+ )
+ _ = cmd.RegisterFlagCompletionFunc(memoryFlagName, completion.AutocompleteNone)
- healthTimeoutFlagName := "health-timeout"
- createFlags.StringVar(
- &cf.HealthTimeout,
- healthTimeoutFlagName, DefaultHealthCheckTimeout,
- "the maximum time allowed to complete the healthcheck before an interval is considered failed",
- )
- _ = cmd.RegisterFlagCompletionFunc(healthTimeoutFlagName, completion.AutocompleteNone)
+ memoryReservationFlagName := "memory-reservation"
+ createFlags.StringVar(
+ &cf.MemoryReservation,
+ memoryReservationFlagName, "",
+ "Memory soft limit "+sizeWithUnitFormat,
+ )
+ _ = cmd.RegisterFlagCompletionFunc(memoryReservationFlagName, completion.AutocompleteNone)
- hostnameFlagName := "hostname"
- createFlags.StringVarP(
- &cf.Hostname,
- hostnameFlagName, "h", "",
- "Set container hostname",
- )
- _ = cmd.RegisterFlagCompletionFunc(hostnameFlagName, completion.AutocompleteNone)
+ memorySwapFlagName := "memory-swap"
+ createFlags.StringVar(
+ &cf.MemorySwap,
+ memorySwapFlagName, "",
+ "Swap limit equal to memory plus swap: '-1' to enable unlimited swap",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(memorySwapFlagName, completion.AutocompleteNone)
- createFlags.BoolVar(
- &cf.HTTPProxy,
- "http-proxy", containerConfig.Containers.HTTPProxy,
- "Set proxy environment variables in the container based on the host proxy vars",
- )
+ memorySwappinessFlagName := "memory-swappiness"
+ createFlags.Int64Var(
+ &cf.MemorySwappiness,
+ memorySwappinessFlagName, -1,
+ "Tune container memory swappiness (0 to 100, or -1 for system default)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(memorySwappinessFlagName, completion.AutocompleteNone)
- imageVolumeFlagName := "image-volume"
- createFlags.StringVar(
- &cf.ImageVolume,
- imageVolumeFlagName, DefaultImageVolume,
- `Tells podman how to handle the builtin image volumes ("bind"|"tmpfs"|"ignore")`,
- )
- _ = cmd.RegisterFlagCompletionFunc(imageVolumeFlagName, AutocompleteImageVolume)
+ createFlags.BoolVar(
+ &cf.NoHealthCheck,
+ "no-healthcheck", false,
+ "Disable healthchecks on container",
+ )
+ createFlags.BoolVar(
+ &cf.OOMKillDisable,
+ "oom-kill-disable", false,
+ "Disable OOM Killer",
+ )
- createFlags.BoolVar(
- &cf.Init,
- "init", false,
- "Run an init binary inside the container that forwards signals and reaps processes",
- )
+ oomScoreAdjFlagName := "oom-score-adj"
+ createFlags.IntVar(
+ &cf.OOMScoreAdj,
+ oomScoreAdjFlagName, 0,
+ "Tune the host's OOM preferences (-1000 to 1000)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(oomScoreAdjFlagName, completion.AutocompleteNone)
- initPathFlagName := "init-path"
- createFlags.StringVar(
- &cf.InitPath,
- initPathFlagName, initPath(),
- // Do not use the Value field for setting the default value to determine user input (i.e., non-empty string)
- "Path to the container-init binary",
- )
- _ = cmd.RegisterFlagCompletionFunc(initPathFlagName, completion.AutocompleteDefault)
+ archFlagName := "arch"
+ createFlags.StringVar(
+ &cf.Arch,
+ archFlagName, "",
+ "use `ARCH` instead of the architecture of the machine for choosing images",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(archFlagName, completion.AutocompleteArch)
- createFlags.BoolVarP(
- &cf.Interactive,
- "interactive", "i", false,
- "Keep STDIN open even if not attached",
- )
+ osFlagName := "os"
+ createFlags.StringVar(
+ &cf.OS,
+ osFlagName, "",
+ "use `OS` instead of the running OS for choosing images",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(osFlagName, completion.AutocompleteOS)
- ipcFlagName := "ipc"
- createFlags.String(
- ipcFlagName, "",
- "IPC namespace to use",
- )
- _ = cmd.RegisterFlagCompletionFunc(ipcFlagName, AutocompleteNamespace)
+ variantFlagName := "variant"
+ createFlags.StringVar(
+ &cf.Variant,
+ variantFlagName, "",
+ "Use _VARIANT_ instead of the running architecture variant for choosing images",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(variantFlagName, completion.AutocompleteNone)
- kernelMemoryFlagName := "kernel-memory"
- createFlags.StringVar(
- &cf.KernelMemory,
- kernelMemoryFlagName, "",
- "Kernel memory limit "+sizeWithUnitFormat,
- )
- _ = cmd.RegisterFlagCompletionFunc(kernelMemoryFlagName, completion.AutocompleteNone)
+ pidsLimitFlagName := "pids-limit"
+ createFlags.Int64(
+ pidsLimitFlagName, pidsLimit(),
+ "Tune container pids limit (set 0 for unlimited, -1 for server defaults)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(pidsLimitFlagName, completion.AutocompleteNone)
- labelFlagName := "label"
- createFlags.StringArrayVarP(
- &cf.Label,
- labelFlagName, "l", []string{},
- "Set metadata on container",
- )
- _ = cmd.RegisterFlagCompletionFunc(labelFlagName, completion.AutocompleteNone)
+ platformFlagName := "platform"
+ createFlags.StringVar(
+ &cf.Platform,
+ platformFlagName, "",
+ "Specify the platform for selecting the image. (Conflicts with --arch and --os)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(platformFlagName, completion.AutocompleteNone)
- labelFileFlagName := "label-file"
- createFlags.StringSliceVar(
- &cf.LabelFile,
- labelFileFlagName, []string{},
- "Read in a line delimited file of labels",
- )
- _ = cmd.RegisterFlagCompletionFunc(labelFileFlagName, completion.AutocompleteDefault)
+ podFlagName := "pod"
+ createFlags.StringVar(
+ &cf.Pod,
+ podFlagName, "",
+ "Run container in an existing pod",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(podFlagName, AutocompletePods)
- logDriverFlagName := "log-driver"
- createFlags.StringVar(
- &cf.LogDriver,
- logDriverFlagName, logDriver(),
- "Logging driver for the container",
- )
- _ = cmd.RegisterFlagCompletionFunc(logDriverFlagName, AutocompleteLogDriver)
+ podIDFileFlagName := "pod-id-file"
+ createFlags.StringVar(
+ &cf.PodIDFile,
+ podIDFileFlagName, "",
+ "Read the pod ID from the file",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(podIDFileFlagName, completion.AutocompleteDefault)
+ createFlags.BoolVar(
+ &cf.Privileged,
+ "privileged", false,
+ "Give extended privileges to container",
+ )
+ createFlags.BoolVarP(
+ &cf.PublishAll,
+ "publish-all", "P", false,
+ "Publish all exposed ports to random ports on the host interface",
+ )
- logOptFlagName := "log-opt"
- createFlags.StringSliceVar(
- &cf.LogOptions,
- logOptFlagName, []string{},
- "Logging driver options",
- )
- _ = cmd.RegisterFlagCompletionFunc(logOptFlagName, AutocompleteLogOpt)
+ pullFlagName := "pull"
+ createFlags.StringVar(
+ &cf.Pull,
+ pullFlagName, policy(),
+ `Pull image before creating ("always"|"missing"|"never")`,
+ )
+ _ = cmd.RegisterFlagCompletionFunc(pullFlagName, AutocompletePullOption)
- memoryFlagName := "memory"
- createFlags.StringVarP(
- &cf.Memory,
- memoryFlagName, "m", "",
- "Memory limit "+sizeWithUnitFormat,
- )
- _ = cmd.RegisterFlagCompletionFunc(memoryFlagName, completion.AutocompleteNone)
+ createFlags.BoolVarP(
+ &cf.Quiet,
+ "quiet", "q", false,
+ "Suppress output information when pulling images",
+ )
+ createFlags.BoolVar(
+ &cf.ReadOnly,
+ "read-only", false,
+ "Make containers root filesystem read-only",
+ )
+ createFlags.BoolVar(
+ &cf.ReadOnlyTmpFS,
+ "read-only-tmpfs", true,
+ "When running containers in read-only mode mount a read-write tmpfs on /run, /tmp and /var/tmp",
+ )
+ requiresFlagName := "requires"
+ createFlags.StringSliceVar(
+ &cf.Requires,
+ requiresFlagName, []string{},
+ "Add one or more requirement containers that must be started before this container will start",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(requiresFlagName, AutocompleteContainers)
- memoryReservationFlagName := "memory-reservation"
- createFlags.StringVar(
- &cf.MemoryReservation,
- memoryReservationFlagName, "",
- "Memory soft limit "+sizeWithUnitFormat,
- )
- _ = cmd.RegisterFlagCompletionFunc(memoryReservationFlagName, completion.AutocompleteNone)
+ restartFlagName := "restart"
+ createFlags.StringVar(
+ &cf.Restart,
+ restartFlagName, "",
+ `Restart policy to apply when a container exits ("always"|"no"|"on-failure"|"unless-stopped")`,
+ )
+ _ = cmd.RegisterFlagCompletionFunc(restartFlagName, AutocompleteRestartOption)
- memorySwapFlagName := "memory-swap"
- createFlags.StringVar(
- &cf.MemorySwap,
- memorySwapFlagName, "",
- "Swap limit equal to memory plus swap: '-1' to enable unlimited swap",
- )
- _ = cmd.RegisterFlagCompletionFunc(memorySwapFlagName, completion.AutocompleteNone)
+ createFlags.BoolVar(
+ &cf.Rm,
+ "rm", false,
+ "Remove container (and pod if created) after exit",
+ )
+ createFlags.BoolVar(
+ &cf.RootFS,
+ "rootfs", false,
+ "The first argument is not an image but the rootfs to the exploded container",
+ )
- memorySwappinessFlagName := "memory-swappiness"
- createFlags.Int64Var(
- &cf.MemorySwappiness,
- memorySwappinessFlagName, -1,
- "Tune container memory swappiness (0 to 100, or -1 for system default)",
- )
- _ = cmd.RegisterFlagCompletionFunc(memorySwappinessFlagName, completion.AutocompleteNone)
+ sdnotifyFlagName := "sdnotify"
+ createFlags.StringVar(
+ &cf.SdNotifyMode,
+ sdnotifyFlagName, define.SdNotifyModeContainer,
+ `control sd-notify behavior ("container"|"conmon"|"ignore")`,
+ )
+ _ = cmd.RegisterFlagCompletionFunc(sdnotifyFlagName, AutocompleteSDNotify)
- nameFlagName := "name"
- createFlags.StringVar(
- &cf.Name,
- nameFlagName, "",
- "Assign a name to the container",
- )
- _ = cmd.RegisterFlagCompletionFunc(nameFlagName, completion.AutocompleteNone)
+ secretFlagName := "secret"
+ createFlags.StringArrayVar(
+ &cf.Secrets,
+ secretFlagName, []string{},
+ "Add secret to container",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(secretFlagName, AutocompleteSecrets)
- createFlags.BoolVar(
- &cf.NoHealthCheck,
- "no-healthcheck", false,
- "Disable healthchecks on container",
- )
- createFlags.BoolVar(
- &cf.OOMKillDisable,
- "oom-kill-disable", false,
- "Disable OOM Killer",
- )
+ securityOptFlagName := "security-opt"
+ createFlags.StringArrayVar(
+ &cf.SecurityOpt,
+ securityOptFlagName, []string{},
+ "Security Options",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(securityOptFlagName, AutocompleteSecurityOption)
- oomScoreAdjFlagName := "oom-score-adj"
- createFlags.IntVar(
- &cf.OOMScoreAdj,
- oomScoreAdjFlagName, 0,
- "Tune the host's OOM preferences (-1000 to 1000)",
- )
- _ = cmd.RegisterFlagCompletionFunc(oomScoreAdjFlagName, completion.AutocompleteNone)
+ shmSizeFlagName := "shm-size"
+ createFlags.String(
+ shmSizeFlagName, shmSize(),
+ "Size of /dev/shm "+sizeWithUnitFormat,
+ )
+ _ = cmd.RegisterFlagCompletionFunc(shmSizeFlagName, completion.AutocompleteNone)
- archFlagName := "arch"
- createFlags.StringVar(
- &cf.Arch,
- archFlagName, "",
- "use `ARCH` instead of the architecture of the machine for choosing images",
- )
- _ = cmd.RegisterFlagCompletionFunc(archFlagName, completion.AutocompleteArch)
+ stopSignalFlagName := "stop-signal"
+ createFlags.StringVar(
+ &cf.SignaturePolicy,
+ "signature-policy", "",
+ "`Pathname` of signature policy file (not usually used)",
+ )
+ createFlags.StringVar(
+ &cf.StopSignal,
+ stopSignalFlagName, "",
+ "Signal to stop a container. Default is SIGTERM",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(stopSignalFlagName, AutocompleteStopSignal)
- osFlagName := "os"
- createFlags.StringVar(
- &cf.OS,
- osFlagName, "",
- "use `OS` instead of the running OS for choosing images",
- )
- _ = cmd.RegisterFlagCompletionFunc(osFlagName, completion.AutocompleteOS)
+ stopTimeoutFlagName := "stop-timeout"
+ createFlags.UintVar(
+ &cf.StopTimeout,
+ stopTimeoutFlagName, containerConfig.Engine.StopTimeout,
+ "Timeout (in seconds) that containers stopped by user command have to exit. If exceeded, the container will be forcibly stopped via SIGKILL.",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(stopTimeoutFlagName, completion.AutocompleteNone)
- variantFlagName := "variant"
- createFlags.StringVar(
- &cf.Variant,
- variantFlagName, "",
- "Use _VARIANT_ instead of the running architecture variant for choosing images",
- )
- _ = cmd.RegisterFlagCompletionFunc(variantFlagName, completion.AutocompleteNone)
+ sysctlFlagName := "sysctl"
+ createFlags.StringSliceVar(
+ &cf.Sysctl,
+ sysctlFlagName, []string{},
+ "Sysctl options",
+ )
+ //TODO: Add function for sysctl completion.
+ _ = cmd.RegisterFlagCompletionFunc(sysctlFlagName, completion.AutocompleteNone)
+
+ systemdFlagName := "systemd"
+ createFlags.StringVar(
+ &cf.Systemd,
+ systemdFlagName, "true",
+ `Run container in systemd mode ("true"|"false"|"always")`,
+ )
+ _ = cmd.RegisterFlagCompletionFunc(systemdFlagName, AutocompleteSystemdFlag)
- personalityFlagName := "personality"
- createFlags.StringVar(
- &cf.Personality,
- personalityFlagName, "",
- "Configure execution domain using personality (e.g., LINUX/LINUX32)",
- )
- _ = cmd.RegisterFlagCompletionFunc(personalityFlagName, AutocompleteNamespace)
+ personalityFlagName := "personality"
+ createFlags.StringVar(
+ &cf.Personality,
+ personalityFlagName, "",
+ "Configure execution domain using personality (e.g., LINUX/LINUX32)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(personalityFlagName, AutocompleteNamespace)
- pidFlagName := "pid"
- createFlags.String(
- pidFlagName, "",
- "PID namespace to use",
- )
- _ = cmd.RegisterFlagCompletionFunc(pidFlagName, AutocompleteNamespace)
+ timeoutFlagName := "timeout"
+ createFlags.UintVar(
+ &cf.Timeout,
+ timeoutFlagName, 0,
+ "Maximum length of time a container is allowed to run. The container will be killed automatically after the time expires.",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(timeoutFlagName, completion.AutocompleteNone)
- pidsLimitFlagName := "pids-limit"
- createFlags.Int64(
- pidsLimitFlagName, pidsLimit(),
- "Tune container pids limit (set 0 for unlimited, -1 for server defaults)",
- )
- _ = cmd.RegisterFlagCompletionFunc(pidsLimitFlagName, completion.AutocompleteNone)
+ // Flag for TLS verification, so that `run` and `create` commands can make use of it.
+ // Make sure to use `=` while using this flag i.e `--tls-verify=false/true`
+ tlsVerifyFlagName := "tls-verify"
+ createFlags.BoolVar(
+ &cf.TLSVerify,
+ tlsVerifyFlagName, true,
+ "Require HTTPS and verify certificates when contacting registries for pulling images",
+ )
- platformFlagName := "platform"
- createFlags.StringVar(
- &cf.Platform,
- platformFlagName, "",
- "Specify the platform for selecting the image. (Conflicts with --arch and --os)",
- )
- _ = cmd.RegisterFlagCompletionFunc(platformFlagName, completion.AutocompleteNone)
+ tmpfsFlagName := "tmpfs"
+ createFlags.StringArrayVar(
+ &cf.TmpFS,
+ tmpfsFlagName, []string{},
+ "Mount a temporary filesystem (`tmpfs`) into a container",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(tmpfsFlagName, completion.AutocompleteDefault)
- podFlagName := "pod"
- createFlags.StringVar(
- &cf.Pod,
- podFlagName, "",
- "Run container in an existing pod",
- )
- _ = cmd.RegisterFlagCompletionFunc(podFlagName, AutocompletePods)
+ createFlags.BoolVarP(
+ &cf.TTY,
+ "tty", "t", false,
+ "Allocate a pseudo-TTY for container",
+ )
- podIDFileFlagName := "pod-id-file"
- createFlags.StringVar(
- &cf.PodIDFile,
- podIDFileFlagName, "",
- "Read the pod ID from the file",
- )
- _ = cmd.RegisterFlagCompletionFunc(podIDFileFlagName, completion.AutocompleteDefault)
-
- // Flag for TLS verification, so that `run` and `create` commands can make use of it.
- // Make sure to use `=` while using this flag i.e `--tls-verify=false/true`
- tlsVerifyFlagName := "tls-verify"
- createFlags.BoolVar(
- &cf.TLSVerify,
- tlsVerifyFlagName, true,
- "Require HTTPS and verify certificates when contacting registries for pulling images",
- )
+ timezoneFlagName := "tz"
+ createFlags.StringVar(
+ &cf.Timezone,
+ timezoneFlagName, containerConfig.TZ(),
+ "Set timezone in container",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(timezoneFlagName, completion.AutocompleteNone) //TODO: add timezone completion
- createFlags.BoolVar(
- &cf.Privileged,
- "privileged", false,
- "Give extended privileges to container",
- )
- createFlags.BoolVarP(
- &cf.PublishAll,
- "publish-all", "P", false,
- "Publish all exposed ports to random ports on the host interface",
- )
+ umaskFlagName := "umask"
+ createFlags.StringVar(
+ &cf.Umask,
+ umaskFlagName, containerConfig.Umask(),
+ "Set umask in container",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(umaskFlagName, completion.AutocompleteNone)
- pullFlagName := "pull"
- createFlags.StringVar(
- &cf.Pull,
- pullFlagName, policy(),
- `Pull image before creating ("always"|"missing"|"never")`,
- )
- _ = cmd.RegisterFlagCompletionFunc(pullFlagName, AutocompletePullOption)
+ ulimitFlagName := "ulimit"
+ createFlags.StringSliceVar(
+ &cf.Ulimit,
+ ulimitFlagName, ulimits(),
+ "Ulimit options",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(ulimitFlagName, completion.AutocompleteNone)
- createFlags.BoolVarP(
- &cf.Quiet,
- "quiet", "q", false,
- "Suppress output information when pulling images",
- )
- createFlags.BoolVar(
- &cf.ReadOnly,
- "read-only", false,
- "Make containers root filesystem read-only",
- )
- createFlags.BoolVar(
- &cf.ReadOnlyTmpFS,
- "read-only-tmpfs", true,
- "When running containers in read-only mode mount a read-write tmpfs on /run, /tmp and /var/tmp",
- )
- createFlags.BoolVar(
- &cf.Replace,
- "replace", false,
- `If a container with the same name exists, replace it`,
- )
+ userFlagName := "user"
+ createFlags.StringVarP(
+ &cf.User,
+ userFlagName, "u", "",
+ "Username or UID (format: <name|uid>[:<group|gid>])",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(userFlagName, AutocompleteUserFlag)
- requiresFlagName := "requires"
- createFlags.StringSliceVar(
- &cf.Requires,
- requiresFlagName, []string{},
- "Add one or more requirement containers that must be started before this container will start",
- )
- _ = cmd.RegisterFlagCompletionFunc(requiresFlagName, AutocompleteContainers)
+ utsFlagName := "uts"
+ createFlags.String(
+ utsFlagName, "",
+ "UTS namespace to use",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(utsFlagName, AutocompleteNamespace)
- restartFlagName := "restart"
- createFlags.StringVar(
- &cf.Restart,
- restartFlagName, "",
- `Restart policy to apply when a container exits ("always"|"no"|"on-failure"|"unless-stopped")`,
- )
- _ = cmd.RegisterFlagCompletionFunc(restartFlagName, AutocompleteRestartOption)
+ mountFlagName := "mount"
+ createFlags.StringArrayVar(
+ &cf.Mount,
+ mountFlagName, []string{},
+ "Attach a filesystem mount to the container",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(mountFlagName, AutocompleteMountFlag)
+
+ volumeDesciption := "Bind mount a volume into the container"
+ if registry.IsRemote() {
+ volumeDesciption = "Bind mount a volume into the container. Volume src will be on the server machine, not the client"
+ }
+ volumeFlagName := "volume"
+ createFlags.StringArrayVarP(
+ &cf.Volume,
+ volumeFlagName, "v", volumes(),
+ volumeDesciption,
+ )
+ _ = cmd.RegisterFlagCompletionFunc(volumeFlagName, AutocompleteVolumeFlag)
- createFlags.BoolVar(
- &cf.Rm,
- "rm", false,
- "Remove container (and pod if created) after exit",
- )
- createFlags.BoolVar(
- &cf.RootFS,
- "rootfs", false,
- "The first argument is not an image but the rootfs to the exploded container",
- )
+ volumesFromFlagName := "volumes-from"
+ createFlags.StringArrayVar(
+ &cf.VolumesFrom,
+ volumesFromFlagName, []string{},
+ "Mount volumes from the specified container(s)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(volumesFromFlagName, AutocompleteContainers)
- sdnotifyFlagName := "sdnotify"
- createFlags.StringVar(
- &cf.SdNotifyMode,
- sdnotifyFlagName, define.SdNotifyModeContainer,
- `control sd-notify behavior ("container"|"conmon"|"ignore")`,
- )
- _ = cmd.RegisterFlagCompletionFunc(sdnotifyFlagName, AutocompleteSDNotify)
+ workdirFlagName := "workdir"
+ createFlags.StringVarP(
+ &cf.Workdir,
+ workdirFlagName, "w", "",
+ "Working directory inside the container",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(workdirFlagName, completion.AutocompleteDefault)
- secretFlagName := "secret"
- createFlags.StringArrayVar(
- &cf.Secrets,
- secretFlagName, []string{},
- "Add secret to container",
- )
- _ = cmd.RegisterFlagCompletionFunc(secretFlagName, AutocompleteSecrets)
+ seccompPolicyFlagName := "seccomp-policy"
+ createFlags.StringVar(
+ &cf.SeccompPolicy,
+ seccompPolicyFlagName, "default",
+ "Policy for selecting a seccomp profile (experimental)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(seccompPolicyFlagName, completion.AutocompleteDefault)
- securityOptFlagName := "security-opt"
- createFlags.StringArrayVar(
- &cf.SecurityOpt,
- securityOptFlagName, []string{},
- "Security Options",
- )
- _ = cmd.RegisterFlagCompletionFunc(securityOptFlagName, AutocompleteSecurityOption)
+ cgroupConfFlagName := "cgroup-conf"
+ createFlags.StringSliceVar(
+ &cf.CgroupConf,
+ cgroupConfFlagName, []string{},
+ "Configure cgroup v2 (key=value)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(cgroupConfFlagName, completion.AutocompleteNone)
- shmSizeFlagName := "shm-size"
- createFlags.String(
- shmSizeFlagName, shmSize(),
- "Size of /dev/shm "+sizeWithUnitFormat,
- )
- _ = cmd.RegisterFlagCompletionFunc(shmSizeFlagName, completion.AutocompleteNone)
+ pidFileFlagName := "pidfile"
+ createFlags.StringVar(
+ &cf.PidFile,
+ pidFileFlagName, "",
+ "Write the container process ID to the file")
+ _ = cmd.RegisterFlagCompletionFunc(pidFileFlagName, completion.AutocompleteDefault)
- stopSignalFlagName := "stop-signal"
- createFlags.StringVar(
- &cf.SignaturePolicy,
- "signature-policy", "",
- "`Pathname` of signature policy file (not usually used)",
- )
- createFlags.StringVar(
- &cf.StopSignal,
- stopSignalFlagName, "",
- "Signal to stop a container. Default is SIGTERM",
- )
- _ = cmd.RegisterFlagCompletionFunc(stopSignalFlagName, AutocompleteStopSignal)
+ _ = createFlags.MarkHidden("signature-policy")
+ if registry.IsRemote() {
+ _ = createFlags.MarkHidden("env-host")
+ _ = createFlags.MarkHidden("http-proxy")
+ }
- stopTimeoutFlagName := "stop-timeout"
- createFlags.UintVar(
- &cf.StopTimeout,
- stopTimeoutFlagName, containerConfig.Engine.StopTimeout,
- "Timeout (in seconds) that containers stopped by user command have to exit. If exceeded, the container will be forcibly stopped via SIGKILL.",
- )
- _ = cmd.RegisterFlagCompletionFunc(stopTimeoutFlagName, completion.AutocompleteNone)
+ createFlags.BoolVar(
+ &cf.Replace,
+ "replace", false,
+ `If a container with the same name exists, replace it`,
+ )
+ }
subgidnameFlagName := "subgidname"
createFlags.StringVar(
@@ -688,60 +740,13 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
)
_ = cmd.RegisterFlagCompletionFunc(subuidnameFlagName, completion.AutocompleteSubuidName)
- sysctlFlagName := "sysctl"
+ gidmapFlagName := "gidmap"
createFlags.StringSliceVar(
- &cf.Sysctl,
- sysctlFlagName, []string{},
- "Sysctl options",
- )
- //TODO: Add function for sysctl completion.
- _ = cmd.RegisterFlagCompletionFunc(sysctlFlagName, completion.AutocompleteNone)
-
- systemdFlagName := "systemd"
- createFlags.StringVar(
- &cf.Systemd,
- systemdFlagName, "true",
- `Run container in systemd mode ("true"|"false"|"always")`,
- )
- _ = cmd.RegisterFlagCompletionFunc(systemdFlagName, AutocompleteSystemdFlag)
-
- timeoutFlagName := "timeout"
- createFlags.UintVar(
- &cf.Timeout,
- timeoutFlagName, 0,
- "Maximum length of time a container is allowed to run. The container will be killed automatically after the time expires.",
- )
- _ = cmd.RegisterFlagCompletionFunc(timeoutFlagName, completion.AutocompleteNone)
-
- tmpfsFlagName := "tmpfs"
- createFlags.StringArrayVar(
- &cf.TmpFS,
- tmpfsFlagName, []string{},
- "Mount a temporary filesystem (`tmpfs`) into a container",
- )
- _ = cmd.RegisterFlagCompletionFunc(tmpfsFlagName, completion.AutocompleteDefault)
-
- createFlags.BoolVarP(
- &cf.TTY,
- "tty", "t", false,
- "Allocate a pseudo-TTY for container",
- )
-
- timezoneFlagName := "tz"
- createFlags.StringVar(
- &cf.Timezone,
- timezoneFlagName, containerConfig.TZ(),
- "Set timezone in container",
- )
- _ = cmd.RegisterFlagCompletionFunc(timezoneFlagName, completion.AutocompleteNone) //TODO: add timezone completion
-
- umaskFlagName := "umask"
- createFlags.StringVar(
- &cf.Umask,
- umaskFlagName, containerConfig.Umask(),
- "Set umask in container",
+ &cf.GIDMap,
+ gidmapFlagName, []string{},
+ "GID map to use for the user namespace",
)
- _ = cmd.RegisterFlagCompletionFunc(umaskFlagName, completion.AutocompleteNone)
+ _ = cmd.RegisterFlagCompletionFunc(gidmapFlagName, completion.AutocompleteNone)
uidmapFlagName := "uidmap"
createFlags.StringSliceVar(
@@ -751,22 +756,6 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
)
_ = cmd.RegisterFlagCompletionFunc(uidmapFlagName, completion.AutocompleteNone)
- ulimitFlagName := "ulimit"
- createFlags.StringSliceVar(
- &cf.Ulimit,
- ulimitFlagName, ulimits(),
- "Ulimit options",
- )
- _ = cmd.RegisterFlagCompletionFunc(ulimitFlagName, completion.AutocompleteNone)
-
- userFlagName := "user"
- createFlags.StringVarP(
- &cf.User,
- userFlagName, "u", "",
- "Username or UID (format: <name|uid>[:<group|gid>])",
- )
- _ = cmd.RegisterFlagCompletionFunc(userFlagName, AutocompleteUserFlag)
-
usernsFlagName := "userns"
createFlags.String(
usernsFlagName, os.Getenv("PODMAN_USERNS"),
@@ -774,75 +763,106 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
)
_ = cmd.RegisterFlagCompletionFunc(usernsFlagName, AutocompleteUserNamespace)
- utsFlagName := "uts"
- createFlags.String(
- utsFlagName, "",
- "UTS namespace to use",
+ cgroupParentFlagName := "cgroup-parent"
+ createFlags.StringVar(
+ &cf.CGroupParent,
+ cgroupParentFlagName, "",
+ "Optional parent cgroup for the container",
)
- _ = cmd.RegisterFlagCompletionFunc(utsFlagName, AutocompleteNamespace)
+ _ = cmd.RegisterFlagCompletionFunc(cgroupParentFlagName, completion.AutocompleteDefault)
- mountFlagName := "mount"
- createFlags.StringArrayVar(
- &cf.Mount,
- mountFlagName, []string{},
- "Attach a filesystem mount to the container",
+ conmonPidfileFlagName := ""
+ if !isInfra {
+ conmonPidfileFlagName = "conmon-pidfile"
+ } else {
+ conmonPidfileFlagName = "infra-conmon-pidfile"
+ }
+ createFlags.StringVar(
+ &cf.ConmonPIDFile,
+ conmonPidfileFlagName, "",
+ "Path to the file that will receive the PID of conmon",
)
- _ = cmd.RegisterFlagCompletionFunc(mountFlagName, AutocompleteMountFlag)
+ _ = cmd.RegisterFlagCompletionFunc(conmonPidfileFlagName, completion.AutocompleteDefault)
- volumeDesciption := "Bind mount a volume into the container"
- if registry.IsRemote() {
- volumeDesciption = "Bind mount a volume into the container. Volume src will be on the server machine, not the client"
- }
- volumeFlagName := "volume"
- createFlags.StringArrayVarP(
- &cf.Volume,
- volumeFlagName, "v", volumes(),
- volumeDesciption,
+ cpusFlagName := "cpus"
+ createFlags.Float64Var(
+ &cf.CPUS,
+ cpusFlagName, 0,
+ "Number of CPUs. The default is 0.000 which means no limit",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(cpusFlagName, completion.AutocompleteNone)
+
+ cpusetCpusFlagName := "cpuset-cpus"
+ createFlags.StringVar(
+ &cf.CPUSetCPUs,
+ cpusetCpusFlagName, "",
+ "CPUs in which to allow execution (0-3, 0,1)",
)
- _ = cmd.RegisterFlagCompletionFunc(volumeFlagName, AutocompleteVolumeFlag)
+ _ = cmd.RegisterFlagCompletionFunc(cpusetCpusFlagName, completion.AutocompleteNone)
+
+ entrypointFlagName := ""
+ if !isInfra {
+ entrypointFlagName = "entrypoint"
+ } else {
+ entrypointFlagName = "infra-command"
+ }
- volumesFromFlagName := "volumes-from"
- createFlags.StringArrayVar(
- &cf.VolumesFrom,
- volumesFromFlagName, []string{},
- "Mount volumes from the specified container(s)",
+ createFlags.String(entrypointFlagName, "",
+ "Overwrite the default ENTRYPOINT of the image",
)
- _ = cmd.RegisterFlagCompletionFunc(volumesFromFlagName, AutocompleteContainers)
+ _ = cmd.RegisterFlagCompletionFunc(entrypointFlagName, completion.AutocompleteNone)
- workdirFlagName := "workdir"
+ hostnameFlagName := "hostname"
createFlags.StringVarP(
- &cf.Workdir,
- workdirFlagName, "w", "",
- "Working directory inside the container",
+ &cf.Hostname,
+ hostnameFlagName, "h", "",
+ "Set container hostname",
)
- _ = cmd.RegisterFlagCompletionFunc(workdirFlagName, completion.AutocompleteDefault)
+ _ = cmd.RegisterFlagCompletionFunc(hostnameFlagName, completion.AutocompleteNone)
- seccompPolicyFlagName := "seccomp-policy"
- createFlags.StringVar(
- &cf.SeccompPolicy,
- seccompPolicyFlagName, "default",
- "Policy for selecting a seccomp profile (experimental)",
+ labelFlagName := "label"
+ createFlags.StringArrayVarP(
+ &cf.Label,
+ labelFlagName, "l", []string{},
+ "Set metadata on container",
)
- _ = cmd.RegisterFlagCompletionFunc(seccompPolicyFlagName, completion.AutocompleteDefault)
+ _ = cmd.RegisterFlagCompletionFunc(labelFlagName, completion.AutocompleteNone)
- cgroupConfFlagName := "cgroup-conf"
+ labelFileFlagName := "label-file"
createFlags.StringSliceVar(
- &cf.CgroupConf,
- cgroupConfFlagName, []string{},
- "Configure cgroup v2 (key=value)",
+ &cf.LabelFile,
+ labelFileFlagName, []string{},
+ "Read in a line delimited file of labels",
)
- _ = cmd.RegisterFlagCompletionFunc(cgroupConfFlagName, completion.AutocompleteNone)
+ _ = cmd.RegisterFlagCompletionFunc(labelFileFlagName, completion.AutocompleteDefault)
- pidFileFlagName := "pidfile"
- createFlags.StringVar(
- &cf.PidFile,
- pidFileFlagName, "",
- "Write the container process ID to the file")
- _ = cmd.RegisterFlagCompletionFunc(pidFileFlagName, completion.AutocompleteDefault)
-
- _ = createFlags.MarkHidden("signature-policy")
- if registry.IsRemote() {
- _ = createFlags.MarkHidden("env-host")
- _ = createFlags.MarkHidden("http-proxy")
+ nameFlagName := ""
+ if !isInfra {
+ nameFlagName = "name"
+ createFlags.StringVar(
+ &cf.Name,
+ nameFlagName, "",
+ "Assign a name to the container",
+ )
+ } else {
+ nameFlagName = "infra-name"
+ createFlags.StringVar(
+ &cf.Name,
+ nameFlagName, "",
+ "Assign a name to the container",
+ )
}
+ _ = cmd.RegisterFlagCompletionFunc(nameFlagName, completion.AutocompleteNone)
+
+ createFlags.Bool(
+ "help", false, "",
+ )
+
+ pidFlagName := "pid"
+ createFlags.StringVar(
+ &cf.PID,
+ pidFlagName, "",
+ "PID namespace to use",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(pidFlagName, AutocompleteNamespace)
}
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index c94f46cf2..2f592cba7 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -19,122 +19,6 @@ import (
"github.com/pkg/errors"
)
-type ContainerCLIOpts struct {
- Annotation []string
- Attach []string
- Authfile string
- BlkIOWeight string
- BlkIOWeightDevice []string
- CapAdd []string
- CapDrop []string
- CgroupNS string
- CGroupsMode string
- CGroupParent string
- CIDFile string
- ConmonPIDFile string
- CPUPeriod uint64
- CPUQuota int64
- CPURTPeriod uint64
- CPURTRuntime int64
- CPUShares uint64
- CPUS float64
- CPUSetCPUs string
- CPUSetMems string
- Devices []string
- DeviceCGroupRule []string
- DeviceReadBPs []string
- DeviceReadIOPs []string
- DeviceWriteBPs []string
- DeviceWriteIOPs []string
- Entrypoint *string
- Env []string
- EnvHost bool
- EnvFile []string
- Expose []string
- GIDMap []string
- GroupAdd []string
- HealthCmd string
- HealthInterval string
- HealthRetries uint
- HealthStartPeriod string
- HealthTimeout string
- Hostname string
- HTTPProxy bool
- ImageVolume string
- Init bool
- InitContainerType string
- InitPath string
- Interactive bool
- IPC string
- KernelMemory string
- Label []string
- LabelFile []string
- LogDriver string
- LogOptions []string
- Memory string
- MemoryReservation string
- MemorySwap string
- MemorySwappiness int64
- Name string
- NoHealthCheck bool
- OOMKillDisable bool
- OOMScoreAdj int
- Arch string
- OS string
- Variant string
- Personality string
- PID string
- PIDsLimit *int64
- Platform string
- Pod string
- PodIDFile string
- PreserveFDs uint
- Privileged bool
- PublishAll bool
- Pull string
- Quiet bool
- ReadOnly bool
- ReadOnlyTmpFS bool
- Restart string
- Replace bool
- Requires []string
- Rm bool
- RootFS bool
- Secrets []string
- SecurityOpt []string
- SdNotifyMode string
- ShmSize string
- SignaturePolicy string
- StopSignal string
- StopTimeout uint
- StorageOpt []string
- SubUIDName string
- SubGIDName string
- Sysctl []string
- Systemd string
- Timeout uint
- TLSVerify bool
- TmpFS []string
- TTY bool
- Timezone string
- Umask string
- UIDMap []string
- Ulimit []string
- User string
- UserNS string
- UTS string
- Mount []string
- Volume []string
- VolumesFrom []string
- Workdir string
- SeccompPolicy string
- PidFile string
-
- Net *entities.NetOptions
-
- CgroupConf []string
-}
-
func stringMaptoArray(m map[string]string) []string {
a := make([]string, 0, len(m))
for k, v := range m {
@@ -145,7 +29,7 @@ func stringMaptoArray(m map[string]string) []string {
// ContainerCreateToContainerCLIOpts converts a compat input struct to cliopts so it can be converted to
// a specgen spec.
-func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*ContainerCLIOpts, []string, error) {
+func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*entities.ContainerCreateOptions, []string, error) {
var (
capAdd []string
cappDrop []string
@@ -341,7 +225,7 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
// Note: several options here are marked as "don't need". this is based
// on speculation by Matt and I. We think that these come into play later
// like with start. We believe this is just a difference in podman/compat
- cliOpts := ContainerCLIOpts{
+ cliOpts := entities.ContainerCreateOptions{
// Attach: nil, // don't need?
Authfile: "",
CapAdd: append(capAdd, cc.HostConfig.CapAdd...),
diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go
index aa8714b50..d11f3c9d2 100644
--- a/cmd/podman/common/netflags.go
+++ b/cmd/podman/common/netflags.go
@@ -8,8 +8,10 @@ import (
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/specgen"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/pkg/errors"
"github.com/spf13/cobra"
+ "github.com/spf13/pflag"
)
func DefineNetFlags(cmd *cobra.Command) {
@@ -87,12 +89,15 @@ func DefineNetFlags(cmd *cobra.Command) {
// NetFlagsToNetOptions parses the network flags for the given cmd.
// The netnsFromConfig bool is used to indicate if the --network flag
// should always be parsed regardless if it was set on the cli.
-func NetFlagsToNetOptions(cmd *cobra.Command, netnsFromConfig bool) (*entities.NetOptions, error) {
+func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet, netnsFromConfig bool) (*entities.NetOptions, error) {
var (
err error
)
- opts := entities.NetOptions{}
- opts.AddHosts, err = cmd.Flags().GetStringSlice("add-host")
+ if opts == nil {
+ opts = &entities.NetOptions{}
+ }
+
+ opts.AddHosts, err = flags.GetStringSlice("add-host")
if err != nil {
return nil, err
}
@@ -103,56 +108,50 @@ func NetFlagsToNetOptions(cmd *cobra.Command, netnsFromConfig bool) (*entities.N
}
}
- if cmd.Flags().Changed("dns") {
- servers, err := cmd.Flags().GetStringSlice("dns")
- if err != nil {
- return nil, err
- }
- for _, d := range servers {
- if d == "none" {
- opts.UseImageResolvConf = true
- if len(servers) > 1 {
- return nil, errors.Errorf("%s is not allowed to be specified with other DNS ip addresses", d)
- }
- break
- }
- dns := net.ParseIP(d)
- if dns == nil {
- return nil, errors.Errorf("%s is not an ip address", d)
+ servers, err := flags.GetStringSlice("dns")
+ if err != nil {
+ return nil, err
+ }
+ for _, d := range servers {
+ if d == "none" {
+ opts.UseImageResolvConf = true
+ if len(servers) > 1 {
+ return nil, errors.Errorf("%s is not allowed to be specified with other DNS ip addresses", d)
}
- opts.DNSServers = append(opts.DNSServers, dns)
+ break
+ }
+ dns := net.ParseIP(d)
+ if dns == nil {
+ return nil, errors.Errorf("%s is not an ip address", d)
}
+ opts.DNSServers = append(opts.DNSServers, dns)
}
- if cmd.Flags().Changed("dns-opt") {
- options, err := cmd.Flags().GetStringSlice("dns-opt")
- if err != nil {
- return nil, err
- }
- opts.DNSOptions = options
+ options, err := flags.GetStringSlice("dns-opt")
+ if err != nil {
+ return nil, err
}
+ opts.DNSOptions = options
- if cmd.Flags().Changed("dns-search") {
- dnsSearches, err := cmd.Flags().GetStringSlice("dns-search")
- if err != nil {
- return nil, err
- }
- // Validate domains are good
- for _, dom := range dnsSearches {
- if dom == "." {
- if len(dnsSearches) > 1 {
- return nil, errors.Errorf("cannot pass additional search domains when also specifying '.'")
- }
- continue
- }
- if _, err := parse.ValidateDomain(dom); err != nil {
- return nil, err
+ dnsSearches, err := flags.GetStringSlice("dns-search")
+ if err != nil {
+ return nil, err
+ }
+ // Validate domains are good
+ for _, dom := range dnsSearches {
+ if dom == "." {
+ if len(dnsSearches) > 1 {
+ return nil, errors.Errorf("cannot pass additional search domains when also specifying '.'")
}
+ continue
+ }
+ if _, err := parse.ValidateDomain(dom); err != nil {
+ return nil, err
}
- opts.DNSSearch = dnsSearches
}
+ opts.DNSSearch = dnsSearches
- m, err := cmd.Flags().GetString("mac-address")
+ m, err := flags.GetString("mac-address")
if err != nil {
return nil, err
}
@@ -164,18 +163,18 @@ func NetFlagsToNetOptions(cmd *cobra.Command, netnsFromConfig bool) (*entities.N
opts.StaticMAC = &mac
}
- inputPorts, err := cmd.Flags().GetStringSlice("publish")
+ inputPorts, err := flags.GetStringSlice("publish")
if err != nil {
return nil, err
}
if len(inputPorts) > 0 {
- opts.PublishPorts, err = CreatePortBindings(inputPorts)
+ opts.PublishPorts, err = specgenutil.CreatePortBindings(inputPorts)
if err != nil {
return nil, err
}
}
- ip, err := cmd.Flags().GetString("ip")
+ ip, err := flags.GetString("ip")
if err != nil {
return nil, err
}
@@ -190,15 +189,15 @@ func NetFlagsToNetOptions(cmd *cobra.Command, netnsFromConfig bool) (*entities.N
opts.StaticIP = &staticIP
}
- opts.NoHosts, err = cmd.Flags().GetBool("no-hosts")
+ opts.NoHosts, err = flags.GetBool("no-hosts")
if err != nil {
return nil, err
}
// parse the --network value only when the flag is set or we need to use
// the netns config value, e.g. when --pod is not used
- if netnsFromConfig || cmd.Flag("network").Changed {
- network, err := cmd.Flags().GetString("network")
+ if netnsFromConfig || flags.Changed("network") {
+ network, err := flags.GetString("network")
if err != nil {
return nil, err
}
@@ -215,12 +214,13 @@ func NetFlagsToNetOptions(cmd *cobra.Command, netnsFromConfig bool) (*entities.N
opts.CNINetworks = cniNets
}
- aliases, err := cmd.Flags().GetStringSlice("network-alias")
+ aliases, err := flags.GetStringSlice("network-alias")
if err != nil {
return nil, err
}
if len(aliases) > 0 {
opts.Aliases = aliases
}
- return &opts, err
+
+ return opts, err
}
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 7583a024e..8b27de53e 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -17,6 +17,7 @@ import (
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/specgen"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@@ -52,8 +53,8 @@ var (
)
var (
- cliVals common.ContainerCLIOpts
InitContainerType string
+ cliVals entities.ContainerCreateOptions
)
func createFlags(cmd *cobra.Command) {
@@ -67,13 +68,18 @@ func createFlags(cmd *cobra.Command) {
)
flags.SetInterspersed(false)
- common.DefineCreateFlags(cmd, &cliVals)
+ common.DefineCreateFlags(cmd, &cliVals, false)
common.DefineNetFlags(cmd)
flags.SetNormalizeFunc(utils.AliasFlags)
if registry.IsRemote() {
- _ = flags.MarkHidden("conmon-pidfile")
+ if cliVals.IsInfra {
+ _ = flags.MarkHidden("infra-conmon-pidfile")
+ } else {
+ _ = flags.MarkHidden("conmon-pidfile")
+ }
+
_ = flags.MarkHidden("pidfile")
}
@@ -97,7 +103,8 @@ func create(cmd *cobra.Command, args []string) error {
var (
err error
)
- cliVals.Net, err = common.NetFlagsToNetOptions(cmd, cliVals.Pod == "" && cliVals.PodIDFile == "")
+ flags := cmd.Flags()
+ cliVals.Net, err = common.NetFlagsToNetOptions(nil, *flags, cliVals.Pod == "" && cliVals.PodIDFile == "")
if err != nil {
return err
}
@@ -113,22 +120,22 @@ func create(cmd *cobra.Command, args []string) error {
cliVals.InitContainerType = initctr
}
- if err := createInit(cmd); err != nil {
+ cliVals, err = CreateInit(cmd, cliVals, false)
+ if err != nil {
return err
}
-
imageName := args[0]
rawImageName := ""
if !cliVals.RootFS {
rawImageName = args[0]
- name, err := pullImage(args[0])
+ name, err := PullImage(args[0], cliVals)
if err != nil {
return err
}
imageName = name
}
s := specgen.NewSpecGenerator(imageName, cliVals.RootFS)
- if err := common.FillOutSpecGen(s, &cliVals, args); err != nil {
+ if err := specgenutil.FillOutSpecGen(s, &cliVals, args); err != nil {
return err
}
s.RawImageName = rawImageName
@@ -169,100 +176,101 @@ func replaceContainer(name string) error {
return removeContainers([]string{name}, rmOptions, false)
}
-func createInit(c *cobra.Command) error {
- cliVals.StorageOpt = registry.PodmanConfig().StorageOpts
-
- if c.Flag("shm-size").Changed {
- cliVals.ShmSize = c.Flag("shm-size").Value.String()
+func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra bool) (entities.ContainerCreateOptions, error) {
+ vals.UserNS = c.Flag("userns").Value.String()
+ // if user did not modify --userns flag and did turn on
+ // uid/gid mappings, set userns flag to "private"
+ if !c.Flag("userns").Changed && vals.UserNS == "host" {
+ if len(vals.UIDMap) > 0 ||
+ len(vals.GIDMap) > 0 ||
+ vals.SubUIDName != "" ||
+ vals.SubGIDName != "" {
+ vals.UserNS = "private"
+ }
}
- if (c.Flag("dns").Changed || c.Flag("dns-opt").Changed || c.Flag("dns-search").Changed) && (cliVals.Net.Network.NSMode == specgen.NoNetwork || cliVals.Net.Network.IsContainer()) {
- return errors.Errorf("conflicting options: dns and the network mode.")
- }
+ if !isInfra {
+ if c.Flag("shm-size").Changed {
+ vals.ShmSize = c.Flag("shm-size").Value.String()
+ }
+ if c.Flag("cpu-period").Changed && c.Flag("cpus").Changed {
+ return vals, errors.Errorf("--cpu-period and --cpus cannot be set together")
+ }
+ if c.Flag("cpu-quota").Changed && c.Flag("cpus").Changed {
+ return vals, errors.Errorf("--cpu-quota and --cpus cannot be set together")
+ }
+ vals.IPC = c.Flag("ipc").Value.String()
+ vals.UTS = c.Flag("uts").Value.String()
+ vals.PID = c.Flag("pid").Value.String()
+ vals.CgroupNS = c.Flag("cgroupns").Value.String()
+
+ if c.Flags().Changed("group-add") {
+ groups := []string{}
+ for _, g := range cliVals.GroupAdd {
+ if g == "keep-groups" {
+ if len(cliVals.GroupAdd) > 1 {
+ return vals, errors.New("the '--group-add keep-groups' option is not allowed with any other --group-add options")
+ }
+ if registry.IsRemote() {
+ return vals, errors.New("the '--group-add keep-groups' option is not supported in remote mode")
+ }
+ vals.Annotation = append(vals.Annotation, "run.oci.keep_original_groups=1")
+ } else {
+ groups = append(groups, g)
+ }
+ }
+ vals.GroupAdd = groups
+ }
- if c.Flag("cpu-period").Changed && c.Flag("cpus").Changed {
- return errors.Errorf("--cpu-period and --cpus cannot be set together")
- }
- if c.Flag("cpu-quota").Changed && c.Flag("cpus").Changed {
- return errors.Errorf("--cpu-quota and --cpus cannot be set together")
+ if c.Flags().Changed("pids-limit") {
+ val := c.Flag("pids-limit").Value.String()
+ pidsLimit, err := strconv.ParseInt(val, 10, 32)
+ if err != nil {
+ return vals, err
+ }
+ vals.PIDsLimit = &pidsLimit
+ }
+ if c.Flags().Changed("env") {
+ env, err := c.Flags().GetStringArray("env")
+ if err != nil {
+ return vals, errors.Wrapf(err, "retrieve env flag")
+ }
+ vals.Env = env
+ }
+ if c.Flag("cgroups").Changed && vals.CGroupsMode == "split" && registry.IsRemote() {
+ return vals, errors.Errorf("the option --cgroups=%q is not supported in remote mode", vals.CGroupsMode)
+ }
+
+ if c.Flag("pod").Changed && !strings.HasPrefix(c.Flag("pod").Value.String(), "new:") && c.Flag("userns").Changed {
+ return vals, errors.Errorf("--userns and --pod cannot be set together")
+ }
}
- if c.Flag("pod").Changed && !strings.HasPrefix(c.Flag("pod").Value.String(), "new:") && c.Flag("userns").Changed {
- return errors.Errorf("--userns and --pod cannot be set together")
+ if (c.Flag("dns").Changed || c.Flag("dns-opt").Changed || c.Flag("dns-search").Changed) && vals.Net != nil && (vals.Net.Network.NSMode == specgen.NoNetwork || vals.Net.Network.IsContainer()) {
+ return vals, errors.Errorf("conflicting options: dns and the network mode: " + string(vals.Net.Network.NSMode))
}
-
noHosts, err := c.Flags().GetBool("no-hosts")
if err != nil {
- return err
+ return vals, err
}
if noHosts && c.Flag("add-host").Changed {
- return errors.Errorf("--no-hosts and --add-host cannot be set together")
- }
- cliVals.UserNS = c.Flag("userns").Value.String()
- // if user did not modify --userns flag and did turn on
- // uid/gid mappings, set userns flag to "private"
- if !c.Flag("userns").Changed && cliVals.UserNS == "host" {
- if len(cliVals.UIDMap) > 0 ||
- len(cliVals.GIDMap) > 0 ||
- cliVals.SubUIDName != "" ||
- cliVals.SubGIDName != "" {
- cliVals.UserNS = "private"
- }
+ return vals, errors.Errorf("--no-hosts and --add-host cannot be set together")
}
- cliVals.IPC = c.Flag("ipc").Value.String()
- cliVals.UTS = c.Flag("uts").Value.String()
- cliVals.PID = c.Flag("pid").Value.String()
- cliVals.CgroupNS = c.Flag("cgroupns").Value.String()
- if c.Flag("entrypoint").Changed {
+ if !isInfra && c.Flag("entrypoint").Changed {
val := c.Flag("entrypoint").Value.String()
- cliVals.Entrypoint = &val
- }
-
- if c.Flags().Changed("group-add") {
- groups := []string{}
- for _, g := range cliVals.GroupAdd {
- if g == "keep-groups" {
- if len(cliVals.GroupAdd) > 1 {
- return errors.New("the '--group-add keep-groups' option is not allowed with any other --group-add options")
- }
- if registry.IsRemote() {
- return errors.New("the '--group-add keep-groups' option is not supported in remote mode")
- }
- cliVals.Annotation = append(cliVals.Annotation, "run.oci.keep_original_groups=1")
- } else {
- groups = append(groups, g)
- }
- }
- cliVals.GroupAdd = groups
- }
+ vals.Entrypoint = &val
+ } else if isInfra && c.Flag("infra-command").Changed {
- if c.Flags().Changed("pids-limit") {
- val := c.Flag("pids-limit").Value.String()
- pidsLimit, err := strconv.ParseInt(val, 10, 32)
- if err != nil {
- return err
- }
- cliVals.PIDsLimit = &pidsLimit
- }
- if c.Flags().Changed("env") {
- env, err := c.Flags().GetStringArray("env")
- if err != nil {
- return errors.Wrapf(err, "retrieve env flag")
- }
- cliVals.Env = env
- }
- if c.Flag("cgroups").Changed && cliVals.CGroupsMode == "split" && registry.IsRemote() {
- return errors.Errorf("the option --cgroups=%q is not supported in remote mode", cliVals.CGroupsMode)
}
// Docker-compatibility: the "-h" flag for run/create is reserved for
// the hostname (see https://github.com/containers/podman/issues/1367).
- return nil
+ return vals, nil
}
-func pullImage(imageName string) (string, error) {
- pullPolicy, err := config.ParsePullPolicy(cliVals.Pull)
+func PullImage(imageName string, cliVals entities.ContainerCreateOptions) (string, error) {
+ pullPolicy, err := config.ValidatePullPolicy(cliVals.Pull)
if err != nil {
return "", err
}
@@ -316,11 +324,14 @@ func createPodIfNecessary(s *specgen.SpecGenerator, netOpts *entities.NetOptions
return nil, errors.Errorf("new pod name must be at least one character")
}
- userns, err := specgen.ParseUserNamespace(cliVals.UserNS)
- if err != nil {
- return nil, err
+ var err error
+ uns := specgen.Namespace{NSMode: specgen.Default}
+ if cliVals.UserNS != "" {
+ uns, err = specgen.ParseNamespace(cliVals.UserNS)
+ if err != nil {
+ return nil, err
+ }
}
-
createOptions := entities.PodCreateOptions{
Name: podName,
Infra: true,
@@ -330,12 +341,36 @@ func createPodIfNecessary(s *specgen.SpecGenerator, netOpts *entities.NetOptions
Cpus: cliVals.CPUS,
CpusetCpus: cliVals.CPUSetCPUs,
Pid: cliVals.PID,
- Userns: userns,
+ Userns: uns,
}
// Unset config values we passed to the pod to prevent them being used twice for the container and pod.
s.ContainerBasicConfig.Hostname = ""
s.ContainerNetworkConfig = specgen.ContainerNetworkConfig{}
s.Pod = podName
- return registry.ContainerEngine().PodCreate(context.Background(), createOptions)
+ podSpec := entities.PodSpec{}
+ podGen := specgen.NewPodSpecGenerator()
+ podSpec.PodSpecGen = *podGen
+ podGen, err = entities.ToPodSpecGen(*&podSpec.PodSpecGen, &createOptions)
+ if err != nil {
+ return nil, err
+ }
+
+ infraOpts := entities.ContainerCreateOptions{ImageVolume: "bind", Net: netOpts, Quiet: true}
+ rawImageName := config.DefaultInfraImage
+ name, err := PullImage(rawImageName, infraOpts)
+ if err != nil {
+ fmt.Println(err)
+ }
+ imageName := name
+ podGen.InfraImage = imageName
+ podGen.InfraContainerSpec = specgen.NewSpecGenerator(imageName, false)
+ podGen.InfraContainerSpec.RawImageName = rawImageName
+ podGen.InfraContainerSpec.NetworkOptions = podGen.NetworkOptions
+ err = specgenutil.FillOutSpecGen(podGen.InfraContainerSpec, &infraOpts, []string{})
+ if err != nil {
+ return nil, err
+ }
+ podSpec.PodSpecGen = *podGen
+ return registry.ContainerEngine().PodCreate(context.Background(), podSpec)
}
diff --git a/cmd/podman/containers/prune.go b/cmd/podman/containers/prune.go
index e55bd8a53..e13b9e7f6 100644
--- a/cmd/podman/containers/prune.go
+++ b/cmd/podman/containers/prune.go
@@ -13,6 +13,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/spf13/cobra"
)
@@ -63,7 +64,7 @@ func prune(cmd *cobra.Command, args []string) error {
}
}
- pruneOptions.Filters, err = common.ParseFilters(filter)
+ pruneOptions.Filters, err = specgenutil.ParseFilters(filter)
if err != nil {
return err
}
diff --git a/cmd/podman/containers/restore.go b/cmd/podman/containers/restore.go
index 3b6f74efa..05214f32c 100644
--- a/cmd/podman/containers/restore.go
+++ b/cmd/podman/containers/restore.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/rootless"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -106,7 +107,7 @@ func restore(cmd *cobra.Command, args []string) error {
return err
}
if len(inputPorts) > 0 {
- restoreOptions.PublishPorts, err = common.CreatePortBindings(inputPorts)
+ restoreOptions.PublishPorts, err = specgenutil.CreatePortBindings(inputPorts)
if err != nil {
return err
}
diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go
index 830d1de7f..d14961829 100644
--- a/cmd/podman/containers/run.go
+++ b/cmd/podman/containers/run.go
@@ -14,6 +14,7 @@ import (
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/specgen"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -60,7 +61,7 @@ func runFlags(cmd *cobra.Command) {
flags := cmd.Flags()
flags.SetInterspersed(false)
- common.DefineCreateFlags(cmd, &cliVals)
+ common.DefineCreateFlags(cmd, &cliVals, false)
common.DefineNetFlags(cmd)
flags.SetNormalizeFunc(utils.AliasFlags)
@@ -106,10 +107,6 @@ func init() {
func run(cmd *cobra.Command, args []string) error {
var err error
- cliVals.Net, err = common.NetFlagsToNetOptions(cmd, cliVals.Pod == "" && cliVals.PodIDFile == "")
- if err != nil {
- return err
- }
// TODO: Breaking change should be made fatal in next major Release
if cliVals.TTY && cliVals.Interactive && !terminal.IsTerminal(int(os.Stdin.Fd())) {
@@ -122,11 +119,17 @@ func run(cmd *cobra.Command, args []string) error {
}
}
+ flags := cmd.Flags()
+ cliVals.Net, err = common.NetFlagsToNetOptions(nil, *flags, cliVals.Pod == "" && cliVals.PodIDFile == "")
+ if err != nil {
+ return err
+ }
runOpts.CIDFile = cliVals.CIDFile
runOpts.Rm = cliVals.Rm
- if err := createInit(cmd); err != nil {
+ if cliVals, err = CreateInit(cmd, cliVals, false); err != nil {
return err
}
+
for fd := 3; fd < int(3+runOpts.PreserveFDs); fd++ {
if !rootless.IsFdInherited(fd) {
return errors.Errorf("file descriptor %d is not available - the preserve-fds option requires that file descriptors must be passed", fd)
@@ -137,7 +140,7 @@ func run(cmd *cobra.Command, args []string) error {
rawImageName := ""
if !cliVals.RootFS {
rawImageName = args[0]
- name, err := pullImage(args[0])
+ name, err := PullImage(args[0], cliVals)
if err != nil {
return err
}
@@ -178,7 +181,7 @@ func run(cmd *cobra.Command, args []string) error {
}
cliVals.PreserveFDs = runOpts.PreserveFDs
s := specgen.NewSpecGenerator(imageName, cliVals.RootFS)
- if err := common.FillOutSpecGen(s, &cliVals, args); err != nil {
+ if err := specgenutil.FillOutSpecGen(s, &cliVals, args); err != nil {
return err
}
s.RawImageName = rawImageName
diff --git a/cmd/podman/images/prune.go b/cmd/podman/images/prune.go
index 6ecf4f2aa..8a484495a 100644
--- a/cmd/podman/images/prune.go
+++ b/cmd/podman/images/prune.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/spf13/cobra"
)
@@ -59,7 +60,7 @@ func prune(cmd *cobra.Command, args []string) error {
return nil
}
}
- filterMap, err := common.ParseFilters(filter)
+ filterMap, err := specgenutil.ParseFilters(filter)
if err != nil {
return err
}
diff --git a/cmd/podman/networks/prune.go b/cmd/podman/networks/prune.go
index e6b779ded..311d098cd 100644
--- a/cmd/podman/networks/prune.go
+++ b/cmd/podman/networks/prune.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
@@ -67,7 +68,7 @@ func networkPrune(cmd *cobra.Command, _ []string) error {
return nil
}
}
- networkPruneOptions.Filters, err = common.ParseFilters(filter)
+ networkPruneOptions.Filters, err = specgenutil.ParseFilters(filter)
if err != nil {
return err
}
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index bf5b9e350..b3f84dcd8 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -11,14 +11,17 @@ import (
"strings"
"github.com/containers/common/pkg/completion"
+ "github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/sysinfo"
"github.com/containers/podman/v3/cmd/podman/common"
+ "github.com/containers/podman/v3/cmd/podman/containers"
"github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/containers/podman/v3/pkg/specgen"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/containers/podman/v3/pkg/util"
"github.com/docker/docker/pkg/parsers"
"github.com/pkg/errors"
@@ -44,11 +47,11 @@ var (
var (
createOptions entities.PodCreateOptions
+ infraOptions entities.ContainerCreateOptions
labels, labelFile []string
podIDFile string
replace bool
share string
- userns string
)
func init() {
@@ -58,62 +61,19 @@ func init() {
})
flags := createCommand.Flags()
flags.SetInterspersed(false)
-
+ infraOptions.IsInfra = true
+ common.DefineCreateFlags(createCommand, &infraOptions, true)
common.DefineNetFlags(createCommand)
- cpusetflagName := "cpuset-cpus"
- flags.StringVar(&createOptions.CpusetCpus, cpusetflagName, "", "CPUs in which to allow execution")
- _ = createCommand.RegisterFlagCompletionFunc(cpusetflagName, completion.AutocompleteDefault)
-
- cpusflagName := "cpus"
- flags.Float64Var(&createOptions.Cpus, cpusflagName, 0.000, "set amount of CPUs for the pod")
- _ = createCommand.RegisterFlagCompletionFunc(cpusflagName, completion.AutocompleteDefault)
-
- cgroupParentflagName := "cgroup-parent"
- flags.StringVar(&createOptions.CGroupParent, cgroupParentflagName, "", "Set parent cgroup for the pod")
- _ = createCommand.RegisterFlagCompletionFunc(cgroupParentflagName, completion.AutocompleteDefault)
-
- usernsFlagName := "userns"
- flags.StringVar(&userns, usernsFlagName, os.Getenv("PODMAN_USERNS"), "User namespace to use")
- _ = createCommand.RegisterFlagCompletionFunc(usernsFlagName, common.AutocompleteUserNamespace)
-
flags.BoolVar(&createOptions.Infra, "infra", true, "Create an infra container associated with the pod to share namespaces with")
- infraConmonPidfileFlagName := "infra-conmon-pidfile"
- flags.StringVar(&createOptions.InfraConmonPidFile, infraConmonPidfileFlagName, "", "Path to the file that will receive the POD of the infra container's conmon")
- _ = createCommand.RegisterFlagCompletionFunc(infraConmonPidfileFlagName, completion.AutocompleteDefault)
-
- infraImageFlagName := "infra-image"
- flags.String(infraImageFlagName, containerConfig.Engine.InfraImage, "The image of the infra container to associate with the pod")
- _ = createCommand.RegisterFlagCompletionFunc(infraImageFlagName, common.AutocompleteImages)
-
- infraCommandFlagName := "infra-command"
- flags.String(infraCommandFlagName, containerConfig.Engine.InfraCommand, "The command to run on the infra container when the pod is started")
- _ = createCommand.RegisterFlagCompletionFunc(infraCommandFlagName, completion.AutocompleteNone)
-
- infraNameFlagName := "infra-name"
- flags.StringVarP(&createOptions.InfraName, infraNameFlagName, "", "", "The name used as infra container name")
- _ = createCommand.RegisterFlagCompletionFunc(infraNameFlagName, completion.AutocompleteNone)
-
- labelFileFlagName := "label-file"
- flags.StringSliceVar(&labelFile, labelFileFlagName, []string{}, "Read in a line delimited file of labels")
- _ = createCommand.RegisterFlagCompletionFunc(labelFileFlagName, completion.AutocompleteDefault)
-
- labelFlagName := "label"
- flags.StringSliceVarP(&labels, labelFlagName, "l", []string{}, "Set metadata on pod (default [])")
- _ = createCommand.RegisterFlagCompletionFunc(labelFlagName, completion.AutocompleteNone)
-
nameFlagName := "name"
flags.StringVarP(&createOptions.Name, nameFlagName, "n", "", "Assign a name to the pod")
_ = createCommand.RegisterFlagCompletionFunc(nameFlagName, completion.AutocompleteNone)
- hostnameFlagName := "hostname"
- flags.StringVarP(&createOptions.Hostname, hostnameFlagName, "", "", "Set a hostname to the pod")
- _ = createCommand.RegisterFlagCompletionFunc(hostnameFlagName, completion.AutocompleteNone)
-
- pidFlagName := "pid"
- flags.StringVar(&createOptions.Pid, pidFlagName, "", "PID namespace to use")
- _ = createCommand.RegisterFlagCompletionFunc(pidFlagName, common.AutocompleteNamespace)
+ infraImageFlagName := "infra-image"
+ flags.String(infraImageFlagName, containerConfig.Engine.InfraImage, "The image of the infra container to associate with the pod")
+ _ = createCommand.RegisterFlagCompletionFunc(infraImageFlagName, common.AutocompleteImages)
podIDFileFlagName := "pod-id-file"
flags.StringVar(&podIDFile, podIDFileFlagName, "", "Write the pod ID to the file")
@@ -137,25 +97,30 @@ func aliasNetworkFlag(_ *pflag.FlagSet, name string) pflag.NormalizedName {
func create(cmd *cobra.Command, args []string) error {
var (
- err error
- podIDFD *os.File
+ err error
+ podIDFD *os.File
+ imageName string
+ rawImageName string
)
+ labelFile = infraOptions.LabelFile
+ labels = infraOptions.Label
createOptions.Labels, err = parse.GetAllLabels(labelFile, labels)
if err != nil {
return errors.Wrapf(err, "unable to process labels")
}
+ imageName = config.DefaultInfraImage
+ img := imageName
if !createOptions.Infra {
- logrus.Debugf("Not creating an infra container")
- if cmd.Flag("infra-conmon-pidfile").Changed {
- return errors.New("cannot set infra-conmon-pid without an infra container")
+ if cmd.Flag("no-hosts").Changed {
+ return fmt.Errorf("cannot specify no-hosts without an infra container")
}
- if cmd.Flag("infra-command").Changed {
- return errors.New("cannot set infra-command without an infra container")
- }
- if cmd.Flag("infra-image").Changed {
- return errors.New("cannot set infra-image without an infra container")
+ flags := cmd.Flags()
+ createOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags, false)
+ if err != nil {
+ return err
}
+ logrus.Debugf("Not creating an infra container")
createOptions.InfraImage = ""
if createOptions.InfraName != "" {
return errors.New("cannot set infra-name without an infra container")
@@ -166,28 +131,43 @@ func create(cmd *cobra.Command, args []string) error {
}
createOptions.Share = nil
} else {
+ // reassign certain optios for lbpod api, these need to be populated in spec
+ createOptions.InfraConmonPidFile = infraOptions.ConmonPIDFile
+ createOptions.InfraName = infraOptions.Name
+ createOptions.Hostname = infraOptions.Hostname
+ createOptions.Cpus = infraOptions.CPUS
+ createOptions.CpusetCpus = infraOptions.CPUSetCPUs
+ createOptions.Pid = infraOptions.PID
+ flags := cmd.Flags()
+ infraOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags, false)
+ if err != nil {
+ return err
+ }
+ infraOptions, err = containers.CreateInit(cmd, infraOptions, true)
+ if err != nil {
+ return err
+ }
+ createOptions.Net = infraOptions.Net
createOptions.Share = strings.Split(share, ",")
if cmd.Flag("infra-command").Changed {
// Only send content to server side if user changed defaults
- createOptions.InfraCommand, err = cmd.Flags().GetString("infra-command")
+ cmdIn, err := cmd.Flags().GetString("infra-command")
+ infraOptions.Entrypoint = &cmdIn
+ createOptions.InfraCommand = cmdIn
if err != nil {
return err
}
}
if cmd.Flag("infra-image").Changed {
// Only send content to server side if user changed defaults
- createOptions.InfraImage, err = cmd.Flags().GetString("infra-image")
+ img, err = cmd.Flags().GetString("infra-image")
+ imageName = img
if err != nil {
return err
}
}
}
- createOptions.Userns, err = specgen.ParseUserNamespace(userns)
- if err != nil {
- return err
- }
-
if cmd.Flag("pod-id-file").Changed {
podIDFD, err = util.OpenExclusiveFile(podIDFile)
if err != nil && os.IsExist(err) {
@@ -200,13 +180,6 @@ func create(cmd *cobra.Command, args []string) error {
defer errorhandling.SyncQuiet(podIDFD)
}
- createOptions.Pid = cmd.Flag("pid").Value.String()
-
- createOptions.Net, err = common.NetFlagsToNetOptions(cmd, createOptions.Infra)
- if err != nil {
- return err
- }
-
if len(createOptions.Net.PublishPorts) > 0 {
if !createOptions.Infra {
return errors.Errorf("you must have an infra container to publish port bindings to the host")
@@ -261,10 +234,44 @@ func create(cmd *cobra.Command, args []string) error {
copy = "" + strconv.Itoa(core)
}
}
- response, err := registry.ContainerEngine().PodCreate(context.Background(), createOptions)
+ podSpec := specgen.NewPodSpecGenerator()
+ podSpec, err = entities.ToPodSpecGen(*podSpec, &createOptions)
if err != nil {
return err
}
+ if createOptions.Infra {
+ rawImageName = img
+ if !infraOptions.RootFS {
+ curr := infraOptions.Quiet
+ infraOptions.Quiet = true
+ name, err := containers.PullImage(imageName, infraOptions)
+ if err != nil {
+ fmt.Println(err)
+ }
+ imageName = name
+ infraOptions.Quiet = curr
+ }
+ podSpec.InfraImage = imageName
+ if infraOptions.Entrypoint != nil {
+ createOptions.InfraCommand = *infraOptions.Entrypoint
+ }
+ infraOptions.CPUS = createOptions.Cpus
+ infraOptions.CPUSetCPUs = createOptions.CpusetCpus
+ infraOptions.PID = createOptions.Pid
+ podSpec.InfraContainerSpec = specgen.NewSpecGenerator(imageName, false)
+ podSpec.InfraContainerSpec.RawImageName = rawImageName
+ podSpec.InfraContainerSpec.NetworkOptions = podSpec.NetworkOptions
+ err = specgenutil.FillOutSpecGen(podSpec.InfraContainerSpec, &infraOptions, []string{})
+ if err != nil {
+ return err
+ }
+ }
+ PodSpec := entities.PodSpec{PodSpecGen: *podSpec}
+ response, err := registry.ContainerEngine().PodCreate(context.Background(), PodSpec)
+ if err != nil {
+ return err
+ }
+
if len(podIDFile) > 0 {
if err = ioutil.WriteFile(podIDFile, []byte(response.Id), 0644); err != nil {
return errors.Wrapf(err, "failed to write pod ID to file")
diff --git a/cmd/podman/pods/rm.go b/cmd/podman/pods/rm.go
index fbaf64c1f..dc4c7eb83 100644
--- a/cmd/podman/pods/rm.go
+++ b/cmd/podman/pods/rm.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -66,7 +67,7 @@ func init() {
}
func rm(_ *cobra.Command, args []string) error {
- ids, err := common.ReadPodIDFiles(rmOptions.PodIDFiles)
+ ids, err := specgenutil.ReadPodIDFiles(rmOptions.PodIDFiles)
if err != nil {
return err
}
diff --git a/cmd/podman/pods/start.go b/cmd/podman/pods/start.go
index e39891a9b..e5f9eaa84 100644
--- a/cmd/podman/pods/start.go
+++ b/cmd/podman/pods/start.go
@@ -10,6 +10,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/spf13/cobra"
)
@@ -64,7 +65,7 @@ func start(cmd *cobra.Command, args []string) error {
errs utils.OutputErrors
)
- ids, err := common.ReadPodIDFiles(startOptions.PodIDFiles)
+ ids, err := specgenutil.ReadPodIDFiles(startOptions.PodIDFiles)
if err != nil {
return err
}
diff --git a/cmd/podman/pods/stop.go b/cmd/podman/pods/stop.go
index bcc054b8e..41325649f 100644
--- a/cmd/podman/pods/stop.go
+++ b/cmd/podman/pods/stop.go
@@ -10,6 +10,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/spf13/cobra"
)
@@ -78,7 +79,7 @@ func stop(cmd *cobra.Command, args []string) error {
stopOptions.Timeout = int(stopOptions.TimeoutCLI)
}
- ids, err := common.ReadPodIDFiles(stopOptions.PodIDFiles)
+ ids, err := specgenutil.ReadPodIDFiles(stopOptions.PodIDFiles)
if err != nil {
return err
}
diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md
index 4e822dca5..fc7d39754 100644
--- a/docs/source/markdown/podman-pod-create.1.md
+++ b/docs/source/markdown/podman-pod-create.1.md
@@ -51,7 +51,26 @@ Set custom DNS options in the /etc/resolv.conf file that will be shared between
Set custom DNS search domains in the /etc/resolv.conf file that will be shared between all containers in the pod.
-#### **--help**
+#### **--gidmap**=*container_gid:host_gid:amount*
+
+GID map for the user namespace. Using this flag will run the container with user namespace enabled. It conflicts with the `--userns` and `--subgidname` flags.
+
+#### **--uidmap**=*container_uid*:*from_uid*:*amount*
+
+Run the container in a new user namespace using the supplied mapping. This
+option conflicts with the **--userns** and **--subuidname** options. This
+option provides a way to map host UIDs to container UIDs. It can be passed
+several times to map different ranges.
+
+#### **--subgidname**=*name*
+
+Name for GID map from the `/etc/subgid` file. Using this flag will run the container with user namespace enabled. This flag conflicts with `--userns` and `--gidmap`.
+
+#### **--subuidname**=*name*
+
+Name for UID map from the `/etc/subuid` file. Using this flag will run the container with user namespace enabled. This flag conflicts with `--userns` and `--uidmap`.
+
+#### **--help**, **-h**
Print usage statement.
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 3f7a4807d..6717ada59 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -972,11 +972,12 @@ func (c *Container) checkDependenciesRunning() ([]string, error) {
}
// Check the status
+ conf := depCtr.Config()
state, err := depCtr.State()
if err != nil {
return nil, errors.Wrapf(err, "error retrieving state of dependency %s of container %s", dep, c.ID())
}
- if state != define.ContainerStateRunning {
+ if state != define.ContainerStateRunning && !conf.IsInfra {
notRunning = append(notRunning, dep)
}
depCtrs[dep] = depCtr
diff --git a/libpod/kube.go b/libpod/kube.go
index a3f49bfe8..fff040adb 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -10,6 +10,8 @@ import (
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/lookup"
+ "github.com/containers/podman/v3/pkg/namespaces"
+ "github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/opencontainers/runtime-spec/specs-go"
@@ -72,7 +74,7 @@ func (p *Pod) GenerateForKube() (*v1.Pod, []v1.ServicePort, error) {
return nil, servicePorts, err
}
servicePorts = containerPortsToServicePorts(ports)
- hostNetwork = p.config.InfraContainer.HostNetwork
+ hostNetwork = infraContainer.NetworkMode() == string(namespaces.NetworkMode(specgen.Host))
}
pod, err := p.podWithContainers(allContainers, ports, hostNetwork)
if err != nil {
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index dbe2274d3..5ade0849d 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -632,7 +632,6 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re
}
podName := getCNIPodName(ctr)
-
networks, _, err := ctr.networks()
if err != nil {
return nil, err
diff --git a/libpod/options.go b/libpod/options.go
index 0bcd1e3a6..4cbd2b5e2 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -14,6 +14,7 @@ import (
"github.com/containers/image/v5/types"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/events"
+ netTypes "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/namespaces"
"github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/specgen"
@@ -21,7 +22,6 @@ import (
"github.com/containers/storage"
"github.com/containers/storage/pkg/idtools"
"github.com/cri-o/ocicni/pkg/ocicni"
- "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -713,7 +713,6 @@ func (r *Runtime) WithPod(pod *Pod) CtrCreateOption {
if pod == nil {
return define.ErrInvalidArg
}
-
ctr.config.Pod = pod.ID()
return nil
@@ -1430,20 +1429,6 @@ func WithRestartRetries(tries uint) CtrCreateOption {
}
}
-// withIsInfra sets the container to be an infra container. This means the container will be sometimes hidden
-// and expected to be the first container in the pod.
-func withIsInfra() CtrCreateOption {
- return func(ctr *Container) error {
- if ctr.valid {
- return define.ErrCtrFinalized
- }
-
- ctr.config.IsInfra = true
-
- return nil
- }
-}
-
// WithNamedVolumes adds the given named volumes to the container.
func WithNamedVolumes(volumes []*ContainerNamedVolume) CtrCreateOption {
return func(ctr *Container) error {
@@ -1541,6 +1526,20 @@ func WithCreateCommand(cmd []string) CtrCreateOption {
}
}
+// withIsInfra allows us to dfferentiate between infra containers and regular containers
+// within the container config
+func withIsInfra() CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return define.ErrCtrFinalized
+ }
+
+ ctr.config.IsInfra = true
+
+ return nil
+ }
+}
+
// WithCreateWorkingDir tells Podman to create the container's working directory
// if it does not exist.
func WithCreateWorkingDir() CtrCreateOption {
@@ -1812,45 +1811,14 @@ func WithInitCtrType(containerType string) CtrCreateOption {
// Pod Creation Options
-// WithInfraImage sets the infra image for libpod.
-// An infra image is used for inter-container kernel
-// namespace sharing within a pod. Typically, an infra
-// container is lightweight and is there to reap
-// zombie processes within its pid namespace.
-func WithInfraImage(img string) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- pod.config.InfraContainer.InfraImage = img
-
- return nil
- }
-}
-
-// WithInfraCommand sets the command to
-// run on pause container start up.
-func WithInfraCommand(cmd []string) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- pod.config.InfraContainer.InfraCommand = cmd
- return nil
- }
-}
-
-// WithInfraName sets the infra container name for a single pod.
-func WithInfraName(name string) PodCreateOption {
+// WithPodCreateCommand adds the full command plus arguments of the current
+// process to the pod config.
+func WithPodCreateCommand(createCmd []string) PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
-
- pod.config.InfraContainer.InfraName = name
-
+ pod.config.CreateCommand = createCmd
return nil
}
}
@@ -1891,26 +1859,14 @@ func WithPodHostname(hostname string) PodCreateOption {
}
}
-// WithPodCreateCommand adds the full command plus arguments of the current
-// process to the pod config.
-func WithPodCreateCommand(createCmd []string) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
- pod.config.CreateCommand = createCmd
- return nil
- }
-}
-
// WithInfraConmonPidFile sets the path to a custom conmon PID file for the
// infra container.
-func WithInfraConmonPidFile(path string) PodCreateOption {
+func WithInfraConmonPidFile(path string, infraSpec *specgen.SpecGenerator) PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
- pod.config.InfraContainer.ConmonPidFile = path
+ infraSpec.ConmonPidFile = path
return nil
}
}
@@ -2099,320 +2055,25 @@ func WithInfraContainer() PodCreateOption {
if pod.valid {
return define.ErrPodFinalized
}
-
- pod.config.InfraContainer.HasInfraContainer = true
+ pod.config.HasInfra = true
return nil
}
}
// WithInfraContainerPorts tells the pod to add port bindings to the pause container
-func WithInfraContainerPorts(bindings []ocicni.PortMapping) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set pod ports as no infra container is being created")
- }
- pod.config.InfraContainer.PortBindings = bindings
- return nil
- }
-}
-
-// WithPodStaticIP sets a static IP for the pod.
-func WithPodStaticIP(ip net.IP) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set pod static IP as no infra container is being created")
- }
-
- if pod.config.InfraContainer.HostNetwork {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set static IP if host network is specified")
- }
-
- if len(pod.config.InfraContainer.Networks) > 1 {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set a static IP if joining more than 1 CNI network")
- }
-
- pod.config.InfraContainer.StaticIP = ip
-
- return nil
- }
-}
-
-// WithPodStaticMAC sets a static MAC address for the pod.
-func WithPodStaticMAC(mac net.HardwareAddr) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set pod static MAC as no infra container is being created")
- }
-
- if pod.config.InfraContainer.HostNetwork {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set static MAC if host network is specified")
- }
-
- if len(pod.config.InfraContainer.Networks) > 1 {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set a static MAC if joining more than 1 CNI network")
- }
-
- pod.config.InfraContainer.StaticMAC = mac
-
- return nil
- }
-}
-
-// WithPodUseImageResolvConf sets a pod to use an image's resolv.conf and not
-// create its own.
-func WithPodUseImageResolvConf() PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod DNS as no infra container is being created")
- }
-
- if len(pod.config.InfraContainer.DNSServer) != 0 ||
- len(pod.config.InfraContainer.DNSSearch) != 0 ||
- len(pod.config.InfraContainer.DNSOption) != 0 {
- return errors.Wrapf(define.ErrInvalidArg, "requested use of image resolv.conf conflicts with already-configured DNS settings")
- }
-
- pod.config.InfraContainer.UseImageResolvConf = true
-
- return nil
- }
-}
-
-// WithPodDNS sets the DNS Servers for a pod.
-func WithPodDNS(dnsServer []string) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod DNS as no infra container is being created")
- }
-
- if pod.config.InfraContainer.UseImageResolvConf {
- return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS servers if pod will not create /etc/resolv.conf")
- }
-
- pod.config.InfraContainer.DNSServer = dnsServer
-
- return nil
- }
-}
-
-// WithPodDNSSearch sets the DNS Search domains for a pod.
-func WithPodDNSSearch(dnsSearch []string) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod DNS as no infra container is being created")
- }
-
- if pod.config.InfraContainer.UseImageResolvConf {
- return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS search domains if pod will not create /etc/resolv.conf")
- }
-
- pod.config.InfraContainer.DNSSearch = dnsSearch
-
- return nil
- }
-}
-
-// WithPodDNSOption sets DNS Options for a pod.
-func WithPodDNSOption(dnsOption []string) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod DNS as no infra container is being created")
- }
-
- if pod.config.InfraContainer.UseImageResolvConf {
- return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS options if pod will not create /etc/resolv.conf")
- }
-
- pod.config.InfraContainer.DNSOption = dnsOption
-
- return nil
- }
-}
-
-// WithPodUseImageHosts tells the pod not to create /etc/hosts and instead to
-// use the one provided by the image.
-func WithPodUseImageHosts() PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod hosts as no infra container is being created")
- }
-
- if len(pod.config.InfraContainer.HostAdd) != 0 {
- return errors.Wrapf(define.ErrInvalidArg, "not creating /etc/hosts conflicts with adding to the hosts file")
- }
-
- pod.config.InfraContainer.UseImageHosts = true
-
- return nil
- }
-}
-
-// WithPodHosts adds additional entries to the pod's /etc/hosts
-func WithPodHosts(hosts []string) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod hosts as no infra container is being created")
- }
-
- if pod.config.InfraContainer.UseImageHosts {
- return errors.Wrapf(define.ErrInvalidArg, "cannot add to /etc/hosts if container is using image hosts")
- }
-
- pod.config.InfraContainer.HostAdd = hosts
-
- return nil
- }
-}
-
-// WithPodNetworks sets additional CNI networks for the pod to join.
-func WithPodNetworks(networks []string) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod CNI networks as no infra container is being created")
- }
-
- if (pod.config.InfraContainer.StaticIP != nil || pod.config.InfraContainer.StaticMAC != nil) &&
- len(networks) > 1 {
- return errors.Wrapf(define.ErrInvalidArg, "cannot join more than one CNI network if setting a static IP or MAC address")
- }
-
- if pod.config.InfraContainer.HostNetwork {
- return errors.Wrapf(define.ErrInvalidArg, "cannot join pod to CNI networks if host network is specified")
- }
-
- pod.config.InfraContainer.Networks = networks
-
- return nil
- }
-}
-
-// WithPodNoNetwork tells the pod to disable external networking.
-func WithPodNoNetwork() PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot disable pod networking as no infra container is being created")
- }
-
- if len(pod.config.InfraContainer.PortBindings) > 0 ||
- pod.config.InfraContainer.StaticIP != nil ||
- pod.config.InfraContainer.StaticMAC != nil ||
- len(pod.config.InfraContainer.Networks) > 0 ||
- pod.config.InfraContainer.HostNetwork {
- return errors.Wrapf(define.ErrInvalidArg, "cannot disable pod network if network-related configuration is specified")
- }
-
- pod.config.InfraContainer.NoNetwork = true
-
- return nil
- }
-}
-
-// WithPodHostNetwork tells the pod to use the host's network namespace.
-func WithPodHostNetwork() PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod host networking as no infra container is being created")
- }
-
- if len(pod.config.InfraContainer.PortBindings) > 0 ||
- pod.config.InfraContainer.StaticIP != nil ||
- pod.config.InfraContainer.StaticMAC != nil ||
- len(pod.config.InfraContainer.Networks) > 0 ||
- pod.config.InfraContainer.NoNetwork {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set host network if network-related configuration is specified")
- }
-
- pod.config.InfraContainer.HostNetwork = true
-
- return nil
- }
-}
-
-// WithPodInfraExitCommand sets an exit command for the pod's infra container.
-// Semantics are identical to WithExitCommand() above - the ID of the container
-// will be appended to the end of the provided command (note that this will
-// specifically be the ID of the infra container *and not the pod's id*.
-func WithPodInfraExitCommand(exitCmd []string) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod infra container exit command as no infra container is being created")
- }
-
- pod.config.InfraContainer.ExitCommand = exitCmd
-
- return nil
- }
-}
-
-// WithPodSlirp4netns tells the pod to use slirp4netns.
-func WithPodSlirp4netns(networkOptions map[string][]string) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod networking as no infra container is being created")
- }
- if pod.config.InfraContainer.HostNetwork {
- return errors.Wrapf(define.ErrInvalidArg, "cannot set both HostNetwork and Slirp4netns")
- }
- pod.config.InfraContainer.Slirp4netns = true
- pod.config.InfraContainer.NetworkOptions = networkOptions
-
- return nil
+func WithInfraContainerPorts(bindings []ocicni.PortMapping, infraSpec *specgen.SpecGenerator) []netTypes.PortMapping {
+ bindingSpec := []netTypes.PortMapping{}
+ for _, bind := range bindings {
+ currBind := netTypes.PortMapping{}
+ currBind.ContainerPort = uint16(bind.ContainerPort)
+ currBind.HostIP = bind.HostIP
+ currBind.HostPort = uint16(bind.HostPort)
+ currBind.Protocol = bind.Protocol
+ bindingSpec = append(bindingSpec, currBind)
}
+ infraSpec.PortMappings = bindingSpec
+ return infraSpec.PortMappings
}
// WithVolatile sets the volatile flag for the container storage.
@@ -2428,78 +2089,3 @@ func WithVolatile() CtrCreateOption {
return nil
}
}
-
-// WithPodUserns sets the userns for the infra container in a pod.
-func WithPodUserns(userns specgen.Namespace) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
-
- if !pod.config.InfraContainer.HasInfraContainer {
- return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod userns as no infra container is being created")
- }
-
- pod.config.InfraContainer.Userns = userns
-
- return nil
- }
-}
-
-// WithPodCPUPAQ takes the given cpu period and quota and inserts them in the proper place.
-func WithPodCPUPAQ(period uint64, quota int64) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
- if pod.CPUPeriod() != 0 && pod.CPUQuota() != 0 {
- pod.config.InfraContainer.ResourceLimits.CPU = &specs.LinuxCPU{
- Period: &period,
- Quota: &quota,
- }
- } else {
- pod.config.InfraContainer.ResourceLimits = &specs.LinuxResources{}
- pod.config.InfraContainer.ResourceLimits.CPU = &specs.LinuxCPU{
- Period: &period,
- Quota: &quota,
- }
- }
- return nil
- }
-}
-
-// WithPodCPUSetCPUS computes and sets the Cpus linux resource string which determines the amount of cores, from those available, we are allowed to execute on
-func WithPodCPUSetCPUs(inp string) PodCreateOption {
- return func(pod *Pod) error {
- if pod.valid {
- return define.ErrPodFinalized
- }
- if pod.ResourceLim().CPU.Period != nil {
- pod.config.InfraContainer.ResourceLimits.CPU.Cpus = inp
- } else {
- pod.config.InfraContainer.ResourceLimits = &specs.LinuxResources{}
- pod.config.InfraContainer.ResourceLimits.CPU = &specs.LinuxCPU{}
- pod.config.InfraContainer.ResourceLimits.CPU.Cpus = inp
- }
- return nil
- }
-}
-
-func WithPodPidNS(inp specgen.Namespace) PodCreateOption {
- return func(p *Pod) error {
- if p.valid {
- return define.ErrPodFinalized
- }
- if p.config.UsePodPID {
- switch inp.NSMode {
- case "container":
- return errors.Wrap(define.ErrInvalidArg, "Cannot take container in a different NS as an argument")
- case "host":
- p.config.UsePodPID = false
- }
- p.config.InfraContainer.PidNS = inp
- }
-
- return nil
- }
-}
diff --git a/libpod/pod.go b/libpod/pod.go
index 7df15df7b..e4516b354 100644
--- a/libpod/pod.go
+++ b/libpod/pod.go
@@ -2,14 +2,12 @@ package libpod
import (
"context"
- "net"
+ "fmt"
"sort"
"time"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/lock"
- "github.com/containers/podman/v3/pkg/specgen"
- "github.com/cri-o/ocicni/pkg/ocicni"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@@ -63,7 +61,7 @@ type PodConfig struct {
UsePodUTS bool `json:"sharesUts,omitempty"`
UsePodCgroupNS bool `json:"sharesCgroupNS,omitempty"`
- InfraContainer *InfraContainerConfig `json:"infraConfig"`
+ HasInfra bool `json:"hasInfra,omitempty"`
// Time pod was created
CreatedTime time.Time `json:"created"`
@@ -85,41 +83,6 @@ type podState struct {
InfraContainerID string
}
-// InfraContainerConfig is the configuration for the pod's infra container.
-// Generally speaking, these are equivalent to container configuration options
-// you will find in container_config.go (and even named identically), save for
-// HasInfraContainer (which determines if an infra container is even created -
-// if it is false, no other options in this struct will be used) and HostNetwork
-// (this involves the created OCI spec, and as such is not represented directly
-// in container_config.go).
-// Generally speaking, aside from those two exceptions, these options will set
-// the equivalent field in the container's configuration.
-type InfraContainerConfig struct {
- ConmonPidFile string `json:"conmonPidFile"`
- HasInfraContainer bool `json:"makeInfraContainer"`
- NoNetwork bool `json:"noNetwork,omitempty"`
- HostNetwork bool `json:"infraHostNetwork,omitempty"`
- PidNS specgen.Namespace `json:"infraPid,omitempty"`
- PortBindings []ocicni.PortMapping `json:"infraPortBindings"`
- StaticIP net.IP `json:"staticIP,omitempty"`
- StaticMAC net.HardwareAddr `json:"staticMAC,omitempty"`
- UseImageResolvConf bool `json:"useImageResolvConf,omitempty"`
- DNSServer []string `json:"dnsServer,omitempty"`
- DNSSearch []string `json:"dnsSearch,omitempty"`
- DNSOption []string `json:"dnsOption,omitempty"`
- UseImageHosts bool `json:"useImageHosts,omitempty"`
- HostAdd []string `json:"hostsAdd,omitempty"`
- Networks []string `json:"networks,omitempty"`
- ExitCommand []string `json:"exitCommand,omitempty"`
- InfraImage string `json:"infraImage,omitempty"`
- InfraCommand []string `json:"infraCommand,omitempty"`
- InfraName string `json:"infraName,omitempty"`
- Slirp4netns bool `json:"slirp4netns,omitempty"`
- NetworkOptions map[string][]string `json:"network_options,omitempty"`
- ResourceLimits *specs.LinuxResources `json:"resource_limits,omitempty"`
- Userns specgen.Namespace `json:"userns,omitempty"`
-}
-
// ID retrieves the pod's ID
func (p *Pod) ID() string {
return p.config.ID
@@ -139,45 +102,104 @@ func (p *Pod) Namespace() string {
// ResourceLim returns the cpuset resource limits for the pod
func (p *Pod) ResourceLim() *specs.LinuxResources {
resCopy := &specs.LinuxResources{}
- if err := JSONDeepCopy(p.config.InfraContainer.ResourceLimits, resCopy); err != nil {
+ empty := &specs.LinuxResources{
+ CPU: &specs.LinuxCPU{},
+ }
+ infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
+ if err != nil {
+ return empty
+ }
+ conf := infra.config.Spec
+ if err != nil {
+ return empty
+ }
+ if conf.Linux == nil || conf.Linux.Resources == nil {
+ return empty
+ }
+ if err = JSONDeepCopy(conf.Linux.Resources, resCopy); err != nil {
return nil
}
- if resCopy != nil && resCopy.CPU != nil {
+ if resCopy.CPU != nil {
return resCopy
}
- empty := &specs.LinuxResources{
- CPU: &specs.LinuxCPU{},
- }
+
return empty
}
// CPUPeriod returns the pod CPU period
func (p *Pod) CPUPeriod() uint64 {
- resCopy := &specs.LinuxResources{}
- if err := JSONDeepCopy(p.config.InfraContainer.ResourceLimits, resCopy); err != nil {
+ if p.state.InfraContainerID == "" {
return 0
}
- if resCopy != nil && resCopy.CPU != nil && resCopy.CPU.Period != nil {
- return *resCopy.CPU.Period
+ infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
+ if err != nil {
+ return 0
+ }
+ conf := infra.config.Spec
+ if conf != nil && conf.Linux != nil && conf.Linux.Resources != nil && conf.Linux.Resources.CPU != nil && conf.Linux.Resources.CPU.Period != nil {
+ return *conf.Linux.Resources.CPU.Period
}
return 0
}
// CPUQuota returns the pod CPU quota
func (p *Pod) CPUQuota() int64 {
- resCopy := &specs.LinuxResources{}
- if err := JSONDeepCopy(p.config.InfraContainer.ResourceLimits, resCopy); err != nil {
+ if p.state.InfraContainerID == "" {
+ return 0
+ }
+ infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
+ if err != nil {
return 0
}
- if resCopy != nil && resCopy.CPU != nil && resCopy.CPU.Quota != nil {
- return *resCopy.CPU.Quota
+ conf := infra.config.Spec
+ if conf != nil && conf.Linux != nil && conf.Linux.Resources != nil && conf.Linux.Resources.CPU != nil && conf.Linux.Resources.CPU.Quota != nil {
+ return *conf.Linux.Resources.CPU.Quota
}
return 0
}
// PidMode returns the PID mode given by the user ex: pod, private...
func (p *Pod) PidMode() string {
- return string(p.config.InfraContainer.PidNS.NSMode)
+ infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
+ if err != nil {
+ return ""
+ }
+ conf := infra.Config()
+ ctrSpec := conf.Spec
+ if ctrSpec != nil && ctrSpec.Linux != nil {
+ for _, ns := range ctrSpec.Linux.Namespaces {
+ if ns.Type == specs.PIDNamespace {
+ if ns.Path != "" {
+ return fmt.Sprintf("ns:%s", ns.Path)
+ }
+ return "private"
+ }
+ }
+ return "host"
+ }
+ return ""
+}
+
+// PidMode returns the PID mode given by the user ex: pod, private...
+func (p *Pod) UserNSMode() string {
+ infra, err := p.infraContainer()
+ if err != nil {
+ return ""
+ }
+ conf := infra.Config()
+ ctrSpec := conf.Spec
+ if ctrSpec != nil && ctrSpec.Linux != nil {
+ for _, ns := range ctrSpec.Linux.Namespaces {
+ if ns.Type == specs.UserNamespace {
+ if ns.Path != "" {
+ return fmt.Sprintf("ns:%s", ns.Path)
+ }
+ return "private"
+ }
+ }
+ return "host"
+ }
+ return ""
}
// Labels returns the pod's labels
@@ -263,20 +285,24 @@ func (p *Pod) CgroupPath() (string, error) {
if p.state.CgroupPath != "" {
return p.state.CgroupPath, nil
}
- if !p.HasInfraContainer() {
+ if p.state.InfraContainerID == "" {
return "", errors.Wrap(define.ErrNoSuchCtr, "pod has no infra container")
}
- id := p.state.InfraContainerID
+ id, err := p.infraContainerID()
+ if err != nil {
+ return "", err
+ }
if id != "" {
- ctr, err := p.runtime.state.Container(id)
+ ctr, err := p.infraContainer()
if err != nil {
return "", errors.Wrapf(err, "could not get infra")
}
if ctr != nil {
- ctr.Start(context.Background(), false)
+ ctr.Start(context.Background(), true)
cgroupPath, err := ctr.CGroupPath()
+ fmt.Println(cgroupPath)
if err != nil {
return "", errors.Wrapf(err, "could not get container cgroup")
}
@@ -325,7 +351,7 @@ func (p *Pod) allContainers() ([]*Container, error) {
// HasInfraContainer returns whether the pod will create an infra container
func (p *Pod) HasInfraContainer() bool {
- return p.config.InfraContainer.HasInfraContainer
+ return p.config.HasInfra
}
// SharesNamespaces checks if the pod has any kernel namespaces set as shared. An infra container will not be
@@ -350,19 +376,26 @@ func (p *Pod) InfraContainerID() (string, error) {
return p.infraContainerID()
}
-// InfraContainer returns the infra container.
-func (p *Pod) InfraContainer() (*Container, error) {
- if !p.HasInfraContainer() {
- return nil, errors.Wrap(define.ErrNoSuchCtr, "pod has no infra container")
- }
- id, err := p.InfraContainerID()
+// infraContainer is the unlocked versio of InfraContainer which returns the infra container
+func (p *Pod) infraContainer() (*Container, error) {
+ id, err := p.infraContainerID()
if err != nil {
return nil, err
}
+ if id == "" {
+ return nil, errors.Wrap(define.ErrNoSuchCtr, "pod has no infra container")
+ }
return p.runtime.state.Container(id)
}
+// InfraContainer returns the infra container.
+func (p *Pod) InfraContainer() (*Container, error) {
+ p.lock.Lock()
+ defer p.lock.Unlock()
+ return p.infraContainer()
+}
+
// TODO add pod batching
// Lock pod to avoid lock contention
// Store and lock all containers (no RemoveContainer in batch guarantees cache will not become stale)
@@ -412,13 +445,7 @@ func (p *Pod) ProcessLabel() (string, error) {
if !p.HasInfraContainer() {
return "", nil
}
-
- id, err := p.InfraContainerID()
- if err != nil {
- return "", err
- }
-
- ctr, err := p.runtime.state.Container(id)
+ ctr, err := p.infraContainer()
if err != nil {
return "", err
}
diff --git a/libpod/pod_api.go b/libpod/pod_api.go
index 53fb9538f..5f4d983b9 100644
--- a/libpod/pod_api.go
+++ b/libpod/pod_api.go
@@ -582,41 +582,46 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
// Infra config contains detailed information on the pod's infra
// container.
var infraConfig *define.InspectPodInfraConfig
- if p.config.InfraContainer != nil && p.config.InfraContainer.HasInfraContainer {
+ if p.state.InfraContainerID != "" {
+ infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
+ if err != nil {
+ return nil, err
+ }
infraConfig = new(define.InspectPodInfraConfig)
- infraConfig.HostNetwork = p.config.InfraContainer.HostNetwork
- infraConfig.StaticIP = p.config.InfraContainer.StaticIP
- infraConfig.StaticMAC = p.config.InfraContainer.StaticMAC.String()
- infraConfig.NoManageResolvConf = p.config.InfraContainer.UseImageResolvConf
- infraConfig.NoManageHosts = p.config.InfraContainer.UseImageHosts
+ infraConfig.HostNetwork = !infra.Config().ContainerNetworkConfig.UseImageHosts
+ infraConfig.StaticIP = infra.Config().ContainerNetworkConfig.StaticIP
+ infraConfig.NoManageResolvConf = infra.Config().UseImageResolvConf
+ infraConfig.NoManageHosts = infra.Config().UseImageHosts
infraConfig.CPUPeriod = p.CPUPeriod()
infraConfig.CPUQuota = p.CPUQuota()
infraConfig.CPUSetCPUs = p.ResourceLim().CPU.Cpus
infraConfig.PidNS = p.PidMode()
- infraConfig.UserNS = p.config.InfraContainer.Userns.String()
+ infraConfig.UserNS = p.UserNSMode()
- if len(p.config.InfraContainer.DNSServer) > 0 {
- infraConfig.DNSServer = make([]string, 0, len(p.config.InfraContainer.DNSServer))
- infraConfig.DNSServer = append(infraConfig.DNSServer, p.config.InfraContainer.DNSServer...)
+ if len(infra.Config().ContainerNetworkConfig.DNSServer) > 0 {
+ infraConfig.DNSServer = make([]string, 0, len(infra.Config().ContainerNetworkConfig.DNSServer))
+ for _, entry := range infra.Config().ContainerNetworkConfig.DNSServer {
+ infraConfig.DNSServer = append(infraConfig.DNSServer, entry.String())
+ }
}
- if len(p.config.InfraContainer.DNSSearch) > 0 {
- infraConfig.DNSSearch = make([]string, 0, len(p.config.InfraContainer.DNSSearch))
- infraConfig.DNSSearch = append(infraConfig.DNSSearch, p.config.InfraContainer.DNSSearch...)
+ if len(infra.Config().ContainerNetworkConfig.DNSSearch) > 0 {
+ infraConfig.DNSSearch = make([]string, 0, len(infra.Config().ContainerNetworkConfig.DNSSearch))
+ infraConfig.DNSSearch = append(infraConfig.DNSSearch, infra.Config().ContainerNetworkConfig.DNSSearch...)
}
- if len(p.config.InfraContainer.DNSOption) > 0 {
- infraConfig.DNSOption = make([]string, 0, len(p.config.InfraContainer.DNSOption))
- infraConfig.DNSOption = append(infraConfig.DNSOption, p.config.InfraContainer.DNSOption...)
+ if len(infra.Config().ContainerNetworkConfig.DNSOption) > 0 {
+ infraConfig.DNSOption = make([]string, 0, len(infra.Config().ContainerNetworkConfig.DNSOption))
+ infraConfig.DNSOption = append(infraConfig.DNSOption, infra.Config().ContainerNetworkConfig.DNSOption...)
}
- if len(p.config.InfraContainer.HostAdd) > 0 {
- infraConfig.HostAdd = make([]string, 0, len(p.config.InfraContainer.HostAdd))
- infraConfig.HostAdd = append(infraConfig.HostAdd, p.config.InfraContainer.HostAdd...)
+ if len(infra.Config().HostAdd) > 0 {
+ infraConfig.HostAdd = make([]string, 0, len(infra.Config().HostAdd))
+ infraConfig.HostAdd = append(infraConfig.HostAdd, infra.Config().HostAdd...)
}
- if len(p.config.InfraContainer.Networks) > 0 {
- infraConfig.Networks = make([]string, 0, len(p.config.InfraContainer.Networks))
- infraConfig.Networks = append(infraConfig.Networks, p.config.InfraContainer.Networks...)
+ if len(infra.Config().ContainerNetworkConfig.Networks) > 0 {
+ infraConfig.Networks = make([]string, 0, len(infra.Config().ContainerNetworkConfig.Networks))
+ infraConfig.Networks = append(infraConfig.Networks, infra.Config().ContainerNetworkConfig.Networks...)
}
- infraConfig.NetworkOptions = p.config.InfraContainer.NetworkOptions
- infraConfig.PortBindings = makeInspectPortBindings(p.config.InfraContainer.PortBindings, nil)
+ infraConfig.NetworkOptions = infra.Config().ContainerNetworkConfig.NetworkOptions
+ infraConfig.PortBindings = makeInspectPortBindings(infra.Config().ContainerNetworkConfig.PortMappings, nil)
}
inspectData := define.InspectPodData{
diff --git a/libpod/pod_internal.go b/libpod/pod_internal.go
index e81bd7b16..079b631a0 100644
--- a/libpod/pod_internal.go
+++ b/libpod/pod_internal.go
@@ -20,7 +20,7 @@ func newPod(runtime *Runtime) *Pod {
pod.config.ID = stringid.GenerateNonCryptoID()
pod.config.Labels = make(map[string]string)
pod.config.CreatedTime = time.Now()
- pod.config.InfraContainer = new(InfraContainerConfig)
+ // pod.config.InfraContainer = new(ContainerConfig)
pod.state = new(podState)
pod.runtime = runtime
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 52072b0f3..7d3891f6e 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -17,6 +17,7 @@ import (
"github.com/containers/podman/v3/pkg/cgroups"
"github.com/containers/podman/v3/pkg/domain/entities/reports"
"github.com/containers/podman/v3/pkg/rootless"
+ "github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/storage"
"github.com/containers/storage/pkg/stringid"
"github.com/docker/go-units"
@@ -38,12 +39,15 @@ type CtrCreateOption func(*Container) error
type ContainerFilter func(*Container) bool
// NewContainer creates a new container from a given OCI config.
-func (r *Runtime) NewContainer(ctx context.Context, rSpec *spec.Spec, options ...CtrCreateOption) (*Container, error) {
+func (r *Runtime) NewContainer(ctx context.Context, rSpec *spec.Spec, spec *specgen.SpecGenerator, infra bool, options ...CtrCreateOption) (*Container, error) {
r.lock.Lock()
defer r.lock.Unlock()
if !r.valid {
return nil, define.ErrRuntimeStopped
}
+ if infra {
+ options = append(options, withIsInfra())
+ }
return r.newContainer(ctx, rSpec, options...)
}
@@ -172,6 +176,7 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf
}
ctr.config.ShmSize = size
ctr.config.StopSignal = 15
+
ctr.config.StopTimeout = r.config.Engine.StopTimeout
} else {
// This is a restore from an imported checkpoint
@@ -211,7 +216,11 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf
}
func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ...CtrCreateOption) (*Container, error) {
- ctr, err := r.initContainerVariables(rSpec, nil)
+ var ctr *Container
+ var err error
+
+ ctr, err = r.initContainerVariables(rSpec, nil)
+
if err != nil {
return nil, errors.Wrapf(err, "error initializing container variables")
}
@@ -230,7 +239,9 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
if err := ctr.validate(); err != nil {
return nil, err
}
-
+ if ctr.config.IsInfra {
+ ctr.config.StopTimeout = 10
+ }
// normalize the networks to names
// ocicni only knows about cni names so we have to make
// sure we do not use ids internally
@@ -327,7 +338,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
switch r.config.Engine.CgroupManager {
case config.CgroupfsCgroupsManager:
if ctr.config.CgroupParent == "" {
- if pod != nil && pod.config.UsePodCgroup {
+ if pod != nil && pod.config.UsePodCgroup && !ctr.IsInfra() {
podCgroup, err := pod.CgroupPath()
if err != nil {
return nil, errors.Wrapf(err, "error retrieving pod %s cgroup", pod.ID())
@@ -348,7 +359,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
case config.SystemdCgroupsManager:
if ctr.config.CgroupParent == "" {
switch {
- case pod != nil && pod.config.UsePodCgroup:
+ case pod != nil && pod.config.UsePodCgroup && !ctr.IsInfra():
podCgroup, err := pod.CgroupPath()
if err != nil {
return nil, errors.Wrapf(err, "error retrieving pod %s cgroup", pod.ID())
@@ -833,7 +844,10 @@ func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVol
return id, err
}
- infraID := pod.state.InfraContainerID
+ infraID, err := pod.infraContainerID()
+ if err != nil {
+ return "", err
+ }
if c.ID() == infraID {
return id, errors.Errorf("container %s is the infra container of pod %s and cannot be removed without removing the pod", c.ID(), pod.ID())
}
diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go
deleted file mode 100644
index 9236fb1f5..000000000
--- a/libpod/runtime_pod_infra_linux.go
+++ /dev/null
@@ -1,284 +0,0 @@
-// +build linux
-
-package libpod
-
-import (
- "context"
- "strings"
-
- "github.com/containers/common/pkg/config"
- "github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/pkg/namespaces"
- "github.com/containers/podman/v3/pkg/rootless"
- "github.com/containers/podman/v3/pkg/specgen"
- "github.com/containers/podman/v3/pkg/util"
- v1 "github.com/opencontainers/image-spec/specs-go/v1"
- spec "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/opencontainers/runtime-tools/generate"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
-)
-
-const (
- // IDTruncLength is the length of the pod's id that will be used to make the
- // infra container name
- IDTruncLength = 12
-)
-
-func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawImageName, imgID string, config *v1.ImageConfig) (*Container, error) {
- // Set up generator for infra container defaults
- g, err := generate.New("linux")
- if err != nil {
- return nil, err
- }
-
- // Set Pod hostname
- g.Config.Hostname = p.config.Hostname
-
- var options []CtrCreateOption
-
- // Command: If user-specified, use that preferentially.
- // If not set and the config file is set, fall back to that.
- var infraCtrCommand []string
- if p.config.InfraContainer.InfraCommand != nil {
- logrus.Debugf("User-specified infra container entrypoint %v", p.config.InfraContainer.InfraCommand)
- infraCtrCommand = p.config.InfraContainer.InfraCommand
- } else if r.config.Engine.InfraCommand != "" {
- logrus.Debugf("Config-specified infra container entrypoint %s", r.config.Engine.InfraCommand)
- infraCtrCommand = []string{r.config.Engine.InfraCommand}
- }
- // Only if set by the user or containers.conf, we set entrypoint for the
- // infra container.
- // This is only used by commit, so it shouldn't matter... But someone
- // may eventually want to commit an infra container?
- // TODO: Should we actually do this if set by containers.conf?
- if infraCtrCommand != nil {
- // Need to duplicate the array - we are going to add Cmd later
- // so the current array will be changed.
- newArr := make([]string, 0, len(infraCtrCommand))
- newArr = append(newArr, infraCtrCommand...)
- options = append(options, WithEntrypoint(newArr))
- }
-
- isRootless := rootless.IsRootless()
-
- // I've seen circumstances where config is being passed as nil.
- // Let's err on the side of safety and make sure it's safe to use.
- if config != nil {
- if infraCtrCommand == nil {
- // If we have no entrypoint and command from the image,
- // we can't go on - the infra container has no command.
- if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 {
- return nil, errors.Errorf("infra container has no command")
- }
- if len(config.Entrypoint) > 0 {
- infraCtrCommand = config.Entrypoint
- } else {
- // Use the Docker default "/bin/sh -c"
- // entrypoint, as we're overriding command.
- // If an image doesn't want this, it can
- // override entrypoint too.
- infraCtrCommand = []string{"/bin/sh", "-c"}
- }
- }
- if len(config.Cmd) > 0 {
- infraCtrCommand = append(infraCtrCommand, config.Cmd...)
- }
-
- if len(config.Env) > 0 {
- for _, nameValPair := range config.Env {
- nameValSlice := strings.Split(nameValPair, "=")
- if len(nameValSlice) < 2 {
- return nil, errors.Errorf("Invalid environment variable structure in pause image")
- }
- g.AddProcessEnv(nameValSlice[0], nameValSlice[1])
- }
- }
-
- switch {
- case p.config.InfraContainer.HostNetwork:
- if err := g.RemoveLinuxNamespace(string(spec.NetworkNamespace)); err != nil {
- return nil, errors.Wrapf(err, "error removing network namespace from pod %s infra container", p.ID())
- }
- case p.config.InfraContainer.NoNetwork:
- // Do nothing - we have a network namespace by default,
- // but should not configure slirp.
- default:
- // Since user namespace sharing is not implemented, we only need to check if it's rootless
- netmode := "bridge"
- if p.config.InfraContainer.Slirp4netns {
- netmode = "slirp4netns"
- if len(p.config.InfraContainer.NetworkOptions) != 0 {
- options = append(options, WithNetworkOptions(p.config.InfraContainer.NetworkOptions))
- }
- }
- // FIXME allow pods to have exposed ports
- options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, nil, !p.config.InfraContainer.Userns.IsHost(), netmode, p.config.InfraContainer.Networks))
- }
-
- // For each option in InfraContainerConfig - if set, pass into
- // the infra container we're creating with the appropriate
- // With... option.
- if p.config.InfraContainer.StaticIP != nil {
- options = append(options, WithStaticIP(p.config.InfraContainer.StaticIP))
- }
- if p.config.InfraContainer.StaticMAC != nil {
- options = append(options, WithStaticMAC(p.config.InfraContainer.StaticMAC))
- }
- if p.config.InfraContainer.UseImageResolvConf {
- options = append(options, WithUseImageResolvConf())
- }
- if len(p.config.InfraContainer.DNSServer) > 0 {
- options = append(options, WithDNS(p.config.InfraContainer.DNSServer))
- }
- if len(p.config.InfraContainer.DNSSearch) > 0 {
- options = append(options, WithDNSSearch(p.config.InfraContainer.DNSSearch))
- }
- if len(p.config.InfraContainer.DNSOption) > 0 {
- options = append(options, WithDNSOption(p.config.InfraContainer.DNSOption))
- }
- if p.config.InfraContainer.UseImageHosts {
- options = append(options, WithUseImageHosts())
- }
- if len(p.config.InfraContainer.HostAdd) > 0 {
- options = append(options, WithHosts(p.config.InfraContainer.HostAdd))
- }
- if len(p.config.InfraContainer.ExitCommand) > 0 {
- options = append(options, WithExitCommand(p.config.InfraContainer.ExitCommand))
- }
-
- if p.config.UsePodPID && p.config.InfraContainer.PidNS.NSMode != "host" {
- g.AddOrReplaceLinuxNamespace(string(spec.LinuxNamespaceType("pid")), p.config.InfraContainer.PidNS.Value)
- } else if p.config.InfraContainer.PidNS.NSMode == "host" {
- newNS := []spec.LinuxNamespace{}
- for _, entry := range g.Config.Linux.Namespaces {
- if entry.Type != spec.LinuxNamespaceType("pid") {
- newNS = append(newNS, entry)
- }
- }
- g.Config.Linux.Namespaces = newNS
- }
- }
-
- for _, ctl := range r.config.Containers.DefaultSysctls {
- sysctl := strings.SplitN(ctl, "=", 2)
- if len(sysctl) < 2 {
- return nil, errors.Errorf("invalid default sysctl %s", ctl)
- }
-
- // Ignore net sysctls if --net=host
- if p.config.InfraContainer.HostNetwork && strings.HasPrefix(sysctl[0], "net.") {
- logrus.Infof("Sysctl %s=%s ignored in containers.conf, since Network Namespace set to host", sysctl[0], sysctl[1])
- continue
- }
-
- g.AddLinuxSysctl(sysctl[0], sysctl[1])
- }
-
- g.SetRootReadonly(true)
- g.SetProcessArgs(infraCtrCommand)
-
- logrus.Debugf("Using %q as infra container command", infraCtrCommand)
-
- mapopt, err := util.ParseIDMapping(namespaces.UsernsMode(p.config.InfraContainer.Userns.String()), []string{}, []string{}, "", "")
- if err != nil {
- return nil, err
- }
- user, err := specgen.SetupUserNS(mapopt, p.config.InfraContainer.Userns, &g)
- if err != nil {
- return nil, err
- }
- if user != "" {
- options = append(options, WithUser(user))
- }
-
- g.RemoveMount("/dev/shm")
- if isRootless {
- g.RemoveMount("/dev/pts")
- devPts := spec.Mount{
- Destination: "/dev/pts",
- Type: "devpts",
- Source: "devpts",
- Options: []string{"private", "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"},
- }
- g.AddMount(devPts)
- }
-
- // Add default sysctls from containers.conf
- defaultSysctls, err := util.ValidateSysctls(r.config.Sysctls())
- if err != nil {
- return nil, err
- }
- for sysctlKey, sysctlVal := range defaultSysctls {
- // Ignore mqueue sysctls if not sharing IPC
- if !p.config.UsePodIPC && strings.HasPrefix(sysctlKey, "fs.mqueue.") {
- logrus.Infof("Sysctl %s=%s ignored in containers.conf, since IPC Namespace for pod is unused", sysctlKey, sysctlVal)
- continue
- }
-
- // Ignore net sysctls if host network or not sharing network
- if (p.config.InfraContainer.HostNetwork || !p.config.UsePodNet) && strings.HasPrefix(sysctlKey, "net.") {
- logrus.Infof("Sysctl %s=%s ignored in containers.conf, since Network Namespace for pod is unused", sysctlKey, sysctlVal)
- continue
- }
-
- // Ignore uts sysctls if not sharing UTS
- if !p.config.UsePodUTS && (strings.HasPrefix(sysctlKey, "kernel.domainname") || strings.HasPrefix(sysctlKey, "kernel.hostname")) {
- logrus.Infof("Sysctl %s=%s ignored in containers.conf, since UTS Namespace for pod is unused", sysctlKey, sysctlVal)
- continue
- }
- g.AddLinuxSysctl(sysctlKey, sysctlVal)
- }
-
- containerName := p.config.InfraContainer.InfraName
- if containerName == "" {
- containerName = p.ID()[:IDTruncLength] + "-infra"
- }
- logrus.Infof("Infra container name %s", containerName)
- options = append(options, r.WithPod(p))
- options = append(options, WithRootFSFromImage(imgID, imgName, rawImageName))
- options = append(options, WithName(containerName))
- options = append(options, withIsInfra())
- options = append(options, WithIDMappings(*mapopt))
- if len(p.config.InfraContainer.ConmonPidFile) > 0 {
- options = append(options, WithConmonPidFile(p.config.InfraContainer.ConmonPidFile))
- }
- newRes := new(spec.LinuxResources)
- newRes.CPU = new(spec.LinuxCPU)
- newRes.CPU = p.ResourceLim().CPU
- g.Config.Linux.Resources.CPU = newRes.CPU
-
- return r.newContainer(ctx, g.Config, options...)
-}
-
-// createInfraContainer wrap creates an infra container for a pod.
-// An infra container becomes the basis for kernel namespace sharing between
-// containers in the pod.
-func (r *Runtime) createInfraContainer(ctx context.Context, p *Pod) (*Container, error) {
- if !r.valid {
- return nil, define.ErrRuntimeStopped
- }
- imageName := p.config.InfraContainer.InfraImage
- if imageName == "" {
- imageName = r.config.Engine.InfraImage
- }
-
- pulledImages, err := r.LibimageRuntime().Pull(ctx, imageName, config.PullPolicyMissing, nil)
- if err != nil {
- return nil, errors.Wrap(err, "error pulling infra-container image")
- }
-
- newImage := pulledImages[0]
- data, err := newImage.Inspect(ctx, false)
- if err != nil {
- return nil, err
- }
-
- imageName = "none"
- if len(newImage.Names()) > 0 {
- imageName = newImage.Names()[0]
- }
- imageID := data.ID
-
- return r.makeInfraContainer(ctx, p, imageName, r.config.Engine.InfraImage, imageID, data.Config)
-}
diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go
index fce3f38a7..7571fdfff 100644
--- a/libpod/runtime_pod_linux.go
+++ b/libpod/runtime_pod_linux.go
@@ -14,13 +14,14 @@ import (
"github.com/containers/podman/v3/libpod/events"
"github.com/containers/podman/v3/pkg/cgroups"
"github.com/containers/podman/v3/pkg/rootless"
+ "github.com/containers/podman/v3/pkg/specgen"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// NewPod makes a new, empty pod
-func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Pod, deferredErr error) {
+func (r *Runtime) NewPod(ctx context.Context, p specgen.PodSpecGenerator, options ...PodCreateOption) (_ *Pod, deferredErr error) {
r.lock.Lock()
defer r.lock.Unlock()
@@ -50,8 +51,8 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po
pod.config.Name = name
}
- if pod.config.Hostname == "" {
- pod.config.Hostname = pod.config.Name
+ if p.InfraContainerSpec != nil && p.InfraContainerSpec.Hostname == "" {
+ p.InfraContainerSpec.Hostname = pod.config.Name
}
// Allocate a lock for the pod
@@ -88,6 +89,9 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po
// launch should do it for us
if pod.config.UsePodCgroup {
pod.state.CgroupPath = filepath.Join(pod.config.CgroupParent, pod.ID())
+ if p.InfraContainerSpec != nil {
+ p.InfraContainerSpec.CgroupParent = pod.state.CgroupPath
+ }
}
}
case config.SystemdCgroupsManager:
@@ -108,6 +112,9 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po
return nil, errors.Wrapf(err, "unable to create pod cgroup for pod %s", pod.ID())
}
pod.state.CgroupPath = cgroupPath
+ if p.InfraContainerSpec != nil {
+ p.InfraContainerSpec.CgroupParent = pod.state.CgroupPath
+ }
}
default:
return nil, errors.Wrapf(define.ErrInvalidArg, "unsupported CGroup manager: %s - cannot validate cgroup parent", r.config.Engine.CgroupManager)
@@ -127,28 +134,40 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po
if err := r.state.AddPod(pod); err != nil {
return nil, errors.Wrapf(err, "error adding pod to state")
}
- defer func() {
- if deferredErr != nil {
- if err := r.removePod(ctx, pod, true, true); err != nil {
- logrus.Errorf("Error removing pod after pause container creation failure: %v", err)
- }
- }
- }()
+ return pod, nil
+}
- if pod.HasInfraContainer() {
- ctr, err := r.createInfraContainer(ctx, pod)
- if err != nil {
- return nil, errors.Wrapf(err, "error adding Infra Container")
- }
- pod.state.InfraContainerID = ctr.ID()
- if err := pod.save(); err != nil {
- return nil, err
- }
+// AddInfra adds the created infra container to the pod state
+func (r *Runtime) AddInfra(ctx context.Context, pod *Pod, infraCtr *Container) (*Pod, error) {
+ r.lock.Lock()
+ defer r.lock.Unlock()
+
+ if !r.valid {
+ return nil, define.ErrRuntimeStopped
+ }
+ pod.state.InfraContainerID = infraCtr.ID()
+ if err := pod.save(); err != nil {
+ return nil, err
}
pod.newPodEvent(events.Create)
return pod, nil
}
+// SavePod is a helper function to save the pod state from outside of libpod
+func (r *Runtime) SavePod(pod *Pod) error {
+ r.lock.Lock()
+ defer r.lock.Unlock()
+
+ if !r.valid {
+ return define.ErrRuntimeStopped
+ }
+ if err := pod.save(); err != nil {
+ return err
+ }
+ pod.newPodEvent(events.Create)
+ return nil
+}
+
func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool) error {
if err := p.updatePod(); err != nil {
return err
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go
index 0b5cbd343..9df35697a 100644
--- a/pkg/api/handlers/compat/containers_create.go
+++ b/pkg/api/handlers/compat/containers_create.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/domain/infra/abi"
"github.com/containers/podman/v3/pkg/specgen"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/containers/storage"
"github.com/gorilla/schema"
"github.com/pkg/errors"
@@ -80,7 +81,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
}
sg := specgen.NewSpecGenerator(imgNameOrID, cliOpts.RootFS)
- if err := common.FillOutSpecGen(sg, cliOpts, args); err != nil {
+ if err := specgenutil.FillOutSpecGen(sg, cliOpts, args); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "fill out specgen"))
return
}
diff --git a/pkg/api/handlers/libpod/containers_create.go b/pkg/api/handlers/libpod/containers_create.go
index 65951861b..0e2163d5c 100644
--- a/pkg/api/handlers/libpod/containers_create.go
+++ b/pkg/api/handlers/libpod/containers_create.go
@@ -28,7 +28,12 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
- ctr, err := generate.MakeContainer(context.Background(), runtime, &sg)
+ rtSpec, spec, opts, err := generate.MakeContainer(context.Background(), runtime, &sg)
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+ ctr, err := generate.ExecuteCreate(context.Background(), runtime, rtSpec, spec, false, opts...)
if err != nil {
utils.InternalServerError(w, err)
return
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go
index ff105bc48..3d6cf093b 100644
--- a/pkg/api/handlers/libpod/pods.go
+++ b/pkg/api/handlers/libpod/pods.go
@@ -1,11 +1,15 @@
package libpod
import (
+ "context"
"encoding/json"
"fmt"
"net/http"
"strings"
+ "github.com/containers/common/libimage"
+ "github.com/containers/common/pkg/config"
+ "github.com/containers/image/v5/transports/alltransports"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/api/handlers"
@@ -14,6 +18,7 @@ import (
"github.com/containers/podman/v3/pkg/domain/infra/abi"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/specgen/generate"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/containers/podman/v3/pkg/util"
"github.com/gorilla/schema"
"github.com/pkg/errors"
@@ -25,24 +30,70 @@ func PodCreate(w http.ResponseWriter, r *http.Request) {
runtime = r.Context().Value("runtime").(*libpod.Runtime)
err error
)
- var psg specgen.PodSpecGenerator
+ psg := specgen.PodSpecGenerator{InfraContainerSpec: &specgen.SpecGenerator{}}
if err := json.NewDecoder(r.Body).Decode(&psg); err != nil {
- utils.Error(w, "failed to decode specgen", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen"))
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen"))
return
}
- // parse userns so we get the valid default value of userns
- psg.Userns, err = specgen.ParseUserNamespace(psg.Userns.String())
if err != nil {
- utils.Error(w, "failed to parse userns", http.StatusInternalServerError, errors.Wrap(err, "failed to parse userns"))
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen"))
return
}
- pod, err := generate.MakePod(&psg, runtime)
+ if !psg.NoInfra {
+ infraOptions := &entities.ContainerCreateOptions{ImageVolume: "bind", IsInfra: true, Net: &entities.NetOptions{}} // options for pulling the image and FillOutSpec
+ err = specgenutil.FillOutSpecGen(psg.InfraContainerSpec, infraOptions, []string{}) // necessary for default values in many cases (userns, idmappings)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error filling out specgen"))
+ return
+ }
+ out, err := json.Marshal(psg) // marshal our spec so the matching options can be unmarshaled into infra
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen"))
+ return
+ }
+ tempSpec := &specgen.SpecGenerator{} // temporary spec since infra cannot be decoded into
+ err = json.Unmarshal(out, tempSpec) // unmarhal matching options
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen"))
+ return
+ }
+ psg.InfraContainerSpec = tempSpec // set infra spec equal to temp
+ // a few extra that do not have the same json tags
+ psg.InfraContainerSpec.Name = psg.InfraName
+ psg.InfraContainerSpec.ConmonPidFile = psg.InfraConmonPidFile
+ psg.InfraContainerSpec.ContainerCreateCommand = psg.InfraCommand
+ imageName := psg.InfraImage
+ rawImageName := psg.InfraImage
+ if imageName == "" {
+ imageName = config.DefaultInfraImage
+ rawImageName = config.DefaultInfraImage
+ }
+ curr := infraOptions.Quiet
+ infraOptions.Quiet = true
+ pullOptions := &libimage.PullOptions{}
+ pulledImages, err := runtime.LibimageRuntime().Pull(context.Background(), imageName, config.PullPolicyMissing, pullOptions)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "could not pull image"))
+ return
+ }
+ if _, err := alltransports.ParseImageName(imageName); err == nil {
+ if len(pulledImages) != 0 {
+ imageName = pulledImages[0].ID()
+ }
+ }
+ infraOptions.Quiet = curr
+ psg.InfraImage = imageName
+ psg.InfraContainerSpec.Image = imageName
+ psg.InfraContainerSpec.RawImageName = rawImageName
+ }
+ podSpecComplete := entities.PodSpec{PodSpecGen: psg}
+ pod, err := generate.MakePod(&podSpecComplete, runtime)
if err != nil {
httpCode := http.StatusInternalServerError
if errors.Cause(err) == define.ErrPodExists {
httpCode = http.StatusConflict
}
- utils.Error(w, "Something went wrong.", httpCode, err)
+ utils.Error(w, "Something went wrong.", httpCode, errors.Wrap(err, "failed to make pod"))
return
}
utils.WriteResponse(w, http.StatusCreated, handlers.IDResponse{ID: pod.ID()})
diff --git a/pkg/api/handlers/types/types.go b/pkg/api/handlers/types/types.go
index 71165364f..e7920047e 100644
--- a/pkg/api/handlers/types/types.go
+++ b/pkg/api/handlers/types/types.go
@@ -1,8 +1,6 @@
package types
-import (
- "github.com/containers/podman/v3/pkg/domain/entities"
-)
+import "github.com/containers/podman/v3/pkg/domain/entities"
// LibpodImagesRemoveReport is the return type for image removal via the rest
// api.
diff --git a/pkg/bindings/pods/pods.go b/pkg/bindings/pods/pods.go
index 9d3ff322e..a1a431a3b 100644
--- a/pkg/bindings/pods/pods.go
+++ b/pkg/bindings/pods/pods.go
@@ -9,27 +9,25 @@ import (
"github.com/containers/podman/v3/pkg/api/handlers"
"github.com/containers/podman/v3/pkg/bindings"
"github.com/containers/podman/v3/pkg/domain/entities"
- "github.com/containers/podman/v3/pkg/specgen"
jsoniter "github.com/json-iterator/go"
)
-func CreatePodFromSpec(ctx context.Context, s *specgen.PodSpecGenerator, options *CreateOptions) (*entities.PodCreateReport, error) {
+func CreatePodFromSpec(ctx context.Context, spec *entities.PodSpec) (*entities.PodCreateReport, error) {
var (
pcr entities.PodCreateReport
)
- if options == nil {
- options = new(CreateOptions)
+ if spec == nil {
+ spec = new(entities.PodSpec)
}
- _ = options
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
}
- specgenString, err := jsoniter.MarshalToString(s)
+ specString, err := jsoniter.MarshalToString(spec.PodSpecGen)
if err != nil {
return nil, err
}
- stringReader := strings.NewReader(specgenString)
+ stringReader := strings.NewReader(specString)
response, err := conn.DoRequest(stringReader, http.MethodPost, "/pods/create", nil, nil)
if err != nil {
return nil, err
diff --git a/pkg/bindings/test/pods_test.go b/pkg/bindings/test/pods_test.go
index b06ff31a2..5331cf439 100644
--- a/pkg/bindings/test/pods_test.go
+++ b/pkg/bindings/test/pods_test.go
@@ -8,6 +8,7 @@ import (
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/bindings"
"github.com/containers/podman/v3/pkg/bindings/pods"
+ "github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/specgen"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -333,9 +334,9 @@ var _ = Describe("Podman pods", func() {
})
It("simple create pod", func() {
- ps := specgen.PodSpecGenerator{}
- ps.Name = "foobar"
- _, err := pods.CreatePodFromSpec(bt.conn, &ps, nil)
+ ps := entities.PodSpec{PodSpecGen: specgen.PodSpecGenerator{InfraContainerSpec: &specgen.SpecGenerator{}}}
+ ps.PodSpecGen.Name = "foobar"
+ _, err := pods.CreatePodFromSpec(bt.conn, &ps)
Expect(err).To(BeNil())
exists, err := pods.Exists(bt.conn, "foobar", nil)
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 5acf7211c..bd011d309 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -68,7 +68,7 @@ type ContainerEngine interface {
NetworkRm(ctx context.Context, namesOrIds []string, options NetworkRmOptions) ([]*NetworkRmReport, error)
PlayKube(ctx context.Context, path string, opts PlayKubeOptions) (*PlayKubeReport, error)
PlayKubeDown(ctx context.Context, path string, opts PlayKubeDownOptions) (*PlayKubeReport, error)
- PodCreate(ctx context.Context, opts PodCreateOptions) (*PodCreateReport, error)
+ PodCreate(ctx context.Context, specg PodSpec) (*PodCreateReport, error)
PodExists(ctx context.Context, nameOrID string) (*BoolReport, error)
PodInspect(ctx context.Context, options PodInspectOptions) (*PodInspectReport, error)
PodKill(ctx context.Context, namesOrIds []string, options PodKillOptions) ([]*PodKillReport, error)
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index c66bf96fc..10bd7e5ce 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -106,6 +106,14 @@ type PodRmReport struct {
Id string //nolint
}
+// PddSpec is an abstracted version of PodSpecGen designed to eventually accept options
+// not meant to be in a specgen
+type PodSpec struct {
+ PodSpecGen specgen.PodSpecGenerator
+}
+
+// PodCreateOptions provides all possible options for creating a pod and its infra container
+// swagger:model PodCreateOptions
type PodCreateOptions struct {
CGroupParent string
CreateCommand []string
@@ -125,6 +133,123 @@ type PodCreateOptions struct {
Userns specgen.Namespace
}
+type ContainerCreateOptions struct {
+ Annotation []string
+ Attach []string
+ Authfile string
+ BlkIOWeight string
+ BlkIOWeightDevice []string
+ CapAdd []string
+ CapDrop []string
+ CgroupNS string
+ CGroupsMode string
+ CGroupParent string
+ CIDFile string
+ ConmonPIDFile string
+ CPUPeriod uint64
+ CPUQuota int64
+ CPURTPeriod uint64
+ CPURTRuntime int64
+ CPUShares uint64
+ CPUS float64
+ CPUSetCPUs string
+ CPUSetMems string
+ Devices []string
+ DeviceCGroupRule []string
+ DeviceReadBPs []string
+ DeviceReadIOPs []string
+ DeviceWriteBPs []string
+ DeviceWriteIOPs []string
+ Entrypoint *string
+ Env []string
+ EnvHost bool
+ EnvFile []string
+ Expose []string
+ GIDMap []string
+ GroupAdd []string
+ HealthCmd string
+ HealthInterval string
+ HealthRetries uint
+ HealthStartPeriod string
+ HealthTimeout string
+ Hostname string
+ HTTPProxy bool
+ ImageVolume string
+ Init bool
+ InitContainerType string
+ InitPath string
+ Interactive bool
+ IPC string
+ KernelMemory string
+ Label []string
+ LabelFile []string
+ LogDriver string
+ LogOptions []string
+ Memory string
+ MemoryReservation string
+ MemorySwap string
+ MemorySwappiness int64
+ Name string
+ NoHealthCheck bool
+ OOMKillDisable bool
+ OOMScoreAdj int
+ Arch string
+ OS string
+ Variant string
+ PID string
+ PIDsLimit *int64
+ Platform string
+ Pod string
+ PodIDFile string
+ Personality string
+ PreserveFDs uint
+ Privileged bool
+ PublishAll bool
+ Pull string
+ Quiet bool
+ ReadOnly bool
+ ReadOnlyTmpFS bool
+ Restart string
+ Replace bool
+ Requires []string
+ Rm bool
+ RootFS bool
+ Secrets []string
+ SecurityOpt []string
+ SdNotifyMode string
+ ShmSize string
+ SignaturePolicy string
+ StopSignal string
+ StopTimeout uint
+ StorageOpt []string
+ SubUIDName string
+ SubGIDName string
+ Sysctl []string
+ Systemd string
+ Timeout uint
+ TLSVerify bool
+ TmpFS []string
+ TTY bool
+ Timezone string
+ Umask string
+ UIDMap []string
+ Ulimit []string
+ User string
+ UserNS string
+ UTS string
+ Mount []string
+ Volume []string
+ VolumesFrom []string
+ Workdir string
+ SeccompPolicy string
+ PidFile string
+ IsInfra bool
+
+ Net *NetOptions
+
+ CgroupConf []string
+}
+
type PodCreateReport struct {
Id string //nolint
}
@@ -149,21 +274,15 @@ func (p *PodCreateOptions) CPULimits() *specs.LinuxCPU {
return cpu
}
-func setNamespaces(p *PodCreateOptions) ([4]specgen.Namespace, error) {
- allNS := [4]specgen.Namespace{}
- if p.Pid != "" {
- pid, err := specgen.ParseNamespace(p.Pid)
- if err != nil {
- return [4]specgen.Namespace{}, err
- }
- allNS[0] = pid
- }
- return allNS, nil
-}
-
-func (p *PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) error {
+func ToPodSpecGen(s specgen.PodSpecGenerator, p *PodCreateOptions) (*specgen.PodSpecGenerator, error) {
// Basic Config
s.Name = p.Name
+ s.InfraName = p.InfraName
+ out, err := specgen.ParseNamespace(p.Pid)
+ if err != nil {
+ return nil, err
+ }
+ s.Pid = out
s.Hostname = p.Hostname
s.Labels = p.Labels
s.NoInfra = !p.Infra
@@ -174,32 +293,26 @@ func (p *PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) error {
s.InfraConmonPidFile = p.InfraConmonPidFile
}
s.InfraImage = p.InfraImage
- s.InfraName = p.InfraName
s.SharedNamespaces = p.Share
s.PodCreateCommand = p.CreateCommand
// Networking config
- s.NetNS = p.Net.Network
- s.StaticIP = p.Net.StaticIP
- s.StaticMAC = p.Net.StaticMAC
- s.PortMappings = p.Net.PublishPorts
- s.CNINetworks = p.Net.CNINetworks
- s.NetworkOptions = p.Net.NetworkOptions
- if p.Net.UseImageResolvConf {
- s.NoManageResolvConf = true
- }
- s.DNSServer = p.Net.DNSServers
- s.DNSSearch = p.Net.DNSSearch
- s.DNSOption = p.Net.DNSOptions
- s.NoManageHosts = p.Net.NoHosts
- s.HostAdd = p.Net.AddHosts
- namespaces, err := setNamespaces(p)
- if err != nil {
- return err
- }
- if !namespaces[0].IsDefault() {
- s.Pid = namespaces[0]
+ if p.Net != nil {
+ s.NetNS = p.Net.Network
+ s.StaticIP = p.Net.StaticIP
+ s.StaticMAC = p.Net.StaticMAC
+ s.PortMappings = p.Net.PublishPorts
+ s.CNINetworks = p.Net.CNINetworks
+ s.NetworkOptions = p.Net.NetworkOptions
+ if p.Net.UseImageResolvConf {
+ s.NoManageResolvConf = true
+ }
+ s.DNSServer = p.Net.DNSServers
+ s.DNSSearch = p.Net.DNSSearch
+ s.DNSOption = p.Net.DNSOptions
+ s.NoManageHosts = p.Net.NoHosts
+ s.HostAdd = p.Net.AddHosts
}
// Cgroup
@@ -219,7 +332,7 @@ func (p *PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) error {
}
}
s.Userns = p.Userns
- return nil
+ return &s, nil
}
type PodPruneOptions struct {
diff --git a/pkg/domain/entities/types.go b/pkg/domain/entities/types.go
index db4c6bb8a..ec4d4a902 100644
--- a/pkg/domain/entities/types.go
+++ b/pkg/domain/entities/types.go
@@ -31,21 +31,33 @@ type VolumeDeleteReport struct{ Report }
// NetOptions reflect the shared network options between
// pods and containers
+type NetFlags struct {
+ AddHosts []string `json:"add-host,omitempty"`
+ DNS []string `json:"dns,omitempty"`
+ DNSOpt []string `json:"dns-opt,omitempty"`
+ DNDSearch []string `json:"dns-search,omitempty"`
+ MacAddr string `json:"mac-address,omitempty"`
+ Publish []string `json:"publish,omitempty"`
+ IP string `json:"ip,omitempty"`
+ NoHosts bool `json:"no-hosts,omitempty"`
+ Network string `json:"network,omitempty"`
+ NetworkAlias []string `json:"network-alias,omitempty"`
+}
type NetOptions struct {
- AddHosts []string
- Aliases []string
- CNINetworks []string
- UseImageResolvConf bool
- DNSOptions []string
- DNSSearch []string
- DNSServers []net.IP
- Network specgen.Namespace
- NoHosts bool
- PublishPorts []types.PortMapping
- StaticIP *net.IP
- StaticMAC *net.HardwareAddr
+ AddHosts []string `json:"hostadd,omitempty"`
+ Aliases []string `json:"network_alias,omitempty"`
+ CNINetworks []string `json:"cni_networks,omitempty"`
+ UseImageResolvConf bool `json:"no_manage_resolv_conf,omitempty"`
+ DNSOptions []string `json:"dns_option,omitempty"`
+ DNSSearch []string `json:"dns_search,omitempty"`
+ DNSServers []net.IP `json:"dns_server,omitempty"`
+ Network specgen.Namespace `json:"netns,omitempty"`
+ NoHosts bool `json:"no_manage_hosts,omitempty"`
+ PublishPorts []types.PortMapping `json:"portmappings,omitempty"`
+ StaticIP *net.IP `json:"static_ip,omitempty"`
+ StaticMAC *net.HardwareAddr `json:"static_mac,omitempty"`
// NetworkOptions are additional options for each network
- NetworkOptions map[string][]string
+ NetworkOptions map[string][]string `json:"network_options,omitempty"`
}
// All CLI inspect commands and inspect sub-commands use the same options
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index a74b65ab9..8b2a5bfae 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -583,7 +583,11 @@ func (ic *ContainerEngine) ContainerCreate(ctx context.Context, s *specgen.SpecG
for _, w := range warn {
fmt.Fprintf(os.Stderr, "%s\n", w)
}
- ctr, err := generate.MakeContainer(ctx, ic.Libpod, s)
+ rtSpec, spec, opts, err := generate.MakeContainer(context.Background(), ic.Libpod, s)
+ if err != nil {
+ return nil, err
+ }
+ ctr, err := generate.ExecuteCreate(ctx, ic.Libpod, rtSpec, spec, false, opts...)
if err != nil {
return nil, err
}
@@ -915,7 +919,11 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
for _, w := range warn {
fmt.Fprintf(os.Stderr, "%s\n", w)
}
- ctr, err := generate.MakeContainer(ctx, ic.Libpod, opts.Spec)
+ rtSpec, spec, optsN, err := generate.MakeContainer(ctx, ic.Libpod, opts.Spec)
+ if err != nil {
+ return nil, err
+ }
+ ctr, err := generate.ExecuteCreate(ctx, ic.Libpod, rtSpec, spec, false, optsN...)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/abi/generate.go b/pkg/domain/infra/abi/generate.go
index b0853b554..2d7bc15f5 100644
--- a/pkg/domain/infra/abi/generate.go
+++ b/pkg/domain/infra/abi/generate.go
@@ -60,9 +60,7 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string,
return nil, err
}
} else {
- if len(ctr.Dependencies()) > 0 {
- return nil, errors.Wrapf(define.ErrNotImplemented, "containers with dependencies")
- }
+ // now that infra holds NS data, we need to support dependencies.
// we cannot deal with ctrs already in a pod.
if len(ctr.PodID()) > 0 {
return nil, errors.Errorf("container %s is associated with pod %s: use generate on the pod itself", ctr.ID(), ctr.PodID())
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index f22b2dbbb..2799df794 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -6,6 +6,7 @@ import (
"fmt"
"io"
"io/ioutil"
+ "net"
"os"
"path/filepath"
"strconv"
@@ -22,6 +23,7 @@ import (
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/specgen/generate"
"github.com/containers/podman/v3/pkg/specgen/generate/kube"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/containers/podman/v3/pkg/util"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
@@ -179,10 +181,12 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
}
}
- p, err := kube.ToPodGen(ctx, podName, podYAML)
+ podOpt := entities.PodCreateOptions{Infra: true, Net: &entities.NetOptions{StaticIP: &net.IP{}, StaticMAC: &net.HardwareAddr{}}}
+ podOpt, err = kube.ToPodOpt(ctx, podName, podOpt, podYAML)
if err != nil {
return nil, err
}
+
if options.Network != "" {
ns, cniNets, netOpts, err := specgen.ParseNetworkString(options.Network)
if err != nil {
@@ -193,42 +197,37 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
return nil, errors.Errorf("invalid value passed to --network: bridge or host networking must be configured in YAML")
}
logrus.Debugf("Pod %q joining CNI networks: %v", podName, cniNets)
- p.NetNS.NSMode = specgen.Bridge
- p.CNINetworks = append(p.CNINetworks, cniNets...)
+ podOpt.Net.Network.NSMode = specgen.Bridge
+ podOpt.Net.CNINetworks = append(podOpt.Net.CNINetworks, cniNets...)
if len(netOpts) > 0 {
- p.NetworkOptions = netOpts
+ podOpt.Net.NetworkOptions = netOpts
}
}
if len(options.StaticIPs) > *ipIndex {
- p.StaticIP = &options.StaticIPs[*ipIndex]
+ podOpt.Net.StaticIP = &options.StaticIPs[*ipIndex]
} else if len(options.StaticIPs) > 0 {
// only warn if the user has set at least one ip
logrus.Warn("No more static ips left using a random one")
}
if len(options.StaticMACs) > *ipIndex {
- p.StaticMAC = &options.StaticMACs[*ipIndex]
+ podOpt.Net.StaticMAC = &options.StaticMACs[*ipIndex]
} else if len(options.StaticIPs) > 0 {
// only warn if the user has set at least one mac
logrus.Warn("No more static macs left using a random one")
}
*ipIndex++
- // Create the Pod
- pod, err := generate.MakePod(p, ic.Libpod)
+ p := specgen.NewPodSpecGenerator()
if err != nil {
return nil, err
}
- podInfraID, err := pod.InfraContainerID()
+ p, err = entities.ToPodSpecGen(*p, &podOpt)
if err != nil {
return nil, err
}
-
- if !options.Quiet {
- writer = os.Stderr
- }
-
+ podSpec := entities.PodSpec{PodSpecGen: *p}
volumes, err := kube.InitializeVolumes(podYAML.Spec.Volumes)
if err != nil {
return nil, err
@@ -267,112 +266,146 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
configMaps = append(configMaps, cm)
}
- containers := make([]*libpod.Container, 0, len(podYAML.Spec.Containers))
- cwd, err := os.Getwd()
- if err != nil {
- return nil, err
- }
- for _, container := range podYAML.Spec.Containers {
- // Contains all labels obtained from kube
- labels := make(map[string]string)
- var pulledImage *libimage.Image
- buildFile, err := getBuildFile(container.Image, cwd)
+ if podOpt.Infra {
+ imagePull := config.DefaultInfraImage
+ if podOpt.InfraImage != config.DefaultInfraImage && podOpt.InfraImage != "" {
+ imagePull = podOpt.InfraImage
+ }
+
+ pulledImages, err := pullImage(ic, writer, imagePull, options, config.PullPolicyNewer)
if err != nil {
return nil, err
}
- existsLocally, err := ic.Libpod.LibimageRuntime().Exists(container.Image)
+ infraOptions := entities.ContainerCreateOptions{ImageVolume: "bind"}
+
+ podSpec.PodSpecGen.InfraImage = pulledImages[0].Names()[0]
+ podSpec.PodSpecGen.NoInfra = false
+ podSpec.PodSpecGen.InfraContainerSpec = specgen.NewSpecGenerator(pulledImages[0].Names()[0], false)
+ podSpec.PodSpecGen.InfraContainerSpec.NetworkOptions = p.NetworkOptions
+
+ err = specgenutil.FillOutSpecGen(podSpec.PodSpecGen.InfraContainerSpec, &infraOptions, []string{})
if err != nil {
return nil, err
}
- if (len(buildFile) > 0 && !existsLocally) || (len(buildFile) > 0 && options.Build) {
- buildOpts := new(buildahDefine.BuildOptions)
- commonOpts := new(buildahDefine.CommonBuildOptions)
- buildOpts.ConfigureNetwork = buildahDefine.NetworkDefault
- buildOpts.Isolation = buildahDefine.IsolationChroot
- buildOpts.CommonBuildOpts = commonOpts
- buildOpts.Output = container.Image
- if _, _, err := ic.Libpod.Build(ctx, *buildOpts, []string{buildFile}...); err != nil {
+ }
+
+ // Create the Pod
+ pod, err := generate.MakePod(&podSpec, ic.Libpod)
+ if err != nil {
+ return nil, err
+ }
+
+ podInfraID, err := pod.InfraContainerID()
+ if err != nil {
+ return nil, err
+ }
+
+ if !options.Quiet {
+ writer = os.Stderr
+ }
+
+ containers := make([]*libpod.Container, 0, len(podYAML.Spec.Containers))
+ cwd, err := os.Getwd()
+ if err != nil {
+ return nil, err
+ }
+ for _, container := range podYAML.Spec.Containers {
+ if !strings.Contains("infra", container.Name) {
+ // Contains all labels obtained from kube
+ labels := make(map[string]string)
+ var pulledImage *libimage.Image
+ buildFile, err := getBuildFile(container.Image, cwd)
+ if err != nil {
return nil, err
}
- i, _, err := ic.Libpod.LibimageRuntime().LookupImage(container.Image, new(libimage.LookupImageOptions))
+ existsLocally, err := ic.Libpod.LibimageRuntime().Exists(container.Image)
if err != nil {
return nil, err
}
- pulledImage = i
- } else {
- // NOTE: set the pull policy to "newer". This will cover cases
- // where the "latest" tag requires a pull and will also
- // transparently handle "localhost/" prefixed files which *may*
- // refer to a locally built image OR an image running a
- // registry on localhost.
- pullPolicy := config.PullPolicyNewer
- if len(container.ImagePullPolicy) > 0 {
- // Make sure to lower the strings since K8s pull policy
- // may be capitalized (see bugzilla.redhat.com/show_bug.cgi?id=1985905).
- rawPolicy := string(container.ImagePullPolicy)
- pullPolicy, err = config.ParsePullPolicy(strings.ToLower(rawPolicy))
+ if (len(buildFile) > 0 && !existsLocally) || (len(buildFile) > 0 && options.Build) {
+ buildOpts := new(buildahDefine.BuildOptions)
+ commonOpts := new(buildahDefine.CommonBuildOptions)
+ buildOpts.ConfigureNetwork = buildahDefine.NetworkDefault
+ buildOpts.Isolation = buildahDefine.IsolationChroot
+ buildOpts.CommonBuildOpts = commonOpts
+ buildOpts.Output = container.Image
+ if _, _, err := ic.Libpod.Build(ctx, *buildOpts, []string{buildFile}...); err != nil {
+ return nil, err
+ }
+ i, _, err := ic.Libpod.LibimageRuntime().LookupImage(container.Image, new(libimage.LookupImageOptions))
+ if err != nil {
+ return nil, err
+ }
+ pulledImage = i
+ } else {
+ // NOTE: set the pull policy to "newer". This will cover cases
+ // where the "latest" tag requires a pull and will also
+ // transparently handle "localhost/" prefixed files which *may*
+ // refer to a locally built image OR an image running a
+ // registry on localhost.
+ pullPolicy := config.PullPolicyNewer
+ if len(container.ImagePullPolicy) > 0 {
+ // Make sure to lower the strings since K8s pull policy
+ // may be capitalized (see bugzilla.redhat.com/show_bug.cgi?id=1985905).
+ rawPolicy := string(container.ImagePullPolicy)
+ pullPolicy, err = config.ParsePullPolicy(strings.ToLower(rawPolicy))
+ if err != nil {
+ return nil, err
+ }
+ }
+ pulledImages, err := pullImage(ic, writer, container.Image, options, pullPolicy)
if err != nil {
return nil, err
}
+ pulledImage = pulledImages[0]
+ }
+
+ // Handle kube annotations
+ for k, v := range annotations {
+ switch k {
+ // Auto update annotation without container name will apply to
+ // all containers within the pod
+ case autoupdate.Label, autoupdate.AuthfileLabel:
+ labels[k] = v
+ // Auto update annotation with container name will apply only
+ // to the specified container
+ case fmt.Sprintf("%s/%s", autoupdate.Label, container.Name),
+ fmt.Sprintf("%s/%s", autoupdate.AuthfileLabel, container.Name):
+ prefixAndCtr := strings.Split(k, "/")
+ labels[prefixAndCtr[0]] = v
+ }
}
- // This ensures the image is the image store
- pullOptions := &libimage.PullOptions{}
- pullOptions.AuthFilePath = options.Authfile
- pullOptions.CertDirPath = options.CertDir
- pullOptions.SignaturePolicyPath = options.SignaturePolicy
- pullOptions.Writer = writer
- pullOptions.Username = options.Username
- pullOptions.Password = options.Password
- pullOptions.InsecureSkipTLSVerify = options.SkipTLSVerify
-
- pulledImages, err := ic.Libpod.LibimageRuntime().Pull(ctx, container.Image, pullPolicy, pullOptions)
+
+ specgenOpts := kube.CtrSpecGenOptions{
+ Container: container,
+ Image: pulledImage,
+ Volumes: volumes,
+ PodID: pod.ID(),
+ PodName: podName,
+ PodInfraID: podInfraID,
+ ConfigMaps: configMaps,
+ SeccompPaths: seccompPaths,
+ RestartPolicy: ctrRestartPolicy,
+ NetNSIsHost: p.NetNS.IsHost(),
+ SecretsManager: secretsManager,
+ LogDriver: options.LogDriver,
+ Labels: labels,
+ }
+ specGen, err := kube.ToSpecGen(ctx, &specgenOpts)
if err != nil {
return nil, err
}
- pulledImage = pulledImages[0]
- }
- // Handle kube annotations
- for k, v := range annotations {
- switch k {
- // Auto update annotation without container name will apply to
- // all containers within the pod
- case autoupdate.Label, autoupdate.AuthfileLabel:
- labels[k] = v
- // Auto update annotation with container name will apply only
- // to the specified container
- case fmt.Sprintf("%s/%s", autoupdate.Label, container.Name),
- fmt.Sprintf("%s/%s", autoupdate.AuthfileLabel, container.Name):
- prefixAndCtr := strings.Split(k, "/")
- labels[prefixAndCtr[0]] = v
+ rtSpec, spec, opts, err := generate.MakeContainer(ctx, ic.Libpod, specGen)
+ if err != nil {
+ return nil, err
}
+ ctr, err := generate.ExecuteCreate(ctx, ic.Libpod, rtSpec, spec, false, opts...)
+ if err != nil {
+ return nil, err
+ }
+ containers = append(containers, ctr)
}
-
- specgenOpts := kube.CtrSpecGenOptions{
- Container: container,
- Image: pulledImage,
- Volumes: volumes,
- PodID: pod.ID(),
- PodName: podName,
- PodInfraID: podInfraID,
- ConfigMaps: configMaps,
- SeccompPaths: seccompPaths,
- RestartPolicy: ctrRestartPolicy,
- NetNSIsHost: p.NetNS.IsHost(),
- SecretsManager: secretsManager,
- LogDriver: options.LogDriver,
- Labels: labels,
- }
- specGen, err := kube.ToSpecGen(ctx, &specgenOpts)
- if err != nil {
- return nil, err
- }
-
- ctr, err := generate.MakeContainer(ctx, ic.Libpod, specGen)
- if err != nil {
- return nil, err
- }
- containers = append(containers, ctr)
}
if options.Start != types.OptionalBoolFalse {
@@ -383,6 +416,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
}
for id, err := range podStartErrors {
playKubePod.ContainerErrors = append(playKubePod.ContainerErrors, errors.Wrapf(err, "error starting container %s", id).Error())
+ fmt.Println(playKubePod.ContainerErrors)
}
}
@@ -656,3 +690,21 @@ func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, path string, _ enti
}
return reports, nil
}
+
+// pullImage is a helper function to set up the proper pull options and pull the image for certain containers
+func pullImage(ic *ContainerEngine, writer io.Writer, imagePull string, options entities.PlayKubeOptions, pullPolicy config.PullPolicy) ([]*libimage.Image, error) {
+ // This ensures the image is the image store
+ pullOptions := &libimage.PullOptions{}
+ pullOptions.AuthFilePath = options.Authfile
+ pullOptions.CertDirPath = options.CertDir
+ pullOptions.SignaturePolicyPath = options.SignaturePolicy
+ pullOptions.Writer = writer
+ pullOptions.Username = options.Username
+ pullOptions.Password = options.Password
+ pullOptions.InsecureSkipTLSVerify = options.SkipTLSVerify
+ pulledImages, err := ic.Libpod.LibimageRuntime().Pull(context.Background(), imagePull, pullPolicy, pullOptions)
+ if err != nil {
+ return nil, err
+ }
+ return pulledImages, nil
+}
diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go
index 055c495d5..98233f60d 100644
--- a/pkg/domain/infra/abi/pods.go
+++ b/pkg/domain/infra/abi/pods.go
@@ -8,7 +8,6 @@ import (
"github.com/containers/podman/v3/pkg/domain/entities"
dfilters "github.com/containers/podman/v3/pkg/domain/filters"
"github.com/containers/podman/v3/pkg/signal"
- "github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/specgen/generate"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -248,12 +247,8 @@ func (ic *ContainerEngine) prunePodHelper(ctx context.Context) ([]*entities.PodP
return reports, nil
}
-func (ic *ContainerEngine) PodCreate(ctx context.Context, opts entities.PodCreateOptions) (*entities.PodCreateReport, error) {
- podSpec := specgen.NewPodSpecGenerator()
- if err := opts.ToPodSpecGen(podSpec); err != nil {
- return nil, err
- }
- pod, err := generate.MakePod(podSpec, ic.Libpod)
+func (ic *ContainerEngine) PodCreate(ctx context.Context, specg entities.PodSpec) (*entities.PodCreateReport, error) {
+ pod, err := generate.MakePod(&specg, ic.Libpod)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/tunnel/events.go b/pkg/domain/infra/tunnel/events.go
index 6e2c3f8ba..203550c5d 100644
--- a/pkg/domain/infra/tunnel/events.go
+++ b/pkg/domain/infra/tunnel/events.go
@@ -7,6 +7,7 @@ import (
"github.com/containers/podman/v3/libpod/events"
"github.com/containers/podman/v3/pkg/bindings/system"
"github.com/containers/podman/v3/pkg/domain/entities"
+
"github.com/pkg/errors"
)
diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go
index 82f062b2c..480adb88a 100644
--- a/pkg/domain/infra/tunnel/pods.go
+++ b/pkg/domain/infra/tunnel/pods.go
@@ -6,7 +6,6 @@ import (
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/bindings/pods"
"github.com/containers/podman/v3/pkg/domain/entities"
- "github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
)
@@ -179,10 +178,8 @@ func (ic *ContainerEngine) PodPrune(ctx context.Context, opts entities.PodPruneO
return pods.Prune(ic.ClientCtx, nil)
}
-func (ic *ContainerEngine) PodCreate(ctx context.Context, opts entities.PodCreateOptions) (*entities.PodCreateReport, error) {
- podSpec := specgen.NewPodSpecGenerator()
- opts.ToPodSpecGen(podSpec)
- return pods.CreatePodFromSpec(ic.ClientCtx, podSpec, nil)
+func (ic *ContainerEngine) PodCreate(ctx context.Context, specg entities.PodSpec) (*entities.PodCreateReport, error) {
+ return pods.CreatePodFromSpec(ic.ClientCtx, &specg)
}
func (ic *ContainerEngine) PodTop(ctx context.Context, opts entities.PodTopOptions) (*entities.StringSliceReport, error) {
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 5101a6ccb..f82b2a3c6 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -22,10 +22,10 @@ import (
// MakeContainer creates a container based on the SpecGenerator.
// Returns the created, container and any warnings resulting from creating the
// container, or an error.
-func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator) (*libpod.Container, error) {
+func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator) (*spec.Spec, *specgen.SpecGenerator, []libpod.CtrCreateOption, error) {
rtc, err := rt.GetConfig()
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
// If joining a pod, retrieve the pod for use.
@@ -33,7 +33,7 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
if s.Pod != "" {
pod, err = rt.LookupPod(s.Pod)
if err != nil {
- return nil, errors.Wrapf(err, "error retrieving pod %s", s.Pod)
+ return nil, nil, nil, errors.Wrapf(err, "error retrieving pod %s", s.Pod)
}
}
@@ -41,47 +41,48 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
if s.PidNS.IsDefault() {
defaultNS, err := GetDefaultNamespaceMode("pid", rtc, pod)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
s.PidNS = defaultNS
}
if s.IpcNS.IsDefault() {
defaultNS, err := GetDefaultNamespaceMode("ipc", rtc, pod)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
s.IpcNS = defaultNS
}
if s.UtsNS.IsDefault() {
defaultNS, err := GetDefaultNamespaceMode("uts", rtc, pod)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
s.UtsNS = defaultNS
}
if s.UserNS.IsDefault() {
defaultNS, err := GetDefaultNamespaceMode("user", rtc, pod)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
s.UserNS = defaultNS
}
if s.NetNS.IsDefault() {
defaultNS, err := GetDefaultNamespaceMode("net", rtc, pod)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
s.NetNS = defaultNS
}
if s.CgroupNS.IsDefault() {
defaultNS, err := GetDefaultNamespaceMode("cgroup", rtc, pod)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
s.CgroupNS = defaultNS
}
options := []libpod.CtrCreateOption{}
+
if s.ContainerCreateCommand != nil {
options = append(options, libpod.WithCreateCommand(s.ContainerCreateCommand))
}
@@ -94,12 +95,11 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
var resolvedImageName string
newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, nil)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
-
imageData, err = newImage.Inspect(ctx, false)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
// If the input name changed, we could properly resolve the
// image. Otherwise, it must have been an ID where we're
@@ -115,29 +115,32 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
options = append(options, libpod.WithRootFSFromImage(newImage.ID(), resolvedImageName, s.RawImageName))
}
if err := s.Validate(); err != nil {
- return nil, errors.Wrap(err, "invalid config provided")
+ return nil, nil, nil, errors.Wrap(err, "invalid config provided")
}
finalMounts, finalVolumes, finalOverlays, err := finalizeMounts(ctx, s, rt, rtc, newImage)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
command, err := makeCommand(ctx, s, imageData, rtc)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
opts, err := createContainerOptions(ctx, rt, s, pod, finalVolumes, finalOverlays, imageData, command)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
options = append(options, opts...)
- exitCommandArgs, err := CreateExitCommandArgs(rt.StorageConfig(), rtc, logrus.IsLevelEnabled(logrus.DebugLevel), s.Remove, false)
+ var exitCommandArgs []string
+
+ exitCommandArgs, err = CreateExitCommandArgs(rt.StorageConfig(), rtc, logrus.IsLevelEnabled(logrus.DebugLevel), s.Remove, false)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
+
options = append(options, libpod.WithExitCommand(exitCommandArgs))
if len(s.Aliases) > 0 {
@@ -147,23 +150,26 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
if containerType := s.InitContainerType; len(containerType) > 0 {
options = append(options, libpod.WithInitCtrType(containerType))
}
-
+ if len(s.Name) > 0 {
+ logrus.Debugf("setting container name %s", s.Name)
+ options = append(options, libpod.WithName(s.Name))
+ }
if len(s.Devices) > 0 {
opts = extractCDIDevices(s)
options = append(options, opts...)
}
runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts, pod, command)
if err != nil {
- return nil, err
+ return nil, nil, nil, err
}
-
- ctr, err := rt.NewContainer(ctx, runtimeSpec, options...)
+ return runtimeSpec, s, options, err
+}
+func ExecuteCreate(ctx context.Context, rt *libpod.Runtime, runtimeSpec *spec.Spec, s *specgen.SpecGenerator, infra bool, options ...libpod.CtrCreateOption) (*libpod.Container, error) {
+ ctr, err := rt.NewContainer(ctx, runtimeSpec, s, infra, options...)
if err != nil {
return ctr, err
}
- // Copy the content from the underlying image into the newly created
- // volume if configured to do so.
return ctr, rt.PrepareVolumeOnCreateContainer(ctx, ctr)
}
@@ -256,11 +262,6 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
if len(s.SdNotifyMode) > 0 {
options = append(options, libpod.WithSdNotifyMode(s.SdNotifyMode))
}
-
- if len(s.Name) > 0 {
- logrus.Debugf("setting container name %s", s.Name)
- options = append(options, libpod.WithName(s.Name))
- }
if pod != nil {
logrus.Debugf("adding container to pod %s", pod.Name())
options = append(options, rt.WithPod(pod))
@@ -379,11 +380,11 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
options = append(options, libpod.WithPrivileged(s.Privileged))
// Get namespace related options
- namespaceOptions, err := namespaceOptions(ctx, s, rt, pod, imageData)
+ namespaceOpts, err := namespaceOptions(ctx, s, rt, pod, imageData)
if err != nil {
return nil, err
}
- options = append(options, namespaceOptions...)
+ options = append(options, namespaceOpts...)
if len(s.ConmonPidFile) > 0 {
options = append(options, libpod.WithConmonPidFile(s.ConmonPidFile))
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index 04b4e5ab3..5188abc3a 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -14,6 +14,7 @@ import (
"github.com/containers/image/v5/manifest"
"github.com/containers/podman/v3/libpod/network/types"
ann "github.com/containers/podman/v3/pkg/annotations"
+ "github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/specgen/generate"
"github.com/containers/podman/v3/pkg/util"
@@ -23,25 +24,26 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
)
-func ToPodGen(ctx context.Context, podName string, podYAML *v1.PodTemplateSpec) (*specgen.PodSpecGenerator, error) {
- p := specgen.NewPodSpecGenerator()
+func ToPodOpt(ctx context.Context, podName string, p entities.PodCreateOptions, podYAML *v1.PodTemplateSpec) (entities.PodCreateOptions, error) {
+ // p := specgen.NewPodSpecGenerator()
+ p.Net = &entities.NetOptions{}
p.Name = podName
p.Labels = podYAML.ObjectMeta.Labels
// Kube pods must share {ipc, net, uts} by default
- p.SharedNamespaces = append(p.SharedNamespaces, "ipc")
- p.SharedNamespaces = append(p.SharedNamespaces, "net")
- p.SharedNamespaces = append(p.SharedNamespaces, "uts")
+ p.Share = append(p.Share, "ipc")
+ p.Share = append(p.Share, "net")
+ p.Share = append(p.Share, "uts")
// TODO we only configure Process namespace. We also need to account for Host{IPC,Network,PID}
// which is not currently possible with pod create
if podYAML.Spec.ShareProcessNamespace != nil && *podYAML.Spec.ShareProcessNamespace {
- p.SharedNamespaces = append(p.SharedNamespaces, "pid")
+ p.Share = append(p.Share, "pid")
}
p.Hostname = podYAML.Spec.Hostname
if p.Hostname == "" {
p.Hostname = podName
}
if podYAML.Spec.HostNetwork {
- p.NetNS.NSMode = specgen.Host
+ p.Net.Network = specgen.Namespace{NSMode: "host"}
}
if podYAML.Spec.HostAliases != nil {
hosts := make([]string, 0, len(podYAML.Spec.HostAliases))
@@ -50,10 +52,10 @@ func ToPodGen(ctx context.Context, podName string, podYAML *v1.PodTemplateSpec)
hosts = append(hosts, host+":"+hostAlias.IP)
}
}
- p.HostAdd = hosts
+ p.Net.AddHosts = hosts
}
podPorts := getPodPorts(podYAML.Spec.Containers)
- p.PortMappings = podPorts
+ p.Net.PublishPorts = podPorts
if dnsConfig := podYAML.Spec.DNSConfig; dnsConfig != nil {
// name servers
@@ -62,11 +64,11 @@ func ToPodGen(ctx context.Context, podName string, podYAML *v1.PodTemplateSpec)
for _, server := range dnsServers {
servers = append(servers, net.ParseIP(server))
}
- p.DNSServer = servers
+ p.Net.DNSServers = servers
}
// search domains
if domains := dnsConfig.Searches; len(domains) > 0 {
- p.DNSSearch = domains
+ p.Net.DNSSearch = domains
}
// dns options
if options := dnsConfig.Options; len(options) > 0 {
@@ -110,6 +112,8 @@ type CtrSpecGenOptions struct {
LogDriver string
// Labels define key-value pairs of metadata
Labels map[string]string
+ //
+ IsInfra bool
}
func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGenerator, error) {
@@ -216,19 +220,19 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
}
}
// If only the yaml.Command is specified, set it as the entrypoint and drop the image Cmd
- if len(opts.Container.Command) != 0 {
+ if !opts.IsInfra && len(opts.Container.Command) != 0 {
s.Entrypoint = opts.Container.Command
s.Command = []string{}
}
// Only override the cmd field if yaml.Args is specified
// Keep the image entrypoint, or the yaml.command if specified
- if len(opts.Container.Args) != 0 {
+ if !opts.IsInfra && len(opts.Container.Args) != 0 {
s.Command = opts.Container.Args
}
// FIXME,
// we are currently ignoring imageData.Config.ExposedPorts
- if opts.Container.WorkingDir != "" {
+ if !opts.IsInfra && opts.Container.WorkingDir != "" {
s.WorkDir = opts.Container.WorkingDir
}
diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go
index 80790dcc1..5349e224f 100644
--- a/pkg/specgen/generate/namespaces.go
+++ b/pkg/specgen/generate/namespaces.go
@@ -250,7 +250,7 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
if s.NetNS.Value != "" {
val = fmt.Sprintf("slirp4netns:%s", s.NetNS.Value)
}
- toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, val, nil))
+ toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, val, s.CNINetworks))
case specgen.Private:
fallthrough
case specgen.Bridge:
diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go
index 1f3f9e832..80c7f112f 100644
--- a/pkg/specgen/generate/oci.go
+++ b/pkg/specgen/generate/oci.go
@@ -201,7 +201,8 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
Options: []string{"rprivate", "nosuid", "noexec", "nodev", "rw"},
}
g.AddMount(sysMnt)
- } else if !canMountSys {
+ }
+ if !canMountSys {
addCgroup = false
g.RemoveMount("/sys")
r := "ro"
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index 426cf1b6d..e523aef42 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -2,53 +2,82 @@ package generate
import (
"context"
+ "net"
+ "github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod"
+ "github.com/containers/podman/v3/libpod/define"
+ "github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
-func MakePod(p *specgen.PodSpecGenerator, rt *libpod.Runtime) (*libpod.Pod, error) {
- if err := p.Validate(); err != nil {
+func MakePod(p *entities.PodSpec, rt *libpod.Runtime) (*libpod.Pod, error) {
+ if err := p.PodSpecGen.Validate(); err != nil {
return nil, err
}
- options, err := createPodOptions(p, rt)
+ if !p.PodSpecGen.NoInfra && p.PodSpecGen.InfraContainerSpec != nil {
+ var err error
+ p.PodSpecGen.InfraContainerSpec, err = MapSpec(&p.PodSpecGen)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ options, err := createPodOptions(&p.PodSpecGen, rt, p.PodSpecGen.InfraContainerSpec)
if err != nil {
return nil, err
}
- return rt.NewPod(context.Background(), options...)
+ pod, err := rt.NewPod(context.Background(), p.PodSpecGen, options...)
+ if err != nil {
+ return nil, err
+ }
+ if !p.PodSpecGen.NoInfra && p.PodSpecGen.InfraContainerSpec != nil {
+ p.PodSpecGen.InfraContainerSpec.ContainerCreateCommand = []string{} // we do NOT want os.Args as the command, will display the pod create cmd
+ if p.PodSpecGen.InfraContainerSpec.Name == "" {
+ p.PodSpecGen.InfraContainerSpec.Name = pod.ID()[:12] + "-infra"
+ }
+ _, err = CompleteSpec(context.Background(), rt, p.PodSpecGen.InfraContainerSpec)
+ if err != nil {
+ return nil, err
+ }
+ p.PodSpecGen.InfraContainerSpec.User = "" // infraSpec user will get incorrectly assigned via the container creation process, overwrite here
+ rtSpec, spec, opts, err := MakeContainer(context.Background(), rt, p.PodSpecGen.InfraContainerSpec)
+ if err != nil {
+ return nil, err
+ }
+ spec.Pod = pod.ID()
+ opts = append(opts, rt.WithPod(pod))
+ spec.CgroupParent = pod.CgroupParent()
+ infraCtr, err := ExecuteCreate(context.Background(), rt, rtSpec, spec, true, opts...)
+ if err != nil {
+ return nil, err
+ }
+ pod, err = rt.AddInfra(context.Background(), pod, infraCtr)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return pod, nil
}
-func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime) ([]libpod.PodCreateOption, error) {
+func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime, infraSpec *specgen.SpecGenerator) ([]libpod.PodCreateOption, error) {
var (
options []libpod.PodCreateOption
)
- if !p.NoInfra {
+ if !p.NoInfra { //&& infraSpec != nil {
options = append(options, libpod.WithInfraContainer())
- nsOptions, err := GetNamespaceOptions(p.SharedNamespaces, p.NetNS.IsHost())
+ nsOptions, err := GetNamespaceOptions(p.SharedNamespaces, p.InfraContainerSpec.NetNS.IsHost())
if err != nil {
return nil, err
}
options = append(options, nsOptions...)
// Use pod user and infra userns only when --userns is not set to host
- if !p.Userns.IsHost() {
+ if !p.InfraContainerSpec.UserNS.IsHost() && !p.InfraContainerSpec.UserNS.IsDefault() {
options = append(options, libpod.WithPodUser())
- options = append(options, libpod.WithPodUserns(p.Userns))
}
-
- // Make our exit command
- storageConfig := rt.StorageConfig()
- runtimeConfig, err := rt.GetConfig()
- if err != nil {
- return nil, err
- }
- exitCommand, err := CreateExitCommandArgs(storageConfig, runtimeConfig, logrus.IsLevelEnabled(logrus.DebugLevel), false, false)
- if err != nil {
- return nil, errors.Wrapf(err, "error creating infra container exit command")
- }
- options = append(options, libpod.WithPodInfraExitCommand(exitCommand))
}
if len(p.CgroupParent) > 0 {
options = append(options, libpod.WithPodCgroupParent(p.CgroupParent))
@@ -59,62 +88,27 @@ func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime) ([]libpod
if len(p.Name) > 0 {
options = append(options, libpod.WithPodName(p.Name))
}
- if p.ResourceLimits != nil && p.ResourceLimits.CPU != nil && p.ResourceLimits.CPU.Period != nil && p.ResourceLimits.CPU.Quota != nil {
- if *p.ResourceLimits.CPU.Period != 0 || *p.ResourceLimits.CPU.Quota != 0 {
- options = append(options, libpod.WithPodCPUPAQ((*p.ResourceLimits.CPU.Period), (*p.ResourceLimits.CPU.Quota)))
- }
- }
- if p.ResourceLimits != nil && p.ResourceLimits.CPU != nil && p.ResourceLimits.CPU.Cpus != "" {
- options = append(options, libpod.WithPodCPUSetCPUs(p.ResourceLimits.CPU.Cpus))
+ if p.PodCreateCommand != nil {
+ options = append(options, libpod.WithPodCreateCommand(p.PodCreateCommand))
}
+
if len(p.Hostname) > 0 {
options = append(options, libpod.WithPodHostname(p.Hostname))
}
- if len(p.HostAdd) > 0 {
- options = append(options, libpod.WithPodHosts(p.HostAdd))
- }
- if len(p.DNSServer) > 0 {
- var dnsServers []string
- for _, d := range p.DNSServer {
- dnsServers = append(dnsServers, d.String())
- }
- options = append(options, libpod.WithPodDNS(dnsServers))
- }
- if len(p.DNSOption) > 0 {
- options = append(options, libpod.WithPodDNSOption(p.DNSOption))
- }
- if len(p.DNSSearch) > 0 {
- options = append(options, libpod.WithPodDNSSearch(p.DNSSearch))
- }
- if p.StaticIP != nil {
- options = append(options, libpod.WithPodStaticIP(*p.StaticIP))
- }
- if p.StaticMAC != nil {
- options = append(options, libpod.WithPodStaticMAC(*p.StaticMAC))
- }
- if p.NoManageResolvConf {
- options = append(options, libpod.WithPodUseImageResolvConf())
- }
- if len(p.CNINetworks) > 0 {
- options = append(options, libpod.WithPodNetworks(p.CNINetworks))
- }
-
- if len(p.InfraImage) > 0 {
- options = append(options, libpod.WithInfraImage(p.InfraImage))
- }
- if len(p.InfraName) > 0 {
- options = append(options, libpod.WithInfraName(p.InfraName))
- }
-
- if len(p.InfraCommand) > 0 {
- options = append(options, libpod.WithInfraCommand(p.InfraCommand))
- }
+ return options, nil
+}
- if !p.Pid.IsDefault() {
- options = append(options, libpod.WithPodPidNS(p.Pid))
+// MapSpec modifies the already filled Infra specgenerator,
+// replacing necessary values with those specified in pod creation
+func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) {
+ if len(p.PortMappings) > 0 {
+ ports, _, _, err := ParsePortMapping(p.PortMappings)
+ if err != nil {
+ return nil, err
+ }
+ p.InfraContainerSpec.PortMappings = libpod.WithInfraContainerPorts(ports, p.InfraContainerSpec)
}
-
switch p.NetNS.NSMode {
case specgen.Default, "":
if p.NoInfra {
@@ -123,42 +117,88 @@ func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime) ([]libpod
}
if rootless.IsRootless() {
logrus.Debugf("Pod will use slirp4netns")
- options = append(options, libpod.WithPodSlirp4netns(p.NetworkOptions))
+ if p.InfraContainerSpec.NetNS.NSMode != "host" {
+ p.InfraContainerSpec.NetworkOptions = p.NetworkOptions
+ p.InfraContainerSpec.NetNS.NSMode = specgen.NamespaceMode("slirp4netns")
+ }
} else {
logrus.Debugf("Pod using bridge network mode")
}
case specgen.Bridge:
+ p.InfraContainerSpec.NetNS.NSMode = specgen.Bridge
logrus.Debugf("Pod using bridge network mode")
case specgen.Host:
logrus.Debugf("Pod will use host networking")
- options = append(options, libpod.WithPodHostNetwork())
+ if len(p.InfraContainerSpec.PortMappings) > 0 ||
+ p.InfraContainerSpec.StaticIP != nil ||
+ p.InfraContainerSpec.StaticMAC != nil ||
+ len(p.InfraContainerSpec.CNINetworks) > 0 ||
+ p.InfraContainerSpec.NetNS.NSMode == specgen.NoNetwork {
+ return nil, errors.Wrapf(define.ErrInvalidArg, "cannot set host network if network-related configuration is specified")
+ }
+ p.InfraContainerSpec.NetNS.NSMode = specgen.Host
case specgen.Slirp:
logrus.Debugf("Pod will use slirp4netns")
- options = append(options, libpod.WithPodSlirp4netns(p.NetworkOptions))
+ if p.InfraContainerSpec.NetNS.NSMode != "host" {
+ p.InfraContainerSpec.NetworkOptions = p.NetworkOptions
+ p.InfraContainerSpec.NetNS.NSMode = specgen.NamespaceMode("slirp4netns")
+ }
case specgen.NoNetwork:
logrus.Debugf("Pod will not use networking")
- options = append(options, libpod.WithPodNoNetwork())
+ if len(p.InfraContainerSpec.PortMappings) > 0 ||
+ p.InfraContainerSpec.StaticIP != nil ||
+ p.InfraContainerSpec.StaticMAC != nil ||
+ len(p.InfraContainerSpec.CNINetworks) > 0 ||
+ p.InfraContainerSpec.NetNS.NSMode == "host" {
+ return nil, errors.Wrapf(define.ErrInvalidArg, "cannot disable pod network if network-related configuration is specified")
+ }
+ p.InfraContainerSpec.NetNS.NSMode = specgen.NoNetwork
default:
return nil, errors.Errorf("pods presently do not support network mode %s", p.NetNS.NSMode)
}
- if p.NoManageHosts {
- options = append(options, libpod.WithPodUseImageHosts())
+ libpod.WithPodCgroups()
+ if len(p.InfraCommand) > 0 {
+ p.InfraContainerSpec.Entrypoint = p.InfraCommand
}
- if len(p.PortMappings) > 0 {
- ports, _, _, err := ParsePortMapping(p.PortMappings)
- if err != nil {
- return nil, err
- }
- options = append(options, libpod.WithInfraContainerPorts(ports))
+
+ if len(p.HostAdd) > 0 {
+ p.InfraContainerSpec.HostAdd = p.HostAdd
}
- options = append(options, libpod.WithPodCgroups())
- if p.PodCreateCommand != nil {
- options = append(options, libpod.WithPodCreateCommand(p.PodCreateCommand))
+ if len(p.DNSServer) > 0 {
+ var dnsServers []net.IP
+ dnsServers = append(dnsServers, p.DNSServer...)
+
+ p.InfraContainerSpec.DNSServers = dnsServers
+ }
+ if len(p.DNSOption) > 0 {
+ p.InfraContainerSpec.DNSOptions = p.DNSOption
+ }
+ if len(p.DNSSearch) > 0 {
+ p.InfraContainerSpec.DNSSearch = p.DNSSearch
+ }
+ if p.StaticIP != nil {
+ p.InfraContainerSpec.StaticIP = p.StaticIP
+ }
+ if p.StaticMAC != nil {
+ p.InfraContainerSpec.StaticMAC = p.StaticMAC
+ }
+ if p.NoManageResolvConf {
+ p.InfraContainerSpec.UseImageResolvConf = true
+ }
+ if len(p.CNINetworks) > 0 {
+ p.InfraContainerSpec.CNINetworks = p.CNINetworks
+ }
+ if p.NoManageHosts {
+ p.InfraContainerSpec.UseImageHosts = p.NoManageHosts
}
+
if len(p.InfraConmonPidFile) > 0 {
- options = append(options, libpod.WithInfraConmonPidFile(p.InfraConmonPidFile))
+ p.InfraContainerSpec.ConmonPidFile = p.InfraConmonPidFile
}
- return options, nil
+ if p.InfraImage != config.DefaultInfraImage {
+ p.InfraContainerSpec.Image = p.InfraImage
+ }
+ return p.InfraContainerSpec, nil
}
diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go
index 386571d11..8872a1321 100644
--- a/pkg/specgen/podspecgen.go
+++ b/pkg/specgen/podspecgen.go
@@ -67,7 +67,7 @@ type PodBasicConfig struct {
// Pid sets the process id namespace of the pod
// Optional (defaults to private if unset). This sets the PID namespace of the infra container
// This configuration will then be shared with the entire pod if PID namespace sharing is enabled via --share
- Pid Namespace `json:"pid,omitempty:"`
+ Pid Namespace `json:"pidns,omitempty"`
// Userns is used to indicate which kind of Usernamespace to enter.
// Any containers created within the pod will inherit the pod's userns settings.
// Optional
@@ -173,6 +173,7 @@ type PodSpecGenerator struct {
PodNetworkConfig
PodCgroupConfig
PodResourceConfig
+ InfraContainerSpec *SpecGenerator `json:"-"`
}
type PodResourceConfig struct {
diff --git a/cmd/podman/common/createparse.go b/pkg/specgenutil/createparse.go
index dcef1a151..b46d8fbc6 100644
--- a/cmd/podman/common/createparse.go
+++ b/pkg/specgenutil/createparse.go
@@ -1,13 +1,14 @@
-package common
+package specgenutil
import (
"github.com/containers/common/pkg/config"
+ "github.com/containers/podman/v3/pkg/domain/entities"
"github.com/pkg/errors"
)
// validate determines if the flags and values given by the user are valid. things checked
// by validate must not need any state information on the flag (i.e. changed)
-func (c *ContainerCLIOpts) validate() error {
+func validate(c *entities.ContainerCreateOptions) error {
var ()
if c.Rm && (c.Restart != "" && c.Restart != "no" && c.Restart != "on-failure") {
return errors.Errorf(`the --rm option conflicts with --restart, when the restartPolicy is not "" and "no"`)
@@ -23,7 +24,11 @@ func (c *ContainerCLIOpts) validate() error {
"ignore": "",
}
if _, ok := imageVolType[c.ImageVolume]; !ok {
- return errors.Errorf("invalid image-volume type %q. Pick one of bind, tmpfs, or ignore", c.ImageVolume)
+ if c.IsInfra {
+ c.ImageVolume = "bind"
+ } else {
+ return errors.Errorf("invalid image-volume type %q. Pick one of bind, tmpfs, or ignore", c.ImageVolume)
+ }
}
return nil
}
diff --git a/cmd/podman/common/ports.go b/pkg/specgenutil/ports.go
index 2092bbe53..6cc4de1ed 100644
--- a/cmd/podman/common/ports.go
+++ b/pkg/specgenutil/ports.go
@@ -1,4 +1,4 @@
-package common
+package specgenutil
import (
"github.com/docker/go-connections/nat"
diff --git a/cmd/podman/common/specgen.go b/pkg/specgenutil/specgen.go
index 59d32f568..9f676db1b 100644
--- a/cmd/podman/common/specgen.go
+++ b/pkg/specgenutil/specgen.go
@@ -1,6 +1,7 @@
-package common
+package specgenutil
import (
+ "encoding/json"
"fmt"
"os"
"strconv"
@@ -11,8 +12,9 @@ import (
"github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/libpod/define"
ann "github.com/containers/podman/v3/pkg/annotations"
+ "github.com/containers/podman/v3/pkg/domain/entities"
envLib "github.com/containers/podman/v3/pkg/env"
- ns "github.com/containers/podman/v3/pkg/namespaces"
+ "github.com/containers/podman/v3/pkg/namespaces"
"github.com/containers/podman/v3/pkg/specgen"
systemdDefine "github.com/containers/podman/v3/pkg/systemd/define"
"github.com/containers/podman/v3/pkg/util"
@@ -21,7 +23,7 @@ import (
"github.com/pkg/errors"
)
-func getCPULimits(c *ContainerCLIOpts) *specs.LinuxCPU {
+func getCPULimits(c *entities.ContainerCreateOptions) *specs.LinuxCPU {
cpu := &specs.LinuxCPU{}
hasLimits := false
@@ -67,7 +69,7 @@ func getCPULimits(c *ContainerCLIOpts) *specs.LinuxCPU {
return cpu
}
-func getIOLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.LinuxBlockIO, error) {
+func getIOLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (*specs.LinuxBlockIO, error) {
var err error
io := &specs.LinuxBlockIO{}
hasLimits := false
@@ -122,7 +124,7 @@ func getIOLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.LinuxBlo
return io, nil
}
-func getMemoryLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.LinuxMemory, error) {
+func getMemoryLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (*specs.LinuxMemory, error) {
var err error
memory := &specs.LinuxMemory{}
hasLimits := false
@@ -167,7 +169,7 @@ func getMemoryLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.Linu
memory.Kernel = &mk
hasLimits = true
}
- if c.MemorySwappiness >= 0 {
+ if c.MemorySwappiness > 0 {
swappiness := uint64(c.MemorySwappiness)
memory.Swappiness = &swappiness
hasLimits = true
@@ -182,7 +184,7 @@ func getMemoryLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.Linu
return memory, nil
}
-func setNamespaces(s *specgen.SpecGenerator, c *ContainerCLIOpts) error {
+func setNamespaces(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) error {
var err error
if c.PID != "" {
@@ -222,18 +224,22 @@ func setNamespaces(s *specgen.SpecGenerator, c *ContainerCLIOpts) error {
return nil
}
-func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string) error {
+func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions, args []string) error {
var (
err error
)
-
// validate flags as needed
- if err := c.validate(); err != nil {
+ if err := validate(c); err != nil {
return err
}
-
s.User = c.User
- inputCommand := args[1:]
+ var inputCommand []string
+ if !c.IsInfra {
+ if len(args) > 1 {
+ inputCommand = args[1:]
+ }
+ }
+
if len(c.HealthCmd) > 0 {
if c.NoHealthCheck {
return errors.New("Cannot specify both --no-healthcheck and --health-cmd")
@@ -247,12 +253,33 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
Test: []string{"NONE"},
}
}
-
- userNS := ns.UsernsMode(c.UserNS)
+ if err := setNamespaces(s, c); err != nil {
+ return err
+ }
+ userNS := namespaces.UsernsMode(s.UserNS.NSMode)
+ tempIDMap, err := util.ParseIDMapping(namespaces.UsernsMode(c.UserNS), []string{}, []string{}, "", "")
+ if err != nil {
+ return err
+ }
s.IDMappings, err = util.ParseIDMapping(userNS, c.UIDMap, c.GIDMap, c.SubUIDName, c.SubGIDName)
if err != nil {
return err
}
+ if len(s.IDMappings.GIDMap) == 0 {
+ s.IDMappings.AutoUserNsOpts.AdditionalGIDMappings = tempIDMap.AutoUserNsOpts.AdditionalGIDMappings
+ if s.UserNS.NSMode == specgen.NamespaceMode("auto") {
+ s.IDMappings.AutoUserNs = true
+ }
+ }
+ if len(s.IDMappings.UIDMap) == 0 {
+ s.IDMappings.AutoUserNsOpts.AdditionalUIDMappings = tempIDMap.AutoUserNsOpts.AdditionalUIDMappings
+ if s.UserNS.NSMode == specgen.NamespaceMode("auto") {
+ s.IDMappings.AutoUserNs = true
+ }
+ }
+ if tempIDMap.AutoUserNsOpts.Size != 0 {
+ s.IDMappings.AutoUserNsOpts.Size = tempIDMap.AutoUserNsOpts.Size
+ }
// If some mappings are specified, assume a private user namespace
if userNS.IsDefaultValue() && (!s.IDMappings.HostUIDMapping || !s.IDMappings.HostGIDMapping) {
s.UserNS.NSMode = specgen.Private
@@ -267,7 +294,9 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
}
// We are not handling the Expose flag yet.
// s.PortsExpose = c.Expose
- s.PortMappings = c.Net.PublishPorts
+ if c.Net != nil {
+ s.PortMappings = c.Net.PublishPorts
+ }
s.PublishExposedPorts = c.PublishAll
s.Pod = c.Pod
@@ -288,10 +317,6 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
}
s.Expose = expose
- if err := setNamespaces(s, c); err != nil {
- return err
- }
-
if sig := c.StopSignal; len(sig) > 0 {
stopSignal, err := util.ParseSignal(sig)
if err != nil {
@@ -380,6 +405,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
}
// Include the command used to create the container.
+
s.ContainerCreateCommand = os.Args
if len(inputCommand) > 0 {
@@ -394,28 +420,34 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
}
s.ShmSize = &shmSize
}
- s.CNINetworks = c.Net.CNINetworks
+
+ if c.Net != nil {
+ s.CNINetworks = c.Net.CNINetworks
+ }
// Network aliases
- if len(c.Net.Aliases) > 0 {
- // build a map of aliases where key=cniName
- aliases := make(map[string][]string, len(s.CNINetworks))
- for _, cniNetwork := range s.CNINetworks {
- aliases[cniNetwork] = c.Net.Aliases
+ if c.Net != nil {
+ if len(c.Net.Aliases) > 0 {
+ // build a map of aliases where key=cniName
+ aliases := make(map[string][]string, len(s.CNINetworks))
+ for _, cniNetwork := range s.CNINetworks {
+ aliases[cniNetwork] = c.Net.Aliases
+ }
+ s.Aliases = aliases
}
- s.Aliases = aliases
}
- s.HostAdd = c.Net.AddHosts
- s.UseImageResolvConf = c.Net.UseImageResolvConf
- s.DNSServers = c.Net.DNSServers
- s.DNSSearch = c.Net.DNSSearch
- s.DNSOptions = c.Net.DNSOptions
- s.StaticIP = c.Net.StaticIP
- s.StaticMAC = c.Net.StaticMAC
- s.NetworkOptions = c.Net.NetworkOptions
- s.UseImageHosts = c.Net.NoHosts
-
+ if c.Net != nil {
+ s.HostAdd = c.Net.AddHosts
+ s.UseImageResolvConf = c.Net.UseImageResolvConf
+ s.DNSServers = c.Net.DNSServers
+ s.DNSSearch = c.Net.DNSSearch
+ s.DNSOptions = c.Net.DNSOptions
+ s.StaticIP = c.Net.StaticIP
+ s.StaticMAC = c.Net.StaticMAC
+ s.NetworkOptions = c.Net.NetworkOptions
+ s.UseImageHosts = c.Net.NoHosts
+ }
s.ImageVolumeMode = c.ImageVolume
if s.ImageVolumeMode == "bind" {
s.ImageVolumeMode = "anonymous"
diff --git a/cmd/podman/common/util.go b/pkg/specgenutil/util.go
index cdfff9d6f..15676d086 100644
--- a/cmd/podman/common/util.go
+++ b/pkg/specgenutil/util.go
@@ -1,4 +1,4 @@
-package common
+package specgenutil
import (
"io/ioutil"
diff --git a/cmd/podman/common/volumes.go b/pkg/specgenutil/volumes.go
index 883d604da..e9f70fc9d 100644
--- a/cmd/podman/common/volumes.go
+++ b/pkg/specgenutil/volumes.go
@@ -1,4 +1,4 @@
-package common
+package specgenutil
import (
"fmt"
diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go
index c961bfc32..7297bfc6e 100644
--- a/test/e2e/pod_create_test.go
+++ b/test/e2e/pod_create_test.go
@@ -559,7 +559,7 @@ ENTRYPOINT ["sleep","99999"]
It("podman pod create --cpuset-cpus", func() {
podName := "testPod"
ctrName := "testCtr"
- numCPU := float64(sysinfo.NumCPU())
+ numCPU := float64(sysinfo.NumCPU()) - 1
numCPUStr := strconv.Itoa(int(numCPU))
in := "0-" + numCPUStr
podCreate := podmanTest.Podman([]string{"pod", "create", "--cpuset-cpus", in, "--name", podName})
@@ -588,20 +588,14 @@ ENTRYPOINT ["sleep","99999"]
podInspect.WaitWithDefaultTimeout()
Expect(podInspect).Should(Exit(0))
podJSON := podInspect.InspectPodToJSON()
- Expect(podJSON.InfraConfig.PidNS).To(Equal("path"))
+ Expect(podJSON.InfraConfig.PidNS).To(Equal(ns))
podName = "pidPod2"
ns = "pod"
podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"})
podCreate.WaitWithDefaultTimeout()
- Expect(podCreate).Should(Exit(0))
-
- podInspect = podmanTest.Podman([]string{"pod", "inspect", podName})
- podInspect.WaitWithDefaultTimeout()
- Expect(podInspect).Should(Exit(0))
- podJSON = podInspect.InspectPodToJSON()
- Expect(podJSON.InfraConfig.PidNS).To(Equal("pod"))
+ Expect(podCreate).Should(ExitWithError())
podName = "pidPod3"
ns = "host"