github.com/rsampaio/docker@v0.7.2-0.20150827203920-fdc73cc3fc31/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  # You can tailor completion for the "events", "history", "inspect", "run",
    21  # "rmi" and "save" commands by settings the following environment
    22  # variables:
    23  #   
    24  # DOCKER_COMPLETION_SHOW_IMAGE_IDS
    25  #   "none" - Show names only (default)
    26  #   "non-intermediate" - Show names and ids, but omit intermediate image IDs
    27  #   "all" - Show names and ids, including intermediate image IDs
    28  # 
    29  # DOCKER_COMPLETION_SHOW_TAGS
    30  #   "yes" - include tags in completion options (default)
    31  #   "no"  - don't include tags in completion options
    32  
    33  #
    34  # Note:
    35  # Currently, the completions will not work if the docker daemon is not
    36  # bound to the default communication port/socket
    37  # If the docker daemon is using a unix socket for communication your user
    38  # must have access to the socket for the completions to function correctly
    39  #
    40  # Note for developers:
    41  # Please arrange options sorted alphabetically by long name with the short
    42  # options immediately following their corresponding long form.
    43  # This order should be applied to lists, alternatives and code blocks.
    44  
    45  __docker_q() {
    46  	docker ${host:+-H "$host"} ${config:+--config "$config"} 2>/dev/null "$@"
    47  }
    48  
    49  __docker_containers_all() {
    50  	local IFS=$'\n'
    51  	local containers=( $(__docker_q ps -aq --no-trunc) )
    52  	if [ "$1" ]; then
    53  		containers=( $(__docker_q inspect --format "{{if $1}}{{.Id}}{{end}}" "${containers[@]}") )
    54  	fi
    55  	local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") )
    56  	names=( "${names[@]#/}" ) # trim off the leading "/" from the container names
    57  	unset IFS
    58  	COMPREPLY=( $(compgen -W "${names[*]} ${containers[*]}" -- "$cur") )
    59  }
    60  
    61  __docker_containers_running() {
    62  	__docker_containers_all '.State.Running'
    63  }
    64  
    65  __docker_containers_stopped() {
    66  	__docker_containers_all 'not .State.Running'
    67  }
    68  
    69  __docker_containers_pauseable() {
    70  	__docker_containers_all 'and .State.Running (not .State.Paused)'
    71  }
    72  
    73  __docker_containers_unpauseable() {
    74  	__docker_containers_all '.State.Paused'
    75  }
    76  
    77  __docker_container_names() {
    78  	local containers=( $(__docker_q ps -aq --no-trunc) )
    79  	local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") )
    80  	names=( "${names[@]#/}" ) # trim off the leading "/" from the container names
    81  	COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") )
    82  }
    83  
    84  __docker_container_ids() {
    85  	local containers=( $(__docker_q ps -aq) )
    86  	COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") )
    87  }
    88  
    89  __docker_images() {
    90  	local images_args=""
    91  
    92  	case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in
    93  		all)
    94  			images_args="--no-trunc -a"
    95  			;;
    96  		non-intermediate)
    97  			images_args="--no-trunc"
    98  			;;
    99  	esac
   100  
   101  	local repo_print_command
   102  	if [ "${DOCKER_COMPLETION_SHOW_TAGS:-yes}" = "yes" ]; then
   103  		repo_print_command='print $1; print $1":"$2'
   104  	else
   105  		repo_print_command='print $1'
   106  	fi
   107  
   108  	local awk_script
   109  	case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in
   110  		all|non-intermediate)
   111  			awk_script='NR>1 { print $3; if ($1 != "<none>") { '"$repo_print_command"' } }'
   112  			;;
   113  		none|*)
   114  			awk_script='NR>1 && $1 != "<none>" { '"$repo_print_command"' }'
   115  			;;
   116  	esac
   117  
   118  	local images=$(__docker_q images $images_args | awk "$awk_script")
   119  	COMPREPLY=( $(compgen -W "$images" -- "$cur") )
   120  	__ltrim_colon_completions "$cur"
   121  }
   122  
   123  __docker_image_repos() {
   124  	local repos="$(__docker_q images | awk 'NR>1 && $1 != "<none>" { print $1 }')"
   125  	COMPREPLY=( $(compgen -W "$repos" -- "$cur") )
   126  }
   127  
   128  __docker_image_repos_and_tags() {
   129  	local reposAndTags="$(__docker_q images | awk 'NR>1 && $1 != "<none>" { print $1; print $1":"$2 }')"
   130  	COMPREPLY=( $(compgen -W "$reposAndTags" -- "$cur") )
   131  	__ltrim_colon_completions "$cur"
   132  }
   133  
   134  __docker_containers_and_images() {
   135  	__docker_containers_all
   136  	local containers=( "${COMPREPLY[@]}" )
   137  	__docker_images
   138  	COMPREPLY+=( "${containers[@]}" )
   139  }
   140  
   141  # Finds the position of the first word that is neither option nor an option's argument.
   142  # If there are options that require arguments, you should pass a glob describing those
   143  # options, e.g. "--option1|-o|--option2"
   144  # Use this function to restrict completions to exact positions after the argument list.
   145  __docker_pos_first_nonflag() {
   146  	local argument_flags=$1
   147  
   148  	local counter=$((command_pos + 1))
   149  	while [ $counter -le $cword ]; do
   150  		if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then
   151  			(( counter++ ))
   152  			# eat "=" in case of --option=arg syntax
   153  			[ "${words[$counter]}" = "=" ] && (( counter++ ))
   154  		else
   155  			case "${words[$counter]}" in
   156  				-*)
   157  					;;
   158  				*)
   159  					break
   160  					;;
   161  			esac
   162  		fi
   163  
   164  		# Bash splits words at "=", retaining "=" as a word, examples:
   165  		# "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words
   166  		while [ "${words[$counter + 1]}" = "=" ] ; do
   167  			counter=$(( counter + 2))
   168  		done
   169  
   170  		(( counter++ ))
   171  	done
   172  
   173  	echo $counter
   174  }
   175  
   176  # Returns the value of the first option matching option_glob.
   177  # Valid values for option_glob are option names like '--log-level' and
   178  # globs like '--log-level|-l'
   179  # Only positions between the command and the current word are considered.
   180  __docker_value_of_option() {
   181  	local option_glob=$1
   182  
   183  	local counter=$((command_pos + 1))
   184  	while [ $counter -lt $cword ]; do
   185  		case ${words[$counter]} in
   186  			@($option_glob) )
   187  				echo ${words[$counter + 1]}
   188  				break
   189  				;;
   190  		esac
   191  		(( counter++ ))
   192  	done
   193  }
   194  
   195  # Transforms a multiline list of strings into a single line string
   196  # with the words separated by "|".
   197  # This is used to prepare arguments to __docker_pos_first_nonflag().
   198  __docker_to_alternatives() {
   199  	local parts=( $1 )
   200  	local IFS='|'
   201  	echo "${parts[*]}"
   202  }
   203  
   204  # Transforms a multiline list of options into an extglob pattern
   205  # suitable for use in case statements.
   206  __docker_to_extglob() {
   207  	local extglob=$( __docker_to_alternatives "$1" )
   208  	echo "@($extglob)"
   209  }
   210  
   211  __docker_resolve_hostname() {
   212  	command -v host >/dev/null 2>&1 || return
   213  	COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') )
   214  }
   215  
   216  __docker_capabilities() {
   217  	# The list of capabilities is defined in types.go, ALL was added manually.
   218  	COMPREPLY=( $( compgen -W "
   219  		ALL
   220  		AUDIT_CONTROL
   221  		AUDIT_WRITE
   222  		AUDIT_READ
   223  		BLOCK_SUSPEND
   224  		CHOWN
   225  		DAC_OVERRIDE
   226  		DAC_READ_SEARCH
   227  		FOWNER
   228  		FSETID
   229  		IPC_LOCK
   230  		IPC_OWNER
   231  		KILL
   232  		LEASE
   233  		LINUX_IMMUTABLE
   234  		MAC_ADMIN
   235  		MAC_OVERRIDE
   236  		MKNOD
   237  		NET_ADMIN
   238  		NET_BIND_SERVICE
   239  		NET_BROADCAST
   240  		NET_RAW
   241  		SETFCAP
   242  		SETGID
   243  		SETPCAP
   244  		SETUID
   245  		SYS_ADMIN
   246  		SYS_BOOT
   247  		SYS_CHROOT
   248  		SYSLOG
   249  		SYS_MODULE
   250  		SYS_NICE
   251  		SYS_PACCT
   252  		SYS_PTRACE
   253  		SYS_RAWIO
   254  		SYS_RESOURCE
   255  		SYS_TIME
   256  		SYS_TTY_CONFIG
   257  		WAKE_ALARM
   258  	" -- "$cur" ) )
   259  }
   260  
   261  __docker_log_drivers() {
   262  	COMPREPLY=( $( compgen -W "
   263  		fluentd
   264  		gelf
   265  		journald
   266  		json-file
   267  		none
   268  		syslog
   269  	" -- "$cur" ) )
   270  }
   271  
   272  __docker_log_driver_options() {
   273  	# see docs/reference/logging/index.md
   274  	local fluentd_options="fluentd-address fluentd-tag"
   275  	local gelf_options="gelf-address gelf-tag"
   276  	local json_file_options="max-file max-size"
   277  	local syslog_options="syslog-address syslog-facility syslog-tag"
   278  
   279  	case $(__docker_value_of_option --log-driver) in
   280  		'')
   281  			COMPREPLY=( $( compgen -W "$fluentd_options $gelf_options $json_file_options $syslog_options" -S = -- "$cur" ) )
   282  			;;
   283  		fluentd)
   284  			COMPREPLY=( $( compgen -W "$fluentd_options" -S = -- "$cur" ) )
   285  			;;
   286  		gelf)
   287  			COMPREPLY=( $( compgen -W "$gelf_options" -S = -- "$cur" ) )
   288  			;;
   289  		json-file)
   290  			COMPREPLY=( $( compgen -W "$json_file_options" -S = -- "$cur" ) )
   291  			;;
   292  		syslog)
   293  			COMPREPLY=( $( compgen -W "$syslog_options" -S = -- "$cur" ) )
   294  			;;
   295  		*)
   296  			return
   297  			;;
   298  	esac
   299  
   300  	compopt -o nospace
   301  }
   302  
   303  __docker_complete_log_driver_options() {
   304  	# "=" gets parsed to a word and assigned to either $cur or $prev depending on whether
   305  	# it is the last character or not. So we search for "xxx=" in the the last two words.
   306  	case "${words[$cword-2]}$prev=" in
   307  		*gelf-address=*)
   308  			COMPREPLY=( $( compgen -W "udp" -S "://" -- "${cur#=}" ) )
   309  			compopt -o nospace
   310  			return
   311  			;;
   312  		*syslog-address=*)
   313  			COMPREPLY=( $( compgen -W "tcp udp unix" -S "://" -- "${cur#=}" ) )
   314  			compopt -o nospace
   315  			return
   316  			;;
   317  		*syslog-facility=*)
   318  			COMPREPLY=( $( compgen -W "
   319  				auth
   320  				authpriv
   321  				cron
   322  				daemon
   323  				ftp
   324  				kern
   325  				local0
   326  				local1
   327  				local2
   328  				local3
   329  				local4
   330  				local5
   331  				local6
   332  				local7
   333  				lpr
   334  				mail
   335  				news
   336  				syslog
   337  				user
   338  				uucp
   339  			" -- "${cur#=}" ) )
   340  			return
   341  			;;
   342  	esac
   343  	return 1
   344  }
   345  
   346  __docker_log_levels() {
   347  	COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) )
   348  }
   349  
   350  # a selection of the available signals that is most likely of interest in the
   351  # context of docker containers.
   352  __docker_signals() {
   353  	local signals=(
   354  		SIGCONT
   355  		SIGHUP
   356  		SIGINT
   357  		SIGKILL
   358  		SIGQUIT
   359  		SIGSTOP
   360  		SIGTERM
   361  		SIGUSR1
   362  		SIGUSR2
   363  	)
   364  	COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo $cur | tr '[:lower:]' '[:upper:]')" ) )
   365  }
   366  
   367  # global options that may appear after the docker command
   368  _docker_docker() {
   369  	local boolean_options="
   370  		$global_boolean_options
   371  		--help
   372  		--version -v
   373  	"
   374  
   375  	case "$prev" in
   376  		--config)
   377  			_filedir -d
   378  			return
   379  			;;
   380  		--log-level|-l)
   381  			__docker_log_levels
   382  			return
   383  			;;
   384  		$(__docker_to_extglob "$global_options_with_args") )
   385  			return
   386  			;;
   387  	esac
   388  
   389  	case "$cur" in
   390  		-*)
   391  			COMPREPLY=( $( compgen -W "$boolean_options $global_options_with_args" -- "$cur" ) )
   392  			;;
   393  		*)
   394  			local counter=$( __docker_pos_first_nonflag $(__docker_to_extglob "$global_options_with_args") )
   395  			if [ $cword -eq $counter ]; then
   396  				COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) )
   397  			fi
   398  			;;
   399  	esac
   400  }
   401  
   402  _docker_attach() {
   403  	case "$cur" in
   404  		-*)
   405  			COMPREPLY=( $( compgen -W "--help --no-stdin --sig-proxy" -- "$cur" ) )
   406  			;;
   407  		*)
   408  			local counter="$(__docker_pos_first_nonflag)"
   409  			if [ $cword -eq $counter ]; then
   410  				__docker_containers_running
   411  			fi
   412  			;;
   413  	esac
   414  }
   415  
   416  _docker_build() {
   417  	case "$prev" in
   418  		--cgroup-parent|--cpuset-cpus|--cpuset-mems|--cpu-shares|-c|--cpu-period|--cpu-quota|--memory|-m|--memory-swap)
   419  			return
   420  			;;
   421  		--file|-f)
   422  			_filedir
   423  			return
   424  			;;
   425  		--tag|-t)
   426  			__docker_image_repos_and_tags
   427  			return
   428  			;;
   429  	esac
   430  
   431  	case "$cur" in
   432  		-*)
   433  			COMPREPLY=( $( compgen -W "--cgroup-parent --cpuset-cpus --cpuset-mems --cpu-shares -c --cpu-period --cpu-quota --file -f --force-rm --help --memory -m --memory-swap --no-cache --pull --quiet -q --rm --tag -t --ulimit" -- "$cur" ) )
   434  			;;
   435  		*)
   436  			local counter="$(__docker_pos_first_nonflag '--cgroup-parent|--cpuset-cpus|--cpuset-mems|--cpu-shares|-c|--cpu-period|--cpu-quota|--file|-f|--memory|-m|--memory-swap|--tag|-t')"
   437  			if [ $cword -eq $counter ]; then
   438  				_filedir -d
   439  			fi
   440  			;;
   441  	esac
   442  }
   443  
   444  _docker_commit() {
   445  	case "$prev" in
   446  		--author|-a|--change|-c|--message|-m)
   447  			return
   448  			;;
   449  	esac
   450  
   451  	case "$cur" in
   452  		-*)
   453  			COMPREPLY=( $( compgen -W "--author -a --change -c --help --message -m --pause -p" -- "$cur" ) )
   454  			;;
   455  		*)
   456  			local counter=$(__docker_pos_first_nonflag '--author|-a|--change|-c|--message|-m')
   457  
   458  			if [ $cword -eq $counter ]; then
   459  				__docker_containers_all
   460  				return
   461  			fi
   462  			(( counter++ ))
   463  
   464  			if [ $cword -eq $counter ]; then
   465  				__docker_image_repos_and_tags
   466  				return
   467  			fi
   468  			;;
   469  	esac
   470  }
   471  
   472  _docker_cp() {
   473  	case "$cur" in
   474  		-*)
   475  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
   476  			;;
   477  		*)
   478  			local counter=$(__docker_pos_first_nonflag)
   479  			if [ $cword -eq $counter ]; then
   480  				case "$cur" in
   481  					*:)
   482  						return
   483  						;;
   484  					*)
   485  						__docker_containers_all
   486  						COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
   487  						compopt -o nospace
   488  						return
   489  						;;
   490  				esac
   491  			fi
   492  			(( counter++ ))
   493  
   494  			if [ $cword -eq $counter ]; then
   495  				_filedir -d
   496  				return
   497  			fi
   498  			;;
   499  	esac
   500  }
   501  
   502  _docker_create() {
   503  	_docker_run
   504  }
   505  
   506  _docker_daemon() {
   507  	local boolean_options="
   508  		$global_boolean_options
   509  		--help
   510  		--icc=false
   511  		--ip-forward=false
   512  		--ip-masq=false
   513  		--iptables=false
   514  		--ipv6
   515  		--selinux-enabled
   516  		--userland-proxy=false
   517  	"
   518  	local options_with_args="
   519  		$global_options_with_args
   520  		--api-cors-header
   521  		--bip
   522  		--bridge -b
   523  		--default-gateway
   524  		--default-gateway-v6
   525  		--default-ulimit
   526  		--dns
   527  		--dns-search
   528  		--exec-driver -e
   529  		--exec-opt
   530  		--exec-root
   531  		--fixed-cidr
   532  		--fixed-cidr-v6
   533  		--graph -g
   534  		--group -G
   535  		--insecure-registry
   536  		--ip
   537  		--label
   538  		--log-driver
   539  		--log-opt
   540  		--mtu
   541  		--pidfile -p
   542  		--registry-mirror
   543  		--storage-driver -s
   544  		--storage-opt
   545  	"
   546  
   547  	case "$prev" in
   548  		--exec-root|--graph|-g)
   549  			_filedir -d
   550  			return
   551  			;;
   552  		--log-driver)
   553  			__docker_log_drivers
   554  			return
   555  			;;
   556  		--pidfile|-p|--tlscacert|--tlscert|--tlskey)
   557  			_filedir
   558  			return
   559  			;;
   560  		--storage-driver|-s)
   561  			COMPREPLY=( $( compgen -W "aufs btrfs devicemapper overlay vfs zfs" -- "$(echo $cur | tr '[:upper:]' '[:lower:]')" ) )
   562  			return
   563  			;;
   564  		--storage-opt)
   565  			local devicemapper_options="
   566  				dm.basesize
   567  				dm.blkdiscard
   568  				dm.blocksize
   569  				dm.fs
   570  				dm.loopdatasize
   571  				dm.loopmetadatasize
   572  				dm.mkfsarg
   573  				dm.mountopt
   574  				dm.override_udev_sync_check
   575  				dm.thinpooldev
   576  			"
   577  			local zfs_options="zfs.fsname"
   578  
   579  			case $(__docker_value_of_option '--storage-driver|-s') in
   580  				'')
   581  					COMPREPLY=( $( compgen -W "$devicemapper_options $zfs_options" -S = -- "$cur" ) )
   582  					;;
   583  				devicemapper)
   584  					COMPREPLY=( $( compgen -W "$devicemapper_options" -S = -- "$cur" ) )
   585  					;;
   586  				zfs)
   587  					COMPREPLY=( $( compgen -W "$zfs_options" -S = -- "$cur" ) )
   588  					;;
   589  				*)
   590  					return
   591  					;;
   592  			esac
   593  			compopt -o nospace
   594  			return
   595  			;;
   596  		--log-level|-l)
   597  			__docker_log_levels
   598  			return
   599  			;;
   600  		--log-opt)
   601  			__docker_log_driver_options
   602  			return
   603  			;;
   604  		$(__docker_to_extglob "$options_with_args") )
   605  			return
   606  			;;
   607  	esac
   608  
   609  	__docker_complete_log_driver_options && return
   610  
   611  	# completions for --storage-opt
   612  	case "${words[$cword-2]}$prev=" in
   613  		*dm.blkdiscard=*)
   614  			COMPREPLY=( $( compgen -W "false true" -- "${cur#=}" ) )
   615  			return
   616  			;;
   617  		*dm.fs=*)
   618  			COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur#=}" ) )
   619  			return
   620  			;;
   621  		*dm.override_udev_sync_check=*)
   622  			COMPREPLY=( $( compgen -W "false true" -- "${cur#=}" ) )
   623  			return
   624  			;;
   625  		*dm.thinpooldev=*)
   626  			_filedir
   627  			return
   628  			;;
   629  	esac
   630  
   631  	case "$cur" in
   632  		-*)
   633  			COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) )
   634  			;;
   635  	esac
   636  }
   637  
   638  _docker_diff() {
   639  	case "$cur" in
   640  		-*)
   641  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
   642  			;;
   643  		*)
   644  			local counter=$(__docker_pos_first_nonflag)
   645  			if [ $cword -eq $counter ]; then
   646  				__docker_containers_all
   647  			fi
   648  			;;
   649  	esac
   650  }
   651  
   652  _docker_events() {
   653  	case "$prev" in
   654  		--filter|-f)
   655  			COMPREPLY=( $( compgen -S = -W "container event image" -- "$cur" ) )
   656  			compopt -o nospace
   657  			return
   658  			;;
   659  		--since|--until)
   660  			return
   661  			;;
   662  	esac
   663  
   664  	case "${words[$cword-2]}$prev=" in
   665  		*container=*)
   666  			cur="${cur#=}"
   667  			__docker_containers_all
   668  			return
   669  			;;
   670  		*event=*)
   671  			COMPREPLY=( $( compgen -W "
   672  				attach
   673  				commit
   674  				copy
   675  				create
   676  				delete
   677  				destroy
   678  				die
   679  				exec_create
   680  				exec_start
   681  				export
   682  				import
   683  				kill
   684  				oom
   685  				pause
   686  				pull
   687  				push
   688  				rename
   689  				resize
   690  				restart
   691  				start
   692  				stop
   693  				tag
   694  				top
   695  				unpause
   696  				untag
   697  			" -- "${cur#=}" ) )
   698  			return
   699  			;;
   700  		*image=*)
   701  			cur="${cur#=}"
   702  			__docker_images
   703  			return
   704  			;;
   705  	esac
   706  
   707  	case "$cur" in
   708  		-*)
   709  			COMPREPLY=( $( compgen -W "--filter -f --help --since --until" -- "$cur" ) )
   710  			;;
   711  	esac
   712  }
   713  
   714  _docker_exec() {
   715  	case "$prev" in
   716  		--user|-u)
   717  			return
   718  			;;
   719  	esac
   720  
   721  	case "$cur" in
   722  		-*)
   723  			COMPREPLY=( $( compgen -W "--detach -d --help --interactive -i --privileged -t --tty -u --user" -- "$cur" ) )
   724  			;;
   725  		*)
   726  			__docker_containers_running
   727  			;;
   728  	esac
   729  }
   730  
   731  _docker_export() {
   732  	case "$cur" in
   733  		-*)
   734  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
   735  			;;
   736  		*)
   737  			local counter=$(__docker_pos_first_nonflag)
   738  			if [ $cword -eq $counter ]; then
   739  				__docker_containers_all
   740  			fi
   741  			;;
   742  	esac
   743  }
   744  
   745  _docker_help() {
   746  	local counter=$(__docker_pos_first_nonflag)
   747  	if [ $cword -eq $counter ]; then
   748  		COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
   749  	fi
   750  }
   751  
   752  _docker_history() {
   753  	case "$cur" in
   754  		-*)
   755  			COMPREPLY=( $( compgen -W "--help --no-trunc --quiet -q" -- "$cur" ) )
   756  			;;
   757  		*)
   758  			local counter=$(__docker_pos_first_nonflag)
   759  			if [ $cword -eq $counter ]; then
   760  				__docker_images
   761  			fi
   762  			;;
   763  	esac
   764  }
   765  
   766  _docker_images() {
   767  	case "$prev" in
   768  		--filter|-f)
   769  			COMPREPLY=( $( compgen -W "dangling=true label=" -- "$cur" ) )
   770  			if [ "$COMPREPLY" = "label=" ]; then
   771  				compopt -o nospace
   772  			fi
   773  			return
   774  			;;
   775  	esac
   776  
   777  	case "${words[$cword-2]}$prev=" in
   778  		*dangling=*)
   779  			COMPREPLY=( $( compgen -W "true false" -- "${cur#=}" ) )
   780  			return
   781  			;;
   782  		*label=*)
   783  			return
   784  			;;
   785  	esac
   786  
   787  	case "$cur" in
   788  		-*)
   789  			COMPREPLY=( $( compgen -W "--all -a --digests --filter -f --help --no-trunc --quiet -q" -- "$cur" ) )
   790  			;;
   791  		=)
   792  			return
   793  			;;
   794  		*)
   795  			__docker_image_repos
   796  			;;
   797  	esac
   798  }
   799  
   800  _docker_import() {
   801  	case "$cur" in
   802  		-*)
   803  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
   804  			;;
   805  		*)
   806  			local counter=$(__docker_pos_first_nonflag)
   807  			if [ $cword -eq $counter ]; then
   808  				return
   809  			fi
   810  			(( counter++ ))
   811  
   812  			if [ $cword -eq $counter ]; then
   813  				__docker_image_repos_and_tags
   814  				return
   815  			fi
   816  			;;
   817  	esac
   818  }
   819  
   820  _docker_info() {
   821  	case "$cur" in
   822  		-*)
   823  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
   824  			;;
   825  	esac
   826  }
   827  
   828  _docker_inspect() {
   829  	case "$prev" in
   830  		--format|-f)
   831  			return
   832  			;;
   833  		--type)
   834                       COMPREPLY=( $( compgen -W "image container" -- "$cur" ) )
   835                       return
   836                          ;;
   837  
   838  	esac
   839  
   840  	case "$cur" in
   841  		-*)
   842  			COMPREPLY=( $( compgen -W "--format -f --type --help" -- "$cur" ) )
   843  			;;
   844  		*)
   845  			case $(__docker_value_of_option --type) in
   846  				'')
   847  					__docker_containers_and_images
   848  					;;
   849  				container)
   850  					__docker_containers_all
   851  					;;
   852  				image)
   853  					__docker_images
   854  					;;
   855  			esac
   856  	esac
   857  }
   858  
   859  _docker_kill() {
   860  	case "$prev" in
   861  		--signal|-s)
   862  			__docker_signals
   863  			return
   864  			;;
   865  	esac
   866  
   867  	case "$cur" in
   868  		-*)
   869  			COMPREPLY=( $( compgen -W "--help --signal -s" -- "$cur" ) )
   870  			;;
   871  		*)
   872  			__docker_containers_running
   873  			;;
   874  	esac
   875  }
   876  
   877  _docker_load() {
   878  	case "$prev" in
   879  		--input|-i)
   880  			_filedir
   881  			return
   882  			;;
   883  	esac
   884  
   885  	case "$cur" in
   886  		-*)
   887  			COMPREPLY=( $( compgen -W "--help --input -i" -- "$cur" ) )
   888  			;;
   889  	esac
   890  }
   891  
   892  _docker_login() {
   893  	case "$prev" in
   894  		--email|-e|--password|-p|--username|-u)
   895  			return
   896  			;;
   897  	esac
   898  
   899  	case "$cur" in
   900  		-*)
   901  			COMPREPLY=( $( compgen -W "--email -e --help --password -p --username -u" -- "$cur" ) )
   902  			;;
   903  	esac
   904  }
   905  
   906  _docker_logout() {
   907  	case "$cur" in
   908  		-*)
   909  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
   910  			;;
   911  	esac
   912  }
   913  
   914  _docker_logs() {
   915  	case "$prev" in
   916  		--since|--tail)
   917  			return
   918  			;;
   919  	esac
   920  
   921  	case "$cur" in
   922  		-*)
   923  			COMPREPLY=( $( compgen -W "--follow -f --help --since --tail --timestamps -t" -- "$cur" ) )
   924  			;;
   925  		*)
   926  			local counter=$(__docker_pos_first_nonflag '--tail')
   927  			if [ $cword -eq $counter ]; then
   928  				__docker_containers_all
   929  			fi
   930  			;;
   931  	esac
   932  }
   933  
   934  _docker_pause() {
   935  	case "$cur" in
   936  		-*)
   937  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
   938  			;;
   939  		*)
   940  			local counter=$(__docker_pos_first_nonflag)
   941  			if [ $cword -eq $counter ]; then
   942  				__docker_containers_pauseable
   943  			fi
   944  			;;
   945  	esac
   946  }
   947  
   948  _docker_port() {
   949  	case "$cur" in
   950  		-*)
   951  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
   952  			;;
   953  		*)
   954  			local counter=$(__docker_pos_first_nonflag)
   955  			if [ $cword -eq $counter ]; then
   956  				__docker_containers_all
   957  			fi
   958  			;;
   959  	esac
   960  }
   961  
   962  _docker_ps() {
   963  	case "$prev" in
   964  		--before|--since)
   965  			__docker_containers_all
   966  			;;
   967  		--filter|-f)
   968  			COMPREPLY=( $( compgen -S = -W "exited id label name status" -- "$cur" ) )
   969  			compopt -o nospace
   970  			return
   971  			;;
   972  		--format|-n)
   973  			return
   974  			;;
   975  	esac
   976  
   977  	case "${words[$cword-2]}$prev=" in
   978  		*id=*)
   979  			cur="${cur#=}"
   980  			__docker_container_ids
   981  			return
   982  			;;
   983  		*name=*)
   984  			cur="${cur#=}"
   985  			__docker_container_names
   986  			return
   987  			;;
   988  		*status=*)
   989  			COMPREPLY=( $( compgen -W "exited paused restarting running" -- "${cur#=}" ) )
   990  			return
   991  			;;
   992  	esac
   993  
   994  	case "$cur" in
   995  		-*)
   996  			COMPREPLY=( $( compgen -W "--all -a --before --filter -f --format --help --latest -l -n --no-trunc --quiet -q --size -s --since" -- "$cur" ) )
   997  			;;
   998  	esac
   999  }
  1000  
  1001  _docker_pull() {
  1002  	case "$cur" in
  1003  		-*)
  1004  			COMPREPLY=( $( compgen -W "--all-tags -a --help" -- "$cur" ) )
  1005  			;;
  1006  		*)
  1007  			local counter=$(__docker_pos_first_nonflag)
  1008  			if [ $cword -eq $counter ]; then
  1009  				for arg in "${COMP_WORDS[@]}"; do
  1010  					case "$arg" in
  1011  						--all-tags|-a)
  1012  							__docker_image_repos
  1013  							return
  1014  							;;
  1015  					esac
  1016  				done
  1017  				__docker_image_repos_and_tags
  1018  			fi
  1019  			;;
  1020  	esac
  1021  }
  1022  
  1023  _docker_push() {
  1024  	case "$cur" in
  1025  		-*)
  1026  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1027  			;;
  1028  		*)
  1029  			local counter=$(__docker_pos_first_nonflag)
  1030  			if [ $cword -eq $counter ]; then
  1031  				__docker_image_repos_and_tags
  1032  			fi
  1033  			;;
  1034  	esac
  1035  }
  1036  
  1037  _docker_rename() {
  1038  	case "$cur" in
  1039  		-*)
  1040  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1041  			;;
  1042  		*)
  1043  			local counter=$(__docker_pos_first_nonflag)
  1044  			if [ $cword -eq $counter ]; then
  1045  				__docker_containers_all
  1046  			fi
  1047  			;;
  1048  	esac
  1049  }
  1050  
  1051  _docker_restart() {
  1052  	case "$prev" in
  1053  		--time|-t)
  1054  			return
  1055  			;;
  1056  	esac
  1057  
  1058  	case "$cur" in
  1059  		-*)
  1060  			COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) )
  1061  			;;
  1062  		*)
  1063  			__docker_containers_all
  1064  			;;
  1065  	esac
  1066  }
  1067  
  1068  _docker_rm() {
  1069  	case "$cur" in
  1070  		-*)
  1071  			COMPREPLY=( $( compgen -W "--force -f --help --link -l --volumes -v" -- "$cur" ) )
  1072  			;;
  1073  		*)
  1074  			for arg in "${COMP_WORDS[@]}"; do
  1075  				case "$arg" in
  1076  					--force|-f)
  1077  						__docker_containers_all
  1078  						return
  1079  						;;
  1080  				esac
  1081  			done
  1082  			__docker_containers_stopped
  1083  			;;
  1084  	esac
  1085  }
  1086  
  1087  _docker_rmi() {
  1088  	case "$cur" in
  1089  		-*)
  1090  			COMPREPLY=( $( compgen -W "--force -f --help --no-prune" -- "$cur" ) )
  1091  			;;
  1092  		*)
  1093  			__docker_images
  1094  			;;
  1095  	esac
  1096  }
  1097  
  1098  _docker_run() {
  1099  	local options_with_args="
  1100  		--add-host
  1101  		--attach -a
  1102  		--blkio-weight
  1103  		--cap-add
  1104  		--cap-drop
  1105  		--cgroup-parent
  1106  		--cidfile
  1107  		--cpu-period
  1108  		--cpu-quota
  1109  		--cpuset-cpus
  1110  		--cpuset-mems
  1111  		--cpu-shares -c
  1112  		--device
  1113  		--dns
  1114  		--dns-search
  1115  		--entrypoint
  1116  		--env -e
  1117  		--env-file
  1118  		--expose
  1119  		--group-add
  1120  		--hostname -h
  1121  		--ipc
  1122  		--kernel-memory
  1123  		--label-file
  1124  		--label -l
  1125  		--link
  1126  		--log-driver
  1127  		--log-opt
  1128  		--lxc-conf
  1129  		--mac-address
  1130  		--memory -m
  1131  		--memory-swap
  1132  		--memory-swappiness
  1133  		--name
  1134  		--net
  1135  		--pid
  1136  		--publish -p
  1137  		--restart
  1138  		--security-opt
  1139  		--ulimit
  1140  		--user -u
  1141  		--uts
  1142  		--volumes-from
  1143  		--volume -v
  1144  		--workdir -w
  1145  	"
  1146  
  1147  	local all_options="$options_with_args
  1148  		--disable-content-trust=false
  1149  		--help
  1150  		--interactive -i
  1151  		--oom-kill-disable
  1152  		--privileged
  1153  		--publish-all -P
  1154  		--read-only
  1155  		--tty -t
  1156  	"
  1157  
  1158  	[ "$command" = "run" ] && all_options="$all_options
  1159  		--detach -d
  1160  		--rm
  1161  		--sig-proxy=false
  1162  	"
  1163  
  1164  	local options_with_args_glob=$(__docker_to_extglob "$options_with_args")
  1165  
  1166  	case "$prev" in
  1167  		--add-host)
  1168  			case "$cur" in
  1169  				*:)
  1170  					__docker_resolve_hostname
  1171  					return
  1172  					;;
  1173  			esac
  1174  			;;
  1175  		--attach|-a)
  1176  			COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) )
  1177  			return
  1178  			;;
  1179  		--cap-add|--cap-drop)
  1180  			__docker_capabilities
  1181  			return
  1182  			;;
  1183  		--cidfile|--env-file|--label-file)
  1184  			_filedir
  1185  			return
  1186  			;;
  1187  		--device|--volume|-v)
  1188  			case "$cur" in
  1189  				*:*)
  1190  					# TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine)
  1191  					;;
  1192  				'')
  1193  					COMPREPLY=( $( compgen -W '/' -- "$cur" ) )
  1194  					compopt -o nospace
  1195  					;;
  1196  				/*)
  1197  					_filedir
  1198  					compopt -o nospace
  1199  					;;
  1200  			esac
  1201  			return
  1202  			;;
  1203  		--env|-e)
  1204  			COMPREPLY=( $( compgen -e -- "$cur" ) )
  1205  			compopt -o nospace
  1206  			return
  1207  			;;
  1208  		--ipc)
  1209  			case "$cur" in
  1210  				*:*)
  1211  					cur="${cur#*:}"
  1212  					__docker_containers_running
  1213  					;;
  1214  				*)
  1215  					COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) )
  1216  					if [ "$COMPREPLY" = "container:" ]; then
  1217  						compopt -o nospace
  1218  					fi
  1219  					;;
  1220  			esac
  1221  			return
  1222  			;;
  1223  		--link)
  1224  			case "$cur" in
  1225  				*:*)
  1226  					;;
  1227  				*)
  1228  					__docker_containers_running
  1229  					COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
  1230  					compopt -o nospace
  1231  					;;
  1232  			esac
  1233  			return
  1234  			;;
  1235  		--log-driver)
  1236  			__docker_log_drivers
  1237  			return
  1238  			;;
  1239  		--log-opt)
  1240  			__docker_log_driver_options
  1241  			return
  1242  			;;
  1243  		--net)
  1244  			case "$cur" in
  1245  				container:*)
  1246  					local cur=${cur#*:}
  1247  					__docker_containers_all
  1248  					;;
  1249  				*)
  1250  					COMPREPLY=( $( compgen -W "bridge none container: host" -- "$cur") )
  1251  					if [ "${COMPREPLY[*]}" = "container:" ] ; then
  1252  						compopt -o nospace
  1253  					fi
  1254  					;;
  1255  			esac
  1256  			return
  1257  			;;
  1258  		--restart)
  1259  			case "$cur" in
  1260  				on-failure:*)
  1261  					;;
  1262  				*)
  1263  					COMPREPLY=( $( compgen -W "no on-failure on-failure: always" -- "$cur") )
  1264  					;;
  1265  			esac
  1266  			return
  1267  			;;
  1268  		--security-opt)
  1269  			case "$cur" in
  1270  				label:*:*)
  1271  					;;
  1272  				label:*)
  1273  					local cur=${cur##*:}
  1274  					COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "$cur") )
  1275  					if [ "${COMPREPLY[*]}" != "disable" ] ; then
  1276  						compopt -o nospace
  1277  					fi
  1278  					;;
  1279  				*)
  1280  					COMPREPLY=( $( compgen -W "label apparmor" -S ":" -- "$cur") )
  1281  					compopt -o nospace
  1282  					;;
  1283  			esac
  1284  			return
  1285  			;;
  1286  		--volumes-from)
  1287  			__docker_containers_all
  1288  			return
  1289  			;;
  1290  		$options_with_args_glob )
  1291  			return
  1292  			;;
  1293  	esac
  1294  
  1295  	__docker_complete_log_driver_options && return
  1296  
  1297  	case "$cur" in
  1298  		-*)
  1299  			COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) )
  1300  			;;
  1301  		*)
  1302  			local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) )
  1303  			if [ $cword -eq $counter ]; then
  1304  				__docker_images
  1305  			fi
  1306  			;;
  1307  	esac
  1308  }
  1309  
  1310  _docker_save() {
  1311  	case "$prev" in
  1312  		--output|-o)
  1313  			_filedir
  1314  			return
  1315  			;;
  1316  	esac
  1317  
  1318  	case "$cur" in
  1319  		-*)
  1320  			COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) )
  1321  			;;
  1322  		*)
  1323  			__docker_images
  1324  			;;
  1325  	esac
  1326  }
  1327  
  1328  _docker_search() {
  1329  	case "$prev" in
  1330  		--stars|-s)
  1331  			return
  1332  			;;
  1333  	esac
  1334  
  1335  	case "$cur" in
  1336  		-*)
  1337  			COMPREPLY=( $( compgen -W "--automated --help --no-trunc --stars -s" -- "$cur" ) )
  1338  			;;
  1339  	esac
  1340  }
  1341  
  1342  _docker_start() {
  1343  	case "$cur" in
  1344  		-*)
  1345  			COMPREPLY=( $( compgen -W "--attach -a --help --interactive -i" -- "$cur" ) )
  1346  			;;
  1347  		*)
  1348  			__docker_containers_stopped
  1349  			;;
  1350  	esac
  1351  }
  1352  
  1353  _docker_stats() {
  1354  	case "$cur" in
  1355  		-*)
  1356  			COMPREPLY=( $( compgen -W "--no-stream --help" -- "$cur" ) )
  1357  			;;
  1358  		*)
  1359  			__docker_containers_running
  1360  			;;
  1361  	esac
  1362  }
  1363  
  1364  _docker_stop() {
  1365  	case "$prev" in
  1366  		--time|-t)
  1367  			return
  1368  			;;
  1369  	esac
  1370  
  1371  	case "$cur" in
  1372  		-*)
  1373  			COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) )
  1374  			;;
  1375  		*)
  1376  			__docker_containers_running
  1377  			;;
  1378  	esac
  1379  }
  1380  
  1381  _docker_tag() {
  1382  	case "$cur" in
  1383  		-*)
  1384  			COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) )
  1385  			;;
  1386  		*)
  1387  			local counter=$(__docker_pos_first_nonflag)
  1388  
  1389  			if [ $cword -eq $counter ]; then
  1390  				__docker_image_repos_and_tags
  1391  				return
  1392  			fi
  1393  			(( counter++ ))
  1394  
  1395  			if [ $cword -eq $counter ]; then
  1396  				__docker_image_repos_and_tags
  1397  				return
  1398  			fi
  1399  			;;
  1400  	esac
  1401  }
  1402  
  1403  _docker_unpause() {
  1404  	case "$cur" in
  1405  		-*)
  1406  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1407  			;;
  1408  		*)
  1409  			local counter=$(__docker_pos_first_nonflag)
  1410  			if [ $cword -eq $counter ]; then
  1411  				__docker_containers_unpauseable
  1412  			fi
  1413  			;;
  1414  	esac
  1415  }
  1416  
  1417  _docker_top() {
  1418  	case "$cur" in
  1419  		-*)
  1420  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1421  			;;
  1422  		*)
  1423  			local counter=$(__docker_pos_first_nonflag)
  1424  			if [ $cword -eq $counter ]; then
  1425  				__docker_containers_running
  1426  			fi
  1427  			;;
  1428  	esac
  1429  }
  1430  
  1431  _docker_version() {
  1432  	case "$cur" in
  1433  		-*)
  1434  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1435  			;;
  1436  	esac
  1437  }
  1438  
  1439  _docker_wait() {
  1440  	case "$cur" in
  1441  		-*)
  1442  			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  1443  			;;
  1444  		*)
  1445  			__docker_containers_all
  1446  			;;
  1447  	esac
  1448  }
  1449  
  1450  _docker() {
  1451  	local previous_extglob_setting=$(shopt -p extglob)
  1452  	shopt -s extglob
  1453  
  1454  	local commands=(
  1455  		attach
  1456  		build
  1457  		commit
  1458  		cp
  1459  		create
  1460  		daemon
  1461  		diff
  1462  		events
  1463  		exec
  1464  		export
  1465  		history
  1466  		images
  1467  		import
  1468  		info
  1469  		inspect
  1470  		kill
  1471  		load
  1472  		login
  1473  		logout
  1474  		logs
  1475  		pause
  1476  		port
  1477  		ps
  1478  		pull
  1479  		push
  1480  		rename
  1481  		restart
  1482  		rm
  1483  		rmi
  1484  		run
  1485  		save
  1486  		search
  1487  		start
  1488  		stats
  1489  		stop
  1490  		tag
  1491  		top
  1492  		unpause
  1493  		version
  1494  		wait
  1495  	)
  1496  
  1497  	# These options are valid as global options for all client commands
  1498  	# and valid as command options for `docker daemon`
  1499  	local global_boolean_options="
  1500  		--debug -D
  1501  		--tls
  1502  		--tlsverify
  1503  	"
  1504  	local global_options_with_args="
  1505  		--config
  1506  		--host -H
  1507  		--log-level -l
  1508  		--tlscacert
  1509  		--tlscert
  1510  		--tlskey
  1511  	"
  1512  
  1513  	local host config
  1514  
  1515  	COMPREPLY=()
  1516  	local cur prev words cword
  1517  	_get_comp_words_by_ref -n : cur prev words cword
  1518  
  1519  	local command='docker' command_pos=0
  1520  	local counter=1
  1521  	while [ $counter -lt $cword ]; do
  1522  		case "${words[$counter]}" in
  1523  			# save host so that completion can use custom daemon
  1524  			--host|-H)
  1525  				(( counter++ ))
  1526  				host="${words[$counter]}"
  1527  				;;
  1528  			# save config so that completion can use custom configuration directories
  1529  			--config)
  1530  				(( counter++ ))
  1531  				config="${words[$counter]}"
  1532  				;;
  1533  			$(__docker_to_extglob "$global_options_with_args") )
  1534  				(( counter++ ))
  1535  				;;
  1536  			-*)
  1537  				;;
  1538  			=)
  1539  				(( counter++ ))
  1540  				;;
  1541  			*)
  1542  				command="${words[$counter]}"
  1543  				command_pos=$counter
  1544  				break
  1545  				;;
  1546  		esac
  1547  		(( counter++ ))
  1548  	done
  1549  
  1550  	local completions_func=_docker_${command}
  1551  	declare -F $completions_func >/dev/null && $completions_func
  1552  
  1553  	eval "$previous_extglob_setting"
  1554  	return 0
  1555  }
  1556  
  1557  complete -F _docker docker