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