diff options
-rw-r--r-- | cmd/podman/main_local.go | 2 | ||||
-rw-r--r-- | cmd/podman/pod_rm.go | 2 | ||||
-rw-r--r-- | cmd/podman/pods_prune.go | 4 | ||||
-rw-r--r-- | cmd/podman/system_prune.go | 1 | ||||
-rw-r--r-- | docs/source/markdown/podman-create.1.md | 23 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-prune.1.md | 11 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-rm.1.md | 4 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod.1.md | 4 | ||||
-rw-r--r-- | docs/source/markdown/podman-run.1.md | 23 | ||||
-rw-r--r-- | docs/source/markdown/podman.1.md | 39 | ||||
-rw-r--r-- | docs/source/pod.rst | 4 | ||||
-rw-r--r-- | libpod/networking_linux.go | 34 | ||||
-rw-r--r-- | libpod/options.go | 8 | ||||
-rw-r--r-- | pkg/adapter/pods.go | 4 | ||||
-rw-r--r-- | pkg/varlinkapi/pods.go | 2 | ||||
-rw-r--r-- | test/e2e/pod_prune_test.go | 23 | ||||
-rw-r--r-- | test/e2e/pod_rm_test.go | 8 | ||||
-rw-r--r-- | test/e2e/run_networking_test.go | 14 |
18 files changed, 162 insertions, 48 deletions
diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go index 0484e3cf0..968d7331a 100644 --- a/cmd/podman/main_local.go +++ b/cmd/podman/main_local.go @@ -69,7 +69,7 @@ func init() { rootCmd.PersistentFlags().StringArrayVar(&MainGlobalOpts.StorageOpts, "storage-opt", []string{}, "Used to pass an option to the storage driver") rootCmd.PersistentFlags().BoolVar(&MainGlobalOpts.Syslog, "syslog", false, "Output logging information to syslog as well as the console") - rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.TmpDir, "tmpdir", "", "Path to the tmp directory") + rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.TmpDir, "tmpdir", "", "Path to the tmp directory for libpod state content.\n\nNote: use the environment variable 'TMPDIR' to change the temporary storage location for container images, '/var/tmp'.\n") rootCmd.PersistentFlags().BoolVar(&MainGlobalOpts.Trace, "trace", false, "Enable opentracing output") } diff --git a/cmd/podman/pod_rm.go b/cmd/podman/pod_rm.go index fcf1d5bc7..02daf8764 100644 --- a/cmd/podman/pod_rm.go +++ b/cmd/podman/pod_rm.go @@ -12,7 +12,7 @@ import ( var ( podRmCommand cliconfig.PodRmValues - podRmDescription = fmt.Sprintf(`podman rm will remove one or more pods from the host. + podRmDescription = fmt.Sprintf(`podman rm will remove one or more stopped pods and their containers from the host. The pod name or ID can be used. A pod with containers will not be removed without --force. If --force is specified, all containers will be stopped, then removed.`) _podRmCommand = &cobra.Command{ diff --git a/cmd/podman/pods_prune.go b/cmd/podman/pods_prune.go index d40e37bdb..1c5c0bb58 100644 --- a/cmd/podman/pods_prune.go +++ b/cmd/podman/pods_prune.go @@ -17,7 +17,7 @@ var ( _prunePodsCommand = &cobra.Command{ Use: "prune", Args: noSubArgs, - Short: "Remove all stopped pods", + Short: "Remove all stopped pods and their containers", Long: podPruneDescription, RunE: func(cmd *cobra.Command, args []string) error { podPruneCommand.InputArgs = args @@ -32,7 +32,7 @@ func init() { podPruneCommand.SetHelpTemplate(HelpTemplate()) podPruneCommand.SetUsageTemplate(UsageTemplate()) flags := podPruneCommand.Flags() - flags.BoolVarP(&podPruneCommand.Force, "force", "f", false, "Force removal of a running pods. The default is false") + flags.BoolVarP(&podPruneCommand.Force, "force", "f", false, "Force removal of all running pods. The default is false") } func podPruneCmd(c *cliconfig.PodPruneValues) error { diff --git a/cmd/podman/system_prune.go b/cmd/podman/system_prune.go index c4d76b2dd..ae5d7ed2d 100644 --- a/cmd/podman/system_prune.go +++ b/cmd/podman/system_prune.go @@ -82,7 +82,6 @@ Are you sure you want to continue? [y/N] `, volumeString) fmt.Println("Deleted Pods") pruneValues := cliconfig.PodPruneValues{ PodmanCommand: c.PodmanCommand, - Force: c.Force, } ctx := getContext() ok, failures, lasterr := runtime.PrunePods(ctx, &pruneValues) diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md index 0ddcc7ed8..82d2e8f6a 100644 --- a/docs/source/markdown/podman-create.1.md +++ b/docs/source/markdown/podman-create.1.md @@ -817,6 +817,10 @@ container. The `OPTIONS` are a comma delimited list and can be: * [rw|ro] * [z|Z] * [`[r]shared`|`[r]slave`|`[r]private`] +* [`[r]bind`] +* [`noexec`|`exec`] +* [`nodev`|`dev`] +* [`nosuid`|`suid`] The `CONTAINER-DIR` must be an absolute path such as `/src/docs`. The volume will be mounted into the container at this directory. @@ -870,6 +874,25 @@ where source dir is mounted on) has to have right propagation properties. For shared volumes, source mount point has to be shared. And for slave volumes, source mount has to be either shared or slave. +If you want to recursively mount a volume and all of it's submounts into a +container, then you can use the `rbind` option. By default the bind option is +used, and submounts of the source directory will not be mounted into the +container. + +Mounting the volume with the `nosuid` options means that SUID applications on +the volume will not be able to change their privilege. By default volumes +are mounted with `nosuid`. + +Mounting the volume with the noexec option means that no executables on the +volume will be able to executed within the container. + +Mounting the volume with the nodev option means that no devices on the volume +will be able to be used by processes within the container. By default volumes +are mounted with `nodev`. + +If the <source-dir> is a mount point, then "dev", "suid", and "exec" options are +ignored by the kernel. + Use `df <source-dir>` to figure out the source mount and then use `findmnt -o TARGET,PROPAGATION <source-mount-dir>` to figure out propagation properties of source mount. If `findmnt` utility is not available, then one diff --git a/docs/source/markdown/podman-pod-prune.1.md b/docs/source/markdown/podman-pod-prune.1.md index f79961b2f..478f563c3 100644 --- a/docs/source/markdown/podman-pod-prune.1.md +++ b/docs/source/markdown/podman-pod-prune.1.md @@ -1,16 +1,21 @@ % podman-pod-prune(1) ## NAME -podman-pod-prune - Remove all stopped pods +podman-pod-prune - Remove all stopped pods and their containers ## SYNOPSIS **podman pod prune** ## DESCRIPTION -**podman pod prune** removes all stopped pods from local storage. +**podman pod prune** removes all stopped pods and their containers from local storage. + +## OPTIONS + +**--force** **-f** +Force removal of all running pods and their containers. The default is false. ## EXAMPLES -Remove all stopped pods from local storage +Remove all stopped pods and their containers from local storage ``` $ sudo podman pod prune 22b8813332948064b6566370088c5e0230eeaf15a58b1c5646859fd9fc364fe7 diff --git a/docs/source/markdown/podman-pod-rm.1.md b/docs/source/markdown/podman-pod-rm.1.md index aee582dc6..14da2071f 100644 --- a/docs/source/markdown/podman-pod-rm.1.md +++ b/docs/source/markdown/podman-pod-rm.1.md @@ -1,13 +1,13 @@ % podman-pod-rm(1) ## NAME -podman\-pod\-rm - Remove one or more pods +podman\-pod\-rm - Remove one or more stopped pods and containers ## SYNOPSIS **podman pod rm** [*options*] *pod* ## DESCRIPTION -**podman pod rm** will remove one or more pods from the host. The pod name or ID can be used. The \-f option stops all containers and then removes them before removing the pod. Without the \-f option, a pod cannot be removed if it has associated containers. +**podman pod rm** will remove one or more stopped pods and their containers from the host. The pod name or ID can be used. The \-f option stops all containers and then removes them before removing the pod. ## OPTIONS diff --git a/docs/source/markdown/podman-pod.1.md b/docs/source/markdown/podman-pod.1.md index b3d002a06..e5a8207e9 100644 --- a/docs/source/markdown/podman-pod.1.md +++ b/docs/source/markdown/podman-pod.1.md @@ -18,10 +18,10 @@ podman pod is a set of subcommands that manage pods, or groups of containers. | inspect | [podman-pod-inspect(1)](podman-pod-inspect.1.md) | Displays information describing a pod. | | kill | [podman-pod-kill(1)](podman-pod-kill.1.md) | Kill the main process of each container in one or more pods. | | pause | [podman-pod-pause(1)](podman-pod-pause.1.md) | Pause one or more pods. | -| prune | [podman-pod-prune(1)](podman-pod-prune.1.md) | Remove all stopped pods. | +| prune | [podman-pod-prune(1)](podman-pod-prune.1.md) | Remove all stopped pods and their containers. | | ps | [podman-pod-ps(1)](podman-pod-ps.1.md) | Prints out information about pods. | | restart | [podman-pod-restart(1)](podman-pod-restart.1.md) | Restart one or more pods. | -| rm | [podman-pod-rm(1)](podman-pod-rm.1.md) | Remove one or more pods. | +| rm | [podman-pod-rm(1)](podman-pod-rm.1.md) | Remove one or more stopped pods and containers. | | start | [podman-pod-start(1)](podman-pod-start.1.md) | Start one or more pods. | | stats | [podman-pod-stats(1)](podman-pod-stats.1.md) | Display a live stream of resource usage stats for containers in one or more pods. | | stop | [podman-pod-stop(1)](podman-pod-stop.1.md) | Stop one or more pods. | diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index d487af235..e1177cb34 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -860,6 +860,10 @@ create one. * [`rw`|`ro`] * [`z`|`Z`] * [`[r]shared`|`[r]slave`|`[r]private`] +* [`[r]bind`] +* [`noexec`|`exec`] +* [`nodev`|`dev`] +* [`nosuid`|`suid`] The `CONTAINER-DIR` must be an absolute path such as `/src/docs`. The volume will be mounted into the container at this directory. @@ -913,6 +917,25 @@ where source dir is mounted on) has to have right propagation properties. For shared volumes, source mount point has to be shared. And for slave volumes, source mount has to be either shared or slave. +If you want to recursively mount a volume and all of it's submounts into a +container, then you can use the `rbind` option. By default the bind option is +used, and submounts of the source directory will not be mounted into the +container. + +Mounting the volume with the `nosuid` options means that SUID applications on +the volume will not be able to change their privilege. By default volumes +are mounted with `nosuid`. + +Mounting the volume with the noexec option means that no executables on the +volume will be able to executed within the container. + +Mounting the volume with the nodev option means that no devices on the volume +will be able to be used by processes within the container. By default volumes +are mounted with `nodev`. + +If the <source-dir> is a mount point, then "dev", "suid", and "exec" options are +ignored by the kernel. + Use `df <source-dir>` to figure out the source mount and then use `findmnt -o TARGET,PROPAGATION <source-mount-dir>` to figure out propagation properties of source mount. If `findmnt` utility is not available, then one diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/podman.1.md index f6fa1a457..c62f54fbb 100644 --- a/docs/source/markdown/podman.1.md +++ b/docs/source/markdown/podman.1.md @@ -21,10 +21,6 @@ created by the other. ## GLOBAL OPTIONS -**--help**, **-h** - -Print usage statement - **--cgroup-manager**=*manager* CGroup manager to use for container cgroups. Supported values are cgroupfs or systemd. Default is systemd unless overridden in the libpod.conf file. @@ -32,6 +28,17 @@ CGroup manager to use for container cgroups. Supported values are cgroupfs or sy Note: Setting this flag can cause certain commands to break when called on containers previously created by the other CGroup manager type. Note: CGroup manager is not supported in rootless mode when using CGroups Version V1. +**--cni-config-dir** +Path of the configuration directory for CNI networks. (Default: `/etc/cni/net.d`) + +**--config** +Path of a libpod config file detailing container server configuration options + +Default libpod config file is /usr/share/containers/libpod.conf. Override file is in /etc/containers/libpod.conf. In rootless mode the config file will be read from $HOME/.config/containers/libpod.conf. + +**--conmon** +Path of the conmon binary (Default path is configured in `libpod.conf`) + **--cpu-profile**=*path* Path to where the cpu performance results should be written @@ -40,6 +47,10 @@ Path to where the cpu performance results should be written Backend to use for storing events. Allowed values are **file**, **journald**, and **none**. +**--help**, **-h** + +Print usage statement + **--hooks-dir**=*path* Each `*.json` file in the path configures a hook for Podman containers. For more details on the syntax of the JSON files and the semantics of hook injection, see `oci-hooks(5)`. Podman and libpod currently support both the 1.0.0 and 0.1.0 hook schemas, although the 0.1.0 schema is deprecated. @@ -58,30 +69,30 @@ Podman and libpod currently support an additional `precreate` state which is cal **--log-level**=*level* -Log messages above specified level: debug, info, warn, error (default), fatal or panic +Log messages above specified level: debug, info, warn, error (default), fatal or panic (default: "error") **--namespace**=*namespace* Set libpod namespace. Namespaces are used to separate groups of containers and pods in libpod's state. When namespace is set, created containers and pods will join the given namespace, and only containers and pods in the given namespace will be visible to Podman. +**--network-cmd-path**=*path* +Path to the command binary to use for setting up a network. It is currently only used for setting up a slirp4netns network. If "" is used then the binary is looked up using the $PATH environment variable. + **--root=***value* Storage root dir in which data, including images, is stored (default: "/var/lib/containers/storage" for UID 0, "$HOME/.local/share/containers/storage" for other users). -Default root dir is configured in /etc/containers/storage.conf. +Default root dir is configured in `/etc/containers/storage.conf`. **--runroot**=*value* Storage state directory where all state information is stored (default: "/var/run/containers/storage" for UID 0, "/var/run/user/$UID/run" for other users). -Default state dir is configured in /etc/containers/storage.conf. +Default state dir is configured in `/etc/containers/storage.conf`. **--runtime**=*value* Name of the OCI runtime as specified in libpod.conf or absolute path to the OCI compatible binary used to run containers. -**--network-cmd-path**=*path* -Path to the command binary to use for setting up a network. It is currently only used for setting up a slirp4netns network. If "" is used then the binary is looked up using the $PATH environment variable. - **--storage-driver**=*value* Storage driver. The default storage driver for UID 0 is configured in /etc/containers/storage.conf (`$HOME/.config/containers/storage.conf` in rootless mode), and is *vfs* for non-root users when *fuse-overlayfs* is not available. The `STORAGE_DRIVER` environment variable overrides the default. The --storage-driver specified driver overrides all. @@ -95,10 +106,16 @@ Storage driver option, Default storage driver options are configured in /etc/con **--syslog** -output logging information to syslog as well as the console +Output logging information to syslog as well as the console. On remote clients, logging is directed to the file ~/.config/containers/podman.log +**--tmpdir** + +Path to the tmp directory, for libpod runtime content. + +NOTE --tmpdir is not used for the temporary storage of downloaded images. Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`. + **--version**, **-v** Print the version diff --git a/docs/source/pod.rst b/docs/source/pod.rst index 391686ce5..2df377762 100644 --- a/docs/source/pod.rst +++ b/docs/source/pod.rst @@ -11,13 +11,13 @@ Pod :doc:`pause <markdown/podman-pause.1>` Pause one or more pods -:doc:`prune <markdown/podman-pod-prune.1>` Remove all stopped pods +:doc:`prune <markdown/podman-pod-prune.1>` Remove all stopped pods and their containers :doc:`ps <markdown/podman-pod-ps.1>` List pods :doc:`restart <markdown/podman-pod-restart.1>` Restart one or more pods -:doc:`rm <markdown/podman-pod-rm.1>` Remove one or more pods +:doc:`rm <markdown/podman-pod-rm.1>` Remove one or more stopped pods and containers :doc:`start <markdown/podman-pod-start.1>` Start one or more pods diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index cba7b636a..a68338dbb 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -29,19 +29,40 @@ import ( // Get an OCICNI network config func (r *Runtime) getPodNetwork(id, name, nsPath string, networks []string, ports []ocicni.PortMapping, staticIP net.IP, staticMAC net.HardwareAddr) ocicni.PodNetwork { - defaultNetwork := r.netPlugin.GetDefaultNetworkName() + var networkKey string + if len(networks) > 0 { + // This is inconsistent for >1 network, but it's probably the + // best we can do. + networkKey = networks[0] + } else { + networkKey = r.netPlugin.GetDefaultNetworkName() + } network := ocicni.PodNetwork{ Name: name, Namespace: name, // TODO is there something else we should put here? We don't know about Kube namespaces ID: id, NetNS: nsPath, RuntimeConfig: map[string]ocicni.RuntimeConfig{ - defaultNetwork: {PortMappings: ports}, + networkKey: {PortMappings: ports}, }, } + // If we have extra networks, add them + if len(networks) > 0 { + network.Networks = make([]ocicni.NetAttachment, len(networks)) + for i, netName := range networks { + network.Networks[i].Name = netName + } + } + if staticIP != nil || staticMAC != nil { - network.Networks = []ocicni.NetAttachment{{Name: defaultNetwork}} + // For static IP or MAC, we need to populate networks even if + // it's just the default. + if len(networks) == 0 { + // If len(networks) == 0 this is guaranteed to be the + // default network. + network.Networks = []ocicni.NetAttachment{{Name: networkKey}} + } var rt ocicni.RuntimeConfig = ocicni.RuntimeConfig{PortMappings: ports} if staticIP != nil { rt.IP = staticIP.String() @@ -50,12 +71,7 @@ func (r *Runtime) getPodNetwork(id, name, nsPath string, networks []string, port rt.MAC = staticMAC.String() } network.RuntimeConfig = map[string]ocicni.RuntimeConfig{ - defaultNetwork: rt, - } - } else { - network.Networks = make([]ocicni.NetAttachment, len(networks)) - for i, netName := range networks { - network.Networks[i].Name = netName + networkKey: rt, } } diff --git a/libpod/options.go b/libpod/options.go index bfbbb9e2d..f7f14eb26 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1041,8 +1041,8 @@ func WithStaticIP(ip net.IP) CtrCreateOption { return errors.Wrapf(define.ErrInvalidArg, "cannot set a static IP if the container is not creating a network namespace") } - if len(ctr.config.Networks) != 0 { - return errors.Wrapf(define.ErrInvalidArg, "cannot set a static IP if joining additional CNI networks") + if len(ctr.config.Networks) > 1 { + return errors.Wrapf(define.ErrInvalidArg, "cannot set a static IP if joining more than 1 CNI network") } ctr.config.StaticIP = ip @@ -1066,8 +1066,8 @@ func WithStaticMAC(mac net.HardwareAddr) CtrCreateOption { return errors.Wrapf(define.ErrInvalidArg, "cannot set a static MAC if the container is not creating a network namespace") } - if len(ctr.config.Networks) != 0 { - return errors.Wrapf(define.ErrInvalidArg, "cannot set a static MAC if joining additional CNI networks") + if len(ctr.config.Networks) > 1 { + return errors.Wrapf(define.ErrInvalidArg, "cannot set a static MAC if joining more than 1 CNI network") } ctr.config.StaticMAC = mac diff --git a/pkg/adapter/pods.go b/pkg/adapter/pods.go index e9f3d41a9..a726153c0 100644 --- a/pkg/adapter/pods.go +++ b/pkg/adapter/pods.go @@ -77,7 +77,7 @@ func (r *LocalRuntime) PrunePods(ctx context.Context, cli *cliconfig.PodPruneVal pool.Add(shared.Job{ ID: p.ID(), Fn: func() error { - err := r.Runtime.RemovePod(ctx, p, cli.Force, cli.Force) + err := r.Runtime.RemovePod(ctx, p, true, cli.Force) if err != nil { logrus.Debugf("Failed to remove pod %s: %s", p.ID(), err.Error()) } @@ -101,7 +101,7 @@ func (r *LocalRuntime) RemovePods(ctx context.Context, cli *cliconfig.PodRmValue } for _, p := range pods { - if err := r.Runtime.RemovePod(ctx, p, cli.Force, cli.Force); err != nil { + if err := r.Runtime.RemovePod(ctx, p, true, cli.Force); err != nil { errs = append(errs, err) } else { podids = append(podids, p.ID()) diff --git a/pkg/varlinkapi/pods.go b/pkg/varlinkapi/pods.go index 9b659f66b..1ebe5d424 100644 --- a/pkg/varlinkapi/pods.go +++ b/pkg/varlinkapi/pods.go @@ -247,7 +247,7 @@ func (i *LibpodAPI) RemovePod(call iopodman.VarlinkCall, name string, force bool if err != nil { return call.ReplyPodNotFound(name, err.Error()) } - if err = i.Runtime.RemovePod(ctx, pod, force, force); err != nil { + if err = i.Runtime.RemovePod(ctx, pod, true, force); err != nil { return call.ReplyErrorOccurred(err.Error()) } diff --git a/test/e2e/pod_prune_test.go b/test/e2e/pod_prune_test.go index da0d425cb..389d3cb27 100644 --- a/test/e2e/pod_prune_test.go +++ b/test/e2e/pod_prune_test.go @@ -41,7 +41,24 @@ var _ = Describe("Podman pod prune", func() { Expect(result.ExitCode()).To(Equal(0)) }) - It("podman pod prune doesn't remove a pod with a container", func() { + It("podman pod prune doesn't remove a pod with a running container", func() { + _, ec, podid := podmanTest.CreatePod("") + Expect(ec).To(Equal(0)) + + ec2 := podmanTest.RunTopContainerInPod("", podid) + ec2.WaitWithDefaultTimeout() + Expect(ec2.ExitCode()).To(Equal(0)) + + result := podmanTest.Podman([]string{"pod", "prune"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To((Equal(0))) + + result = podmanTest.Podman([]string{"ps", "-qa"}) + result.WaitWithDefaultTimeout() + Expect(len(result.OutputToStringArray())).To(Equal(1)) + }) + + It("podman pod prune removes a pod with a stopped container", func() { _, ec, podid := podmanTest.CreatePod("") Expect(ec).To(Equal(0)) @@ -50,11 +67,11 @@ var _ = Describe("Podman pod prune", func() { result := podmanTest.Podman([]string{"pod", "prune"}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result.ExitCode()).To(Equal(0)) result = podmanTest.Podman([]string{"ps", "-qa"}) result.WaitWithDefaultTimeout() - Expect(len(result.OutputToStringArray())).To(Equal(1)) + Expect(len(result.OutputToStringArray())).To(Equal(0)) }) It("podman pod prune -f does remove a running container", func() { diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go index c0277ca0d..90f178be6 100644 --- a/test/e2e/pod_rm_test.go +++ b/test/e2e/pod_rm_test.go @@ -77,7 +77,7 @@ var _ = Describe("Podman pod rm", func() { Expect(result.OutputToString()).To(Not(ContainSubstring(podid2))) }) - It("podman pod rm doesn't remove a pod with a container", func() { + It("podman pod rm removes a pod with a container", func() { _, ec, podid := podmanTest.CreatePod("") Expect(ec).To(Equal(0)) @@ -86,11 +86,11 @@ var _ = Describe("Podman pod rm", func() { result := podmanTest.Podman([]string{"pod", "rm", podid}) result.WaitWithDefaultTimeout() - Expect(result.ExitCode()).To(Equal(125)) + Expect(result.ExitCode()).To(Equal(0)) result = podmanTest.Podman([]string{"ps", "-qa"}) result.WaitWithDefaultTimeout() - Expect(len(result.OutputToStringArray())).To(Equal(1)) + Expect(len(result.OutputToStringArray())).To(Equal(0)) }) It("podman pod rm -f does remove a running container", func() { @@ -136,7 +136,7 @@ var _ = Describe("Podman pod rm", func() { result := podmanTest.Podman([]string{"pod", "rm", "-a"}) result.WaitWithDefaultTimeout() Expect(result).To(ExitWithError()) - foundExpectedError, _ := result.ErrorGrepString("contains containers and cannot be removed") + foundExpectedError, _ := result.ErrorGrepString("cannot be removed") Expect(foundExpectedError).To(Equal(true)) num_pods = podmanTest.NumberOfPods() diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index ec12f709a..5e587b198 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -232,4 +232,18 @@ var _ = Describe("Podman run networking", func() { Expect(session).To(ExitWithError()) Expect(session.ErrorToString()).To(ContainSubstring("stat /run/netns/xxy: no such file or directory")) }) + + It("podman run in custom CNI network with --static-ip", func() { + SkipIfRootless() + netName := "podmantestnetwork" + ipAddr := "10.20.30.128" + create := podmanTest.Podman([]string{"network", "create", "--subnet", "10.20.30.0/24", netName}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(BeZero()) + + run := podmanTest.Podman([]string{"run", "-t", "-i", "--rm", "--net", netName, "--ip", ipAddr, ALPINE, "ip", "addr"}) + run.WaitWithDefaultTimeout() + Expect(run.ExitCode()).To(BeZero()) + Expect(run.OutputToString()).To(ContainSubstring(ipAddr)) + }) }) |