ps: support the container notation for ps --filter network=...

Signed-off-by: flouthoc <flouthoc.git@gmail.com>
This commit is contained in:
flouthoc
2021-07-29 16:25:18 +05:30
parent f17b810279
commit 2a484e782a
5 changed files with 120 additions and 32 deletions

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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 {

View File

@ -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))