2024-07-05 09:54:09 -04:00
package container
import (
2024-09-26 07:35:46 -04:00
"strings"
"sync"
2024-07-05 09:54:09 -04:00
"github.com/docker/cli/cli/command/completion"
2024-07-05 18:48:51 -04:00
"github.com/docker/docker/api/types/container"
2024-09-26 07:35:46 -04:00
"github.com/moby/sys/capability"
2024-07-05 19:46:47 -04:00
"github.com/moby/sys/signal"
2024-07-05 09:54:09 -04:00
"github.com/spf13/cobra"
)
2024-09-26 07:35:46 -04:00
// allCaps is the magic value for "all capabilities".
const allCaps = "ALL"
2024-07-05 09:54:09 -04:00
// allLinuxCapabilities is a list of all known Linux capabilities.
//
// TODO(thaJeztah): add descriptions, and enable descriptions for our completion scripts (cobra.CompletionOptions.DisableDescriptions is currently set to "true")
2024-09-26 07:35:46 -04:00
// TODO(thaJeztah): consider what casing we want to use for completion (see below);
//
// We need to consider what format is most convenient; currently we use the
// canonical name (uppercase and "CAP_" prefix), however, tab-completion is
// case-sensitive by default, so requires the user to type uppercase letters
// to filter the list of options.
//
// Bash completion provides a `completion-ignore-case on` option to make completion
// case-insensitive (https://askubuntu.com/a/87066), but it looks to be a global
// option; the current cobra.CompletionOptions also don't provide this as an option
// to be used in the generated completion-script.
//
// Fish completion has `smartcase` (by default?) which matches any case if
// all of the input is lowercase.
//
// Zsh does not appear have a dedicated option, but allows setting matching-rules
// (see https://superuser.com/a/1092328).
var allLinuxCapabilities = sync . OnceValue ( func ( ) [ ] string {
caps := capability . ListKnown ( )
out := make ( [ ] string , 0 , len ( caps ) + 1 )
out = append ( out , allCaps )
for _ , c := range caps {
out = append ( out , "CAP_" + strings . ToUpper ( c . String ( ) ) )
}
return out
} )
2024-07-05 09:54:09 -04:00
2024-07-05 18:48:51 -04:00
// restartPolicies is a list of all valid restart-policies..
//
// TODO(thaJeztah): add descriptions, and enable descriptions for our completion scripts (cobra.CompletionOptions.DisableDescriptions is currently set to "true")
var restartPolicies = [ ] string {
string ( container . RestartPolicyDisabled ) ,
string ( container . RestartPolicyAlways ) ,
string ( container . RestartPolicyOnFailure ) ,
string ( container . RestartPolicyUnlessStopped ) ,
}
2024-10-22 15:40:31 -04:00
// addCompletions adds the completions that `run` and `create` have in common.
func addCompletions ( cmd * cobra . Command , dockerCLI completion . APIClientProvider ) {
_ = cmd . RegisterFlagCompletionFunc ( "cap-add" , completeLinuxCapabilityNames )
_ = cmd . RegisterFlagCompletionFunc ( "cap-drop" , completeLinuxCapabilityNames )
_ = cmd . RegisterFlagCompletionFunc ( "env" , completion . EnvVarNames )
_ = cmd . RegisterFlagCompletionFunc ( "env-file" , completion . FileNames )
_ = cmd . RegisterFlagCompletionFunc ( "network" , completion . NetworkNames ( dockerCLI ) )
_ = cmd . RegisterFlagCompletionFunc ( "platform" , completion . Platforms )
_ = cmd . RegisterFlagCompletionFunc ( "pull" , completion . FromList ( PullImageAlways , PullImageMissing , PullImageNever ) )
_ = cmd . RegisterFlagCompletionFunc ( "restart" , completeRestartPolicies )
_ = cmd . RegisterFlagCompletionFunc ( "stop-signal" , completeSignals )
_ = cmd . RegisterFlagCompletionFunc ( "volumes-from" , completion . ContainerNames ( dockerCLI , true ) )
}
2024-07-05 09:54:09 -04:00
func completeLinuxCapabilityNames ( cmd * cobra . Command , args [ ] string , toComplete string ) ( names [ ] string , _ cobra . ShellCompDirective ) {
2024-09-26 07:35:46 -04:00
return completion . FromList ( allLinuxCapabilities ( ) ... ) ( cmd , args , toComplete )
2024-07-05 09:54:09 -04:00
}
2024-07-05 18:48:51 -04:00
func completeRestartPolicies ( cmd * cobra . Command , args [ ] string , toComplete string ) ( names [ ] string , _ cobra . ShellCompDirective ) {
return completion . FromList ( restartPolicies ... ) ( cmd , args , toComplete )
}
2024-07-05 19:46:47 -04:00
func completeSignals ( cmd * cobra . Command , args [ ] string , toComplete string ) ( names [ ] string , _ cobra . ShellCompDirective ) {
// TODO(thaJeztah): do we want to provide the full list here, or a subset?
signalNames := make ( [ ] string , 0 , len ( signal . SignalMap ) )
for k := range signal . SignalMap {
signalNames = append ( signalNames , k )
}
return completion . FromList ( signalNames ... ) ( cmd , args , toComplete )
}