mirror of https://github.com/containers/podman.git
Merge pull request #11075 from flouthoc/ps-filter-network-by-container
ps: support the `container...` notation for `ps --filter network=...`
This commit is contained in:
commit
aaf02cfbd4
|
@ -1173,6 +1173,46 @@ func (c *Container) Networks() ([]string, bool, error) {
|
||||||
return c.networks()
|
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
|
// Unlocked accessor for networks
|
||||||
func (c *Container) networks() ([]string, bool, error) {
|
func (c *Container) networks() ([]string, bool, error) {
|
||||||
networks, err := c.runtime.state.GetNetworks(c)
|
networks, err := c.runtime.state.GetNetworks(c)
|
||||||
|
|
|
@ -618,38 +618,7 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
|
||||||
hostConfig.Tmpfs = tmpfs
|
hostConfig.Tmpfs = tmpfs
|
||||||
|
|
||||||
// Network mode parsing.
|
// Network mode parsing.
|
||||||
networkMode := ""
|
networkMode := c.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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hostConfig.NetworkMode = networkMode
|
hostConfig.NetworkMode = networkMode
|
||||||
|
|
||||||
// Port bindings.
|
// Port bindings.
|
||||||
|
|
|
@ -894,6 +894,18 @@ func (r *Runtime) LookupContainer(idOrName string) (*Container, error) {
|
||||||
return r.state.LookupContainer(idOrName)
|
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
|
// GetContainers retrieves all containers from the state
|
||||||
// Filters can be provided which will determine what containers are included in
|
// Filters can be provided which will determine what containers are included in
|
||||||
// the output. Multiple filters are handled by ANDing their output, so only
|
// the output. Multiple filters are handled by ANDing their output, so only
|
||||||
|
|
|
@ -211,6 +211,36 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
|
||||||
}, nil
|
}, nil
|
||||||
case "network":
|
case "network":
|
||||||
return func(c *libpod.Container) bool {
|
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()
|
networks, _, err := c.Networks()
|
||||||
// if err or no networks, quick out
|
// if err or no networks, quick out
|
||||||
if err != nil || len(networks) == 0 {
|
if err != nil || len(networks) == 0 {
|
||||||
|
|
|
@ -172,6 +172,43 @@ var _ = Describe("Podman ps", func() {
|
||||||
Expect(fullCid).To(Equal(result.OutputToStringArray()[0]))
|
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() {
|
It("podman ps namespace flag", func() {
|
||||||
_, ec, _ := podmanTest.RunLsContainer("")
|
_, ec, _ := podmanTest.RunLsContainer("")
|
||||||
Expect(ec).To(Equal(0))
|
Expect(ec).To(Equal(0))
|
||||||
|
|
Loading…
Reference in New Issue