-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5538 from albers/completion-events--filter
Completion for `events --filter`
- Loading branch information
Showing
4 changed files
with
464 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
package system | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/docker/cli/cli/command/completion" | ||
"github.com/docker/docker/api/types" | ||
"github.com/docker/docker/api/types/events" | ||
"github.com/docker/docker/api/types/image" | ||
"github.com/docker/docker/api/types/network" | ||
"github.com/docker/docker/api/types/volume" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
eventFilters = []string{"container", "daemon", "event", "image", "label", "network", "node", "scope", "type", "volume"} | ||
|
||
// eventTypes is a list of all event types. | ||
// This should be moved to the moby codebase once its usage is consolidated here. | ||
eventTypes = []events.Type{ | ||
events.BuilderEventType, | ||
events.ConfigEventType, | ||
events.ContainerEventType, | ||
events.DaemonEventType, | ||
events.ImageEventType, | ||
events.NetworkEventType, | ||
events.NodeEventType, | ||
events.PluginEventType, | ||
events.SecretEventType, | ||
events.ServiceEventType, | ||
events.VolumeEventType, | ||
} | ||
|
||
// eventActions is a list of all event actions. | ||
// This should be moved to the moby codebase once its usage is consolidated here. | ||
eventActions = []events.Action{ | ||
events.ActionCreate, | ||
events.ActionStart, | ||
events.ActionRestart, | ||
events.ActionStop, | ||
events.ActionCheckpoint, | ||
events.ActionPause, | ||
events.ActionUnPause, | ||
events.ActionAttach, | ||
events.ActionDetach, | ||
events.ActionResize, | ||
events.ActionUpdate, | ||
events.ActionRename, | ||
events.ActionKill, | ||
events.ActionDie, | ||
events.ActionOOM, | ||
events.ActionDestroy, | ||
events.ActionRemove, | ||
events.ActionCommit, | ||
events.ActionTop, | ||
events.ActionCopy, | ||
events.ActionArchivePath, | ||
events.ActionExtractToDir, | ||
events.ActionExport, | ||
events.ActionImport, | ||
events.ActionSave, | ||
events.ActionLoad, | ||
events.ActionTag, | ||
events.ActionUnTag, | ||
events.ActionPush, | ||
events.ActionPull, | ||
events.ActionPrune, | ||
events.ActionDelete, | ||
events.ActionEnable, | ||
events.ActionDisable, | ||
events.ActionConnect, | ||
events.ActionDisconnect, | ||
events.ActionReload, | ||
events.ActionMount, | ||
events.ActionUnmount, | ||
events.ActionExecCreate, | ||
events.ActionExecStart, | ||
events.ActionExecDie, | ||
events.ActionExecDetach, | ||
events.ActionHealthStatus, | ||
events.ActionHealthStatusRunning, | ||
events.ActionHealthStatusHealthy, | ||
events.ActionHealthStatusUnhealthy, | ||
} | ||
) | ||
|
||
// completeEventFilters provides completion for the filters that can be used with `--filter`. | ||
func completeEventFilters(dockerCLI completion.APIClientProvider) completion.ValidArgsFn { | ||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { | ||
key, _, ok := strings.Cut(toComplete, "=") | ||
if !ok { | ||
return postfixWith("=", eventFilters), cobra.ShellCompDirectiveNoSpace | ||
} | ||
switch key { | ||
case "container": | ||
return prefixWith("container=", containerNames(dockerCLI, cmd, args, toComplete)), cobra.ShellCompDirectiveNoFileComp | ||
case "daemon": | ||
return prefixWith("daemon=", daemonNames(dockerCLI, cmd)), cobra.ShellCompDirectiveNoFileComp | ||
case "event": | ||
return prefixWith("event=", validEventNames()), cobra.ShellCompDirectiveNoFileComp | ||
case "image": | ||
return prefixWith("image=", imageNames(dockerCLI, cmd)), cobra.ShellCompDirectiveNoFileComp | ||
case "label": | ||
return nil, cobra.ShellCompDirectiveNoFileComp | ||
case "network": | ||
return prefixWith("network=", networkNames(dockerCLI, cmd)), cobra.ShellCompDirectiveNoFileComp | ||
case "node": | ||
return prefixWith("node=", nodeNames(dockerCLI, cmd)), cobra.ShellCompDirectiveNoFileComp | ||
case "scope": | ||
return prefixWith("scope=", []string{"local", "swarm"}), cobra.ShellCompDirectiveNoFileComp | ||
case "type": | ||
return prefixWith("type=", eventTypeNames()), cobra.ShellCompDirectiveNoFileComp | ||
case "volume": | ||
return prefixWith("volume=", volumeNames(dockerCLI, cmd)), cobra.ShellCompDirectiveNoFileComp | ||
default: | ||
return postfixWith("=", eventFilters), cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp | ||
} | ||
} | ||
} | ||
|
||
// prefixWith prefixes every element in the slice with the given prefix. | ||
func prefixWith(prefix string, values []string) []string { | ||
result := make([]string, len(values)) | ||
for i, v := range values { | ||
result[i] = prefix + v | ||
} | ||
return result | ||
} | ||
|
||
// postfixWith appends postfix to every element in the slice. | ||
func postfixWith(postfix string, values []string) []string { | ||
result := make([]string, len(values)) | ||
for i, v := range values { | ||
result[i] = v + postfix | ||
} | ||
return result | ||
} | ||
|
||
// eventTypeNames provides a list of all event types. | ||
// The list is derived from eventTypes. | ||
func eventTypeNames() []string { | ||
names := make([]string, len(eventTypes)) | ||
for i, eventType := range eventTypes { | ||
names[i] = string(eventType) | ||
} | ||
return names | ||
} | ||
|
||
// validEventNames provides a list of all event actions. | ||
// The list is derived from eventActions. | ||
// Actions that are not suitable for usage in completions are removed. | ||
func validEventNames() []string { | ||
names := make([]string, 0, len(eventActions)) | ||
for _, eventAction := range eventActions { | ||
if strings.Contains(string(eventAction), " ") { | ||
continue | ||
} | ||
names = append(names, string(eventAction)) | ||
} | ||
return names | ||
} | ||
|
||
// containerNames contacts the API to get names and optionally IDs of containers. | ||
// In case of an error, an empty list is returned. | ||
func containerNames(dockerCLI completion.APIClientProvider, cmd *cobra.Command, args []string, toComplete string) []string { | ||
names, _ := completion.ContainerNames(dockerCLI, true)(cmd, args, toComplete) | ||
if names == nil { | ||
return []string{} | ||
} | ||
return names | ||
} | ||
|
||
// daemonNames contacts the API to get name and ID of the current docker daemon. | ||
// In case of an error, an empty list is returned. | ||
func daemonNames(dockerCLI completion.APIClientProvider, cmd *cobra.Command) []string { | ||
info, err := dockerCLI.Client().Info(cmd.Context()) | ||
if err != nil { | ||
return []string{} | ||
} | ||
return []string{info.Name, info.ID} | ||
} | ||
|
||
// imageNames contacts the API to get a list of image names. | ||
// In case of an error, an empty list is returned. | ||
func imageNames(dockerCLI completion.APIClientProvider, cmd *cobra.Command) []string { | ||
list, err := dockerCLI.Client().ImageList(cmd.Context(), image.ListOptions{}) | ||
if err != nil { | ||
return []string{} | ||
} | ||
names := make([]string, 0, len(list)) | ||
for _, img := range list { | ||
names = append(names, img.RepoTags...) | ||
} | ||
return names | ||
} | ||
|
||
// networkNames contacts the API to get a list of network names. | ||
// In case of an error, an empty list is returned. | ||
func networkNames(dockerCLI completion.APIClientProvider, cmd *cobra.Command) []string { | ||
list, err := dockerCLI.Client().NetworkList(cmd.Context(), network.ListOptions{}) | ||
if err != nil { | ||
return []string{} | ||
} | ||
names := make([]string, 0, len(list)) | ||
for _, nw := range list { | ||
names = append(names, nw.Name) | ||
} | ||
return names | ||
} | ||
|
||
// nodeNames contacts the API to get a list of node names. | ||
// In case of an error, an empty list is returned. | ||
func nodeNames(dockerCLI completion.APIClientProvider, cmd *cobra.Command) []string { | ||
list, err := dockerCLI.Client().NodeList(cmd.Context(), types.NodeListOptions{}) | ||
if err != nil { | ||
return []string{} | ||
} | ||
names := make([]string, 0, len(list)) | ||
for _, node := range list { | ||
names = append(names, node.Description.Hostname) | ||
} | ||
return names | ||
} | ||
|
||
// volumeNames contacts the API to get a list of volume names. | ||
// In case of an error, an empty list is returned. | ||
func volumeNames(dockerCLI completion.APIClientProvider, cmd *cobra.Command) []string { | ||
list, err := dockerCLI.Client().VolumeList(cmd.Context(), volume.ListOptions{}) | ||
if err != nil { | ||
return []string{} | ||
} | ||
names := make([]string, 0, len(list.Volumes)) | ||
for _, v := range list.Volumes { | ||
names = append(names, v.Name) | ||
} | ||
return names | ||
} |
Oops, something went wrong.