DockerCLI/contrib/completion/bash/docker

3034 lines
59 KiB
Plaintext
Raw Normal View History

#!/bin/bash
#
# bash completion file for core docker commands
#
# This script provides completion of:
# - commands and their options
# - container ids and names
# - image repos and tags
# - filepaths
#
# To enable the completions either:
# - place this file in /etc/bash_completion.d
# or
# - copy this file to e.g. ~/.docker-completion.sh and add the line
# below to your .bashrc after bash completion features are loaded
# . ~/.docker-completion.sh
#
# Configuration:
#
# For several commands, the amount of completions can be configured by
# setting environment variables.
#
# DOCKER_COMPLETION_SHOW_NETWORK_IDS
# DOCKER_COMPLETION_SHOW_NODE_IDS
# DOCKER_COMPLETION_SHOW_SERVICE_IDS
# "no" - Show names only (default)
# "yes" - Show names and ids
#
# You can tailor completion for the "events", "history", "inspect", "run",
# "rmi" and "save" commands by settings the following environment
# variables:
#
# DOCKER_COMPLETION_SHOW_IMAGE_IDS
# "none" - Show names only (default)
# "non-intermediate" - Show names and ids, but omit intermediate image IDs
# "all" - Show names and ids, including intermediate image IDs
#
# DOCKER_COMPLETION_SHOW_TAGS
# "yes" - include tags in completion options (default)
# "no" - don't include tags in completion options
#
# Note:
# Currently, the completions will not work if the docker daemon is not
# bound to the default communication port/socket
# If the docker daemon is using a unix socket for communication your user
# must have access to the socket for the completions to function correctly
#
# Note for developers:
# Please arrange options sorted alphabetically by long name with the short
# options immediately following their corresponding long form.
# This order should be applied to lists, alternatives and code blocks.
__docker_previous_extglob_setting=$(shopt -p extglob)
shopt -s extglob
__docker_q() {
docker ${host:+-H "$host"} ${config:+--config "$config"} 2>/dev/null "$@"
}
__docker_complete_containers_all() {
local IFS=$'\n'
local containers=( $(__docker_q ps -aq --no-trunc) )
if [ "$1" ]; then
containers=( $(__docker_q inspect --format "{{if $1}}{{.Id}}{{end}}" "${containers[@]}") )
fi
local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") )
names=( "${names[@]#/}" ) # trim off the leading "/" from the container names
unset IFS
COMPREPLY=( $(compgen -W "${names[*]} ${containers[*]}" -- "$cur") )
}
__docker_complete_containers_running() {
__docker_complete_containers_all '.State.Running'
}
__docker_complete_containers_stopped() {
__docker_complete_containers_all 'not .State.Running'
}
__docker_complete_containers_pauseable() {
__docker_complete_containers_all 'and .State.Running (not .State.Paused)'
}
__docker_complete_containers_unpauseable() {
__docker_complete_containers_all '.State.Paused'
}
__docker_complete_container_names() {
local containers=( $(__docker_q ps -aq --no-trunc) )
local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") )
names=( "${names[@]#/}" ) # trim off the leading "/" from the container names
COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") )
}
__docker_complete_container_ids() {
local containers=( $(__docker_q ps -aq) )
COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") )
}
__docker_complete_images() {
local images_args=""
case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in
all)
images_args="--no-trunc -a"
;;
non-intermediate)
images_args="--no-trunc"
;;
esac
local repo_print_command
if [ "${DOCKER_COMPLETION_SHOW_TAGS:-yes}" = "yes" ]; then
repo_print_command='print $1; print $1":"$2'
else
repo_print_command='print $1'
fi
local awk_script
case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in
all|non-intermediate)
awk_script='NR>1 { print $3; if ($1 != "<none>") { '"$repo_print_command"' } }'
;;
none|*)
awk_script='NR>1 && $1 != "<none>" { '"$repo_print_command"' }'
;;
esac
local images=$(__docker_q images $images_args | awk "$awk_script")
COMPREPLY=( $(compgen -W "$images" -- "$cur") )
__ltrim_colon_completions "$cur"
}
__docker_complete_image_repos() {
local repos="$(__docker_q images | awk 'NR>1 && $1 != "<none>" { print $1 }')"
COMPREPLY=( $(compgen -W "$repos" -- "$cur") )
}
__docker_complete_image_repos_and_tags() {
local reposAndTags="$(__docker_q images | awk 'NR>1 && $1 != "<none>" { print $1; print $1":"$2 }')"
COMPREPLY=( $(compgen -W "$reposAndTags" -- "$cur") )
__ltrim_colon_completions "$cur"
}
__docker_complete_containers_and_images() {
__docker_complete_containers_all
local containers=( "${COMPREPLY[@]}" )
__docker_complete_images
COMPREPLY+=( "${containers[@]}" )
}
# Returns the names and optionally IDs of networks.
# The selection can be narrowed by an optional filter parameter, e.g. 'type=custom'
__docker_networks() {
local filter="$1"
# By default, only network names are completed.
# Set DOCKER_COMPLETION_SHOW_NETWORK_IDS=yes to also complete network IDs.
local fields='$2'
[ "${DOCKER_COMPLETION_SHOW_NETWORK_IDS}" = yes ] && fields='$1,$2'
__docker_q network ls --no-trunc ${filter:+-f "$filter"} | awk "NR>1 {print $fields}"
#__docker_q network ls --no-trunc | awk "NR>1 {print $fields}"
}
__docker_complete_networks() {
COMPREPLY=( $(compgen -W "$(__docker_networks $@)" -- "$cur") )
}
__docker_complete_network_ids() {
COMPREPLY=( $(compgen -W "$(__docker_q network ls -q --no-trunc)" -- "$cur") )
}
__docker_complete_network_names() {
COMPREPLY=( $(compgen -W "$(__docker_q network ls | awk 'NR>1 {print $2}')" -- "$cur") )
}
__docker_complete_containers_in_network() {
local containers=$(__docker_q network inspect -f '{{range $i, $c := .Containers}}{{$i}} {{$c.Name}} {{end}}' "$1")
COMPREPLY=( $(compgen -W "$containers" -- "$cur") )
}
__docker_complete_volumes() {
COMPREPLY=( $(compgen -W "$(__docker_q volume ls -q)" -- "$cur") )
}
__docker_plugins() {
__docker_q info | sed -n "/^Plugins/,/^[^ ]/s/ $1: //p"
}
__docker_complete_plugins() {
COMPREPLY=( $(compgen -W "$(__docker_plugins $1)" -- "$cur") )
}
__docker_runtimes() {
__docker_q info | sed -n 's/^Runtimes: \(.*\)/\1/p'
}
__docker_complete_runtimes() {
COMPREPLY=( $(compgen -W "$(__docker_runtimes)" -- "$cur") )
}
# Returns a list of all nodes. Additional arguments to `docker node`
# may be specified in order to filter the node list, e.g.
# `__docker_nodes --filter role=manager`
# By default, only node names are completed.
# Set DOCKER_COMPLETION_SHOW_NODE_IDS=yes to also complete node IDs.
# An optional first argument `--id|--name` may be used to limit
# the output to the IDs or names of matching nodes. This setting takes
# precedence over the environment setting.
__docker_nodes() {
local fields='$2' # default: node name only
[ "${DOCKER_COMPLETION_SHOW_NODE_IDS}" = yes ] && fields='$1,$2' # ID and name
if [ "$1" = "--id" ] ; then
fields='$1' # IDs only
shift
elif [ "$1" = "--name" ] ; then
fields='$2' # names only
shift
fi
__docker_q node ls "$@" | tr -d '*' | awk "NR>1 {print $fields}"
}
# Applies completion of nodes based on the current value of `$cur` or
# the value of the optional first argument `--cur`, if given.
# Additional filters may be appended, see `__docker_nodes`.
__docker_complete_nodes() {
local current=$cur
if [ "$1" = "--cur" ] ; then
current="$2"
shift 2
fi
COMPREPLY=( $(compgen -W "$(__docker_nodes "$@")" -- "$current") )
}
__docker_complete_nodes_plus_self() {
__docker_complete_nodes "$@"
COMPREPLY+=( self )
}
# Returns a list of all services. Additional arguments to `docker service ls`
# may be specified in order to filter the service list, e.g.
# `__docker_services --filter name=xxx`
# By default, only node names are completed.
# Set DOCKER_COMPLETION_SHOW_SERVICE_IDS=yes to also complete service IDs.
# An optional first argument `--id|--name` may be used to limit
# the output to the IDs or names of matching services. This setting takes
# precedence over the environment setting.
__docker_services() {
local fields='$2' # default: service name only
[ "${DOCKER_COMPLETION_SHOW_SERVICE_IDS}" = yes ] && fields='$1,$2' # ID & name
if [ "$1" = "--id" ] ; then
fields='$1' # IDs only
shift
elif [ "$1" = "--name" ] ; then
fields='$2' # names only
shift
fi
__docker_q service ls "$@" | awk "NR>1 {print $fields}"
}
# Applies completion of services based on the current value of `$cur` or
# the value of the optional first argument `--cur`, if given.
# Additional filters may be appended, see `__docker_services`.
__docker_complete_services() {
local current=$cur
if [ "$1" = "--cur" ] ; then
current="$2"
shift 2
fi
COMPREPLY=( $(compgen -W "$(__docker_services "$@")" -- "$current") )
}
# Appends the word passed as an argument to every word in `$COMPREPLY`.
# Normally you do this with `compgen -S`. This function exists so that you can use
# the __docker_complete_XXX functions in cases where you need a suffix.
__docker_append_to_completions() {
COMPREPLY=( ${COMPREPLY[@]/%/"$1"} )
}
# Finds the position of the first word that is neither option nor an option's argument.
# If there are options that require arguments, you should pass a glob describing those
# options, e.g. "--option1|-o|--option2"
# Use this function to restrict completions to exact positions after the argument list.
__docker_pos_first_nonflag() {
local argument_flags=$1
local counter=$((${subcommand_pos:-${command_pos}} + 1))
while [ $counter -le $cword ]; do
if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then
(( counter++ ))
# eat "=" in case of --option=arg syntax
[ "${words[$counter]}" = "=" ] && (( counter++ ))
else
case "${words[$counter]}" in
-*)
;;
*)
break
;;
esac
fi
# Bash splits words at "=", retaining "=" as a word, examples:
# "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words
while [ "${words[$counter + 1]}" = "=" ] ; do
counter=$(( counter + 2))
done
(( counter++ ))
done
echo $counter
}
# If we are currently completing the value of a map option (key=value)
# which matches the extglob given as an argument, returns key.
# This function is needed for key-specific completions.
__docker_map_key_of_current_option() {
local glob="$1"
local key glob_pos
if [ "$cur" = "=" ] ; then # key= case
key="$prev"
glob_pos=$((cword - 2))
elif [[ $cur == *=* ]] ; then # key=value case (OSX)
key=${cur%=*}
glob_pos=$((cword - 1))
elif [ "$prev" = "=" ] ; then
key=${words[$cword - 2]} # key=value case
glob_pos=$((cword - 3))
else
return
fi
[ "${words[$glob_pos]}" = "=" ] && ((glob_pos--)) # --option=key=value syntax
[[ ${words[$glob_pos]} == @($glob) ]] && echo "$key"
}
# Returns the value of the first option matching option_glob.
# Valid values for option_glob are option names like '--log-level' and
# globs like '--log-level|-l'
# Only positions between the command and the current word are considered.
__docker_value_of_option() {
local option_extglob=$(__docker_to_extglob "$1")
local counter=$((command_pos + 1))
while [ $counter -lt $cword ]; do
case ${words[$counter]} in
$option_extglob )
echo ${words[$counter + 1]}
break
;;
esac
(( counter++ ))
done
}
# Transforms a multiline list of strings into a single line string
# with the words separated by "|".
# This is used to prepare arguments to __docker_pos_first_nonflag().
__docker_to_alternatives() {
local parts=( $1 )
local IFS='|'
echo "${parts[*]}"
}
# Transforms a multiline list of options into an extglob pattern
# suitable for use in case statements.
__docker_to_extglob() {
local extglob=$( __docker_to_alternatives "$1" )
echo "@($extglob)"
}
# Subcommand processing.
# Locates the first occurrence of any of the subcommands contained in the
# first argument. In case of a match, calls the corresponding completion
# function and returns 0.
# If no match is found, 1 is returned. The calling function can then
# continue processing its completion.
#
# TODO if the preceding command has options that accept arguments and an
# argument is equal ot one of the subcommands, this is falsely detected as
# a match.
__docker_subcommands() {
local subcommands="$1"
local counter=$(($command_pos + 1))
while [ $counter -lt $cword ]; do
case "${words[$counter]}" in
$(__docker_to_extglob "$subcommands") )
subcommand_pos=$counter
local subcommand=${words[$counter]}
local completions_func=_docker_${command}_${subcommand}
declare -F $completions_func >/dev/null && $completions_func
return 0
;;
esac
(( counter++ ))
done
return 1
}
# suppress trailing whitespace
__docker_nospace() {
# compopt is not available in ancient bash versions
type compopt &>/dev/null && compopt -o nospace
}
__docker_complete_resolved_hostname() {
command -v host >/dev/null 2>&1 || return
COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') )
}
__docker_local_interfaces() {
command -v ip >/dev/null 2>&1 || return
ip addr show scope global 2>/dev/null | sed -n 's| \+inet \([0-9.]\+\).* \([^ ]\+\)|\1 \2|p'
}
__docker_complete_local_interfaces() {
local additional_interface
if [ "$1" = "--add" ] ; then
additional_interface="$2"
fi
COMPREPLY=( $( compgen -W "$(__docker_local_interfaces) $additional_interface" -- "$cur" ) )
}
__docker_complete_capabilities() {
# The list of capabilities is defined in types.go, ALL was added manually.
COMPREPLY=( $( compgen -W "
ALL
AUDIT_CONTROL
AUDIT_WRITE
AUDIT_READ
BLOCK_SUSPEND
CHOWN
DAC_OVERRIDE
DAC_READ_SEARCH
FOWNER
FSETID
IPC_LOCK
IPC_OWNER
KILL
LEASE
LINUX_IMMUTABLE
MAC_ADMIN
MAC_OVERRIDE
MKNOD
NET_ADMIN
NET_BIND_SERVICE
NET_BROADCAST
NET_RAW
SETFCAP
SETGID
SETPCAP
SETUID
SYS_ADMIN
SYS_BOOT
SYS_CHROOT
SYSLOG
SYS_MODULE
SYS_NICE
SYS_PACCT
SYS_PTRACE
SYS_RAWIO
SYS_RESOURCE
SYS_TIME
SYS_TTY_CONFIG
WAKE_ALARM
" -- "$cur" ) )
}
__docker_complete_detach-keys() {
case "$prev" in
--detach-keys)
case "$cur" in
*,)
COMPREPLY=( $( compgen -W "${cur}ctrl-" -- "$cur" ) )
;;
*)
COMPREPLY=( $( compgen -W "ctrl-" -- "$cur" ) )
;;
esac
__docker_nospace
return
;;
esac
return 1
}
__docker_complete_isolation() {
COMPREPLY=( $( compgen -W "default hyperv process" -- "$cur" ) )
}
__docker_complete_log_drivers() {
COMPREPLY=( $( compgen -W "
awslogs
etwlogs
fluentd
gcplogs
gelf
journald
json-file
none
splunk
syslog
" -- "$cur" ) )
}
__docker_complete_log_options() {
# see docs/reference/logging/index.md
local awslogs_options="awslogs-region awslogs-group awslogs-stream"
local fluentd_options="env fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries labels tag"
local gcplogs_options="env gcp-log-cmd gcp-project labels"
local gelf_options="env gelf-address gelf-compression-level gelf-compression-type labels tag"
local journald_options="env labels tag"
local json_file_options="env labels max-file max-size"
local syslog_options="env labels syslog-address syslog-facility syslog-format syslog-tls-ca-cert syslog-tls-cert syslog-tls-key syslog-tls-skip-verify tag"
local splunk_options="env labels splunk-caname splunk-capath splunk-format splunk-gzip splunk-gzip-level splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url splunk-verify-connection tag"
local all_options="$fluentd_options $gcplogs_options $gelf_options $journald_options $json_file_options $syslog_options $splunk_options"
case $(__docker_value_of_option --log-driver) in
'')
COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) )
;;
awslogs)
COMPREPLY=( $( compgen -W "$awslogs_options" -S = -- "$cur" ) )
;;
fluentd)
COMPREPLY=( $( compgen -W "$fluentd_options" -S = -- "$cur" ) )
;;
gcplogs)
COMPREPLY=( $( compgen -W "$gcplogs_options" -S = -- "$cur" ) )
;;
gelf)
COMPREPLY=( $( compgen -W "$gelf_options" -S = -- "$cur" ) )
;;
journald)
COMPREPLY=( $( compgen -W "$journald_options" -S = -- "$cur" ) )
;;
json-file)
COMPREPLY=( $( compgen -W "$json_file_options" -S = -- "$cur" ) )
;;
syslog)
COMPREPLY=( $( compgen -W "$syslog_options" -S = -- "$cur" ) )
;;
splunk)
COMPREPLY=( $( compgen -W "$splunk_options" -S = -- "$cur" ) )
;;
*)
return
;;
esac
__docker_nospace
}
__docker_complete_log_driver_options() {
local key=$(__docker_map_key_of_current_option '--log-opt')
case "$key" in
fluentd-async-connect)
COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
return
;;
gelf-address)
COMPREPLY=( $( compgen -W "udp" -S "://" -- "${cur##*=}" ) )
__docker_nospace
return
;;
gelf-compression-level)
COMPREPLY=( $( compgen -W "1 2 3 4 5 6 7 8 9" -- "${cur##*=}" ) )
return
;;
gelf-compression-type)
COMPREPLY=( $( compgen -W "gzip none zlib" -- "${cur##*=}" ) )
return
;;
syslog-address)
COMPREPLY=( $( compgen -W "tcp:// tcp+tls:// udp:// unix://" -- "${cur##*=}" ) )
__docker_nospace
__ltrim_colon_completions "${cur}"
return
;;
syslog-facility)
COMPREPLY=( $( compgen -W "
auth
authpriv
cron
daemon
ftp
kern
local0
local1
local2
local3
local4
local5
local6
local7
lpr
mail
news
syslog
user
uucp
" -- "${cur##*=}" ) )
return
;;
syslog-format)
COMPREPLY=( $( compgen -W "rfc3164 rfc5424 rfc5424micro" -- "${cur##*=}" ) )
return
;;
syslog-tls-ca-cert|syslog-tls-cert|syslog-tls-key)
_filedir
return
;;
syslog-tls-skip-verify)
COMPREPLY=( $( compgen -W "true" -- "${cur##*=}" ) )
return
;;
splunk-url)
COMPREPLY=( $( compgen -W "http:// https://" -- "${cur##*=}" ) )
__docker_nospace
__ltrim_colon_completions "${cur}"
return
;;
splunk-gzip|splunk-insecureskipverify|splunk-verify-connection)
COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
return
;;
splunk-format)
COMPREPLY=( $( compgen -W "inline json raw" -- "${cur##*=}" ) )
return
;;
esac
return 1
}
__docker_complete_log_levels() {
COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) )
}
__docker_complete_restart() {
case "$prev" in
--restart)
case "$cur" in
on-failure:*)
;;
*)
COMPREPLY=( $( compgen -W "always no on-failure on-failure: unless-stopped" -- "$cur") )
;;
esac
return
;;
esac
return 1
}
# a selection of the available signals that is most likely of interest in the
# context of docker containers.
__docker_complete_signals() {
local signals=(
SIGCONT
SIGHUP
SIGINT
SIGKILL
SIGQUIT
SIGSTOP
SIGTERM
SIGUSR1
SIGUSR2
)
COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo $cur | tr '[:lower:]' '[:upper:]')" ) )
}
__docker_complete_user_group() {
if [[ $cur == *:* ]] ; then
COMPREPLY=( $(compgen -g -- "${cur#*:}") )
else
COMPREPLY=( $(compgen -u -S : -- "$cur") )
__docker_nospace
fi
}
# global options that may appear after the docker command
_docker_docker() {
local boolean_options="
$global_boolean_options
--help
--version -v
"
case "$prev" in
--config)
_filedir -d
return
;;
--log-level|-l)
__docker_complete_log_levels
return
;;
$(__docker_to_extglob "$global_options_with_args") )
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "$boolean_options $global_options_with_args" -- "$cur" ) )
;;
*)
local counter=$( __docker_pos_first_nonflag "$(__docker_to_extglob "$global_options_with_args")" )
if [ $cword -eq $counter ]; then
COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) )
fi
;;
esac
}
_docker_attach() {
__docker_complete_detach-keys && return
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy=false" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag '--detach-keys')
if [ $cword -eq $counter ]; then
__docker_complete_containers_running
fi
;;
esac
}
_docker_build() {
local options_with_args="
--build-arg
--cgroup-parent
--cpuset-cpus
--cpuset-mems
--cpu-shares -c
--cpu-period
--cpu-quota
--file -f
--isolation
--label
--memory -m
--memory-swap
--shm-size
--tag -t
--ulimit
"
local boolean_options="
--disable-content-trust=false
--force-rm
--help
--no-cache
--pull
--quiet -q
--rm
"
local all_options="$options_with_args $boolean_options"
case "$prev" in
--build-arg)
COMPREPLY=( $( compgen -e -- "$cur" ) )
__docker_nospace
return
;;
--file|-f)
_filedir
return
;;
--isolation)
__docker_complete_isolation
return
;;
--tag|-t)
__docker_complete_image_repos_and_tags
return
;;
$(__docker_to_extglob "$options_with_args") )
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) )
;;
*)
local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) )
if [ $cword -eq $counter ]; then
_filedir -d
fi
;;
esac
}
_docker_commit() {
case "$prev" in
--author|-a|--change|-c|--message|-m)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--author -a --change -c --help --message -m --pause=false -p=false" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag '--author|-a|--change|-c|--message|-m')
if [ $cword -eq $counter ]; then
__docker_complete_containers_all
return
fi
(( counter++ ))
if [ $cword -eq $counter ]; then
__docker_complete_image_repos_and_tags
return
fi
;;
esac
}
_docker_cp() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--follow-link -L --help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
case "$cur" in
*:)
return
;;
*)
# combined container and filename completion
_filedir
local files=( ${COMPREPLY[@]} )
__docker_complete_containers_all
COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
local containers=( ${COMPREPLY[@]} )
COMPREPLY=( $( compgen -W "${files[*]} ${containers[*]}" -- "$cur" ) )
if [[ "$COMPREPLY" == *: ]]; then
__docker_nospace
fi
return
;;
esac
fi
(( counter++ ))
if [ $cword -eq $counter ]; then
if [ -e "$prev" ]; then
__docker_complete_containers_all
COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
__docker_nospace
else
_filedir
fi
return
fi
;;
esac
}
_docker_create() {
_docker_run
}
_docker_daemon() {
local boolean_options="
$global_boolean_options
--disable-legacy-registry
--help
--icc=false
--ip-forward=false
--ip-masq=false
--iptables=false
--ipv6
--live-restore
--raw-logs
--selinux-enabled
--userland-proxy=false
"
local options_with_args="
$global_options_with_args
--add-runtime
--api-cors-header
--authorization-plugin
--bip
--bridge -b
--cgroup-parent
--cluster-advertise
--cluster-store
--cluster-store-opt
--config-file
--containerd
--default-gateway
--default-gateway-v6
--default-ulimit
--dns
--dns-search
--dns-opt
--exec-opt
--exec-root
--fixed-cidr
--fixed-cidr-v6
--graph -g
--group -G
--insecure-registry
--ip
--label
--log-driver
--log-opt
--max-concurrent-downloads
--max-concurrent-uploads
--mtu
--oom-score-adjust
--pidfile -p
--registry-mirror
--storage-driver -s
--storage-opt
--userns-remap
"
__docker_complete_log_driver_options && return
key=$(__docker_map_key_of_current_option '--cluster-store-opt')
case "$key" in
kv.*file)
cur=${cur##*=}
_filedir
return
;;
esac
local key=$(__docker_map_key_of_current_option '--storage-opt')
case "$key" in
dm.blkdiscard|dm.override_udev_sync_check|dm.use_deferred_removal|dm.use_deferred_deletion)
COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
return
;;
dm.fs)
COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur##*=}" ) )
return
;;
dm.thinpooldev)
cur=${cur##*=}
_filedir
return
;;
esac
case "$prev" in
--authorization-plugin)
__docker_complete_plugins Authorization
return
;;
--cluster-store)
COMPREPLY=( $( compgen -W "consul etcd zk" -S "://" -- "$cur" ) )
__docker_nospace
return
;;
--cluster-store-opt)
COMPREPLY=( $( compgen -W "discovery.heartbeat discovery.ttl kv.cacertfile kv.certfile kv.keyfile kv.path" -S = -- "$cur" ) )
__docker_nospace
return
;;
--exec-root|--graph|-g)
_filedir -d
return
;;
--log-driver)
__docker_complete_log_drivers
return
;;
--config-file|--containerd|--pidfile|-p|--tlscacert|--tlscert|--tlskey)
_filedir
return
;;
--storage-driver|-s)
COMPREPLY=( $( compgen -W "aufs btrfs devicemapper overlay overlay2 vfs zfs" -- "$(echo $cur | tr '[:upper:]' '[:lower:]')" ) )
return
;;
--storage-opt)
local btrfs_options="btrfs.min_space"
local devicemapper_options="
dm.basesize
dm.blkdiscard
dm.blocksize
dm.fs
dm.loopdatasize
dm.loopmetadatasize
dm.min_free_space
dm.mkfsarg
dm.mountopt
dm.override_udev_sync_check
dm.thinpooldev
dm.use_deferred_deletion
dm.use_deferred_removal
"
local zfs_options="zfs.fsname"
case $(__docker_value_of_option '--storage-driver|-s') in
'')
COMPREPLY=( $( compgen -W "$btrfs_options $devicemapper_options $zfs_options" -S = -- "$cur" ) )
;;
btrfs)
COMPREPLY=( $( compgen -W "$btrfs_options" -S = -- "$cur" ) )
;;
devicemapper)
COMPREPLY=( $( compgen -W "$devicemapper_options" -S = -- "$cur" ) )
;;
zfs)
COMPREPLY=( $( compgen -W "$zfs_options" -S = -- "$cur" ) )
;;
*)
return
;;
esac
__docker_nospace
return
;;
--log-level|-l)
__docker_complete_log_levels
return
;;
--log-opt)
__docker_complete_log_options
return
;;
--userns-remap)
__docker_complete_user_group
return
;;
$(__docker_to_extglob "$options_with_args") )
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) )
;;
esac
}
_docker_diff() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
__docker_complete_containers_all
fi
;;
esac
}
_docker_events() {
local key=$(__docker_map_key_of_current_option '-f|--filter')
case "$key" in
container)
cur="${cur##*=}"
__docker_complete_containers_all
return
;;
daemon)
local name=$(__docker_q info | sed -n 's/^\(ID\|Name\): //p')
COMPREPLY=( $( compgen -W "$name" -- "${cur##*=}" ) )
return
;;
event)
COMPREPLY=( $( compgen -W "
attach
commit
connect
copy
create
delete
destroy
detach
die
disconnect
exec_create
exec_detach
exec_start
export
health_status
import
kill
load
mount
oom
pause
pull
push
reload
rename
resize
restart
save
start
stop
tag
top
unmount
unpause
untag
update
" -- "${cur##*=}" ) )
return
;;
image)
cur="${cur##*=}"
__docker_complete_images
return
;;
network)
cur="${cur##*=}"
__docker_complete_networks
return
;;
type)
COMPREPLY=( $( compgen -W "container daemon image network volume" -- "${cur##*=}" ) )
return
;;
volume)
cur="${cur##*=}"
__docker_complete_volumes
return
;;
esac
case "$prev" in
--filter|-f)
COMPREPLY=( $( compgen -S = -W "container daemon event image label network type volume" -- "$cur" ) )
__docker_nospace
return
;;
--since|--until)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--filter -f --help --since --until --format" -- "$cur" ) )
;;
esac
}
_docker_exec() {
__docker_complete_detach-keys && return
case "$prev" in
--user|-u)
__docker_complete_user_group
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--detach -d --detach-keys --help --interactive -i --privileged -t --tty -u --user" -- "$cur" ) )
;;
*)
__docker_complete_containers_running
;;
esac
}
_docker_export() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
__docker_complete_containers_all
fi
;;
esac
}
_docker_help() {
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
fi
}
_docker_history() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --human=false -H=false --no-trunc --quiet -q" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
__docker_complete_images
fi
;;
esac
}
_docker_images() {
local key=$(__docker_map_key_of_current_option '--filter|-f')
case "$key" in
before)
cur="${cur##*=}"
__docker_complete_images
return
;;
dangling)
COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
return
;;
label)
return
;;
since)
cur="${cur##*=}"
__docker_complete_images
return
;;
esac
case "$prev" in
--filter|-f)
COMPREPLY=( $( compgen -S = -W "before dangling label since" -- "$cur" ) )
__docker_nospace
return
;;
--format)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--all -a --digests --filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) )
;;
=)
return
;;
*)
__docker_complete_image_repos
;;
esac
}
_docker_import() {
case "$prev" in
--change|-c|--message|-m)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--change -c --help --message -m" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag '--change|-c|--message|-m')
if [ $cword -eq $counter ]; then
return
fi
(( counter++ ))
if [ $cword -eq $counter ]; then
__docker_complete_image_repos_and_tags
return
fi
;;
esac
}
_docker_info() {
case "$prev" in
--format|-f)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) )
;;
esac
}
_docker_inspect() {
case "$prev" in
--format|-f)
return
;;
--type)
COMPREPLY=( $( compgen -W "image container" -- "$cur" ) )
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--format -f --help --size -s --type" -- "$cur" ) )
;;
*)
case $(__docker_value_of_option --type) in
'')
__docker_complete_containers_and_images
;;
container)
__docker_complete_containers_all
;;
image)
__docker_complete_images
;;
esac
esac
}
_docker_kill() {
case "$prev" in
--signal|-s)
__docker_complete_signals
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --signal -s" -- "$cur" ) )
;;
*)
__docker_complete_containers_running
;;
esac
}
_docker_load() {
case "$prev" in
--input|-i)
_filedir
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --input -i --quiet -q" -- "$cur" ) )
;;
esac
}
_docker_login() {
case "$prev" in
--password|-p|--username|-u)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --password -p --username -u" -- "$cur" ) )
;;
esac
}
_docker_logout() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
esac
}
_docker_logs() {
case "$prev" in
--since|--tail)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--details --follow -f --help --since --tail --timestamps -t" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag '--tail')
if [ $cword -eq $counter ]; then
__docker_complete_containers_all
fi
;;
esac
}
_docker_network_connect() {
local options_with_args="
--alias
--ip
--ip6
--link
--link-local-ip
"
local boolean_options="
--help
"
case "$prev" in
--link)
case "$cur" in
*:*)
;;
*)
__docker_complete_containers_running
COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
__docker_nospace
;;
esac
return
;;
$(__docker_to_extglob "$options_with_args") )
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) )
;;
*)
local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) )
if [ $cword -eq $counter ]; then
__docker_complete_networks
elif [ $cword -eq $(($counter + 1)) ]; then
__docker_complete_containers_all
fi
;;
esac
}
_docker_network_create() {
case "$prev" in
--aux-address|--gateway|--internal|--ip-range|--ipam-opt|--ipv6|--opt|-o|--subnet)
return
;;
--ipam-driver)
COMPREPLY=( $( compgen -W "default" -- "$cur" ) )
return
;;
--driver|-d)
local plugins="$(__docker_plugins Network) macvlan"
# remove drivers that allow one instance only
plugins=${plugins/ host / }
plugins=${plugins/ null / }
COMPREPLY=( $(compgen -W "$plugins" -- "$cur") )
return
;;
--label)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--aux-address --driver -d --gateway --help --internal --ip-range --ipam-driver --ipam-opt --ipv6 --label --opt -o --subnet" -- "$cur" ) )
;;
esac
}
_docker_network_disconnect() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
__docker_complete_networks
elif [ $cword -eq $(($counter + 1)) ]; then
__docker_complete_containers_in_network "$prev"
fi
;;
esac
}
_docker_network_inspect() {
case "$prev" in
--format|-f)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) )
;;
*)
__docker_complete_networks
esac
}
_docker_network_ls() {
local key=$(__docker_map_key_of_current_option '--filter|-f')
case "$key" in
driver)
local plugins=" $(__docker_plugins Network) "
COMPREPLY=( $(compgen -W "$plugins" -- "${cur##*=}") )
return
;;
id)
cur="${cur##*=}"
__docker_complete_network_ids
return
;;
name)
cur="${cur##*=}"
__docker_complete_network_names
return
;;
type)
COMPREPLY=( $( compgen -W "builtin custom" -- "${cur##*=}" ) )
return
;;
esac
case "$prev" in
--filter|-f)
COMPREPLY=( $( compgen -S = -W "driver id label name type" -- "$cur" ) )
__docker_nospace
return
;;
--format)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) )
;;
esac
}
_docker_network_rm() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
__docker_complete_networks type=custom
esac
}
_docker_network() {
local subcommands="
connect
create
disconnect
inspect
ls
rm
"
__docker_subcommands "$subcommands" && return
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
;;
esac
}
_docker_service() {
local subcommands="
create
inspect
ls list
rm remove
scale
ps
update
"
__docker_subcommands "$subcommands" && return
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
;;
esac
}
_docker_service_create() {
_docker_service_update
}
_docker_service_inspect() {
case "$prev" in
--format|-f)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) )
;;
*)
__docker_complete_services
esac
}
_docker_service_list() {
_docker_service_ls
}
_docker_service_ls() {
local key=$(__docker_map_key_of_current_option '--filter|-f')
case "$key" in
id)
__docker_complete_services --cur "${cur##*=}" --id
return
;;
name)
__docker_complete_services --cur "${cur##*=}" --name
return
;;
esac
case "$prev" in
--filter|-f)
COMPREPLY=( $( compgen -W "id label name" -S = -- "$cur" ) )
__docker_nospace
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--filter -f --help --quiet -q" -- "$cur" ) )
;;
esac
}
_docker_service_remove() {
_docker_service_rm
}
_docker_service_rm() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
__docker_complete_services
esac
}
_docker_service_scale() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
__docker_complete_services
__docker_append_to_completions "="
__docker_nospace
;;
esac
}
_docker_service_ps() {
local key=$(__docker_map_key_of_current_option '--filter|-f')
case "$key" in
desired-state)
COMPREPLY=( $( compgen -W "accepted running" -- "${cur##*=}" ) )
return
;;
name)
__docker_complete_services --cur "${cur##*=}" --name
return
;;
esac
case "$prev" in
--filter|-f)
COMPREPLY=( $( compgen -W "desired-state id name" -S = -- "$cur" ) )
__docker_nospace
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--all -a --filter -f --help --no-resolve --no-trunc" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag '--filter|-f')
if [ $cword -eq $counter ]; then
__docker_complete_services
fi
;;
esac
}
_docker_service_update() {
local $subcommand="${words[$subcommand_pos]}"
local options_with_args="
--constraint
--endpoint-mode
--env -e
--group-add
--label -l
--limit-cpu
--limit-memory
--log-driver
--log-opt
--mount
--name
--network
--publish -p
--replicas
--reserve-cpu
--reserve-memory
--restart-condition
--restart-delay
--restart-max-attempts
--restart-window
--stop-grace-period
--update-delay
--update-failure-action
--update-parallelism
--user -u
--workdir -w
"
local boolean_options="
--help
--with-registry-auth
"
__docker_complete_log_driver_options && return
if [ "$subcommand" = "create" ] ; then
options_with_args="$options_with_args
--container-label
--mode
"
case "$prev" in
--mode)
COMPREPLY=( $( compgen -W "global replicated" -- "$cur" ) )
return
;;
esac
fi
if [ "$subcommand" = "update" ] ; then
options_with_args="$options_with_args
--arg
--container-label-add
--container-label-rm
--group-rm
--image
"
case "$prev" in
--group-rm)
COMPREPLY=( $(compgen -g -- "$cur") )
return
;;
--image)
__docker_complete_image_repos_and_tags
return
;;
esac
fi
case "$prev" in
--endpoint-mode)
COMPREPLY=( $( compgen -W "dnsrr vip" -- "$cur" ) )
return
;;
--env|-e)
# we do not append a "=" here because "-e VARNAME" is legal systax, too
COMPREPLY=( $( compgen -e -- "$cur" ) )
__docker_nospace
return
;;
--group-add)
COMPREPLY=( $(compgen -g -- "$cur") )
return
;;
--log-driver)
__docker_complete_log_drivers
return
;;
--log-opt)
__docker_complete_log_options
return
;;
--network)
__docker_complete_networks
return
;;
--restart-condition)
COMPREPLY=( $( compgen -W "any none on-failure" -- "$cur" ) )
return
;;
--user|-u)
__docker_complete_user_group
return
;;
$(__docker_to_extglob "$options_with_args") )
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) )
;;
*)
if [ "$subcommand" = "update" ] ; then
__docker_complete_services
fi
esac
}
_docker_swarm() {
local subcommands="
init
join
join-token
leave
update
"
__docker_subcommands "$subcommands" && return
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
;;
esac
}
_docker_swarm_init() {
case "$prev" in
--advertise-addr)
if [[ $cur == *: ]] ; then
COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) )
else
__docker_complete_local_interfaces
__docker_nospace
fi
return
;;
--listen-addr)
Split advertised address from listen address There are currently problems with "swarm init" and "swarm join" when an explicit --listen-addr flag is not provided. swarmkit defaults to finding the IP address associated with the default route, and in cloud setups this is often the wrong choice. Introduce a notion of "advertised address", with the client flag --advertise-addr, and the daemon flag --swarm-default-advertise-addr to provide a default. The default listening address is now 0.0.0.0, but a valid advertised address must be detected or specified. If no explicit advertised address is specified, error out if there is more than one usable candidate IP address on the system. This requires a user to explicitly choose instead of letting swarmkit make the wrong choice. For the purposes of this autodetection, we ignore certain interfaces that are unlikely to be relevant (currently docker*). The user is also required to choose a listen address on swarm init if they specify an explicit advertise address that is a hostname or an IP address that's not local to the system. This is a requirement for overlay networking. Also support specifying interface names to --listen-addr, --advertise-addr, and the daemon flag --swarm-default-advertise-addr. This will fail if the interface has multiple IP addresses (unless it has a single IPv4 address and a single IPv6 address - then we resolve the tie in favor of IPv4). This change also exposes the node's externally-reachable address in docker info, as requested by #24017. Make corresponding API and CLI docs changes. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
2016-06-30 21:07:35 -04:00
if [[ $cur == *: ]] ; then
COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) )
else
__docker_complete_local_interfaces --add 0.0.0.0
__docker_nospace
Split advertised address from listen address There are currently problems with "swarm init" and "swarm join" when an explicit --listen-addr flag is not provided. swarmkit defaults to finding the IP address associated with the default route, and in cloud setups this is often the wrong choice. Introduce a notion of "advertised address", with the client flag --advertise-addr, and the daemon flag --swarm-default-advertise-addr to provide a default. The default listening address is now 0.0.0.0, but a valid advertised address must be detected or specified. If no explicit advertised address is specified, error out if there is more than one usable candidate IP address on the system. This requires a user to explicitly choose instead of letting swarmkit make the wrong choice. For the purposes of this autodetection, we ignore certain interfaces that are unlikely to be relevant (currently docker*). The user is also required to choose a listen address on swarm init if they specify an explicit advertise address that is a hostname or an IP address that's not local to the system. This is a requirement for overlay networking. Also support specifying interface names to --listen-addr, --advertise-addr, and the daemon flag --swarm-default-advertise-addr. This will fail if the interface has multiple IP addresses (unless it has a single IPv4 address and a single IPv6 address - then we resolve the tie in favor of IPv4). This change also exposes the node's externally-reachable address in docker info, as requested by #24017. Make corresponding API and CLI docs changes. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
2016-06-30 21:07:35 -04:00
fi
return
;;
esac
case "$cur" in
-*)
Split advertised address from listen address There are currently problems with "swarm init" and "swarm join" when an explicit --listen-addr flag is not provided. swarmkit defaults to finding the IP address associated with the default route, and in cloud setups this is often the wrong choice. Introduce a notion of "advertised address", with the client flag --advertise-addr, and the daemon flag --swarm-default-advertise-addr to provide a default. The default listening address is now 0.0.0.0, but a valid advertised address must be detected or specified. If no explicit advertised address is specified, error out if there is more than one usable candidate IP address on the system. This requires a user to explicitly choose instead of letting swarmkit make the wrong choice. For the purposes of this autodetection, we ignore certain interfaces that are unlikely to be relevant (currently docker*). The user is also required to choose a listen address on swarm init if they specify an explicit advertise address that is a hostname or an IP address that's not local to the system. This is a requirement for overlay networking. Also support specifying interface names to --listen-addr, --advertise-addr, and the daemon flag --swarm-default-advertise-addr. This will fail if the interface has multiple IP addresses (unless it has a single IPv4 address and a single IPv6 address - then we resolve the tie in favor of IPv4). This change also exposes the node's externally-reachable address in docker info, as requested by #24017. Make corresponding API and CLI docs changes. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
2016-06-30 21:07:35 -04:00
COMPREPLY=( $( compgen -W "--advertise-addr --force-new-cluster --help --listen-addr" -- "$cur" ) )
;;
esac
}
_docker_swarm_join() {
case "$prev" in
--advertise-addr)
if [[ $cur == *: ]] ; then
COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) )
else
__docker_complete_local_interfaces
__docker_nospace
fi
return
;;
--listen-addr)
Split advertised address from listen address There are currently problems with "swarm init" and "swarm join" when an explicit --listen-addr flag is not provided. swarmkit defaults to finding the IP address associated with the default route, and in cloud setups this is often the wrong choice. Introduce a notion of "advertised address", with the client flag --advertise-addr, and the daemon flag --swarm-default-advertise-addr to provide a default. The default listening address is now 0.0.0.0, but a valid advertised address must be detected or specified. If no explicit advertised address is specified, error out if there is more than one usable candidate IP address on the system. This requires a user to explicitly choose instead of letting swarmkit make the wrong choice. For the purposes of this autodetection, we ignore certain interfaces that are unlikely to be relevant (currently docker*). The user is also required to choose a listen address on swarm init if they specify an explicit advertise address that is a hostname or an IP address that's not local to the system. This is a requirement for overlay networking. Also support specifying interface names to --listen-addr, --advertise-addr, and the daemon flag --swarm-default-advertise-addr. This will fail if the interface has multiple IP addresses (unless it has a single IPv4 address and a single IPv6 address - then we resolve the tie in favor of IPv4). This change also exposes the node's externally-reachable address in docker info, as requested by #24017. Make corresponding API and CLI docs changes. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
2016-06-30 21:07:35 -04:00
if [[ $cur == *: ]] ; then
COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) )
else
__docker_complete_local_interfaces --add 0.0.0.0
__docker_nospace
Split advertised address from listen address There are currently problems with "swarm init" and "swarm join" when an explicit --listen-addr flag is not provided. swarmkit defaults to finding the IP address associated with the default route, and in cloud setups this is often the wrong choice. Introduce a notion of "advertised address", with the client flag --advertise-addr, and the daemon flag --swarm-default-advertise-addr to provide a default. The default listening address is now 0.0.0.0, but a valid advertised address must be detected or specified. If no explicit advertised address is specified, error out if there is more than one usable candidate IP address on the system. This requires a user to explicitly choose instead of letting swarmkit make the wrong choice. For the purposes of this autodetection, we ignore certain interfaces that are unlikely to be relevant (currently docker*). The user is also required to choose a listen address on swarm init if they specify an explicit advertise address that is a hostname or an IP address that's not local to the system. This is a requirement for overlay networking. Also support specifying interface names to --listen-addr, --advertise-addr, and the daemon flag --swarm-default-advertise-addr. This will fail if the interface has multiple IP addresses (unless it has a single IPv4 address and a single IPv6 address - then we resolve the tie in favor of IPv4). This change also exposes the node's externally-reachable address in docker info, as requested by #24017. Make corresponding API and CLI docs changes. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
2016-06-30 21:07:35 -04:00
fi
return
;;
--token)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--advertise-addr --help --listen-addr --token" -- "$cur" ) )
;;
*:)
COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) )
;;
esac
}
_docker_swarm_join-token() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) )
;;
*)
local counter=$( __docker_pos_first_nonflag )
if [ $cword -eq $counter ]; then
COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) )
fi
;;
esac
}
_docker_swarm_leave() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--force --help" -- "$cur" ) )
;;
esac
}
_docker_swarm_update() {
case "$prev" in
--cert-expiry|--dispatcher-heartbeat|--task-history-limit)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--cert-expiry --dispatcher-heartbeat --help --task-history-limit" -- "$cur" ) )
;;
esac
}
_docker_node() {
local subcommands="
demote
inspect
ls list
promote
rm remove
ps
update
"
__docker_subcommands "$subcommands" && return
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
;;
esac
}
_docker_node_demote() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
__docker_complete_nodes --filter role=manager
esac
}
_docker_node_inspect() {
case "$prev" in
--format|-f)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) )
;;
*)
__docker_complete_nodes_plus_self
esac
}
_docker_node_list() {
_docker_node_ls
}
_docker_node_ls() {
local key=$(__docker_map_key_of_current_option '--filter|-f')
case "$key" in
id)
__docker_complete_nodes --cur "${cur##*=}" --id
return
;;
name)
__docker_complete_nodes --cur "${cur##*=}" --name
return
;;
esac
case "$prev" in
--filter|-f)
COMPREPLY=( $( compgen -W "id label name" -S = -- "$cur" ) )
__docker_nospace
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--filter -f --help --quiet -q" -- "$cur" ) )
;;
esac
}
_docker_node_promote() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
__docker_complete_nodes --filter role=worker
esac
}
_docker_node_remove() {
_docker_node_rm
}
_docker_node_rm() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--force --help" -- "$cur" ) )
;;
*)
__docker_complete_nodes
esac
}
_docker_node_ps() {
local key=$(__docker_map_key_of_current_option '--filter|-f')
case "$key" in
desired-state)
COMPREPLY=( $( compgen -W "accepted running" -- "${cur##*=}" ) )
return
;;
name)
__docker_complete_services --cur "${cur##*=}" --name
return
;;
esac
case "$prev" in
--filter|-f)
COMPREPLY=( $( compgen -W "desired-state id label name" -S = -- "$cur" ) )
__docker_nospace
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--all -a --filter -f --help --no-resolve --no-trunc" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag '--filter|-f')
if [ $cword -eq $counter ]; then
__docker_complete_nodes_plus_self
fi
;;
esac
}
_docker_node_update() {
case "$prev" in
--availability)
COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) )
return
;;
--role)
COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) )
return
;;
--label-add|--label-rm)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--availability --help --label-add --label-rm --role" -- "$cur" ) )
;;
*)
__docker_complete_nodes
esac
}
_docker_pause() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
__docker_complete_containers_pauseable
fi
;;
esac
}
_docker_port() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
__docker_complete_containers_all
fi
;;
esac
}
_docker_ps() {
local key=$(__docker_map_key_of_current_option '--filter|-f')
case "$key" in
ancestor)
cur="${cur##*=}"
__docker_complete_images
return
;;
before)
cur="${cur##*=}"
__docker_complete_containers_all
return
;;
id)
cur="${cur##*=}"
__docker_complete_container_ids
return
;;
name)
cur="${cur##*=}"
__docker_complete_container_names
return
;;
network)
cur="${cur##*=}"
__docker_complete_networks
return
;;
since)
cur="${cur##*=}"
__docker_complete_containers_all
return
;;
status)
COMPREPLY=( $( compgen -W "created dead exited paused restarting running removing" -- "${cur##*=}" ) )
return
;;
volume)
cur="${cur##*=}"
__docker_complete_volumes
return
;;
esac
case "$prev" in
--filter|-f)
COMPREPLY=( $( compgen -S = -W "ancestor before exited id label name network since status volume" -- "$cur" ) )
__docker_nospace
return
;;
--format|--last|-n)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--all -a --filter -f --format --help --last -n --latest -l --no-trunc --quiet -q --size -s" -- "$cur" ) )
;;
esac
}
_docker_pull() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--all-tags -a --disable-content-trust=false --help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
for arg in "${COMP_WORDS[@]}"; do
case "$arg" in
--all-tags|-a)
__docker_complete_image_repos
return
;;
esac
done
__docker_complete_image_repos_and_tags
fi
;;
esac
}
_docker_push() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--disable-content-trust=false --help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
__docker_complete_image_repos_and_tags
fi
;;
esac
}
_docker_rename() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
__docker_complete_containers_all
fi
;;
esac
}
_docker_restart() {
case "$prev" in
--time|-t)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) )
;;
*)
__docker_complete_containers_all
;;
esac
}
_docker_rm() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--force -f --help --link -l --volumes -v" -- "$cur" ) )
;;
*)
for arg in "${COMP_WORDS[@]}"; do
case "$arg" in
--force|-f)
__docker_complete_containers_all
return
;;
esac
done
__docker_complete_containers_stopped
;;
esac
}
_docker_rmi() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--force -f --help --no-prune" -- "$cur" ) )
;;
*)
__docker_complete_images
;;
esac
}
_docker_run() {
local options_with_args="
--add-host
--attach -a
--blkio-weight
--blkio-weight-device
--cap-add
--cap-drop
--cgroup-parent
--cidfile
--cpu-period
--cpu-quota
--cpuset-cpus
--cpuset-mems
--cpu-shares -c
--device
--device-read-bps
--device-read-iops
--device-write-bps
--device-write-iops
--dns
--dns-opt
--dns-search
--entrypoint
--env -e
--env-file
--expose
--group-add
--hostname -h
--ip
--ip6
--ipc
--isolation
--kernel-memory
--label-file
--label -l
--link
--link-local-ip
--log-driver
--log-opt
--mac-address
--memory -m
--memory-swap
--memory-swappiness
--memory-reservation
--name
--network
--network-alias
--oom-score-adj
--pid
--pids-limit
--publish -p
--restart
--runtime
--security-opt
--shm-size
--stop-signal
--storage-opt
--tmpfs
--sysctl
--ulimit
--user -u
--userns
--uts
--volume-driver
--volumes-from
--volume -v
--workdir -w
"
local boolean_options="
--disable-content-trust=false
--help
--interactive -i
--oom-kill-disable
--privileged
--publish-all -P
--read-only
--tty -t
"
if [ "$command" = "run" ] ; then
options_with_args="$options_with_args
--detach-keys
--health-cmd
--health-interval
--health-retries
--health-timeout
"
boolean_options="$boolean_options
--detach -d
--no-healthcheck
--rm
--sig-proxy=false
"
__docker_complete_detach-keys && return
fi
local all_options="$options_with_args $boolean_options"
__docker_complete_log_driver_options && return
__docker_complete_restart && return
local key=$(__docker_map_key_of_current_option '--security-opt')
case "$key" in
label)
[[ $cur == *: ]] && return
COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "${cur##*=}") )
if [ "${COMPREPLY[*]}" != "disable" ] ; then
__docker_nospace
fi
return
;;
seccomp)
local cur=${cur##*=}
_filedir
COMPREPLY+=( $( compgen -W "unconfined" -- "$cur" ) )
return
;;
esac
case "$prev" in
--add-host)
case "$cur" in
*:)
__docker_complete_resolved_hostname
return
;;
esac
;;
--attach|-a)
COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) )
return
;;
--cap-add|--cap-drop)
__docker_complete_capabilities
return
;;
--cidfile|--env-file|--label-file)
_filedir
return
;;
--device|--tmpfs|--volume|-v)
case "$cur" in
*:*)
# TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine)
;;
'')
COMPREPLY=( $( compgen -W '/' -- "$cur" ) )
__docker_nospace
;;
/*)
_filedir
__docker_nospace
;;
esac
return
;;
--env|-e)
# we do not append a "=" here because "-e VARNAME" is legal systax, too
COMPREPLY=( $( compgen -e -- "$cur" ) )
__docker_nospace
return
;;
--ipc)
case "$cur" in
*:*)
cur="${cur#*:}"
__docker_complete_containers_running
;;
*)
COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) )
if [ "$COMPREPLY" = "container:" ]; then
__docker_nospace
fi
;;
esac
return
;;
--isolation)
__docker_complete_isolation
return
;;
--link)
case "$cur" in
*:*)
;;
*)
__docker_complete_containers_running
COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
__docker_nospace
;;
esac
return
;;
--log-driver)
__docker_complete_log_drivers
return
;;
--log-opt)
__docker_complete_log_options
return
;;
--network)
case "$cur" in
container:*)
local cur=${cur#*:}
__docker_complete_containers_all
;;
*)
COMPREPLY=( $( compgen -W "$(__docker_plugins Network) $(__docker_networks) container:" -- "$cur") )
if [ "${COMPREPLY[*]}" = "container:" ] ; then
__docker_nospace
fi
;;
esac
return
;;
--pid)
case "$cur" in
*:*)
cur="${cur#*:}"
__docker_complete_containers_running
;;
*)
COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) )
if [ "$COMPREPLY" = "container:" ]; then
__docker_nospace
fi
;;
esac
return
;;
--runtime)
__docker_complete_runtimes
return
;;
--security-opt)
COMPREPLY=( $( compgen -W "apparmor= label= no-new-privileges seccomp=" -- "$cur") )
if [ "${COMPREPLY[*]}" != "no-new-privileges" ] ; then
__docker_nospace
fi
return
;;
--storage-opt)
COMPREPLY=( $( compgen -W "size" -S = -- "$cur") )
__docker_nospace
return
;;
--user|-u)
__docker_complete_user_group
return
;;
--userns)
COMPREPLY=( $( compgen -W "host" -- "$cur" ) )
return
;;
--volume-driver)
__docker_complete_plugins Volume
return
;;
--volumes-from)
__docker_complete_containers_all
return
;;
$(__docker_to_extglob "$options_with_args") )
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) )
;;
*)
local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) )
if [ $cword -eq $counter ]; then
__docker_complete_images
fi
;;
esac
}
_docker_save() {
case "$prev" in
--output|-o)
_filedir
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) )
;;
*)
__docker_complete_images
;;
esac
}
_docker_search() {
local key=$(__docker_map_key_of_current_option '--filter|-f')
case "$key" in
is-automated)
COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
return
;;
is-official)
COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
return
;;
esac
case "$prev" in
--filter|-f)
COMPREPLY=( $( compgen -S = -W "is-automated is-official stars" -- "$cur" ) )
__docker_nospace
return
;;
--limit)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--filter --help --limit --no-trunc" -- "$cur" ) )
;;
esac
}
_docker_start() {
__docker_complete_detach-keys && return
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--attach -a --detach-keys --help --interactive -i" -- "$cur" ) )
;;
*)
__docker_complete_containers_stopped
;;
esac
}
_docker_stats() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--all -a --help --no-stream" -- "$cur" ) )
;;
*)
__docker_complete_containers_running
;;
esac
}
_docker_stop() {
case "$prev" in
--time|-t)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) )
;;
*)
__docker_complete_containers_running
;;
esac
}
_docker_tag() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
__docker_complete_image_repos_and_tags
return
fi
(( counter++ ))
if [ $cword -eq $counter ]; then
__docker_complete_image_repos_and_tags
return
fi
;;
esac
}
_docker_unpause() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
__docker_complete_containers_unpauseable
fi
;;
esac
}
_docker_update() {
local options_with_args="
--blkio-weight
--cpu-period
--cpu-quota
--cpuset-cpus
--cpuset-mems
--cpu-shares -c
--kernel-memory
--memory -m
--memory-reservation
--memory-swap
--restart
"
local boolean_options="
--help
"
local all_options="$options_with_args $boolean_options"
__docker_complete_restart && return
case "$prev" in
$(__docker_to_extglob "$options_with_args") )
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) )
;;
*)
__docker_complete_containers_all
;;
esac
}
_docker_top() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ $cword -eq $counter ]; then
__docker_complete_containers_running
fi
;;
esac
}
_docker_version() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
esac
}
_docker_volume_create() {
case "$prev" in
--driver|-d)
__docker_complete_plugins Volume
return
;;
--label|--opt|-o)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--driver -d --help --label --opt -o" -- "$cur" ) )
;;
esac
}
_docker_volume_inspect() {
case "$prev" in
--format|-f)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) )
;;
*)
__docker_complete_volumes
;;
esac
}
_docker_volume_ls() {
local key=$(__docker_map_key_of_current_option '--filter|-f')
case "$key" in
dangling)
COMPREPLY=( $( compgen -W "true false" -- "${cur##*=}" ) )
return
;;
driver)
cur=${cur##*=}
__docker_complete_plugins Volume
return
;;
name)
cur=${cur##*=}
__docker_complete_volumes
return
;;
esac
case "$prev" in
--filter|-f)
COMPREPLY=( $( compgen -S = -W "dangling driver label name" -- "$cur" ) )
__docker_nospace
return
;;
--format)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) )
;;
esac
}
_docker_volume_rm() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) )
;;
*)
__docker_complete_volumes
;;
esac
}
_docker_volume() {
local subcommands="
create
inspect
ls
rm
"
__docker_subcommands "$subcommands" && return
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
;;
esac
}
_docker_wait() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
__docker_complete_containers_all
;;
esac
}
_docker() {
local previous_extglob_setting=$(shopt -p extglob)
shopt -s extglob
local commands=(
attach
build
commit
cp
create
daemon
diff
events
exec
export
history
images
import
info
inspect
kill
load
login
logout
logs
network
node
pause
port
ps
pull
push
rename
restart
rm
rmi
run
save
search
service
start
stats
stop
swarm
tag
top
unpause
update
version
volume
wait
)
# These options are valid as global options for all client commands
# and valid as command options for `docker daemon`
local global_boolean_options="
--debug -D
--tls
--tlsverify
"
local global_options_with_args="
--config
--host -H
--log-level -l
--tlscacert
--tlscert
--tlskey
"
local host config
COMPREPLY=()
local cur prev words cword
_get_comp_words_by_ref -n : cur prev words cword
local command='docker' command_pos=0 subcommand_pos
local counter=1
while [ $counter -lt $cword ]; do
case "${words[$counter]}" in
# save host so that completion can use custom daemon
--host|-H)
(( counter++ ))
host="${words[$counter]}"
;;
# save config so that completion can use custom configuration directories
--config)
(( counter++ ))
config="${words[$counter]}"
;;
$(__docker_to_extglob "$global_options_with_args") )
(( counter++ ))
;;
-*)
;;
=)
(( counter++ ))
;;
*)
command="${words[$counter]}"
command_pos=$counter
break
;;
esac
(( counter++ ))
done
local binary="${words[0]}"
if [[ $binary == ?(*/)dockerd ]] ; then
# for the dockerd binary, we reuse completion of `docker daemon`.
# dockerd does not have subcommands and global options.
command=daemon
command_pos=0
fi
local completions_func=_docker_${command}
declare -F $completions_func >/dev/null && $completions_func
eval "$previous_extglob_setting"
return 0
}
eval "$__docker_previous_extglob_setting"
unset __docker_previous_extglob_setting
complete -F _docker docker dockerd