Parent directory

_docker

129545 bytes
   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:Execute 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:Create and run a new container from an image"
 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)*--annotation=[Add an annotation to the container (passed through to the OCI runtime)]:annotations: "
 606        "($help)*--blkio-weight-device=[Block IO (relative device weight)]:device:Block IO weight: "
 607        "($help)*--cap-add=[Add Linux capabilities]:capability: "
 608        "($help)*--cap-drop=[Drop Linux capabilities]:capability: "
 609        "($help)--cgroupns=[Cgroup namespace mode to use]:cgroup namespace mode: "
 610        "($help)--cgroup-parent=[Parent cgroup for the container]:cgroup: "
 611        "($help)--cidfile=[Write the container ID to the file]:CID file:_files"
 612        "($help)--cpus=[Number of CPUs (default 0.000)]:cpus: "
 613        "($help)*--device=[Add a host device to the container]:device:_files"
 614        "($help)*--device-cgroup-rule=[Add a rule to the cgroup allowed devices list]:device:cgroup: "
 615        "($help)*--device-read-bps=[Limit the read rate (bytes per second) from a device]:device:IO rate: "
 616        "($help)*--device-read-iops=[Limit the read rate (IO per second) from a device]:device:IO rate: "
 617        "($help)*--device-write-bps=[Limit the write rate (bytes per second) to a device]:device:IO rate: "
 618        "($help)*--device-write-iops=[Limit the write rate (IO per second) to a device]:device:IO rate: "
 619        "($help)--disable-content-trust[Skip image verification]"
 620        "($help)*--dns=[Custom DNS servers]:DNS server: "
 621        "($help)*--dns-option=[Custom DNS options]:DNS option: "
 622        "($help)*--dns-search=[Custom DNS search domains]:DNS domains: "
 623        "($help)*--domainname=[Container NIS domain name]:domainname:_hosts"
 624        "($help)*"{-e=,--env=}"[Environment variables]:environment variable: "
 625        "($help)--entrypoint=[Overwrite the default entrypoint of the image]:entry point: "
 626        "($help)*--env-file=[Read environment variables from a file]:environment file:_files"
 627        "($help)*--expose=[Expose a port from the container without publishing it]: "
 628        "($help)*--gpus=[GPU devices to add to the container ('all' to pass all GPUs)]:device: "
 629        "($help)*--group-add=[Set one or more supplementary user groups for the container]:group:_groups"
 630        "($help -h --hostname)"{-h=,--hostname=}"[Container host name]:hostname:_hosts"
 631        "($help -i --interactive)"{-i,--interactive}"[Keep stdin open even if not attached]"
 632        "($help)--init[Run an init inside the container that forwards signals and reaps processes]"
 633        "($help)--ip=[IPv4 address]:IPv4: "
 634        "($help)--ip6=[IPv6 address]:IPv6: "
 635        "($help)--ipc=[IPC namespace to use]:IPC namespace: "
 636        "($help)--isolation=[Container isolation technology]:isolation:(default hyperv process)"
 637        "($help)*--link=[Add link to another container]:link:->link"
 638        "($help)*--link-local-ip=[Container IPv4/IPv6 link-local addresses]:IPv4/IPv6: "
 639        "($help)*"{-l=,--label=}"[Container metadata]:label: "
 640        "($help)--log-driver=[Default driver for container logs]:logging driver:__docker_complete_log_drivers"
 641        "($help)*--log-opt=[Log driver specific options]:log driver options:__docker_complete_log_options"
 642        "($help)--mac-address=[Container MAC address]:MAC address: "
 643        "($help)*--mount=[Attach a filesystem mount to the container]:mount: "
 644        "($help)--name=[Container name]:name: "
 645        "($help)--network=[Connect a container to a network]:network mode:(bridge none container host)"
 646        "($help)*--network-alias=[Add network-scoped alias for the container]:alias: "
 647        "($help)--oom-kill-disable[Disable OOM Killer]"
 648        "($help)--oom-score-adj[Tune the host's OOM preferences for containers (accepts -1000 to 1000)]"
 649        "($help)--pids-limit[Tune container pids limit (set -1 for unlimited)]"
 650        "($help -P --publish-all)"{-P,--publish-all}"[Publish all exposed ports]"
 651        "($help)*"{-p=,--publish=}"[Expose a container's port to the host]:port:_ports"
 652        "($help)--pid=[PID namespace to use]:PID namespace:__docker_complete_pid"
 653        "($help)--privileged[Give extended privileges to this container]"
 654        "($help -q --quiet)"{-q,--quiet}"[Suppress the pull output]"
 655        "($help)--read-only[Mount the container's root filesystem as read only]"
 656        "($help)*--security-opt=[Security options]:security option: "
 657        "($help)*--shm-size=[Size of '/dev/shm' (format is '<number><unit>')]:shm size: "
 658        "($help)--stop-signal=[Signal to kill a container]:signal:_signals"
 659        "($help)--stop-timeout=[Timeout (in seconds) to stop a container]:time: "
 660        "($help)*--sysctl=-[sysctl options]:sysctl: "
 661        "($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]"
 662        "($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users"
 663        "($help)*--ulimit=[ulimit options]:ulimit: "
 664        "($help)--userns=[Container user namespace]:user namespace:(host)"
 665        "($help)--tmpfs[mount tmpfs]"
 666        "($help)*-v[Bind mount a volume]:volume:_directories -W / -P '/' -S '\:' -r '/ '"
 667        "($help)--volume-driver=[Optional volume driver for the container]:volume driver:(local)"
 668        "($help)*--volumes-from=[Mount volumes from the specified container]:volume: "
 669        "($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories"
 670    )
 671    opts_create_run_update=(
 672        "($help)--blkio-weight=[Block IO (relative weight), between 10 and 1000]:Block IO weight:(10 100 500 1000)"
 673        "($help -c --cpu-shares)"{-c=,--cpu-shares=}"[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)"
 674        "($help)--cpu-period=[Limit the CPU CFS (Completely Fair Scheduler) period]:CPU period: "
 675        "($help)--cpu-quota=[Limit the CPU CFS (Completely Fair Scheduler) quota]:CPU quota: "
 676        "($help)--cpu-rt-period=[Limit the CPU real-time period]:CPU real-time period in microseconds: "
 677        "($help)--cpu-rt-runtime=[Limit the CPU real-time runtime]:CPU real-time runtime in microseconds: "
 678        "($help)--cpuset-cpus=[CPUs in which to allow execution]:CPUs: "
 679        "($help)--cpuset-mems=[MEMs in which to allow execution]:MEMs: "
 680        "($help)--kernel-memory=[Kernel memory limit in bytes]:Memory limit: "
 681        "($help -m --memory)"{-m=,--memory=}"[Memory limit]:Memory limit: "
 682        "($help)--memory-reservation=[Memory soft limit]:Memory limit: "
 683        "($help)--memory-swap=[Total memory limit with swap]:Memory limit: "
 684        "($help)--pids-limit[Tune container pids limit (set -1 for unlimited)]"
 685        "($help)--restart=[Restart policy]:restart policy:(no on-failure always unless-stopped)"
 686    )
 687    opts_help=("(: -)--help[Print usage]")
 688
 689    case "$words[1]" in
 690        (attach)
 691            _arguments $(__docker_arguments) \
 692                $opts_help \
 693                $opts_attach_exec_run_start \
 694                "($help)--no-stdin[Do not attach stdin]" \
 695                "($help)--sig-proxy[Proxy all received signals to the process (non-TTY mode only)]" \
 696                "($help -):containers:__docker_complete_running_containers" && ret=0
 697            ;;
 698        (commit)
 699            _arguments $(__docker_arguments) \
 700                $opts_help \
 701                "($help -a --author)"{-a=,--author=}"[Author]:author: " \
 702                "($help)*"{-c=,--change=}"[Apply Dockerfile instruction to the created image]:Dockerfile:_files" \
 703                "($help -m --message)"{-m=,--message=}"[Commit message]:message: " \
 704                "($help -p --pause)"{-p,--pause}"[Pause container during commit]" \
 705                "($help -):container:__docker_complete_containers" \
 706                "($help -): :__docker_complete_repositories_with_tags" && ret=0
 707            ;;
 708        (cp)
 709            local state
 710            _arguments $(__docker_arguments) \
 711                $opts_help \
 712                "($help -L --follow-link)"{-L,--follow-link}"[Always follow symbol link]" \
 713                "($help -)1:container:->container" \
 714                "($help -)2:hostpath:_files" && ret=0
 715            case $state in
 716                (container)
 717                    if compset -P "*:"; then
 718                        _files && ret=0
 719                    else
 720                        __docker_complete_containers -qS ":" && ret=0
 721                    fi
 722                    ;;
 723            esac
 724            ;;
 725        (create)
 726            local state
 727            _arguments $(__docker_arguments) \
 728                $opts_help \
 729                $opts_create_run \
 730                $opts_create_run_update \
 731                "($help -): :__docker_complete_images" \
 732                "($help -):command: _command_names -e" \
 733                "($help -)*::arguments: _normal" && ret=0
 734            case $state in
 735                (link)
 736                    if compset -P "*:"; then
 737                        _wanted alias expl "Alias" compadd -E "" && ret=0
 738                    else
 739                        __docker_complete_running_containers -qS ":" && ret=0
 740                    fi
 741                    ;;
 742            esac
 743            ;;
 744        (diff)
 745            _arguments $(__docker_arguments) \
 746                $opts_help \
 747                "($help -)*:containers:__docker_complete_containers" && ret=0
 748            ;;
 749        (exec)
 750            local state
 751            _arguments $(__docker_arguments) \
 752                $opts_help \
 753                $opts_attach_exec_run_start \
 754                "($help -d --detach)"{-d,--detach}"[Detached mode: leave the container running in the background]" \
 755                "($help)*"{-e=,--env=}"[Set environment variables]:environment variable: " \
 756                "($help)*--env-file=[Read environment variables from a file]:environment file:_files" \
 757                "($help -i --interactive)"{-i,--interactive}"[Keep stdin open even if not attached]" \
 758                "($help)--privileged[Give extended Linux capabilities to the command]" \
 759                "($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]" \
 760                "($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users" \
 761                "($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories" \
 762                "($help -):containers:__docker_complete_running_containers" \
 763                "($help -)*::command:->anycommand" && ret=0
 764            case $state in
 765                (anycommand)
 766                    shift 1 words
 767                    (( CURRENT-- ))
 768                    _normal && ret=0
 769                    ;;
 770            esac
 771            ;;
 772        (export)
 773            _arguments $(__docker_arguments) \
 774                $opts_help \
 775                "($help -o --output)"{-o=,--output=}"[Write to a file, instead of stdout]:output file:_files" \
 776                "($help -)*:containers:__docker_complete_containers" && ret=0
 777            ;;
 778        (inspect)
 779            _arguments $(__docker_arguments) \
 780                $opts_help \
 781                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
 782                "($help -s --size)"{-s,--size}"[Display total file sizes]" \
 783                "($help -)*:containers:__docker_complete_containers" && ret=0
 784            ;;
 785        (kill)
 786            _arguments $(__docker_arguments) \
 787                $opts_help \
 788                "($help -s --signal)"{-s=,--signal=}"[Signal to send]:signal:_signals" \
 789                "($help -)*:containers:__docker_complete_running_containers" && ret=0
 790            ;;
 791        (logs)
 792            _arguments $(__docker_arguments) \
 793                $opts_help \
 794                "($help)--details[Show extra details provided to logs]" \
 795                "($help -f --follow)"{-f,--follow}"[Follow log output]" \
 796                "($help -s --since)"{-s=,--since=}"[Show logs since this timestamp]:timestamp: " \
 797                "($help -t --timestamps)"{-t,--timestamps}"[Show timestamps]" \
 798                "($help -n --tail)"{-n=,--tail=}"[Number of lines to show from the end of the logs]:lines:(1 10 20 50 all)" \
 799                "($help -)*:containers:__docker_complete_containers" && ret=0
 800            ;;
 801        (ls|list)
 802            _arguments $(__docker_arguments) \
 803                $opts_help \
 804                "($help -a --all)"{-a,--all}"[Show all containers]" \
 805                "($help)--before=[Show only container created before...]:containers:__docker_complete_containers" \
 806                "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_ps_filters" \
 807                "($help)--format=[Format the output using the given Go template]:template: " \
 808                "($help -l --latest)"{-l,--latest}"[Show only the latest created container]" \
 809                "($help -n --last)"{-n=,--last=}"[Show n last created containers (includes all states)]:n:(1 5 10 25 50)" \
 810                "($help)--no-trunc[Do not truncate output]" \
 811                "($help -q --quiet)"{-q,--quiet}"[Only show container IDs]" \
 812                "($help -s --size)"{-s,--size}"[Display total file sizes]" \
 813                "($help)--since=[Show only containers created since...]:containers:__docker_complete_containers" && ret=0
 814            ;;
 815        (pause|unpause)
 816            _arguments $(__docker_arguments) \
 817                $opts_help \
 818                "($help -)*:containers:__docker_complete_running_containers" && ret=0
 819            ;;
 820        (port)
 821            _arguments $(__docker_arguments) \
 822                $opts_help \
 823                "($help -)1:containers:__docker_complete_running_containers" \
 824                "($help -)2:port:_ports" && ret=0
 825            ;;
 826        (prune)
 827            _arguments $(__docker_arguments) \
 828                $opts_help \
 829                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
 830                "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
 831            ;;
 832        (rename)
 833            _arguments $(__docker_arguments) \
 834                $opts_help \
 835                "($help -):old name:__docker_complete_containers" \
 836                "($help -):new name: " && ret=0
 837            ;;
 838        (restart)
 839            _arguments $(__docker_arguments) \
 840                $opts_help \
 841                "($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)" \
 842                "($help -)*:containers:__docker_complete_containers" && ret=0
 843            ;;
 844        (rm)
 845            local state
 846            _arguments $(__docker_arguments) \
 847                $opts_help \
 848                "($help -f --force)"{-f,--force}"[Force removal]" \
 849                "($help -l --link)"{-l,--link}"[Remove the specified link and not the underlying container]" \
 850                "($help -v --volumes)"{-v,--volumes}"[Remove the volumes associated to the container]" \
 851                "($help -)*:containers:->values" && ret=0
 852            case $state in
 853                (values)
 854                    if [[ ${words[(r)-f]} == -f || ${words[(r)--force]} == --force ]]; then
 855                        __docker_complete_containers && ret=0
 856                    else
 857                        __docker_complete_stopped_containers && ret=0
 858                    fi
 859                    ;;
 860            esac
 861            ;;
 862        (run)
 863            local state
 864            _arguments $(__docker_arguments) \
 865                $opts_help \
 866                $opts_create_run \
 867                $opts_create_run_update \
 868                $opts_attach_exec_run_start \
 869                "($help -d --detach)"{-d,--detach}"[Detached mode: leave the container running in the background]" \
 870                "($help)--health-cmd=[Command to run to check health]:command: " \
 871                "($help)--health-interval=[Time between running the check]:time: " \
 872                "($help)--health-retries=[Consecutive failures needed to report unhealthy]:retries:(1 2 3 4 5)" \
 873                "($help)--health-timeout=[Maximum time to allow one check to run]:time: " \
 874                "($help)--no-healthcheck[Disable any container-specified HEALTHCHECK]" \
 875                "($help)--rm[Remove intermediate containers when it exits]" \
 876                "($help)--runtime=[Name of the runtime to be used for that container]:runtime:__docker_complete_runtimes" \
 877                "($help)--sig-proxy[Proxy all received signals to the process (non-TTY mode only)]" \
 878                "($help)--storage-opt=[Storage driver options for the container]:storage options:->storage-opt" \
 879                "($help -): :__docker_complete_images" \
 880                "($help -):command: _command_names -e" \
 881                "($help -)*::arguments: _normal" && ret=0
 882            case $state in
 883                (link)
 884                    if compset -P "*:"; then
 885                        _wanted alias expl "Alias" compadd -E "" && ret=0
 886                    else
 887                        __docker_complete_running_containers -qS ":" && ret=0
 888                    fi
 889                    ;;
 890                (storage-opt)
 891                    if compset -P "*="; then
 892                        _message "value" && ret=0
 893                    else
 894                        opts=('size')
 895                        _describe -t filter-opts "storage options" opts -qS "=" && ret=0
 896                    fi
 897                    ;;
 898            esac
 899            ;;
 900        (start)
 901            _arguments $(__docker_arguments) \
 902                $opts_help \
 903                $opts_attach_exec_run_start \
 904                "($help -a --attach)"{-a,--attach}"[Attach container's stdout/stderr and forward all signals]" \
 905                "($help -i --interactive)"{-i,--interactive}"[Attach container's stdin]" \
 906                "($help -)*:containers:__docker_complete_stopped_containers" && ret=0
 907            ;;
 908        (stats)
 909            _arguments $(__docker_arguments) \
 910                $opts_help \
 911                "($help -a --all)"{-a,--all}"[Show all containers (default shows just running)]" \
 912                "($help)--format=[Format the output using the given Go template]:template: " \
 913                "($help)--no-stream[Disable streaming stats and only pull the first result]" \
 914                "($help)--no-trunc[Do not truncate output]" \
 915                "($help -)*:containers:__docker_complete_running_containers" && ret=0
 916            ;;
 917        (stop)
 918            _arguments $(__docker_arguments) \
 919                $opts_help \
 920                "($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)" \
 921                "($help -)*:containers:__docker_complete_running_containers" && ret=0
 922            ;;
 923        (top)
 924            local state
 925            _arguments $(__docker_arguments) \
 926                $opts_help \
 927                "($help -)1:containers:__docker_complete_running_containers" \
 928                "($help -)*:: :->ps-arguments" && ret=0
 929            case $state in
 930                (ps-arguments)
 931                    _ps && ret=0
 932                    ;;
 933            esac
 934            ;;
 935        (update)
 936            local state
 937            _arguments $(__docker_arguments) \
 938                $opts_help \
 939                $opts_create_run_update \
 940                "($help -)*: :->values" && ret=0
 941            case $state in
 942                (values)
 943                    if [[ ${words[(r)--kernel-memory*]} = (--kernel-memory*) ]]; then
 944                        __docker_complete_stopped_containers && ret=0
 945                    else
 946                        __docker_complete_containers && ret=0
 947                    fi
 948                    ;;
 949            esac
 950            ;;
 951        (wait)
 952            _arguments $(__docker_arguments) \
 953                $opts_help \
 954                "($help -)*:containers:__docker_complete_running_containers" && ret=0
 955            ;;
 956        (help)
 957            _arguments $(__docker_arguments) ":subcommand:__docker_container_commands" && ret=0
 958            ;;
 959    esac
 960
 961    return ret
 962}
 963
 964# EO container
 965
 966# BO image
 967
 968__docker_image_commands() {
 969    local -a _docker_image_subcommands
 970    _docker_image_subcommands=(
 971        "build:Build an image from a Dockerfile"
 972        "history:Show the history of an image"
 973        "import:Import the contents from a tarball to create a filesystem image"
 974        "inspect:Display detailed information on one or more images"
 975        "load:Load an image from a tar archive or STDIN"
 976        "ls:List images"
 977        "prune:Remove unused images"
 978        "pull:Download an image from a registry"
 979        "push:Upload an image to a registry"
 980        "rm:Remove one or more images"
 981        "save:Save one or more images to a tar archive (streamed to STDOUT by default)"
 982        "tag:Tag an image into a repository"
 983    )
 984    _describe -t docker-image-commands "docker image command" _docker_image_subcommands
 985}
 986
 987__docker_image_subcommand() {
 988    local -a _command_args opts_help
 989    local expl help="--help"
 990    integer ret=1
 991
 992    opts_help=("(: -)--help[Print usage]")
 993
 994    case "$words[1]" in
 995        (build)
 996            _arguments $(__docker_arguments) \
 997                $opts_help \
 998                "($help)*--add-host=[Add a custom host-to-IP mapping]:host\:ip mapping: " \
 999                "($help)*--build-arg=[Build-time variables]:<varname>=<value>: " \
1000                "($help)*--cache-from=[Images to consider as cache sources]: :__docker_complete_repositories_with_tags" \
1001                "($help -c --cpu-shares)"{-c=,--cpu-shares=}"[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)" \
1002                "($help)--cgroup-parent=[Parent cgroup for the container]:cgroup: " \
1003                "($help)--compress[Compress the build context using gzip]" \
1004                "($help)--cpu-period=[Limit the CPU CFS (Completely Fair Scheduler) period]:CPU period: " \
1005                "($help)--cpu-quota=[Limit the CPU CFS (Completely Fair Scheduler) quota]:CPU quota: " \
1006                "($help)--cpu-rt-period=[Limit the CPU real-time period]:CPU real-time period in microseconds: " \
1007                "($help)--cpu-rt-runtime=[Limit the CPU real-time runtime]:CPU real-time runtime in microseconds: " \
1008                "($help)--cpuset-cpus=[CPUs in which to allow execution]:CPUs: " \
1009                "($help)--cpuset-mems=[MEMs in which to allow execution]:MEMs: " \
1010                "($help)--disable-content-trust[Skip image verification]" \
1011                "($help -f --file)"{-f=,--file=}"[Name of the Dockerfile]:Dockerfile:_files" \
1012                "($help)--force-rm[Always remove intermediate containers]" \
1013                "($help)--isolation=[Container isolation technology]:isolation:(default hyperv process)" \
1014                "($help)*--label=[Set metadata for an image]:label=value: " \
1015                "($help -m --memory)"{-m=,--memory=}"[Memory limit]:Memory limit: " \
1016                "($help)--memory-swap=[Total memory limit with swap]:Memory limit: " \
1017                "($help)--network=[Connect a container to a network]:network mode:(bridge none container host)" \
1018                "($help)--no-cache[Do not use cache when building the image]" \
1019                "($help)--pull[Attempt to pull a newer version of the image]" \
1020                "($help -q --quiet)"{-q,--quiet}"[Suppress verbose build output]" \
1021                "($help)--rm[Remove intermediate containers after a successful build]" \
1022                "($help)*--shm-size=[Size of '/dev/shm' (format is '<number><unit>')]:shm size: " \
1023                "($help)--squash[Squash newly built layers into a single new layer]" \
1024                "($help -t --tag)*"{-t=,--tag=}"[Repository, name and tag for the image]: :__docker_complete_repositories_with_tags" \
1025                "($help)--target=[Set the target build stage to build.]" \
1026                "($help)*--ulimit=[ulimit options]:ulimit: " \
1027                "($help)--userns=[Container user namespace]:user namespace:(host)" \
1028                "($help -):path or URL:_directories" && ret=0
1029            ;;
1030        (history)
1031            _arguments $(__docker_arguments) \
1032                $opts_help \
1033                "($help -H --human)"{-H,--human}"[Print sizes and dates in human readable format]" \
1034                "($help)--no-trunc[Do not truncate output]" \
1035                "($help -q --quiet)"{-q,--quiet}"[Only show image IDs]" \
1036                "($help -)*: :__docker_complete_images" && ret=0
1037            ;;
1038        (import)
1039            _arguments $(__docker_arguments) \
1040                $opts_help \
1041                "($help)*"{-c=,--change=}"[Apply Dockerfile instruction to the created image]:Dockerfile:_files" \
1042                "($help -m --message)"{-m=,--message=}"[Commit message for imported image]:message: " \
1043                "($help -):URL:(- http:// file://)" \
1044                "($help -): :__docker_complete_repositories_with_tags" && ret=0
1045            ;;
1046        (inspect)
1047            _arguments $(__docker_arguments) \
1048                $opts_help \
1049                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
1050                "($help -)*:images:__docker_complete_images" && ret=0
1051            ;;
1052        (load)
1053            _arguments $(__docker_arguments) \
1054                $opts_help \
1055                "($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))(-.)\"" \
1056                "($help -q --quiet)"{-q,--quiet}"[Suppress the load output]" && ret=0
1057            ;;
1058        (ls|list)
1059            local state
1060            _arguments $(__docker_arguments) \
1061                $opts_help \
1062                "($help -a --all)"{-a,--all}"[Show all images]" \
1063                "($help)--digests[Show digests]" \
1064                "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_images_filters" \
1065                "($help)--format=[Format the output using the given Go template]:template: " \
1066                "($help)--no-trunc[Do not truncate output]" \
1067                "($help -q --quiet)"{-q,--quiet}"[Only show image IDs]" \
1068                "($help -): :__docker_complete_repositories" && ret=0
1069            ;;
1070        (prune)
1071            _arguments $(__docker_arguments) \
1072                $opts_help \
1073                "($help -a --all)"{-a,--all}"[Remove all unused images, not just dangling ones]" \
1074                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
1075                "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
1076            ;;
1077        (pull)
1078            _arguments $(__docker_arguments) \
1079                $opts_help \
1080                "($help -a --all-tags)"{-a,--all-tags}"[Download all tagged images]" \
1081                "($help)--disable-content-trust[Skip image verification]" \
1082                "($help -):name:__docker_search" && ret=0
1083            ;;
1084        (push)
1085            _arguments $(__docker_arguments) \
1086                $opts_help \
1087                "($help -a --all-tags)"{-a,--all-tags}"[Push all tags of an image to the repository]" \
1088                "($help)--disable-content-trust[Skip image signing]" \
1089                "($help -): :__docker_complete_images" && ret=0
1090            ;;
1091        (rm)
1092            _arguments $(__docker_arguments) \
1093                $opts_help \
1094                "($help -f --force)"{-f,--force}"[Force removal]" \
1095                "($help)--no-prune[Do not delete untagged parents]" \
1096                "($help -)*: :__docker_complete_images" && ret=0
1097            ;;
1098        (save)
1099            _arguments $(__docker_arguments) \
1100                $opts_help \
1101                "($help -o --output)"{-o=,--output=}"[Write to file]:file:_files" \
1102                "($help -)*: :__docker_complete_images" && ret=0
1103            ;;
1104        (tag)
1105            _arguments $(__docker_arguments) \
1106                $opts_help \
1107                "($help -):source:__docker_complete_images"\
1108                "($help -):destination:__docker_complete_repositories_with_tags" && ret=0
1109            ;;
1110        (help)
1111            _arguments $(__docker_arguments) ":subcommand:__docker_container_commands" && ret=0
1112            ;;
1113    esac
1114
1115    return ret
1116}
1117
1118# EO image
1119
1120# BO network
1121
1122__docker_network_complete_ls_filters() {
1123    [[ $PREFIX = -* ]] && return 1
1124    integer ret=1
1125
1126    if compset -P '*='; then
1127        case "${${words[-1]%=*}#*=}" in
1128            (driver)
1129                __docker_complete_info_plugins Network && ret=0
1130                ;;
1131            (id)
1132                __docker_complete_networks_ids && ret=0
1133                ;;
1134            (name)
1135                __docker_complete_networks_names && ret=0
1136                ;;
1137            (scope)
1138                opts=('global' 'local' 'swarm')
1139                _describe -t scope-filter-opts "Scope filter options" opts && ret=0
1140                ;;
1141            (type)
1142                opts=('builtin' 'custom')
1143                _describe -t type-filter-opts "Type filter options" opts && ret=0
1144                ;;
1145            *)
1146                _message 'value' && ret=0
1147                ;;
1148        esac
1149    else
1150        opts=('driver' 'id' 'label' 'name' 'scope' 'type')
1151        _describe -t filter-opts "Filter Options" opts -qS "=" && ret=0
1152    fi
1153
1154    return ret
1155}
1156
1157__docker_get_networks() {
1158    [[ $PREFIX = -* ]] && return 1
1159    integer ret=1
1160    local line s
1161    declare -a lines networks
1162
1163    type=$1; shift
1164
1165    lines=(${(f)${:-"$(_call_program commands docker $docker_options network ls)"$'\n'}})
1166
1167    # Parse header line to find columns
1168    local i=1 j=1 k header=${lines[1]}
1169    declare -A begin end
1170    while (( j < ${#header} - 1 )); do
1171        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
1172        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
1173        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
1174        begin[${header[$i,$((j-1))]}]=$i
1175        end[${header[$i,$((j-1))]}]=$k
1176    done
1177    end[${header[$i,$((j-1))]}]=-1
1178    lines=(${lines[2,-1]})
1179
1180    # Network ID
1181    if [[ $type = (ids|all) ]]; then
1182        for line in $lines; do
1183            s="${line[${begin[NETWORK ID]},${end[NETWORK ID]}]%% ##}"
1184            s="$s:${(l:7:: :::)${${line[${begin[DRIVER]},${end[DRIVER]}]}%% ##}}"
1185            s="$s, ${${line[${begin[SCOPE]},${end[SCOPE]}]}%% ##}"
1186            networks=($networks $s)
1187        done
1188    fi
1189
1190    # Names
1191    if [[ $type = (names|all) ]]; then
1192        for line in $lines; do
1193            s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
1194            s="$s:${(l:7:: :::)${${line[${begin[DRIVER]},${end[DRIVER]}]}%% ##}}"
1195            s="$s, ${${line[${begin[SCOPE]},${end[SCOPE]}]}%% ##}"
1196            networks=($networks $s)
1197        done
1198    fi
1199
1200    _describe -t networks-list "networks" networks "$@" && ret=0
1201    return ret
1202}
1203
1204__docker_complete_networks() {
1205    [[ $PREFIX = -* ]] && return 1
1206    __docker_get_networks all "$@"
1207}
1208
1209__docker_complete_networks_ids() {
1210    [[ $PREFIX = -* ]] && return 1
1211    __docker_get_networks ids "$@"
1212}
1213
1214__docker_complete_networks_names() {
1215    [[ $PREFIX = -* ]] && return 1
1216    __docker_get_networks names "$@"
1217}
1218
1219__docker_network_commands() {
1220    local -a _docker_network_subcommands
1221    _docker_network_subcommands=(
1222        "connect:Connect a container to a network"
1223        "create:Creates a new network with a name specified by the user"
1224        "disconnect:Disconnects a container from a network"
1225        "inspect:Displays detailed information on a network"
1226        "ls:Lists all the networks created by the user"
1227        "prune:Remove all unused networks"
1228        "rm:Deletes one or more networks"
1229    )
1230    _describe -t docker-network-commands "docker network command" _docker_network_subcommands
1231}
1232
1233__docker_network_subcommand() {
1234    local -a _command_args opts_help
1235    local expl help="--help"
1236    integer ret=1
1237
1238    opts_help=("(: -)--help[Print usage]")
1239
1240    case "$words[1]" in
1241        (connect)
1242            _arguments $(__docker_arguments) \
1243                $opts_help \
1244                "($help)*--alias=[Add network-scoped alias for the container]:alias: " \
1245                "($help)--ip=[IPv4 address]:IPv4: " \
1246                "($help)--ip6=[IPv6 address]:IPv6: " \
1247                "($help)*--link=[Add a link to another container]:link:->link" \
1248                "($help)*--link-local-ip=[Add a link-local address for the container]:IPv4/IPv6: " \
1249                "($help -)1:network:__docker_complete_networks" \
1250                "($help -)2:containers:__docker_complete_containers" && ret=0
1251
1252            case $state in
1253                (link)
1254                    if compset -P "*:"; then
1255                        _wanted alias expl "Alias" compadd -E "" && ret=0
1256                    else
1257                        __docker_complete_running_containers -qS ":" && ret=0
1258                    fi
1259                    ;;
1260            esac
1261            ;;
1262        (create)
1263            _arguments $(__docker_arguments) -A '-*' \
1264                $opts_help \
1265                "($help)--attachable[Enable manual container attachment]" \
1266                "($help)*--aux-address[Auxiliary IPv4 or IPv6 addresses used by network driver]:key=IP: " \
1267                "($help -d --driver)"{-d=,--driver=}"[Driver to manage the Network]:driver:(null host bridge overlay)" \
1268                "($help)*--gateway=[IPv4 or IPv6 Gateway for the master subnet]:IP: " \
1269                "($help)--internal[Restricts external access to the network]" \
1270                "($help)*--ip-range=[Allocate container ip from a sub-range]:IP/mask: " \
1271                "($help)--ipam-driver=[IP Address Management Driver]:driver:(default)" \
1272                "($help)*--ipam-opt=[Custom IPAM plugin options]:opt=value: " \
1273                "($help)--ipv6[Enable IPv6 networking]" \
1274                "($help)*--label=[Set metadata on a network]:label=value: " \
1275                "($help)*"{-o=,--opt=}"[Driver specific options]:opt=value: " \
1276                "($help)*--subnet=[Subnet in CIDR format that represents a network segment]:IP/mask: " \
1277                "($help -)1:Network Name: " && ret=0
1278            ;;
1279        (disconnect)
1280            _arguments $(__docker_arguments) \
1281                $opts_help \
1282                "($help -)1:network:__docker_complete_networks" \
1283                "($help -)2:containers:__docker_complete_containers" && ret=0
1284            ;;
1285        (inspect)
1286            _arguments $(__docker_arguments) \
1287                $opts_help \
1288                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
1289                "($help)--verbose[Show detailed information]" \
1290                "($help -)*:network:__docker_complete_networks" && ret=0
1291            ;;
1292        (ls)
1293            _arguments $(__docker_arguments) \
1294                $opts_help \
1295                "($help)--no-trunc[Do not truncate the output]" \
1296                "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_network_complete_ls_filters" \
1297                "($help)--format=[Format the output using the given Go template]:template: " \
1298                "($help -q --quiet)"{-q,--quiet}"[Only display network IDs]" && ret=0
1299            ;;
1300        (prune)
1301            _arguments $(__docker_arguments) \
1302                $opts_help \
1303                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
1304                "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
1305            ;;
1306        (rm)
1307            _arguments $(__docker_arguments) \
1308                $opts_help \
1309                "($help -)*:network:__docker_complete_networks" && ret=0
1310            ;;
1311        (help)
1312            _arguments $(__docker_arguments) ":subcommand:__docker_network_commands" && ret=0
1313            ;;
1314    esac
1315
1316    return ret
1317}
1318
1319# EO network
1320
1321# BO node
1322
1323__docker_node_complete_ls_filters() {
1324    [[ $PREFIX = -* ]] && return 1
1325    integer ret=1
1326
1327    if compset -P '*='; then
1328        case "${${words[-1]%=*}#*=}" in
1329            (id)
1330                __docker_complete_nodes_ids && ret=0
1331                ;;
1332            (membership)
1333                membership_opts=('accepted' 'pending' 'rejected')
1334                _describe -t membership-opts "membership options" membership_opts && ret=0
1335                ;;
1336            (name)
1337                __docker_complete_nodes_names && ret=0
1338                ;;
1339            (role)
1340                role_opts=('manager' 'worker')
1341                _describe -t role-opts "role options" role_opts && ret=0
1342                ;;
1343            *)
1344                _message 'value' && ret=0
1345                ;;
1346        esac
1347    else
1348        opts=('id' 'label' 'membership' 'name' 'node.label' 'role')
1349        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
1350    fi
1351
1352    return ret
1353}
1354
1355__docker_node_complete_ps_filters() {
1356    [[ $PREFIX = -* ]] && return 1
1357    integer ret=1
1358
1359    if compset -P '*='; then
1360        case "${${words[-1]%=*}#*=}" in
1361            (desired-state)
1362                state_opts=('accepted' 'running' 'shutdown')
1363                _describe -t state-opts "desired state options" state_opts && ret=0
1364                ;;
1365            *)
1366                _message 'value' && ret=0
1367                ;;
1368        esac
1369    else
1370        opts=('desired-state' 'id' 'label' 'name')
1371        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
1372    fi
1373
1374    return ret
1375}
1376
1377__docker_nodes() {
1378    [[ $PREFIX = -* ]] && return 1
1379    integer ret=1
1380    local line s
1381    declare -a lines nodes args
1382
1383    type=$1; shift
1384    filter=$1; shift
1385    [[ $filter != "none" ]] && args=("-f $filter")
1386
1387    lines=(${(f)${:-"$(_call_program commands docker $docker_options node ls $args)"$'\n'}})
1388    # Parse header line to find columns
1389    local i=1 j=1 k header=${lines[1]}
1390    declare -A begin end
1391    while (( j < ${#header} - 1 )); do
1392        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
1393        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
1394        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
1395        begin[${header[$i,$((j-1))]}]=$i
1396        end[${header[$i,$((j-1))]}]=$k
1397    done
1398    end[${header[$i,$((j-1))]}]=-1
1399    lines=(${lines[2,-1]})
1400
1401    # Node ID
1402    if [[ $type = (ids|all) ]]; then
1403        for line in $lines; do
1404            s="${line[${begin[ID]},${end[ID]}]%% ##}"
1405            nodes=($nodes $s)
1406        done
1407    fi
1408
1409    # Names
1410    if [[ $type = (names|all) ]]; then
1411        for line in $lines; do
1412            s="${line[${begin[HOSTNAME]},${end[HOSTNAME]}]%% ##}"
1413            nodes=($nodes $s)
1414        done
1415    fi
1416
1417    _describe -t nodes-list "nodes" nodes "$@" && ret=0
1418    return ret
1419}
1420
1421__docker_complete_nodes() {
1422    [[ $PREFIX = -* ]] && return 1
1423    __docker_nodes all none "$@"
1424}
1425
1426__docker_complete_nodes_ids() {
1427    [[ $PREFIX = -* ]] && return 1
1428    __docker_nodes ids none "$@"
1429}
1430
1431__docker_complete_nodes_names() {
1432    [[ $PREFIX = -* ]] && return 1
1433    __docker_nodes names none "$@"
1434}
1435
1436__docker_complete_pending_nodes() {
1437    [[ $PREFIX = -* ]] && return 1
1438    __docker_nodes all "membership=pending" "$@"
1439}
1440
1441__docker_complete_manager_nodes() {
1442    [[ $PREFIX = -* ]] && return 1
1443    __docker_nodes all "role=manager" "$@"
1444}
1445
1446__docker_complete_worker_nodes() {
1447    [[ $PREFIX = -* ]] && return 1
1448    __docker_nodes all "role=worker" "$@"
1449}
1450
1451__docker_node_commands() {
1452    local -a _docker_node_subcommands
1453    _docker_node_subcommands=(
1454        "demote:Demote a node as manager in the swarm"
1455        "inspect:Display detailed information on one or more nodes"
1456        "ls:List nodes in the swarm"
1457        "promote:Promote a node as manager in the swarm"
1458        "rm:Remove one or more nodes from the swarm"
1459        "ps:List tasks running on one or more nodes, defaults to current node"
1460        "update:Update a node"
1461    )
1462    _describe -t docker-node-commands "docker node command" _docker_node_subcommands
1463}
1464
1465__docker_node_subcommand() {
1466    local -a _command_args opts_help
1467    local expl help="--help"
1468    integer ret=1
1469
1470    opts_help=("(: -)--help[Print usage]")
1471
1472    case "$words[1]" in
1473        (rm|remove)
1474             _arguments $(__docker_arguments) \
1475                $opts_help \
1476                "($help -f --force)"{-f,--force}"[Force remove a node from the swarm]" \
1477                "($help -)*:node:__docker_complete_pending_nodes" && ret=0
1478            ;;
1479        (demote)
1480             _arguments $(__docker_arguments) \
1481                $opts_help \
1482                "($help -)*:node:__docker_complete_manager_nodes" && ret=0
1483            ;;
1484        (inspect)
1485            _arguments $(__docker_arguments) \
1486                $opts_help \
1487                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
1488                "($help)--pretty[Print the information in a human friendly format]" \
1489                "($help -)*:node:__docker_complete_nodes" && ret=0
1490            ;;
1491        (ls|list)
1492            _arguments $(__docker_arguments) \
1493                $opts_help \
1494                "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_node_complete_ls_filters" \
1495                "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0
1496            ;;
1497        (promote)
1498             _arguments $(__docker_arguments) \
1499                $opts_help \
1500                "($help -)*:node:__docker_complete_worker_nodes" && ret=0
1501            ;;
1502        (ps)
1503            _arguments $(__docker_arguments) \
1504                $opts_help \
1505                "($help -a --all)"{-a,--all}"[Display all instances]" \
1506                "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_node_complete_ps_filters" \
1507                "($help)--format=[Format the output using the given go template]:template: " \
1508                "($help)--no-resolve[Do not map IDs to Names]" \
1509                "($help)--no-trunc[Do not truncate output]" \
1510                "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" \
1511                "($help -)*:node:__docker_complete_nodes" && ret=0
1512            ;;
1513        (update)
1514            _arguments $(__docker_arguments) \
1515                $opts_help \
1516                "($help)--availability=[Availability of the node]:availability:(active pause drain)" \
1517                "($help)*--label-add=[Add or update a node label]:key=value: " \
1518                "($help)*--label-rm=[Remove a node label if exists]:label: " \
1519                "($help)--role=[Role of the node]:role:(manager worker)" \
1520                "($help -)1:node:__docker_complete_nodes" && ret=0
1521            ;;
1522        (help)
1523            _arguments $(__docker_arguments) ":subcommand:__docker_node_commands" && ret=0
1524            ;;
1525    esac
1526
1527    return ret
1528}
1529
1530# EO node
1531
1532# BO plugin
1533
1534__docker_plugin_complete_ls_filters() {
1535    [[ $PREFIX = -* ]] && return 1
1536    integer ret=1
1537
1538    if compset -P '*='; then
1539        case "${${words[-1]%=*}#*=}" in
1540            (capability)
1541                opts=('authz' 'ipamdriver' 'logdriver' 'metricscollector' 'networkdriver' 'volumedriver')
1542                _describe -t capability-opts "capability options" opts && ret=0
1543                ;;
1544            (enabled)
1545                opts=('false' 'true')
1546                _describe -t enabled-opts "enabled options" opts && ret=0
1547                ;;
1548            *)
1549                _message 'value' && ret=0
1550                ;;
1551        esac
1552    else
1553        opts=('capability' 'enabled')
1554        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
1555    fi
1556
1557    return ret
1558}
1559
1560__docker_plugins() {
1561    [[ $PREFIX = -* ]] && return 1
1562    integer ret=1
1563    local line s
1564    declare -a lines plugins args
1565
1566    filter=$1; shift
1567    [[ $filter != "none" ]] && args=("-f $filter")
1568
1569    lines=(${(f)${:-"$(_call_program commands docker $docker_options plugin ls $args)"$'\n'}})
1570
1571    # Parse header line to find columns
1572    local i=1 j=1 k header=${lines[1]}
1573    declare -A begin end
1574    while (( j < ${#header} - 1 )); do
1575        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
1576        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
1577        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
1578        begin[${header[$i,$((j-1))]}]=$i
1579        end[${header[$i,$((j-1))]}]=$k
1580    done
1581    end[${header[$i,$((j-1))]}]=-1
1582    lines=(${lines[2,-1]})
1583
1584    # Name
1585    for line in $lines; do
1586        s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
1587        s="$s:${(l:7:: :::)${${line[${begin[TAG]},${end[TAG]}]}%% ##}}"
1588        plugins=($plugins $s)
1589    done
1590
1591    _describe -t plugins-list "plugins" plugins "$@" && ret=0
1592    return ret
1593}
1594
1595__docker_complete_plugins() {
1596    [[ $PREFIX = -* ]] && return 1
1597    __docker_plugins none "$@"
1598}
1599
1600__docker_complete_enabled_plugins() {
1601    [[ $PREFIX = -* ]] && return 1
1602    __docker_plugins enabled=true "$@"
1603}
1604
1605__docker_complete_disabled_plugins() {
1606    [[ $PREFIX = -* ]] && return 1
1607    __docker_plugins enabled=false "$@"
1608}
1609
1610__docker_plugin_commands() {
1611    local -a _docker_plugin_subcommands
1612    _docker_plugin_subcommands=(
1613        "disable:Disable a plugin"
1614        "enable:Enable a plugin"
1615        "inspect:Return low-level information about a plugin"
1616        "install:Install a plugin"
1617        "ls:List plugins"
1618        "push:Push a plugin"
1619        "rm:Remove a plugin"
1620        "set:Change settings for a plugin"
1621        "upgrade:Upgrade an existing plugin"
1622    )
1623    _describe -t docker-plugin-commands "docker plugin command" _docker_plugin_subcommands
1624}
1625
1626__docker_plugin_subcommand() {
1627    local -a _command_args opts_help
1628    local expl help="--help"
1629    integer ret=1
1630
1631    opts_help=("(: -)--help[Print usage]")
1632
1633    case "$words[1]" in
1634        (disable)
1635            _arguments $(__docker_arguments) \
1636                $opts_help \
1637                "($help -f --force)"{-f,--force}"[Force the disable of an active plugin]" \
1638                "($help -)1:plugin:__docker_complete_enabled_plugins" && ret=0
1639            ;;
1640        (enable)
1641            _arguments $(__docker_arguments) \
1642                $opts_help \
1643                "($help)--timeout=[HTTP client timeout (in seconds)]:timeout: " \
1644                "($help -)1:plugin:__docker_complete_disabled_plugins" && ret=0
1645            ;;
1646        (inspect)
1647            _arguments $(__docker_arguments) \
1648                $opts_help \
1649                "($help -f --format)"{-f=,--format=}"[Format the output using the given Go template]:template: " \
1650                "($help -)*:plugin:__docker_complete_plugins" && ret=0
1651            ;;
1652        (install)
1653            _arguments $(__docker_arguments) \
1654                $opts_help \
1655                "($help)--alias=[Local name for plugin]:alias: " \
1656                "($help)--disable[Do not enable the plugin on install]" \
1657                "($help)--disable-content-trust[Skip image verification (default true)]" \
1658                "($help)--grant-all-permissions[Grant all permissions necessary to run the plugin]" \
1659                "($help -)1:plugin:__docker_complete_plugins" \
1660                "($help -)*:key=value: " && ret=0
1661            ;;
1662        (ls|list)
1663            _arguments $(__docker_arguments) \
1664                $opts_help \
1665                "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_plugin_complete_ls_filters" \
1666                "($help --format)--format=[Format the output using the given Go template]:template: " \
1667                "($help)--no-trunc[Don't truncate output]" \
1668                "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0
1669            ;;
1670        (push)
1671            _arguments $(__docker_arguments) \
1672                $opts_help \
1673                "($help)--disable-content-trust[Skip image verification (default true)]" \
1674                "($help -)1:plugin:__docker_complete_plugins" && ret=0
1675            ;;
1676        (rm|remove)
1677            _arguments $(__docker_arguments) \
1678                $opts_help \
1679                "($help -f --force)"{-f,--force}"[Force the removal of an active plugin]" \
1680                "($help -)*:plugin:__docker_complete_plugins" && ret=0
1681            ;;
1682        (set)
1683            _arguments $(__docker_arguments) \
1684                $opts_help \
1685                "($help -)1:plugin:__docker_complete_plugins" \
1686                "($help -)*:key=value: " && ret=0
1687            ;;
1688        (upgrade)
1689            _arguments $(__docker_arguments) \
1690                $opts_help \
1691                "($help)--disable-content-trust[Skip image verification (default true)]" \
1692                "($help)--grant-all-permissions[Grant all permissions necessary to run the plugin]" \
1693                "($help)--skip-remote-check[Do not check if specified remote plugin matches existing plugin image]" \
1694                "($help -)1:plugin:__docker_complete_plugins" \
1695                "($help -):remote: " && ret=0
1696            ;;
1697        (help)
1698            _arguments $(__docker_arguments) ":subcommand:__docker_plugin_commands" && ret=0
1699            ;;
1700    esac
1701
1702    return ret
1703}
1704
1705# EO plugin
1706
1707# BO secret
1708
1709__docker_secrets() {
1710    [[ $PREFIX = -* ]] && return 1
1711    integer ret=1
1712    local line s
1713    declare -a lines secrets
1714
1715    type=$1; shift
1716
1717    lines=(${(f)${:-"$(_call_program commands docker $docker_options secret ls)"$'\n'}})
1718
1719    # Parse header line to find columns
1720    local i=1 j=1 k header=${lines[1]}
1721    declare -A begin end
1722    while (( j < ${#header} - 1 )); do
1723        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
1724        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
1725        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
1726        begin[${header[$i,$((j-1))]}]=$i
1727        end[${header[$i,$((j-1))]}]=$k
1728    done
1729    end[${header[$i,$((j-1))]}]=-1
1730    lines=(${lines[2,-1]})
1731
1732    # ID
1733    if [[ $type = (ids|all) ]]; then
1734        for line in $lines; do
1735            s="${line[${begin[ID]},${end[ID]}]%% ##}"
1736            secrets=($secrets $s)
1737        done
1738    fi
1739
1740    # Names
1741    if [[ $type = (names|all) ]]; then
1742        for line in $lines; do
1743            s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
1744            secrets=($secrets $s)
1745        done
1746    fi
1747
1748    _describe -t secrets-list "secrets" secrets "$@" && ret=0
1749    return ret
1750}
1751
1752__docker_complete_secrets() {
1753    [[ $PREFIX = -* ]] && return 1
1754    __docker_secrets all "$@"
1755}
1756
1757__docker_secret_commands() {
1758    local -a _docker_secret_subcommands
1759    _docker_secret_subcommands=(
1760        "create:Create a secret using stdin as content"
1761        "inspect:Display detailed information on one or more secrets"
1762        "ls:List secrets"
1763        "rm:Remove one or more secrets"
1764    )
1765    _describe -t docker-secret-commands "docker secret command" _docker_secret_subcommands
1766}
1767
1768__docker_secret_subcommand() {
1769    local -a _command_args opts_help
1770    local expl help="--help"
1771    integer ret=1
1772
1773    opts_help=("(: -)--help[Print usage]")
1774
1775    case "$words[1]" in
1776        (create)
1777            _arguments $(__docker_arguments) -A '-*' \
1778                $opts_help \
1779                "($help)*"{-l=,--label=}"[Secret labels]:label: " \
1780                "($help -):secret: " && ret=0
1781            ;;
1782        (inspect)
1783            _arguments $(__docker_arguments) \
1784                $opts_help \
1785                "($help -f --format)"{-f=,--format=}"[Format the output using the given Go template]:template: " \
1786                "($help -)*:secret:__docker_complete_secrets" && ret=0
1787            ;;
1788        (ls|list)
1789            _arguments $(__docker_arguments) \
1790                $opts_help \
1791                "($help)--format=[Format the output using the given go template]:template: " \
1792                "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0
1793            ;;
1794        (rm|remove)
1795            _arguments $(__docker_arguments) \
1796                $opts_help \
1797                "($help -)*:secret:__docker_complete_secrets" && ret=0
1798            ;;
1799        (help)
1800            _arguments $(__docker_arguments) ":subcommand:__docker_secret_commands" && ret=0
1801            ;;
1802    esac
1803
1804    return ret
1805}
1806
1807# EO secret
1808
1809# BO service
1810
1811__docker_service_complete_ls_filters() {
1812    [[ $PREFIX = -* ]] && return 1
1813    integer ret=1
1814
1815    if compset -P '*='; then
1816        case "${${words[-1]%=*}#*=}" in
1817            (id)
1818                __docker_complete_services_ids && ret=0
1819                ;;
1820            (mode)
1821                opts=('global' 'replicated')
1822                _describe -t mode-opts "mode options" opts && ret=0
1823                ;;
1824            (name)
1825                __docker_complete_services_names && ret=0
1826                ;;
1827            *)
1828                _message 'value' && ret=0
1829                ;;
1830        esac
1831    else
1832        opts=('id' 'label' 'mode' 'name')
1833        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
1834    fi
1835
1836    return ret
1837}
1838
1839__docker_service_complete_ps_filters() {
1840    [[ $PREFIX = -* ]] && return 1
1841    integer ret=1
1842
1843    if compset -P '*='; then
1844        case "${${words[-1]%=*}#*=}" in
1845            (desired-state)
1846                state_opts=('accepted' 'running' 'shutdown')
1847                _describe -t state-opts "desired state options" state_opts && ret=0
1848                ;;
1849            *)
1850                _message 'value' && ret=0
1851                ;;
1852        esac
1853    else
1854        opts=('desired-state' 'id' 'label' 'name')
1855        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
1856    fi
1857
1858    return ret
1859}
1860
1861__docker_service_complete_placement_pref() {
1862    [[ $PREFIX = -* ]] && return 1
1863    integer ret=1
1864
1865    if compset -P '*='; then
1866        case "${${words[-1]%=*}#*=}" in
1867            (spread)
1868                opts=('engine.labels' 'node.labels')
1869                _describe -t spread-opts "spread options" opts -qS "." && ret=0
1870                ;;
1871            *)
1872                _message 'value' && ret=0
1873                ;;
1874        esac
1875    else
1876        opts=('spread')
1877        _describe -t pref-opts "placement pref options" opts -qS "=" && ret=0
1878    fi
1879
1880    return ret
1881}
1882
1883__docker_services() {
1884    [[ $PREFIX = -* ]] && return 1
1885    integer ret=1
1886    local line s
1887    declare -a lines services
1888
1889    type=$1; shift
1890
1891    lines=(${(f)${:-"$(_call_program commands docker $docker_options service ls)"$'\n'}})
1892
1893    # Parse header line to find columns
1894    local i=1 j=1 k header=${lines[1]}
1895    declare -A begin end
1896    while (( j < ${#header} - 1 )); do
1897        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
1898        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
1899        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
1900        begin[${header[$i,$((j-1))]}]=$i
1901        end[${header[$i,$((j-1))]}]=$k
1902    done
1903    end[${header[$i,$((j-1))]}]=-1
1904    lines=(${lines[2,-1]})
1905
1906    # Service ID
1907    if [[ $type = (ids|all) ]]; then
1908        for line in $lines; do
1909            s="${line[${begin[ID]},${end[ID]}]%% ##}"
1910            s="$s:${(l:7:: :::)${${line[${begin[IMAGE]},${end[IMAGE]}]}%% ##}}"
1911            services=($services $s)
1912        done
1913    fi
1914
1915    # Names
1916    if [[ $type = (names|all) ]]; then
1917        for line in $lines; do
1918            s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
1919            s="$s:${(l:7:: :::)${${line[${begin[IMAGE]},${end[IMAGE]}]}%% ##}}"
1920            services=($services $s)
1921        done
1922    fi
1923
1924    _describe -t services-list "services" services "$@" && ret=0
1925    return ret
1926}
1927
1928__docker_complete_services() {
1929    [[ $PREFIX = -* ]] && return 1
1930    __docker_services all "$@"
1931}
1932
1933__docker_complete_services_ids() {
1934    [[ $PREFIX = -* ]] && return 1
1935    __docker_services ids "$@"
1936}
1937
1938__docker_complete_services_names() {
1939    [[ $PREFIX = -* ]] && return 1
1940    __docker_services names "$@"
1941}
1942
1943__docker_service_commands() {
1944    local -a _docker_service_subcommands
1945    _docker_service_subcommands=(
1946        "create:Create a new service"
1947        "inspect:Display detailed information on one or more services"
1948        "logs:Fetch the logs of a service or task"
1949        "ls:List services"
1950        "rm:Remove one or more services"
1951        "rollback:Revert changes to a service's configuration"
1952        "scale:Scale one or multiple replicated services"
1953        "ps:List the tasks of a service"
1954        "update:Update a service"
1955    )
1956    _describe -t docker-service-commands "docker service command" _docker_service_subcommands
1957}
1958
1959__docker_service_subcommand() {
1960    local -a _command_args opts_help opts_create_update
1961    local expl help="--help"
1962    integer ret=1
1963
1964    opts_help=("(: -)--help[Print usage]")
1965    opts_create_update=(
1966        "($help)*--cap-add=[Add Linux capabilities]:capability: "
1967        "($help)*--cap-drop=[Drop Linux capabilities]:capability: "
1968        "($help)*--constraint=[Placement constraints]:constraint: "
1969        "($help)--endpoint-mode=[Placement constraints]:mode:(dnsrr vip)"
1970        "($help)*"{-e=,--env=}"[Set environment variables]:env: "
1971        "($help)--health-cmd=[Command to run to check health]:command: "
1972        "($help)--health-interval=[Time between running the check]:time: "
1973        "($help)--health-retries=[Consecutive failures needed to report unhealthy]:retries:(1 2 3 4 5)"
1974        "($help)--health-timeout=[Maximum time to allow one check to run]:time: "
1975        "($help)--hostname=[Service container hostname]:hostname: " \
1976        "($help)--isolation=[Service container isolation mode]:isolation:(default process hyperv)" \
1977        "($help)*--label=[Service labels]:label: "
1978        "($help)--limit-cpu=[Limit CPUs]:value: "
1979        "($help)--limit-memory=[Limit Memory]:value: "
1980        "($help)--limit-pids[Limit maximum number of processes (default 0 = unlimited)]"
1981        "($help)--log-driver=[Logging driver for service]:logging driver:__docker_complete_log_drivers"
1982        "($help)*--log-opt=[Logging driver options]:log driver options:__docker_complete_log_options"
1983        "($help)*--mount=[Attach a filesystem mount to the service]:mount: "
1984        "($help)*--network=[Network attachments]:network: "
1985        "($help)--no-healthcheck[Disable any container-specified HEALTHCHECK]"
1986        "($help)--read-only[Mount the container's root filesystem as read only]"
1987        "($help)--replicas=[Number of tasks]:replicas: "
1988        "($help)--reserve-cpu=[Reserve CPUs]:value: "
1989        "($help)--reserve-memory=[Reserve Memory]:value: "
1990        "($help)--restart-condition=[Restart when condition is met]:mode:(any none on-failure)"
1991        "($help)--restart-delay=[Delay between restart attempts]:delay: "
1992        "($help)--restart-max-attempts=[Maximum number of restarts before giving up]:max-attempts: "
1993        "($help)--restart-window=[Window used to evaluate the restart policy]:duration: "
1994        "($help)--rollback-delay=[Delay between task rollbacks]:duration: "
1995        "($help)--rollback-failure-action=[Action on rollback failure]:action:(continue pause)"
1996        "($help)--rollback-max-failure-ratio=[Failure rate to tolerate during a rollback]:failure rate: "
1997        "($help)--rollback-monitor=[Duration after each task rollback to monitor for failure]:duration: "
1998        "($help)--rollback-parallelism=[Maximum number of tasks rolled back simultaneously]:number: "
1999        "($help)*--secret=[Specify secrets to expose to the service]:secret:__docker_complete_secrets"
2000        "($help)--stop-grace-period=[Time to wait before force killing a container]:grace period: "
2001        "($help)--stop-signal=[Signal to stop the container]:signal:_signals"
2002        "($help -t --tty)"{-t,--tty}"[Allocate a pseudo-TTY]"
2003        "($help)--update-delay=[Delay between updates]:delay: "
2004        "($help)--update-failure-action=[Action on update failure]:mode:(continue pause rollback)"
2005        "($help)--update-max-failure-ratio=[Failure rate to tolerate during an update]:fraction: "
2006        "($help)--update-monitor=[Duration after each task update to monitor for failure]:window: "
2007        "($help)--update-parallelism=[Maximum number of tasks updated simultaneously]:number: "
2008        "($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users"
2009        "($help)--with-registry-auth[Send registry authentication details to swarm agents]"
2010        "($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories"
2011    )
2012
2013    case "$words[1]" in
2014        (create)
2015            _arguments $(__docker_arguments) \
2016                $opts_help \
2017                $opts_create_update \
2018                "($help)*--container-label=[Container labels]:label: " \
2019                "($help)*--dns=[Set custom DNS servers]:DNS: " \
2020                "($help)*--dns-option=[Set DNS options]:DNS option: " \
2021                "($help)*--dns-search=[Set custom DNS search domains]:DNS search: " \
2022                "($help)*--env-file=[Read environment variables from a file]:environment file:_files" \
2023                "($help)*--group=[Set one or more supplementary user groups for the container]:group: _groups " \
2024                "($help)--mode=[Service Mode]:mode:(global replicated)" \
2025                "($help)--name=[Service name]:name: " \
2026                "($help)*--placement-pref=[Add a placement preference]:pref:__docker_service_complete_placement_pref" \
2027                "($help)*"{-p=,--publish=}"[Publish a port as a node port]:port: " \
2028                "($help -): :__docker_complete_images" \
2029                "($help -):command: _command_names -e" \
2030                "($help -)*::arguments: _normal" && ret=0
2031            ;;
2032        (inspect)
2033            _arguments $(__docker_arguments) \
2034                $opts_help \
2035                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
2036                "($help)--pretty[Print the information in a human friendly format]" \
2037                "($help -)*:service:__docker_complete_services" && ret=0
2038            ;;
2039        (logs)
2040            _arguments $(__docker_arguments) \
2041                $opts_help \
2042                "($help -f --follow)"{-f,--follow}"[Follow log output]" \
2043                "($help)--no-resolve[Do not map IDs to Names]" \
2044                "($help)--no-task-ids[Do not include task IDs]" \
2045                "($help)--no-trunc[Do not truncate output]" \
2046                "($help)--since=[Show logs since timestamp]:timestamp: " \
2047                "($help -n --tail)"{-n=,--tail=}"[Number of lines to show from the end of the logs]:lines:(1 10 20 50 all)" \
2048                "($help -t --timestamps)"{-t,--timestamps}"[Show timestamps]" \
2049                "($help -)1:service:__docker_complete_services" && ret=0
2050            ;;
2051        (ls|list)
2052            _arguments $(__docker_arguments) \
2053                $opts_help \
2054                "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_service_complete_ls_filters" \
2055                "($help)--format=[Format the output using the given Go template]:template: " \
2056                "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0
2057            ;;
2058        (rm|remove)
2059            _arguments $(__docker_arguments) \
2060                $opts_help \
2061                "($help -)*:service:__docker_complete_services" && ret=0
2062            ;;
2063        (rollback)
2064            _arguments $(__docker_arguments) \
2065                $opts_help \
2066                "($help -d --detach)"{-d=false,--detach=false}"[Disable detached mode]" \
2067                "($help -q --quiet)"{-q,--quiet}"[Suppress progress output]" \
2068                "($help -)*:service:__docker_complete_services" && ret=0
2069            ;;
2070        (scale)
2071            _arguments $(__docker_arguments) \
2072                $opts_help \
2073                "($help -d --detach)"{-d=false,--detach=false}"[Disable detached mode]" \
2074                "($help -)*:service:->values" && ret=0
2075            case $state in
2076                (values)
2077                    if compset -P '*='; then
2078                        _message 'replicas' && ret=0
2079                    else
2080                        __docker_complete_services -qS "="
2081                    fi
2082                    ;;
2083            esac
2084            ;;
2085        (ps)
2086            _arguments $(__docker_arguments) \
2087                $opts_help \
2088                "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_service_complete_ps_filters" \
2089                "($help)--format=[Format the output using the given go template]:template: " \
2090                "($help)--no-resolve[Do not map IDs to Names]" \
2091                "($help)--no-trunc[Do not truncate output]" \
2092                "($help -q --quiet)"{-q,--quiet}"[Only display task IDs]" \
2093                "($help -)*:service:__docker_complete_services" && ret=0
2094            ;;
2095        (update)
2096            _arguments $(__docker_arguments) \
2097                $opts_help \
2098                $opts_create_update \
2099                "($help)--arg=[Service command args]:arguments: _normal" \
2100                "($help)*--container-label-add=[Add or update container labels]:label: " \
2101                "($help)*--container-label-rm=[Remove a container label by its key]:label: " \
2102                "($help)*--dns-add=[Add or update custom DNS servers]:DNS: " \
2103                "($help)*--dns-rm=[Remove custom DNS servers]:DNS: " \
2104                "($help)*--dns-option-add=[Add or update DNS options]:DNS option: " \
2105                "($help)*--dns-option-rm=[Remove DNS options]:DNS option: " \
2106                "($help)*--dns-search-add=[Add or update custom DNS search domains]:DNS search: " \
2107                "($help)*--dns-search-rm=[Remove DNS search domains]:DNS search: " \
2108                "($help)--force[Force update]" \
2109                "($help)*--group-add=[Add additional supplementary user groups to the container]:group:_groups" \
2110                "($help)*--group-rm=[Remove previously added supplementary user groups from the container]:group:_groups" \
2111                "($help)--image=[Service image tag]:image:__docker_complete_repositories" \
2112                "($help)*--placement-pref-add=[Add a placement preference]:pref:__docker_service_complete_placement_pref" \
2113                "($help)*--placement-pref-rm=[Remove a placement preference]:pref:__docker_service_complete_placement_pref" \
2114                "($help)*--publish-add=[Add or update a port]:port: " \
2115                "($help)*--publish-rm=[Remove a port(target-port mandatory)]:port: " \
2116                "($help)--rollback[Rollback to previous specification]" \
2117                "($help -)1:service:__docker_complete_services" && ret=0
2118            ;;
2119        (help)
2120            _arguments $(__docker_arguments) ":subcommand:__docker_service_commands" && ret=0
2121            ;;
2122    esac
2123
2124    return ret
2125}
2126
2127# EO service
2128
2129# BO stack
2130
2131__docker_stack_complete_ps_filters() {
2132    [[ $PREFIX = -* ]] && return 1
2133    integer ret=1
2134
2135    if compset -P '*='; then
2136        case "${${words[-1]%=*}#*=}" in
2137            (desired-state)
2138                state_opts=('accepted' 'running' 'shutdown')
2139                _describe -t state-opts "desired state options" state_opts && ret=0
2140                ;;
2141            *)
2142                _message 'value' && ret=0
2143                ;;
2144        esac
2145    else
2146        opts=('desired-state' 'id' 'name')
2147        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
2148    fi
2149
2150    return ret
2151}
2152
2153__docker_stack_complete_services_filters() {
2154    [[ $PREFIX = -* ]] && return 1
2155    integer ret=1
2156
2157    if compset -P '*='; then
2158        case "${${words[-1]%=*}#*=}" in
2159            *)
2160                _message 'value' && ret=0
2161                ;;
2162        esac
2163    else
2164        opts=('id' 'label' 'name')
2165        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
2166    fi
2167
2168    return ret
2169}
2170
2171__docker_stacks() {
2172    [[ $PREFIX = -* ]] && return 1
2173    integer ret=1
2174    local line s
2175    declare -a lines stacks
2176
2177    lines=(${(f)${:-"$(_call_program commands docker $docker_options stack ls)"$'\n'}})
2178
2179    # Parse header line to find columns
2180    local i=1 j=1 k header=${lines[1]}
2181    declare -A begin end
2182    while (( j < ${#header} - 1 )); do
2183        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
2184        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
2185        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
2186        begin[${header[$i,$((j-1))]}]=$i
2187        end[${header[$i,$((j-1))]}]=$k
2188    done
2189    end[${header[$i,$((j-1))]}]=-1
2190    lines=(${lines[2,-1]})
2191
2192    # Service NAME
2193    for line in $lines; do
2194        s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
2195        stacks=($stacks $s)
2196    done
2197
2198    _describe -t stacks-list "stacks" stacks "$@" && ret=0
2199    return ret
2200}
2201
2202__docker_complete_stacks() {
2203    [[ $PREFIX = -* ]] && return 1
2204    __docker_stacks "$@"
2205}
2206
2207__docker_stack_commands() {
2208    local -a _docker_stack_subcommands
2209    _docker_stack_subcommands=(
2210        "deploy:Deploy a new stack or update an existing stack"
2211        "ls:List stacks"
2212        "ps:List the tasks in the stack"
2213        "rm:Remove the stack"
2214        "services:List the services in the stack"
2215    )
2216    _describe -t docker-stack-commands "docker stack command" _docker_stack_subcommands
2217}
2218
2219__docker_stack_subcommand() {
2220    local -a _command_args opts_help
2221    local expl help="--help"
2222    integer ret=1
2223
2224    opts_help=("(: -)--help[Print usage]")
2225
2226    case "$words[1]" in
2227        (deploy|up)
2228            _arguments $(__docker_arguments) \
2229                $opts_help \
2230                "($help -c --compose-file)"{-c=,--compose-file=}"[Path to a Compose file, or '-' to read from stdin]:compose file:_files -g \"*.(yml|yaml)\"" \
2231                "($help)--with-registry-auth[Send registry authentication details to Swarm agents]" \
2232                "($help -):stack:__docker_complete_stacks" && ret=0
2233            ;;
2234        (ls|list)
2235            _arguments $(__docker_arguments) \
2236                $opts_help && ret=0
2237            ;;
2238        (ps)
2239            _arguments $(__docker_arguments) \
2240                $opts_help \
2241                "($help -a --all)"{-a,--all}"[Display all tasks]" \
2242                "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_stack_complete_ps_filters" \
2243                "($help)--format=[Format the output using the given go template]:template: " \
2244                "($help)--no-resolve[Do not map IDs to Names]" \
2245                "($help)--no-trunc[Do not truncate output]" \
2246                "($help -q --quiet)"{-q,--quiet}"[Only display task IDs]" \
2247                "($help -):stack:__docker_complete_stacks" && ret=0
2248            ;;
2249        (rm|remove|down)
2250            _arguments $(__docker_arguments) \
2251                $opts_help \
2252                "($help -):stack:__docker_complete_stacks" && ret=0
2253            ;;
2254        (services)
2255            _arguments $(__docker_arguments) \
2256                $opts_help \
2257                "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_stack_complete_services_filters" \
2258                "($help)--format=[Format the output using the given Go template]:template: " \
2259                "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" \
2260                "($help -):stack:__docker_complete_stacks" && ret=0
2261            ;;
2262        (help)
2263            _arguments $(__docker_arguments) ":subcommand:__docker_stack_commands" && ret=0
2264            ;;
2265    esac
2266
2267    return ret
2268}
2269
2270# EO stack
2271
2272# BO swarm
2273
2274__docker_swarm_commands() {
2275    local -a _docker_swarm_subcommands
2276    _docker_swarm_subcommands=(
2277        "init:Initialize a swarm"
2278        "join:Join a swarm as a node and/or manager"
2279        "join-token:Manage join tokens"
2280        "leave:Leave a swarm"
2281        "unlock:Unlock swarm"
2282        "unlock-key:Manage the unlock key"
2283        "update:Update the swarm"
2284    )
2285    _describe -t docker-swarm-commands "docker swarm command" _docker_swarm_subcommands
2286}
2287
2288__docker_swarm_subcommand() {
2289    local -a _command_args opts_help
2290    local expl help="--help"
2291    integer ret=1
2292
2293    opts_help=("(: -)--help[Print usage]")
2294
2295    case "$words[1]" in
2296        (init)
2297            _arguments $(__docker_arguments) \
2298                $opts_help \
2299                "($help)--advertise-addr=[Advertised address]:ip\:port: " \
2300                "($help)--data-path-addr=[Data path IP or interface]:ip " \
2301                "($help)--data-path-port=[Data Path Port]:port " \
2302                "($help)--default-addr-pool=[Default address pool]" \
2303                "($help)--default-addr-pool-mask-length=[Default address pool subnet mask length]" \
2304                "($help)--autolock[Enable manager autolocking]" \
2305                "($help)--availability=[Availability of the node]:availability:(active drain pause)" \
2306                "($help)--cert-expiry=[Validity period for node certificates]:duration: " \
2307                "($help)--dispatcher-heartbeat=[Dispatcher heartbeat period]:duration: " \
2308                "($help)*--external-ca=[Specifications of one or more certificate signing endpoints]:endpoint: " \
2309                "($help)--force-new-cluster[Force create a new cluster from current state]" \
2310                "($help)--listen-addr=[Listen address]:ip\:port: " \
2311                "($help)--max-snapshots[Number of additional Raft snapshots to retain]" \
2312                "($help)--snapshot-interval[Number of log entries between Raft snapshots]" \
2313                "($help)--task-history-limit=[Task history retention limit]:limit: " && ret=0
2314            ;;
2315        (join)
2316            _arguments $(__docker_arguments) -A '-*' \
2317                $opts_help \
2318                "($help)--advertise-addr=[Advertised address]:ip\:port: " \
2319                "($help)--data-path-addr=[Data path IP or interface]:ip " \
2320                "($help)--availability=[Availability of the node]:availability:(active drain pause)" \
2321                "($help)--listen-addr=[Listen address]:ip\:port: " \
2322                "($help)--token=[Token for entry into the swarm]:secret: " \
2323                "($help -):host\:port: " && ret=0
2324            ;;
2325        (join-token)
2326            _arguments $(__docker_arguments) \
2327                $opts_help \
2328                "($help -q --quiet)"{-q,--quiet}"[Only display token]" \
2329                "($help)--rotate[Rotate join token]" \
2330                "($help -):role:(manager worker)" && ret=0
2331            ;;
2332        (leave)
2333            _arguments $(__docker_arguments) \
2334                $opts_help \
2335                "($help -f --force)"{-f,--force}"[Force this node to leave the swarm, ignoring warnings]" && ret=0
2336            ;;
2337        (unlock)
2338            _arguments $(__docker_arguments) \
2339                $opts_help && ret=0
2340            ;;
2341        (unlock-key)
2342            _arguments $(__docker_arguments) \
2343                $opts_help \
2344                "($help -q --quiet)"{-q,--quiet}"[Only display token]" \
2345                "($help)--rotate[Rotate unlock token]" && ret=0
2346            ;;
2347        (update)
2348            _arguments $(__docker_arguments) \
2349                $opts_help \
2350                "($help)--autolock[Enable manager autolocking]" \
2351                "($help)--cert-expiry=[Validity period for node certificates]:duration: " \
2352                "($help)--dispatcher-heartbeat=[Dispatcher heartbeat period]:duration: " \
2353                "($help)*--external-ca=[Specifications of one or more certificate signing endpoints]:endpoint: " \
2354                "($help)--max-snapshots[Number of additional Raft snapshots to retain]" \
2355                "($help)--snapshot-interval[Number of log entries between Raft snapshots]" \
2356                "($help)--task-history-limit=[Task history retention limit]:limit: " && ret=0
2357            ;;
2358        (help)
2359            _arguments $(__docker_arguments) ":subcommand:__docker_network_commands" && ret=0
2360            ;;
2361    esac
2362
2363    return ret
2364}
2365
2366# EO swarm
2367
2368# BO system
2369
2370__docker_system_commands() {
2371    local -a _docker_system_subcommands
2372    _docker_system_subcommands=(
2373        "df:Show docker filesystem usage"
2374        "events:Get real time events from the server"
2375        "info:Display system-wide information"
2376        "prune:Remove unused data"
2377    )
2378    _describe -t docker-system-commands "docker system command" _docker_system_subcommands
2379}
2380
2381__docker_system_subcommand() {
2382    local -a _command_args opts_help
2383    local expl help="--help"
2384    integer ret=1
2385
2386    opts_help=("(: -)--help[Print usage]")
2387
2388    case "$words[1]" in
2389        (df)
2390            _arguments $(__docker_arguments) \
2391                $opts_help \
2392                "($help -v --verbose)"{-v,--verbose}"[Show detailed information on space usage]" && ret=0
2393            ;;
2394        (events)
2395            _arguments $(__docker_arguments) \
2396                $opts_help \
2397                "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_events_filter" \
2398                "($help)--since=[Events created since this timestamp]:timestamp: " \
2399                "($help)--until=[Events created until this timestamp]:timestamp: " \
2400                "($help)--format=[Format the output using the given go template]:template: " && ret=0
2401            ;;
2402        (info)
2403            _arguments $(__docker_arguments) \
2404                $opts_help \
2405                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " && ret=0
2406            ;;
2407        (prune)
2408            _arguments $(__docker_arguments) \
2409                $opts_help \
2410                "($help -a --all)"{-a,--all}"[Remove all unused data, not just dangling ones]" \
2411                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
2412                "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" \
2413                "($help)--volumes=[Remove all unused volumes]" && ret=0
2414            ;;
2415        (help)
2416            _arguments $(__docker_arguments) ":subcommand:__docker_volume_commands" && ret=0
2417            ;;
2418    esac
2419
2420    return ret
2421}
2422
2423# EO system
2424
2425# BO volume
2426
2427__docker_volume_complete_ls_filters() {
2428    [[ $PREFIX = -* ]] && return 1
2429    integer ret=1
2430
2431    if compset -P '*='; then
2432        case "${${words[-1]%=*}#*=}" in
2433            (dangling)
2434                dangling_opts=('true' 'false')
2435                _describe -t dangling-filter-opts "Dangling Filter Options" dangling_opts && ret=0
2436                ;;
2437            (driver)
2438                __docker_complete_info_plugins Volume && ret=0
2439                ;;
2440            (name)
2441                __docker_complete_volumes && ret=0
2442                ;;
2443            *)
2444                _message 'value' && ret=0
2445                ;;
2446        esac
2447    else
2448        opts=('dangling' 'driver' 'label' 'name')
2449        _describe -t filter-opts "Filter Options" opts -qS "=" && ret=0
2450    fi
2451
2452    return ret
2453}
2454
2455__docker_complete_volumes() {
2456    [[ $PREFIX = -* ]] && return 1
2457    integer ret=1
2458    declare -a lines volumes
2459
2460    lines=(${(f)${:-"$(_call_program commands docker $docker_options volume ls)"$'\n'}})
2461
2462    # Parse header line to find columns
2463    local i=1 j=1 k header=${lines[1]}
2464    declare -A begin end
2465    while (( j < ${#header} - 1 )); do
2466        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
2467        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
2468        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
2469        begin[${header[$i,$((j-1))]}]=$i
2470        end[${header[$i,$((j-1))]}]=$k
2471    done
2472    end[${header[$i,$((j-1))]}]=-1
2473    lines=(${lines[2,-1]})
2474
2475    # Names
2476    local line s
2477    for line in $lines; do
2478        s="${line[${begin[VOLUME NAME]},${end[VOLUME NAME]}]%% ##}"
2479        s="$s:${(l:7:: :::)${${line[${begin[DRIVER]},${end[DRIVER]}]}%% ##}}"
2480        volumes=($volumes $s)
2481    done
2482
2483    _describe -t volumes-list "volumes" volumes && ret=0
2484    return ret
2485}
2486
2487__docker_volume_commands() {
2488    local -a _docker_volume_subcommands
2489    _docker_volume_subcommands=(
2490        "create:Create a volume"
2491        "inspect:Display detailed information on one or more volumes"
2492        "ls:List volumes"
2493        "prune:Remove all unused volumes"
2494        "rm:Remove one or more volumes"
2495    )
2496    _describe -t docker-volume-commands "docker volume command" _docker_volume_subcommands
2497}
2498
2499__docker_volume_subcommand() {
2500    local -a _command_args opts_help
2501    local expl help="--help"
2502    integer ret=1
2503
2504    opts_help=("(: -)--help[Print usage]")
2505
2506    case "$words[1]" in
2507        (create)
2508            _arguments $(__docker_arguments) -A '-*' \
2509                $opts_help \
2510                "($help -d --driver)"{-d=,--driver=}"[Volume driver name]:Driver name:(local)" \
2511                "($help)*--label=[Set metadata for a volume]:label=value: " \
2512                "($help)*"{-o=,--opt=}"[Driver specific options]:Driver option: " \
2513                "($help -)1:Volume name: " && ret=0
2514            ;;
2515        (inspect)
2516            _arguments $(__docker_arguments) \
2517                $opts_help \
2518                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
2519                "($help -)1:volume:__docker_complete_volumes" && ret=0
2520            ;;
2521        (ls)
2522            _arguments $(__docker_arguments) \
2523                $opts_help \
2524                "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_volume_complete_ls_filters" \
2525                "($help)--format=[Format the output using the given Go template]:template: " \
2526                "($help -q --quiet)"{-q,--quiet}"[Only display volume names]" && ret=0
2527            ;;
2528        (prune)
2529            _arguments $(__docker_arguments) \
2530                $opts_help \
2531                "($help -a --all)"{-a,--all}"[Remove all unused local volumes, not just anonymous ones]" \
2532                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
2533                "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
2534            ;;
2535        (rm)
2536            _arguments $(__docker_arguments) \
2537                $opts_help \
2538                "($help -f --force)"{-f,--force}"[Force the removal of one or more volumes]" \
2539                "($help -):volume:__docker_complete_volumes" && ret=0
2540            ;;
2541        (help)
2542            _arguments $(__docker_arguments) ":subcommand:__docker_volume_commands" && ret=0
2543            ;;
2544    esac
2545
2546    return ret
2547}
2548
2549# EO volume
2550
2551# BO context
2552
2553__docker_complete_contexts() {
2554    [[ $PREFIX = -* ]] && return 1
2555    integer ret=1
2556    declare -a contexts
2557
2558    contexts=(${(f)${:-"$(_call_program commands docker $docker_options context ls -q)"$'\n'}})
2559
2560    _describe -t context-list "context" contexts && ret=0
2561    return ret
2562}
2563
2564__docker_context_commands() {
2565    local -a _docker_context_subcommands
2566    _docker_context_subcommands=(
2567        "create:Create new context"
2568        "inspect:Display detailed information on one or more contexts"
2569        "list:List available contexts"
2570        "rm:Remove one or more contexts"
2571        "show:Print the current context"
2572        "update:Update a context"
2573        "use:Set the default context"
2574    )
2575    _describe -t docker-context-commands "docker context command" _docker_context_subcommands
2576}
2577
2578__docker_context_subcommand() {
2579    local -a _command_args opts_help
2580    local expl help="--help"
2581    integer ret=1
2582
2583    opts_help=("(: -)--help[Print usage]")
2584
2585    case "$words[1]" in
2586        (create)
2587            _arguments $(__docker_arguments) \
2588                $opts_help \
2589                "($help)--description=[Description of the context]:description:" \
2590                "($help)--docker=[Set the docker endpoint]:docker:" \
2591                "($help)--from=[Create context from a named context]:from:__docker_complete_contexts" \
2592                "($help -):name: " && ret=0
2593            ;;
2594        (use)
2595            _arguments $(__docker_arguments) \
2596                $opts_help \
2597                "($help -)1:context:__docker_complete_contexts" && ret=0
2598            ;;
2599        (inspect)
2600            _arguments $(__docker_arguments) \
2601                $opts_help \
2602                "($help -)1:context:__docker_complete_contexts" && ret=0
2603            ;;
2604        (rm)
2605            _arguments $(__docker_arguments) \
2606                $opts_help \
2607                "($help -)1:context:__docker_complete_contexts" && ret=0
2608            ;;
2609        (update)
2610            _arguments $(__docker_arguments) \
2611                $opts_help \
2612                "($help)--description=[Description of the context]:description:" \
2613                "($help)--docker=[Set the docker endpoint]:docker:" \
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)--config-file=[Path to daemon configuration file]:Config File:_files" \
2738                "($help)--containerd=[Path to containerd socket]:socket:_files -g \"*.sock\"" \
2739                "($help)--containerd-namespace=[Containerd namespace to use]:containerd namespace:" \
2740                "($help)--containerd-plugins-namespace=[Containerd namespace to use for plugins]:containerd namespace:" \
2741                "($help)--data-root=[Root directory of persisted Docker data]:path:_directories" \
2742                "($help -D --debug)"{-D,--debug}"[Enable debug mode]" \
2743                "($help)--default-gateway[Container default gateway IPv4 address]:IPv4 address: " \
2744                "($help)--default-gateway-v6[Container default gateway IPv6 address]:IPv6 address: " \
2745                "($help)--default-shm-size=[Default shm size for containers]:size:" \
2746                "($help)*--default-ulimit=[Default ulimits for containers]:ulimit: " \
2747                "($help)*--dns=[DNS server to use]:DNS: " \
2748                "($help)*--dns-opt=[DNS options to use]:DNS option: " \
2749                "($help)*--dns-search=[DNS search domains to use]:DNS search: " \
2750                "($help)*--exec-opt=[Runtime execution options]:runtime execution options: " \
2751                "($help)--exec-root=[Root directory for execution state files]:path:_directories" \
2752                "($help)--experimental[Enable experimental features]" \
2753                "($help)--fixed-cidr=[IPv4 subnet for fixed IPs]:IPv4 subnet: " \
2754                "($help)--fixed-cidr-v6=[IPv6 subnet for fixed IPs]:IPv6 subnet: " \
2755                "($help -G --group)"{-G=,--group=}"[Group for the unix socket]:group:_groups" \
2756                "($help -H --host)"{-H=,--host=}"[tcp://host:port to bind/connect to]:host: " \
2757                "($help)--icc[Enable inter-container communication]" \
2758                "($help)--init[Run an init inside containers to forward signals and reap processes]" \
2759                "($help)--init-path=[Path to the docker-init binary]:docker-init binary:_files" \
2760                "($help)*--insecure-registry=[Enable insecure registry communication]:registry: " \
2761                "($help)--ip=[Default IP when binding container ports]" \
2762                "($help)--ip-forward[Enable net.ipv4.ip_forward]" \
2763                "($help)--ip-masq[Enable IP masquerading]" \
2764                "($help)--iptables[Enable addition of iptables rules]" \
2765                "($help)--ipv6[Enable IPv6 networking]" \
2766                "($help -l --log-level)"{-l=,--log-level=}"[Logging level]:level:(debug info warn error fatal)" \
2767                "($help)*--label=[Key=value labels]:label: " \
2768                "($help)--live-restore[Enable live restore of docker when containers are still running]" \
2769                "($help)--log-driver=[Default driver for container logs]:logging driver:__docker_complete_log_drivers" \
2770                "($help)*--log-opt=[Default log driver options for containers]:log driver options:__docker_complete_log_options" \
2771                "($help)--max-concurrent-downloads[Set the max concurrent downloads]" \
2772                "($help)--max-concurrent-uploads[Set the max concurrent uploads]" \
2773                "($help)--max-download-attempts[Set the max download attempts for each pull]" \
2774                "($help)--mtu=[Network MTU]:mtu:(0 576 1420 1500 9000)" \
2775                "($help)--oom-score-adjust=[Set the oom_score_adj for the daemon]:oom-score:(-500)" \
2776                "($help -p --pidfile)"{-p=,--pidfile=}"[Path to use for daemon PID file]:PID file:_files" \
2777                "($help)--raw-logs[Full timestamps without ANSI coloring]" \
2778                "($help)*--registry-mirror=[Preferred registry mirror]:registry mirror: " \
2779                "($help)--seccomp-profile=[Path to seccomp profile]:path:_files -g \"*.json\"" \
2780                "($help -s --storage-driver)"{-s=,--storage-driver=}"[Storage driver to use]:driver:(btrfs devicemapper overlay2 vfs zfs)" \
2781                "($help)--selinux-enabled[Enable selinux support]" \
2782                "($help)--shutdown-timeout=[Set the shutdown timeout value in seconds]:time: " \
2783                "($help)*--storage-opt=[Storage driver options]:storage driver options: " \
2784                "($help)--tls[Use TLS]" \
2785                "($help)--tlscacert=[Trust certs signed only by this CA]:PEM file:_files -g \"*.(pem|crt)\"" \
2786                "($help)--tlscert=[Path to TLS certificate file]:PEM file:_files -g \"*.(pem|crt)\"" \
2787                "($help)--tlskey=[Path to TLS key file]:Key file:_files -g \"*.(pem|key)\"" \
2788                "($help)--tlsverify[Use TLS and verify the remote]" \
2789                "($help)--userns-remap=[User/Group setting for user namespaces]:user\:group:->users-groups" \
2790                "($help)--userland-proxy[Use userland proxy for loopback traffic]" \
2791                "($help)--userland-proxy-path=[Path to the userland proxy binary]:binary:_files" \
2792                "($help)--validate[Validate daemon configuration and exit]" && ret=0
2793
2794            case $state in
2795                (users-groups)
2796                    if compset -P '*:'; then
2797                        _groups && ret=0
2798                    else
2799                        _describe -t userns-default "default Docker user management" '(default)' && ret=0
2800                        _users && ret=0
2801                    fi
2802                    ;;
2803            esac
2804            ;;
2805        (events|info)
2806            __docker_system_subcommand && ret=0
2807            ;;
2808        (image)
2809            local curcontext="$curcontext" state
2810            _arguments $(__docker_arguments) \
2811                $opts_help \
2812                "($help -): :->command" \
2813                "($help -)*:: :->option-or-argument" && ret=0
2814
2815            case $state in
2816                (command)
2817                    __docker_image_commands && ret=0
2818                    ;;
2819                (option-or-argument)
2820                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2821                    __docker_image_subcommand && ret=0
2822                    ;;
2823            esac
2824            ;;
2825        (images)
2826            words[1]='ls'
2827            __docker_image_subcommand && ret=0
2828            ;;
2829        (inspect)
2830            local state
2831            _arguments $(__docker_arguments) \
2832                $opts_help \
2833                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
2834                "($help -s --size)"{-s,--size}"[Display total file sizes if the type is container]" \
2835                "($help)--type=[Return JSON for specified type]:type:(container image network node plugin service volume)" \
2836                "($help -)*: :->values" && ret=0
2837
2838            case $state in
2839                (values)
2840                    if [[ ${words[(r)--type=container]} == --type=container ]]; then
2841                        __docker_complete_containers && ret=0
2842                    elif [[ ${words[(r)--type=image]} == --type=image ]]; then
2843                        __docker_complete_images && ret=0
2844                    elif [[ ${words[(r)--type=network]} == --type=network ]]; then
2845                        __docker_complete_networks && ret=0
2846                    elif [[ ${words[(r)--type=node]} == --type=node ]]; then
2847                        __docker_complete_nodes && ret=0
2848                    elif [[ ${words[(r)--type=plugin]} == --type=plugin ]]; then
2849                        __docker_complete_plugins && ret=0
2850                    elif [[ ${words[(r)--type=service]} == --type=secrets ]]; then
2851                        __docker_complete_secrets && ret=0
2852                    elif [[ ${words[(r)--type=service]} == --type=service ]]; then
2853                        __docker_complete_services && ret=0
2854                    elif [[ ${words[(r)--type=volume]} == --type=volume ]]; then
2855                        __docker_complete_volumes && ret=0
2856                    else
2857                        __docker_complete_containers
2858                        __docker_complete_images
2859                        __docker_complete_networks
2860                        __docker_complete_nodes
2861                        __docker_complete_plugins
2862                        __docker_complete_secrets
2863                        __docker_complete_services
2864                        __docker_complete_volumes && ret=0
2865                    fi
2866                    ;;
2867            esac
2868            ;;
2869        (login)
2870            _arguments $(__docker_arguments) -A '-*' \
2871                $opts_help \
2872                "($help -p --password)"{-p=,--password=}"[Password]:password: " \
2873                "($help)--password-stdin[Read password from stdin]" \
2874                "($help -u --username)"{-u=,--username=}"[Username]:username: " \
2875                "($help -)1:server: " && ret=0
2876            ;;
2877        (logout)
2878            _arguments $(__docker_arguments) -A '-*' \
2879                $opts_help \
2880                "($help -)1:server: " && ret=0
2881            ;;
2882        (network)
2883            local curcontext="$curcontext" state
2884            _arguments $(__docker_arguments) \
2885                $opts_help \
2886                "($help -): :->command" \
2887                "($help -)*:: :->option-or-argument" && ret=0
2888
2889            case $state in
2890                (command)
2891                    __docker_network_commands && ret=0
2892                    ;;
2893                (option-or-argument)
2894                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2895                    __docker_network_subcommand && ret=0
2896                    ;;
2897            esac
2898            ;;
2899        (node)
2900            local curcontext="$curcontext" state
2901            _arguments $(__docker_arguments) \
2902                $opts_help \
2903                "($help -): :->command" \
2904                "($help -)*:: :->option-or-argument" && ret=0
2905
2906            case $state in
2907                (command)
2908                    __docker_node_commands && ret=0
2909                    ;;
2910                (option-or-argument)
2911                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2912                    __docker_node_subcommand && ret=0
2913                    ;;
2914            esac
2915            ;;
2916        (plugin)
2917            local curcontext="$curcontext" state
2918            _arguments $(__docker_arguments) \
2919                $opts_help \
2920                "($help -): :->command" \
2921                "($help -)*:: :->option-or-argument" && ret=0
2922
2923            case $state in
2924                (command)
2925                    __docker_plugin_commands && ret=0
2926                    ;;
2927                (option-or-argument)
2928                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2929                    __docker_plugin_subcommand && ret=0
2930                    ;;
2931            esac
2932            ;;
2933        (ps)
2934            words[1]='ls'
2935            __docker_container_subcommand && ret=0
2936            ;;
2937        (rmi)
2938            words[1]='rm'
2939            __docker_image_subcommand && ret=0
2940            ;;
2941        (search)
2942            _arguments $(__docker_arguments) -A '-*' \
2943                $opts_help \
2944                "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_search_filters" \
2945                "($help)--limit=[Maximum returned search results]:limit:(1 5 10 25 50)" \
2946                "($help)--no-trunc[Do not truncate output]" \
2947                "($help -):term: " && ret=0
2948            ;;
2949        (secret)
2950            local curcontext="$curcontext" state
2951            _arguments $(__docker_arguments) \
2952                $opts_help \
2953                "($help -): :->command" \
2954                "($help -)*:: :->option-or-argument" && ret=0
2955
2956            case $state in
2957                (command)
2958                    __docker_secret_commands && ret=0
2959                    ;;
2960                (option-or-argument)
2961                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2962                    __docker_secret_subcommand && ret=0
2963                    ;;
2964            esac
2965            ;;
2966        (service)
2967            local curcontext="$curcontext" state
2968            _arguments $(__docker_arguments) \
2969                $opts_help \
2970                "($help -): :->command" \
2971                "($help -)*:: :->option-or-argument" && ret=0
2972
2973            case $state in
2974                (command)
2975                    __docker_service_commands && ret=0
2976                    ;;
2977                (option-or-argument)
2978                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2979                    __docker_service_subcommand && ret=0
2980                    ;;
2981            esac
2982            ;;
2983        (stack)
2984            local curcontext="$curcontext" state
2985            _arguments $(__docker_arguments) \
2986                $opts_help \
2987                "($help -): :->command" \
2988                "($help -)*:: :->option-or-argument" && ret=0
2989
2990            case $state in
2991                (command)
2992                    __docker_stack_commands && ret=0
2993                    ;;
2994                (option-or-argument)
2995                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
2996                    __docker_stack_subcommand && ret=0
2997                    ;;
2998            esac
2999            ;;
3000        (swarm)
3001            local curcontext="$curcontext" state
3002            _arguments $(__docker_arguments) \
3003                $opts_help \
3004                "($help -): :->command" \
3005                "($help -)*:: :->option-or-argument" && ret=0
3006
3007            case $state in
3008                (command)
3009                    __docker_swarm_commands && ret=0
3010                    ;;
3011                (option-or-argument)
3012                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
3013                    __docker_swarm_subcommand && ret=0
3014                    ;;
3015            esac
3016            ;;
3017        (system)
3018            local curcontext="$curcontext" state
3019            _arguments $(__docker_arguments) \
3020                $opts_help \
3021                "($help -): :->command" \
3022                "($help -)*:: :->option-or-argument" && ret=0
3023
3024            case $state in
3025                (command)
3026                    __docker_system_commands && ret=0
3027                    ;;
3028                (option-or-argument)
3029                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
3030                    __docker_system_subcommand && ret=0
3031                    ;;
3032            esac
3033            ;;
3034        (version)
3035            _arguments $(__docker_arguments) \
3036                $opts_help \
3037                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " && ret=0
3038            ;;
3039        (volume)
3040            local curcontext="$curcontext" state
3041            _arguments $(__docker_arguments) \
3042                $opts_help \
3043                "($help -): :->command" \
3044                "($help -)*:: :->option-or-argument" && ret=0
3045
3046            case $state in
3047                (command)
3048                    __docker_volume_commands && ret=0
3049                    ;;
3050                (option-or-argument)
3051                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
3052                    __docker_volume_subcommand && ret=0
3053                    ;;
3054            esac
3055            ;;
3056        (help)
3057            _arguments $(__docker_arguments) ":subcommand:__docker_commands" && ret=0
3058            ;;
3059    esac
3060
3061    return ret
3062}
3063
3064_docker() {
3065    # Support for subservices, which allows for `compdef _docker docker-shell=_docker_containers`.
3066    # Based on /usr/share/zsh/functions/Completion/Unix/_git without support for `ret`.
3067    if [[ $service != docker ]]; then
3068        _call_function - _$service
3069        return
3070    fi
3071
3072    local curcontext="$curcontext" state line help="-h --help"
3073    integer ret=1
3074    typeset -A opt_args
3075
3076    _arguments $(__docker_arguments) -C \
3077        "(: -)"{-h,--help}"[Print usage]" \
3078        "($help)--config[Location of client config files]:path:_directories" \
3079        "($help -c --context)"{-c=,--context=}"[Execute the command in a docker context]:context:__docker_complete_contexts" \
3080        "($help -D --debug)"{-D,--debug}"[Enable debug mode]" \
3081        "($help -H --host)"{-H=,--host=}"[tcp://host:port to bind/connect to]:host: " \
3082        "($help -l --log-level)"{-l=,--log-level=}"[Logging level]:level:(debug info warn error fatal)" \
3083        "($help)--tls[Use TLS]" \
3084        "($help)--tlscacert=[Trust certs signed only by this CA]:PEM file:_files -g "*.(pem|crt)"" \
3085        "($help)--tlscert=[Path to TLS certificate file]:PEM file:_files -g "*.(pem|crt)"" \
3086        "($help)--tlskey=[Path to TLS key file]:Key file:_files -g "*.(pem|key)"" \
3087        "($help)--tlsverify[Use TLS and verify the remote]" \
3088        "($help)--userland-proxy[Use userland proxy for loopback traffic]" \
3089        "($help -v --version)"{-v,--version}"[Print version information and quit]" \
3090        "($help -): :->command" \
3091        "($help -)*:: :->option-or-argument" && ret=0
3092
3093    local host=${opt_args[-H]}${opt_args[--host]}
3094    local config=${opt_args[--config]}
3095    local context=${opt_args[-c]}${opt_args[--context]}
3096    local docker_options="${host:+--host $host} ${config:+--config $config} ${context:+--context $context} "
3097
3098    case $state in
3099        (command)
3100            __docker_commands && ret=0
3101            ;;
3102        (option-or-argument)
3103            curcontext=${curcontext%:*:*}:docker-$words[1]:
3104            __docker_subcommand && ret=0
3105            ;;
3106    esac
3107
3108    return ret
3109}
3110
3111_dockerd() {
3112    integer ret=1
3113    words[1]='daemon'
3114    __docker_subcommand && ret=0
3115    return ret
3116}
3117
3118_docker "$@"
3119
3120# Local Variables:
3121# mode: Shell-Script
3122# sh-indentation: 4
3123# indent-tabs-mode: nil
3124# sh-basic-offset: 4
3125# End:
3126# vim: ft=zsh sw=4 ts=4 et