diff options
author | flouthoc <flouthoc.git@gmail.com> | 2021-07-29 16:25:18 +0530 |
---|---|---|
committer | flouthoc <flouthoc.git@gmail.com> | 2021-07-30 19:31:05 +0530 |
commit | 2a484e782a23ad67c98e22121fde2b83b4072d1a (patch) | |
tree | 4691b5c19020ec9281bda7e58dee88e6d63d753f | |
parent | f17b810279fd04c3d574e8d3dcc1878d50083a68 (diff) | |
download | podman-2a484e782a23ad67c98e22121fde2b83b4072d1a.tar.gz podman-2a484e782a23ad67c98e22121fde2b83b4072d1a.tar.bz2 podman-2a484e782a23ad67c98e22121fde2b83b4072d1a.zip |
ps: support the container notation for ps --filter network=...
Signed-off-by: flouthoc <flouthoc.git@gmail.com>
-rw-r--r-- | libpod/container.go | 40 | ||||
-rw-r--r-- | libpod/container_inspect.go | 33 | ||||
-rw-r--r-- | libpod/runtime_ctr.go | 12 | ||||
-rw-r--r-- | pkg/domain/filters/containers.go | 30 | ||||
-rw-r--r-- | test/e2e/ps_test.go | 37 |
5 files changed, 120 insertions, 32 deletions
diff --git a/libpod/container.go b/libpod/container.go index 4b9bea5fc..f3f4b27b7 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -1173,6 +1173,46 @@ func (c *Container) Networks() ([]string, bool, error) { return c.networks() } +// NetworkMode gets the configured network mode for the container. +// Get actual value from the database +func (c *Container) NetworkMode() string { + networkMode := "" + ctrSpec := c.config.Spec + + switch { + case c.config.CreateNetNS: + // We actually store the network + // mode for Slirp and Bridge, so + // we can just use that + networkMode = string(c.config.NetMode) + case c.config.NetNsCtr != "": + networkMode = fmt.Sprintf("container:%s", c.config.NetNsCtr) + default: + // Find the spec's network namespace. + // If there is none, it's host networking. + // If there is one and it has a path, it's "ns:". + foundNetNS := false + for _, ns := range ctrSpec.Linux.Namespaces { + if ns.Type == spec.NetworkNamespace { + foundNetNS = true + if ns.Path != "" { + networkMode = fmt.Sprintf("ns:%s", ns.Path) + } else { + // We're making a network ns, but not + // configuring with Slirp or CNI. That + // means it's --net=none + networkMode = "none" + } + break + } + } + if !foundNetNS { + networkMode = "host" + } + } + return networkMode +} + // Unlocked accessor for networks func (c *Container) networks() ([]string, bool, error) { networks, err := c.runtime.state.GetNetworks(c) diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 638e0b756..8c662c488 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -618,38 +618,7 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named hostConfig.Tmpfs = tmpfs // Network mode parsing. - networkMode := "" - switch { - case c.config.CreateNetNS: - // We actually store the network - // mode for Slirp and Bridge, so - // we can just use that - networkMode = string(c.config.NetMode) - case c.config.NetNsCtr != "": - networkMode = fmt.Sprintf("container:%s", c.config.NetNsCtr) - default: - // Find the spec's network namespace. - // If there is none, it's host networking. - // If there is one and it has a path, it's "ns:". - foundNetNS := false - for _, ns := range ctrSpec.Linux.Namespaces { - if ns.Type == spec.NetworkNamespace { - foundNetNS = true - if ns.Path != "" { - networkMode = fmt.Sprintf("ns:%s", ns.Path) - } else { - // We're making a network ns, but not - // configuring with Slirp or CNI. That - // means it's --net=none - networkMode = "none" - } - break - } - } - if !foundNetNS { - networkMode = "host" - } - } + networkMode := c.NetworkMode() hostConfig.NetworkMode = networkMode // Port bindings. diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index ce4c5d758..31e2d09ce 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -894,6 +894,18 @@ func (r *Runtime) LookupContainer(idOrName string) (*Container, error) { return r.state.LookupContainer(idOrName) } +// LookupContainerId looks up a container id by its name or a partial ID +// If a partial ID is not unique, an error will be returned +func (r *Runtime) LookupContainerID(idOrName string) (string, error) { + r.lock.RLock() + defer r.lock.RUnlock() + + if !r.valid { + return "", define.ErrRuntimeStopped + } + return r.state.LookupContainerID(idOrName) +} + // GetContainers retrieves all containers from the state // Filters can be provided which will determine what containers are included in // the output. Multiple filters are handled by ANDing their output, so only diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go index 965a12468..dc9fed2a4 100644 --- a/pkg/domain/filters/containers.go +++ b/pkg/domain/filters/containers.go @@ -211,6 +211,36 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo }, nil case "network": return func(c *libpod.Container) bool { + networkMode := c.NetworkMode() + // support docker like `--filter network=container:<IDorName>` + // check if networkMode is configured as `container:<ctr>` + // peform a match against filter `container:<IDorName>` + // networks is already going to be empty if `container:<ctr>` is configured as Mode + if strings.HasPrefix(networkMode, "container:") { + networkModeContainerPart := strings.SplitN(networkMode, ":", 2) + if len(networkModeContainerPart) < 2 { + return false + } + networkModeContainerID := networkModeContainerPart[1] + for _, val := range filterValues { + if strings.HasPrefix(val, "container:") { + filterNetworkModePart := strings.SplitN(val, ":", 2) + if len(filterNetworkModePart) < 2 { + return false + } + filterNetworkModeIDorName := filterNetworkModePart[1] + filterID, err := r.LookupContainerID(filterNetworkModeIDorName) + if err != nil { + return false + } + if filterID == networkModeContainerID { + return true + } + } + } + return false + } + networks, _, err := c.Networks() // if err or no networks, quick out if err != nil || len(networks) == 0 { diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index e27ff27a4..aeb88e481 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -172,6 +172,43 @@ var _ = Describe("Podman ps", func() { Expect(fullCid).To(Equal(result.OutputToStringArray()[0])) }) + It("podman ps --filter network=container:<name>", func() { + ctrAlpha := "alpha" + container := podmanTest.Podman([]string{"run", "-dt", "--name", ctrAlpha, ALPINE, "top"}) + container.WaitWithDefaultTimeout() + Expect(container).Should(Exit(0)) + + ctrBravo := "bravo" + containerBravo := podmanTest.Podman([]string{"run", "-dt", "--network", "container:alpha", "--name", ctrBravo, ALPINE, "top"}) + containerBravo.WaitWithDefaultTimeout() + Expect(containerBravo).Should(Exit(0)) + + result := podmanTest.Podman([]string{"ps", "-a", "--format", "table {{.Names}}", "--filter", "network=container:alpha"}) + result.WaitWithDefaultTimeout() + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(result.OutputToString()).To(ContainSubstring("bravo")) + }) + + It("podman ps --filter network=container:<id>", func() { + ctrAlpha := "first" + container := podmanTest.Podman([]string{"run", "-dt", "--name", ctrAlpha, ALPINE, "top"}) + container.WaitWithDefaultTimeout() + cid := container.OutputToString() + Expect(container).Should(Exit(0)) + + ctrBravo := "second" + containerBravo := podmanTest.Podman([]string{"run", "-dt", "--network", "container:" + cid, "--name", ctrBravo, ALPINE, "top"}) + containerBravo.WaitWithDefaultTimeout() + Expect(containerBravo).Should(Exit(0)) + + result := podmanTest.Podman([]string{"ps", "-a", "--format", "table {{.Names}}", "--filter", "network=container:" + cid}) + result.WaitWithDefaultTimeout() + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(result.OutputToString()).To(ContainSubstring("second")) + }) + It("podman ps namespace flag", func() { _, ec, _ := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) |