summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflouthoc <flouthoc.git@gmail.com>2021-07-29 16:25:18 +0530
committerflouthoc <flouthoc.git@gmail.com>2021-07-30 19:31:05 +0530
commit2a484e782a23ad67c98e22121fde2b83b4072d1a (patch)
tree4691b5c19020ec9281bda7e58dee88e6d63d753f
parentf17b810279fd04c3d574e8d3dcc1878d50083a68 (diff)
downloadpodman-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.go40
-rw-r--r--libpod/container_inspect.go33
-rw-r--r--libpod/runtime_ctr.go12
-rw-r--r--pkg/domain/filters/containers.go30
-rw-r--r--test/e2e/ps_test.go37
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))