Skip to content

Commit 20e1b9d

Browse files
Merge pull request #24791 from arsenalzp/issue_24664
Allow filtering containers by command
2 parents 450f854 + af19eea commit 20e1b9d

File tree

13 files changed

+468
-11
lines changed

13 files changed

+468
-11
lines changed

cmd/podman/common/completion.go

+53-1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ func setupImageEngine(cmd *cobra.Command) (entities.ImageEngine, error) {
8888
}
8989

9090
func getContainers(cmd *cobra.Command, toComplete string, cType completeType, statuses ...string) ([]string, cobra.ShellCompDirective) {
91+
var listContainers []entities.ListContainer
9192
suggestions := []string{}
9293
listOpts := entities.ContainerListOptions{
9394
Filters: make(map[string][]string),
@@ -109,7 +110,20 @@ func getContainers(cmd *cobra.Command, toComplete string, cType completeType, st
109110
return nil, cobra.ShellCompDirectiveNoFileComp
110111
}
111112

112-
for _, c := range containers {
113+
listContainers = append(listContainers, containers...)
114+
115+
// Add containers from the external storage into complete list
116+
if ok, _ := cmd.Flags().GetBool("external"); ok {
117+
externalContainers, err := engine.ContainerListExternal(registry.Context())
118+
if err != nil {
119+
cobra.CompErrorln(err.Error())
120+
return nil, cobra.ShellCompDirectiveNoFileComp
121+
}
122+
123+
listContainers = append(listContainers, externalContainers...)
124+
}
125+
126+
for _, c := range listContainers {
113127
// include ids in suggestions if cType == completeIDs or
114128
// more then 2 chars are typed and cType == completeDefault
115129
if ((len(toComplete) > 1 && cType == completeDefault) ||
@@ -341,6 +355,43 @@ func getArtifacts(cmd *cobra.Command, toComplete string) ([]string, cobra.ShellC
341355
return suggestions, cobra.ShellCompDirectiveNoFileComp
342356
}
343357

358+
func getCommands(cmd *cobra.Command, toComplete string) ([]string, cobra.ShellCompDirective) {
359+
suggestions := []string{}
360+
lsOpts := entities.ContainerListOptions{}
361+
362+
engine, err := setupContainerEngine(cmd)
363+
if err != nil {
364+
cobra.CompErrorln(err.Error())
365+
return nil, cobra.ShellCompDirectiveNoFileComp
366+
}
367+
368+
containers, err := engine.ContainerList(registry.Context(), lsOpts)
369+
if err != nil {
370+
cobra.CompErrorln(err.Error())
371+
return nil, cobra.ShellCompDirectiveNoFileComp
372+
}
373+
374+
externalContainers, err := engine.ContainerListExternal(registry.Context())
375+
if err != nil {
376+
cobra.CompErrorln(err.Error())
377+
return nil, cobra.ShellCompDirectiveNoFileComp
378+
}
379+
containers = append(containers, externalContainers...)
380+
381+
for _, container := range containers {
382+
// taking of the first element of commands list is done intentionally
383+
// to exclude command arguments from suggestions (e.g. exclude arguments "-g daemon"
384+
// from "nginx -g daemon" output)
385+
if len(container.Command) > 0 {
386+
if strings.HasPrefix(container.Command[0], toComplete) {
387+
suggestions = append(suggestions, container.Command[0])
388+
}
389+
}
390+
}
391+
392+
return suggestions, cobra.ShellCompDirectiveNoFileComp
393+
}
394+
344395
func fdIsNotDir(f *os.File) bool {
345396
stat, err := f.Stat()
346397
if err != nil {
@@ -1703,6 +1754,7 @@ func AutocompletePsFilters(cmd *cobra.Command, args []string, toComplete string)
17031754
kv := keyValueCompletion{
17041755
"ancestor=": func(s string) ([]string, cobra.ShellCompDirective) { return getImages(cmd, s) },
17051756
"before=": func(s string) ([]string, cobra.ShellCompDirective) { return getContainers(cmd, s, completeDefault) },
1757+
"command=": func(s string) ([]string, cobra.ShellCompDirective) { return getCommands(cmd, s) },
17061758
"exited=": nil,
17071759
"health=": func(_ string) ([]string, cobra.ShellCompDirective) {
17081760
return []string{define.HealthCheckHealthy,

docs/source/markdown/podman-pause.1.md.in

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Valid filters are listed below:
4343
| pod | [Pod] name or full or partial ID of pod |
4444
| network | [Network] name or full ID of network |
4545
| until | [DateTime] Containers created before the given duration or time. |
46+
| command | [Command] the command the container is executing, only argv[0] is taken |
4647

4748
@@option latest
4849

docs/source/markdown/podman-ps.1.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ Valid filters are listed below:
6161
| pod | [Pod] name or full or partial ID of pod |
6262
| network | [Network] name or full ID of network |
6363
| until | [DateTime] container created before the given duration or time. |
64-
64+
| command | [Command] the command the container is executing, only argv[0] is taken |
6565

6666
#### **--format**=*format*
6767

docs/source/markdown/podman-restart.1.md.in

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Valid filters are listed below:
4646
| pod | [Pod] name or full or partial ID of pod |
4747
| network | [Network] name or full ID of network |
4848
| until | [DateTime] Containers created before the given duration or time. |
49+
| command | [Command] the command the container is executing, only argv[0] is taken |
4950

5051
@@option latest
5152

docs/source/markdown/podman-rm.1.md.in

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Valid filters are listed below:
5050
| pod | [Pod] name or full or partial ID of pod |
5151
| network | [Network] name or full ID of network |
5252
| until | [DateTime] Containers created before the given duration or time. |
53+
| command | [Command] the command the container is executing, only argv[0] is taken |
5354

5455
#### **--force**, **-f**
5556

docs/source/markdown/podman-start.1.md.in

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Valid filters are listed below:
5151
| pod | [Pod] name or full or partial ID of pod |
5252
| network | [Network] name or full ID of network |
5353
| until | [DateTime] Containers created before the given duration or time. |
54+
| command | [Command] the command the container is executing, only argv[0] is taken |
5455

5556
@@option interactive
5657

docs/source/markdown/podman-stop.1.md.in

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Valid filters are listed below:
4949
| pod | [Pod] name or full or partial ID of pod |
5050
| network | [Network] name or full ID of network |
5151
| until | [DateTime] Containers created before the given duration or time. |
52+
| command | [Command] the command the container is executing, only argv[0] is taken |
5253

5354
@@option ignore
5455

docs/source/markdown/podman-unpause.1.md.in

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Valid filters are listed below:
4343
| pod | [Pod] name or full or partial ID of pod |
4444
| network | [Network] name or full ID of network |
4545
| until | [DateTime] Containers created before the given duration or time. |
46+
| command | [Command] the command the container is executing, only argv[0] is taken |
4647

4748
@@option latest
4849

libpod/runtime_ctr.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -1246,11 +1246,21 @@ func (r *Runtime) GetContainers(loadState bool, filters ...ContainerFilter) ([]*
12461246
return nil, err
12471247
}
12481248

1249-
ctrsFiltered := make([]*Container, 0, len(ctrs))
1249+
ctrsFiltered := applyContainersFilters(ctrs, filters...)
12501250

1251-
for _, ctr := range ctrs {
1251+
return ctrsFiltered, nil
1252+
}
1253+
1254+
// Applies container filters on bunch of containers
1255+
func applyContainersFilters(containers []*Container, filters ...ContainerFilter) []*Container {
1256+
ctrsFiltered := make([]*Container, 0, len(containers))
1257+
1258+
for _, ctr := range containers {
12521259
include := true
12531260
for _, filter := range filters {
1261+
if filter == nil {
1262+
continue
1263+
}
12541264
include = include && filter(ctr)
12551265
}
12561266

@@ -1259,7 +1269,7 @@ func (r *Runtime) GetContainers(loadState bool, filters ...ContainerFilter) ([]*
12591269
}
12601270
}
12611271

1262-
return ctrsFiltered, nil
1272+
return ctrsFiltered
12631273
}
12641274

12651275
// GetAllContainers is a helper function for GetContainers

pkg/domain/entities/container_ps.go

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ import (
88
"github.com/containers/podman/v5/pkg/domain/entities/types"
99
)
1010

11+
// ExternalContainerFilter is a function to determine whether a container list is included
12+
// in command output. Container lists to be outputted are tested using the function.
13+
// A true return will include the container list, a false return will exclude it.
14+
type ExternalContainerFilter func(*ListContainer) bool
15+
1116
// ListContainer describes a container suitable for listing
1217
type ListContainer = types.ListContainer
1318

0 commit comments

Comments
 (0)