mirror of
https://github.com/containers/podman.git
synced 2025-07-03 17:27:18 +08:00
ps: support the container notation for ps --filter network=...
Signed-off-by: flouthoc <flouthoc.git@gmail.com>
This commit is contained in:
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
|
Reference in New Issue
Block a user