]> src.twobees.de Git - dotfiles.git/blob - stow/oh-my-zsh/.oh-my-zsh/plugins/docker/_docker
initial
[dotfiles.git] / stow / oh-my-zsh / .oh-my-zsh / plugins / docker / _docker
1 #compdef docker dockerd
2 #
3 # zsh completion for docker (http://docker.com)
4 #
5 # version:  0.3.0
6 # github:   https://github.com/felixr/docker-zsh-completion
7 #
8 # contributors:
9 #   - Felix Riedel
10 #   - Steve Durrheimer
11 #   - Vincent Bernat
12 #   - Rohan Verma
13 #
14 # license:
15 #
16 # Copyright (c) 2013, Felix Riedel
17 # All rights reserved.
18 #
19 # Redistribution and use in source and binary forms, with or without
20 # modification, are permitted provided that the following conditions are met:
21 #     * Redistributions of source code must retain the above copyright
22 #       notice, this list of conditions and the following disclaimer.
23 #     * Redistributions in binary form must reproduce the above copyright
24 #       notice, this list of conditions and the following disclaimer in the
25 #       documentation and/or other materials provided with the distribution.
26 #     * Neither the name of the <organization> nor the
27 #       names of its contributors may be used to endorse or promote products
28 #       derived from this software without specific prior written permission.
29 #
30 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
31 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33 # DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
34 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 #
41
42 # Short-option stacking can be enabled with:
43 #  zstyle ':completion:*:*:docker:*' option-stacking yes
44 #  zstyle ':completion:*:*:docker-*:*' option-stacking yes
45 __docker_arguments() {
46     if zstyle -t ":completion:${curcontext}:" option-stacking; then
47         print -- -s
48     fi
49 }
50
51 __docker_get_containers() {
52     [[ $PREFIX = -* ]] && return 1
53     integer ret=1
54     local kind type line s
55     declare -a running stopped lines args names
56
57     kind=$1; shift
58     type=$1; shift
59     [[ $kind = (stopped|all) ]] && args=($args -a)
60
61     lines=(${(f)${:-"$(_call_program commands docker $docker_options ps --format 'table' --no-trunc $args)"$'\n'}})
62
63     # Parse header line to find columns
64     local i=1 j=1 k header=${lines[1]}
65     declare -A begin end
66     while (( j < ${#header} - 1 )); do
67         i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
68         j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
69         k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
70         begin[${header[$i,$((j-1))]}]=$i
71         end[${header[$i,$((j-1))]}]=$k
72     done
73     end[${header[$i,$((j-1))]}]=-1 # Last column, should go to the end of the line
74     lines=(${lines[2,-1]})
75
76     # Container ID
77     if [[ $type = (ids|all) ]]; then
78         for line in $lines; do
79             s="${${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}[0,12]}"
80             s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
81             s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
82             if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = (Exit*|Created*) ]]; then
83                 stopped=($stopped $s)
84             else
85                 running=($running $s)
86             fi
87         done
88     fi
89
90     # Names: we only display the one without slash. All other names
91     # are generated and may clutter the completion. However, with
92     # Swarm, all names may be prefixed by the swarm node name.
93     if [[ $type = (names|all) ]]; then
94         for line in $lines; do
95             names=(${(ps:,:)${${line[${begin[NAMES]},${end[NAMES]}]}%% *}})
96             # First step: find a common prefix and strip it (swarm node case)
97             (( ${#${(u)names%%/*}} == 1 )) && names=${names#${names[1]%%/*}/}
98             # Second step: only keep the first name without a /
99             s=${${names:#*/*}[1]}
100             # If no name, well give up.
101             (( $#s != 0 )) || continue
102             s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
103             s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
104             if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = (Exit*|Created*) ]]; then
105                 stopped=($stopped $s)
106             else
107                 running=($running $s)
108             fi
109         done
110     fi
111
112     [[ $kind = (running|all) ]] && _describe -t containers-running "running containers" running "$@" && ret=0
113     [[ $kind = (stopped|all) ]] && _describe -t containers-stopped "stopped containers" stopped "$@" && ret=0
114     return ret
115 }
116
117 __docker_complete_stopped_containers() {
118     [[ $PREFIX = -* ]] && return 1
119     __docker_get_containers stopped all "$@"
120 }
121
122 __docker_complete_running_containers() {
123     [[ $PREFIX = -* ]] && return 1
124     __docker_get_containers running all "$@"
125 }
126
127 __docker_complete_containers() {
128     [[ $PREFIX = -* ]] && return 1
129     __docker_get_containers all all "$@"
130 }
131
132 __docker_complete_containers_ids() {
133     [[ $PREFIX = -* ]] && return 1
134     __docker_get_containers all ids "$@"
135 }
136
137 __docker_complete_containers_names() {
138     [[ $PREFIX = -* ]] && return 1
139     __docker_get_containers all names "$@"
140 }
141
142 __docker_complete_info_plugins() {
143     [[ $PREFIX = -* ]] && return 1
144     integer ret=1
145     emulate -L zsh
146     setopt extendedglob
147     local -a plugins
148     plugins=(${(ps: :)${(M)${(f)${${"$(_call_program commands docker $docker_options info)"##*$'\n'Plugins:}%%$'\n'^ *}}:# $1: *}## $1: })
149     _describe -t plugins "$1 plugins" plugins && ret=0
150     return ret
151 }
152
153 __docker_complete_images() {
154     [[ $PREFIX = -* ]] && return 1
155     integer ret=1
156     declare -a images
157     images=(${${${(f)${:-"$(_call_program commands docker $docker_options images)"$'\n'}}[2,-1]}/(#b)([^ ]##) ##([^ ]##) ##([^ ]##)*/${match[3]}:${(r:15:: :::)match[2]} in ${match[1]}})
158     _describe -t docker-images "images" images && ret=0
159     __docker_complete_repositories_with_tags && ret=0
160     return ret
161 }
162
163 __docker_complete_repositories() {
164     [[ $PREFIX = -* ]] && return 1
165     integer ret=1
166     declare -a repos
167     repos=(${${${(f)${:-"$(_call_program commands docker $docker_options images)"$'\n'}}%% *}[2,-1]})
168     repos=(${repos#<none>})
169     _describe -t docker-repos "repositories" repos && ret=0
170     return ret
171 }
172
173 __docker_complete_repositories_with_tags() {
174     [[ $PREFIX = -* ]] && return 1
175     integer ret=1
176     declare -a repos onlyrepos matched
177     declare m
178     repos=(${${${${(f)${:-"$(_call_program commands docker $docker_options images)"$'\n'}}[2,-1]}/ ##/:::}%% *})
179     repos=(${${repos%:::<none>}#<none>})
180     # Check if we have a prefix-match for the current prefix.
181     onlyrepos=(${repos%::*})
182     for m in $onlyrepos; do
183         [[ ${PREFIX##${~~m}} != ${PREFIX} ]] && {
184             # Yes, complete with tags
185             repos=(${${repos/:::/:}/:/\\:})
186             _describe -t docker-repos-with-tags "repositories with tags" repos && ret=0
187             return ret
188         }
189     done
190     # No, only complete repositories
191     onlyrepos=(${${repos%:::*}/:/\\:})
192     _describe -t docker-repos "repositories" onlyrepos -qS : && ret=0
193
194     return ret
195 }
196
197 __docker_search() {
198     [[ $PREFIX = -* ]] && return 1
199     local cache_policy
200     zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
201     if [[ -z "$cache_policy" ]]; then
202         zstyle ":completion:${curcontext}:" cache-policy __docker_caching_policy
203     fi
204
205     local searchterm cachename
206     searchterm="${words[$CURRENT]%/}"
207     cachename=_docker-search-$searchterm
208
209     local expl
210     local -a result
211     if ( [[ ${(P)+cachename} -eq 0 ]] || _cache_invalid ${cachename#_} ) \
212         && ! _retrieve_cache ${cachename#_}; then
213         _message "Searching for ${searchterm}..."
214         result=(${${${(f)${:-"$(_call_program commands docker $docker_options search $searchterm)"$'\n'}}%% *}[2,-1]})
215         _store_cache ${cachename#_} result
216     fi
217     _wanted dockersearch expl 'available images' compadd -a result
218 }
219
220 __docker_get_log_options() {
221     [[ $PREFIX = -* ]] && return 1
222
223     integer ret=1
224     local log_driver=${opt_args[--log-driver]:-"all"}
225     local -a common_options common_options2 awslogs_options fluentd_options gelf_options journald_options json_file_options logentries_options syslog_options splunk_options
226
227     common_options=("max-buffer-size" "mode")
228     common_options2=("env" "env-regex" "labels")
229     awslogs_options=($common_options "awslogs-create-group" "awslogs-datetime-format" "awslogs-group" "awslogs-multiline-pattern" "awslogs-region" "awslogs-stream" "tag")
230     fluentd_options=($common_options $common_options2 "fluentd-address" "fluentd-async-connect" "fluentd-buffer-limit" "fluentd-retry-wait" "fluentd-max-retries" "fluentd-sub-second-precision" "tag")
231     gcplogs_options=($common_options $common_options2 "gcp-log-cmd" "gcp-meta-id" "gcp-meta-name" "gcp-meta-zone" "gcp-project")
232     gelf_options=($common_options $common_options2 "gelf-address" "gelf-compression-level" "gelf-compression-type" "tag")
233     journald_options=($common_options $common_options2 "tag")
234     json_file_options=($common_options $common_options2 "max-file" "max-size")
235     logentries_options=($common_options $common_options2 "logentries-token" "tag")
236     syslog_options=($common_options $common_options2 "syslog-address" "syslog-facility" "syslog-format" "syslog-tls-ca-cert" "syslog-tls-cert" "syslog-tls-key" "syslog-tls-skip-verify" "tag")
237     splunk_options=($common_options $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")
238
239     [[ $log_driver = (awslogs|all) ]] && _describe -t awslogs-options "awslogs options" awslogs_options "$@" && ret=0
240     [[ $log_driver = (fluentd|all) ]] && _describe -t fluentd-options "fluentd options" fluentd_options "$@" && ret=0
241     [[ $log_driver = (gcplogs|all) ]] && _describe -t gcplogs-options "gcplogs options" gcplogs_options "$@" && ret=0
242     [[ $log_driver = (gelf|all) ]] && _describe -t gelf-options "gelf options" gelf_options "$@" && ret=0
243     [[ $log_driver = (journald|all) ]] && _describe -t journald-options "journald options" journald_options "$@" && ret=0
244     [[ $log_driver = (json-file|all) ]] && _describe -t json-file-options "json-file options" json_file_options "$@" && ret=0
245     [[ $log_driver = (logentries|all) ]] && _describe -t logentries-options "logentries options" logentries_options "$@" && ret=0
246     [[ $log_driver = (syslog|all) ]] && _describe -t syslog-options "syslog options" syslog_options "$@" && ret=0
247     [[ $log_driver = (splunk|all) ]] && _describe -t splunk-options "splunk options" splunk_options "$@" && ret=0
248
249     return ret
250 }
251
252 __docker_complete_log_drivers() {
253     [[ $PREFIX = -*  ]] && return 1
254     integer ret=1
255     drivers=(awslogs etwlogs fluentd gcplogs gelf journald json-file none splunk syslog)
256     _describe -t log-drivers "log drivers" drivers && ret=0
257     return ret
258 }
259
260 __docker_complete_log_options() {
261     [[ $PREFIX = -* ]] && return 1
262     integer ret=1
263
264     if compset -P '*='; then
265         case "${${words[-1]%=*}#*=}" in
266             (syslog-format)
267                 local opts=('rfc3164' 'rfc5424' 'rfc5424micro')
268                 _describe -t syslog-format-opts "syslog format options" opts && ret=0
269                 ;;
270             (mode)
271                 local opts=('blocking' 'non-blocking')
272                 _describe -t mode-opts "mode options" opts && ret=0
273                 ;;
274             *)
275                 _message 'value' && ret=0
276                 ;;
277         esac
278     else
279         __docker_get_log_options -qS "=" && ret=0
280     fi
281
282     return ret
283 }
284
285 __docker_complete_detach_keys() {
286     [[ $PREFIX = -* ]] && return 1
287     integer ret=1
288
289     compset -P "*,"
290     keys=(${:-{a-z}})
291     ctrl_keys=(${:-ctrl-{{a-z},{@,'[','\\','^',']',_}}})
292     _describe -t detach_keys "[a-z]" keys -qS "," && ret=0
293     _describe -t detach_keys-ctrl "'ctrl-' + 'a-z @ [ \\\\ ] ^ _'" ctrl_keys -qS "," && ret=0
294 }
295
296 __docker_complete_pid() {
297     [[ $PREFIX = -* ]] && return 1
298     integer ret=1
299     local -a opts vopts
300
301     opts=('host')
302     vopts=('container')
303
304     if compset -P '*:'; then
305         case "${${words[-1]%:*}#*=}" in
306             (container)
307                 __docker_complete_running_containers && ret=0
308                 ;;
309             *)
310                 _message 'value' && ret=0
311                 ;;
312         esac
313     else
314         _describe -t pid-value-opts "PID Options with value" vopts -qS ":" && ret=0
315         _describe -t pid-opts "PID Options" opts && ret=0
316     fi
317
318     return ret
319 }
320
321 __docker_complete_runtimes() {
322     [[ $PREFIX = -*  ]] && return 1
323     integer ret=1
324
325     emulate -L zsh
326     setopt extendedglob
327     local -a runtimes_opts
328     runtimes_opts=(${(ps: :)${(f)${${"$(_call_program commands docker $docker_options info)"##*$'\n'Runtimes: }%%$'\n'^ *}}})
329     _describe -t runtimes-opts "runtimes options" runtimes_opts && ret=0
330 }
331
332 __docker_complete_ps_filters() {
333     [[ $PREFIX = -* ]] && return 1
334     integer ret=1
335
336     if compset -P '*='; then
337         case "${${words[-1]%=*}#*=}" in
338             (ancestor)
339                 __docker_complete_images && ret=0
340                 ;;
341             (before|since)
342                 __docker_complete_containers && ret=0
343                 ;;
344             (health)
345                 health_opts=('healthy' 'none' 'starting' 'unhealthy')
346                 _describe -t health-filter-opts "health filter options" health_opts && ret=0
347                 ;;
348             (id)
349                 __docker_complete_containers_ids && ret=0
350                 ;;
351             (is-task)
352                 _describe -t boolean-filter-opts "filter options" boolean_opts && ret=0
353                 ;;
354             (name)
355                 __docker_complete_containers_names && ret=0
356                 ;;
357             (network)
358                 __docker_complete_networks && ret=0
359                 ;;
360             (status)
361                 status_opts=('created' 'dead' 'exited' 'paused' 'restarting' 'running' 'removing')
362                 _describe -t status-filter-opts "status filter options" status_opts && ret=0
363                 ;;
364             (volume)
365                 __docker_complete_volumes && ret=0
366                 ;;
367             *)
368                 _message 'value' && ret=0
369                 ;;
370         esac
371     else
372         opts=('ancestor' 'before' 'exited' 'expose' 'health' 'id' 'label' 'name' 'network' 'publish' 'since' 'status' 'volume')
373         _describe -t filter-opts "Filter Options" opts -qS "=" && ret=0
374     fi
375
376     return ret
377 }
378
379 __docker_complete_search_filters() {
380     [[ $PREFIX = -* ]] && return 1
381     integer ret=1
382     declare -a boolean_opts opts
383
384     boolean_opts=('true' 'false')
385     opts=('is-automated' 'is-official' 'stars')
386
387     if compset -P '*='; then
388         case "${${words[-1]%=*}#*=}" in
389             (is-automated|is-official)
390                 _describe -t boolean-filter-opts "filter options" boolean_opts && ret=0
391                 ;;
392             *)
393                 _message 'value' && ret=0
394                 ;;
395         esac
396     else
397         _describe -t filter-opts "filter options" opts -qS "=" && ret=0
398     fi
399
400     return ret
401 }
402
403 __docker_complete_images_filters() {
404     [[ $PREFIX = -* ]] && return 1
405     integer ret=1
406     declare -a boolean_opts opts
407
408     boolean_opts=('true' 'false')
409     opts=('before' 'dangling' 'label' 'reference' 'since')
410
411     if compset -P '*='; then
412         case "${${words[-1]%=*}#*=}" in
413             (before|reference|since)
414                 __docker_complete_images && ret=0
415                 ;;
416             (dangling)
417                 _describe -t boolean-filter-opts "filter options" boolean_opts && ret=0
418                 ;;
419             *)
420                 _message 'value' && ret=0
421                 ;;
422         esac
423     else
424         _describe -t filter-opts "Filter Options" opts -qS "=" && ret=0
425     fi
426
427     return ret
428 }
429
430 __docker_complete_events_filter() {
431     [[ $PREFIX = -* ]] && return 1
432     integer ret=1
433     declare -a opts
434
435     opts=('container' 'daemon' 'event' 'image' 'label' 'network' 'scope' 'type' 'volume')
436
437     if compset -P '*='; then
438         case "${${words[-1]%=*}#*=}" in
439             (container)
440                 __docker_complete_containers && ret=0
441                 ;;
442             (daemon)
443                 emulate -L zsh
444                 setopt extendedglob
445                 local -a daemon_opts
446                 daemon_opts=(
447                     ${(f)${${"$(_call_program commands docker $docker_options info)"##*$'\n'Name: }%%$'\n'^ *}}
448                     ${${(f)${${"$(_call_program commands docker $docker_options info)"##*$'\n'ID: }%%$'\n'^ *}}//:/\\:}
449                 )
450                 _describe -t daemon-filter-opts "daemon filter options" daemon_opts && ret=0
451                 ;;
452             (event)
453                 local -a event_opts
454                 event_opts=('attach' 'commit' 'connect' 'copy' 'create' 'delete' 'destroy' 'detach' 'die' 'disable' 'disconnect' 'enable' 'exec_create' 'exec_detach'
455                 'exec_start' 'export' 'health_status' 'import' 'install' 'kill' 'load'  'mount' 'oom' 'pause' 'pull' 'push' 'reload' 'remove' 'rename' 'resize'
456                 'restart' 'save' 'start' 'stop' 'tag' 'top' 'unmount' 'unpause' 'untag' 'update')
457                 _describe -t event-filter-opts "event filter options" event_opts && ret=0
458                 ;;
459             (image)
460                 __docker_complete_images && ret=0
461                 ;;
462             (network)
463                 __docker_complete_networks && ret=0
464                 ;;
465             (scope)
466                 local -a scope_opts
467                 scope_opts=('local' 'swarm')
468                 _describe -t scope-filter-opts "scope filter options" scope_opts && ret=0
469                 ;;
470             (type)
471                 local -a type_opts
472                 type_opts=('container' 'daemon' 'image' 'network' 'volume')
473                 _describe -t type-filter-opts "type filter options" type_opts && ret=0
474                 ;;
475             (volume)
476                 __docker_complete_volumes && ret=0
477                 ;;
478             *)
479                 _message 'value' && ret=0
480                 ;;
481         esac
482     else
483         _describe -t filter-opts "filter options" opts -qS "=" && ret=0
484     fi
485
486     return ret
487 }
488
489 __docker_complete_prune_filters() {
490     [[ $PREFIX = -* ]] && return 1
491     integer ret=1
492     declare -a opts
493
494     opts=('until')
495
496     if compset -P '*='; then
497         case "${${words[-1]%=*}#*=}" in
498             *)
499                 _message 'value' && ret=0
500                 ;;
501         esac
502     else
503         _describe -t filter-opts "filter options" opts -qS "=" && ret=0
504     fi
505
506     return ret
507 }
508
509 # BO checkpoint
510
511 __docker_checkpoint_commands() {
512     local -a _docker_checkpoint_subcommands
513     _docker_checkpoint_subcommands=(
514         "create:Create a checkpoint from a running container"
515         "ls:List checkpoints for a container"
516         "rm:Remove a checkpoint"
517     )
518     _describe -t docker-checkpoint-commands "docker checkpoint command" _docker_checkpoint_subcommands
519 }
520
521 __docker_checkpoint_subcommand() {
522     local -a _command_args opts_help
523     local expl help="--help"
524     integer ret=1
525
526     opts_help=("(: -)--help[Print usage]")
527
528     case "$words[1]" in
529         (create)
530             _arguments $(__docker_arguments) \
531                 $opts_help \
532                 "($help)--checkpoint-dir=[Use a custom checkpoint storage directory]:dir:_directories" \
533                 "($help)--leave-running[Leave the container running after checkpoint]" \
534                 "($help -)1:container:__docker_complete_running_containers" \
535                 "($help -)2:checkpoint: " && ret=0
536             ;;
537         (ls|list)
538             _arguments $(__docker_arguments) \
539                 $opts_help \
540                 "($help)--checkpoint-dir=[Use a custom checkpoint storage directory]:dir:_directories" \
541                 "($help -)1:container:__docker_complete_containers" && ret=0
542             ;;
543         (rm|remove)
544             _arguments $(__docker_arguments) \
545                 $opts_help \
546                 "($help)--checkpoint-dir=[Use a custom checkpoint storage directory]:dir:_directories" \
547                 "($help -)1:container:__docker_complete_containers" \
548                 "($help -)2:checkpoint: " && ret=0
549             ;;
550         (help)
551             _arguments $(__docker_arguments) ":subcommand:__docker_checkpoint_commands" && ret=0
552             ;;
553     esac
554
555     return ret
556 }
557
558 # EO checkpoint
559
560 # BO container
561
562 __docker_container_commands() {
563     local -a _docker_container_subcommands
564     _docker_container_subcommands=(
565         "attach:Attach to a running container"
566         "commit:Create a new image from a container's changes"
567         "cp:Copy files/folders between a container and the local filesystem"
568         "create:Create a new container"
569         "diff:Inspect changes on a container's filesystem"
570         "exec:Run a command in a running container"
571         "export:Export a container's filesystem as a tar archive"
572         "inspect:Display detailed information on one or more containers"
573         "kill:Kill one or more running containers"
574         "logs:Fetch the logs of a container"
575         "ls:List containers"
576         "pause:Pause all processes within one or more containers"
577         "port:List port mappings or a specific mapping for the container"
578         "prune:Remove all stopped containers"
579         "rename:Rename a container"
580         "restart:Restart one or more containers"
581         "rm:Remove one or more containers"
582         "run:Run a command in a new container"
583         "start:Start one or more stopped containers"
584         "stats:Display a live stream of container(s) resource usage statistics"
585         "stop:Stop one or more running containers"
586         "top:Display the running processes of a container"
587         "unpause:Unpause all processes within one or more containers"
588         "update:Update configuration of one or more containers"
589         "wait:Block until one or more containers stop, then print their exit codes"
590     )
591     _describe -t docker-container-commands "docker container command" _docker_container_subcommands
592 }
593
594 __docker_container_subcommand() {
595     local -a _command_args opts_help opts_attach_exec_run_start opts_create_run opts_create_run_update
596     local expl help="--help"
597     integer ret=1
598
599     opts_attach_exec_run_start=(
600         "($help)--detach-keys=[Escape key sequence used to detach a container]:sequence:__docker_complete_detach_keys"
601     )
602     opts_create_run=(
603         "($help -a --attach)"{-a=,--attach=}"[Attach to stdin, stdout or stderr]:device:(STDIN STDOUT STDERR)"
604         "($help)*--add-host=[Add a custom host-to-IP mapping]:host\:ip mapping: "
605         "($help)*--blkio-weight-device=[Block IO (relative device weight)]:device:Block IO weight: "
606         "($help)*--cap-add=[Add Linux capabilities]:capability: "
607         "($help)*--cap-drop=[Drop Linux capabilities]:capability: "
608         "($help)--cgroupns=[Cgroup namespace mode to use]:cgroup namespace mode: "
609         "($help)--cgroup-parent=[Parent cgroup for the container]:cgroup: "
610         "($help)--cidfile=[Write the container ID to the file]:CID file:_files"
611         "($help)--cpus=[Number of CPUs (default 0.000)]:cpus: "
612         "($help)*--device=[Add a host device to the container]:device:_files"
613         "($help)*--device-cgroup-rule=[Add a rule to the cgroup allowed devices list]:device:cgroup: "
614         "($help)*--device-read-bps=[Limit the read rate (bytes per second) from a device]:device:IO rate: "
615         "($help)*--device-read-iops=[Limit the read rate (IO per second) from a device]:device:IO rate: "
616         "($help)*--device-write-bps=[Limit the write rate (bytes per second) to a device]:device:IO rate: "
617         "($help)*--device-write-iops=[Limit the write rate (IO per second) to a device]:device:IO rate: "
618         "($help)--disable-content-trust[Skip image verification]"
619         "($help)*--dns=[Custom DNS servers]:DNS server: "
620         "($help)*--dns-option=[Custom DNS options]:DNS option: "
621         "($help)*--dns-search=[Custom DNS search domains]:DNS domains: "
622         "($help)*--domainname=[Container NIS domain name]:domainname:_hosts"
623         "($help)*"{-e=,--env=}"[Environment variables]:environment variable: "
624         "($help)--entrypoint=[Overwrite the default entrypoint of the image]:entry point: "
625         "($help)*--env-file=[Read environment variables from a file]:environment file:_files"
626         "($help)*--expose=[Expose a port from the container without publishing it]: "
627         "($help)*--gpus=[GPU devices to add to the container ('all' to pass all GPUs)]:device: "
628         "($help)*--group-add=[Set one or more supplementary user groups for the container]:group:_groups"
629         "($help -h --hostname)"{-h=,--hostname=}"[Container host name]:hostname:_hosts"
630         "($help -i --interactive)"{-i,--interactive}"[Keep stdin open even if not attached]"
631         "($help)--init[Run an init inside the container that forwards signals and reaps processes]"
632         "($help)--ip=[IPv4 address]:IPv4: "
633         "($help)--ip6=[IPv6 address]:IPv6: "
634         "($help)--ipc=[IPC namespace to use]:IPC namespace: "
635         "($help)--isolation=[Container isolation technology]:isolation:(default hyperv process)"
636         "($help)*--link=[Add link to another container]:link:->link"
637         "($help)*--link-local-ip=[Container IPv4/IPv6 link-local addresses]:IPv4/IPv6: "
638         "($help)*"{-l=,--label=}"[Container metadata]:label: "
639         "($help)--log-driver=[Default driver for container logs]:logging driver:__docker_complete_log_drivers"
640         "($help)*--log-opt=[Log driver specific options]:log driver options:__docker_complete_log_options"
641         "($help)--mac-address=[Container MAC address]:MAC address: "
642         "($help)*--mount=[Attach a filesystem mount to the container]:mount: "
643         "($help)--name=[Container name]:name: "
644         "($help)--network=[Connect a container to a network]:network mode:(bridge none container host)"
645         "($help)*--network-alias=[Add network-scoped alias for the container]:alias: "
646         "($help)--oom-kill-disable[Disable OOM Killer]"
647         "($help)--oom-score-adj[Tune the host's OOM preferences for containers (accepts -1000 to 1000)]"
648         "($help)--pids-limit[Tune container pids limit (set -1 for unlimited)]"
649         "($help -P --publish-all)"{-P,--publish-all}"[Publish all exposed ports]"
650         "($help)*"{-p=,--publish=}"[Expose a container's port to the host]:port:_ports"
651         "($help)--pid=[PID namespace to use]:PID namespace:__docker_complete_pid"
652         "($help)--privileged[Give extended privileges to this container]"
653         "($help)--read-only[Mount the container's root filesystem as read only]"
654         "($help)*--security-opt=[Security options]:security option: "
655         "($help)*--shm-size=[Size of '/dev/shm' (format is '<number><unit>')]:shm size: "
656         "($help)--stop-signal=[Signal to kill a container]:signal:_signals"
657         "($help)--stop-timeout=[Timeout (in seconds) to stop a container]:time: "
658         "($help)*--sysctl=-[sysctl options]:sysctl: "
659         "($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]"
660         "($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users"
661         "($help)*--ulimit=[ulimit options]:ulimit: "
662         "($help)--userns=[Container user namespace]:user namespace:(host)"
663         "($help)--tmpfs[mount tmpfs]"
664         "($help)*-v[Bind mount a volume]:volume: "
665         "($help)--volume-driver=[Optional volume driver for the container]:volume driver:(local)"
666         "($help)*--volumes-from=[Mount volumes from the specified container]:volume: "
667         "($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories"
668     )
669     opts_create_run_update=(
670         "($help)--blkio-weight=[Block IO (relative weight), between 10 and 1000]:Block IO weight:(10 100 500 1000)"
671         "($help -c --cpu-shares)"{-c=,--cpu-shares=}"[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)"
672         "($help)--cpu-period=[Limit the CPU CFS (Completely Fair Scheduler) period]:CPU period: "
673         "($help)--cpu-quota=[Limit the CPU CFS (Completely Fair Scheduler) quota]:CPU quota: "
674         "($help)--cpu-rt-period=[Limit the CPU real-time period]:CPU real-time period in microseconds: "
675         "($help)--cpu-rt-runtime=[Limit the CPU real-time runtime]:CPU real-time runtime in microseconds: "
676         "($help)--cpuset-cpus=[CPUs in which to allow execution]:CPUs: "
677         "($help)--cpuset-mems=[MEMs in which to allow execution]:MEMs: "
678         "($help)--kernel-memory=[Kernel memory limit in bytes]:Memory limit: "
679         "($help -m --memory)"{-m=,--memory=}"[Memory limit]:Memory limit: "
680         "($help)--memory-reservation=[Memory soft limit]:Memory limit: "
681         "($help)--memory-swap=[Total memory limit with swap]:Memory limit: "
682         "($help)--pids-limit[Tune container pids limit (set -1 for unlimited)]"
683         "($help)--restart=[Restart policy]:restart policy:(no on-failure always unless-stopped)"
684     )
685     opts_help=("(: -)--help[Print usage]")
686
687     case "$words[1]" in
688         (attach)
689             _arguments $(__docker_arguments) \
690                 $opts_help \
691                 $opts_attach_exec_run_start \
692                 "($help)--no-stdin[Do not attach stdin]" \
693                 "($help)--sig-proxy[Proxy all received signals to the process (non-TTY mode only)]" \
694                 "($help -):containers:__docker_complete_running_containers" && ret=0
695             ;;
696         (commit)
697             _arguments $(__docker_arguments) \
698                 $opts_help \
699                 "($help -a --author)"{-a=,--author=}"[Author]:author: " \
700                 "($help)*"{-c=,--change=}"[Apply Dockerfile instruction to the created image]:Dockerfile:_files" \
701                 "($help -m --message)"{-m=,--message=}"[Commit message]:message: " \
702                 "($help -p --pause)"{-p,--pause}"[Pause container during commit]" \
703                 "($help -):container:__docker_complete_containers" \
704                 "($help -): :__docker_complete_repositories_with_tags" && ret=0
705             ;;
706         (cp)
707             local state
708             _arguments $(__docker_arguments) \
709                 $opts_help \
710                 "($help -L --follow-link)"{-L,--follow-link}"[Always follow symbol link]" \
711                 "($help -)1:container:->container" \
712                 "($help -)2:hostpath:_files" && ret=0
713             case $state in
714                 (container)
715                     if compset -P "*:"; then
716                         _files && ret=0
717                     else
718                         __docker_complete_containers -qS ":" && ret=0
719                     fi
720                     ;;
721             esac
722             ;;
723         (create)
724             local state
725             _arguments $(__docker_arguments) \
726                 $opts_help \
727                 $opts_create_run \
728                 $opts_create_run_update \
729                 "($help -): :__docker_complete_images" \
730                 "($help -):command: _command_names -e" \
731                 "($help -)*::arguments: _normal" && ret=0
732             case $state in
733                 (link)
734                     if compset -P "*:"; then
735                         _wanted alias expl "Alias" compadd -E "" && ret=0
736                     else
737                         __docker_complete_running_containers -qS ":" && ret=0
738                     fi
739                     ;;
740             esac
741             ;;
742         (diff)
743             _arguments $(__docker_arguments) \
744                 $opts_help \
745                 "($help -)*:containers:__docker_complete_containers" && ret=0
746             ;;
747         (exec)
748             local state
749             _arguments $(__docker_arguments) \
750                 $opts_help \
751                 $opts_attach_exec_run_start \
752                 "($help -d --detach)"{-d,--detach}"[Detached mode: leave the container running in the background]" \
753                 "($help)*"{-e=,--env=}"[Set environment variables]:environment variable: " \
754                 "($help)*--env-file=[Read environment variables from a file]:environment file:_files" \
755                 "($help -i --interactive)"{-i,--interactive}"[Keep stdin open even if not attached]" \
756                 "($help)--privileged[Give extended Linux capabilities to the command]" \
757                 "($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]" \
758                 "($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users" \
759                 "($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories" \
760                 "($help -):containers:__docker_complete_running_containers" \
761                 "($help -)*::command:->anycommand" && ret=0
762             case $state in
763                 (anycommand)
764                     shift 1 words
765                     (( CURRENT-- ))
766                     _normal && ret=0
767                     ;;
768             esac
769             ;;
770         (export)
771             _arguments $(__docker_arguments) \
772                 $opts_help \
773                 "($help -o --output)"{-o=,--output=}"[Write to a file, instead of stdout]:output file:_files" \
774                 "($help -)*:containers:__docker_complete_containers" && ret=0
775             ;;
776         (inspect)
777             _arguments $(__docker_arguments) \
778                 $opts_help \
779                 "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
780                 "($help -s --size)"{-s,--size}"[Display total file sizes]" \
781                 "($help -)*:containers:__docker_complete_containers" && ret=0
782             ;;
783         (kill)
784             _arguments $(__docker_arguments) \
785                 $opts_help \
786                 "($help -s --signal)"{-s=,--signal=}"[Signal to send]:signal:_signals" \
787                 "($help -)*:containers:__docker_complete_running_containers" && ret=0
788             ;;
789         (logs)
790             _arguments $(__docker_arguments) \
791                 $opts_help \
792                 "($help)--details[Show extra details provided to logs]" \
793                 "($help -f --follow)"{-f,--follow}"[Follow log output]" \
794                 "($help -s --since)"{-s=,--since=}"[Show logs since this timestamp]:timestamp: " \
795                 "($help -t --timestamps)"{-t,--timestamps}"[Show timestamps]" \
796                 "($help -n --tail)"{-n=,--tail=}"[Number of lines to show from the end of the logs]:lines:(1 10 20 50 all)" \
797                 "($help -)*:containers:__docker_complete_containers" && ret=0
798             ;;
799         (ls|list)
800             _arguments $(__docker_arguments) \
801                 $opts_help \
802                 "($help -a --all)"{-a,--all}"[Show all containers]" \
803                 "($help)--before=[Show only container created before...]:containers:__docker_complete_containers" \
804                 "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_ps_filters" \
805                 "($help)--format=[Pretty-print containers using a Go template]:template: " \
806                 "($help -l --latest)"{-l,--latest}"[Show only the latest created container]" \
807                 "($help -n --last)"{-n=,--last=}"[Show n last created containers (includes all states)]:n:(1 5 10 25 50)" \
808                 "($help)--no-trunc[Do not truncate output]" \
809                 "($help -q --quiet)"{-q,--quiet}"[Only show container IDs]" \
810                 "($help -s --size)"{-s,--size}"[Display total file sizes]" \
811                 "($help)--since=[Show only containers created since...]:containers:__docker_complete_containers" && ret=0
812             ;;
813         (pause|unpause)
814             _arguments $(__docker_arguments) \
815                 $opts_help \
816                 "($help -)*:containers:__docker_complete_running_containers" && ret=0
817             ;;
818         (port)
819             _arguments $(__docker_arguments) \
820                 $opts_help \
821                 "($help -)1:containers:__docker_complete_running_containers" \
822                 "($help -)2:port:_ports" && ret=0
823             ;;
824         (prune)
825             _arguments $(__docker_arguments) \
826                 $opts_help \
827                 "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
828                 "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
829             ;;
830         (rename)
831             _arguments $(__docker_arguments) \
832                 $opts_help \
833                 "($help -):old name:__docker_complete_containers" \
834                 "($help -):new name: " && ret=0
835             ;;
836         (restart)
837             _arguments $(__docker_arguments) \
838                 $opts_help \
839                 "($help -t --time)"{-t=,--time=}"[Number of seconds to try to stop for before killing the container]:seconds to before killing:(1 5 10 30 60)" \
840                 "($help -)*:containers:__docker_complete_containers" && ret=0
841             ;;
842         (rm)
843             local state
844             _arguments $(__docker_arguments) \
845                 $opts_help \
846                 "($help -f --force)"{-f,--force}"[Force removal]" \
847                 "($help -l --link)"{-l,--link}"[Remove the specified link and not the underlying container]" \
848                 "($help -v --volumes)"{-v,--volumes}"[Remove the volumes associated to the container]" \
849                 "($help -)*:containers:->values" && ret=0
850             case $state in
851                 (values)
852                     if [[ ${words[(r)-f]} == -f || ${words[(r)--force]} == --force ]]; then
853                         __docker_complete_containers && ret=0
854                     else
855                         __docker_complete_stopped_containers && ret=0
856                     fi
857                     ;;
858             esac
859             ;;
860         (run)
861             local state
862             _arguments $(__docker_arguments) \
863                 $opts_help \
864                 $opts_create_run \
865                 $opts_create_run_update \
866                 $opts_attach_exec_run_start \
867                 "($help -d --detach)"{-d,--detach}"[Detached mode: leave the container running in the background]" \
868                 "($help)--health-cmd=[Command to run to check health]:command: " \
869                 "($help)--health-interval=[Time between running the check]:time: " \
870                 "($help)--health-retries=[Consecutive failures needed to report unhealthy]:retries:(1 2 3 4 5)" \
871                 "($help)--health-timeout=[Maximum time to allow one check to run]:time: " \
872                 "($help)--no-healthcheck[Disable any container-specified HEALTHCHECK]" \
873                 "($help)--rm[Remove intermediate containers when it exits]" \
874                 "($help)--runtime=[Name of the runtime to be used for that container]:runtime:__docker_complete_runtimes" \
875                 "($help)--sig-proxy[Proxy all received signals to the process (non-TTY mode only)]" \
876                 "($help)--storage-opt=[Storage driver options for the container]:storage options:->storage-opt" \
877                 "($help -): :__docker_complete_images" \
878                 "($help -):command: _command_names -e" \
879                 "($help -)*::arguments: _normal" && ret=0
880             case $state in
881                 (link)
882                     if compset -P "*:"; then
883                         _wanted alias expl "Alias" compadd -E "" && ret=0
884                     else
885                         __docker_complete_running_containers -qS ":" && ret=0
886                     fi
887                     ;;
888                 (storage-opt)
889                     if compset -P "*="; then
890                         _message "value" && ret=0
891                     else
892                         opts=('size')
893                         _describe -t filter-opts "storage options" opts -qS "=" && ret=0
894                     fi
895                     ;;
896             esac
897             ;;
898         (start)
899             _arguments $(__docker_arguments) \
900                 $opts_help \
901                 $opts_attach_exec_run_start \
902                 "($help -a --attach)"{-a,--attach}"[Attach container's stdout/stderr and forward all signals]" \
903                 "($help -i --interactive)"{-i,--interactive}"[Attach container's stdin]" \
904                 "($help -)*:containers:__docker_complete_stopped_containers" && ret=0
905             ;;
906         (stats)
907             _arguments $(__docker_arguments) \
908                 $opts_help \
909                 "($help -a --all)"{-a,--all}"[Show all containers (default shows just running)]" \
910                 "($help)--format=[Pretty-print images using a Go template]:template: " \
911                 "($help)--no-stream[Disable streaming stats and only pull the first result]" \
912                 "($help)--no-trunc[Do not truncate output]" \
913                 "($help -)*:containers:__docker_complete_running_containers" && ret=0
914             ;;
915         (stop)
916             _arguments $(__docker_arguments) \
917                 $opts_help \
918                 "($help -t --time)"{-t=,--time=}"[Number of seconds to try to stop for before killing the container]:seconds to before killing:(1 5 10 30 60)" \
919                 "($help -)*:containers:__docker_complete_running_containers" && ret=0
920             ;;
921         (top)
922             local state
923             _arguments $(__docker_arguments) \
924                 $opts_help \
925                 "($help -)1:containers:__docker_complete_running_containers" \
926                 "($help -)*:: :->ps-arguments" && ret=0
927             case $state in
928                 (ps-arguments)
929                     _ps && ret=0
930                     ;;
931             esac
932             ;;
933         (update)
934             local state
935             _arguments $(__docker_arguments) \
936                 $opts_help \
937                 $opts_create_run_update \
938                 "($help -)*: :->values" && ret=0
939             case $state in
940                 (values)
941                     if [[ ${words[(r)--kernel-memory*]} = (--kernel-memory*) ]]; then
942                         __docker_complete_stopped_containers && ret=0
943                     else
944                         __docker_complete_containers && ret=0
945                     fi
946                     ;;
947             esac
948             ;;
949         (wait)
950             _arguments $(__docker_arguments) \
951                 $opts_help \
952                 "($help -)*:containers:__docker_complete_running_containers" && ret=0
953             ;;
954         (help)
955             _arguments $(__docker_arguments) ":subcommand:__docker_container_commands" && ret=0
956             ;;
957     esac
958
959     return ret
960 }
961
962 # EO container
963
964 # BO image
965
966 __docker_image_commands() {
967     local -a _docker_image_subcommands
968     _docker_image_subcommands=(
969         "build:Build an image from a Dockerfile"
970         "history:Show the history of an image"
971         "import:Import the contents from a tarball to create a filesystem image"
972         "inspect:Display detailed information on one or more images"
973         "load:Load an image from a tar archive or STDIN"
974         "ls:List images"
975         "prune:Remove unused images"
976         "pull:Pull an image or a repository from a registry"
977         "push:Push an image or a repository to a registry"
978         "rm:Remove one or more images"
979         "save:Save one or more images to a tar archive (streamed to STDOUT by default)"
980         "tag:Tag an image into a repository"
981     )
982     _describe -t docker-image-commands "docker image command" _docker_image_subcommands
983 }
984
985 __docker_image_subcommand() {
986     local -a _command_args opts_help
987     local expl help="--help"
988     integer ret=1
989
990     opts_help=("(: -)--help[Print usage]")
991
992     case "$words[1]" in
993         (build)
994             _arguments $(__docker_arguments) \
995                 $opts_help \
996                 "($help)*--add-host=[Add a custom host-to-IP mapping]:host\:ip mapping: " \
997                 "($help)*--build-arg=[Build-time variables]:<varname>=<value>: " \
998                 "($help)*--cache-from=[Images to consider as cache sources]: :__docker_complete_repositories_with_tags" \
999                 "($help -c --cpu-shares)"{-c=,--cpu-shares=}"[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)" \
1000                 "($help)--cgroup-parent=[Parent cgroup for the container]:cgroup: " \
1001                 "($help)--compress[Compress the build context using gzip]" \
1002                 "($help)--cpu-period=[Limit the CPU CFS (Completely Fair Scheduler) period]:CPU period: " \
1003                 "($help)--cpu-quota=[Limit the CPU CFS (Completely Fair Scheduler) quota]:CPU quota: " \
1004                 "($help)--cpu-rt-period=[Limit the CPU real-time period]:CPU real-time period in microseconds: " \
1005                 "($help)--cpu-rt-runtime=[Limit the CPU real-time runtime]:CPU real-time runtime in microseconds: " \
1006                 "($help)--cpuset-cpus=[CPUs in which to allow execution]:CPUs: " \
1007                 "($help)--cpuset-mems=[MEMs in which to allow execution]:MEMs: " \
1008                 "($help)--disable-content-trust[Skip image verification]" \
1009                 "($help -f --file)"{-f=,--file=}"[Name of the Dockerfile]:Dockerfile:_files" \
1010                 "($help)--force-rm[Always remove intermediate containers]" \
1011                 "($help)--isolation=[Container isolation technology]:isolation:(default hyperv process)" \
1012                 "($help)*--label=[Set metadata for an image]:label=value: " \
1013                 "($help -m --memory)"{-m=,--memory=}"[Memory limit]:Memory limit: " \
1014                 "($help)--memory-swap=[Total memory limit with swap]:Memory limit: " \
1015                 "($help)--network=[Connect a container to a network]:network mode:(bridge none container host)" \
1016                 "($help)--no-cache[Do not use cache when building the image]" \
1017                 "($help)--pull[Attempt to pull a newer version of the image]" \
1018                 "($help -q --quiet)"{-q,--quiet}"[Suppress verbose build output]" \
1019                 "($help)--rm[Remove intermediate containers after a successful build]" \
1020                 "($help)*--shm-size=[Size of '/dev/shm' (format is '<number><unit>')]:shm size: " \
1021                 "($help)--squash[Squash newly built layers into a single new layer]" \
1022                 "($help -t --tag)*"{-t=,--tag=}"[Repository, name and tag for the image]: :__docker_complete_repositories_with_tags" \
1023                 "($help)--target=[Set the target build stage to build.]" \
1024                 "($help)*--ulimit=[ulimit options]:ulimit: " \
1025                 "($help)--userns=[Container user namespace]:user namespace:(host)" \
1026                 "($help -):path or URL:_directories" && ret=0
1027             ;;
1028         (history)
1029             _arguments $(__docker_arguments) \
1030                 $opts_help \
1031                 "($help -H --human)"{-H,--human}"[Print sizes and dates in human readable format]" \
1032                 "($help)--no-trunc[Do not truncate output]" \
1033                 "($help -q --quiet)"{-q,--quiet}"[Only show image IDs]" \
1034                 "($help -)*: :__docker_complete_images" && ret=0
1035             ;;
1036         (import)
1037             _arguments $(__docker_arguments) \
1038                 $opts_help \
1039                 "($help)*"{-c=,--change=}"[Apply Dockerfile instruction to the created image]:Dockerfile:_files" \
1040                 "($help -m --message)"{-m=,--message=}"[Commit message for imported image]:message: " \
1041                 "($help -):URL:(- http:// file://)" \
1042                 "($help -): :__docker_complete_repositories_with_tags" && ret=0
1043             ;;
1044         (inspect)
1045             _arguments $(__docker_arguments) \
1046                 $opts_help \
1047                 "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
1048                 "($help -)*:images:__docker_complete_images" && ret=0
1049             ;;
1050         (load)
1051             _arguments $(__docker_arguments) \
1052                 $opts_help \
1053                 "($help -i --input)"{-i=,--input=}"[Read from tar archive file]:archive file:_files -g \"*.((tar|TAR)(.gz|.GZ|.Z|.bz2|.lzma|.xz|)|(tbz|tgz|txz))(-.)\"" \
1054                 "($help -q --quiet)"{-q,--quiet}"[Suppress the load output]" && ret=0
1055             ;;
1056         (ls|list)
1057             local state
1058             _arguments $(__docker_arguments) \
1059                 $opts_help \
1060                 "($help -a --all)"{-a,--all}"[Show all images]" \
1061                 "($help)--digests[Show digests]" \
1062                 "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_images_filters" \
1063                 "($help)--format=[Pretty-print images using a Go template]:template: " \
1064                 "($help)--no-trunc[Do not truncate output]" \
1065                 "($help -q --quiet)"{-q,--quiet}"[Only show image IDs]" \
1066                 "($help -): :__docker_complete_repositories" && ret=0
1067             ;;
1068         (prune)
1069             _arguments $(__docker_arguments) \
1070                 $opts_help \
1071                 "($help -a --all)"{-a,--all}"[Remove all unused images, not just dangling ones]" \
1072                 "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
1073                 "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
1074             ;;
1075         (pull)
1076             _arguments $(__docker_arguments) \
1077                 $opts_help \
1078                 "($help -a --all-tags)"{-a,--all-tags}"[Download all tagged images]" \
1079                 "($help)--disable-content-trust[Skip image verification]" \
1080                 "($help -):name:__docker_search" && ret=0
1081             ;;
1082         (push)
1083             _arguments $(__docker_arguments) \
1084                 $opts_help \
1085                 "($help -a --all-tags)"{-a,--all-tags}"[Push all tagged images in the repository]" \
1086                 "($help)--disable-content-trust[Skip image signing]" \
1087                 "($help -): :__docker_complete_images" && ret=0
1088             ;;
1089         (rm)
1090             _arguments $(__docker_arguments) \
1091                 $opts_help \
1092                 "($help -f --force)"{-f,--force}"[Force removal]" \
1093                 "($help)--no-prune[Do not delete untagged parents]" \
1094                 "($help -)*: :__docker_complete_images" && ret=0
1095             ;;
1096         (save)
1097             _arguments $(__docker_arguments) \
1098                 $opts_help \
1099                 "($help -o --output)"{-o=,--output=}"[Write to file]:file:_files" \
1100                 "($help -)*: :__docker_complete_images" && ret=0
1101             ;;
1102         (tag)
1103             _arguments $(__docker_arguments) \
1104                 $opts_help \
1105                 "($help -):source:__docker_complete_images"\
1106                 "($help -):destination:__docker_complete_repositories_with_tags" && ret=0
1107             ;;
1108         (help)
1109             _arguments $(__docker_arguments) ":subcommand:__docker_container_commands" && ret=0
1110             ;;
1111     esac
1112
1113     return ret
1114 }
1115
1116 # EO image
1117
1118 # BO network
1119
1120 __docker_network_complete_ls_filters() {
1121     [[ $PREFIX = -* ]] && return 1
1122     integer ret=1
1123
1124     if compset -P '*='; then
1125         case "${${words[-1]%=*}#*=}" in
1126             (driver)
1127                 __docker_complete_info_plugins Network && ret=0
1128                 ;;
1129             (id)
1130                 __docker_complete_networks_ids && ret=0
1131                 ;;
1132             (name)
1133                 __docker_complete_networks_names && ret=0
1134                 ;;
1135             (scope)
1136                 opts=('global' 'local' 'swarm')
1137                 _describe -t scope-filter-opts "Scope filter options" opts && ret=0
1138                 ;;
1139             (type)
1140                 opts=('builtin' 'custom')
1141                 _describe -t type-filter-opts "Type filter options" opts && ret=0
1142                 ;;
1143             *)
1144                 _message 'value' && ret=0
1145                 ;;
1146         esac
1147     else
1148         opts=('driver' 'id' 'label' 'name' 'scope' 'type')
1149         _describe -t filter-opts "Filter Options" opts -qS "=" && ret=0
1150     fi
1151
1152     return ret
1153 }
1154
1155 __docker_get_networks() {
1156     [[ $PREFIX = -* ]] && return 1
1157     integer ret=1
1158     local line s
1159     declare -a lines networks
1160
1161     type=$1; shift
1162
1163     lines=(${(f)${:-"$(_call_program commands docker $docker_options network ls)"$'\n'}})
1164
1165     # Parse header line to find columns
1166     local i=1 j=1 k header=${lines[1]}
1167     declare -A begin end
1168     while (( j < ${#header} - 1 )); do
1169         i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
1170         j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
1171         k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
1172         begin[${header[$i,$((j-1))]}]=$i
1173         end[${header[$i,$((j-1))]}]=$k
1174     done
1175     end[${header[$i,$((j-1))]}]=-1
1176     lines=(${lines[2,-1]})
1177
1178     # Network ID
1179     if [[ $type = (ids|all) ]]; then
1180         for line in $lines; do
1181             s="${line[${begin[NETWORK ID]},${end[NETWORK ID]}]%% ##}"
1182             s="$s:${(l:7:: :::)${${line[${begin[DRIVER]},${end[DRIVER]}]}%% ##}}"
1183             s="$s, ${${line[${begin[SCOPE]},${end[SCOPE]}]}%% ##}"
1184             networks=($networks $s)
1185         done
1186     fi
1187
1188     # Names
1189     if [[ $type = (names|all) ]]; then
1190         for line in $lines; do
1191             s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
1192             s="$s:${(l:7:: :::)${${line[${begin[DRIVER]},${end[DRIVER]}]}%% ##}}"
1193             s="$s, ${${line[${begin[SCOPE]},${end[SCOPE]}]}%% ##}"
1194             networks=($networks $s)
1195         done
1196     fi
1197
1198     _describe -t networks-list "networks" networks "$@" && ret=0
1199     return ret
1200 }
1201
1202 __docker_complete_networks() {
1203     [[ $PREFIX = -* ]] && return 1
1204     __docker_get_networks all "$@"
1205 }
1206
1207 __docker_complete_networks_ids() {
1208     [[ $PREFIX = -* ]] && return 1
1209     __docker_get_networks ids "$@"
1210 }
1211
1212 __docker_complete_networks_names() {
1213     [[ $PREFIX = -* ]] && return 1
1214     __docker_get_networks names "$@"
1215 }
1216
1217 __docker_network_commands() {
1218     local -a _docker_network_subcommands
1219     _docker_network_subcommands=(
1220         "connect:Connect a container to a network"
1221         "create:Creates a new network with a name specified by the user"
1222         "disconnect:Disconnects a container from a network"
1223         "inspect:Displays detailed information on a network"
1224         "ls:Lists all the networks created by the user"
1225         "prune:Remove all unused networks"
1226         "rm:Deletes one or more networks"
1227     )
1228     _describe -t docker-network-commands "docker network command" _docker_network_subcommands
1229 }
1230
1231 __docker_network_subcommand() {
1232     local -a _command_args opts_help
1233     local expl help="--help"
1234     integer ret=1
1235
1236     opts_help=("(: -)--help[Print usage]")
1237
1238     case "$words[1]" in
1239         (connect)
1240             _arguments $(__docker_arguments) \
1241                 $opts_help \
1242                 "($help)*--alias=[Add network-scoped alias for the container]:alias: " \
1243                 "($help)--ip=[IPv4 address]:IPv4: " \
1244                 "($help)--ip6=[IPv6 address]:IPv6: " \
1245                 "($help)*--link=[Add a link to another container]:link:->link" \
1246                 "($help)*--link-local-ip=[Add a link-local address for the container]:IPv4/IPv6: " \
1247                 "($help -)1:network:__docker_complete_networks" \
1248                 "($help -)2:containers:__docker_complete_containers" && ret=0
1249
1250             case $state in
1251                 (link)
1252                     if compset -P "*:"; then
1253                         _wanted alias expl "Alias" compadd -E "" && ret=0
1254                     else
1255                         __docker_complete_running_containers -qS ":" && ret=0
1256                     fi
1257                     ;;
1258             esac
1259             ;;
1260         (create)
1261             _arguments $(__docker_arguments) -A '-*' \
1262                 $opts_help \
1263                 "($help)--attachable[Enable manual container attachment]" \
1264                 "($help)*--aux-address[Auxiliary IPv4 or IPv6 addresses used by network driver]:key=IP: " \
1265                 "($help -d --driver)"{-d=,--driver=}"[Driver to manage the Network]:driver:(null host bridge overlay)" \
1266                 "($help)*--gateway=[IPv4 or IPv6 Gateway for the master subnet]:IP: " \
1267                 "($help)--internal[Restricts external access to the network]" \
1268                 "($help)*--ip-range=[Allocate container ip from a sub-range]:IP/mask: " \
1269                 "($help)--ipam-driver=[IP Address Management Driver]:driver:(default)" \
1270                 "($help)*--ipam-opt=[Custom IPAM plugin options]:opt=value: " \
1271                 "($help)--ipv6[Enable IPv6 networking]" \
1272                 "($help)*--label=[Set metadata on a network]:label=value: " \
1273                 "($help)*"{-o=,--opt=}"[Driver specific options]:opt=value: " \
1274                 "($help)*--subnet=[Subnet in CIDR format that represents a network segment]:IP/mask: " \
1275                 "($help -)1:Network Name: " && ret=0
1276             ;;
1277         (disconnect)
1278             _arguments $(__docker_arguments) \
1279                 $opts_help \
1280                 "($help -)1:network:__docker_complete_networks" \
1281                 "($help -)2:containers:__docker_complete_containers" && ret=0
1282             ;;
1283         (inspect)
1284             _arguments $(__docker_arguments) \
1285                 $opts_help \
1286                 "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
1287                 "($help)--verbose[Show detailed information]" \
1288                 "($help -)*:network:__docker_complete_networks" && ret=0
1289             ;;
1290         (ls)
1291             _arguments $(__docker_arguments) \
1292                 $opts_help \
1293                 "($help)--no-trunc[Do not truncate the output]" \
1294                 "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_network_complete_ls_filters" \
1295                 "($help)--format=[Pretty-print networks using a Go template]:template: " \
1296                 "($help -q --quiet)"{-q,--quiet}"[Only display network IDs]" && ret=0
1297             ;;
1298         (prune)
1299             _arguments $(__docker_arguments) \
1300                 $opts_help \
1301                 "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
1302                 "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
1303             ;;
1304         (rm)
1305             _arguments $(__docker_arguments) \
1306                 $opts_help \
1307                 "($help -)*:network:__docker_complete_networks" && ret=0
1308             ;;
1309         (help)
1310             _arguments $(__docker_arguments) ":subcommand:__docker_network_commands" && ret=0
1311             ;;
1312     esac
1313
1314     return ret
1315 }
1316
1317 # EO network
1318
1319 # BO node
1320
1321 __docker_node_complete_ls_filters() {
1322     [[ $PREFIX = -* ]] && return 1
1323     integer ret=1
1324
1325     if compset -P '*='; then
1326         case "${${words[-1]%=*}#*=}" in
1327             (id)
1328                 __docker_complete_nodes_ids && ret=0
1329                 ;;
1330             (membership)
1331                 membership_opts=('accepted' 'pending' 'rejected')
1332                 _describe -t membership-opts "membership options" membership_opts && ret=0
1333                 ;;
1334             (name)
1335                 __docker_complete_nodes_names && ret=0
1336                 ;;
1337             (role)
1338                 role_opts=('manager' 'worker')
1339                 _describe -t role-opts "role options" role_opts && ret=0
1340                 ;;
1341             *)
1342                 _message 'value' && ret=0
1343                 ;;
1344         esac
1345     else
1346         opts=('id' 'label' 'membership' 'name' 'node.label' 'role')
1347         _describe -t filter-opts "filter options" opts -qS "=" && ret=0
1348     fi
1349
1350     return ret
1351 }
1352
1353 __docker_node_complete_ps_filters() {
1354     [[ $PREFIX = -* ]] && return 1
1355     integer ret=1
1356
1357     if compset -P '*='; then
1358         case "${${words[-1]%=*}#*=}" in
1359             (desired-state)
1360                 state_opts=('accepted' 'running' 'shutdown')
1361                 _describe -t state-opts "desired state options" state_opts && ret=0
1362                 ;;
1363             *)
1364                 _message 'value' && ret=0
1365                 ;;
1366         esac
1367     else
1368         opts=('desired-state' 'id' 'label' 'name')
1369         _describe -t filter-opts "filter options" opts -qS "=" && ret=0
1370     fi
1371
1372     return ret
1373 }
1374
1375 __docker_nodes() {
1376     [[ $PREFIX = -* ]] && return 1
1377     integer ret=1
1378     local line s
1379     declare -a lines nodes args
1380
1381     type=$1; shift
1382     filter=$1; shift
1383     [[ $filter != "none" ]] && args=("-f $filter")
1384
1385     lines=(${(f)${:-"$(_call_program commands docker $docker_options node ls $args)"$'\n'}})
1386     # Parse header line to find columns
1387     local i=1 j=1 k header=${lines[1]}
1388     declare -A begin end
1389     while (( j < ${#header} - 1 )); do
1390         i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
1391         j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
1392         k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
1393         begin[${header[$i,$((j-1))]}]=$i
1394         end[${header[$i,$((j-1))]}]=$k
1395     done
1396     end[${header[$i,$((j-1))]}]=-1
1397     lines=(${lines[2,-1]})
1398
1399     # Node ID
1400     if [[ $type = (ids|all) ]]; then
1401         for line in $lines; do
1402             s="${line[${begin[ID]},${end[ID]}]%% ##}"
1403             nodes=($nodes $s)
1404         done
1405     fi
1406
1407     # Names
1408     if [[ $type = (names|all) ]]; then
1409         for line in $lines; do
1410             s="${line[${begin[HOSTNAME]},${end[HOSTNAME]}]%% ##}"
1411             nodes=($nodes $s)
1412         done
1413     fi
1414
1415     _describe -t nodes-list "nodes" nodes "$@" && ret=0
1416     return ret
1417 }
1418
1419 __docker_complete_nodes() {
1420     [[ $PREFIX = -* ]] && return 1
1421     __docker_nodes all none "$@"
1422 }
1423
1424 __docker_complete_nodes_ids() {
1425     [[ $PREFIX = -* ]] && return 1
1426     __docker_nodes ids none "$@"
1427 }
1428
1429 __docker_complete_nodes_names() {
1430     [[ $PREFIX = -* ]] && return 1
1431     __docker_nodes names none "$@"
1432 }
1433
1434 __docker_complete_pending_nodes() {
1435     [[ $PREFIX = -* ]] && return 1
1436     __docker_nodes all "membership=pending" "$@"
1437 }
1438
1439 __docker_complete_manager_nodes() {
1440     [[ $PREFIX = -* ]] && return 1
1441     __docker_nodes all "role=manager" "$@"
1442 }
1443
1444 __docker_complete_worker_nodes() {
1445     [[ $PREFIX = -* ]] && return 1
1446     __docker_nodes all "role=worker" "$@"
1447 }
1448
1449 __docker_node_commands() {
1450     local -a _docker_node_subcommands
1451     _docker_node_subcommands=(
1452         "demote:Demote a node as manager in the swarm"
1453         "inspect:Display detailed information on one or more nodes"
1454         "ls:List nodes in the swarm"
1455         "promote:Promote a node as manager in the swarm"
1456         "rm:Remove one or more nodes from the swarm"
1457         "ps:List tasks running on one or more nodes, defaults to current node"
1458         "update:Update a node"
1459     )
1460     _describe -t docker-node-commands "docker node command" _docker_node_subcommands
1461 }
1462
1463 __docker_node_subcommand() {
1464     local -a _command_args opts_help
1465     local expl help="--help"
1466     integer ret=1
1467
1468     opts_help=("(: -)--help[Print usage]")
1469
1470     case "$words[1]" in
1471         (rm|remove)
1472              _arguments $(__docker_arguments) \
1473                 $opts_help \
1474                 "($help -f --force)"{-f,--force}"[Force remove a node from the swarm]" \
1475                 "($help -)*:node:__docker_complete_pending_nodes" && ret=0
1476             ;;
1477         (demote)
1478              _arguments $(__docker_arguments) \
1479                 $opts_help \
1480                 "($help -)*:node:__docker_complete_manager_nodes" && ret=0
1481             ;;
1482         (inspect)
1483             _arguments $(__docker_arguments) \
1484                 $opts_help \
1485                 "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
1486                 "($help)--pretty[Print the information in a human friendly format]" \
1487                 "($help -)*:node:__docker_complete_nodes" && ret=0
1488             ;;
1489         (ls|list)
1490             _arguments $(__docker_arguments) \
1491                 $opts_help \
1492                 "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_node_complete_ls_filters" \
1493                 "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0
1494             ;;
1495         (promote)
1496              _arguments $(__docker_arguments) \
1497                 $opts_help \
1498                 "($help -)*:node:__docker_complete_worker_nodes" && ret=0
1499             ;;
1500         (ps)
1501             _arguments $(__docker_arguments) \
1502                 $opts_help \
1503                 "($help -a --all)"{-a,--all}"[Display all instances]" \
1504                 "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_node_complete_ps_filters" \
1505                 "($help)--format=[Format the output using the given go template]:template: " \
1506                 "($help)--no-resolve[Do not map IDs to Names]" \
1507                 "($help)--no-trunc[Do not truncate output]" \
1508                 "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" \
1509                 "($help -)*:node:__docker_complete_nodes" && ret=0
1510             ;;
1511         (update)
1512             _arguments $(__docker_arguments) \
1513                 $opts_help \
1514                 "($help)--availability=[Availability of the node]:availability:(active pause drain)" \
1515                 "($help)*--label-add=[Add or update a node label]:key=value: " \
1516                 "($help)*--label-rm=[Remove a node label if exists]:label: " \
1517                 "($help)--role=[Role of the node]:role:(manager worker)" \
1518                 "($help -)1:node:__docker_complete_nodes" && ret=0
1519             ;;
1520         (help)
1521             _arguments $(__docker_arguments) ":subcommand:__docker_node_commands" && ret=0
1522             ;;
1523     esac
1524
1525     return ret
1526 }
1527
1528 # EO node
1529
1530 # BO plugin
1531
1532 __docker_plugin_complete_ls_filters() {
1533     [[ $PREFIX = -* ]] && return 1
1534     integer ret=1
1535
1536     if compset -P '*='; then
1537         case "${${words[-1]%=*}#*=}" in
1538             (capability)
1539                 opts=('authz' 'ipamdriver' 'logdriver' 'metricscollector' 'networkdriver' 'volumedriver')
1540                 _describe -t capability-opts "capability options" opts && ret=0
1541                 ;;
1542             (enabled)
1543                 opts=('false' 'true')
1544                 _describe -t enabled-opts "enabled options" opts && ret=0
1545                 ;;
1546             *)
1547                 _message 'value' && ret=0
1548                 ;;
1549         esac
1550     else
1551         opts=('capability' 'enabled')
1552         _describe -t filter-opts "filter options" opts -qS "=" && ret=0
1553     fi
1554
1555     return ret
1556 }
1557
1558 __docker_plugins() {
1559     [[ $PREFIX = -* ]] && return 1
1560     integer ret=1
1561     local line s
1562     declare -a lines plugins args
1563
1564     filter=$1; shift
1565     [[ $filter != "none" ]] && args=("-f $filter")
1566
1567     lines=(${(f)${:-"$(_call_program commands docker $docker_options plugin ls $args)"$'\n'}})
1568
1569     # Parse header line to find columns
1570     local i=1 j=1 k header=${lines[1]}
1571     declare -A begin end
1572     while (( j < ${#header} - 1 )); do
1573         i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
1574         j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
1575         k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
1576         begin[${header[$i,$((j-1))]}]=$i
1577         end[${header[$i,$((j-1))]}]=$k
1578     done
1579     end[${header[$i,$((j-1))]}]=-1
1580     lines=(${lines[2,-1]})
1581
1582     # Name
1583     for line in $lines; do
1584         s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
1585         s="$s:${(l:7:: :::)${${line[${begin[TAG]},${end[TAG]}]}%% ##}}"
1586         plugins=($plugins $s)
1587     done
1588
1589     _describe -t plugins-list "plugins" plugins "$@" && ret=0
1590     return ret
1591 }
1592
1593 __docker_complete_plugins() {
1594     [[ $PREFIX = -* ]] && return 1
1595     __docker_plugins none "$@"
1596 }
1597
1598 __docker_complete_enabled_plugins() {
1599     [[ $PREFIX = -* ]] && return 1
1600     __docker_plugins enabled=true "$@"
1601 }
1602
1603 __docker_complete_disabled_plugins() {
1604     [[ $PREFIX = -* ]] && return 1
1605     __docker_plugins enabled=false "$@"
1606 }
1607
1608 __docker_plugin_commands() {
1609     local -a _docker_plugin_subcommands
1610     _docker_plugin_subcommands=(
1611         "disable:Disable a plugin"
1612         "enable:Enable a plugin"
1613         "inspect:Return low-level information about a plugin"
1614         "install:Install a plugin"
1615         "ls:List plugins"
1616         "push:Push a plugin"
1617         "rm:Remove a plugin"
1618         "set:Change settings for a plugin"
1619         "upgrade:Upgrade an existing plugin"
1620     )
1621     _describe -t docker-plugin-commands "docker plugin command" _docker_plugin_subcommands
1622 }
1623
1624 __docker_plugin_subcommand() {
1625     local -a _command_args opts_help
1626     local expl help="--help"
1627     integer ret=1
1628
1629     opts_help=("(: -)--help[Print usage]")
1630
1631     case "$words[1]" in
1632         (disable)
1633             _arguments $(__docker_arguments) \
1634                 $opts_help \
1635                 "($help -f --force)"{-f,--force}"[Force the disable of an active plugin]" \
1636                 "($help -)1:plugin:__docker_complete_enabled_plugins" && ret=0
1637             ;;
1638         (enable)
1639             _arguments $(__docker_arguments) \
1640                 $opts_help \
1641                 "($help)--timeout=[HTTP client timeout (in seconds)]:timeout: " \
1642                 "($help -)1:plugin:__docker_complete_disabled_plugins" && ret=0
1643             ;;
1644         (inspect)
1645             _arguments $(__docker_arguments) \
1646                 $opts_help \
1647                 "($help -f --format)"{-f=,--format=}"[Format the output using the given Go template]:template: " \
1648                 "($help -)*:plugin:__docker_complete_plugins" && ret=0
1649             ;;
1650         (install)
1651             _arguments $(__docker_arguments) \
1652                 $opts_help \
1653                 "($help)--alias=[Local name for plugin]:alias: " \
1654                 "($help)--disable[Do not enable the plugin on install]" \
1655                 "($help)--disable-content-trust[Skip image verification (default true)]" \
1656                 "($help)--grant-all-permissions[Grant all permissions necessary to run the plugin]" \
1657                 "($help -)1:plugin:__docker_complete_plugins" \
1658                 "($help -)*:key=value: " && ret=0
1659             ;;
1660         (ls|list)
1661             _arguments $(__docker_arguments) \
1662                 $opts_help \
1663                 "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_plugin_complete_ls_filters" \
1664                 "($help --format)--format=[Format the output using the given Go template]:template: " \
1665                 "($help)--no-trunc[Don't truncate output]" \
1666                 "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0
1667             ;;
1668         (push)
1669             _arguments $(__docker_arguments) \
1670                 $opts_help \
1671                 "($help)--disable-content-trust[Skip image verification (default true)]" \
1672                 "($help -)1:plugin:__docker_complete_plugins" && ret=0
1673             ;;
1674         (rm|remove)
1675             _arguments $(__docker_arguments) \
1676                 $opts_help \
1677                 "($help -f --force)"{-f,--force}"[Force the removal of an active plugin]" \
1678                 "($help -)*:plugin:__docker_complete_plugins" && ret=0
1679             ;;
1680         (set)
1681             _arguments $(__docker_arguments) \
1682                 $opts_help \
1683                 "($help -)1:plugin:__docker_complete_plugins" \
1684                 "($help -)*:key=value: " && ret=0
1685             ;;
1686         (upgrade)
1687             _arguments $(__docker_arguments) \
1688                 $opts_help \
1689                 "($help)--disable-content-trust[Skip image verification (default true)]" \
1690                 "($help)--grant-all-permissions[Grant all permissions necessary to run the plugin]" \
1691                 "($help)--skip-remote-check[Do not check if specified remote plugin matches existing plugin image]" \
1692                 "($help -)1:plugin:__docker_complete_plugins" \
1693                 "($help -):remote: " && ret=0
1694             ;;
1695         (help)
1696             _arguments $(__docker_arguments) ":subcommand:__docker_plugin_commands" && ret=0
1697             ;;
1698     esac
1699
1700     return ret
1701 }
1702
1703 # EO plugin
1704
1705 # BO secret
1706
1707 __docker_secrets() {
1708     [[ $PREFIX = -* ]] && return 1
1709     integer ret=1
1710     local line s
1711     declare -a lines secrets
1712
1713     type=$1; shift
1714
1715     lines=(${(f)${:-"$(_call_program commands docker $docker_options secret ls)"$'\n'}})
1716
1717     # Parse header line to find columns
1718     local i=1 j=1 k header=${lines[1]}
1719     declare -A begin end
1720     while (( j < ${#header} - 1 )); do
1721         i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
1722         j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
1723         k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
1724         begin[${header[$i,$((j-1))]}]=$i
1725         end[${header[$i,$((j-1))]}]=$k
1726     done
1727     end[${header[$i,$((j-1))]}]=-1
1728     lines=(${lines[2,-1]})
1729
1730     # ID
1731     if [[ $type = (ids|all) ]]; then
1732         for line in $lines; do
1733             s="${line[${begin[ID]},${end[ID]}]%% ##}"
1734             secrets=($secrets $s)
1735         done
1736     fi
1737
1738     # Names
1739     if [[ $type = (names|all) ]]; then
1740         for line in $lines; do
1741             s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
1742             secrets=($secrets $s)
1743         done
1744     fi
1745
1746     _describe -t secrets-list "secrets" secrets "$@" && ret=0
1747     return ret
1748 }
1749
1750 __docker_complete_secrets() {
1751     [[ $PREFIX = -* ]] && return 1
1752     __docker_secrets all "$@"
1753 }
1754
1755 __docker_secret_commands() {
1756     local -a _docker_secret_subcommands
1757     _docker_secret_subcommands=(
1758         "create:Create a secret using stdin as content"
1759         "inspect:Display detailed information on one or more secrets"
1760         "ls:List secrets"
1761         "rm:Remove one or more secrets"
1762     )
1763     _describe -t docker-secret-commands "docker secret command" _docker_secret_subcommands
1764 }
1765
1766 __docker_secret_subcommand() {
1767     local -a _command_args opts_help
1768     local expl help="--help"
1769     integer ret=1
1770
1771     opts_help=("(: -)--help[Print usage]")
1772
1773     case "$words[1]" in
1774         (create)
1775             _arguments $(__docker_arguments) -A '-*' \
1776                 $opts_help \
1777                 "($help)*"{-l=,--label=}"[Secret labels]:label: " \
1778                 "($help -):secret: " && ret=0
1779             ;;
1780         (inspect)
1781             _arguments $(__docker_arguments) \
1782                 $opts_help \
1783                 "($help -f --format)"{-f=,--format=}"[Format the output using the given Go template]:template: " \
1784                 "($help -)*:secret:__docker_complete_secrets" && ret=0
1785             ;;
1786         (ls|list)
1787             _arguments $(__docker_arguments) \
1788                 $opts_help \
1789                 "($help)--format=[Format the output using the given go template]:template: " \
1790                 "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0
1791             ;;
1792         (rm|remove)
1793             _arguments $(__docker_arguments) \
1794                 $opts_help \
1795                 "($help -)*:secret:__docker_complete_secrets" && ret=0
1796             ;;
1797         (help)
1798             _arguments $(__docker_arguments) ":subcommand:__docker_secret_commands" && ret=0
1799             ;;
1800     esac
1801
1802     return ret
1803 }
1804
1805 # EO secret
1806
1807 # BO service
1808
1809 __docker_service_complete_ls_filters() {
1810     [[ $PREFIX = -* ]] && return 1
1811     integer ret=1
1812
1813     if compset -P '*='; then
1814         case "${${words[-1]%=*}#*=}" in
1815             (id)
1816                 __docker_complete_services_ids && ret=0
1817                 ;;
1818             (mode)
1819                 opts=('global' 'replicated')
1820                 _describe -t mode-opts "mode options" opts && ret=0
1821                 ;;
1822             (name)
1823                 __docker_complete_services_names && ret=0
1824                 ;;
1825             *)
1826                 _message 'value' && ret=0
1827                 ;;
1828         esac
1829     else
1830         opts=('id' 'label' 'mode' 'name')
1831         _describe -t filter-opts "filter options" opts -qS "=" && ret=0
1832     fi
1833
1834     return ret
1835 }
1836
1837 __docker_service_complete_ps_filters() {
1838     [[ $PREFIX = -* ]] && return 1
1839     integer ret=1
1840
1841     if compset -P '*='; then
1842         case "${${words[-1]%=*}#*=}" in
1843             (desired-state)
1844                 state_opts=('accepted' 'running' 'shutdown')
1845                 _describe -t state-opts "desired state options" state_opts && ret=0
1846                 ;;
1847             *)
1848                 _message 'value' && ret=0
1849                 ;;
1850         esac
1851     else
1852         opts=('desired-state' 'id' 'label' 'name')
1853         _describe -t filter-opts "filter options" opts -qS "=" && ret=0
1854     fi
1855
1856     return ret
1857 }
1858
1859 __docker_service_complete_placement_pref() {
1860     [[ $PREFIX = -* ]] && return 1
1861     integer ret=1
1862
1863     if compset -P '*='; then
1864         case "${${words[-1]%=*}#*=}" in
1865             (spread)
1866                 opts=('engine.labels' 'node.labels')
1867                 _describe -t spread-opts "spread options" opts -qS "." && ret=0
1868                 ;;
1869             *)
1870                 _message 'value' && ret=0
1871                 ;;
1872         esac
1873     else
1874         opts=('spread')
1875         _describe -t pref-opts "placement pref options" opts -qS "=" && ret=0
1876     fi
1877
1878     return ret
1879 }
1880
1881 __docker_services() {
1882     [[ $PREFIX = -* ]] && return 1
1883     integer ret=1
1884     local line s
1885     declare -a lines services
1886
1887     type=$1; shift
1888
1889     lines=(${(f)${:-"$(_call_program commands docker $docker_options service ls)"$'\n'}})
1890
1891     # Parse header line to find columns
1892     local i=1 j=1 k header=${lines[1]}
1893     declare -A begin end
1894     while (( j < ${#header} - 1 )); do
1895         i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
1896         j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
1897         k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
1898         begin[${header[$i,$((j-1))]}]=$i
1899         end[${header[$i,$((j-1))]}]=$k
1900     done
1901     end[${header[$i,$((j-1))]}]=-1
1902     lines=(${lines[2,-1]})
1903
1904     # Service ID
1905     if [[ $type = (ids|all) ]]; then
1906         for line in $lines; do
1907             s="${line[${begin[ID]},${end[ID]}]%% ##}"
1908             s="$s:${(l:7:: :::)${${line[${begin[IMAGE]},${end[IMAGE]}]}%% ##}}"
1909             services=($services $s)
1910         done
1911     fi
1912
1913     # Names
1914     if [[ $type = (names|all) ]]; then
1915         for line in $lines; do
1916             s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
1917             s="$s:${(l:7:: :::)${${line[${begin[IMAGE]},${end[IMAGE]}]}%% ##}}"
1918             services=($services $s)
1919         done
1920     fi
1921
1922     _describe -t services-list "services" services "$@" && ret=0
1923     return ret
1924 }
1925
1926 __docker_complete_services() {
1927     [[ $PREFIX = -* ]] && return 1
1928     __docker_services all "$@"
1929 }
1930
1931 __docker_complete_services_ids() {
1932     [[ $PREFIX = -* ]] && return 1
1933     __docker_services ids "$@"
1934 }
1935
1936 __docker_complete_services_names() {
1937     [[ $PREFIX = -* ]] && return 1
1938     __docker_services names "$@"
1939 }
1940
1941 __docker_service_commands() {
1942     local -a _docker_service_subcommands
1943     _docker_service_subcommands=(
1944         "create:Create a new service"
1945         "inspect:Display detailed information on one or more services"
1946         "logs:Fetch the logs of a service or task"
1947         "ls:List services"
1948         "rm:Remove one or more services"
1949         "rollback:Revert changes to a service's configuration"
1950         "scale:Scale one or multiple replicated services"
1951         "ps:List the tasks of a service"
1952         "update:Update a service"
1953     )
1954     _describe -t docker-service-commands "docker service command" _docker_service_subcommands
1955 }
1956
1957 __docker_service_subcommand() {
1958     local -a _command_args opts_help opts_create_update
1959     local expl help="--help"
1960     integer ret=1
1961
1962     opts_help=("(: -)--help[Print usage]")
1963     opts_create_update=(
1964         "($help)*--cap-add=[Add Linux capabilities]:capability: "
1965         "($help)*--cap-drop=[Drop Linux capabilities]:capability: "
1966         "($help)*--constraint=[Placement constraints]:constraint: "
1967         "($help)--endpoint-mode=[Placement constraints]:mode:(dnsrr vip)"
1968         "($help)*"{-e=,--env=}"[Set environment variables]:env: "
1969         "($help)--health-cmd=[Command to run to check health]:command: "
1970         "($help)--health-interval=[Time between running the check]:time: "
1971         "($help)--health-retries=[Consecutive failures needed to report unhealthy]:retries:(1 2 3 4 5)"
1972         "($help)--health-timeout=[Maximum time to allow one check to run]:time: "
1973         "($help)--hostname=[Service container hostname]:hostname: " \
1974         "($help)--isolation=[Service container isolation mode]:isolation:(default process hyperv)" \
1975         "($help)*--label=[Service labels]:label: "
1976         "($help)--limit-cpu=[Limit CPUs]:value: "
1977         "($help)--limit-memory=[Limit Memory]:value: "
1978         "($help)--limit-pids[Limit maximum number of processes (default 0 = unlimited)]"
1979         "($help)--log-driver=[Logging driver for service]:logging driver:__docker_complete_log_drivers"
1980         "($help)*--log-opt=[Logging driver options]:log driver options:__docker_complete_log_options"
1981         "($help)*--mount=[Attach a filesystem mount to the service]:mount: "
1982         "($help)*--network=[Network attachments]:network: "
1983         "($help)--no-healthcheck[Disable any container-specified HEALTHCHECK]"
1984         "($help)--read-only[Mount the container's root filesystem as read only]"
1985         "($help)--replicas=[Number of tasks]:replicas: "
1986         "($help)--reserve-cpu=[Reserve CPUs]:value: "
1987         "($help)--reserve-memory=[Reserve Memory]:value: "
1988         "($help)--restart-condition=[Restart when condition is met]:mode:(any none on-failure)"
1989         "($help)--restart-delay=[Delay between restart attempts]:delay: "
1990         "($help)--restart-max-attempts=[Maximum number of restarts before giving up]:max-attempts: "
1991         "($help)--restart-window=[Window used to evaluate the restart policy]:duration: "
1992         "($help)--rollback-delay=[Delay between task rollbacks]:duration: "
1993         "($help)--rollback-failure-action=[Action on rollback failure]:action:(continue pause)"
1994         "($help)--rollback-max-failure-ratio=[Failure rate to tolerate during a rollback]:failure rate: "
1995         "($help)--rollback-monitor=[Duration after each task rollback to monitor for failure]:duration: "
1996         "($help)--rollback-parallelism=[Maximum number of tasks rolled back simultaneously]:number: "
1997         "($help)*--secret=[Specify secrets to expose to the service]:secret:__docker_complete_secrets"
1998         "($help)--stop-grace-period=[Time to wait before force killing a container]:grace period: "
1999         "($help)--stop-signal=[Signal to stop the container]:signal:_signals"
2000         "($help -t --tty)"{-t,--tty}"[Allocate a pseudo-TTY]"
2001         "($help)--update-delay=[Delay between updates]:delay: "
2002         "($help)--update-failure-action=[Action on update failure]:mode:(continue pause rollback)"
2003         "($help)--update-max-failure-ratio=[Failure rate to tolerate during an update]:fraction: "
2004         "($help)--update-monitor=[Duration after each task update to monitor for failure]:window: "
2005         "($help)--update-parallelism=[Maximum number of tasks updated simultaneously]:number: "
2006         "($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users"
2007         "($help)--with-registry-auth[Send registry authentication details to swarm agents]"
2008         "($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories"
2009     )
2010
2011     case "$words[1]" in
2012         (create)
2013             _arguments $(__docker_arguments) \
2014                 $opts_help \
2015                 $opts_create_update \
2016                 "($help)*--container-label=[Container labels]:label: " \
2017                 "($help)*--dns=[Set custom DNS servers]:DNS: " \
2018                 "($help)*--dns-option=[Set DNS options]:DNS option: " \
2019                 "($help)*--dns-search=[Set custom DNS search domains]:DNS search: " \
2020                 "($help)*--env-file=[Read environment variables from a file]:environment file:_files" \
2021                 "($help)*--group=[Set one or more supplementary user groups for the container]:group: _groups " \
2022                 "($help)--mode=[Service Mode]:mode:(global replicated)" \
2023                 "($help)--name=[Service name]:name: " \
2024                 "($help)*--placement-pref=[Add a placement preference]:pref:__docker_service_complete_placement_pref" \
2025                 "($help)*"{-p=,--publish=}"[Publish a port as a node port]:port: " \
2026                 "($help -): :__docker_complete_images" \
2027                 "($help -):command: _command_names -e" \
2028                 "($help -)*::arguments: _normal" && ret=0
2029             ;;
2030         (inspect)
2031             _arguments $(__docker_arguments) \
2032                 $opts_help \
2033                 "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
2034                 "($help)--pretty[Print the information in a human friendly format]" \
2035                 "($help -)*:service:__docker_complete_services" && ret=0
2036             ;;
2037         (logs)
2038             _arguments $(__docker_arguments) \
2039                 $opts_help \
2040                 "($help -f --follow)"{-f,--follow}"[Follow log output]" \
2041                 "($help)--no-resolve[Do not map IDs to Names]" \
2042                 "($help)--no-task-ids[Do not include task IDs]" \
2043                 "($help)--no-trunc[Do not truncate output]" \
2044                 "($help)--since=[Show logs since timestamp]:timestamp: " \
2045                 "($help -n --tail)"{-n=,--tail=}"[Number of lines to show from the end of the logs]:lines:(1 10 20 50 all)" \
2046                 "($help -t --timestamps)"{-t,--timestamps}"[Show timestamps]" \
2047                 "($help -)1:service:__docker_complete_services" && ret=0
2048             ;;
2049         (ls|list)
2050             _arguments $(__docker_arguments) \
2051                 $opts_help \
2052                 "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_service_complete_ls_filters" \
2053                 "($help)--format=[Pretty-print services using a Go template]:template: " \
2054                 "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0
2055             ;;
2056         (rm|remove)
2057             _arguments $(__docker_arguments) \
2058                 $opts_help \
2059                 "($help -)*:service:__docker_complete_services" && ret=0
2060             ;;
2061         (rollback)
2062             _arguments $(__docker_arguments) \
2063                 $opts_help \
2064                 "($help -d --detach)"{-d=false,--detach=false}"[Disable detached mode]" \
2065                 "($help -q --quiet)"{-q,--quiet}"[Suppress progress output]" \
2066                 "($help -)*:service:__docker_complete_services" && ret=0
2067             ;;
2068         (scale)
2069             _arguments $(__docker_arguments) \
2070                 $opts_help \
2071                 "($help -d --detach)"{-d=false,--detach=false}"[Disable detached mode]" \
2072                 "($help -)*:service:->values" && ret=0
2073             case $state in
2074                 (values)
2075                     if compset -P '*='; then
2076                         _message 'replicas' && ret=0
2077                     else
2078                         __docker_complete_services -qS "="
2079                     fi
2080                     ;;
2081             esac
2082             ;;
2083         (ps)
2084             _arguments $(__docker_arguments) \
2085                 $opts_help \
2086                 "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_service_complete_ps_filters" \
2087                 "($help)--format=[Format the output using the given go template]:template: " \
2088                 "($help)--no-resolve[Do not map IDs to Names]" \
2089                 "($help)--no-trunc[Do not truncate output]" \
2090                 "($help -q --quiet)"{-q,--quiet}"[Only display task IDs]" \
2091                 "($help -)*:service:__docker_complete_services" && ret=0
2092             ;;
2093         (update)
2094             _arguments $(__docker_arguments) \
2095                 $opts_help \
2096                 $opts_create_update \
2097                 "($help)--arg=[Service command args]:arguments: _normal" \
2098                 "($help)*--container-label-add=[Add or update container labels]:label: " \
2099                 "($help)*--container-label-rm=[Remove a container label by its key]:label: " \
2100                 "($help)*--dns-add=[Add or update custom DNS servers]:DNS: " \
2101                 "($help)*--dns-rm=[Remove custom DNS servers]:DNS: " \
2102                 "($help)*--dns-option-add=[Add or update DNS options]:DNS option: " \
2103                 "($help)*--dns-option-rm=[Remove DNS options]:DNS option: " \
2104                 "($help)*--dns-search-add=[Add or update custom DNS search domains]:DNS search: " \
2105                 "($help)*--dns-search-rm=[Remove DNS search domains]:DNS search: " \
2106                 "($help)--force[Force update]" \
2107                 "($help)*--group-add=[Add additional supplementary user groups to the container]:group:_groups" \
2108                 "($help)*--group-rm=[Remove previously added supplementary user groups from the container]:group:_groups" \
2109                 "($help)--image=[Service image tag]:image:__docker_complete_repositories" \
2110                 "($help)*--placement-pref-add=[Add a placement preference]:pref:__docker_service_complete_placement_pref" \
2111                 "($help)*--placement-pref-rm=[Remove a placement preference]:pref:__docker_service_complete_placement_pref" \
2112                 "($help)*--publish-add=[Add or update a port]:port: " \
2113                 "($help)*--publish-rm=[Remove a port(target-port mandatory)]:port: " \
2114                 "($help)--rollback[Rollback to previous specification]" \
2115                 "($help -)1:service:__docker_complete_services" && ret=0
2116             ;;
2117         (help)
2118             _arguments $(__docker_arguments) ":subcommand:__docker_service_commands" && ret=0
2119             ;;
2120     esac
2121
2122     return ret
2123 }
2124
2125 # EO service
2126
2127 # BO stack
2128
2129 __docker_stack_complete_ps_filters() {
2130     [[ $PREFIX = -* ]] && return 1
2131     integer ret=1
2132
2133     if compset -P '*='; then
2134         case "${${words[-1]%=*}#*=}" in
2135             (desired-state)
2136                 state_opts=('accepted' 'running' 'shutdown')
2137                 _describe -t state-opts "desired state options" state_opts && ret=0
2138                 ;;
2139             *)
2140                 _message 'value' && ret=0
2141                 ;;
2142         esac
2143     else
2144         opts=('desired-state' 'id' 'name')
2145         _describe -t filter-opts "filter options" opts -qS "=" && ret=0
2146     fi
2147
2148     return ret
2149 }
2150
2151 __docker_stack_complete_services_filters() {
2152     [[ $PREFIX = -* ]] && return 1
2153     integer ret=1
2154
2155     if compset -P '*='; then
2156         case "${${words[-1]%=*}#*=}" in
2157             *)
2158                 _message 'value' && ret=0
2159                 ;;
2160         esac
2161     else
2162         opts=('id' 'label' 'name')
2163         _describe -t filter-opts "filter options" opts -qS "=" && ret=0
2164     fi
2165
2166     return ret
2167 }
2168
2169 __docker_stacks() {
2170     [[ $PREFIX = -* ]] && return 1
2171     integer ret=1
2172     local line s
2173     declare -a lines stacks
2174
2175     lines=(${(f)${:-"$(_call_program commands docker $docker_options stack ls)"$'\n'}})
2176
2177     # Parse header line to find columns
2178     local i=1 j=1 k header=${lines[1]}
2179     declare -A begin end
2180     while (( j < ${#header} - 1 )); do
2181         i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
2182         j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
2183         k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
2184         begin[${header[$i,$((j-1))]}]=$i
2185         end[${header[$i,$((j-1))]}]=$k
2186     done
2187     end[${header[$i,$((j-1))]}]=-1
2188     lines=(${lines[2,-1]})
2189
2190     # Service NAME
2191     for line in $lines; do
2192         s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
2193         stacks=($stacks $s)
2194     done
2195
2196     _describe -t stacks-list "stacks" stacks "$@" && ret=0
2197     return ret
2198 }
2199
2200 __docker_complete_stacks() {
2201     [[ $PREFIX = -* ]] && return 1
2202     __docker_stacks "$@"
2203 }
2204
2205 __docker_stack_commands() {
2206     local -a _docker_stack_subcommands
2207     _docker_stack_subcommands=(
2208         "deploy:Deploy a new stack or update an existing stack"
2209         "ls:List stacks"
2210         "ps:List the tasks in the stack"
2211         "rm:Remove the stack"
2212         "services:List the services in the stack"
2213     )
2214     _describe -t docker-stack-commands "docker stack command" _docker_stack_subcommands
2215 }
2216
2217 __docker_stack_subcommand() {
2218     local -a _command_args opts_help
2219     local expl help="--help"
2220     integer ret=1
2221
2222     opts_help=("(: -)--help[Print usage]")
2223
2224     case "$words[1]" in
2225         (deploy|up)
2226             _arguments $(__docker_arguments) \
2227                 $opts_help \
2228                 "($help -c --compose-file)"{-c=,--compose-file=}"[Path to a Compose file, or '-' to read from stdin]:compose file:_files -g \"*.(yml|yaml)\"" \
2229                 "($help)--with-registry-auth[Send registry authentication details to Swarm agents]" \
2230                 "($help -):stack:__docker_complete_stacks" && ret=0
2231             ;;
2232         (ls|list)
2233             _arguments $(__docker_arguments) \
2234                 $opts_help && ret=0
2235             ;;
2236         (ps)
2237             _arguments $(__docker_arguments) \
2238                 $opts_help \
2239                 "($help -a --all)"{-a,--all}"[Display all tasks]" \
2240                 "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_stack_complete_ps_filters" \
2241                 "($help)--format=[Format the output using the given go template]:template: " \
2242                 "($help)--no-resolve[Do not map IDs to Names]" \
2243                 "($help)--no-trunc[Do not truncate output]" \
2244                 "($help -q --quiet)"{-q,--quiet}"[Only display task IDs]" \
2245                 "($help -):stack:__docker_complete_stacks" && ret=0
2246             ;;
2247         (rm|remove|down)
2248             _arguments $(__docker_arguments) \
2249                 $opts_help \
2250                 "($help -):stack:__docker_complete_stacks" && ret=0
2251             ;;
2252         (services)
2253             _arguments $(__docker_arguments) \
2254                 $opts_help \
2255                 "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_stack_complete_services_filters" \
2256                 "($help)--format=[Pretty-print services using a Go template]:template: " \
2257                 "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" \
2258                 "($help -):stack:__docker_complete_stacks" && ret=0
2259             ;;
2260         (help)
2261             _arguments $(__docker_arguments) ":subcommand:__docker_stack_commands" && ret=0
2262             ;;
2263     esac
2264
2265     return ret
2266 }
2267
2268 # EO stack
2269
2270 # BO swarm
2271
2272 __docker_swarm_commands() {
2273     local -a _docker_swarm_subcommands
2274     _docker_swarm_subcommands=(
2275         "init:Initialize a swarm"
2276         "join:Join a swarm as a node and/or manager"
2277         "join-token:Manage join tokens"
2278         "leave:Leave a swarm"
2279         "unlock:Unlock swarm"
2280         "unlock-key:Manage the unlock key"
2281         "update:Update the swarm"
2282     )
2283     _describe -t docker-swarm-commands "docker swarm command" _docker_swarm_subcommands
2284 }
2285
2286 __docker_swarm_subcommand() {
2287     local -a _command_args opts_help
2288     local expl help="--help"
2289     integer ret=1
2290
2291     opts_help=("(: -)--help[Print usage]")
2292
2293     case "$words[1]" in
2294         (init)
2295             _arguments $(__docker_arguments) \
2296                 $opts_help \
2297                 "($help)--advertise-addr=[Advertised address]:ip\:port: " \
2298                 "($help)--data-path-addr=[Data path IP or interface]:ip " \
2299                 "($help)--data-path-port=[Data Path Port]:port " \
2300                 "($help)--default-addr-pool=[Default address pool]" \
2301                 "($help)--default-addr-pool-mask-length=[Default address pool subnet mask length]" \
2302                 "($help)--autolock[Enable manager autolocking]" \
2303                 "($help)--availability=[Availability of the node]:availability:(active drain pause)" \
2304                 "($help)--cert-expiry=[Validity period for node certificates]:duration: " \
2305                 "($help)--dispatcher-heartbeat=[Dispatcher heartbeat period]:duration: " \
2306                 "($help)*--external-ca=[Specifications of one or more certificate signing endpoints]:endpoint: " \
2307                 "($help)--force-new-cluster[Force create a new cluster from current state]" \
2308                 "($help)--listen-addr=[Listen address]:ip\:port: " \
2309                 "($help)--max-snapshots[Number of additional Raft snapshots to retain]" \
2310                 "($help)--snapshot-interval[Number of log entries between Raft snapshots]" \
2311                 "($help)--task-history-limit=[Task history retention limit]:limit: " && ret=0
2312             ;;
2313         (join)
2314             _arguments $(__docker_arguments) -A '-*' \
2315                 $opts_help \
2316                 "($help)--advertise-addr=[Advertised address]:ip\:port: " \
2317                 "($help)--data-path-addr=[Data path IP or interface]:ip " \
2318                 "($help)--availability=[Availability of the node]:availability:(active drain pause)" \
2319                 "($help)--listen-addr=[Listen address]:ip\:port: " \
2320                 "($help)--token=[Token for entry into the swarm]:secret: " \
2321                 "($help -):host\:port: " && ret=0
2322             ;;
2323         (join-token)
2324             _arguments $(__docker_arguments) \
2325                 $opts_help \
2326                 "($help -q --quiet)"{-q,--quiet}"[Only display token]" \
2327                 "($help)--rotate[Rotate join token]" \
2328                 "($help -):role:(manager worker)" && ret=0
2329             ;;
2330         (leave)
2331             _arguments $(__docker_arguments) \
2332                 $opts_help \
2333                 "($help -f --force)"{-f,--force}"[Force this node to leave the swarm, ignoring warnings]" && ret=0
2334             ;;
2335         (unlock)
2336             _arguments $(__docker_arguments) \
2337                 $opts_help && ret=0
2338             ;;
2339         (unlock-key)
2340             _arguments $(__docker_arguments) \
2341                 $opts_help \
2342                 "($help -q --quiet)"{-q,--quiet}"[Only display token]" \
2343                 "($help)--rotate[Rotate unlock token]" && ret=0
2344             ;;
2345         (update)
2346             _arguments $(__docker_arguments) \
2347                 $opts_help \
2348                 "($help)--autolock[Enable manager autolocking]" \
2349                 "($help)--cert-expiry=[Validity period for node certificates]:duration: " \
2350                 "($help)--dispatcher-heartbeat=[Dispatcher heartbeat period]:duration: " \
2351                 "($help)*--external-ca=[Specifications of one or more certificate signing endpoints]:endpoint: " \
2352                 "($help)--max-snapshots[Number of additional Raft snapshots to retain]" \
2353                 "($help)--snapshot-interval[Number of log entries between Raft snapshots]" \
2354                 "($help)--task-history-limit=[Task history retention limit]:limit: " && ret=0
2355             ;;
2356         (help)
2357             _arguments $(__docker_arguments) ":subcommand:__docker_network_commands" && ret=0
2358             ;;
2359     esac
2360
2361     return ret
2362 }
2363
2364 # EO swarm
2365
2366 # BO system
2367
2368 __docker_system_commands() {
2369     local -a _docker_system_subcommands
2370     _docker_system_subcommands=(
2371         "df:Show docker filesystem usage"
2372         "events:Get real time events from the server"
2373         "info:Display system-wide information"
2374         "prune:Remove unused data"
2375     )
2376     _describe -t docker-system-commands "docker system command" _docker_system_subcommands
2377 }
2378
2379 __docker_system_subcommand() {
2380     local -a _command_args opts_help
2381     local expl help="--help"
2382     integer ret=1
2383
2384     opts_help=("(: -)--help[Print usage]")
2385
2386     case "$words[1]" in
2387         (df)
2388             _arguments $(__docker_arguments) \
2389                 $opts_help \
2390                 "($help -v --verbose)"{-v,--verbose}"[Show detailed information on space usage]" && ret=0
2391             ;;
2392         (events)
2393             _arguments $(__docker_arguments) \
2394                 $opts_help \
2395                 "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_events_filter" \
2396                 "($help)--since=[Events created since this timestamp]:timestamp: " \
2397                 "($help)--until=[Events created until this timestamp]:timestamp: " \
2398                 "($help)--format=[Format the output using the given go template]:template: " && ret=0
2399             ;;
2400         (info)
2401             _arguments $(__docker_arguments) \
2402                 $opts_help \
2403                 "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " && ret=0
2404             ;;
2405         (prune)
2406             _arguments $(__docker_arguments) \
2407                 $opts_help \
2408                 "($help -a --all)"{-a,--all}"[Remove all unused data, not just dangling ones]" \
2409                 "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
2410                 "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" \
2411                 "($help)--volumes=[Remove all unused volumes]" && ret=0
2412             ;;
2413         (help)
2414             _arguments $(__docker_arguments) ":subcommand:__docker_volume_commands" && ret=0
2415             ;;
2416     esac
2417
2418     return ret
2419 }
2420
2421 # EO system
2422
2423 # BO volume
2424
2425 __docker_volume_complete_ls_filters() {
2426     [[ $PREFIX = -* ]] && return 1
2427     integer ret=1
2428
2429     if compset -P '*='; then
2430         case "${${words[-1]%=*}#*=}" in
2431             (dangling)
2432                 dangling_opts=('true' 'false')
2433                 _describe -t dangling-filter-opts "Dangling Filter Options" dangling_opts && ret=0
2434                 ;;
2435             (driver)
2436                 __docker_complete_info_plugins Volume && ret=0
2437                 ;;
2438             (name)
2439                 __docker_complete_volumes && ret=0
2440                 ;;
2441             *)
2442                 _message 'value' && ret=0
2443                 ;;
2444         esac
2445     else
2446         opts=('dangling' 'driver' 'label' 'name')
2447         _describe -t filter-opts "Filter Options" opts -qS "=" && ret=0
2448     fi
2449
2450     return ret
2451 }
2452
2453 __docker_complete_volumes() {
2454     [[ $PREFIX = -* ]] && return 1
2455     integer ret=1
2456     declare -a lines volumes
2457
2458     lines=(${(f)${:-"$(_call_program commands docker $docker_options volume ls)"$'\n'}})
2459
2460     # Parse header line to find columns
2461     local i=1 j=1 k header=${lines[1]}
2462     declare -A begin end
2463     while (( j < ${#header} - 1 )); do
2464         i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
2465         j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
2466         k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
2467         begin[${header[$i,$((j-1))]}]=$i
2468         end[${header[$i,$((j-1))]}]=$k
2469     done
2470     end[${header[$i,$((j-1))]}]=-1
2471     lines=(${lines[2,-1]})
2472
2473     # Names
2474     local line s
2475     for line in $lines; do
2476         s="${line[${begin[VOLUME NAME]},${end[VOLUME NAME]}]%% ##}"
2477         s="$s:${(l:7:: :::)${${line[${begin[DRIVER]},${end[DRIVER]}]}%% ##}}"
2478         volumes=($volumes $s)
2479     done
2480
2481     _describe -t volumes-list "volumes" volumes && ret=0
2482     return ret
2483 }
2484
2485 __docker_volume_commands() {
2486     local -a _docker_volume_subcommands
2487     _docker_volume_subcommands=(
2488         "create:Create a volume"
2489         "inspect:Display detailed information on one or more volumes"
2490         "ls:List volumes"
2491         "prune:Remove all unused volumes"
2492         "rm:Remove one or more volumes"
2493     )
2494     _describe -t docker-volume-commands "docker volume command" _docker_volume_subcommands
2495 }
2496
2497 __docker_volume_subcommand() {
2498     local -a _command_args opts_help
2499     local expl help="--help"
2500     integer ret=1
2501
2502     opts_help=("(: -)--help[Print usage]")
2503
2504     case "$words[1]" in
2505         (create)
2506             _arguments $(__docker_arguments) -A '-*' \
2507                 $opts_help \
2508                 "($help -d --driver)"{-d=,--driver=}"[Volume driver name]:Driver name:(local)" \
2509                 "($help)*--label=[Set metadata for a volume]:label=value: " \
2510                 "($help)*"{-o=,--opt=}"[Driver specific options]:Driver option: " \
2511                 "($help -)1:Volume name: " && ret=0
2512             ;;
2513         (inspect)
2514             _arguments $(__docker_arguments) \
2515                 $opts_help \
2516                 "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
2517                 "($help -)1:volume:__docker_complete_volumes" && ret=0
2518             ;;
2519         (ls)
2520             _arguments $(__docker_arguments) \
2521                 $opts_help \
2522                 "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_volume_complete_ls_filters" \
2523                 "($help)--format=[Pretty-print volumes using a Go template]:template: " \
2524                 "($help -q --quiet)"{-q,--quiet}"[Only display volume names]" && ret=0
2525             ;;
2526         (prune)
2527             _arguments $(__docker_arguments) \
2528                 $opts_help \
2529                 "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
2530             ;;
2531         (rm)
2532             _arguments $(__docker_arguments) \
2533                 $opts_help \
2534                 "($help -f --force)"{-f,--force}"[Force the removal of one or more volumes]" \
2535                 "($help -):volume:__docker_complete_volumes" && ret=0
2536             ;;
2537         (help)
2538             _arguments $(__docker_arguments) ":subcommand:__docker_volume_commands" && ret=0
2539             ;;
2540     esac
2541
2542     return ret
2543 }
2544
2545 # EO volume
2546
2547 # BO context
2548
2549 __docker_complete_contexts() {
2550     [[ $PREFIX = -* ]] && return 1
2551     integer ret=1
2552     declare -a contexts
2553
2554     contexts=(${(f)${:-"$(_call_program commands docker $docker_options context ls -q)"$'\n'}})
2555
2556     _describe -t context-list "context" contexts && ret=0
2557     return ret
2558 }
2559
2560 __docker_context_commands() {
2561     local -a _docker_context_subcommands
2562     _docker_context_subcommands=(
2563         "create:Create new context"
2564         "inspect:Display detailed information on one or more contexts"
2565         "list:List available contexts"
2566         "rm:Remove one or more contexts"
2567         "show:Print the current context"
2568         "update:Update a context"
2569         "use:Set the default context"
2570     )
2571     _describe -t docker-context-commands "docker context command" _docker_context_subcommands
2572 }
2573
2574 __docker_context_subcommand() {
2575     local -a _command_args opts_help
2576     local expl help="--help"
2577     integer ret=1
2578
2579     opts_help=("(: -)--help[Print usage]")
2580
2581     case "$words[1]" in
2582         (create)
2583             _arguments $(__docker_arguments) \
2584                 $opts_help \
2585                 "($help)--default-stack-orchestrator=[Default orchestrator for stack operations to use with this context]:default-stack-orchestrator:(swarm kubernetes all)" \
2586                 "($help)--description=[Description of the context]:description:" \
2587                 "($help)--docker=[Set the docker endpoint]:docker:" \
2588                 "($help)--kubernetes=[Set the kubernetes endpoint]:kubernetes:" \
2589                 "($help)--from=[Create context from a named context]:from:__docker_complete_contexts" \
2590                 "($help -):name: " && ret=0
2591             ;;
2592         (use)
2593             _arguments $(__docker_arguments) \
2594                 $opts_help \
2595                 "($help -)1:context:__docker_complete_contexts" && ret=0
2596             ;;
2597         (inspect)
2598             _arguments $(__docker_arguments) \
2599                 $opts_help \
2600                 "($help -)1:context:__docker_complete_contexts" && ret=0
2601             ;;
2602         (rm)
2603             _arguments $(__docker_arguments) \
2604                 $opts_help \
2605                 "($help -)1:context:__docker_complete_contexts" && ret=0
2606             ;;
2607         (update)
2608             _arguments $(__docker_arguments) \
2609                 $opts_help \
2610                 "($help)--default-stack-orchestrator=[Default orchestrator for stack operations to use with this context]:default-stack-orchestrator:(swarm kubernetes all)" \
2611                 "($help)--description=[Description of the context]:description:" \
2612                 "($help)--docker=[Set the docker endpoint]:docker:" \
2613                 "($help)--kubernetes=[Set the kubernetes endpoint]:kubernetes:" \
2614                 "($help -):name:" && ret=0
2615             ;;
2616     esac
2617
2618     return ret
2619 }
2620
2621 # EO context
2622
2623 __docker_caching_policy() {
2624   oldp=( "$1"(Nmh+1) )     # 1 hour
2625   (( $#oldp ))
2626 }
2627
2628 __docker_commands() {
2629     local cache_policy
2630     integer force_invalidation=0
2631
2632     zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
2633     if [[ -z "$cache_policy" ]]; then
2634         zstyle ":completion:${curcontext}:" cache-policy __docker_caching_policy
2635     fi
2636
2637     if ( (( ! ${+_docker_hide_legacy_commands} )) || _cache_invalid docker_hide_legacy_commands ) \
2638        && ! _retrieve_cache docker_hide_legacy_commands;
2639     then
2640         _docker_hide_legacy_commands="${DOCKER_HIDE_LEGACY_COMMANDS}"
2641         _store_cache docker_hide_legacy_commands _docker_hide_legacy_commands
2642     fi
2643
2644     if [[ "${_docker_hide_legacy_commands}" != "${DOCKER_HIDE_LEGACY_COMMANDS}" ]]; then
2645         force_invalidation=1
2646         _docker_hide_legacy_commands="${DOCKER_HIDE_LEGACY_COMMANDS}"
2647         _store_cache docker_hide_legacy_commands _docker_hide_legacy_commands
2648     fi
2649
2650     if ( [[ ${+_docker_subcommands} -eq 0 ]] || _cache_invalid docker_subcommands ) \
2651         && ! _retrieve_cache docker_subcommands || [[ ${force_invalidation} -eq 1 ]];
2652     then
2653         local -a lines
2654         lines=(${(f)"$(_call_program commands docker 2>&1)"})
2655         _docker_subcommands=(${${${(M)${lines[$((${lines[(i)*Commands:]} + 1)),-1]}:# *}## #}/\*# ##/:})
2656         _docker_subcommands=($_docker_subcommands 'daemon:Enable daemon mode' 'help:Show help for a command')
2657         (( $#_docker_subcommands > 2 )) && _store_cache docker_subcommands _docker_subcommands
2658     fi
2659     _describe -t docker-commands "docker command" _docker_subcommands
2660 }
2661
2662 __docker_subcommand() {
2663     local -a _command_args opts_help
2664     local expl help="--help"
2665     integer ret=1
2666
2667     opts_help=("(: -)--help[Print usage]")
2668
2669     case "$words[1]" in
2670         (attach|commit|cp|create|diff|exec|export|kill|logs|pause|unpause|port|rename|restart|rm|run|start|stats|stop|top|update|wait)
2671             __docker_container_subcommand && ret=0
2672             ;;
2673         (build|history|import|load|pull|push|save|tag)
2674             __docker_image_subcommand && ret=0
2675             ;;
2676         (checkpoint)
2677             local curcontext="$curcontext" state
2678             _arguments $(__docker_arguments) \
2679                 $opts_help \
2680                 "($help -): :->command" \
2681                 "($help -)*:: :->option-or-argument" && ret=0
2682
2683             case $state in
2684                 (command)
2685                     __docker_checkpoint_commands && ret=0
2686                     ;;
2687                 (option-or-argument)
2688                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2689                     __docker_checkpoint_subcommand && ret=0
2690                     ;;
2691             esac
2692             ;;
2693         (container)
2694             local curcontext="$curcontext" state
2695             _arguments $(__docker_arguments) \
2696                 $opts_help \
2697                 "($help -): :->command" \
2698                 "($help -)*:: :->option-or-argument" && ret=0
2699
2700             case $state in
2701                 (command)
2702                     __docker_container_commands && ret=0
2703                     ;;
2704                 (option-or-argument)
2705                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2706                     __docker_container_subcommand && ret=0
2707                     ;;
2708             esac
2709             ;;
2710         (context)
2711             local curcontext="$curcontext" state
2712             _arguments $(__docker_arguments) \
2713                 $opts_help \
2714                 "($help -): :->command" \
2715                 "($help -)*:: :->option-or-argument" && ret=0
2716
2717             case $state in
2718                 (command)
2719                     __docker_context_commands && ret=0
2720                     ;;
2721                 (option-or-argument)
2722                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2723                     __docker_context_subcommand && ret=0
2724                     ;;
2725             esac
2726             ;;
2727         (daemon)
2728             _arguments $(__docker_arguments) \
2729                 $opts_help \
2730                 "($help)*--add-runtime=[Register an additional OCI compatible runtime]:runtime:__docker_complete_runtimes" \
2731                 "($help)*--allow-nondistributable-artifacts=[Push nondistributable artifacts to specified registries]:registry: " \
2732                 "($help)--api-cors-header=[CORS headers in the Engine API]:CORS headers: " \
2733                 "($help)*--authorization-plugin=[Authorization plugins to load]" \
2734                 "($help -b --bridge)"{-b=,--bridge=}"[Attach containers to a network bridge]:bridge:_net_interfaces" \
2735                 "($help)--bip=[Network bridge IP]:IP address: " \
2736                 "($help)--cgroup-parent=[Parent cgroup for all containers]:cgroup: " \
2737                 "($help)--cluster-advertise=[Address or interface name to advertise]:Instance to advertise (host\:port): " \
2738                 "($help)--cluster-store=[URL of the distributed storage backend]:Cluster Store:->cluster-store" \
2739                 "($help)*--cluster-store-opt=[Cluster store options]:Cluster options:->cluster-store-options" \
2740                 "($help)--config-file=[Path to daemon configuration file]:Config File:_files" \
2741                 "($help)--containerd=[Path to containerd socket]:socket:_files -g \"*.sock\"" \
2742                 "($help)--containerd-namespace=[Containerd namespace to use]:containerd namespace:" \
2743                 "($help)--containerd-plugins-namespace=[Containerd namespace to use for plugins]:containerd namespace:" \
2744                 "($help)--data-root=[Root directory of persisted Docker data]:path:_directories" \
2745                 "($help -D --debug)"{-D,--debug}"[Enable debug mode]" \
2746                 "($help)--default-gateway[Container default gateway IPv4 address]:IPv4 address: " \
2747                 "($help)--default-gateway-v6[Container default gateway IPv6 address]:IPv6 address: " \
2748                 "($help)--default-shm-size=[Default shm size for containers]:size:" \
2749                 "($help)*--default-ulimit=[Default ulimits for containers]:ulimit: " \
2750                 "($help)*--dns=[DNS server to use]:DNS: " \
2751                 "($help)*--dns-opt=[DNS options to use]:DNS option: " \
2752                 "($help)*--dns-search=[DNS search domains to use]:DNS search: " \
2753                 "($help)*--exec-opt=[Runtime execution options]:runtime execution options: " \
2754                 "($help)--exec-root=[Root directory for execution state files]:path:_directories" \
2755                 "($help)--experimental[Enable experimental features]" \
2756                 "($help)--fixed-cidr=[IPv4 subnet for fixed IPs]:IPv4 subnet: " \
2757                 "($help)--fixed-cidr-v6=[IPv6 subnet for fixed IPs]:IPv6 subnet: " \
2758                 "($help -G --group)"{-G=,--group=}"[Group for the unix socket]:group:_groups" \
2759                 "($help -H --host)"{-H=,--host=}"[tcp://host:port to bind/connect to]:host: " \
2760                 "($help)--icc[Enable inter-container communication]" \
2761                 "($help)--init[Run an init inside containers to forward signals and reap processes]" \
2762                 "($help)--init-path=[Path to the docker-init binary]:docker-init binary:_files" \
2763                 "($help)*--insecure-registry=[Enable insecure registry communication]:registry: " \
2764                 "($help)--ip=[Default IP when binding container ports]" \
2765                 "($help)--ip-forward[Enable net.ipv4.ip_forward]" \
2766                 "($help)--ip-masq[Enable IP masquerading]" \
2767                 "($help)--iptables[Enable addition of iptables rules]" \
2768                 "($help)--ipv6[Enable IPv6 networking]" \
2769                 "($help -l --log-level)"{-l=,--log-level=}"[Logging level]:level:(debug info warn error fatal)" \
2770                 "($help)*--label=[Key=value labels]:label: " \
2771                 "($help)--live-restore[Enable live restore of docker when containers are still running]" \
2772                 "($help)--log-driver=[Default driver for container logs]:logging driver:__docker_complete_log_drivers" \
2773                 "($help)*--log-opt=[Default log driver options for containers]:log driver options:__docker_complete_log_options" \
2774                 "($help)--max-concurrent-downloads[Set the max concurrent downloads for each pull]" \
2775                 "($help)--max-concurrent-uploads[Set the max concurrent uploads for each push]" \
2776                 "($help)--max-download-attempts[Set the max download attempts for each pull]" \
2777                 "($help)--mtu=[Network MTU]:mtu:(0 576 1420 1500 9000)" \
2778                 "($help)--oom-score-adjust=[Set the oom_score_adj for the daemon]:oom-score:(-500)" \
2779                 "($help -p --pidfile)"{-p=,--pidfile=}"[Path to use for daemon PID file]:PID file:_files" \
2780                 "($help)--raw-logs[Full timestamps without ANSI coloring]" \
2781                 "($help)*--registry-mirror=[Preferred Docker registry mirror]:registry mirror: " \
2782                 "($help)--seccomp-profile=[Path to seccomp profile]:path:_files -g \"*.json\"" \
2783                 "($help -s --storage-driver)"{-s=,--storage-driver=}"[Storage driver to use]:driver:(aufs btrfs devicemapper overlay overlay2 vfs zfs)" \
2784                 "($help)--selinux-enabled[Enable selinux support]" \
2785                 "($help)--shutdown-timeout=[Set the shutdown timeout value in seconds]:time: " \
2786                 "($help)*--storage-opt=[Storage driver options]:storage driver options: " \
2787                 "($help)--tls[Use TLS]" \
2788                 "($help)--tlscacert=[Trust certs signed only by this CA]:PEM file:_files -g \"*.(pem|crt)\"" \
2789                 "($help)--tlscert=[Path to TLS certificate file]:PEM file:_files -g \"*.(pem|crt)\"" \
2790                 "($help)--tlskey=[Path to TLS key file]:Key file:_files -g \"*.(pem|key)\"" \
2791                 "($help)--tlsverify[Use TLS and verify the remote]" \
2792                 "($help)--userns-remap=[User/Group setting for user namespaces]:user\:group:->users-groups" \
2793                 "($help)--userland-proxy[Use userland proxy for loopback traffic]" \
2794                 "($help)--userland-proxy-path=[Path to the userland proxy binary]:binary:_files" \
2795                 "($help)--validate[Validate daemon configuration and exit]" && ret=0
2796
2797             case $state in
2798                 (cluster-store)
2799                     if compset -P '*://'; then
2800                         _message 'host:port' && ret=0
2801                     else
2802                         store=('consul' 'etcd' 'zk')
2803                         _describe -t cluster-store "Cluster Store" store -qS "://" && ret=0
2804                     fi
2805                     ;;
2806                 (cluster-store-options)
2807                     if compset -P '*='; then
2808                         _files && ret=0
2809                     else
2810                         opts=('discovery.heartbeat' 'discovery.ttl' 'kv.cacertfile' 'kv.certfile' 'kv.keyfile' 'kv.path')
2811                         _describe -t cluster-store-opts "Cluster Store Options" opts -qS "=" && ret=0
2812                     fi
2813                     ;;
2814                 (users-groups)
2815                     if compset -P '*:'; then
2816                         _groups && ret=0
2817                     else
2818                         _describe -t userns-default "default Docker user management" '(default)' && ret=0
2819                         _users && ret=0
2820                     fi
2821                     ;;
2822             esac
2823             ;;
2824         (events|info)
2825             __docker_system_subcommand && ret=0
2826             ;;
2827         (image)
2828             local curcontext="$curcontext" state
2829             _arguments $(__docker_arguments) \
2830                 $opts_help \
2831                 "($help -): :->command" \
2832                 "($help -)*:: :->option-or-argument" && ret=0
2833
2834             case $state in
2835                 (command)
2836                     __docker_image_commands && ret=0
2837                     ;;
2838                 (option-or-argument)
2839                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2840                     __docker_image_subcommand && ret=0
2841                     ;;
2842             esac
2843             ;;
2844         (images)
2845             words[1]='ls'
2846             __docker_image_subcommand && ret=0
2847             ;;
2848         (inspect)
2849             local state
2850             _arguments $(__docker_arguments) \
2851                 $opts_help \
2852                 "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
2853                 "($help -s --size)"{-s,--size}"[Display total file sizes if the type is container]" \
2854                 "($help)--type=[Return JSON for specified type]:type:(container image network node plugin service volume)" \
2855                 "($help -)*: :->values" && ret=0
2856
2857             case $state in
2858                 (values)
2859                     if [[ ${words[(r)--type=container]} == --type=container ]]; then
2860                         __docker_complete_containers && ret=0
2861                     elif [[ ${words[(r)--type=image]} == --type=image ]]; then
2862                         __docker_complete_images && ret=0
2863                     elif [[ ${words[(r)--type=network]} == --type=network ]]; then
2864                         __docker_complete_networks && ret=0
2865                     elif [[ ${words[(r)--type=node]} == --type=node ]]; then
2866                         __docker_complete_nodes && ret=0
2867                     elif [[ ${words[(r)--type=plugin]} == --type=plugin ]]; then
2868                         __docker_complete_plugins && ret=0
2869                     elif [[ ${words[(r)--type=service]} == --type=secrets ]]; then
2870                         __docker_complete_secrets && ret=0
2871                     elif [[ ${words[(r)--type=service]} == --type=service ]]; then
2872                         __docker_complete_services && ret=0
2873                     elif [[ ${words[(r)--type=volume]} == --type=volume ]]; then
2874                         __docker_complete_volumes && ret=0
2875                     else
2876                         __docker_complete_containers
2877                         __docker_complete_images
2878                         __docker_complete_networks
2879                         __docker_complete_nodes
2880                         __docker_complete_plugins
2881                         __docker_complete_secrets
2882                         __docker_complete_services
2883                         __docker_complete_volumes && ret=0
2884                     fi
2885                     ;;
2886             esac
2887             ;;
2888         (login)
2889             _arguments $(__docker_arguments) -A '-*' \
2890                 $opts_help \
2891                 "($help -p --password)"{-p=,--password=}"[Password]:password: " \
2892                 "($help)--password-stdin[Read password from stdin]" \
2893                 "($help -u --username)"{-u=,--username=}"[Username]:username: " \
2894                 "($help -)1:server: " && ret=0
2895             ;;
2896         (logout)
2897             _arguments $(__docker_arguments) -A '-*' \
2898                 $opts_help \
2899                 "($help -)1:server: " && ret=0
2900             ;;
2901         (network)
2902             local curcontext="$curcontext" state
2903             _arguments $(__docker_arguments) \
2904                 $opts_help \
2905                 "($help -): :->command" \
2906                 "($help -)*:: :->option-or-argument" && ret=0
2907
2908             case $state in
2909                 (command)
2910                     __docker_network_commands && ret=0
2911                     ;;
2912                 (option-or-argument)
2913                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2914                     __docker_network_subcommand && ret=0
2915                     ;;
2916             esac
2917             ;;
2918         (node)
2919             local curcontext="$curcontext" state
2920             _arguments $(__docker_arguments) \
2921                 $opts_help \
2922                 "($help -): :->command" \
2923                 "($help -)*:: :->option-or-argument" && ret=0
2924
2925             case $state in
2926                 (command)
2927                     __docker_node_commands && ret=0
2928                     ;;
2929                 (option-or-argument)
2930                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2931                     __docker_node_subcommand && ret=0
2932                     ;;
2933             esac
2934             ;;
2935         (plugin)
2936             local curcontext="$curcontext" state
2937             _arguments $(__docker_arguments) \
2938                 $opts_help \
2939                 "($help -): :->command" \
2940                 "($help -)*:: :->option-or-argument" && ret=0
2941
2942             case $state in
2943                 (command)
2944                     __docker_plugin_commands && ret=0
2945                     ;;
2946                 (option-or-argument)
2947                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2948                     __docker_plugin_subcommand && ret=0
2949                     ;;
2950             esac
2951             ;;
2952         (ps)
2953             words[1]='ls'
2954             __docker_container_subcommand && ret=0
2955             ;;
2956         (rmi)
2957             words[1]='rm'
2958             __docker_image_subcommand && ret=0
2959             ;;
2960         (search)
2961             _arguments $(__docker_arguments) -A '-*' \
2962                 $opts_help \
2963                 "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_search_filters" \
2964                 "($help)--limit=[Maximum returned search results]:limit:(1 5 10 25 50)" \
2965                 "($help)--no-trunc[Do not truncate output]" \
2966                 "($help -):term: " && ret=0
2967             ;;
2968         (secret)
2969             local curcontext="$curcontext" state
2970             _arguments $(__docker_arguments) \
2971                 $opts_help \
2972                 "($help -): :->command" \
2973                 "($help -)*:: :->option-or-argument" && ret=0
2974
2975             case $state in
2976                 (command)
2977                     __docker_secret_commands && ret=0
2978                     ;;
2979                 (option-or-argument)
2980                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2981                     __docker_secret_subcommand && ret=0
2982                     ;;
2983             esac
2984             ;;
2985         (service)
2986             local curcontext="$curcontext" state
2987             _arguments $(__docker_arguments) \
2988                 $opts_help \
2989                 "($help -): :->command" \
2990                 "($help -)*:: :->option-or-argument" && ret=0
2991
2992             case $state in
2993                 (command)
2994                     __docker_service_commands && ret=0
2995                     ;;
2996                 (option-or-argument)
2997                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2998                     __docker_service_subcommand && ret=0
2999                     ;;
3000             esac
3001             ;;
3002         (stack)
3003             local curcontext="$curcontext" state
3004             _arguments $(__docker_arguments) \
3005                 $opts_help \
3006                 "($help -): :->command" \
3007                 "($help -)*:: :->option-or-argument" && ret=0
3008
3009             case $state in
3010                 (command)
3011                     __docker_stack_commands && ret=0
3012                     ;;
3013                 (option-or-argument)
3014                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
3015                     __docker_stack_subcommand && ret=0
3016                     ;;
3017             esac
3018             ;;
3019         (swarm)
3020             local curcontext="$curcontext" state
3021             _arguments $(__docker_arguments) \
3022                 $opts_help \
3023                 "($help -): :->command" \
3024                 "($help -)*:: :->option-or-argument" && ret=0
3025
3026             case $state in
3027                 (command)
3028                     __docker_swarm_commands && ret=0
3029                     ;;
3030                 (option-or-argument)
3031                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
3032                     __docker_swarm_subcommand && ret=0
3033                     ;;
3034             esac
3035             ;;
3036         (system)
3037             local curcontext="$curcontext" state
3038             _arguments $(__docker_arguments) \
3039                 $opts_help \
3040                 "($help -): :->command" \
3041                 "($help -)*:: :->option-or-argument" && ret=0
3042
3043             case $state in
3044                 (command)
3045                     __docker_system_commands && ret=0
3046                     ;;
3047                 (option-or-argument)
3048                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
3049                     __docker_system_subcommand && ret=0
3050                     ;;
3051             esac
3052             ;;
3053         (version)
3054             _arguments $(__docker_arguments) \
3055                 $opts_help \
3056                 "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " && ret=0
3057             ;;
3058         (volume)
3059             local curcontext="$curcontext" state
3060             _arguments $(__docker_arguments) \
3061                 $opts_help \
3062                 "($help -): :->command" \
3063                 "($help -)*:: :->option-or-argument" && ret=0
3064
3065             case $state in
3066                 (command)
3067                     __docker_volume_commands && ret=0
3068                     ;;
3069                 (option-or-argument)
3070                     curcontext=${curcontext%:*:*}:docker-${words[-1]}:
3071                     __docker_volume_subcommand && ret=0
3072                     ;;
3073             esac
3074             ;;
3075         (help)
3076             _arguments $(__docker_arguments) ":subcommand:__docker_commands" && ret=0
3077             ;;
3078     esac
3079
3080     return ret
3081 }
3082
3083 _docker() {
3084     # Support for subservices, which allows for `compdef _docker docker-shell=_docker_containers`.
3085     # Based on /usr/share/zsh/functions/Completion/Unix/_git without support for `ret`.
3086     if [[ $service != docker ]]; then
3087         _call_function - _$service
3088         return
3089     fi
3090
3091     local curcontext="$curcontext" state line help="-h --help"
3092     integer ret=1
3093     typeset -A opt_args
3094
3095     _arguments $(__docker_arguments) -C \
3096         "(: -)"{-h,--help}"[Print usage]" \
3097         "($help)--config[Location of client config files]:path:_directories" \
3098         "($help -D --debug)"{-D,--debug}"[Enable debug mode]" \
3099         "($help -H --host)"{-H=,--host=}"[tcp://host:port to bind/connect to]:host: " \
3100         "($help -l --log-level)"{-l=,--log-level=}"[Logging level]:level:(debug info warn error fatal)" \
3101         "($help)--tls[Use TLS]" \
3102         "($help)--tlscacert=[Trust certs signed only by this CA]:PEM file:_files -g "*.(pem|crt)"" \
3103         "($help)--tlscert=[Path to TLS certificate file]:PEM file:_files -g "*.(pem|crt)"" \
3104         "($help)--tlskey=[Path to TLS key file]:Key file:_files -g "*.(pem|key)"" \
3105         "($help)--tlsverify[Use TLS and verify the remote]" \
3106         "($help)--userland-proxy[Use userland proxy for loopback traffic]" \
3107         "($help -v --version)"{-v,--version}"[Print version information and quit]" \
3108         "($help -): :->command" \
3109         "($help -)*:: :->option-or-argument" && ret=0
3110
3111     local host=${opt_args[-H]}${opt_args[--host]}
3112     local config=${opt_args[--config]}
3113     local docker_options="${host:+--host $host} ${config:+--config $config}"
3114
3115     case $state in
3116         (command)
3117             __docker_commands && ret=0
3118             ;;
3119         (option-or-argument)
3120             curcontext=${curcontext%:*:*}:docker-$words[1]:
3121             __docker_subcommand && ret=0
3122             ;;
3123     esac
3124
3125     return ret
3126 }
3127
3128 _dockerd() {
3129     integer ret=1
3130     words[1]='daemon'
3131     __docker_subcommand && ret=0
3132     return ret
3133 }
3134
3135 _docker "$@"
3136
3137 # Local Variables:
3138 # mode: Shell-Script
3139 # sh-indentation: 4
3140 # indent-tabs-mode: nil
3141 # sh-basic-offset: 4
3142 # End:
3143 # vim: ft=zsh sw=4 ts=4 et