github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/contrib/completion/zsh/_docker (about)

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