1#!/usr/bin/env bash
2# shellcheck disable=SC2016,SC2119,SC2155,SC2206,SC2207
3#
4# Shellcheck ignore list:
5#  - SC2016: Expressions don't expand in single quotes, use double quotes for that.
6#  - SC2119: Use foo "$@" if function's $1 should mean script's $1.
7#  - SC2155: Declare and assign separately to avoid masking return values.
8#  - SC2206: Quote to prevent word splitting, or split robustly with mapfile or read -a.
9#  - SC2207: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
10#
11# You can find more details for each warning at the following page:
12#    https://github.com/koalaman/shellcheck/wiki/<SCXXXX>
13#
14# bash completion file for core docker commands
15#
16# This script provides completion of:
17#  - commands and their options
18#  - container ids and names
19#  - image repos and tags
20#  - filepaths
21#
22# To enable the completions either:
23#  - place this file in /etc/bash_completion.d
24#  or
25#  - copy this file to e.g. ~/.docker-completion.sh and add the line
26#    below to your .bashrc after bash completion features are loaded
27#    . ~/.docker-completion.sh
28#
29# Configuration:
30#
31# For several commands, the amount of completions can be configured by
32# setting environment variables.
33#
34# DOCKER_COMPLETION_SHOW_CONFIG_IDS
35# DOCKER_COMPLETION_SHOW_CONTAINER_IDS
36# DOCKER_COMPLETION_SHOW_NETWORK_IDS
37# DOCKER_COMPLETION_SHOW_NODE_IDS
38# DOCKER_COMPLETION_SHOW_PLUGIN_IDS
39# DOCKER_COMPLETION_SHOW_SECRET_IDS
40# DOCKER_COMPLETION_SHOW_SERVICE_IDS
41#   "no"  - Show names only (default)
42#   "yes" - Show names and ids
43#
44# You can tailor completion for the "events", "history", "inspect", "run",
45# "rmi" and "save" commands by settings the following environment
46# variables:
47#
48# DOCKER_COMPLETION_SHOW_IMAGE_IDS
49#   "none" - Show names only (default)
50#   "non-intermediate" - Show names and ids, but omit intermediate image IDs
51#   "all" - Show names and ids, including intermediate image IDs
52#
53# DOCKER_COMPLETION_SHOW_TAGS
54#   "yes" - include tags in completion options (default)
55#   "no"  - don't include tags in completion options
56
57#
58# Note:
59# Currently, the completions will not work if the docker daemon is not
60# bound to the default communication port/socket
61# If the docker daemon is using a unix socket for communication your user
62# must have access to the socket for the completions to function correctly
63#
64# Note for developers:
65# Please arrange options sorted alphabetically by long name with the short
66# options immediately following their corresponding long form.
67# This order should be applied to lists, alternatives and code blocks.
68
69__docker_previous_extglob_setting=$(shopt -p extglob)
70shopt -s extglob
71
72__docker_q() {
73	docker ${host:+-H "$host"} ${config:+--config "$config"} 2>/dev/null "$@"
74}
75
76# __docker_configs returns a list of configs. Additional options to
77# `docker config ls` may be specified in order to filter the list, e.g.
78# `__docker_configs --filter label=stage=production`.
79# By default, only names are returned.
80# Set DOCKER_COMPLETION_SHOW_CONFIG_IDS=yes to also complete IDs.
81# An optional first option `--id|--name` may be used to limit the
82# output to the IDs or names of matching items. This setting takes
83# precedence over the environment setting.
84__docker_configs() {
85	local format
86	if [ "$1" = "--id" ] ; then
87		format='{{.ID}}'
88		shift
89	elif [ "$1" = "--name" ] ; then
90		format='{{.Name}}'
91		shift
92	elif [ "$DOCKER_COMPLETION_SHOW_CONFIG_IDS" = yes ] ; then
93		format='{{.ID}} {{.Name}}'
94	else
95		format='{{.Name}}'
96	fi
97
98	__docker_q config ls --format "$format" "$@"
99}
100
101# __docker_complete_configs applies completion of configs based on the current value
102# of `$cur` or the value of the optional first option `--cur`, if given.
103__docker_complete_configs() {
104	local current="$cur"
105	if [ "$1" = "--cur" ] ; then
106		current="$2"
107		shift 2
108	fi
109	COMPREPLY=( $(compgen -W "$(__docker_configs "$@")" -- "$current") )
110}
111
112# __docker_containers returns a list of containers. Additional options to
113# `docker ps` may be specified in order to filter the list, e.g.
114# `__docker_containers --filter status=running`
115# By default, only names are returned.
116# Set DOCKER_COMPLETION_SHOW_CONTAINER_IDS=yes to also complete IDs.
117# An optional first option `--id|--name` may be used to limit the
118# output to the IDs or names of matching items. This setting takes
119# precedence over the environment setting.
120__docker_containers() {
121	local format
122	if [ "$1" = "--id" ] ; then
123		format='{{.ID}}'
124		shift
125	elif [ "$1" = "--name" ] ; then
126		format='{{.Names}}'
127		shift
128	elif [ "${DOCKER_COMPLETION_SHOW_CONTAINER_IDS}" = yes ] ; then
129		format='{{.ID}} {{.Names}}'
130	else
131		format='{{.Names}}'
132	fi
133	__docker_q ps --format "$format" "$@"
134}
135
136# __docker_complete_containers applies completion of containers based on the current
137# value of `$cur` or the value of the optional first option `--cur`, if given.
138# Additional filters may be appended, see `__docker_containers`.
139__docker_complete_containers() {
140	local current="$cur"
141	if [ "$1" = "--cur" ] ; then
142		current="$2"
143		shift 2
144	fi
145	COMPREPLY=( $(compgen -W "$(__docker_containers "$@")" -- "$current") )
146}
147
148__docker_complete_containers_all() {
149	__docker_complete_containers "$@" --all
150}
151
152# shellcheck disable=SC2120
153__docker_complete_containers_removable() {
154	__docker_complete_containers "$@" --filter status=created --filter status=exited
155}
156
157__docker_complete_containers_running() {
158	__docker_complete_containers "$@" --filter status=running
159}
160
161# shellcheck disable=SC2120
162__docker_complete_containers_stopped() {
163	__docker_complete_containers "$@" --filter status=exited
164}
165
166# shellcheck disable=SC2120
167__docker_complete_containers_unpauseable() {
168	__docker_complete_containers "$@" --filter status=paused
169}
170
171__docker_complete_container_names() {
172	local containers=( $(__docker_q ps -aq --no-trunc) )
173	local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") )
174	names=( "${names[@]#/}" ) # trim off the leading "/" from the container names
175	COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") )
176}
177
178__docker_complete_container_ids() {
179	local containers=( $(__docker_q ps -aq) )
180	COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") )
181}
182
183# __docker_images returns a list of images. For each image, up to three representations
184# can be generated: the repository (e.g. busybox), repository:tag (e.g. busybox:latest)
185# and the ID (e.g. sha256:ee22cbbd4ea3dff63c86ba60c7691287c321e93adfc1009604eb1dde7ec88645).
186#
187# The optional arguments `--repo`, `--tag` and `--id` select the representations that
188# may be returned. Whether or not a particular representation is actually returned
189# depends on the user's customization through several environment variables:
190# - image IDs are only shown if DOCKER_COMPLETION_SHOW_IMAGE_IDS=all|non-intermediate.
191# - tags can be excluded by setting DOCKER_COMPLETION_SHOW_TAGS=no.
192# - repositories are always shown.
193#
194# In cases where an exact image specification is needed, `--force-tag` can be used.
195# It ignores DOCKER_COMPLETION_SHOW_TAGS and only lists valid repository:tag combinations,
196# avoiding repository names that would default to a potentially missing default tag.
197#
198# Additional arguments to `docker image ls` may be specified in order to filter the list,
199# e.g. `__docker_images --filter dangling=true`.
200#
201__docker_images() {
202	local repo_format='{{.Repository}}'
203	local tag_format='{{.Repository}}:{{.Tag}}'
204	local id_format='{{.ID}}'
205	local all
206	local format
207
208	if [ "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" = "all" ] ; then
209		all='--all'
210	fi
211
212	while true ; do
213		case "$1" in
214			--repo)
215				format+="$repo_format\n"
216				shift
217				;;
218			--tag)
219				if [ "${DOCKER_COMPLETION_SHOW_TAGS:-yes}" = "yes" ]; then
220					format+="$tag_format\n"
221				fi
222				shift
223				;;
224			--id)
225				if [[ $DOCKER_COMPLETION_SHOW_IMAGE_IDS =~ ^(all|non-intermediate)$ ]] ; then
226					format+="$id_format\n"
227				fi
228				shift
229				;;
230			--force-tag)
231				# like `--tag` but ignores environment setting
232				format+="$tag_format\n"
233				shift
234				;;
235			*)
236				break
237				;;
238		esac
239	done
240
241	__docker_q image ls --no-trunc --format "${format%\\n}" $all "$@" | grep -v '<none>$'
242}
243
244# __docker_complete_images applies completion of images based on the current value of `$cur` or
245# the value of the optional first option `--cur`, if given.
246# See __docker_images for customization of the returned items.
247__docker_complete_images() {
248	local current="$cur"
249	if [ "$1" = "--cur" ] ; then
250		current="$2"
251		shift 2
252	fi
253	COMPREPLY=( $(compgen -W "$(__docker_images "$@")" -- "$current") )
254	__ltrim_colon_completions "$current"
255}
256
257# __docker_networks returns a list of all networks. Additional options to
258# `docker network ls` may be specified in order to filter the list, e.g.
259# `__docker_networks --filter type=custom`
260# By default, only names are returned.
261# Set DOCKER_COMPLETION_SHOW_NETWORK_IDS=yes to also complete IDs.
262# An optional first option `--id|--name` may be used to limit the
263# output to the IDs or names of matching items. This setting takes
264# precedence over the environment setting.
265__docker_networks() {
266	local format
267	if [ "$1" = "--id" ] ; then
268		format='{{.ID}}'
269		shift
270	elif [ "$1" = "--name" ] ; then
271		format='{{.Name}}'
272		shift
273	elif [ "${DOCKER_COMPLETION_SHOW_NETWORK_IDS}" = yes ] ; then
274		format='{{.ID}} {{.Name}}'
275	else
276		format='{{.Name}}'
277	fi
278	__docker_q network ls --format "$format" "$@"
279}
280
281# __docker_complete_networks applies completion of networks based on the current
282# value of `$cur` or the value of the optional first option `--cur`, if given.
283# Additional filters may be appended, see `__docker_networks`.
284__docker_complete_networks() {
285	local current="$cur"
286	if [ "$1" = "--cur" ] ; then
287		current="$2"
288		shift 2
289	fi
290	COMPREPLY=( $(compgen -W "$(__docker_networks "$@")" -- "$current") )
291}
292
293__docker_complete_containers_in_network() {
294	local containers=($(__docker_q network inspect -f '{{range $i, $c := .Containers}}{{$i}} {{$c.Name}} {{end}}' "$1"))
295	COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") )
296}
297
298# __docker_volumes returns a list of all volumes. Additional options to
299# `docker volume ls` may be specified in order to filter the list, e.g.
300# `__docker_volumes --filter dangling=true`
301# Because volumes do not have IDs, this function does not distinguish between
302# IDs and names.
303__docker_volumes() {
304	__docker_q volume ls -q "$@"
305}
306
307# __docker_complete_volumes applies completion of volumes based on the current
308# value of `$cur` or the value of the optional first option `--cur`, if given.
309# Additional filters may be appended, see `__docker_volumes`.
310__docker_complete_volumes() {
311	local current="$cur"
312	if [ "$1" = "--cur" ] ; then
313		current="$2"
314		shift 2
315	fi
316	COMPREPLY=( $(compgen -W "$(__docker_volumes "$@")" -- "$current") )
317}
318
319# __docker_plugins_bundled returns a list of all plugins of a given type.
320# The type has to be specified with the mandatory option `--type`.
321# Valid types are: Network, Volume, Authorization.
322# Completions may be added or removed with `--add` and `--remove`
323# This function only deals with plugins that come bundled with Docker.
324# For plugins managed by `docker plugin`, see `__docker_plugins_installed`.
325__docker_plugins_bundled() {
326	local type add=() remove=()
327	while true ; do
328		case "$1" in
329			--type)
330				type="$2"
331				shift 2
332				;;
333			--add)
334				add+=("$2")
335				shift 2
336				;;
337			--remove)
338				remove+=("$2")
339				shift 2
340				;;
341			*)
342				break
343				;;
344		esac
345	done
346
347	local plugins=($(__docker_q info --format "{{range \$i, \$p := .Plugins.$type}}{{.}} {{end}}"))
348	for del in "${remove[@]}" ; do
349		plugins=(${plugins[@]/$del/})
350	done
351	echo "${plugins[@]}" "${add[@]}"
352}
353
354# __docker_complete_plugins_bundled applies completion of plugins based on the current
355# value of `$cur` or the value of the optional first option `--cur`, if given.
356# The plugin type has to be specified with the next option `--type`.
357# This function only deals with plugins that come bundled with Docker.
358# For completion of plugins managed by `docker plugin`, see
359# `__docker_complete_plugins_installed`.
360__docker_complete_plugins_bundled() {
361	local current="$cur"
362	if [ "$1" = "--cur" ] ; then
363		current="$2"
364		shift 2
365	fi
366	COMPREPLY=( $(compgen -W "$(__docker_plugins_bundled "$@")" -- "$current") )
367}
368
369# __docker_plugins_installed returns a list of all plugins that were installed with
370# the Docker plugin API.
371# By default, only names are returned.
372# Set DOCKER_COMPLETION_SHOW_PLUGIN_IDS=yes to also complete IDs.
373# Additional options to `docker plugin ls` may be specified in order to filter the list,
374# e.g. `__docker_plugins_installed --filter enabled=true`
375# For built-in pugins, see `__docker_plugins_bundled`.
376__docker_plugins_installed() {
377	local format
378	if [ "$DOCKER_COMPLETION_SHOW_PLUGIN_IDS" = yes ] ; then
379		format='{{.ID}} {{.Name}}'
380	else
381		format='{{.Name}}'
382	fi
383	__docker_q plugin ls --format "$format" "$@"
384}
385
386# __docker_complete_plugins_installed applies completion of plugins that were installed
387# with the Docker plugin API, based on the current value of `$cur` or the value of
388# the optional first option `--cur`, if given.
389# Additional filters may be appended, see `__docker_plugins_installed`.
390# For completion of built-in pugins, see `__docker_complete_plugins_bundled`.
391__docker_complete_plugins_installed() {
392	local current="$cur"
393	if [ "$1" = "--cur" ] ; then
394		current="$2"
395		shift 2
396	fi
397	COMPREPLY=( $(compgen -W "$(__docker_plugins_installed "$@")" -- "$current") )
398}
399
400__docker_runtimes() {
401	__docker_q info | sed -n 's/^Runtimes: \(.*\)/\1/p'
402}
403
404__docker_complete_runtimes() {
405	COMPREPLY=( $(compgen -W "$(__docker_runtimes)" -- "$cur") )
406}
407
408# __docker_secrets returns a list of secrets. Additional options to
409# `docker secret ls` may be specified in order to filter the list, e.g.
410# `__docker_secrets --filter label=stage=production`
411# By default, only names are returned.
412# Set DOCKER_COMPLETION_SHOW_SECRET_IDS=yes to also complete IDs.
413# An optional first option `--id|--name` may be used to limit the
414# output to the IDs or names of matching items. This setting takes
415# precedence over the environment setting.
416__docker_secrets() {
417	local format
418	if [ "$1" = "--id" ] ; then
419		format='{{.ID}}'
420		shift
421	elif [ "$1" = "--name" ] ; then
422		format='{{.Name}}'
423		shift
424	elif [ "$DOCKER_COMPLETION_SHOW_SECRET_IDS" = yes ] ; then
425		format='{{.ID}} {{.Name}}'
426	else
427		format='{{.Name}}'
428	fi
429
430	__docker_q secret ls --format "$format" "$@"
431}
432
433# __docker_complete_secrets applies completion of secrets based on the current value
434# of `$cur` or the value of the optional first option `--cur`, if given.
435__docker_complete_secrets() {
436	local current="$cur"
437	if [ "$1" = "--cur" ] ; then
438		current="$2"
439		shift 2
440	fi
441	COMPREPLY=( $(compgen -W "$(__docker_secrets "$@")" -- "$current") )
442}
443
444# __docker_stacks returns a list of all stacks.
445__docker_stacks() {
446	__docker_q stack ls | awk 'NR>1 {print $1}'
447}
448
449# __docker_complete_stacks applies completion of stacks based on the current value
450# of `$cur` or the value of the optional first option `--cur`, if given.
451__docker_complete_stacks() {
452	local current="$cur"
453	if [ "$1" = "--cur" ] ; then
454		current="$2"
455		shift 2
456	fi
457	COMPREPLY=( $(compgen -W "$(__docker_stacks "$@")" -- "$current") )
458}
459
460# __docker_nodes returns a list of all nodes. Additional options to
461# `docker node ls` may be specified in order to filter the list, e.g.
462# `__docker_nodes --filter role=manager`
463# By default, only node names are returned.
464# Set DOCKER_COMPLETION_SHOW_NODE_IDS=yes to also complete node IDs.
465# An optional first option `--id|--name` may be used to limit the
466# output to the IDs or names of matching items. This setting takes
467# precedence over the environment setting.
468# Completions may be added with `--add`, e.g. `--add self`.
469__docker_nodes() {
470	local format
471	if [ "$DOCKER_COMPLETION_SHOW_NODE_IDS" = yes ] ; then
472		format='{{.ID}} {{.Hostname}}'
473	else
474		format='{{.Hostname}}'
475	fi
476
477	local add=()
478
479	while true ; do
480		case "$1" in
481			--id)
482				format='{{.ID}}'
483				shift
484				;;
485			--name)
486				format='{{.Hostname}}'
487				shift
488				;;
489			--add)
490				add+=("$2")
491				shift 2
492				;;
493			*)
494				break
495				;;
496		esac
497	done
498
499	echo "$(__docker_q node ls --format "$format" "$@")" "${add[@]}"
500}
501
502# __docker_complete_nodes applies completion of nodes based on the current
503# value of `$cur` or the value of the optional first option `--cur`, if given.
504# Additional filters may be appended, see `__docker_nodes`.
505__docker_complete_nodes() {
506	local current="$cur"
507	if [ "$1" = "--cur" ] ; then
508		current="$2"
509		shift 2
510	fi
511	COMPREPLY=( $(compgen -W "$(__docker_nodes "$@")" -- "$current") )
512}
513
514# __docker_services returns a list of all services. Additional options to
515# `docker service ls` may be specified in order to filter the list, e.g.
516# `__docker_services --filter name=xxx`
517# By default, only node names are returned.
518# Set DOCKER_COMPLETION_SHOW_SERVICE_IDS=yes to also complete IDs.
519# An optional first option `--id|--name` may be used to limit the
520# output to the IDs or names of matching items. This setting takes
521# precedence over the environment setting.
522__docker_services() {
523	local fields='$2'  # default: service name only
524	[ "${DOCKER_COMPLETION_SHOW_SERVICE_IDS}" = yes ] && fields='$1,$2' # ID & name
525
526	if [ "$1" = "--id" ] ; then
527		fields='$1' # IDs only
528		shift
529	elif [ "$1" = "--name" ] ; then
530		fields='$2' # names only
531		shift
532	fi
533        __docker_q service ls "$@" | awk "NR>1 {print $fields}"
534}
535
536# __docker_complete_services applies completion of services based on the current
537# value of `$cur` or the value of the optional first option `--cur`, if given.
538# Additional filters may be appended, see `__docker_services`.
539__docker_complete_services() {
540	local current="$cur"
541	if [ "$1" = "--cur" ] ; then
542		current="$2"
543		shift 2
544	fi
545	COMPREPLY=( $(compgen -W "$(__docker_services "$@")" -- "$current") )
546}
547
548# __docker_tasks returns a list of all task IDs.
549__docker_tasks() {
550	__docker_q service ps --format '{{.ID}}' ""
551}
552
553# __docker_complete_services_and_tasks applies completion of services and task IDs.
554# shellcheck disable=SC2120
555__docker_complete_services_and_tasks() {
556	COMPREPLY=( $(compgen -W "$(__docker_services "$@") $(__docker_tasks)" -- "$cur") )
557}
558
559# __docker_append_to_completions appends the word passed as an argument to every
560# word in `$COMPREPLY`.
561# Normally you do this with `compgen -S` while generating the completions.
562# This function allows you to append a suffix later. It allows you to use
563# the __docker_complete_XXX functions in cases where you need a suffix.
564__docker_append_to_completions() {
565	COMPREPLY=( ${COMPREPLY[@]/%/"$1"} )
566}
567
568# __docker_fetch_info fetches information about the configured Docker server and updates
569# several variables with the results.
570# The result is cached for the duration of one invocation of bash completion.
571__docker_fetch_info() {
572	if [ -z "$info_fetched" ] ; then
573		read -r client_experimental server_experimental server_os < <(__docker_q version -f '{{.Client.Experimental}} {{.Server.Experimental}} {{.Server.Os}}')
574		info_fetched=true
575	fi
576}
577
578# __docker_client_is_experimental tests whether the Docker cli is configured to support
579# experimental features. If so, the function exits with 0 (true).
580# Otherwise, or if the result cannot be determined, the exit value is 1 (false).
581__docker_client_is_experimental() {
582	__docker_fetch_info
583	[ "$client_experimental" = "true" ]
584}
585
586# __docker_server_is_experimental tests whether the currently configured Docker
587# server runs in experimental mode. If so, the function exits with 0 (true).
588# Otherwise, or if the result cannot be determined, the exit value is 1 (false).
589__docker_server_is_experimental() {
590	__docker_fetch_info
591	[ "$server_experimental" = "true" ]
592}
593
594# __docker_server_os_is tests whether the currently configured Docker server runs
595# on the operating system passed in as the first argument.
596# Known operating systems: linux, windows.
597__docker_server_os_is() {
598	local expected_os="$1"
599	__docker_fetch_info
600	[ "$server_os" = "$expected_os" ]
601}
602
603# __docker_stack_orchestrator_is tests whether the client is configured to use
604# the orchestrator that is passed in as the first argument.
605__docker_stack_orchestrator_is() {
606	case "$1" in
607		kubernetes)
608			if [ -z "$stack_orchestrator_is_kubernetes" ] ; then
609				__docker_q stack ls --help | grep -qe --namespace
610				stack_orchestrator_is_kubernetes=$?
611			fi
612			return $stack_orchestrator_is_kubernetes
613			;;
614		swarm)
615			if [ -z "$stack_orchestrator_is_swarm" ] ; then
616				__docker_q stack deploy --help | grep -qe "with-registry-auth"
617				stack_orchestrator_is_swarm=$?
618			fi
619			return $stack_orchestrator_is_swarm
620			;;
621		*)
622			return 1
623			;;
624
625	esac
626}
627
628# __docker_pos_first_nonflag finds the position of the first word that is neither
629# option nor an option's argument. If there are options that require arguments,
630# you should pass a glob describing those options, e.g. "--option1|-o|--option2"
631# Use this function to restrict completions to exact positions after the argument list.
632__docker_pos_first_nonflag() {
633	local argument_flags=$1
634
635	local counter=$((${subcommand_pos:-${command_pos}} + 1))
636	while [ "$counter" -le "$cword" ]; do
637		if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then
638			(( counter++ ))
639			# eat "=" in case of --option=arg syntax
640			[ "${words[$counter]}" = "=" ] && (( counter++ ))
641		else
642			case "${words[$counter]}" in
643				-*)
644					;;
645				*)
646					break
647					;;
648			esac
649		fi
650
651		# Bash splits words at "=", retaining "=" as a word, examples:
652		# "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words
653		while [ "${words[$counter + 1]}" = "=" ] ; do
654			counter=$(( counter + 2))
655		done
656
657		(( counter++ ))
658	done
659
660	echo $counter
661}
662
663# __docker_map_key_of_current_option returns `key` if we are currently completing the
664# value of a map option (`key=value`) which matches the extglob given as an argument.
665# This function is needed for key-specific completions.
666__docker_map_key_of_current_option() {
667	local glob="$1"
668
669	local key glob_pos
670	if [ "$cur" = "=" ] ; then        # key= case
671		key="$prev"
672		glob_pos=$((cword - 2))
673	elif [[ $cur == *=* ]] ; then     # key=value case (OSX)
674		key=${cur%=*}
675		glob_pos=$((cword - 1))
676	elif [ "$prev" = "=" ] ; then
677		key=${words[$cword - 2]}  # key=value case
678		glob_pos=$((cword - 3))
679	else
680		return
681	fi
682
683	[ "${words[$glob_pos]}" = "=" ] && ((glob_pos--))  # --option=key=value syntax
684
685	[[ ${words[$glob_pos]} == @($glob) ]] && echo "$key"
686}
687
688# __docker_value_of_option returns the value of the first option matching `option_glob`.
689# Valid values for `option_glob` are option names like `--log-level` and globs like
690# `--log-level|-l`
691# Only positions between the command and the current word are considered.
692__docker_value_of_option() {
693	local option_extglob=$(__docker_to_extglob "$1")
694
695	local counter=$((command_pos + 1))
696	while [ "$counter" -lt "$cword" ]; do
697		case ${words[$counter]} in
698			$option_extglob )
699				echo "${words[$counter + 1]}"
700				break
701				;;
702		esac
703		(( counter++ ))
704	done
705}
706
707# __docker_to_alternatives transforms a multiline list of strings into a single line
708# string with the words separated by `|`.
709# This is used to prepare arguments to __docker_pos_first_nonflag().
710__docker_to_alternatives() {
711	local parts=( $1 )
712	local IFS='|'
713	echo "${parts[*]}"
714}
715
716# __docker_to_extglob transforms a multiline list of options into an extglob pattern
717# suitable for use in case statements.
718__docker_to_extglob() {
719	local extglob=$( __docker_to_alternatives "$1" )
720	echo "@($extglob)"
721}
722
723# __docker_subcommands processes subcommands
724# Locates the first occurrence of any of the subcommands contained in the
725# first argument. In case of a match, calls the corresponding completion
726# function and returns 0.
727# If no match is found, 1 is returned. The calling function can then
728# continue processing its completion.
729#
730# TODO if the preceding command has options that accept arguments and an
731# argument is equal ot one of the subcommands, this is falsely detected as
732# a match.
733__docker_subcommands() {
734	local subcommands="$1"
735
736	local counter=$((command_pos + 1))
737	while [ "$counter" -lt "$cword" ]; do
738		case "${words[$counter]}" in
739			$(__docker_to_extglob "$subcommands") )
740				subcommand_pos=$counter
741				local subcommand=${words[$counter]}
742				local completions_func=_docker_${command}_${subcommand//-/_}
743				declare -F "$completions_func" >/dev/null && "$completions_func"
744				return 0
745				;;
746		esac
747		(( counter++ ))
748	done
749	return 1
750}
751
752# __docker_nospace suppresses trailing whitespace
753__docker_nospace() {
754	# compopt is not available in ancient bash versions
755	type compopt &>/dev/null && compopt -o nospace
756}
757
758__docker_complete_resolved_hostname() {
759	command -v host >/dev/null 2>&1 || return
760	COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') )
761}
762
763# __docker_local_interfaces returns a list of the names and addresses of all
764# local network interfaces.
765# If `--ip-only` is passed as a first argument, only addresses are returned.
766__docker_local_interfaces() {
767	command -v ip >/dev/null 2>&1 || return
768
769	local format
770	if [ "$1" = "--ip-only" ] ; then
771		format='\1'
772		shift
773	else
774		 format='\1 \2'
775	fi
776
777	ip addr show scope global 2>/dev/null | sed -n "s| \+inet \([0-9.]\+\).* \([^ ]\+\)|$format|p"
778}
779
780# __docker_complete_local_interfaces applies completion of the names and addresses of all
781# local network interfaces based on the current value of `$cur`.
782# An additional value can be added to the possible completions with an `--add` argument.
783__docker_complete_local_interfaces() {
784	local additional_interface
785	if [ "$1" = "--add" ] ; then
786		additional_interface="$2"
787		shift 2
788	fi
789
790	COMPREPLY=( $( compgen -W "$(__docker_local_interfaces "$@") $additional_interface" -- "$cur" ) )
791}
792
793# __docker_complete_local_ips applies completion of the addresses of all local network
794# interfaces based on the current value of `$cur`.
795__docker_complete_local_ips() {
796	__docker_complete_local_interfaces --ip-only
797}
798
799# __docker_complete_capabilities_addable completes Linux capabilities which are
800# not granted by default and may be added.
801# see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities
802__docker_complete_capabilities_addable() {
803	COMPREPLY=( $( compgen -W "
804		ALL
805		AUDIT_CONTROL
806		BLOCK_SUSPEND
807		DAC_READ_SEARCH
808		IPC_LOCK
809		IPC_OWNER
810		LEASE
811		LINUX_IMMUTABLE
812		MAC_ADMIN
813		MAC_OVERRIDE
814		NET_ADMIN
815		NET_BROADCAST
816		SYS_ADMIN
817		SYS_BOOT
818		SYSLOG
819		SYS_MODULE
820		SYS_NICE
821		SYS_PACCT
822		SYS_PTRACE
823		SYS_RAWIO
824		SYS_RESOURCE
825		SYS_TIME
826		SYS_TTY_CONFIG
827		WAKE_ALARM
828	" -- "$cur" ) )
829}
830
831# __docker_complete_capabilities_droppable completes Linux capability options which are
832# allowed by default and can be dropped.
833# see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities
834__docker_complete_capabilities_droppable() {
835	COMPREPLY=( $( compgen -W "
836		ALL
837		AUDIT_WRITE
838		CHOWN
839		DAC_OVERRIDE
840		FOWNER
841		FSETID
842		KILL
843		MKNOD
844		NET_BIND_SERVICE
845		NET_RAW
846		SETFCAP
847		SETGID
848		SETPCAP
849		SETUID
850		SYS_CHROOT
851	" -- "$cur" ) )
852}
853
854__docker_complete_detach_keys() {
855	case "$prev" in
856		--detach-keys)
857			case "$cur" in
858				*,)
859					COMPREPLY=( $( compgen -W "${cur}ctrl-" -- "$cur" ) )
860					;;
861				*)
862					COMPREPLY=( $( compgen -W "ctrl-" -- "$cur" ) )
863					;;
864			esac
865
866			__docker_nospace
867			return
868			;;
869	esac
870	return 1
871}
872
873__docker_complete_isolation() {
874	COMPREPLY=( $( compgen -W "default hyperv process" -- "$cur" ) )
875}
876
877__docker_complete_log_drivers() {
878	COMPREPLY=( $( compgen -W "
879		awslogs
880		etwlogs
881		fluentd
882		gcplogs
883		gelf
884		journald
885		json-file
886		local
887		logentries
888		none
889		splunk
890		syslog
891	" -- "$cur" ) )
892}
893
894__docker_complete_log_options() {
895	# see repository docker/docker.github.io/engine/admin/logging/
896
897	# really global options, defined in https://github.com/moby/moby/blob/master/daemon/logger/factory.go
898	local common_options1="max-buffer-size mode"
899	# common options defined in https://github.com/moby/moby/blob/master/daemon/logger/loginfo.go
900	# but not implemented in all log drivers
901	local common_options2="env env-regex labels"
902
903	# awslogs does not implement the $common_options2.
904	local awslogs_options="$common_options1 awslogs-create-group awslogs-credentials-endpoint awslogs-datetime-format awslogs-group awslogs-multiline-pattern awslogs-region awslogs-stream tag"
905
906	local fluentd_options="$common_options1 $common_options2 fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries fluentd-sub-second-precision tag"
907	local gcplogs_options="$common_options1 $common_options2 gcp-log-cmd gcp-meta-id gcp-meta-name gcp-meta-zone gcp-project"
908	local gelf_options="$common_options1 $common_options2 gelf-address gelf-compression-level gelf-compression-type gelf-tcp-max-reconnect gelf-tcp-reconnect-delay tag"
909	local journald_options="$common_options1 $common_options2 tag"
910	local json_file_options="$common_options1 $common_options2 compress max-file max-size"
911	local local_options="$common_options1 compress max-file max-size"
912	local logentries_options="$common_options1 $common_options2 line-only logentries-token tag"
913	local splunk_options="$common_options1 $common_options2 splunk-caname splunk-capath splunk-format splunk-gzip splunk-gzip-level splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url splunk-verify-connection tag"
914	local syslog_options="$common_options1 $common_options2 syslog-address syslog-facility syslog-format syslog-tls-ca-cert syslog-tls-cert syslog-tls-key syslog-tls-skip-verify tag"
915
916	local all_options="$fluentd_options $gcplogs_options $gelf_options $journald_options $logentries_options $json_file_options $syslog_options $splunk_options"
917
918	case $(__docker_value_of_option --log-driver) in
919		'')
920			COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) )
921			;;
922		awslogs)
923			COMPREPLY=( $( compgen -W "$awslogs_options" -S = -- "$cur" ) )
924			;;
925		fluentd)
926			COMPREPLY=( $( compgen -W "$fluentd_options" -S = -- "$cur" ) )
927			;;
928		gcplogs)
929			COMPREPLY=( $( compgen -W "$gcplogs_options" -S = -- "$cur" ) )
930			;;
931		gelf)
932			COMPREPLY=( $( compgen -W "$gelf_options" -S = -- "$cur" ) )
933			;;
934		journald)
935			COMPREPLY=( $( compgen -W "$journald_options" -S = -- "$cur" ) )
936			;;
937		json-file)
938			COMPREPLY=( $( compgen -W "$json_file_options" -S = -- "$cur" ) )
939			;;
940		local)
941			COMPREPLY=( $( compgen -W "$local_options" -S = -- "$cur" ) )
942			;;
943		logentries)
944			COMPREPLY=( $( compgen -W "$logentries_options" -S = -- "$cur" ) )
945			;;
946		syslog)
947			COMPREPLY=( $( compgen -W "$syslog_options" -S = -- "$cur" ) )
948			;;
949		splunk)
950			COMPREPLY=( $( compgen -W "$splunk_options" -S = -- "$cur" ) )
951			;;
952		*)
953			return
954			;;
955	esac
956
957	__docker_nospace
958}
959
960__docker_complete_log_driver_options() {
961	local key=$(__docker_map_key_of_current_option '--log-opt')
962	case "$key" in
963		awslogs-create-group)
964			COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
965			return
966			;;
967		awslogs-credentials-endpoint)
968			COMPREPLY=( $( compgen -W "/" -- "${cur##*=}" ) )
969			__docker_nospace
970			return
971			;;
972		compress|fluentd-async-connect)
973			COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
974			return
975			;;
976		fluentd-sub-second-precision)
977			COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
978			return
979			;;
980		gelf-address)
981			COMPREPLY=( $( compgen -W "tcp udp" -S "://" -- "${cur##*=}" ) )
982			__docker_nospace
983			return
984			;;
985		gelf-compression-level)
986			COMPREPLY=( $( compgen -W "1 2 3 4 5 6 7 8 9" -- "${cur##*=}" ) )
987			return
988			;;
989		gelf-compression-type)
990			COMPREPLY=( $( compgen -W "gzip none zlib" -- "${cur##*=}" ) )
991			return
992			;;
993		line-only)
994			COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
995			return
996			;;
997		mode)
998			COMPREPLY=( $( compgen -W "blocking non-blocking" -- "${cur##*=}" ) )
999			return
1000			;;
1001		syslog-address)
1002			COMPREPLY=( $( compgen -W "tcp:// tcp+tls:// udp:// unix://" -- "${cur##*=}" ) )
1003			__docker_nospace
1004			__ltrim_colon_completions "${cur}"
1005			return
1006			;;
1007		syslog-facility)
1008			COMPREPLY=( $( compgen -W "
1009				auth
1010				authpriv
1011				cron
1012				daemon
1013				ftp
1014				kern
1015				local0
1016				local1
1017				local2
1018				local3
1019				local4
1020				local5
1021				local6
1022				local7
1023				lpr
1024				mail
1025				news
1026				syslog
1027				user
1028				uucp
1029			" -- "${cur##*=}" ) )
1030			return
1031			;;
1032		syslog-format)
1033			COMPREPLY=( $( compgen -W "rfc3164 rfc5424 rfc5424micro" -- "${cur##*=}" ) )
1034			return
1035			;;
1036		syslog-tls-ca-cert|syslog-tls-cert|syslog-tls-key)
1037			_filedir
1038			return
1039			;;
1040		syslog-tls-skip-verify)
1041			COMPREPLY=( $( compgen -W "true" -- "${cur##*=}" ) )
1042			return
1043			;;
1044		splunk-url)
1045			COMPREPLY=( $( compgen -W "http:// https://" -- "${cur##*=}" ) )
1046			__docker_nospace
1047			__ltrim_colon_completions "${cur}"
1048			return
1049			;;
1050		splunk-gzip|splunk-insecureskipverify|splunk-verify-connection)
1051			COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
1052			return
1053			;;
1054		splunk-format)
1055			COMPREPLY=( $( compgen -W "inline json raw" -- "${cur##*=}" ) )
1056			return
1057			;;
1058	esac
1059	return 1
1060}
1061
1062__docker_complete_log_levels() {
1063	COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) )
1064}
1065
1066__docker_complete_restart() {
1067	case "$prev" in
1068		--restart)
1069			case "$cur" in
1070				on-failure:*)
1071					;;
1072				*)
1073					COMPREPLY=( $( compgen -W "always no on-failure on-failure: unless-stopped" -- "$cur") )
1074					;;
1075			esac
1076			return
1077			;;
1078	esac
1079	return 1
1080}
1081
1082# __docker_complete_signals returns a subset of the available signals that is most likely
1083# relevant in the context of docker containers
1084__docker_complete_signals() {
1085	local signals=(
1086		SIGCONT
1087		SIGHUP
1088		SIGINT
1089		SIGKILL
1090		SIGQUIT
1091		SIGSTOP
1092		SIGTERM
1093		SIGUSR1
1094		SIGUSR2
1095	)
1096	COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo "$cur" | tr '[:lower:]' '[:upper:]')" ) )
1097}
1098
1099__docker_complete_stack_orchestrator_options() {
1100	case "$prev" in
1101		--kubeconfig)
1102			_filedir
1103			return 0
1104			;;
1105		--namespace)
1106			return 0
1107			;;
1108		--orchestrator)
1109			COMPREPLY=( $( compgen -W "all kubernetes swarm" -- "$cur") )
1110			return 0
1111			;;
1112	esac
1113	return 1
1114}
1115
1116__docker_complete_user_group() {
1117	if [[ $cur == *:* ]] ; then
1118		COMPREPLY=( $(compgen -g -- "${cur#*:}") )
1119	else
1120		COMPREPLY=( $(compgen -u -S : -- "$cur") )
1121		__docker_nospace
1122	fi
1123}
1124
1125_docker_docker() {
1126	# global options that may appear after the docker command
1127	local boolean_options="
1128		$global_boolean_options
1129		--help
1130		--version -v
1131	"
1132
1133	case "$prev" in
1134		--config)
1135			_filedir -d
1136			return
1137			;;
1138		--log-level|-l)
1139			__docker_complete_log_levels
1140			return
1141			;;
1142		$(__docker_to_extglob "$global_options_with_args") )
1143			return
1144			;;
1145	esac
1146
1147	case "$cur" in
1148		-*)
1149			COMPREPLY=( $( compgen -W "$boolean_options $global_options_with_args" -- "$cur" ) )
1150			;;
1151		*)
1152			local counter=$( __docker_pos_first_nonflag "$(__docker_to_extglob "$global_options_with_args")" )
1153			if [ "$cword" -eq "$counter" ]; then
1154				__docker_client_is_experimental && commands+=(${experimental_client_commands[*]})
1155				__docker_server_is_experimental && commands+=(${experimental_server_commands[*]})
1156				COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) )
1157			fi
1158			;;
1159	esac
1160}
1161
1162_docker_attach() {
1163	_docker_container_attach
1164}
1165
1166_docker_build() {
1167	_docker_image_build
1168}
1169
1170
1171_docker_checkpoint() {
1172	local subcommands="
1173		create
1174		ls
1175		rm
1176	"
1177	local aliases="
1178		list
1179		remove
1180	"
1181	__docker_subcommands "$subcommands $aliases" && return
1182
1183	case "$cur" in
1184		-*)
1185			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
1186			;;
1187		*)
1188			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
1189			;;
1190	esac
1191}
1192
1193_docker_checkpoint_create() {
1194	case "$prev" in
1195		--checkpoint-dir)
1196			_filedir -d
1197			return
1198			;;
1199	esac
1200
1201	case "$cur" in
1202		-*)
1203			COMPREPLY=( $( compgen -W "--checkpoint-dir --help --leave-running" -- "$cur" ) )
1204			;;
1205		*)
1206			local counter=$(__docker_pos_first_nonflag '--checkpoint-dir')
1207			if [ "$cword" -eq "$counter" ]; then
1208				__docker_complete_containers_running
1209			fi
1210			;;
1211	esac
1212}
1213
1214_docker_checkpoint_ls() {
1215	case "$prev" in
1216		--checkpoint-dir)
1217			_filedir -d
1218			return
1219			;;
1220	esac
1221
1222	case "$cur" in
1223		-*)
1224			COMPREPLY=( $( compgen -W "--checkpoint-dir --help" -- "$cur" ) )
1225			;;
1226		*)
1227			local counter=$(__docker_pos_first_nonflag '--checkpoint-dir')
1228			if [ "$cword" -eq "$counter" ]; then
1229				__docker_complete_containers_all
1230			fi
1231			;;
1232	esac
1233}
1234
1235_docker_checkpoint_rm() {
1236	case "$prev" in
1237		--checkpoint-dir)
1238			_filedir -d
1239			return
1240			;;
1241	esac
1242
1243	case "$cur" in
1244		-*)
1245			COMPREPLY=( $( compgen -W "--checkpoint-dir --help" -- "$cur" ) )
1246			;;
1247		*)
1248			local counter=$(__docker_pos_first_nonflag '--checkpoint-dir')
1249			if [ "$cword" -eq "$counter" ]; then
1250				__docker_complete_containers_all
1251			elif [ "$cword" -eq "$((counter + 1))" ]; then
1252				COMPREPLY=( $( compgen -W "$(__docker_q checkpoint ls "$prev" | sed 1d)" -- "$cur" ) )
1253			fi
1254			;;
1255	esac
1256}
1257
1258
1259_docker_config() {
1260	local subcommands="
1261		create
1262		inspect
1263		ls
1264		rm
1265	"
1266	local aliases="
1267		list
1268		remove
1269	"
1270	__docker_subcommands "$subcommands $aliases" && return
1271
1272	case "$cur" in
1273		-*)
1274			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
1275			;;
1276		*)
1277			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
1278			;;
1279	esac
1280}
1281
1282_docker_config_create() {
1283	case "$prev" in
1284		--label|-l)
1285			return
1286			;;
1287		--template-driver)
1288			COMPREPLY=( $( compgen -W "golang" -- "$cur" ) )
1289			return
1290			;;
1291	esac
1292
1293	case "$cur" in
1294		-*)
1295			COMPREPLY=( $( compgen -W "--help --label -l --template-driver" -- "$cur" ) )
1296			;;
1297		*)
1298			local counter=$(__docker_pos_first_nonflag '--label|-l|--template-driver')
1299			if [ "$cword" -eq "$((counter + 1))" ]; then
1300				_filedir
1301			fi
1302			;;
1303	esac
1304}
1305
1306_docker_config_inspect() {
1307	case "$prev" in
1308		--format|-f)
1309			return
1310			;;
1311	esac
1312
1313	case "$cur" in
1314		-*)
1315			COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) )
1316			;;
1317		*)
1318			__docker_complete_configs
1319			;;
1320	esac
1321}
1322
1323_docker_config_list() {
1324	_docker_config_ls
1325}
1326
1327_docker_config_ls() {
1328	local key=$(__docker_map_key_of_current_option '--filter|-f')
1329	case "$key" in
1330		id)
1331			__docker_complete_configs --cur "${cur##*=}" --id
1332			return
1333			;;
1334		name)
1335			__docker_complete_configs --cur "${cur##*=}" --name
1336			return
1337			;;
1338	esac
1339
1340	case "$prev" in
1341		--filter|-f)
1342			COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) )
1343			__docker_nospace
1344			return
1345			;;
1346		--format)
1347			return
1348			;;
1349	esac
1350
1351	case "$cur" in
1352		-*)
1353			COMPREPLY=( $( compgen -W "--format --filter -f --help --quiet -q" -- "$cur" ) )
1354			;;
1355	esac
1356}
1357
1358_docker_config_remove() {
1359	_docker_config_rm
1360}
1361
1362_docker_config_rm() {
1363	case "$cur" in
1364		-*)
1365			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
1366			;;
1367		*)
1368			__docker_complete_configs
1369			;;
1370	esac
1371}
1372
1373
1374_docker_container() {
1375	local subcommands="
1376		attach
1377		commit
1378		cp
1379		create
1380		diff
1381		exec
1382		export
1383		inspect
1384		kill
1385		logs
1386		ls
1387		pause
1388		port
1389		prune
1390		rename
1391		restart
1392		rm
1393		run
1394		start
1395		stats
1396		stop
1397		top
1398		unpause
1399		update
1400		wait
1401	"
1402	local aliases="
1403		list
1404		ps
1405	"
1406	__docker_subcommands "$subcommands $aliases" && return
1407
1408	case "$cur" in
1409		-*)
1410			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
1411			;;
1412		*)
1413			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
1414			;;
1415	esac
1416}
1417
1418_docker_container_attach() {
1419	__docker_complete_detach_keys && return
1420
1421	case "$cur" in
1422		-*)
1423			COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy=false" -- "$cur" ) )
1424			;;
1425		*)
1426			local counter=$(__docker_pos_first_nonflag '--detach-keys')
1427			if [ "$cword" -eq "$counter" ]; then
1428				__docker_complete_containers_running
1429			fi
1430			;;
1431	esac
1432}
1433
1434_docker_container_commit() {
1435	case "$prev" in
1436		--author|-a|--change|-c|--message|-m)
1437			return
1438			;;
1439	esac
1440
1441	case "$cur" in
1442		-*)
1443			COMPREPLY=( $( compgen -W "--author -a --change -c --help --message -m --pause=false -p=false" -- "$cur" ) )
1444			;;
1445		*)
1446			local counter=$(__docker_pos_first_nonflag '--author|-a|--change|-c|--message|-m')
1447
1448			if [ "$cword" -eq "$counter" ]; then
1449				__docker_complete_containers_all
1450				return
1451			elif [ "$cword" -eq "$((counter + 1))" ]; then
1452				__docker_complete_images --repo --tag
1453				return
1454			fi
1455			;;
1456	esac
1457}
1458
1459_docker_container_cp() {
1460	case "$cur" in
1461		-*)
1462			COMPREPLY=( $( compgen -W "--archive -a --follow-link -L --help" -- "$cur" ) )
1463			;;
1464		*)
1465			local counter=$(__docker_pos_first_nonflag)
1466			if [ "$cword" -eq "$counter" ]; then
1467				case "$cur" in
1468					*:)
1469						return
1470						;;
1471					*)
1472						# combined container and filename completion
1473						_filedir
1474						local files=( ${COMPREPLY[@]} )
1475
1476						__docker_complete_containers_all
1477						COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
1478						local containers=( ${COMPREPLY[@]} )
1479
1480						COMPREPLY=( $( compgen -W "${files[*]} ${containers[*]}" -- "$cur" ) )
1481						if [[ "${COMPREPLY[*]}" = *: ]]; then
1482							__docker_nospace
1483						fi
1484						return
1485						;;
1486				esac
1487			fi
1488			(( counter++ ))
1489
1490			if [ "$cword" -eq "$counter" ]; then
1491				if [ -e "$prev" ]; then
1492					__docker_complete_containers_all
1493					COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
1494					__docker_nospace
1495				else
1496					_filedir
1497				fi
1498				return
1499			fi
1500			;;
1501	esac
1502}
1503
1504_docker_container_create() {
1505	_docker_container_run_and_create
1506}
1507
1508_docker_container_diff() {
1509	case "$cur" in
1510		-*)
1511			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
1512			;;
1513		*)
1514			local counter=$(__docker_pos_first_nonflag)
1515			if [ "$cword" -eq "$counter" ]; then
1516				__docker_complete_containers_all
1517			fi
1518			;;
1519	esac
1520}
1521
1522_docker_container_exec() {
1523	__docker_complete_detach_keys && return
1524
1525	case "$prev" in
1526		--env|-e)
1527			# we do not append a "=" here because "-e VARNAME" is legal syntax, too
1528			COMPREPLY=( $( compgen -e -- "$cur" ) )
1529			__docker_nospace
1530			return
1531			;;
1532		--user|-u)
1533			__docker_complete_user_group
1534			return
1535			;;
1536		--workdir|-w)
1537			return
1538			;;
1539	esac
1540
1541	case "$cur" in
1542		-*)
1543			COMPREPLY=( $( compgen -W "--detach -d --detach-keys --env -e --help --interactive -i --privileged -t --tty -u --user --workdir -w" -- "$cur" ) )
1544			;;
1545		*)
1546			__docker_complete_containers_running
1547			;;
1548	esac
1549}
1550
1551_docker_container_export() {
1552	case "$prev" in
1553		--output|-o)
1554			_filedir
1555			return
1556			;;
1557	esac
1558
1559	case "$cur" in
1560		-*)
1561			COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) )
1562			;;
1563		*)
1564			local counter=$(__docker_pos_first_nonflag)
1565			if [ "$cword" -eq "$counter" ]; then
1566				__docker_complete_containers_all
1567			fi
1568			;;
1569	esac
1570}
1571
1572_docker_container_inspect() {
1573	_docker_inspect --type container
1574}
1575
1576_docker_container_kill() {
1577	case "$prev" in
1578		--signal|-s)
1579			__docker_complete_signals
1580			return
1581			;;
1582	esac
1583
1584	case "$cur" in
1585		-*)
1586			COMPREPLY=( $( compgen -W "--help --signal -s" -- "$cur" ) )
1587			;;
1588		*)
1589			__docker_complete_containers_running
1590			;;
1591	esac
1592}
1593
1594_docker_container_logs() {
1595	case "$prev" in
1596		--since|--tail|--until)
1597			return
1598			;;
1599	esac
1600
1601	case "$cur" in
1602		-*)
1603			COMPREPLY=( $( compgen -W "--details --follow -f --help --since --tail --timestamps -t --until" -- "$cur" ) )
1604			;;
1605		*)
1606			local counter=$(__docker_pos_first_nonflag '--since|--tail|--until')
1607			if [ "$cword" -eq "$counter" ]; then
1608				__docker_complete_containers_all
1609			fi
1610			;;
1611	esac
1612}
1613
1614_docker_container_list() {
1615	_docker_container_ls
1616}
1617
1618_docker_container_ls() {
1619	local key=$(__docker_map_key_of_current_option '--filter|-f')
1620	case "$key" in
1621		ancestor)
1622			__docker_complete_images --cur "${cur##*=}" --repo --tag --id
1623			return
1624			;;
1625		before)
1626			__docker_complete_containers_all --cur "${cur##*=}"
1627			return
1628			;;
1629		expose|publish)
1630			return
1631			;;
1632		id)
1633			__docker_complete_containers_all --cur "${cur##*=}" --id
1634			return
1635			;;
1636		health)
1637			COMPREPLY=( $( compgen -W "healthy starting none unhealthy" -- "${cur##*=}" ) )
1638			return
1639			;;
1640		is-task)
1641			COMPREPLY=( $( compgen -W "true false" -- "${cur##*=}" ) )
1642			return
1643			;;
1644		name)
1645			__docker_complete_containers_all --cur "${cur##*=}" --name
1646			return
1647			;;
1648		network)
1649			__docker_complete_networks --cur "${cur##*=}"
1650			return
1651			;;
1652		since)
1653			__docker_complete_containers_all --cur "${cur##*=}"
1654			return
1655			;;
1656		status)
1657			COMPREPLY=( $( compgen -W "created dead exited paused restarting running removing" -- "${cur##*=}" ) )
1658			return
1659			;;
1660		volume)
1661			__docker_complete_volumes --cur "${cur##*=}"
1662			return
1663			;;
1664	esac
1665
1666	case "$prev" in
1667		--filter|-f)
1668			COMPREPLY=( $( compgen -S = -W "ancestor before exited expose health id is-task label name network publish since status volume" -- "$cur" ) )
1669			__docker_nospace
1670			return
1671			;;
1672		--format|--last|-n)
1673			return
1674			;;
1675	esac
1676
1677	case "$cur" in
1678		-*)
1679			COMPREPLY=( $( compgen -W "--all -a --filter -f --format --help --last -n --latest -l --no-trunc --quiet -q --size -s" -- "$cur" ) )
1680			;;
1681	esac
1682}
1683
1684_docker_container_pause() {
1685	case "$cur" in
1686		-*)
1687			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
1688			;;
1689		*)
1690			__docker_complete_containers_running
1691			;;
1692	esac
1693}
1694
1695_docker_container_port() {
1696	case "$cur" in
1697		-*)
1698			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
1699			;;
1700		*)
1701			local counter=$(__docker_pos_first_nonflag)
1702			if [ "$cword" -eq "$counter" ]; then
1703				__docker_complete_containers_all
1704			fi
1705			;;
1706	esac
1707}
1708
1709_docker_container_prune() {
1710	case "$prev" in
1711		--filter)
1712			COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) )
1713			__docker_nospace
1714			return
1715			;;
1716	esac
1717
1718	case "$cur" in
1719		-*)
1720			COMPREPLY=( $( compgen -W "--force -f --filter --help" -- "$cur" ) )
1721			;;
1722	esac
1723}
1724
1725_docker_container_ps() {
1726	_docker_container_ls
1727}
1728
1729_docker_container_rename() {
1730	case "$cur" in
1731		-*)
1732			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
1733			;;
1734		*)
1735			local counter=$(__docker_pos_first_nonflag)
1736			if [ "$cword" -eq "$counter" ]; then
1737				__docker_complete_containers_all
1738			fi
1739			;;
1740	esac
1741}
1742
1743_docker_container_restart() {
1744	case "$prev" in
1745		--time|-t)
1746			return
1747			;;
1748	esac
1749
1750	case "$cur" in
1751		-*)
1752			COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) )
1753			;;
1754		*)
1755			__docker_complete_containers_all
1756			;;
1757	esac
1758}
1759
1760_docker_container_rm() {
1761	case "$cur" in
1762		-*)
1763			COMPREPLY=( $( compgen -W "--force -f --help --link -l --volumes -v" -- "$cur" ) )
1764			;;
1765		*)
1766			for arg in "${COMP_WORDS[@]}"; do
1767				case "$arg" in
1768					--force|-f)
1769						__docker_complete_containers_all
1770						return
1771						;;
1772				esac
1773			done
1774			__docker_complete_containers_removable
1775			;;
1776	esac
1777}
1778
1779_docker_container_run() {
1780	_docker_container_run_and_create
1781}
1782
1783# _docker_container_run_and_create is the combined completion for `_docker_container_run`
1784# and `_docker_container_create`
1785_docker_container_run_and_create() {
1786	local options_with_args="
1787		--add-host
1788		--attach -a
1789		--blkio-weight
1790		--blkio-weight-device
1791		--cap-add
1792		--cap-drop
1793		--cgroup-parent
1794		--cidfile
1795		--cpu-period
1796		--cpu-quota
1797		--cpu-rt-period
1798		--cpu-rt-runtime
1799		--cpuset-cpus
1800		--cpus
1801		--cpuset-mems
1802		--cpu-shares -c
1803		--device
1804		--device-cgroup-rule
1805		--device-read-bps
1806		--device-read-iops
1807		--device-write-bps
1808		--device-write-iops
1809		--dns
1810		--dns-option
1811		--dns-search
1812		--entrypoint
1813		--env -e
1814		--env-file
1815		--expose
1816		--group-add
1817		--health-cmd
1818		--health-interval
1819		--health-retries
1820		--health-start-period
1821		--health-timeout
1822		--hostname -h
1823		--ip
1824		--ip6
1825		--ipc
1826		--kernel-memory
1827		--label-file
1828		--label -l
1829		--link
1830		--link-local-ip
1831		--log-driver
1832		--log-opt
1833		--mac-address
1834		--memory -m
1835		--memory-swap
1836		--memory-swappiness
1837		--memory-reservation
1838		--mount
1839		--name
1840		--network
1841		--network-alias
1842		--oom-score-adj
1843		--pid
1844		--pids-limit
1845		--publish -p
1846		--restart
1847		--runtime
1848		--security-opt
1849		--shm-size
1850		--stop-signal
1851		--stop-timeout
1852		--storage-opt
1853		--tmpfs
1854		--sysctl
1855		--ulimit
1856		--user -u
1857		--userns
1858		--uts
1859		--volume-driver
1860		--volumes-from
1861		--volume -v
1862		--workdir -w
1863	"
1864	__docker_server_os_is windows && options_with_args+="
1865		--cpu-count
1866		--cpu-percent
1867		--io-maxbandwidth
1868		--io-maxiops
1869		--isolation
1870	"
1871	__docker_server_is_experimental && options_with_args+="
1872		--platform
1873	"
1874
1875	local boolean_options="
1876		--disable-content-trust=false
1877		--help
1878		--init
1879		--interactive -i
1880		--no-healthcheck
1881		--oom-kill-disable
1882		--privileged
1883		--publish-all -P
1884		--read-only
1885		--tty -t
1886	"
1887
1888	if [ "$command" = "run" ] || [ "$subcommand" = "run" ] ; then
1889		options_with_args="$options_with_args
1890			--detach-keys
1891		"
1892		boolean_options="$boolean_options
1893			--detach -d
1894			--rm
1895			--sig-proxy=false
1896		"
1897		__docker_complete_detach_keys && return
1898	fi
1899
1900	local all_options="$options_with_args $boolean_options"
1901
1902
1903	__docker_complete_log_driver_options && return
1904	__docker_complete_restart && return
1905
1906	local key=$(__docker_map_key_of_current_option '--security-opt')
1907	case "$key" in
1908		label)
1909			[[ $cur == *: ]] && return
1910			COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "${cur##*=}") )
1911			if [ "${COMPREPLY[*]}" != "disable" ] ; then
1912				__docker_nospace
1913			fi
1914			return
1915			;;
1916		seccomp)
1917			local cur=${cur##*=}
1918			_filedir
1919			COMPREPLY+=( $( compgen -W "unconfined" -- "$cur" ) )
1920			return
1921			;;
1922	esac
1923
1924	case "$prev" in
1925		--add-host)
1926			case "$cur" in
1927				*:)
1928					__docker_complete_resolved_hostname
1929					return
1930					;;
1931			esac
1932			;;
1933		--attach|-a)
1934			COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) )
1935			return
1936			;;
1937		--cap-add)
1938			__docker_complete_capabilities_addable
1939			return
1940			;;
1941		--cap-drop)
1942			__docker_complete_capabilities_droppable
1943			return
1944			;;
1945		--cidfile|--env-file|--label-file)
1946			_filedir
1947			return
1948			;;
1949		--device|--tmpfs|--volume|-v)
1950			case "$cur" in
1951				*:*)
1952					# TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine)
1953					;;
1954				'')
1955					COMPREPLY=( $( compgen -W '/' -- "$cur" ) )
1956					__docker_nospace
1957					;;
1958				/*)
1959					_filedir
1960					__docker_nospace
1961					;;
1962			esac
1963			return
1964			;;
1965		--env|-e)
1966			# we do not append a "=" here because "-e VARNAME" is legal syntax, too
1967			COMPREPLY=( $( compgen -e -- "$cur" ) )
1968			__docker_nospace
1969			return
1970			;;
1971		--ipc)
1972			case "$cur" in
1973				*:*)
1974					cur="${cur#*:}"
1975					__docker_complete_containers_running
1976					;;
1977				*)
1978					COMPREPLY=( $( compgen -W 'none host private shareable container:' -- "$cur" ) )
1979					if [ "${COMPREPLY[*]}" = "container:" ]; then
1980						__docker_nospace
1981					fi
1982					;;
1983			esac
1984			return
1985			;;
1986		--isolation)
1987			if __docker_server_os_is windows ; then
1988				__docker_complete_isolation
1989				return
1990			fi
1991			;;
1992		--link)
1993			case "$cur" in
1994				*:*)
1995					;;
1996				*)
1997					__docker_complete_containers_running
1998					COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
1999					__docker_nospace
2000					;;
2001			esac
2002			return
2003			;;
2004		--log-driver)
2005			__docker_complete_log_drivers
2006			return
2007			;;
2008		--log-opt)
2009			__docker_complete_log_options
2010			return
2011			;;
2012		--network)
2013			case "$cur" in
2014				container:*)
2015					__docker_complete_containers_all --cur "${cur#*:}"
2016					;;
2017				*)
2018					COMPREPLY=( $( compgen -W "$(__docker_plugins_bundled --type Network) $(__docker_networks) container:" -- "$cur") )
2019					if [ "${COMPREPLY[*]}" = "container:" ] ; then
2020						__docker_nospace
2021					fi
2022					;;
2023			esac
2024			return
2025			;;
2026		--pid)
2027			case "$cur" in
2028				*:*)
2029					__docker_complete_containers_running --cur "${cur#*:}"
2030					;;
2031				*)
2032					COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) )
2033					if [ "${COMPREPLY[*]}" = "container:" ]; then
2034						__docker_nospace
2035					fi
2036					;;
2037			esac
2038			return
2039			;;
2040		--runtime)
2041			__docker_complete_runtimes
2042			return
2043			;;
2044		--security-opt)
2045			COMPREPLY=( $( compgen -W "apparmor= label= no-new-privileges seccomp=" -- "$cur") )
2046			if [ "${COMPREPLY[*]}" != "no-new-privileges" ] ; then
2047				__docker_nospace
2048			fi
2049			return
2050			;;
2051		--stop-signal)
2052			__docker_complete_signals
2053			return
2054			;;
2055		--storage-opt)
2056			COMPREPLY=( $( compgen -W "size" -S = -- "$cur") )
2057			__docker_nospace
2058			return
2059			;;
2060		--user|-u)
2061			__docker_complete_user_group
2062			return
2063			;;
2064		--userns)
2065			COMPREPLY=( $( compgen -W "host" -- "$cur" ) )
2066			return
2067			;;
2068		--volume-driver)
2069			__docker_complete_plugins_bundled --type Volume
2070			return
2071			;;
2072		--volumes-from)
2073			__docker_complete_containers_all
2074			return
2075			;;
2076		$(__docker_to_extglob "$options_with_args") )
2077			return
2078			;;
2079	esac
2080
2081	case "$cur" in
2082		-*)
2083			COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) )
2084			;;
2085		*)
2086			local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" )
2087			if [ "$cword" -eq "$counter" ]; then
2088				__docker_complete_images --repo --tag --id
2089			fi
2090			;;
2091	esac
2092}
2093
2094_docker_container_start() {
2095	__docker_complete_detach_keys && return
2096	case "$prev" in
2097		--checkpoint)
2098			if __docker_server_is_experimental ; then
2099				return
2100			fi
2101			;;
2102		--checkpoint-dir)
2103			if __docker_server_is_experimental ; then
2104				_filedir -d
2105				return
2106			fi
2107			;;
2108	esac
2109
2110	case "$cur" in
2111		-*)
2112			local options="--attach -a --detach-keys --help --interactive -i"
2113			__docker_server_is_experimental && options+=" --checkpoint --checkpoint-dir"
2114			COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )
2115			;;
2116		*)
2117			__docker_complete_containers_stopped
2118			;;
2119	esac
2120}
2121
2122_docker_container_stats() {
2123	case "$prev" in
2124		--format)
2125			return
2126			;;
2127	esac
2128
2129	case "$cur" in
2130		-*)
2131			COMPREPLY=( $( compgen -W "--all -a --format --help --no-stream --no-trunc" -- "$cur" ) )
2132			;;
2133		*)
2134			__docker_complete_containers_running
2135			;;
2136	esac
2137}
2138
2139_docker_container_stop() {
2140	case "$prev" in
2141		--time|-t)
2142			return
2143			;;
2144	esac
2145
2146	case "$cur" in
2147		-*)
2148			COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) )
2149			;;
2150		*)
2151			__docker_complete_containers_running
2152			;;
2153	esac
2154}
2155
2156_docker_container_top() {
2157	case "$cur" in
2158		-*)
2159			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
2160			;;
2161		*)
2162			local counter=$(__docker_pos_first_nonflag)
2163			if [ "$cword" -eq "$counter" ]; then
2164				__docker_complete_containers_running
2165			fi
2166			;;
2167	esac
2168}
2169
2170_docker_container_unpause() {
2171	case "$cur" in
2172		-*)
2173			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
2174			;;
2175		*)
2176			local counter=$(__docker_pos_first_nonflag)
2177			if [ "$cword" -eq "$counter" ]; then
2178				__docker_complete_containers_unpauseable
2179			fi
2180			;;
2181	esac
2182}
2183
2184_docker_container_update() {
2185	local options_with_args="
2186		--blkio-weight
2187		--cpu-period
2188		--cpu-quota
2189		--cpu-rt-period
2190		--cpu-rt-runtime
2191		--cpus
2192		--cpuset-cpus
2193		--cpuset-mems
2194		--cpu-shares -c
2195		--kernel-memory
2196		--memory -m
2197		--memory-reservation
2198		--memory-swap
2199		--restart
2200	"
2201
2202	local boolean_options="
2203		--help
2204	"
2205
2206	local all_options="$options_with_args $boolean_options"
2207
2208	__docker_complete_restart && return
2209
2210	case "$prev" in
2211		$(__docker_to_extglob "$options_with_args") )
2212			return
2213			;;
2214	esac
2215
2216	case "$cur" in
2217		-*)
2218			COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) )
2219			;;
2220		*)
2221			__docker_complete_containers_all
2222			;;
2223	esac
2224}
2225
2226_docker_container_wait() {
2227	case "$cur" in
2228		-*)
2229			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
2230			;;
2231		*)
2232			__docker_complete_containers_all
2233			;;
2234	esac
2235}
2236
2237
2238_docker_commit() {
2239	_docker_container_commit
2240}
2241
2242_docker_cp() {
2243	_docker_container_cp
2244}
2245
2246_docker_create() {
2247	_docker_container_create
2248}
2249
2250_docker_daemon() {
2251	local boolean_options="
2252		$global_boolean_options
2253		--experimental
2254		--help
2255		--icc=false
2256		--init
2257		--ip-forward=false
2258		--ip-masq=false
2259		--iptables=false
2260		--ipv6
2261		--live-restore
2262		--no-new-privileges
2263		--raw-logs
2264		--selinux-enabled
2265		--userland-proxy=false
2266		--version -v
2267	"
2268	local options_with_args="
2269		$global_options_with_args
2270		--add-runtime
2271		--allow-nondistributable-artifacts
2272		--api-cors-header
2273		--authorization-plugin
2274		--bip
2275		--bridge -b
2276		--cgroup-parent
2277		--cluster-advertise
2278		--cluster-store
2279		--cluster-store-opt
2280		--config-file
2281		--containerd
2282		--cpu-rt-period
2283		--cpu-rt-runtime
2284		--data-root
2285		--default-address-pool
2286		--default-gateway
2287		--default-gateway-v6
2288		--default-runtime
2289		--default-shm-size
2290		--default-ulimit
2291		--dns
2292		--dns-search
2293		--dns-opt
2294		--exec-opt
2295		--exec-root
2296		--fixed-cidr
2297		--fixed-cidr-v6
2298		--group -G
2299		--init-path
2300		--insecure-registry
2301		--ip
2302		--label
2303		--log-driver
2304		--log-opt
2305		--max-concurrent-downloads
2306		--max-concurrent-uploads
2307		--metrics-addr
2308		--mtu
2309		--network-control-plane-mtu
2310		--node-generic-resource
2311		--oom-score-adjust
2312		--pidfile -p
2313		--registry-mirror
2314		--seccomp-profile
2315		--shutdown-timeout
2316		--storage-driver -s
2317		--storage-opt
2318		--swarm-default-advertise-addr
2319		--userland-proxy-path
2320		--userns-remap
2321	"
2322
2323	__docker_complete_log_driver_options && return
2324
2325 	key=$(__docker_map_key_of_current_option '--cluster-store-opt')
2326 	case "$key" in
2327 		kv.*file)
2328			cur=${cur##*=}
2329 			_filedir
2330 			return
2331 			;;
2332 	esac
2333
2334 	local key=$(__docker_map_key_of_current_option '--storage-opt')
2335 	case "$key" in
2336 		dm.blkdiscard|dm.override_udev_sync_check|dm.use_deferred_removal|dm.use_deferred_deletion)
2337 			COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
2338 			return
2339 			;;
2340		dm.directlvm_device|dm.thinpooldev)
2341			cur=${cur##*=}
2342			_filedir
2343			return
2344			;;
2345		dm.fs)
2346			COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur##*=}" ) )
2347			return
2348			;;
2349		dm.libdm_log_level)
2350			COMPREPLY=( $( compgen -W "2 3 4 5 6 7" -- "${cur##*=}" ) )
2351			return
2352			;;
2353 	esac
2354
2355	case "$prev" in
2356		--authorization-plugin)
2357			__docker_complete_plugins_bundled --type Authorization
2358			return
2359			;;
2360		--cluster-store)
2361			COMPREPLY=( $( compgen -W "consul etcd zk" -S "://" -- "$cur" ) )
2362			__docker_nospace
2363			return
2364			;;
2365		--cluster-store-opt)
2366			COMPREPLY=( $( compgen -W "discovery.heartbeat discovery.ttl kv.cacertfile kv.certfile kv.keyfile kv.path" -S = -- "$cur" ) )
2367			__docker_nospace
2368			return
2369			;;
2370		--config-file|--containerd|--init-path|--pidfile|-p|--tlscacert|--tlscert|--tlskey|--userland-proxy-path)
2371			_filedir
2372			return
2373			;;
2374		--exec-root|--data-root)
2375			_filedir -d
2376			return
2377			;;
2378		--log-driver)
2379			__docker_complete_log_drivers
2380			return
2381			;;
2382		--storage-driver|-s)
2383			COMPREPLY=( $( compgen -W "aufs btrfs devicemapper overlay overlay2 vfs zfs" -- "$(echo "$cur" | tr '[:upper:]' '[:lower:]')" ) )
2384			return
2385			;;
2386		--storage-opt)
2387			local btrfs_options="btrfs.min_space"
2388			local devicemapper_options="
2389				dm.basesize
2390				dm.blkdiscard
2391				dm.blocksize
2392				dm.directlvm_device
2393				dm.fs
2394				dm.libdm_log_level
2395				dm.loopdatasize
2396				dm.loopmetadatasize
2397				dm.min_free_space
2398				dm.mkfsarg
2399				dm.mountopt
2400				dm.override_udev_sync_check
2401				dm.thinpooldev
2402				dm.thinp_autoextend_percent
2403				dm.thinp_autoextend_threshold
2404				dm.thinp_metapercent
2405				dm.thinp_percent
2406				dm.use_deferred_deletion
2407				dm.use_deferred_removal
2408			"
2409			local overlay2_options="overlay2.size"
2410			local zfs_options="zfs.fsname"
2411
2412			local all_options="$btrfs_options $devicemapper_options $overlay2_options $zfs_options"
2413
2414			case $(__docker_value_of_option '--storage-driver|-s') in
2415				'')
2416					COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) )
2417					;;
2418				btrfs)
2419					COMPREPLY=( $( compgen -W "$btrfs_options" -S = -- "$cur" ) )
2420					;;
2421				devicemapper)
2422					COMPREPLY=( $( compgen -W "$devicemapper_options" -S = -- "$cur" ) )
2423					;;
2424				overlay2)
2425					COMPREPLY=( $( compgen -W "$overlay2_options" -S = -- "$cur" ) )
2426					;;
2427				zfs)
2428					COMPREPLY=( $( compgen -W "$zfs_options" -S = -- "$cur" ) )
2429					;;
2430				*)
2431					return
2432					;;
2433			esac
2434			__docker_nospace
2435			return
2436			;;
2437		--log-level|-l)
2438			__docker_complete_log_levels
2439			return
2440			;;
2441		--log-opt)
2442			__docker_complete_log_options
2443			return
2444			;;
2445		--metrics-addr)
2446			__docker_complete_local_ips
2447			__docker_append_to_completions ":"
2448			__docker_nospace
2449			return
2450			;;
2451		--seccomp-profile)
2452			_filedir json
2453			return
2454			;;
2455		--swarm-default-advertise-addr)
2456			__docker_complete_local_interfaces
2457			return
2458			;;
2459		--userns-remap)
2460			__docker_complete_user_group
2461			return
2462			;;
2463		$(__docker_to_extglob "$options_with_args") )
2464			return
2465			;;
2466	esac
2467
2468	case "$cur" in
2469		-*)
2470			COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) )
2471			;;
2472	esac
2473}
2474
2475_docker_deploy() {
2476	__docker_server_is_experimental && _docker_stack_deploy
2477}
2478
2479_docker_diff() {
2480	_docker_container_diff
2481}
2482
2483_docker_events() {
2484	_docker_system_events
2485}
2486
2487_docker_exec() {
2488	_docker_container_exec
2489}
2490
2491_docker_export() {
2492	_docker_container_export
2493}
2494
2495_docker_help() {
2496	local counter=$(__docker_pos_first_nonflag)
2497	if [ "$cword" -eq "$counter" ]; then
2498		COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
2499	fi
2500}
2501
2502_docker_history() {
2503	_docker_image_history
2504}
2505
2506
2507_docker_image() {
2508	local subcommands="
2509		build
2510		history
2511		import
2512		inspect
2513		load
2514		ls
2515		prune
2516		pull
2517		push
2518		rm
2519		save
2520		tag
2521	"
2522	local aliases="
2523		images
2524		list
2525		remove
2526		rmi
2527	"
2528	__docker_subcommands "$subcommands $aliases" && return
2529
2530	case "$cur" in
2531		-*)
2532			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
2533			;;
2534		*)
2535			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
2536			;;
2537	esac
2538}
2539
2540_docker_image_build() {
2541	local options_with_args="
2542		--add-host
2543		--build-arg
2544		--cache-from
2545		--cgroup-parent
2546		--cpuset-cpus
2547		--cpuset-mems
2548		--cpu-shares -c
2549		--cpu-period
2550		--cpu-quota
2551		--file -f
2552		--iidfile
2553		--label
2554		--memory -m
2555		--memory-swap
2556		--network
2557		--shm-size
2558		--tag -t
2559		--target
2560		--ulimit
2561	"
2562	__docker_server_os_is windows && options_with_args+="
2563		--isolation
2564	"
2565
2566	local boolean_options="
2567		--compress
2568		--disable-content-trust=false
2569		--force-rm
2570		--help
2571		--no-cache
2572		--pull
2573		--quiet -q
2574		--rm
2575	"
2576	if __docker_server_is_experimental ; then
2577		options_with_args+="
2578			--platform
2579		"
2580		boolean_options+="
2581			--squash
2582			--stream
2583		"
2584	fi
2585
2586	local all_options="$options_with_args $boolean_options"
2587
2588	case "$prev" in
2589		--add-host)
2590			case "$cur" in
2591				*:)
2592					__docker_complete_resolved_hostname
2593					return
2594					;;
2595			esac
2596			;;
2597		--build-arg)
2598			COMPREPLY=( $( compgen -e -- "$cur" ) )
2599			__docker_nospace
2600			return
2601			;;
2602		--cache-from)
2603			__docker_complete_images --repo --tag --id
2604			return
2605			;;
2606		--file|-f|--iidfile)
2607			_filedir
2608			return
2609			;;
2610		--isolation)
2611			if __docker_server_os_is windows ; then
2612				__docker_complete_isolation
2613				return
2614			fi
2615			;;
2616		--network)
2617			case "$cur" in
2618				container:*)
2619					__docker_complete_containers_all --cur "${cur#*:}"
2620					;;
2621				*)
2622					COMPREPLY=( $( compgen -W "$(__docker_plugins_bundled --type Network) $(__docker_networks) container:" -- "$cur") )
2623					if [ "${COMPREPLY[*]}" = "container:" ] ; then
2624						__docker_nospace
2625					fi
2626					;;
2627			esac
2628			return
2629			;;
2630		--tag|-t)
2631			__docker_complete_images --repo --tag
2632			return
2633			;;
2634		--target)
2635			local context_pos=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" )
2636			local context="${words[$context_pos]}"
2637			context="${context:-.}"
2638
2639			local file="$( __docker_value_of_option '--file|f' )"
2640			local default_file="${context%/}/Dockerfile"
2641			local dockerfile="${file:-$default_file}"
2642
2643			local targets="$( sed -n 's/^FROM .\+ AS \(.\+\)/\1/p' "$dockerfile" 2>/dev/null )"
2644			COMPREPLY=( $( compgen -W "$targets" -- "$cur" ) )
2645			return
2646			;;
2647		$(__docker_to_extglob "$options_with_args") )
2648			return
2649			;;
2650	esac
2651
2652	case "$cur" in
2653		-*)
2654			COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) )
2655			;;
2656		*)
2657			local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" )
2658			if [ "$cword" -eq "$counter" ]; then
2659				_filedir -d
2660			fi
2661			;;
2662	esac
2663}
2664
2665_docker_image_history() {
2666	case "$prev" in
2667		--format)
2668			return
2669			;;
2670	esac
2671
2672	case "$cur" in
2673		-*)
2674			COMPREPLY=( $( compgen -W "--format --help --human=false -H=false --no-trunc --quiet -q" -- "$cur" ) )
2675			;;
2676		*)
2677			local counter=$(__docker_pos_first_nonflag '--format')
2678			if [ "$cword" -eq "$counter" ]; then
2679				__docker_complete_images --force-tag --id
2680			fi
2681			;;
2682	esac
2683}
2684
2685_docker_image_images() {
2686	_docker_image_ls
2687}
2688
2689_docker_image_import() {
2690	case "$prev" in
2691		--change|-c|--message|-m|--platform)
2692			return
2693			;;
2694	esac
2695
2696	case "$cur" in
2697		-*)
2698			local options="--change -c --help --message -m"
2699			__docker_server_is_experimental && options+=" --platform"
2700			COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )
2701			;;
2702		*)
2703			local counter=$(__docker_pos_first_nonflag '--change|-c|--message|-m')
2704			if [ "$cword" -eq "$counter" ]; then
2705				_filedir
2706				return
2707			elif [ "$cword" -eq "$((counter + 1))" ]; then
2708				__docker_complete_images --repo --tag
2709				return
2710			fi
2711			;;
2712	esac
2713}
2714
2715_docker_image_inspect() {
2716	_docker_inspect --type image
2717}
2718
2719_docker_image_load() {
2720	case "$prev" in
2721		--input|-i|"<")
2722			_filedir
2723			return
2724			;;
2725	esac
2726
2727	case "$cur" in
2728		-*)
2729			COMPREPLY=( $( compgen -W "--help --input -i --quiet -q" -- "$cur" ) )
2730			;;
2731	esac
2732}
2733
2734_docker_image_list() {
2735	_docker_image_ls
2736}
2737
2738_docker_image_ls() {
2739	local key=$(__docker_map_key_of_current_option '--filter|-f')
2740	case "$key" in
2741		before|since)
2742			__docker_complete_images --cur "${cur##*=}" --force-tag --id
2743			return
2744			;;
2745		dangling)
2746			COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
2747			return
2748			;;
2749		label)
2750			return
2751			;;
2752		reference)
2753			__docker_complete_images --cur "${cur##*=}" --repo --tag
2754			return
2755			;;
2756	esac
2757
2758	case "$prev" in
2759		--filter|-f)
2760			COMPREPLY=( $( compgen -S = -W "before dangling label reference since" -- "$cur" ) )
2761			__docker_nospace
2762			return
2763			;;
2764                --format)
2765			return
2766			;;
2767	esac
2768
2769	case "$cur" in
2770		-*)
2771			COMPREPLY=( $( compgen -W "--all -a --digests --filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) )
2772			;;
2773		=)
2774			return
2775			;;
2776		*)
2777			__docker_complete_images --repo --tag
2778			;;
2779	esac
2780}
2781
2782_docker_image_prune() {
2783	case "$prev" in
2784		--filter)
2785			COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) )
2786			__docker_nospace
2787			return
2788			;;
2789	esac
2790
2791	case "$cur" in
2792		-*)
2793			COMPREPLY=( $( compgen -W "--all -a --force -f --filter --help" -- "$cur" ) )
2794			;;
2795	esac
2796}
2797
2798_docker_image_pull() {
2799	case "$prev" in
2800		--platform)
2801			return
2802			;;
2803	esac
2804
2805	case "$cur" in
2806		-*)
2807			local options="--all-tags -a --disable-content-trust=false --help"
2808			__docker_server_is_experimental && options+=" --platform"
2809
2810			COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )
2811			;;
2812		*)
2813			local counter=$(__docker_pos_first_nonflag --platform)
2814			if [ "$cword" -eq "$counter" ]; then
2815				for arg in "${COMP_WORDS[@]}"; do
2816					case "$arg" in
2817						--all-tags|-a)
2818							__docker_complete_images --repo
2819							return
2820							;;
2821					esac
2822				done
2823				__docker_complete_images --repo --tag
2824			fi
2825			;;
2826	esac
2827}
2828
2829_docker_image_push() {
2830	case "$cur" in
2831		-*)
2832			COMPREPLY=( $( compgen -W "--disable-content-trust=false --help" -- "$cur" ) )
2833			;;
2834		*)
2835			local counter=$(__docker_pos_first_nonflag)
2836			if [ "$cword" -eq "$counter" ]; then
2837				__docker_complete_images --repo --tag
2838			fi
2839			;;
2840	esac
2841}
2842
2843_docker_image_remove() {
2844	_docker_image_rm
2845}
2846
2847_docker_image_rm() {
2848	case "$cur" in
2849		-*)
2850			COMPREPLY=( $( compgen -W "--force -f --help --no-prune" -- "$cur" ) )
2851			;;
2852		*)
2853			__docker_complete_images --force-tag --id
2854			;;
2855	esac
2856}
2857
2858_docker_image_rmi() {
2859	_docker_image_rm
2860}
2861
2862_docker_image_save() {
2863	case "$prev" in
2864		--output|-o|">")
2865			_filedir
2866			return
2867			;;
2868	esac
2869
2870	case "$cur" in
2871		-*)
2872			COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) )
2873			;;
2874		*)
2875			__docker_complete_images --repo --tag --id
2876			;;
2877	esac
2878}
2879
2880_docker_image_tag() {
2881	case "$cur" in
2882		-*)
2883			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
2884			;;
2885		*)
2886			local counter=$(__docker_pos_first_nonflag)
2887
2888			if [ "$cword" -eq "$counter" ]; then
2889				__docker_complete_images --force-tag --id
2890				return
2891			elif [ "$cword" -eq "$((counter + 1))" ]; then
2892				__docker_complete_images --repo --tag
2893				return
2894			fi
2895			;;
2896	esac
2897}
2898
2899
2900_docker_images() {
2901	_docker_image_ls
2902}
2903
2904_docker_import() {
2905	_docker_image_import
2906}
2907
2908_docker_info() {
2909	_docker_system_info
2910}
2911
2912_docker_inspect() {
2913	local preselected_type
2914	local type
2915
2916	if [ "$1" = "--type" ] ; then
2917		preselected_type=yes
2918		type="$2"
2919	else
2920		type=$(__docker_value_of_option --type)
2921	fi
2922
2923	case "$prev" in
2924		--format|-f)
2925			return
2926			;;
2927		--type)
2928			if [ -z "$preselected_type" ] ; then
2929				COMPREPLY=( $( compgen -W "container image network node plugin secret service volume" -- "$cur" ) )
2930				return
2931			fi
2932			;;
2933	esac
2934
2935	case "$cur" in
2936		-*)
2937			local options="--format -f --help --size -s"
2938			if [ -z "$preselected_type" ] ; then
2939				options+=" --type"
2940			fi
2941			COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )
2942			;;
2943		*)
2944			case "$type" in
2945				'')
2946					COMPREPLY=( $( compgen -W "
2947						$(__docker_containers --all)
2948						$(__docker_images --force-tag --id)
2949						$(__docker_networks)
2950						$(__docker_nodes)
2951						$(__docker_plugins_installed)
2952						$(__docker_secrets)
2953						$(__docker_services)
2954						$(__docker_volumes)
2955					" -- "$cur" ) )
2956					__ltrim_colon_completions "$cur"
2957					;;
2958				container)
2959					__docker_complete_containers_all
2960					;;
2961				image)
2962					__docker_complete_images --force-tag --id
2963					;;
2964				network)
2965					__docker_complete_networks
2966					;;
2967				node)
2968					__docker_complete_nodes
2969					;;
2970				plugin)
2971					__docker_complete_plugins_installed
2972					;;
2973				secret)
2974					__docker_complete_secrets
2975					;;
2976				service)
2977					__docker_complete_services
2978					;;
2979				volume)
2980					__docker_complete_volumes
2981					;;
2982			esac
2983	esac
2984}
2985
2986_docker_kill() {
2987	_docker_container_kill
2988}
2989
2990_docker_load() {
2991	_docker_image_load
2992}
2993
2994_docker_login() {
2995	case "$prev" in
2996		--password|-p|--username|-u)
2997			return
2998			;;
2999	esac
3000
3001	case "$cur" in
3002		-*)
3003			COMPREPLY=( $( compgen -W "--help --password -p --password-stdin --username -u" -- "$cur" ) )
3004			;;
3005	esac
3006}
3007
3008_docker_logout() {
3009	case "$cur" in
3010		-*)
3011			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
3012			;;
3013	esac
3014}
3015
3016_docker_logs() {
3017	_docker_container_logs
3018}
3019
3020_docker_network_connect() {
3021	local options_with_args="
3022		--alias
3023		--ip
3024		--ip6
3025		--link
3026		--link-local-ip
3027	"
3028
3029	local boolean_options="
3030		--help
3031	"
3032
3033	case "$prev" in
3034		--link)
3035			case "$cur" in
3036				*:*)
3037					;;
3038				*)
3039					__docker_complete_containers_running
3040					COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) )
3041					__docker_nospace
3042					;;
3043			esac
3044			return
3045			;;
3046		$(__docker_to_extglob "$options_with_args") )
3047			return
3048			;;
3049	esac
3050
3051	case "$cur" in
3052		-*)
3053			COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) )
3054			;;
3055		*)
3056			local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" )
3057			if [ "$cword" -eq "$counter" ]; then
3058				__docker_complete_networks
3059			elif [ "$cword" -eq "$((counter + 1))" ]; then
3060				__docker_complete_containers_all
3061			fi
3062			;;
3063	esac
3064}
3065
3066_docker_network_create() {
3067	case "$prev" in
3068		--aux-address|--gateway|--ip-range|--ipam-opt|--ipv6|--opt|-o|--subnet)
3069			return
3070			;;
3071		--config-from)
3072			__docker_complete_networks
3073			return
3074			;;
3075		--driver|-d)
3076			# remove drivers that allow one instance only, add drivers missing in `docker info`
3077			__docker_complete_plugins_bundled --type Network --remove host --remove null --add macvlan
3078			return
3079			;;
3080		--ipam-driver)
3081			COMPREPLY=( $( compgen -W "default" -- "$cur" ) )
3082			return
3083			;;
3084		--label)
3085			return
3086			;;
3087		--scope)
3088			COMPREPLY=( $( compgen -W "local swarm" -- "$cur" ) )
3089			return
3090			;;
3091	esac
3092
3093	case "$cur" in
3094		-*)
3095			COMPREPLY=( $( compgen -W "--attachable --aux-address --config-from --config-only --driver -d --gateway --help --ingress --internal --ip-range --ipam-driver --ipam-opt --ipv6 --label --opt -o --scope --subnet" -- "$cur" ) )
3096			;;
3097	esac
3098}
3099
3100_docker_network_disconnect() {
3101	case "$cur" in
3102		-*)
3103			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
3104			;;
3105		*)
3106			local counter=$(__docker_pos_first_nonflag)
3107			if [ "$cword" -eq "$counter" ]; then
3108				__docker_complete_networks
3109			elif [ "$cword" -eq "$((counter + 1))" ]; then
3110				__docker_complete_containers_in_network "$prev"
3111			fi
3112			;;
3113	esac
3114}
3115
3116_docker_network_inspect() {
3117	case "$prev" in
3118		--format|-f)
3119			return
3120			;;
3121	esac
3122
3123	case "$cur" in
3124		-*)
3125			COMPREPLY=( $( compgen -W "--format -f --help --verbose" -- "$cur" ) )
3126			;;
3127		*)
3128			__docker_complete_networks
3129	esac
3130}
3131
3132_docker_network_ls() {
3133	local key=$(__docker_map_key_of_current_option '--filter|-f')
3134	case "$key" in
3135		driver)
3136			__docker_complete_plugins_bundled --cur "${cur##*=}" --type Network --add macvlan
3137			return
3138			;;
3139		id)
3140			__docker_complete_networks --cur "${cur##*=}" --id
3141			return
3142			;;
3143		name)
3144			__docker_complete_networks --cur "${cur##*=}" --name
3145			return
3146			;;
3147		scope)
3148			COMPREPLY=( $( compgen -W "global local swarm" -- "${cur##*=}" ) )
3149			return
3150			;;
3151		type)
3152			COMPREPLY=( $( compgen -W "builtin custom" -- "${cur##*=}" ) )
3153			return
3154			;;
3155	esac
3156
3157	case "$prev" in
3158		--filter|-f)
3159			COMPREPLY=( $( compgen -S = -W "driver id label name scope type" -- "$cur" ) )
3160			__docker_nospace
3161			return
3162			;;
3163		--format)
3164			return
3165			;;
3166	esac
3167
3168	case "$cur" in
3169		-*)
3170			COMPREPLY=( $( compgen -W "--filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) )
3171			;;
3172	esac
3173}
3174
3175_docker_network_prune() {
3176	case "$prev" in
3177		--filter)
3178			COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) )
3179			__docker_nospace
3180			return
3181			;;
3182	esac
3183
3184	case "$cur" in
3185		-*)
3186			COMPREPLY=( $( compgen -W "--force -f --filter --help" -- "$cur" ) )
3187			;;
3188	esac
3189}
3190
3191_docker_network_rm() {
3192	case "$cur" in
3193		-*)
3194			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
3195			;;
3196		*)
3197			__docker_complete_networks --filter type=custom
3198	esac
3199}
3200
3201_docker_network() {
3202	local subcommands="
3203		connect
3204		create
3205		disconnect
3206		inspect
3207		ls
3208		prune
3209		rm
3210	"
3211	local aliases="
3212		list
3213		remove
3214	"
3215	__docker_subcommands "$subcommands $aliases" && return
3216
3217	case "$cur" in
3218		-*)
3219			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
3220			;;
3221		*)
3222			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
3223			;;
3224	esac
3225}
3226
3227_docker_service() {
3228	local subcommands="
3229		create
3230		inspect
3231		logs
3232		ls
3233		rm
3234		rollback
3235		scale
3236		ps
3237		update
3238	"
3239
3240	local aliases="
3241		list
3242		remove
3243	"
3244	__docker_subcommands "$subcommands $aliases" && return
3245
3246	case "$cur" in
3247		-*)
3248			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
3249			;;
3250		*)
3251			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
3252			;;
3253	esac
3254}
3255
3256_docker_service_create() {
3257	_docker_service_update_and_create
3258}
3259
3260_docker_service_inspect() {
3261	case "$prev" in
3262		--format|-f)
3263			return
3264			;;
3265	esac
3266
3267	case "$cur" in
3268		-*)
3269			COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) )
3270			;;
3271		*)
3272			__docker_complete_services
3273	esac
3274}
3275
3276_docker_service_logs() {
3277	case "$prev" in
3278		--since|--tail)
3279			return
3280			;;
3281	esac
3282
3283	case "$cur" in
3284		-*)
3285			COMPREPLY=( $( compgen -W "--details --follow -f --help --no-resolve --no-task-ids --no-trunc --raw --since --tail --timestamps -t" -- "$cur" ) )
3286			;;
3287		*)
3288			local counter=$(__docker_pos_first_nonflag '--since|--tail')
3289			if [ "$cword" -eq "$counter" ]; then
3290				__docker_complete_services_and_tasks
3291			fi
3292			;;
3293	esac
3294}
3295
3296_docker_service_list() {
3297	_docker_service_ls
3298}
3299
3300_docker_service_ls() {
3301	local key=$(__docker_map_key_of_current_option '--filter|-f')
3302	case "$key" in
3303		id)
3304			__docker_complete_services --cur "${cur##*=}" --id
3305			return
3306			;;
3307		mode)
3308			COMPREPLY=( $( compgen -W "global replicated" -- "${cur##*=}" ) )
3309			return
3310			;;
3311		name)
3312			__docker_complete_services --cur "${cur##*=}" --name
3313			return
3314			;;
3315	esac
3316
3317	case "$prev" in
3318		--filter|-f)
3319			COMPREPLY=( $( compgen -W "id label mode name" -S = -- "$cur" ) )
3320			__docker_nospace
3321			return
3322			;;
3323		--format)
3324			return
3325			;;
3326	esac
3327
3328	case "$cur" in
3329		-*)
3330			COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) )
3331			;;
3332	esac
3333}
3334
3335_docker_service_remove() {
3336	_docker_service_rm
3337}
3338
3339_docker_service_rm() {
3340	case "$cur" in
3341		-*)
3342			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
3343			;;
3344		*)
3345			__docker_complete_services
3346	esac
3347}
3348
3349_docker_service_rollback() {
3350	case "$cur" in
3351		-*)
3352			COMPREPLY=( $( compgen -W "--detach -d --help --quit -q" -- "$cur" ) )
3353			;;
3354		*)
3355			local counter=$( __docker_pos_first_nonflag )
3356			if [ "$cword" -eq "$counter" ]; then
3357				__docker_complete_services
3358			fi
3359			;;
3360	esac
3361}
3362
3363_docker_service_scale() {
3364	case "$cur" in
3365		-*)
3366			COMPREPLY=( $( compgen -W "--detach -d --help" -- "$cur" ) )
3367			;;
3368		*)
3369			__docker_complete_services
3370			__docker_append_to_completions "="
3371			__docker_nospace
3372			;;
3373	esac
3374}
3375
3376_docker_service_ps() {
3377	local key=$(__docker_map_key_of_current_option '--filter|-f')
3378	case "$key" in
3379		desired-state)
3380			COMPREPLY=( $( compgen -W "accepted running shutdown" -- "${cur##*=}" ) )
3381			return
3382			;;
3383		name)
3384			__docker_complete_services --cur "${cur##*=}" --name
3385			return
3386			;;
3387		node)
3388			__docker_complete_nodes --cur "${cur##*=}" --add self
3389			return
3390			;;
3391	esac
3392
3393	case "$prev" in
3394		--filter|-f)
3395			COMPREPLY=( $( compgen -W "desired-state id name node" -S = -- "$cur" ) )
3396			__docker_nospace
3397			return
3398			;;
3399		--format)
3400			return
3401			;;
3402	esac
3403
3404	case "$cur" in
3405		-*)
3406			COMPREPLY=( $( compgen -W "--filter -f --format --help --no-resolve --no-trunc --quiet -q" -- "$cur" ) )
3407			;;
3408		*)
3409			__docker_complete_services
3410			;;
3411	esac
3412}
3413
3414_docker_service_update() {
3415	_docker_service_update_and_create
3416}
3417
3418# _docker_service_update_and_create is the combined completion for `docker service create`
3419# and `docker service update`
3420_docker_service_update_and_create() {
3421	local options_with_args="
3422		--endpoint-mode
3423		--entrypoint
3424		--health-cmd
3425		--health-interval
3426		--health-retries
3427		--health-start-period
3428		--health-timeout
3429		--hostname
3430		--isolation
3431		--limit-cpu
3432		--limit-memory
3433		--log-driver
3434		--log-opt
3435		--replicas
3436		--reserve-cpu
3437		--reserve-memory
3438		--restart-condition
3439		--restart-delay
3440		--restart-max-attempts
3441		--restart-window
3442		--rollback-delay
3443		--rollback-failure-action
3444		--rollback-max-failure-ratio
3445		--rollback-monitor
3446		--rollback-order
3447		--rollback-parallelism
3448		--stop-grace-period
3449		--stop-signal
3450		--update-delay
3451		--update-failure-action
3452		--update-max-failure-ratio
3453		--update-monitor
3454		--update-order
3455		--update-parallelism
3456		--user -u
3457		--workdir -w
3458	"
3459	__docker_server_os_is windows && options_with_args+="
3460		--credential-spec
3461	"
3462
3463	local boolean_options="
3464		--detach -d
3465		--help
3466		--init
3467		--no-healthcheck
3468		--read-only
3469		--tty -t
3470		--with-registry-auth
3471	"
3472
3473	__docker_complete_log_driver_options && return
3474
3475	if [ "$subcommand" = "create" ] ; then
3476		options_with_args="$options_with_args
3477			--config
3478			--constraint
3479			--container-label
3480			--dns
3481			--dns-option
3482			--dns-search
3483			--env -e
3484			--env-file
3485			--generic-resource
3486			--group
3487			--host
3488			--label -l
3489			--mode
3490			--mount
3491			--name
3492			--network
3493			--placement-pref
3494			--publish -p
3495			--secret
3496		"
3497
3498		case "$prev" in
3499			--env-file)
3500				_filedir
3501				return
3502				;;
3503			--mode)
3504				COMPREPLY=( $( compgen -W "global replicated" -- "$cur" ) )
3505				return
3506				;;
3507		esac
3508	fi
3509	if [ "$subcommand" = "update" ] ; then
3510		options_with_args="$options_with_args
3511			--args
3512			--config-add
3513			--config-rm
3514			--constraint-add
3515			--constraint-rm
3516			--container-label-add
3517			--container-label-rm
3518			--dns-add
3519			--dns-option-add
3520			--dns-option-rm
3521			--dns-rm
3522			--dns-search-add
3523			--dns-search-rm
3524			--env-add
3525			--env-rm
3526			--generic-resource-add
3527			--generic-resource-rm
3528			--group-add
3529			--group-rm
3530			--host-add
3531			--host-rm
3532			--image
3533			--label-add
3534			--label-rm
3535			--mount-add
3536			--mount-rm
3537			--network-add
3538			--network-rm
3539			--placement-pref-add
3540			--placement-pref-rm
3541			--publish-add
3542			--publish-rm
3543			--rollback
3544			--secret-add
3545			--secret-rm
3546		"
3547
3548		boolean_options="$boolean_options
3549			--force
3550		"
3551
3552		case "$prev" in
3553			--env-rm)
3554				COMPREPLY=( $( compgen -e -- "$cur" ) )
3555				return
3556				;;
3557			--image)
3558				__docker_complete_images --repo --tag --id
3559				return
3560				;;
3561		esac
3562	fi
3563
3564	local strategy=$(__docker_map_key_of_current_option '--placement-pref|--placement-pref-add|--placement-pref-rm')
3565	case "$strategy" in
3566		spread)
3567			COMPREPLY=( $( compgen -W "engine.labels node.labels" -S . -- "${cur##*=}" ) )
3568			__docker_nospace
3569			return
3570			;;
3571	esac
3572
3573	case "$prev" in
3574		--config|--config-add|--config-rm)
3575			__docker_complete_configs
3576			return
3577			;;
3578		--endpoint-mode)
3579			COMPREPLY=( $( compgen -W "dnsrr vip" -- "$cur" ) )
3580			return
3581			;;
3582		--env|-e|--env-add)
3583			# we do not append a "=" here because "-e VARNAME" is legal systax, too
3584			COMPREPLY=( $( compgen -e -- "$cur" ) )
3585			__docker_nospace
3586			return
3587			;;
3588		--group|--group-add|--group-rm)
3589			COMPREPLY=( $(compgen -g -- "$cur") )
3590			return
3591			;;
3592		--host|--host-add|--host-rm)
3593			case "$cur" in
3594				*:)
3595					__docker_complete_resolved_hostname
3596					return
3597					;;
3598			esac
3599			;;
3600		--isolation)
3601			__docker_complete_isolation
3602			return
3603			;;
3604		--log-driver)
3605			__docker_complete_log_drivers
3606			return
3607			;;
3608		--log-opt)
3609			__docker_complete_log_options
3610			return
3611			;;
3612		--network|--network-add|--network-rm)
3613			__docker_complete_networks
3614			return
3615			;;
3616		--placement-pref|--placement-pref-add|--placement-pref-rm)
3617			COMPREPLY=( $( compgen -W "spread" -S = -- "$cur" ) )
3618			__docker_nospace
3619			return
3620			;;
3621		--restart-condition)
3622			COMPREPLY=( $( compgen -W "any none on-failure" -- "$cur" ) )
3623			return
3624			;;
3625		--rollback-failure-action)
3626			COMPREPLY=( $( compgen -W "continue pause" -- "$cur" ) )
3627			return
3628			;;
3629		--secret|--secret-add|--secret-rm)
3630			__docker_complete_secrets
3631			return
3632			;;
3633		--stop-signal)
3634			__docker_complete_signals
3635			return
3636			;;
3637		--update-failure-action)
3638			COMPREPLY=( $( compgen -W "continue pause rollback" -- "$cur" ) )
3639			return
3640			;;
3641		--update-order|--rollback-order)
3642			COMPREPLY=( $( compgen -W "start-first stop-first" -- "$cur" ) )
3643			return
3644			;;
3645		--user|-u)
3646			__docker_complete_user_group
3647			return
3648			;;
3649		$(__docker_to_extglob "$options_with_args") )
3650			return
3651			;;
3652	esac
3653
3654	case "$cur" in
3655		-*)
3656			COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) )
3657			;;
3658		*)
3659			local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" )
3660			if [ "$subcommand" = "update" ] ; then
3661				if [ "$cword" -eq "$counter" ]; then
3662					__docker_complete_services
3663				fi
3664			else
3665				if [ "$cword" -eq "$counter" ]; then
3666					__docker_complete_images --repo --tag --id
3667				fi
3668			fi
3669			;;
3670	esac
3671}
3672
3673_docker_swarm() {
3674	local subcommands="
3675		ca
3676		init
3677		join
3678		join-token
3679		leave
3680		unlock
3681		unlock-key
3682		update
3683	"
3684	__docker_subcommands "$subcommands" && return
3685
3686	case "$cur" in
3687		-*)
3688			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
3689			;;
3690		*)
3691			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
3692			;;
3693	esac
3694}
3695
3696_docker_swarm_ca() {
3697	case "$prev" in
3698		--ca-cert|--ca-key)
3699			_filedir
3700			return
3701			;;
3702		--cert-expiry|--external-ca)
3703			return
3704			;;
3705	esac
3706
3707	case "$cur" in
3708		-*)
3709			COMPREPLY=( $( compgen -W "--ca-cert --ca-key --cert-expiry --detach -d --external-ca --help --quiet -q --rotate" -- "$cur" ) )
3710			;;
3711	esac
3712}
3713
3714_docker_swarm_init() {
3715	case "$prev" in
3716		--advertise-addr)
3717			if [[ $cur == *: ]] ; then
3718				COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) )
3719			else
3720				__docker_complete_local_interfaces
3721				__docker_nospace
3722			fi
3723			return
3724			;;
3725		--availability)
3726			COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) )
3727			return
3728			;;
3729		--cert-expiry|--default-addr-pool|--default-addr-pool-mask-length|--dispatcher-heartbeat|--external-ca|--max-snapshots|--snapshot-interval|--task-history-limit )
3730			return
3731			;;
3732		--data-path-addr)
3733			__docker_complete_local_interfaces
3734			return
3735			;;
3736		--listen-addr)
3737			if [[ $cur == *: ]] ; then
3738				COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) )
3739			else
3740				__docker_complete_local_interfaces --add 0.0.0.0
3741				__docker_nospace
3742			fi
3743			return
3744			;;
3745	esac
3746
3747	case "$cur" in
3748		-*)
3749			COMPREPLY=( $( compgen -W "--advertise-addr --autolock --availability --cert-expiry --data-path-addr --default-addr-pool --default-addr-pool-mask-length --dispatcher-heartbeat --external-ca --force-new-cluster --help --listen-addr --max-snapshots --snapshot-interval --task-history-limit" -- "$cur" ) )
3750			;;
3751	esac
3752}
3753
3754_docker_swarm_join() {
3755	case "$prev" in
3756		--advertise-addr)
3757			if [[ $cur == *: ]] ; then
3758				COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) )
3759			else
3760				__docker_complete_local_interfaces
3761				__docker_nospace
3762			fi
3763			return
3764			;;
3765		--availability)
3766			COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) )
3767			return
3768			;;
3769		--data-path-addr)
3770			__docker_complete_local_interfaces
3771			return
3772			;;
3773		--listen-addr)
3774			if [[ $cur == *: ]] ; then
3775				COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) )
3776			else
3777				__docker_complete_local_interfaces --add 0.0.0.0
3778				__docker_nospace
3779			fi
3780			return
3781			;;
3782		--token)
3783			return
3784			;;
3785	esac
3786
3787	case "$cur" in
3788		-*)
3789			COMPREPLY=( $( compgen -W "--advertise-addr --availability --data-path-addr --help --listen-addr --token" -- "$cur" ) )
3790			;;
3791		*:)
3792			COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) )
3793			;;
3794	esac
3795}
3796
3797_docker_swarm_join_token() {
3798	case "$cur" in
3799		-*)
3800			COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) )
3801			;;
3802		*)
3803			local counter=$( __docker_pos_first_nonflag )
3804			if [ "$cword" -eq "$counter" ]; then
3805				COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) )
3806			fi
3807			;;
3808	esac
3809}
3810
3811_docker_swarm_leave() {
3812	case "$cur" in
3813		-*)
3814			COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) )
3815			;;
3816	esac
3817}
3818
3819_docker_swarm_unlock() {
3820	case "$cur" in
3821		-*)
3822			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
3823			;;
3824	esac
3825}
3826
3827_docker_swarm_unlock_key() {
3828	case "$cur" in
3829		-*)
3830			COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) )
3831			;;
3832	esac
3833}
3834
3835_docker_swarm_update() {
3836	case "$prev" in
3837		--cert-expiry|--dispatcher-heartbeat|--external-ca|--max-snapshots|--snapshot-interval|--task-history-limit)
3838			return
3839			;;
3840	esac
3841
3842	case "$cur" in
3843		-*)
3844			COMPREPLY=( $( compgen -W "--autolock --cert-expiry --dispatcher-heartbeat --external-ca --help --max-snapshots --snapshot-interval --task-history-limit" -- "$cur" ) )
3845			;;
3846	esac
3847}
3848
3849_docker_manifest() {
3850	local subcommands="
3851		annotate
3852		create
3853		inspect
3854		push
3855	"
3856	__docker_subcommands "$subcommands" && return
3857
3858	case "$cur" in
3859		-*)
3860			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
3861			;;
3862		*)
3863			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
3864			;;
3865	esac
3866}
3867
3868_docker_manifest_annotate() {
3869	case "$prev" in
3870		--arch)
3871			COMPREPLY=( $( compgen -W "
3872				386
3873				amd64
3874				arm
3875				arm64
3876				mips64
3877				mips64le
3878				ppc64le
3879				s390x" -- "$cur" ) )
3880			return
3881			;;
3882		--os)
3883			COMPREPLY=( $( compgen -W "
3884				darwin
3885				dragonfly
3886				freebsd
3887				linux
3888				netbsd
3889				openbsd
3890				plan9
3891				solaris
3892				windows" -- "$cur" ) )
3893			return
3894			;;
3895		--os-features|--variant)
3896			return
3897			;;
3898	esac
3899
3900	case "$cur" in
3901		-*)
3902			COMPREPLY=( $( compgen -W "--arch --help --os --os-features --variant" -- "$cur" ) )
3903			;;
3904		*)
3905			local counter=$( __docker_pos_first_nonflag "--arch|--os|--os-features|--variant" )
3906			if [ "$cword" -eq "$counter" ] || [ "$cword" -eq "$((counter + 1))" ]; then
3907				__docker_complete_images --force-tag --id
3908			fi
3909			;;
3910	esac
3911}
3912
3913_docker_manifest_create() {
3914	case "$cur" in
3915		-*)
3916			COMPREPLY=( $( compgen -W "--amend -a --help --insecure" -- "$cur" ) )
3917			;;
3918		*)
3919			__docker_complete_images --force-tag --id
3920			;;
3921	esac
3922}
3923
3924_docker_manifest_inspect() {
3925	case "$cur" in
3926		-*)
3927			COMPREPLY=( $( compgen -W "--help --insecure --verbose -v" -- "$cur" ) )
3928			;;
3929		*)
3930			local counter=$( __docker_pos_first_nonflag )
3931			if [ "$cword" -eq "$counter" ] || [ "$cword" -eq "$((counter + 1))" ]; then
3932				__docker_complete_images --force-tag --id
3933			fi
3934			;;
3935	esac
3936}
3937
3938_docker_manifest_push() {
3939	case "$cur" in
3940		-*)
3941			COMPREPLY=( $( compgen -W "--help --insecure --purge -p" -- "$cur" ) )
3942			;;
3943		*)
3944			local counter=$( __docker_pos_first_nonflag )
3945			if [ "$cword" -eq "$counter" ]; then
3946				__docker_complete_images --force-tag --id
3947			fi
3948			;;
3949	esac
3950}
3951
3952_docker_node() {
3953	local subcommands="
3954		demote
3955		inspect
3956		ls
3957		promote
3958		rm
3959		ps
3960		update
3961	"
3962	local aliases="
3963		list
3964		remove
3965	"
3966	__docker_subcommands "$subcommands $aliases" && return
3967
3968	case "$cur" in
3969		-*)
3970			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
3971			;;
3972		*)
3973			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
3974			;;
3975	esac
3976}
3977
3978_docker_node_demote() {
3979	case "$cur" in
3980		-*)
3981			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
3982			;;
3983		*)
3984			__docker_complete_nodes --filter role=manager
3985	esac
3986}
3987
3988_docker_node_inspect() {
3989	case "$prev" in
3990		--format|-f)
3991			return
3992			;;
3993	esac
3994
3995	case "$cur" in
3996		-*)
3997			COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) )
3998			;;
3999		*)
4000			__docker_complete_nodes --add self
4001	esac
4002}
4003
4004_docker_node_list() {
4005	_docker_node_ls
4006}
4007
4008_docker_node_ls() {
4009	local key=$(__docker_map_key_of_current_option '--filter|-f')
4010	case "$key" in
4011		id)
4012			__docker_complete_nodes --cur "${cur##*=}" --id
4013			return
4014			;;
4015		membership)
4016			COMPREPLY=( $( compgen -W "accepted pending" -- "${cur##*=}" ) )
4017			return
4018			;;
4019		name)
4020			__docker_complete_nodes --cur "${cur##*=}" --name
4021			return
4022			;;
4023		role)
4024			COMPREPLY=( $( compgen -W "manager worker" -- "${cur##*=}" ) )
4025			return
4026			;;
4027	esac
4028
4029	case "$prev" in
4030		--filter|-f)
4031			COMPREPLY=( $( compgen -W "id label membership name role" -S = -- "$cur" ) )
4032			__docker_nospace
4033			return
4034			;;
4035		--format)
4036			return
4037			;;
4038	esac
4039
4040	case "$cur" in
4041		-*)
4042			COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) )
4043			;;
4044	esac
4045}
4046
4047_docker_node_promote() {
4048	case "$cur" in
4049		-*)
4050			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
4051			;;
4052		*)
4053			__docker_complete_nodes --filter role=worker
4054	esac
4055}
4056
4057_docker_node_remove() {
4058	_docker_node_rm
4059}
4060
4061_docker_node_rm() {
4062	case "$cur" in
4063		-*)
4064			COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) )
4065			;;
4066		*)
4067			__docker_complete_nodes
4068	esac
4069}
4070
4071_docker_node_ps() {
4072	local key=$(__docker_map_key_of_current_option '--filter|-f')
4073	case "$key" in
4074		desired-state)
4075			COMPREPLY=( $( compgen -W "accepted running shutdown" -- "${cur##*=}" ) )
4076			return
4077			;;
4078		name)
4079			__docker_complete_services --cur "${cur##*=}" --name
4080			return
4081			;;
4082	esac
4083
4084	case "$prev" in
4085		--filter|-f)
4086			COMPREPLY=( $( compgen -W "desired-state id label name" -S = -- "$cur" ) )
4087			__docker_nospace
4088			return
4089			;;
4090		--format)
4091			return
4092			;;
4093	esac
4094
4095	case "$cur" in
4096		-*)
4097			COMPREPLY=( $( compgen -W "--filter -f --format --help --no-resolve --no-trunc --quiet -q" -- "$cur" ) )
4098			;;
4099		*)
4100			__docker_complete_nodes --add self
4101			;;
4102	esac
4103}
4104
4105_docker_node_update() {
4106	case "$prev" in
4107		--availability)
4108			COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) )
4109			return
4110			;;
4111		--role)
4112			COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) )
4113			return
4114			;;
4115		--label-add|--label-rm)
4116			return
4117			;;
4118	esac
4119
4120	case "$cur" in
4121		-*)
4122			COMPREPLY=( $( compgen -W "--availability --help --label-add --label-rm --role" -- "$cur" ) )
4123			;;
4124		*)
4125			local counter=$(__docker_pos_first_nonflag '--availability|--label-add|--label-rm|--role')
4126			if [ "$cword" -eq "$counter" ]; then
4127				__docker_complete_nodes
4128			fi
4129			;;
4130	esac
4131}
4132
4133_docker_pause() {
4134	_docker_container_pause
4135}
4136
4137_docker_plugin() {
4138	local subcommands="
4139		create
4140		disable
4141		enable
4142		inspect
4143		install
4144		ls
4145		push
4146		rm
4147		set
4148		upgrade
4149	"
4150	local aliases="
4151		list
4152		remove
4153	"
4154	__docker_subcommands "$subcommands $aliases" && return
4155
4156	case "$cur" in
4157		-*)
4158			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
4159			;;
4160		*)
4161			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
4162			;;
4163	esac
4164}
4165
4166_docker_plugin_create() {
4167	case "$cur" in
4168		-*)
4169			COMPREPLY=( $( compgen -W "--compress --help" -- "$cur" ) )
4170			;;
4171		*)
4172			local counter=$(__docker_pos_first_nonflag)
4173			if [ "$cword" -eq "$counter" ]; then
4174				# reponame
4175				return
4176			elif [ "$cword" -eq  "$((counter + 1))" ]; then
4177				_filedir -d
4178			fi
4179			;;
4180	esac
4181}
4182
4183_docker_plugin_disable() {
4184	case "$cur" in
4185		-*)
4186			COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) )
4187			;;
4188		*)
4189			local counter=$(__docker_pos_first_nonflag)
4190			if [ "$cword" -eq "$counter" ]; then
4191				__docker_complete_plugins_installed --filter enabled=true
4192			fi
4193			;;
4194	esac
4195}
4196
4197_docker_plugin_enable() {
4198	case "$prev" in
4199		--timeout)
4200			return
4201			;;
4202	esac
4203
4204	case "$cur" in
4205		-*)
4206			COMPREPLY=( $( compgen -W "--help --timeout" -- "$cur" ) )
4207			;;
4208		*)
4209			local counter=$(__docker_pos_first_nonflag '--timeout')
4210			if [ "$cword" -eq "$counter" ]; then
4211				__docker_complete_plugins_installed --filter enabled=false
4212			fi
4213			;;
4214	esac
4215}
4216
4217_docker_plugin_inspect() {
4218	case "$prev" in
4219		--format|f)
4220			return
4221			;;
4222	esac
4223
4224	case "$cur" in
4225		-*)
4226			COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) )
4227			;;
4228		*)
4229			__docker_complete_plugins_installed
4230			;;
4231	esac
4232}
4233
4234_docker_plugin_install() {
4235	case "$prev" in
4236		--alias)
4237			return
4238			;;
4239	esac
4240
4241	case "$cur" in
4242		-*)
4243			COMPREPLY=( $( compgen -W "--alias --disable --disable-content-trust=false --grant-all-permissions --help" -- "$cur" ) )
4244			;;
4245	esac
4246}
4247
4248_docker_plugin_list() {
4249	_docker_plugin_ls
4250}
4251
4252_docker_plugin_ls() {
4253	local key=$(__docker_map_key_of_current_option '--filter|-f')
4254	case "$key" in
4255		capability)
4256			COMPREPLY=( $( compgen -W "authz ipamdriver logdriver metricscollector networkdriver volumedriver" -- "${cur##*=}" ) )
4257			return
4258			;;
4259		enabled)
4260			COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
4261			return
4262			;;
4263	esac
4264
4265	case "$prev" in
4266		--filter|-f)
4267			COMPREPLY=( $( compgen -S = -W "capability enabled" -- "$cur" ) )
4268			__docker_nospace
4269			return
4270			;;
4271		--format)
4272			return
4273			;;
4274	esac
4275
4276	case "$cur" in
4277		-*)
4278			COMPREPLY=( $( compgen -W "--filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) )
4279			;;
4280	esac
4281}
4282
4283_docker_plugin_push() {
4284	case "$cur" in
4285		-*)
4286			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
4287			;;
4288		*)
4289			local counter=$(__docker_pos_first_nonflag)
4290			if [ "$cword" -eq "$counter" ]; then
4291				__docker_complete_plugins_installed
4292			fi
4293			;;
4294	esac
4295}
4296
4297_docker_plugin_remove() {
4298	_docker_plugin_rm
4299}
4300
4301_docker_plugin_rm() {
4302	case "$cur" in
4303		-*)
4304			COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) )
4305			;;
4306		*)
4307			__docker_complete_plugins_installed
4308			;;
4309	esac
4310}
4311
4312_docker_plugin_set() {
4313	case "$cur" in
4314		-*)
4315			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
4316			;;
4317		*)
4318			local counter=$(__docker_pos_first_nonflag)
4319			if [ "$cword" -eq "$counter" ]; then
4320				__docker_complete_plugins_installed
4321			fi
4322			;;
4323	esac
4324}
4325
4326_docker_plugin_upgrade() {
4327	case "$cur" in
4328		-*)
4329			COMPREPLY=( $( compgen -W "--disable-content-trust --grant-all-permissions --help --skip-remote-check" -- "$cur" ) )
4330			;;
4331		*)
4332			local counter=$(__docker_pos_first_nonflag)
4333			if [ "$cword" -eq "$counter" ]; then
4334				__docker_complete_plugins_installed
4335				__ltrim_colon_completions "$cur"
4336			elif [ "$cword" -eq  "$((counter + 1))" ]; then
4337				local plugin_images="$(__docker_plugins_installed)"
4338				COMPREPLY=( $(compgen -S : -W "${plugin_images%:*}" -- "$cur") )
4339				__docker_nospace
4340			fi
4341			;;
4342	esac
4343}
4344
4345
4346_docker_port() {
4347	_docker_container_port
4348}
4349
4350_docker_ps() {
4351	_docker_container_ls
4352}
4353
4354_docker_pull() {
4355	_docker_image_pull
4356}
4357
4358_docker_push() {
4359	_docker_image_push
4360}
4361
4362_docker_rename() {
4363	_docker_container_rename
4364}
4365
4366_docker_restart() {
4367	_docker_container_restart
4368}
4369
4370_docker_rm() {
4371	_docker_container_rm
4372}
4373
4374_docker_rmi() {
4375	_docker_image_rm
4376}
4377
4378_docker_run() {
4379	_docker_container_run
4380}
4381
4382_docker_save() {
4383	_docker_image_save
4384}
4385
4386
4387_docker_secret() {
4388	local subcommands="
4389		create
4390		inspect
4391		ls
4392		rm
4393	"
4394	local aliases="
4395		list
4396		remove
4397	"
4398	__docker_subcommands "$subcommands $aliases" && return
4399
4400	case "$cur" in
4401		-*)
4402			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
4403			;;
4404		*)
4405			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
4406			;;
4407	esac
4408}
4409
4410_docker_secret_create() {
4411	case "$prev" in
4412		--driver|-d|--label|-l)
4413			return
4414			;;
4415		--template-driver)
4416			COMPREPLY=( $( compgen -W "golang" -- "$cur" ) )
4417			return
4418			;;
4419	esac
4420
4421	case "$cur" in
4422		-*)
4423			COMPREPLY=( $( compgen -W "--driver -d --help --label -l --template-driver" -- "$cur" ) )
4424			;;
4425		*)
4426			local counter=$(__docker_pos_first_nonflag '--driver|-d|--label|-l|--template-driver')
4427			if [ "$cword" -eq "$((counter + 1))" ]; then
4428				_filedir
4429			fi
4430			;;
4431	esac
4432}
4433
4434_docker_secret_inspect() {
4435	case "$prev" in
4436		--format|-f)
4437			return
4438			;;
4439	esac
4440
4441	case "$cur" in
4442		-*)
4443			COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) )
4444			;;
4445		*)
4446			__docker_complete_secrets
4447			;;
4448	esac
4449}
4450
4451_docker_secret_list() {
4452	_docker_secret_ls
4453}
4454
4455_docker_secret_ls() {
4456	local key=$(__docker_map_key_of_current_option '--filter|-f')
4457	case "$key" in
4458		id)
4459			__docker_complete_secrets --cur "${cur##*=}" --id
4460			return
4461			;;
4462		name)
4463			__docker_complete_secrets --cur "${cur##*=}" --name
4464			return
4465			;;
4466	esac
4467
4468	case "$prev" in
4469		--filter|-f)
4470			COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) )
4471			__docker_nospace
4472			return
4473			;;
4474		--format)
4475			return
4476			;;
4477	esac
4478
4479	case "$cur" in
4480		-*)
4481			COMPREPLY=( $( compgen -W "--format --filter -f --help --quiet -q" -- "$cur" ) )
4482			;;
4483	esac
4484}
4485
4486_docker_secret_remove() {
4487	_docker_secret_rm
4488}
4489
4490_docker_secret_rm() {
4491	case "$cur" in
4492		-*)
4493			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
4494			;;
4495		*)
4496			__docker_complete_secrets
4497			;;
4498	esac
4499}
4500
4501
4502
4503_docker_search() {
4504	local key=$(__docker_map_key_of_current_option '--filter|-f')
4505	case "$key" in
4506		is-automated)
4507			COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
4508			return
4509			;;
4510		is-official)
4511			COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
4512			return
4513			;;
4514	esac
4515
4516	case "$prev" in
4517		--filter|-f)
4518			COMPREPLY=( $( compgen -S = -W "is-automated is-official stars" -- "$cur" ) )
4519			__docker_nospace
4520			return
4521			;;
4522		--format|--limit)
4523			return
4524			;;
4525	esac
4526
4527	case "$cur" in
4528		-*)
4529			COMPREPLY=( $( compgen -W "--filter -f --format --help --limit --no-trunc" -- "$cur" ) )
4530			;;
4531	esac
4532}
4533
4534
4535_docker_stack() {
4536	local subcommands="
4537		deploy
4538		ls
4539		ps
4540		rm
4541		services
4542	"
4543	local aliases="
4544		down
4545		list
4546		remove
4547		up
4548	"
4549
4550	__docker_complete_stack_orchestrator_options && return
4551	__docker_subcommands "$subcommands $aliases" && return
4552
4553	case "$cur" in
4554		-*)
4555			local options="--help --orchestrator"
4556			__docker_stack_orchestrator_is kubernetes && options+=" --kubeconfig"
4557			COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )
4558			;;
4559		*)
4560			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
4561			;;
4562	esac
4563}
4564
4565_docker_stack_deploy() {
4566	__docker_complete_stack_orchestrator_options && return
4567
4568	case "$prev" in
4569		--bundle-file)
4570			_filedir dab
4571			return
4572			;;
4573		--compose-file|-c)
4574			_filedir yml
4575			return
4576			;;
4577		--resolve-image)
4578			COMPREPLY=( $( compgen -W "always changed never" -- "$cur" ) )
4579			return
4580			;;
4581	esac
4582
4583	case "$cur" in
4584		-*)
4585			local options="--compose-file -c --help --orchestrator"
4586			__docker_server_is_experimental && __docker_stack_orchestrator_is swarm && options+=" --bundle-file"
4587			__docker_stack_orchestrator_is kubernetes && options+=" --kubeconfig --namespace"
4588			__docker_stack_orchestrator_is swarm && options+=" --prune --resolve-image --with-registry-auth"
4589			COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )
4590			;;
4591		*)
4592			local counter=$(__docker_pos_first_nonflag '--bundle-file|--compose-file|-c|--kubeconfig|--namespace|--orchestrator|--resolve-image')
4593			if [ "$cword" -eq "$counter" ]; then
4594				__docker_complete_stacks
4595			fi
4596			;;
4597	esac
4598}
4599
4600_docker_stack_down() {
4601	_docker_stack_rm
4602}
4603
4604_docker_stack_list() {
4605	_docker_stack_ls
4606}
4607
4608_docker_stack_ls() {
4609	__docker_complete_stack_orchestrator_options && return
4610
4611	case "$prev" in
4612		--format)
4613			return
4614			;;
4615	esac
4616
4617	case "$cur" in
4618		-*)
4619			local options="--format --help --orchestrator"
4620			__docker_stack_orchestrator_is kubernetes && options+=" --all-namespaces --kubeconfig --namespace"
4621			COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )
4622			;;
4623	esac
4624}
4625
4626_docker_stack_ps() {
4627	local key=$(__docker_map_key_of_current_option '--filter|-f')
4628	case "$key" in
4629		desired-state)
4630			COMPREPLY=( $( compgen -W "accepted running shutdown" -- "${cur##*=}" ) )
4631			return
4632			;;
4633		id)
4634			__docker_complete_stacks --cur "${cur##*=}" --id
4635			return
4636			;;
4637		name)
4638			__docker_complete_stacks --cur "${cur##*=}" --name
4639			return
4640			;;
4641	esac
4642
4643	__docker_complete_stack_orchestrator_options && return
4644
4645	case "$prev" in
4646		--filter|-f)
4647			COMPREPLY=( $( compgen -S = -W "id name desired-state" -- "$cur" ) )
4648			__docker_nospace
4649			return
4650			;;
4651		--format)
4652			return
4653			;;
4654	esac
4655
4656	case "$cur" in
4657		-*)
4658			local options="--filter -f --format --help --no-resolve --no-trunc --orchestrator --quiet -q"
4659			__docker_stack_orchestrator_is kubernetes && options+=" --all-namespaces --kubeconfig --namespace"
4660			COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )
4661			;;
4662		*)
4663			local counter=$(__docker_pos_first_nonflag '--all-namespaces|--filter|-f|--format|--kubeconfig|--namespace')
4664			if [ "$cword" -eq "$counter" ]; then
4665				__docker_complete_stacks
4666			fi
4667			;;
4668	esac
4669}
4670
4671_docker_stack_remove() {
4672	_docker_stack_rm
4673}
4674
4675_docker_stack_rm() {
4676	__docker_complete_stack_orchestrator_options && return
4677
4678	case "$cur" in
4679		-*)
4680			local options="--help --orchestrator"
4681			__docker_stack_orchestrator_is kubernetes && options+=" --kubeconfig --namespace"
4682			COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )
4683			;;
4684		*)
4685			__docker_complete_stacks
4686			;;
4687	esac
4688}
4689
4690_docker_stack_services() {
4691	local key=$(__docker_map_key_of_current_option '--filter|-f')
4692	case "$key" in
4693		id)
4694			__docker_complete_services --cur "${cur##*=}" --id
4695			return
4696			;;
4697		label)
4698			return
4699			;;
4700		name)
4701			__docker_complete_services --cur "${cur##*=}" --name
4702			return
4703			;;
4704	esac
4705
4706	__docker_complete_stack_orchestrator_options && return
4707
4708	case "$prev" in
4709		--filter|-f)
4710			COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) )
4711			__docker_nospace
4712			return
4713			;;
4714		--format)
4715			return
4716			;;
4717	esac
4718
4719	case "$cur" in
4720		-*)
4721			local options="--filter -f --format --help --orchestrator --quiet -q"
4722			__docker_stack_orchestrator_is kubernetes && options+=" --kubeconfig --namespace"
4723			COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )
4724			;;
4725		*)
4726			local counter=$(__docker_pos_first_nonflag '--filter|-f|--format|--kubeconfig|--namespace|--orchestrator')
4727			if [ "$cword" -eq "$counter" ]; then
4728				__docker_complete_stacks
4729			fi
4730			;;
4731	esac
4732}
4733
4734_docker_stack_up() {
4735	_docker_stack_deploy
4736}
4737
4738
4739_docker_start() {
4740	_docker_container_start
4741}
4742
4743_docker_stats() {
4744	_docker_container_stats
4745}
4746
4747_docker_stop() {
4748	_docker_container_stop
4749}
4750
4751
4752_docker_system() {
4753	local subcommands="
4754		df
4755		events
4756		info
4757		prune
4758	"
4759	__docker_subcommands "$subcommands" && return
4760
4761	case "$cur" in
4762		-*)
4763			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
4764			;;
4765		*)
4766			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
4767			;;
4768	esac
4769}
4770
4771_docker_system_df() {
4772	case "$prev" in
4773		--format)
4774			return
4775			;;
4776	esac
4777
4778	case "$cur" in
4779		-*)
4780			COMPREPLY=( $( compgen -W "--format --help --verbose -v" -- "$cur" ) )
4781			;;
4782	esac
4783}
4784
4785_docker_system_events() {
4786	local key=$(__docker_map_key_of_current_option '-f|--filter')
4787	case "$key" in
4788		container)
4789			__docker_complete_containers_all --cur "${cur##*=}"
4790			return
4791			;;
4792		daemon)
4793			local name=$(__docker_q info | sed -n 's/^\(ID\|Name\): //p')
4794			COMPREPLY=( $( compgen -W "$name" -- "${cur##*=}" ) )
4795			return
4796			;;
4797		event)
4798			COMPREPLY=( $( compgen -W "
4799				attach
4800				commit
4801				connect
4802				copy
4803				create
4804				delete
4805				destroy
4806				detach
4807				die
4808				disable
4809				disconnect
4810				enable
4811				exec_create
4812				exec_detach
4813				exec_die
4814				exec_start
4815				export
4816				health_status
4817				import
4818				install
4819				kill
4820				load
4821				mount
4822				oom
4823				pause
4824				pull
4825				push
4826				reload
4827				remove
4828				rename
4829				resize
4830				restart
4831				save
4832				start
4833				stop
4834				tag
4835				top
4836				unmount
4837				unpause
4838				untag
4839				update
4840			" -- "${cur##*=}" ) )
4841			return
4842			;;
4843		image)
4844			__docker_complete_images --cur "${cur##*=}" --repo --tag
4845			return
4846			;;
4847		network)
4848			__docker_complete_networks --cur "${cur##*=}"
4849			return
4850			;;
4851		scope)
4852			COMPREPLY=( $( compgen -W "local swarm" -- "${cur##*=}" ) )
4853			return
4854			;;
4855		type)
4856			COMPREPLY=( $( compgen -W "config container daemon image network plugin secret service volume" -- "${cur##*=}" ) )
4857			return
4858			;;
4859		volume)
4860			__docker_complete_volumes --cur "${cur##*=}"
4861			return
4862			;;
4863	esac
4864
4865	case "$prev" in
4866		--filter|-f)
4867			COMPREPLY=( $( compgen -S = -W "container daemon event image label network scope type volume" -- "$cur" ) )
4868			__docker_nospace
4869			return
4870			;;
4871		--since|--until)
4872			return
4873			;;
4874	esac
4875
4876	case "$cur" in
4877		-*)
4878			COMPREPLY=( $( compgen -W "--filter -f --help --since --until --format" -- "$cur" ) )
4879			;;
4880	esac
4881}
4882
4883_docker_system_info() {
4884	case "$prev" in
4885		--format|-f)
4886			return
4887			;;
4888	esac
4889
4890	case "$cur" in
4891		-*)
4892			COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) )
4893			;;
4894	esac
4895}
4896
4897_docker_system_prune() {
4898	case "$prev" in
4899		--filter)
4900			COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) )
4901			__docker_nospace
4902			return
4903			;;
4904	esac
4905
4906	case "$cur" in
4907		-*)
4908			COMPREPLY=( $( compgen -W "--all -a --force -f --filter --help --volumes" -- "$cur" ) )
4909			;;
4910	esac
4911}
4912
4913
4914_docker_tag() {
4915	_docker_image_tag
4916}
4917
4918
4919_docker_trust() {
4920	local subcommands="
4921		inspect
4922		revoke
4923		sign
4924	"
4925	__docker_subcommands "$subcommands" && return
4926
4927	case "$cur" in
4928		-*)
4929			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
4930			;;
4931		*)
4932			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
4933			;;
4934	esac
4935}
4936
4937_docker_trust_inspect() {
4938	case "$cur" in
4939		-*)
4940			COMPREPLY=( $( compgen -W "--help --pretty" -- "$cur" ) )
4941			;;
4942		*)
4943			local counter=$(__docker_pos_first_nonflag)
4944			if [ "$cword" -eq "$counter" ]; then
4945				__docker_complete_images --repo --tag
4946			fi
4947			;;
4948	esac
4949}
4950
4951_docker_trust_revoke() {
4952	case "$cur" in
4953		-*)
4954			COMPREPLY=( $( compgen -W "--help --yes -y" -- "$cur" ) )
4955			;;
4956		*)
4957			local counter=$(__docker_pos_first_nonflag)
4958			if [ "$cword" -eq "$counter" ]; then
4959				__docker_complete_images --repo --tag
4960			fi
4961			;;
4962	esac
4963}
4964
4965_docker_trust_sign() {
4966	case "$cur" in
4967		-*)
4968			COMPREPLY=( $( compgen -W "--help --local" -- "$cur" ) )
4969			;;
4970		*)
4971			local counter=$(__docker_pos_first_nonflag)
4972			if [ "$cword" -eq "$counter" ]; then
4973				__docker_complete_images --force-tag --id
4974			fi
4975			;;
4976	esac
4977}
4978
4979
4980_docker_unpause() {
4981	_docker_container_unpause
4982}
4983
4984_docker_update() {
4985	_docker_container_update
4986}
4987
4988_docker_top() {
4989	_docker_container_top
4990}
4991
4992_docker_version() {
4993	__docker_complete_stack_orchestrator_options && return
4994
4995	case "$prev" in
4996		--format|-f)
4997			return
4998			;;
4999	esac
5000
5001	case "$cur" in
5002		-*)
5003			local options="--format -f --help"
5004			__docker_stack_orchestrator_is kubernetes && options+=" --kubeconfig"
5005			COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )
5006			;;
5007	esac
5008}
5009
5010_docker_volume_create() {
5011	case "$prev" in
5012		--driver|-d)
5013			__docker_complete_plugins_bundled --type Volume
5014			return
5015			;;
5016		--label|--opt|-o)
5017			return
5018			;;
5019	esac
5020
5021	case "$cur" in
5022		-*)
5023			COMPREPLY=( $( compgen -W "--driver -d --help --label --opt -o" -- "$cur" ) )
5024			;;
5025	esac
5026}
5027
5028_docker_volume_inspect() {
5029	case "$prev" in
5030		--format|-f)
5031			return
5032			;;
5033	esac
5034
5035	case "$cur" in
5036		-*)
5037			COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) )
5038			;;
5039		*)
5040			__docker_complete_volumes
5041			;;
5042	esac
5043}
5044
5045_docker_volume_list() {
5046	_docker_volume_ls
5047}
5048
5049_docker_volume_ls() {
5050	local key=$(__docker_map_key_of_current_option '--filter|-f')
5051	case "$key" in
5052		dangling)
5053			COMPREPLY=( $( compgen -W "true false" -- "${cur##*=}" ) )
5054			return
5055			;;
5056		driver)
5057			__docker_complete_plugins_bundled --cur "${cur##*=}" --type Volume
5058			return
5059			;;
5060		name)
5061			__docker_complete_volumes --cur "${cur##*=}"
5062			return
5063			;;
5064	esac
5065
5066	case "$prev" in
5067		--filter|-f)
5068			COMPREPLY=( $( compgen -S = -W "dangling driver label name" -- "$cur" ) )
5069			__docker_nospace
5070			return
5071			;;
5072		--format)
5073			return
5074			;;
5075	esac
5076
5077	case "$cur" in
5078		-*)
5079			COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) )
5080			;;
5081	esac
5082}
5083
5084_docker_volume_prune() {
5085	case "$prev" in
5086		--filter)
5087			COMPREPLY=( $( compgen -W "label label!" -S = -- "$cur" ) )
5088			__docker_nospace
5089			return
5090			;;
5091	esac
5092
5093	case "$cur" in
5094		-*)
5095			COMPREPLY=( $( compgen -W "--filter --force -f --help" -- "$cur" ) )
5096			;;
5097	esac
5098}
5099
5100_docker_volume_remove() {
5101	_docker_volume_rm
5102}
5103
5104_docker_volume_rm() {
5105	case "$cur" in
5106		-*)
5107			COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) )
5108			;;
5109		*)
5110			__docker_complete_volumes
5111			;;
5112	esac
5113}
5114
5115_docker_volume() {
5116	local subcommands="
5117		create
5118		inspect
5119		ls
5120		prune
5121		rm
5122	"
5123	local aliases="
5124		list
5125		remove
5126	"
5127	__docker_subcommands "$subcommands $aliases" && return
5128
5129	case "$cur" in
5130		-*)
5131			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
5132			;;
5133		*)
5134			COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
5135			;;
5136	esac
5137}
5138
5139_docker_wait() {
5140	_docker_container_wait
5141}
5142
5143_docker() {
5144	local previous_extglob_setting=$(shopt -p extglob)
5145	shopt -s extglob
5146
5147	local management_commands=(
5148		config
5149		container
5150		image
5151		network
5152		node
5153		plugin
5154		secret
5155		service
5156		stack
5157		swarm
5158		system
5159		trust
5160		volume
5161	)
5162
5163	local top_level_commands=(
5164		build
5165		login
5166		logout
5167		run
5168		search
5169		version
5170	)
5171
5172	local legacy_commands=(
5173		attach
5174		commit
5175		cp
5176		create
5177		diff
5178		events
5179		exec
5180		export
5181		history
5182		images
5183		import
5184		info
5185		inspect
5186		kill
5187		load
5188		logs
5189		pause
5190		port
5191		ps
5192		pull
5193		push
5194		rename
5195		restart
5196		rm
5197		rmi
5198		save
5199		start
5200		stats
5201		stop
5202		tag
5203		top
5204		unpause
5205		update
5206		wait
5207	)
5208
5209	local experimental_client_commands=(
5210		manifest
5211	)
5212
5213	local experimental_server_commands=(
5214		checkpoint
5215		deploy
5216	)
5217
5218	local commands=(${management_commands[*]} ${top_level_commands[*]})
5219	[ -z "$DOCKER_HIDE_LEGACY_COMMANDS" ] && commands+=(${legacy_commands[*]})
5220
5221	# These options are valid as global options for all client commands
5222	# and valid as command options for `docker daemon`
5223	local global_boolean_options="
5224		--debug -D
5225		--tls
5226		--tlsverify
5227	"
5228	local global_options_with_args="
5229		--config
5230		--host -H
5231		--log-level -l
5232		--tlscacert
5233		--tlscert
5234		--tlskey
5235	"
5236
5237	# variables to cache server info, populated on demand for performance reasons
5238	local info_fetched server_experimental server_os
5239	# variables to cache client info, populated on demand for performance reasons
5240	local client_experimental stack_orchestrator_is_kubernetes stack_orchestrator_is_swarm
5241
5242	local host config
5243
5244	COMPREPLY=()
5245	local cur prev words cword
5246	_get_comp_words_by_ref -n : cur prev words cword
5247
5248	local command='docker' command_pos=0 subcommand_pos
5249	local counter=1
5250	while [ "$counter" -lt "$cword" ]; do
5251		case "${words[$counter]}" in
5252			docker)
5253				return 0
5254				;;
5255			# save host so that completion can use custom daemon
5256			--host|-H)
5257				(( counter++ ))
5258				host="${words[$counter]}"
5259				;;
5260			# save config so that completion can use custom configuration directories
5261			--config)
5262				(( counter++ ))
5263				config="${words[$counter]}"
5264				;;
5265			$(__docker_to_extglob "$global_options_with_args") )
5266				(( counter++ ))
5267				;;
5268			-*)
5269				;;
5270			=)
5271				(( counter++ ))
5272				;;
5273			*)
5274				command="${words[$counter]}"
5275				command_pos=$counter
5276				break
5277				;;
5278		esac
5279		(( counter++ ))
5280	done
5281
5282	local binary="${words[0]}"
5283	if [[ $binary == ?(*/)dockerd ]] ; then
5284		# for the dockerd binary, we reuse completion of `docker daemon`.
5285		# dockerd does not have subcommands and global options.
5286		command=daemon
5287		command_pos=0
5288	fi
5289
5290	local completions_func=_docker_${command//-/_}
5291	declare -F $completions_func >/dev/null && $completions_func
5292
5293	eval "$previous_extglob_setting"
5294	return 0
5295}
5296
5297eval "$__docker_previous_extglob_setting"
5298unset __docker_previous_extglob_setting
5299
5300complete -F _docker docker docker.exe dockerd dockerd.exe
5301