github.com/ruphin/docker@v1.10.1/contrib/completion/bash/docker (about)

     1  #!/bin/bash
     2  #
     3  # bash completion file for core docker commands
     4  #
     5  # This script provides completion of:
     6  #  - commands and their options
     7  #  - container ids and names
     8  #  - image repos and tags
     9  #  - filepaths
    10  #
    11  # To enable the completions either:
    12  #  - place this file in /etc/bash_completion.d
    13  #  or
    14  #  - copy this file to e.g. ~/.docker-completion.sh and add the line
    15  #    below to your .bashrc after bash completion features are loaded
    16  #    . ~/.docker-completion.sh
    17  #
    18  # Configuration:
    19  #
    20  # For several commands, the amount of completions can be configured by
    21  # setting environment variables.
    22  #
    23  # DOCKER_COMPLETION_SHOW_NETWORK_IDS
    24  #   "no"  - Show names only (default)
    25  #   "yes" - Show names and ids
    26  #
    27  # You can tailor completion for the "events", "history", "inspect", "run",
    28  # "rmi" and "save" commands by settings the following environment
    29  # variables:
    30  #
    31  # DOCKER_COMPLETION_SHOW_IMAGE_IDS
    32  #   "none" - Show names only (default)
    33  #   "non-intermediate" - Show names and ids, but omit intermediate image IDs
    34  #   "all" - Show names and ids, including intermediate image IDs
    35  #
    36  # DOCKER_COMPLETION_SHOW_TAGS
    37  #   "yes" - include tags in completion options (default)
    38  #   "no"  - don't include tags in completion options
    39  
    40  #
    41  # Note:
    42  # Currently, the completions will not work if the docker daemon is not
    43  # bound to the default communication port/socket
    44  # If the docker daemon is using a unix socket for communication your user
    45  # must have access to the socket for the completions to function correctly
    46  #
    47  # Note for developers:
    48  # Please arrange options sorted alphabetically by long name with the short
    49  # options immediately following their corresponding long form.
    50  # This order should be applied to lists, alternatives and code blocks.
    51  
    52  __docker_previous_extglob_setting=$(shopt -p extglob)
    53  shopt -s extglob
    54  
    55  __docker_q() {
    56  	docker ${host:+-H "$host"} ${config:+--config "$config"} 2>/dev/null "$@"
    57  }
    58  
    59  __docker_complete_containers_all() {
    60  	local IFS=$'\n'
    61  	local containers=( $(__docker_q ps -aq --no-trunc) )
    62  	if [ "$1" ]; then
    63  		containers=( $(__docker_q inspect --format "{{if $1}}{{.Id}}{{end}}" "${containers[@]}") )
    64  	fi
    65  	local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") )
    66  	names=( "${names[@]#/}" ) # trim off the leading "/" from the container names
    67  	unset IFS
    68  	COMPREPLY=( $(compgen -W "${names[*]} ${containers[*]}" -- "$cur") )
    69  }
    70  
    71  __docker_complete_containers_running() {
    72  	__docker_complete_containers_all '.State.Running'
    73  }
    74  
    75  __docker_complete_containers_stopped() {
    76  	__docker_complete_containers_all 'not .State.Running'
    77  }
    78  
    79  __docker_complete_containers_pauseable() {
    80  	__docker_complete_containers_all 'and .State.Running (not .State.Paused)'
    81  }
    82  
    83  __docker_complete_containers_unpauseable() {
    84  	__docker_complete_containers_all '.State.Paused'
    85  }
    86  
    87  __docker_complete_container_names() {
    88  	local containers=( $(__docker_q ps -aq --no-trunc) )
    89  	local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") )
    90  	names=( "${names[@]#/}" ) # trim off the leading "/" from the container names
    91  	COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") )
    92  }
    93  
    94  __docker_complete_container_ids() {
    95  	local containers=( $(__docker_q ps -aq) )
    96  	COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") )
    97  }
    98  
    99  __docker_complete_images() {
   100  	local images_args=""
   101  
   102  	case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in
   103  		all)
   104  			images_args="--no-trunc -a"
   105  			;;
   106  		non-intermediate)
   107  			images_args="--no-trunc"
   108  			;;
   109  	esac
   110  
   111  	local repo_print_command
   112  	if [ "${DOCKER_COMPLETION_SHOW_TAGS:-yes}" = "yes" ]; then
   113  		repo_print_command='print $1; print $1":"$2'
   114  	else
   115  		repo_print_command='print $1'
   116  	fi
   117  
   118  	local awk_script
   119  	case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in
   120  		all|non-intermediate)
   121  			awk_script='NR>1 { print $3; if ($1 != "<none>") { '"$repo_print_command"' } }'
   122  			;;
   123  		none|*)
   124  			awk_script='NR>1 && $1 != "<none>" { '"$repo_print_command"' }'
   125  			;;
   126  	esac
   127  
   128  	local images=$(__docker_q images $images_args | awk "$awk_script")
   129  	COMPREPLY=( $(compgen -W "$images" -- "$cur") )
   130  	__ltrim_colon_completions "$cur"
   131  }
   132  
   133  __docker_complete_image_repos() {
   134  	local repos="$(__docker_q images | awk 'NR>1 && $1 != "<none>" { print $1 }')"
   135  	COMPREPLY=( $(compgen -W "$repos" -- "$cur") )
   136  }
   137  
   138  __docker_complete_image_repos_and_tags() {
   139  	local reposAndTags="$(__docker_q images | awk 'NR>1 && $1 != "<none>" { print $1; print $1":"$2 }')"
   140  	COMPREPLY=( $(compgen -W "$reposAndTags" -- "$cur") )
   141  	__ltrim_colon_completions "$cur"
   142  }
   143  
   144  __docker_complete_containers_and_images() {
   145  	__docker_complete_containers_all
   146  	local containers=( "${COMPREPLY[@]}" )
   147  	__docker_complete_images
   148  	COMPREPLY+=( "${containers[@]}" )
   149  }
   150  
   151  __docker_networks() {
   152  	# By default, only network names are completed.
   153  	# Set DOCKER_COMPLETION_SHOW_NETWORK_IDS=yes to also complete network IDs.
   154  	local fields='$2'
   155  	[ "${DOCKER_COMPLETION_SHOW_NETWORK_IDS}" = yes ] && fields='$1,$2'
   156  	__docker_q network ls --no-trunc | awk "NR>1 {print $fields}"
   157  }
   158  
   159  __docker_complete_networks() {
   160  	COMPREPLY=( $(compgen -W "$(__docker_networks)" -- "$cur") )
   161  }
   162  
   163  __docker_complete_network_ids() {
   164  	COMPREPLY=( $(compgen -W "$(__docker_q network ls -q --no-trunc)" -- "$cur") )
   165  }
   166  
   167  __docker_complete_network_names() {
   168  	COMPREPLY=( $(compgen -W "$(__docker_q network ls | awk 'NR>1 {print $2}')" -- "$cur") )
   169  }
   170  
   171  __docker_complete_containers_in_network() {
   172  	local containers=$(__docker_q network inspect -f '{{range $i, $c := .Containers}}{{$i}} {{$c.Name}} {{end}}' "$1")
   173  	COMPREPLY=( $(compgen -W "$containers" -- "$cur") )
   174  }
   175  
   176  __docker_complete_volumes() {
   177  	COMPREPLY=( $(compgen -W "$(__docker_q volume ls -q)" -- "$cur") )
   178  }
   179  
   180  __docker_plugins() {
   181  	__docker_q info | sed -n "/^Plugins/,/^[^ ]/s/ $1: //p"
   182  }
   183  
   184  __docker_complete_plugins() {
   185  	COMPREPLY=( $(compgen -W "$(__docker_plugins $1)" -- "$cur") )
   186  }
   187  
   188  # Finds the position of the first word that is neither option nor an option's argument.
   189  # If there are options that require arguments, you should pass a glob describing those
   190  # options, e.g. "--option1|-o|--option2"
   191  # Use this function to restrict completions to exact positions after the argument list.
   192  __docker_pos_first_nonflag() {
   193  	local argument_flags=$1
   194  
   195  	local counter=$((${subcommand_pos:-${command_pos}} + 1))
   196  	while [ $counter -le $cword ]; do
   197  		if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then
   198  			(( counter++ ))
   199  			# eat "=" in case of --option=arg syntax
   200  			[ "${words[$counter]}" = "=" ] && (( counter++ ))
   201  		else
   202  			case "${words[$counter]}" in
   203  				-*)
   204  					;;
   205  				*)
   206  					break
   207  					;;
   208  			esac
   209  		fi
   210  
   211  		# Bash splits words at "=", retaining "=" as a word, examples:
   212  		# "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words
   213  		while [ "${words[$counter + 1]}" = "=" ] ; do
   214  			counter=$(( counter + 2))
   215  		done
   216  
   217  		(( counter++ ))
   218  	done
   219  
   220  	echo $counter
   221  }
   222  
   223  # If we are currently completing the value of a map option (key=value)
   224  # which matches the extglob given as an argument, returns key.
   225  # This function is needed for key-specific completions.
   226  # TODO use this in all "${words[$cword-2]}$prev=" occurrences
   227  __docker_map_key_of_current_option() {
   228  	local glob="$1"
   229  
   230  	local key glob_pos
   231  	if [ "$cur" = "=" ] ; then        # key= case
   232  		key="$prev"
   233  		glob_pos=$((cword - 2))
   234  	elif [[ $cur == *=* ]] ; then     # key=value case (OSX)
   235  		key=${cur%=*}
   236  		glob_pos=$((cword - 1))
   237  	elif [ "$prev" = "=" ] ; then
   238  		key=${words[$cword - 2]}  # key=value case
   239  		glob_pos=$((cword - 3))
   240  	else
   241  		return
   242  	fi
   243  
   244  	[ "${words[$glob_pos]}" = "=" ] && ((glob_pos--))  # --option=key=value syntax
   245  
   246  	[[ ${words[$glob_pos]} == @($glob) ]] && echo "$key"
   247  }
   248  
   249  # Returns the value of the first option matching option_glob.
   250  # Valid values for option_glob are option names like '--log-level' and
   251  # globs like '--log-level|-l'
   252  # Only positions between the command and the current word are considered.
   253  __docker_value_of_option() {
   254  	local option_extglob=$(__docker_to_extglob "$1")
   255  
   256  	local counter=$((command_pos + 1))
   257  	while [ $counter -lt $cword ]; do
   258  		case ${words[$counter]} in
   259  			$option_extglob )
   260  				echo ${words[$counter + 1]}
   261  				break
   262  				;;
   263  		esac
   264  		(( counter++ ))
   265  	done
   266  }
   267  
   268  # Transforms a multiline list of strings into a single line string
   269  # with the words separated by "|".
   270  # This is used to prepare arguments to __docker_pos_first_nonflag().
   271  __docker_to_alternatives() {
   272  	local parts=( $1 )
   273  	local IFS='|'
   274  	echo "${parts[*]}"
   275  }
   276  
   277  # Transforms a multiline list of options into an extglob pattern
   278  # suitable for use in case statements.
   279  __docker_to_extglob() {
   280  	local extglob=$( __docker_to_alternatives "$1" )
   281  	echo "@($extglob)"
   282  }
   283  
   284  # Subcommand processing.
   285  # Locates the first occurrence of any of the subcommands contained in the
   286  # first argument. In case of a match, calls the corresponding completion
   287  # function and returns 0.
   288  # If no match is found, 1 is returned. The calling function can then
   289  # continue processing its completion.
   290  #
   291  # TODO if the preceding command has options that accept arguments and an
   292  # argument is equal ot one of the subcommands, this is falsely detected as
   293  # a match.
   294  __docker_subcommands() {
   295  	local subcommands="$1"
   296  
   297  	local counter=$(($command_pos + 1))
   298  	while [ $counter -lt $cword ]; do
   299  		case "${words[$counter]}" in
   300  			$(__docker_to_extglob "$subcommands") )
   301  				subcommand_pos=$counter
   302  				local subcommand=${words[$counter]}
   303  				local completions_func=_docker_${command}_${subcommand}
   304  				declare -F $completions_func >/dev/null && $completions_func
   305  				return 0
   306  				;;
   307  		esac
   308  		(( counter++ ))
   309  	done
   310  	return 1
   311  }
   312  
   313  # suppress trailing whitespace
   314  __docker_nospace() {
   315  	# compopt is not available in ancient bash versions
   316  	type compopt &>/dev/null && compopt -o nospace
   317  }
   318  
   319  __docker_complete_resolved_hostname() {
   320  	command -v host >/dev/null 2>&1 || return
   321  	COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') )
   322  }
   323  
   324  __docker_complete_capabilities() {
   325  	# The list of capabilities is defined in types.go, ALL was added manually.
   326  	COMPREPLY=( $( compgen -W "
   327  		ALL
   328  		AUDIT_CONTROL
   329  		AUDIT_WRITE
   330  		AUDIT_READ
   331  		BLOCK_SUSPEND
   332  		CHOWN
   333  		DAC_OVERRIDE
   334  		DAC_READ_SEARCH
   335  		FOWNER
   336  		FSETID
   337  		IPC_LOCK
   338  		IPC_OWNER
   339  		KILL
   340  		LEASE
   341  		LINUX_IMMUTABLE
   342  		MAC_ADMIN
   343  		MAC_OVERRIDE
   344  		MKNOD
   345  		NET_ADMIN
   346  		NET_BIND_SERVICE
   347  		NET_BROADCAST
   348  		NET_RAW
   349  		SETFCAP
   350  		SETGID
   351  		SETPCAP
   352  		SETUID
   353  		SYS_ADMIN
   354  		SYS_BOOT
   355  		SYS_CHROOT
   356  		SYSLOG
   357  		SYS_MODULE
   358  		SYS_NICE
   359  		SYS_PACCT
   360  		SYS_PTRACE
   361  		SYS_RAWIO
   362  		SYS_RESOURCE
   363  		SYS_TIME
   364  		SYS_TTY_CONFIG
   365  		WAKE_ALARM
   366  	" -- "$cur" ) )
   367  }
   368  
   369  __docker_complete_detach-keys() {
   370  	case "$prev" in
   371  		--detach-keys)
   372  			case "$cur" in
   373  				*,)
   374  					COMPREPLY=( $( compgen -W "${cur}ctrl-" -- "$cur" ) )
   375  					;;
   376  				*)
   377  					COMPREPLY=( $( compgen -W "ctrl-" -- "$cur" ) )
   378  					;;
   379  			esac
   380  
   381  			__docker_nospace
   382  			return
   383  			;;
   384  	esac
   385  	return 1
   386  }
   387  
   388  __docker_complete_isolation() {
   389  	COMPREPLY=( $( compgen -W "default hyperv process" -- "$cur" ) )
   390  }
   391  
   392  __docker_complete_log_drivers() {
   393  	COMPREPLY=( $( compgen -W "
   394  		awslogs
   395  		fluentd
   396  		gelf
   397  		journald
   398  		json-file
   399  		none
   400  		splunk
   401  		syslog
   402  	" -- "$cur" ) )
   403  }
   404  
   405  __docker_complete_log_options() {
   406  	# see docs/reference/logging/index.md
   407  	local awslogs_options="awslogs-region awslogs-group awslogs-stream"
   408  	local fluentd_options="env fluentd-address labels tag"
   409  	local gelf_options="env gelf-address labels tag"
   410  	local journald_options="env labels"
   411  	local json_file_options="env labels max-file max-size"
   412  	local syslog_options="syslog-address syslog-tls-ca-cert syslog-tls-cert syslog-tls-key syslog-tls-skip-verify syslog-facility tag"
   413  	local splunk_options="env labels splunk-caname splunk-capath splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url tag"
   414  
   415  	local all_options="$fluentd_options $gelf_options $journald_options $json_file_options $syslog_options $splunk_options"
   416  
   417  	case $(__docker_value_of_option --log-driver) in
   418  		'')
   419  			COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) )
   420  			;;
   421  		awslogs)
   422  			COMPREPLY=( $( compgen -W "$awslogs_options" -S = -- "$cur" ) )
   423  			;;
   424  		fluentd)
   425  			COMPREPLY=( $( compgen -W "$fluentd_options" -S = -- "$cur" ) )
   426  			;;
   427  		gelf)
   428  			COMPREPLY=( $( compgen -W "$gelf_options" -S = -- "$cur" ) )
   429  			;;
   430  		journald)
   431  			COMPREPLY=( $( compgen -W "$journald_options" -S = -- "$cur" ) )
   432  			;;
   433  		json-file)
   434  			COMPREPLY=( $( compgen -W "$json_file_options" -S = -- "$cur" ) )
   435  			;;
   436  		syslog)
   437  			COMPREPLY=( $( compgen -W "$syslog_options" -S = -- "$cur" ) )
   438  			;;
   439  		splunk)
   440  			COMPREPLY=( $( compgen -W "$splunk_options" -S = -- "$cur" ) )
   441  			;;
   442  		*)
   443  			return
   444  			;;
   445  	esac
   446  
   447  	__docker_nospace
   448  }
   449  
   450  __docker_complete_log_driver_options() {
   451  	# "=" gets parsed to a word and assigned to either $cur or $prev depending on whether
   452  	# it is the last character or not. So we search for "xxx=" in the the last two words.
   453  	case "${words[$cword-2]}$prev=" in
   454  		*gelf-address=*)
   455  			COMPREPLY=( $( compgen -W "udp" -S "://" -- "${cur#=}" ) )
   456  			__docker_nospace
   457  			return
   458  			;;
   459  		*syslog-address=*)
   460  			COMPREPLY=( $( compgen -W "tcp:// tcp+tls:// udp:// unix://" -- "${cur#=}" ) )
   461  			__docker_nospace
   462  			__ltrim_colon_completions "${cur}"
   463  			return
   464  			;;
   465  		*syslog-facility=*)
   466  			COMPREPLY=( $( compgen -W "
   467  				auth
   468  				authpriv
   469  				cron
   470  				daemon
   471  				ftp
   472  				kern
   473  				local0
   474  				local1
   475  				local2
   476  				local3
   477  				local4
   478  				local5
   479  				local6
   480  				local7
   481  				lpr
   482  				mail
   483  				news
   484  				syslog
   485  				user
   486  				uucp
   487  			" -- "${cur#=}" ) )
   488  			return
   489  			;;
   490  		*syslog-tls-@(ca-cert|cert|key)=*)
   491  			_filedir
   492  			return
   493  			;;
   494  		*syslog-tls-skip-verify=*)
   495  			COMPREPLY=( $( compgen -W "true" -- "${cur#=}" ) )
   496  			return
   497  			;;
   498  		*splunk-url=*)
   499  			COMPREPLY=( $( compgen -W "http:// https://" -- "${cur#=}" ) )
   500  			__docker_nospace
   501  			__ltrim_colon_completions "${cur}"
   502  			return
   503  			;;
   504  		*splunk-insecureskipverify=*)
   505  			COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) )
   506  			__docker_nospace
   507  			return
   508  			;;
   509  	esac
   510  	return 1
   511  }
   512  
   513  __docker_complete_log_levels() {
   514  	COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) )
   515  }
   516  
   517  # a selection of the available signals that is most likely of interest in the
   518  # context of docker containers.
   519  __docker_complete_signals() {
   520  	local signals=(
   521  		SIGCONT
   522  		SIGHUP
   523  		SIGINT
   524  		SIGKILL
   525  		SIGQUIT
   526  		SIGSTOP
   527  		SIGTERM
   528  		SIGUSR1
   529  		SIGUSR2
   530  	)
   531  	COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo $cur | tr '[:lower:]' '[:upper:]')" ) )
   532  }
   533  
   534  # global options that may appear after the docker command
   535  _docker_docker() {
   536  	local boolean_options="
   537  		$global_boolean_options
   538  		--help
   539  		--version -v
   540  	"
   541  
   542  	case "$prev" in
   543  		--config)
   544  			_filedir -d
   545  			return
   546  			;;
   547  		--log-level|-l)
   548  			__docker_complete_log_levels
   549  			return
   550  			;;
   551  		$(__docker_to_extglob "$global_options_with_args") )
   552  			return
   553  			;;
   554  	esac
   555  
   556  	case "$cur" in
   557  		-*)
   558  			COMPREPLY=( $( compgen -W "$boolean_options $global_options_with_args" -- "$cur" ) )
   559  			;;
   560  		*)
   561  			local counter=$( __docker_pos_first_nonflag $(__docker_to_extglob "$global_options_with_args") )
   562  			if [ $cword -eq $counter ]; then
   563  				COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) )
   564  			fi
   565  			;;
   566  	esac
   567  }
   568  
   569  _docker_attach() {
   570  	__docker_complete_detach-keys && return
   571  
   572   	case "$cur" in
   573  		-*)
   574  			COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy" -- "$cur" ) )
   575  			;;
   576  		*)
   577  			local counter=$(__docker_pos_first_nonflag '--detach-keys')
   578  			if [ $cword -eq $counter ]; then
   579  				__docker_complete_containers_running
   580  			fi
   581  			;;
   582  	esac
   583  }
   584  
   585  _docker_build() {
   586  	local options_with_args="
   587  		--build-arg
   588  		--cgroup-parent
   589  		--cpuset-cpus
   590  		--cpuset-mems
   591  		--cpu-shares
   592  		--cpu-period
   593  		--cpu-quota
   594  		--file -f
   595  		--isolation
   596  		--memory -m
   597  		--memory-swap
   598  		--shm-size
   599  		--tag -t
   600  		--ulimit
   601  	"
   602  
   603  	local boolean_options="
   604  		--disable-content-trust=false
   605  		--force-rm
   606  		--help
   607  		--no-cache
   608  		--pull
   609  		--quiet -q
   610  		--rm
   611  	"
   612  
   613  	local all_options="$options_with_args $boolean_options"
   614  
   615  	case "$prev" in
   616  		--build-arg)
   617  			COMPREPLY=( $( compgen -e -- "$cur" ) )
   618  			__docker_nospace
   619  			return
   620  			;;
   621  		--file|-f)
   622  			_filedir
   623  			return
   624  			;;
   625  		--isolation)
   626  			__docker_complete_isolation
   627  			return
   628  			;;
   629  		--tag|-t)
   630  			__docker_complete_image_repos_and_tags
   631  			return
   632  			;;
   633  		$(__docker_to_extglob "$options_with_args") )
   634  			return
   635  			;;
   636  	esac
   637  
   638  	case "$cur" in
   639  		-*)
   640  			COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) )
   641  			;;
   642  		*)
   643  			local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) )
   644  			if [ $cword -eq $counter ]; then
   645  				_filedir -d
   646  			fi
   647  			;;
   648  	esac
   649  }
   650  
   651  _docker_commit() {
   652  	case "$prev" in
   653  		--author|-a|--change|-c|--message|-m)
   654  			return
   655  			;;
   656  	esac
   657  
   658  	case "$cur" in
   659  		-*)
   660  			COMPREPLY=( $( compgen -W "--author -a --change -c --help --message -m --pause -p" -- "$cur" ) )
   661  			;;
   662  		*)
   663  			local counter=$(__docker_pos_first_nonflag '--author|-a|--change|-c|--message|-m')
   664  
   665  			if [ $cword -eq $counter ]; then
   666  				__docker_complete_containers_all
   667  				return
   668  			fi
   669  			(( counter++ ))
   670  
   671  			if [ $cword -eq $counter ]; then
   672  				__docker_complete_image_repos_and_tags
   673  				return
   674  			fi
   675  			;;
   676  	esac
   677  }
   678  
   679  _docker_cp() {
   680  	case "$cur" in
   681  		-*)
   682  			COMPREPLY=( $( compgen -W "--follow-link -L --help" -- "$cur" ) )
   683  			;;
   684  		*)
   685  			local counter=$(__docker_pos_first_nonflag)
   686  			if [ $cword -eq $counter ]; then
   687  				case "$cur" in
   688  					*:)
   689  						return
   690  						;;
   691  					*)
   692  						# combined container and filename completion
   693  						_filedir
   694  						local files=( ${COMPREPLY[@]} )
   695  
   696  						__docker_complete_containers_all
   697  						COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
   698  						local containers=( ${COMPREPLY[@]} )
   699  
   700  						COMPREPLY=( $( compgen -W "${files[*]} ${containers[*]}" -- "$cur" ) )
   701  						if [[ "$COMPREPLY" == *: ]]; then
   702  							__docker_nospace
   703  						fi
   704  						return
   705  						;;
   706  				esac
   707  			fi
   708  			(( counter++ ))
   709  
   710  			if [ $cword -eq $counter ]; then
   711  				if [ -e "$prev" ]; then
   712  					__docker_complete_containers_all
   713  					COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
   714  					__docker_nospace
   715  				else
   716  					_filedir
   717  				fi
   718  				return
   719  			fi
   720  			;;
   721  	esac
   722  }
   723  
   724  _docker_create() {
   725  	_docker_run
   726  }
   727  
   728  _docker_daemon() {
   729  	local boolean_options="
   730  		$global_boolean_options
   731  		--disable-legacy-registry
   732  		--help
   733  		--icc=false
   734  		--ip-forward=false
   735  		--ip-masq=false
   736  		--iptables=false
   737  		--ipv6
   738  		--selinux-enabled
   739  		--userland-proxy=false
   740  	"
   741  	local options_with_args="
   742  		$global_options_with_args
   743  		--api-cors-header
   744  		--authorization-plugin
   745  		--bip
   746  		--bridge -b
   747  		--cgroup-parent
   748  		--cluster-advertise
   749  		--cluster-store
   750  		--cluster-store-opt
   751  		--default-gateway
   752  		--default-gateway-v6
   753  		--default-ulimit
   754  		--dns
   755  		--dns-search
   756  		--dns-opt
   757  		--exec-opt
   758  		--exec-root
   759  		--fixed-cidr
   760  		--fixed-cidr-v6
   761  		--graph -g
   762  		--group -G
   763  		--insecure-registry
   764  		--ip
   765  		--label
   766  		--log-driver
   767  		--log-opt
   768  		--mtu
   769  		--pidfile -p
   770  		--registry-mirror
   771  		--storage-driver -s
   772  		--storage-opt
   773  		--userns-remap
   774  	"
   775  
   776  	case "$prev" in
   777  		--authorization-plugin)
   778  			__docker_complete_plugins Authorization
   779  			return
   780  			;;
   781  		--cluster-store)
   782  			COMPREPLY=( $( compgen -W "consul etcd zk" -S "://" -- "$cur" ) )
   783  			__docker_nospace
   784  			return
   785  			;;
   786  		--cluster-store-opt)
   787  			COMPREPLY=( $( compgen -W "discovery.heartbeat discovery.ttl kv.cacertfile kv.certfile kv.keyfile kv.path" -S = -- "$cur" ) )
   788  			__docker_nospace
   789  			return
   790  			;;
   791  		--exec-root|--graph|-g)
   792  			_filedir -d
   793  			return
   794  			;;
   795  		--log-driver)
   796  			__docker_complete_log_drivers
   797  			return
   798  			;;
   799  		--pidfile|-p|--tlscacert|--tlscert|--tlskey)
   800  			_filedir
   801  			return
   802  			;;
   803  		--storage-driver|-s)
   804  			COMPREPLY=( $( compgen -W "aufs btrfs devicemapper overlay vfs zfs" -- "$(echo $cur | tr '[:upper:]' '[:lower:]')" ) )
   805  			return
   806  			;;
   807  		--storage-opt)
   808  			local devicemapper_options="
   809  				dm.basesize
   810  				dm.blkdiscard
   811  				dm.blocksize
   812  				dm.fs
   813  				dm.loopdatasize
   814  				dm.loopmetadatasize
   815  				dm.mkfsarg
   816  				dm.mountopt
   817  				dm.override_udev_sync_check
   818  				dm.thinpooldev
   819  				dm.use_deferred_deletion
   820  				dm.use_deferred_removal
   821  			"
   822  			local zfs_options="zfs.fsname"
   823  
   824  			case $(__docker_value_of_option '--storage-driver|-s') in
   825  				'')
   826  					COMPREPLY=( $( compgen -W "$devicemapper_options $zfs_options" -S = -- "$cur" ) )
   827  					;;
   828  				devicemapper)
   829  					COMPREPLY=( $( compgen -W "$devicemapper_options" -S = -- "$cur" ) )
   830  					;;
   831  				zfs)
   832  					COMPREPLY=( $( compgen -W "$zfs_options" -S = -- "$cur" ) )
   833  					;;
   834  				*)
   835  					return
   836  					;;
   837  			esac
   838  			__docker_nospace
   839  			return
   840  			;;
   841  		--log-level|-l)
   842  			__docker_complete_log_levels
   843  			return
   844  			;;
   845  		--log-opt)
   846  			__docker_complete_log_options
   847  			return
   848  			;;
   849  		--userns-remap)
   850  			if [[ $cur == *:* ]] ; then
   851  				COMPREPLY=( $(compgen -g -- "${cur#*:}") )
   852  			else
   853  				COMPREPLY=( $(compgen -u -S : -- "$cur") )
   854  				__docker_nospace
   855  			fi
   856  			return
   857  			;;
   858  		$(__docker_to_extglob "$options_with_args") )
   859  			return
   860  			;;
   861  	esac
   862  
   863  	__docker_complete_log_driver_options && return
   864  
   865  	case "${words[$cword-2]}$prev=" in
   866  		# completions for --storage-opt
   867  		*dm.@(blkdiscard|override_udev_sync_check|use_deferred_@(removal|deletion))=*)
   868  			COMPREPLY=( $( compgen -W "false true" -- "${cur#=}" ) )
   869  			return
   870  			;;
   871  		*dm.fs=*)
   872  			COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur#=}" ) )
   873  			return
   874  			;;
   875  		*dm.thinpooldev=*)
   876  			_filedir
   877  			return
   878  			;;
   879  		# completions for --cluster-store-opt
   880  		*kv.*file=*)
   881  			_filedir
   882  			return
   883  			;;
   884  	esac
   885  
   886  	case "$cur" in
   887  		-*)
   888  			COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) )
   889  			;;
   890  	esac
   891  }
   892  
   893  _docker_diff() {
   894  	case "$cur" in
   895  		-*)
   896  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
   897  			;;
   898  		*)
   899  			local counter=$(__docker_pos_first_nonflag)
   900  			if [ $cword -eq $counter ]; then
   901  				__docker_complete_containers_all
   902  			fi
   903  			;;
   904  	esac
   905  }
   906  
   907  _docker_events() {
   908  	local filter=$(__docker_map_key_of_current_option '-f|--filter')
   909  	case "$filter" in
   910  		container)
   911  			cur="${cur##*=}"
   912  			__docker_complete_containers_all
   913  			return
   914  			;;
   915  		event)
   916  			COMPREPLY=( $( compgen -W "
   917  				attach
   918  				commit
   919  				connect
   920  				copy
   921  				create
   922  				delete
   923  				destroy
   924  				die
   925  				disconnect
   926  				exec_create
   927  				exec_start
   928  				export
   929  				import
   930  				kill
   931  				mount
   932  				oom
   933  				pause
   934  				pull
   935  				push
   936  				rename
   937  				resize
   938  				restart
   939  				start
   940  				stop
   941  				tag
   942  				top
   943  				unmount
   944  				unpause
   945  				untag
   946  				update
   947  			" -- "${cur##*=}" ) )
   948  			return
   949  			;;
   950  		image)
   951  			cur="${cur##*=}"
   952  			__docker_complete_images
   953  			return
   954  			;;
   955  		network)
   956  			cur="${cur##*=}"
   957  			__docker_complete_networks
   958  			return
   959  			;;
   960  		type)
   961  			COMPREPLY=( $( compgen -W "container image network volume" -- "${cur##*=}" ) )
   962  			return
   963  			;;
   964  		volume)
   965  			cur="${cur##*=}"
   966  			__docker_complete_volumes
   967  			return
   968  			;;
   969  	esac
   970  
   971  	case "$prev" in
   972  		--filter|-f)
   973  			COMPREPLY=( $( compgen -S = -W "container event image label network type volume" -- "$cur" ) )
   974  			__docker_nospace
   975  			return
   976  			;;
   977  		--since|--until)
   978  			return
   979  			;;
   980  	esac
   981  
   982  	case "$cur" in
   983  		-*)
   984  			COMPREPLY=( $( compgen -W "--filter -f --help --since --until" -- "$cur" ) )
   985  			;;
   986  	esac
   987  }
   988  
   989  _docker_exec() {
   990  	__docker_complete_detach-keys && return
   991  
   992  	case "$prev" in
   993  		--user|-u)
   994  			return
   995  			;;
   996  	esac
   997  
   998  	case "$cur" in
   999  		-*)
  1000  			COMPREPLY=( $( compgen -W "--detach -d --detach-keys --help --interactive -i --privileged -t --tty -u --user" -- "$cur" ) )
  1001  			;;
  1002  		*)
  1003  			__docker_complete_containers_running
  1004  			;;
  1005  	esac
  1006  }
  1007  
  1008  _docker_export() {
  1009  	case "$cur" in
  1010  		-*)
  1011  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1012  			;;
  1013  		*)
  1014  			local counter=$(__docker_pos_first_nonflag)
  1015  			if [ $cword -eq $counter ]; then
  1016  				__docker_complete_containers_all
  1017  			fi
  1018  			;;
  1019  	esac
  1020  }
  1021  
  1022  _docker_help() {
  1023  	local counter=$(__docker_pos_first_nonflag)
  1024  	if [ $cword -eq $counter ]; then
  1025  		COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
  1026  	fi
  1027  }
  1028  
  1029  _docker_history() {
  1030  	case "$cur" in
  1031  		-*)
  1032  			COMPREPLY=( $( compgen -W "--help --no-trunc --quiet -q" -- "$cur" ) )
  1033  			;;
  1034  		*)
  1035  			local counter=$(__docker_pos_first_nonflag)
  1036  			if [ $cword -eq $counter ]; then
  1037  				__docker_complete_images
  1038  			fi
  1039  			;;
  1040  	esac
  1041  }
  1042  
  1043  _docker_images() {
  1044  	case "$prev" in
  1045  		--filter|-f)
  1046  			COMPREPLY=( $( compgen -S = -W "dangling label" -- "$cur" ) )
  1047  			__docker_nospace
  1048  			return
  1049  			;;
  1050                  --format)
  1051  			return
  1052  			;;
  1053  	esac
  1054  
  1055  	case "${words[$cword-2]}$prev=" in
  1056  		*dangling=*)
  1057  			COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) )
  1058  			return
  1059  			;;
  1060  		*label=*)
  1061  			return
  1062  			;;
  1063  	esac
  1064  
  1065  	case "$cur" in
  1066  		-*)
  1067  			COMPREPLY=( $( compgen -W "--all -a --digests --filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) )
  1068  			;;
  1069  		=)
  1070  			return
  1071  			;;
  1072  		*)
  1073  			__docker_complete_image_repos
  1074  			;;
  1075  	esac
  1076  }
  1077  
  1078  _docker_import() {
  1079  	case "$prev" in
  1080  		--change|-c|--message|-m)
  1081  			return
  1082  			;;
  1083  	esac
  1084  
  1085  	case "$cur" in
  1086  		-*)
  1087  			COMPREPLY=( $( compgen -W "--change -c --help --message -m" -- "$cur" ) )
  1088  			;;
  1089  		*)
  1090  			local counter=$(__docker_pos_first_nonflag '--change|-c|--message|-m')
  1091  			if [ $cword -eq $counter ]; then
  1092  				return
  1093  			fi
  1094  			(( counter++ ))
  1095  
  1096  			if [ $cword -eq $counter ]; then
  1097  				__docker_complete_image_repos_and_tags
  1098  				return
  1099  			fi
  1100  			;;
  1101  	esac
  1102  }
  1103  
  1104  _docker_info() {
  1105  	case "$cur" in
  1106  		-*)
  1107  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1108  			;;
  1109  	esac
  1110  }
  1111  
  1112  _docker_inspect() {
  1113  	case "$prev" in
  1114  		--format|-f)
  1115  			return
  1116  			;;
  1117  		--type)
  1118                       COMPREPLY=( $( compgen -W "image container" -- "$cur" ) )
  1119                       return
  1120                          ;;
  1121  
  1122  	esac
  1123  
  1124  	case "$cur" in
  1125  		-*)
  1126  			COMPREPLY=( $( compgen -W "--format -f --help --size -s --type" -- "$cur" ) )
  1127  			;;
  1128  		*)
  1129  			case $(__docker_value_of_option --type) in
  1130  				'')
  1131  					__docker_complete_containers_and_images
  1132  					;;
  1133  				container)
  1134  					__docker_complete_containers_all
  1135  					;;
  1136  				image)
  1137  					__docker_complete_images
  1138  					;;
  1139  			esac
  1140  	esac
  1141  }
  1142  
  1143  _docker_kill() {
  1144  	case "$prev" in
  1145  		--signal|-s)
  1146  			__docker_complete_signals
  1147  			return
  1148  			;;
  1149  	esac
  1150  
  1151  	case "$cur" in
  1152  		-*)
  1153  			COMPREPLY=( $( compgen -W "--help --signal -s" -- "$cur" ) )
  1154  			;;
  1155  		*)
  1156  			__docker_complete_containers_running
  1157  			;;
  1158  	esac
  1159  }
  1160  
  1161  _docker_load() {
  1162  	case "$prev" in
  1163  		--input|-i)
  1164  			_filedir
  1165  			return
  1166  			;;
  1167  	esac
  1168  
  1169  	case "$cur" in
  1170  		-*)
  1171  			COMPREPLY=( $( compgen -W "--help --input -i" -- "$cur" ) )
  1172  			;;
  1173  	esac
  1174  }
  1175  
  1176  _docker_login() {
  1177  	case "$prev" in
  1178  		--email|-e|--password|-p|--username|-u)
  1179  			return
  1180  			;;
  1181  	esac
  1182  
  1183  	case "$cur" in
  1184  		-*)
  1185  			COMPREPLY=( $( compgen -W "--email -e --help --password -p --username -u" -- "$cur" ) )
  1186  			;;
  1187  	esac
  1188  }
  1189  
  1190  _docker_logout() {
  1191  	case "$cur" in
  1192  		-*)
  1193  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1194  			;;
  1195  	esac
  1196  }
  1197  
  1198  _docker_logs() {
  1199  	case "$prev" in
  1200  		--since|--tail)
  1201  			return
  1202  			;;
  1203  	esac
  1204  
  1205  	case "$cur" in
  1206  		-*)
  1207  			COMPREPLY=( $( compgen -W "--follow -f --help --since --tail --timestamps -t" -- "$cur" ) )
  1208  			;;
  1209  		*)
  1210  			local counter=$(__docker_pos_first_nonflag '--tail')
  1211  			if [ $cword -eq $counter ]; then
  1212  				__docker_complete_containers_all
  1213  			fi
  1214  			;;
  1215  	esac
  1216  }
  1217  
  1218  _docker_network_connect() {
  1219  	local options_with_args="
  1220  		--alias
  1221  		--ip
  1222  		--ip6
  1223  		--link
  1224  	"
  1225  
  1226  	local boolean_options="
  1227  		--help
  1228  	"
  1229  
  1230  	case "$prev" in
  1231  		--link)
  1232  			case "$cur" in
  1233  				*:*)
  1234  					;;
  1235  				*)
  1236  					__docker_complete_containers_running
  1237  					COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
  1238  					__docker_nospace
  1239  					;;
  1240  			esac
  1241  			return
  1242  			;;
  1243  		$(__docker_to_extglob "$options_with_args") )
  1244  			return
  1245  			;;
  1246  	esac
  1247  
  1248  	case "$cur" in
  1249  		-*)
  1250  			COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) )
  1251  			;;
  1252  		*)
  1253  			local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) )
  1254  			if [ $cword -eq $counter ]; then
  1255  				__docker_complete_networks
  1256  			elif [ $cword -eq $(($counter + 1)) ]; then
  1257  				__docker_complete_containers_all
  1258  			fi
  1259  			;;
  1260  	esac
  1261  }
  1262  
  1263  _docker_network_create() {
  1264  	case "$prev" in
  1265  		--aux-address|--gateway|--ip-range|--ipam-opt|--opt|-o|--subnet)
  1266  			return
  1267  			;;
  1268  		--ipam-driver)
  1269  			COMPREPLY=( $( compgen -W "default" -- "$cur" ) )
  1270  			return
  1271  			;;
  1272  		--driver|-d)
  1273  			local plugins=" $(__docker_plugins Network) "
  1274  			# remove drivers that allow one instance only
  1275  			plugins=${plugins/ host / }
  1276  			plugins=${plugins/ null / }
  1277  			COMPREPLY=( $(compgen -W "$plugins" -- "$cur") )
  1278  			return
  1279  			;;
  1280  	esac
  1281  
  1282  	case "$cur" in
  1283  		-*)
  1284  			COMPREPLY=( $( compgen -W "--aux-address --driver -d --gateway --help --internal --ip-range --ipam-driver --ipam-opt --opt -o --subnet" -- "$cur" ) )
  1285  			;;
  1286  	esac
  1287  }
  1288  
  1289  _docker_network_disconnect() {
  1290  	case "$cur" in
  1291  		-*)
  1292  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1293  			;;
  1294  		*)
  1295  			local counter=$(__docker_pos_first_nonflag)
  1296  			if [ $cword -eq $counter ]; then
  1297  				__docker_complete_networks
  1298  			elif [ $cword -eq $(($counter + 1)) ]; then
  1299  				__docker_complete_containers_in_network "$prev"
  1300  			fi
  1301  			;;
  1302  	esac
  1303  }
  1304  
  1305  _docker_network_inspect() {
  1306  	case "$prev" in
  1307  		--format|-f)
  1308  			return
  1309  			;;
  1310  	esac
  1311  
  1312  	case "$cur" in
  1313  		-*)
  1314  			COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) )
  1315  			;;
  1316  		*)
  1317  			__docker_complete_networks
  1318  	esac
  1319  }
  1320  
  1321  _docker_network_ls() {
  1322  	case "$prev" in
  1323  		--filter|-f)
  1324  			COMPREPLY=( $( compgen -S = -W "id name type" -- "$cur" ) )
  1325  			__docker_nospace
  1326  			return
  1327  			;;
  1328  	esac
  1329  
  1330  	case "${words[$cword-2]}$prev=" in
  1331  		*id=*)
  1332  			cur="${cur#=}"
  1333  			__docker_complete_network_ids
  1334  			return
  1335  			;;
  1336  		*name=*)
  1337  			cur="${cur#=}"
  1338  			__docker_complete_network_names
  1339  			return
  1340  			;;
  1341  		*type=*)
  1342  			COMPREPLY=( $( compgen -W "builtin custom" -- "${cur#=}" ) )
  1343  			return
  1344  			;;
  1345  	esac
  1346  
  1347  	case "$cur" in
  1348  		-*)
  1349  			COMPREPLY=( $( compgen -W "--filter -f --help --no-trunc --quiet -q" -- "$cur" ) )
  1350  			;;
  1351  	esac
  1352  }
  1353  
  1354  _docker_network_rm() {
  1355  	case "$cur" in
  1356  		-*)
  1357  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1358  			;;
  1359  		*)
  1360  			__docker_complete_networks
  1361  	esac
  1362  }
  1363  
  1364  _docker_network() {
  1365  	local subcommands="
  1366  		connect
  1367  		create
  1368  		disconnect
  1369  		inspect
  1370  		ls
  1371  		rm
  1372  	"
  1373  	__docker_subcommands "$subcommands" && return
  1374  
  1375  	case "$cur" in
  1376  		-*)
  1377  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1378  			;;
  1379  		*)
  1380  			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
  1381  			;;
  1382  	esac
  1383  }
  1384  
  1385  _docker_pause() {
  1386  	case "$cur" in
  1387  		-*)
  1388  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1389  			;;
  1390  		*)
  1391  			local counter=$(__docker_pos_first_nonflag)
  1392  			if [ $cword -eq $counter ]; then
  1393  				__docker_complete_containers_pauseable
  1394  			fi
  1395  			;;
  1396  	esac
  1397  }
  1398  
  1399  _docker_port() {
  1400  	case "$cur" in
  1401  		-*)
  1402  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1403  			;;
  1404  		*)
  1405  			local counter=$(__docker_pos_first_nonflag)
  1406  			if [ $cword -eq $counter ]; then
  1407  				__docker_complete_containers_all
  1408  			fi
  1409  			;;
  1410  	esac
  1411  }
  1412  
  1413  _docker_ps() {
  1414  	case "$prev" in
  1415  		--before|--since)
  1416  			__docker_complete_containers_all
  1417  			;;
  1418  		--filter|-f)
  1419  			COMPREPLY=( $( compgen -S = -W "ancestor exited id label name status" -- "$cur" ) )
  1420  			__docker_nospace
  1421  			return
  1422  			;;
  1423  		--format|-n)
  1424  			return
  1425  			;;
  1426  	esac
  1427  
  1428  	case "${words[$cword-2]}$prev=" in
  1429  		*ancestor=*)
  1430  			cur="${cur#=}"
  1431  			__docker_complete_images
  1432  			return
  1433  			;;
  1434  		*id=*)
  1435  			cur="${cur#=}"
  1436  			__docker_complete_container_ids
  1437  			return
  1438  			;;
  1439  		*name=*)
  1440  			cur="${cur#=}"
  1441  			__docker_complete_container_names
  1442  			return
  1443  			;;
  1444  		*status=*)
  1445  			COMPREPLY=( $( compgen -W "created dead exited paused restarting running" -- "${cur#=}" ) )
  1446  			return
  1447  			;;
  1448  	esac
  1449  
  1450  	case "$cur" in
  1451  		-*)
  1452  			COMPREPLY=( $( compgen -W "--all -a --before --filter -f --format --help --latest -l -n --no-trunc --quiet -q --size -s --since" -- "$cur" ) )
  1453  			;;
  1454  	esac
  1455  }
  1456  
  1457  _docker_pull() {
  1458  	case "$cur" in
  1459  		-*)
  1460  			COMPREPLY=( $( compgen -W "--all-tags -a --disable-content-trust=false --help" -- "$cur" ) )
  1461  			;;
  1462  		*)
  1463  			local counter=$(__docker_pos_first_nonflag)
  1464  			if [ $cword -eq $counter ]; then
  1465  				for arg in "${COMP_WORDS[@]}"; do
  1466  					case "$arg" in
  1467  						--all-tags|-a)
  1468  							__docker_complete_image_repos
  1469  							return
  1470  							;;
  1471  					esac
  1472  				done
  1473  				__docker_complete_image_repos_and_tags
  1474  			fi
  1475  			;;
  1476  	esac
  1477  }
  1478  
  1479  _docker_push() {
  1480  	case "$cur" in
  1481  		-*)
  1482  			COMPREPLY=( $( compgen -W "--disable-content-trust=false --help" -- "$cur" ) )
  1483  			;;
  1484  		*)
  1485  			local counter=$(__docker_pos_first_nonflag)
  1486  			if [ $cword -eq $counter ]; then
  1487  				__docker_complete_image_repos_and_tags
  1488  			fi
  1489  			;;
  1490  	esac
  1491  }
  1492  
  1493  _docker_rename() {
  1494  	case "$cur" in
  1495  		-*)
  1496  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1497  			;;
  1498  		*)
  1499  			local counter=$(__docker_pos_first_nonflag)
  1500  			if [ $cword -eq $counter ]; then
  1501  				__docker_complete_containers_all
  1502  			fi
  1503  			;;
  1504  	esac
  1505  }
  1506  
  1507  _docker_restart() {
  1508  	case "$prev" in
  1509  		--time|-t)
  1510  			return
  1511  			;;
  1512  	esac
  1513  
  1514  	case "$cur" in
  1515  		-*)
  1516  			COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) )
  1517  			;;
  1518  		*)
  1519  			__docker_complete_containers_all
  1520  			;;
  1521  	esac
  1522  }
  1523  
  1524  _docker_rm() {
  1525  	case "$cur" in
  1526  		-*)
  1527  			COMPREPLY=( $( compgen -W "--force -f --help --link -l --volumes -v" -- "$cur" ) )
  1528  			;;
  1529  		*)
  1530  			for arg in "${COMP_WORDS[@]}"; do
  1531  				case "$arg" in
  1532  					--force|-f)
  1533  						__docker_complete_containers_all
  1534  						return
  1535  						;;
  1536  				esac
  1537  			done
  1538  			__docker_complete_containers_stopped
  1539  			;;
  1540  	esac
  1541  }
  1542  
  1543  _docker_rmi() {
  1544  	case "$cur" in
  1545  		-*)
  1546  			COMPREPLY=( $( compgen -W "--force -f --help --no-prune" -- "$cur" ) )
  1547  			;;
  1548  		*)
  1549  			__docker_complete_images
  1550  			;;
  1551  	esac
  1552  }
  1553  
  1554  _docker_run() {
  1555  	local options_with_args="
  1556  		--add-host
  1557  		--attach -a
  1558  		--blkio-weight
  1559  		--blkio-weight-device
  1560  		--cap-add
  1561  		--cap-drop
  1562  		--cgroup-parent
  1563  		--cidfile
  1564  		--cpu-period
  1565  		--cpu-quota
  1566  		--cpuset-cpus
  1567  		--cpuset-mems
  1568  		--cpu-shares
  1569  		--device
  1570  		--device-read-bps
  1571  		--device-read-iops
  1572  		--device-write-bps
  1573  		--device-write-iops
  1574  		--dns
  1575  		--dns-opt
  1576  		--dns-search
  1577  		--entrypoint
  1578  		--env -e
  1579  		--env-file
  1580  		--expose
  1581  		--group-add
  1582  		--hostname -h
  1583  		--ip
  1584  		--ip6
  1585  		--ipc
  1586  		--isolation
  1587  		--kernel-memory
  1588  		--label-file
  1589  		--label -l
  1590  		--link
  1591  		--log-driver
  1592  		--log-opt
  1593  		--mac-address
  1594  		--memory -m
  1595  		--memory-swap
  1596  		--memory-swappiness
  1597  		--memory-reservation
  1598  		--name
  1599  		--net
  1600  		--net-alias
  1601  		--oom-score-adj
  1602  		--pid
  1603  		--publish -p
  1604  		--restart
  1605  		--security-opt
  1606  		--shm-size
  1607  		--stop-signal
  1608  		--tmpfs
  1609  		--ulimit
  1610  		--user -u
  1611  		--uts
  1612  		--volume-driver
  1613  		--volumes-from
  1614  		--volume -v
  1615  		--workdir -w
  1616  	"
  1617  
  1618  	local boolean_options="
  1619  		--disable-content-trust=false
  1620  		--help
  1621  		--interactive -i
  1622  		--oom-kill-disable
  1623  		--privileged
  1624  		--publish-all -P
  1625  		--read-only
  1626  		--tty -t
  1627  	"
  1628  
  1629  	if [ "$command" = "run" ] ; then
  1630  		options_with_args="$options_with_args
  1631  			--detach-keys
  1632  		"
  1633  		boolean_options="$boolean_options
  1634  			--detach -d
  1635  			--rm
  1636  			--sig-proxy=false
  1637  		"
  1638  		__docker_complete_detach-keys && return
  1639  	fi
  1640  
  1641  	local all_options="$options_with_args $boolean_options"
  1642  
  1643  
  1644  	case "$prev" in
  1645  		--add-host)
  1646  			case "$cur" in
  1647  				*:)
  1648  					__docker_complete_resolved_hostname
  1649  					return
  1650  					;;
  1651  			esac
  1652  			;;
  1653  		--attach|-a)
  1654  			COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) )
  1655  			return
  1656  			;;
  1657  		--cap-add|--cap-drop)
  1658  			__docker_complete_capabilities
  1659  			return
  1660  			;;
  1661  		--cidfile|--env-file|--label-file)
  1662  			_filedir
  1663  			return
  1664  			;;
  1665  		--device|--tmpfs|--volume|-v)
  1666  			case "$cur" in
  1667  				*:*)
  1668  					# TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine)
  1669  					;;
  1670  				'')
  1671  					COMPREPLY=( $( compgen -W '/' -- "$cur" ) )
  1672  					__docker_nospace
  1673  					;;
  1674  				/*)
  1675  					_filedir
  1676  					__docker_nospace
  1677  					;;
  1678  			esac
  1679  			return
  1680  			;;
  1681  		--env|-e)
  1682  			COMPREPLY=( $( compgen -e -- "$cur" ) )
  1683  			__docker_nospace
  1684  			return
  1685  			;;
  1686  		--ipc)
  1687  			case "$cur" in
  1688  				*:*)
  1689  					cur="${cur#*:}"
  1690  					__docker_complete_containers_running
  1691  					;;
  1692  				*)
  1693  					COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) )
  1694  					if [ "$COMPREPLY" = "container:" ]; then
  1695  						__docker_nospace
  1696  					fi
  1697  					;;
  1698  			esac
  1699  			return
  1700  			;;
  1701  		--isolation)
  1702  			__docker_complete_isolation
  1703  			return
  1704  			;;
  1705  		--link)
  1706  			case "$cur" in
  1707  				*:*)
  1708  					;;
  1709  				*)
  1710  					__docker_complete_containers_running
  1711  					COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
  1712  					__docker_nospace
  1713  					;;
  1714  			esac
  1715  			return
  1716  			;;
  1717  		--log-driver)
  1718  			__docker_complete_log_drivers
  1719  			return
  1720  			;;
  1721  		--log-opt)
  1722  			__docker_complete_log_options
  1723  			return
  1724  			;;
  1725  		--net)
  1726  			case "$cur" in
  1727  				container:*)
  1728  					local cur=${cur#*:}
  1729  					__docker_complete_containers_all
  1730  					;;
  1731  				*)
  1732  					COMPREPLY=( $( compgen -W "$(__docker_plugins Network) $(__docker_networks) container:" -- "$cur") )
  1733  					if [ "${COMPREPLY[*]}" = "container:" ] ; then
  1734  						__docker_nospace
  1735  					fi
  1736  					;;
  1737  			esac
  1738  			return
  1739  			;;
  1740  		--restart)
  1741  			case "$cur" in
  1742  				on-failure:*)
  1743  					;;
  1744  				*)
  1745  					COMPREPLY=( $( compgen -W "always no on-failure on-failure: unless-stopped" -- "$cur") )
  1746  					;;
  1747  			esac
  1748  			return
  1749  			;;
  1750  		--security-opt)
  1751  			case "$cur" in
  1752  				label:*:*)
  1753  					;;
  1754  				label:*)
  1755  					local cur=${cur##*:}
  1756  					COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "$cur") )
  1757  					if [ "${COMPREPLY[*]}" != "disable" ] ; then
  1758  						__docker_nospace
  1759  					fi
  1760  					;;
  1761  				seccomp:*)
  1762  					local cur=${cur##*:}
  1763  					_filedir
  1764  					COMPREPLY+=( $( compgen -W "unconfined" -- "$cur" ) )
  1765  					;;
  1766  				*)
  1767  					COMPREPLY=( $( compgen -W "label apparmor seccomp" -S ":" -- "$cur") )
  1768  					__docker_nospace
  1769  					;;
  1770  			esac
  1771  			return
  1772  			;;
  1773  		--volume-driver)
  1774  			__docker_complete_plugins Volume
  1775  			return
  1776  			;;
  1777  		--volumes-from)
  1778  			__docker_complete_containers_all
  1779  			return
  1780  			;;
  1781  		$(__docker_to_extglob "$options_with_args") )
  1782  			return
  1783  			;;
  1784  	esac
  1785  
  1786  	__docker_complete_log_driver_options && return
  1787  
  1788  	case "$cur" in
  1789  		-*)
  1790  			COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) )
  1791  			;;
  1792  		*)
  1793  			local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) )
  1794  			if [ $cword -eq $counter ]; then
  1795  				__docker_complete_images
  1796  			fi
  1797  			;;
  1798  	esac
  1799  }
  1800  
  1801  _docker_save() {
  1802  	case "$prev" in
  1803  		--output|-o)
  1804  			_filedir
  1805  			return
  1806  			;;
  1807  	esac
  1808  
  1809  	case "$cur" in
  1810  		-*)
  1811  			COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) )
  1812  			;;
  1813  		*)
  1814  			__docker_complete_images
  1815  			;;
  1816  	esac
  1817  }
  1818  
  1819  _docker_search() {
  1820  	case "$prev" in
  1821  		--stars|-s)
  1822  			return
  1823  			;;
  1824  	esac
  1825  
  1826  	case "$cur" in
  1827  		-*)
  1828  			COMPREPLY=( $( compgen -W "--automated --help --no-trunc --stars -s" -- "$cur" ) )
  1829  			;;
  1830  	esac
  1831  }
  1832  
  1833  _docker_start() {
  1834  	__docker_complete_detach-keys && return
  1835  
  1836  	case "$cur" in
  1837  		-*)
  1838  			COMPREPLY=( $( compgen -W "--attach -a --detach-keys --help --interactive -i" -- "$cur" ) )
  1839  			;;
  1840  		*)
  1841  			__docker_complete_containers_stopped
  1842  			;;
  1843  	esac
  1844  }
  1845  
  1846  _docker_stats() {
  1847  	case "$cur" in
  1848  		-*)
  1849  			COMPREPLY=( $( compgen -W "--all -a --help --no-stream" -- "$cur" ) )
  1850  			;;
  1851  		*)
  1852  			__docker_complete_containers_running
  1853  			;;
  1854  	esac
  1855  }
  1856  
  1857  _docker_stop() {
  1858  	case "$prev" in
  1859  		--time|-t)
  1860  			return
  1861  			;;
  1862  	esac
  1863  
  1864  	case "$cur" in
  1865  		-*)
  1866  			COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) )
  1867  			;;
  1868  		*)
  1869  			__docker_complete_containers_running
  1870  			;;
  1871  	esac
  1872  }
  1873  
  1874  _docker_tag() {
  1875  	case "$cur" in
  1876  		-*)
  1877  			COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) )
  1878  			;;
  1879  		*)
  1880  			local counter=$(__docker_pos_first_nonflag)
  1881  
  1882  			if [ $cword -eq $counter ]; then
  1883  				__docker_complete_image_repos_and_tags
  1884  				return
  1885  			fi
  1886  			(( counter++ ))
  1887  
  1888  			if [ $cword -eq $counter ]; then
  1889  				__docker_complete_image_repos_and_tags
  1890  				return
  1891  			fi
  1892  			;;
  1893  	esac
  1894  }
  1895  
  1896  _docker_unpause() {
  1897  	case "$cur" in
  1898  		-*)
  1899  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1900  			;;
  1901  		*)
  1902  			local counter=$(__docker_pos_first_nonflag)
  1903  			if [ $cword -eq $counter ]; then
  1904  				__docker_complete_containers_unpauseable
  1905  			fi
  1906  			;;
  1907  	esac
  1908  }
  1909  
  1910  _docker_update() {
  1911  	local options_with_args="
  1912  		--blkio-weight
  1913  		--cpu-period
  1914  		--cpu-quota
  1915  		--cpuset-cpus
  1916  		--cpuset-mems
  1917  		--cpu-shares
  1918  		--kernel-memory
  1919  		--memory -m
  1920  		--memory-reservation
  1921  		--memory-swap
  1922  	"
  1923  
  1924  	local boolean_options="
  1925  		--help
  1926  	"
  1927  
  1928  	local all_options="$options_with_args $boolean_options"
  1929  
  1930  	case "$prev" in
  1931  		$(__docker_to_extglob "$options_with_args") )
  1932  			return
  1933  			;;
  1934  	esac
  1935  
  1936  	case "$cur" in
  1937  		-*)
  1938  			COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) )
  1939  			;;
  1940  		*)
  1941  			__docker_complete_containers_all
  1942  			;;
  1943  	esac
  1944  }
  1945  
  1946  _docker_top() {
  1947  	case "$cur" in
  1948  		-*)
  1949  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1950  			;;
  1951  		*)
  1952  			local counter=$(__docker_pos_first_nonflag)
  1953  			if [ $cword -eq $counter ]; then
  1954  				__docker_complete_containers_running
  1955  			fi
  1956  			;;
  1957  	esac
  1958  }
  1959  
  1960  _docker_version() {
  1961  	case "$cur" in
  1962  		-*)
  1963  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1964  			;;
  1965  	esac
  1966  }
  1967  
  1968  _docker_volume_create() {
  1969  	case "$prev" in
  1970  		--driver|-d)
  1971  			__docker_complete_plugins Volume
  1972  			return
  1973  			;;
  1974  		--name|--opt|-o)
  1975  			return
  1976  			;;
  1977  	esac
  1978  
  1979  	case "$cur" in
  1980  		-*)
  1981  			COMPREPLY=( $( compgen -W "--driver -d --help --name --opt -o" -- "$cur" ) )
  1982  			;;
  1983  	esac
  1984  }
  1985  
  1986  _docker_volume_inspect() {
  1987  	case "$prev" in
  1988  		--format|-f)
  1989  			return
  1990  			;;
  1991  	esac
  1992  
  1993  	case "$cur" in
  1994  		-*)
  1995  			COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) )
  1996  			;;
  1997  		*)
  1998  			__docker_complete_volumes
  1999  			;;
  2000  	esac
  2001  }
  2002  
  2003  _docker_volume_ls() {
  2004  	case "$prev" in
  2005  		--filter|-f)
  2006  			COMPREPLY=( $( compgen -S = -W "dangling" -- "$cur" ) )
  2007  			__docker_nospace
  2008  			return
  2009  			;;
  2010  	esac
  2011  
  2012  	case "${words[$cword-2]}$prev=" in
  2013  		*dangling=*)
  2014  			COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) )
  2015  			return
  2016  			;;
  2017  	esac
  2018  
  2019  	case "$cur" in
  2020  		-*)
  2021  			COMPREPLY=( $( compgen -W "--filter -f --help --quiet -q" -- "$cur" ) )
  2022  			;;
  2023  	esac
  2024  }
  2025  
  2026  _docker_volume_rm() {
  2027  	case "$cur" in
  2028  		-*)
  2029  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  2030  			;;
  2031  		*)
  2032  			__docker_complete_volumes
  2033  			;;
  2034  	esac
  2035  }
  2036  
  2037  _docker_volume() {
  2038  	local subcommands="
  2039  		create
  2040  		inspect
  2041  		ls
  2042  		rm
  2043  	"
  2044  	__docker_subcommands "$subcommands" && return
  2045  
  2046  	case "$cur" in
  2047  		-*)
  2048  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  2049  			;;
  2050  		*)
  2051  			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
  2052  			;;
  2053  	esac
  2054  }
  2055  
  2056  _docker_wait() {
  2057  	case "$cur" in
  2058  		-*)
  2059  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  2060  			;;
  2061  		*)
  2062  			__docker_complete_containers_all
  2063  			;;
  2064  	esac
  2065  }
  2066  
  2067  _docker() {
  2068  	local previous_extglob_setting=$(shopt -p extglob)
  2069  	shopt -s extglob
  2070  
  2071  	local commands=(
  2072  		attach
  2073  		build
  2074  		commit
  2075  		cp
  2076  		create
  2077  		daemon
  2078  		diff
  2079  		events
  2080  		exec
  2081  		export
  2082  		history
  2083  		images
  2084  		import
  2085  		info
  2086  		inspect
  2087  		kill
  2088  		load
  2089  		login
  2090  		logout
  2091  		logs
  2092  		network
  2093  		pause
  2094  		port
  2095  		ps
  2096  		pull
  2097  		push
  2098  		rename
  2099  		restart
  2100  		rm
  2101  		rmi
  2102  		run
  2103  		save
  2104  		search
  2105  		start
  2106  		stats
  2107  		stop
  2108  		tag
  2109  		top
  2110  		unpause
  2111  		update
  2112  		version
  2113  		volume
  2114  		wait
  2115  	)
  2116  
  2117  	# These options are valid as global options for all client commands
  2118  	# and valid as command options for `docker daemon`
  2119  	local global_boolean_options="
  2120  		--debug -D
  2121  		--tls
  2122  		--tlsverify
  2123  	"
  2124  	local global_options_with_args="
  2125  		--config
  2126  		--host -H
  2127  		--log-level -l
  2128  		--tlscacert
  2129  		--tlscert
  2130  		--tlskey
  2131  	"
  2132  
  2133  	local host config
  2134  
  2135  	COMPREPLY=()
  2136  	local cur prev words cword
  2137  	_get_comp_words_by_ref -n : cur prev words cword
  2138  
  2139  	local command='docker' command_pos=0 subcommand_pos
  2140  	local counter=1
  2141  	while [ $counter -lt $cword ]; do
  2142  		case "${words[$counter]}" in
  2143  			# save host so that completion can use custom daemon
  2144  			--host|-H)
  2145  				(( counter++ ))
  2146  				host="${words[$counter]}"
  2147  				;;
  2148  			# save config so that completion can use custom configuration directories
  2149  			--config)
  2150  				(( counter++ ))
  2151  				config="${words[$counter]}"
  2152  				;;
  2153  			$(__docker_to_extglob "$global_options_with_args") )
  2154  				(( counter++ ))
  2155  				;;
  2156  			-*)
  2157  				;;
  2158  			=)
  2159  				(( counter++ ))
  2160  				;;
  2161  			*)
  2162  				command="${words[$counter]}"
  2163  				command_pos=$counter
  2164  				break
  2165  				;;
  2166  		esac
  2167  		(( counter++ ))
  2168  	done
  2169  
  2170  	local completions_func=_docker_${command}
  2171  	declare -F $completions_func >/dev/null && $completions_func
  2172  
  2173  	eval "$previous_extglob_setting"
  2174  	return 0
  2175  }
  2176  
  2177  eval "$__docker_previous_extglob_setting"
  2178  unset __docker_previous_extglob_setting
  2179  
  2180  complete -F _docker docker