diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index 76da887521..848412ea48 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -615,7 +615,7 @@ _docker_attach() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy=false" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag '--detach-keys') @@ -637,6 +637,7 @@ _docker_build() { --cpu-quota --file -f --isolation + --label --memory -m --memory-swap --shm-size @@ -701,7 +702,7 @@ _docker_commit() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--author -a --change -c --help --message -m --pause -p" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--author -a --change -c --help --message -m --pause=false -p=false" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag '--author|-a|--change|-c|--message|-m') @@ -793,6 +794,7 @@ _docker_daemon() { --cluster-advertise --cluster-store --cluster-store-opt + --containerd --default-gateway --default-gateway-v6 --default-ulimit @@ -869,7 +871,7 @@ _docker_daemon() { __docker_complete_log_drivers return ;; - --pidfile|-p|--tlscacert|--tlscert|--tlskey) + --containerd|--pidfile|-p|--tlscacert|--tlscert|--tlskey) _filedir return ;; @@ -1075,7 +1077,7 @@ _docker_help() { _docker_history() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help --no-trunc --quiet -q" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--help --human=false -H=false --no-trunc --quiet -q" -- "$cur" ) ) ;; *) local counter=$(__docker_pos_first_nonflag) @@ -1324,11 +1326,14 @@ _docker_network_create() { COMPREPLY=( $(compgen -W "$plugins" -- "$cur") ) return ;; + --label) + return + ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--aux-address --driver -d --gateway --help --internal --ip-range --ipam-driver --ipam-opt --ipv6 --opt -o --subnet" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--aux-address --driver -d --gateway --help --internal --ip-range --ipam-driver --ipam-opt --ipv6 --label --opt -o --subnet" -- "$cur" ) ) ;; esac } @@ -1663,6 +1668,7 @@ _docker_run() { --tmpfs --ulimit --user -u + --userns --uts --volume-driver --volumes-from @@ -1699,6 +1705,24 @@ _docker_run() { __docker_complete_log_driver_options && return __docker_complete_restart && return + local key=$(__docker_map_key_of_current_option '--security-opt') + case "$key" in + label) + [[ $cur == *: ]] && return + COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "${cur##*=}") ) + if [ "${COMPREPLY[*]}" != "disable" ] ; then + __docker_nospace + fi + return + ;; + seccomp) + local cur=${cur##*=} + _filedir + COMPREPLY+=( $( compgen -W "unconfined" -- "$cur" ) ) + return + ;; + esac + case "$prev" in --add-host) case "$cur" in @@ -1796,32 +1820,20 @@ _docker_run() { return ;; --security-opt) - case "$cur" in - label=*:*) - ;; - label=*) - local cur=${cur##*=} - COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "$cur") ) - if [ "${COMPREPLY[*]}" != "disable" ] ; then - __docker_nospace - fi - ;; - seccomp=*) - local cur=${cur##*=} - _filedir - COMPREPLY+=( $( compgen -W "unconfined" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "label apparmor seccomp" -S ":" -- "$cur") ) - __docker_nospace - ;; - esac + COMPREPLY=( $( compgen -W "apparmor= label= no-new-privileges seccomp=" -- "$cur") ) + if [ "${COMPREPLY[*]}" != "no-new-privileges" ] ; then + __docker_nospace + fi return ;; --user|-u) __docker_complete_user_group return ;; + --userns) + COMPREPLY=( $( compgen -W "host" -- "$cur" ) ) + return + ;; --volume-driver) __docker_complete_plugins Volume return @@ -2024,14 +2036,14 @@ _docker_volume_create() { __docker_complete_plugins Volume return ;; - --name|--opt|-o) + --label|--name|--opt|-o) return ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--driver -d --help --name --opt -o" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--driver -d --help --label --name --opt -o" -- "$cur" ) ) ;; esac } diff --git a/contrib/completion/zsh/_docker b/contrib/completion/zsh/_docker index 8811261f22..1351ae9579 100644 --- a/contrib/completion/zsh/_docker +++ b/contrib/completion/zsh/_docker @@ -50,11 +50,11 @@ __docker_arguments() { __docker_get_containers() { [[ $PREFIX = -* ]] && return 1 integer ret=1 - local kind - declare -a running stopped lines args + local kind type line s + declare -a running stopped lines args names - kind=$1 - shift + kind=$1; shift + type=$1; shift [[ $kind = (stopped|all) ]] && args=($args -a) lines=(${(f)"$(_call_program commands docker $docker_options ps --no-trunc $args)"}) @@ -73,39 +73,40 @@ __docker_get_containers() { lines=(${lines[2,-1]}) # Container ID - local line - local s - for line in $lines; do - s="${${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}[0,12]}" - s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}" - s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}" - if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then - stopped=($stopped $s) - else - running=($running $s) - fi - done + if [[ $type = (ids|all) ]]; then + for line in $lines; do + s="${${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}[0,12]}" + s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}" + s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}" + if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then + stopped=($stopped $s) + else + running=($running $s) + fi + done + fi # Names: we only display the one without slash. All other names # are generated and may clutter the completion. However, with # Swarm, all names may be prefixed by the swarm node name. - local -a names - for line in $lines; do - names=(${(ps:,:)${${line[${begin[NAMES]},${end[NAMES]}]}%% *}}) - # First step: find a common prefix and strip it (swarm node case) - (( ${#${(u)names%%/*}} == 1 )) && names=${names#${names[1]%%/*}/} - # Second step: only keep the first name without a / - s=${${names:#*/*}[1]} - # If no name, well give up. - (( $#s != 0 )) || continue - s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}" - s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}" - if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then - stopped=($stopped $s) - else - running=($running $s) - fi - done + if [[ $type = (names|all) ]]; then + for line in $lines; do + names=(${(ps:,:)${${line[${begin[NAMES]},${end[NAMES]}]}%% *}}) + # First step: find a common prefix and strip it (swarm node case) + (( ${#${(u)names%%/*}} == 1 )) && names=${names#${names[1]%%/*}/} + # Second step: only keep the first name without a / + s=${${names:#*/*}[1]} + # If no name, well give up. + (( $#s != 0 )) || continue + s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}" + s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}" + if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then + stopped=($stopped $s) + else + running=($running $s) + fi + done + fi [[ $kind = (running|all) ]] && _describe -t containers-running "running containers" running "$@" && ret=0 [[ $kind = (stopped|all) ]] && _describe -t containers-stopped "stopped containers" stopped "$@" && ret=0 @@ -114,17 +115,27 @@ __docker_get_containers() { __docker_stoppedcontainers() { [[ $PREFIX = -* ]] && return 1 - __docker_get_containers stopped "$@" + __docker_get_containers stopped all "$@" } __docker_runningcontainers() { [[ $PREFIX = -* ]] && return 1 - __docker_get_containers running "$@" + __docker_get_containers running all "$@" } __docker_containers() { [[ $PREFIX = -* ]] && return 1 - __docker_get_containers all "$@" + __docker_get_containers all all "$@" +} + +__docker_containers_ids() { + [[ $PREFIX = -* ]] && return 1 + __docker_get_containers all ids "$@" +} + +__docker_containers_names() { + [[ $PREFIX = -* ]] && return 1 + __docker_get_containers all names "$@" } __docker_images() { @@ -200,10 +211,10 @@ __docker_get_log_options() { local -a awslogs_options fluentd_options gelf_options journald_options json_file_options syslog_options splunk_options awslogs_options=("awslogs-region" "awslogs-group" "awslogs-stream") - fluentd_options=("env" "fluentd-address" "labels" "tag") + fluentd_options=("env" "fluentd-address" "fluentd-async-connect" "fluentd-buffer-limit" "fluentd-retry-wait" "fluentd-max-retries" "labels" "tag") gcplogs_options=("env" "gcp-log-cmd" "gcp-project" "labels") - gelf_options=("env" "gelf-address" "labels" "tag") - journald_options=("env" "labels") + gelf_options=("env" "gelf-address" "gelf-compression-level" "gelf-compression-type" "labels" "tag") + journald_options=("env" "labels" "tag") json_file_options=("env" "labels" "max-file" "max-size") syslog_options=("syslog-address" "syslog-tls-ca-cert" "syslog-tls-cert" "syslog-tls-key" "syslog-tls-skip-verify" "syslog-facility" "tag") splunk_options=("env" "labels" "splunk-caname" "splunk-capath" "splunk-index" "splunk-insecureskipverify" "splunk-source" "splunk-sourcetype" "splunk-token" "splunk-url" "tag") @@ -244,6 +255,43 @@ __docker_complete_detach_keys() { _describe -t detach_keys-ctrl "'ctrl-' + 'a-z @ [ \\\\ ] ^ _'" ctrl_keys -qS "," && ret=0 } +__docker_complete_ps_filters() { + [[ $PREFIX = -* ]] && return 1 + integer ret=1 + + if compset -P '*='; then + case "${${words[-1]%=*}#*=}" in + (ancestor) + __docker_images && ret=0 + ;; + (before|since) + __docker_containers && ret=0 + ;; + (id) + __docker_containers_ids && ret=0 + ;; + (name) + __docker_containers_names && ret=0 + ;; + (status) + status_opts=('created' 'dead' 'exited' 'paused' 'restarting' 'running') + _describe -t status-filter-opts "Status Filter Options" status_opts && ret=0 + ;; + (volume) + __docker_volumes && ret=0 + ;; + *) + _message 'value' && ret=0 + ;; + esac + else + opts=('ancestor' 'before' 'exited' 'id' 'label' 'name' 'since' 'status' 'volume') + _describe -t filter-opts "Filter Options" opts -qS "=" && ret=0 + fi + + return ret +} + __docker_networks() { [[ $PREFIX = -* ]] && return 1 integer ret=1 @@ -335,6 +383,7 @@ __docker_network_subcommand() { "($help)--ipam-driver=[IP Address Management Driver]:driver:(default)" \ "($help)*--ipam-opt=[Custom IPAM plugin options]:opt=value: " \ "($help)--ipv6[Enable IPv6 networking]" \ + "($help)*--label=[Set metadata on a network]:label=value: " \ "($help)*"{-o=,--opt=}"[Driver specific options]:opt=value: " \ "($help)*--subnet=[Subnet in CIDR format that represents a network segment]:IP/mask: " \ "($help -)1:Network Name: " && ret=0 @@ -425,6 +474,7 @@ __docker_volume_subcommand() { _arguments $(__docker_arguments) \ $opts_help \ "($help -d --driver)"{-d=,--driver=}"[Volume driver name]:Driver name:(local)" \ + "($help)*--label=[Set metadata for a volume]:label=value: " \ "($help)--name=[Volume name]" \ "($help)*"{-o=,--opt=}"[Driver specific options]:Driver option: " && ret=0 ;; @@ -489,6 +539,7 @@ __docker_subcommand() { "($help)--isolation=[Container isolation technology]:isolation:(default hyperv process)" "($help)*--shm-size=[Size of '/dev/shm' (format is '')]:shm size: " "($help)*--ulimit=[ulimit options]:ulimit: " + "($help)--userns=[Container user namespace]:user namespace:(host)" ) opts_build_create_run_update=( "($help)--cpu-shares=[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)" @@ -526,7 +577,7 @@ __docker_subcommand() { "($help)--ipc=[IPC namespace to use]:IPC namespace: " "($help)*--link=[Add link to another container]:link:->link" "($help)*"{-l=,--label=}"[Container metadata]:label: " - "($help)--log-driver=[Default driver for container logs]:Logging driver:(json-file syslog journald gelf fluentd awslogs splunk none)" + "($help)--log-driver=[Default driver for container logs]:Logging driver:(awslogs etwlogs fluentd gcplogs gelf journald json-file none splunk syslog)" "($help)*--log-opt=[Log driver specific options]:log driver options:__docker_log_options" "($help)--mac-address=[Container MAC address]:MAC address: " "($help)--name=[Container name]:name: " @@ -540,7 +591,6 @@ __docker_subcommand() { "($help)--pid=[PID namespace to use]:PID: " "($help)--privileged[Give extended privileges to this container]" "($help)--read-only[Mount the container's root filesystem as read only]" - "($help)--restart=[Restart policy]:restart policy:(no on-failure always unless-stopped)" "($help)*--security-opt=[Security options]:security option: " "($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]" "($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users" @@ -554,6 +604,7 @@ __docker_subcommand() { "($help)--blkio-weight=[Block IO (relative weight), between 10 and 1000]:Block IO weight:(10 100 500 1000)" "($help)--kernel-memory=[Kernel memory limit in bytes]:Memory limit: " "($help)--memory-reservation=[Memory soft limit]:Memory limit: " + "($help)--restart=[Restart policy]:restart policy:(no on-failure always unless-stopped)" ) opts_attach_exec_run_start=( "($help)--detach-keys=[Escape key sequence used to detach a container]:sequence:__docker_complete_detach_keys" @@ -576,6 +627,7 @@ __docker_subcommand() { "($help)*--build-arg[Build-time variables]:=: " \ "($help -f --file)"{-f=,--file=}"[Name of the Dockerfile]:Dockerfile:_files" \ "($help)--force-rm[Always remove intermediate containers]" \ + "($help)*--label=[Set metadata for an image]:label=value: " \ "($help)--no-cache[Do not use cache when building the image]" \ "($help)--pull[Attempt to pull a newer version of the image]" \ "($help -q --quiet)"{-q,--quiet}"[Suppress verbose build output]" \ @@ -639,6 +691,7 @@ __docker_subcommand() { "($help -b --bridge)"{-b=,--bridge=}"[Attach containers to a network bridge]:bridge:_net_interfaces" \ "($help)--bip=[Network bridge IP]:IP address: " \ "($help)--cgroup-parent=[Parent cgroup for all containers]:cgroup: " \ + "($help)--containerd=[Path to containerd socket]:socket:_files -g \"*.sock\"" \ "($help -D --debug)"{-D,--debug}"[Enable debug mode]" \ "($help)--default-gateway[Container default gateway IPv4 address]:IPv4 address: " \ "($help)--default-gateway-v6[Container default gateway IPv6 address]:IPv6 address: " \ @@ -666,7 +719,7 @@ __docker_subcommand() { "($help)--ipv6[Enable IPv6 networking]" \ "($help -l --log-level)"{-l=,--log-level=}"[Logging level]:level:(debug info warn error fatal)" \ "($help)*--label=[Key=value labels]:label: " \ - "($help)--log-driver=[Default driver for container logs]:Logging driver:(json-file syslog journald gelf fluentd awslogs splunk none)" \ + "($help)--log-driver=[Default driver for container logs]:Logging driver:(awslogs etwlogs fluentd gcplogs gelf journald json-file none splunk syslog)" \ "($help)*--log-opt=[Log driver specific options]:log driver options:__docker_log_options" \ "($help)--mtu=[Network MTU]:mtu:(0 576 1420 1500 9000)" \ "($help -p --pidfile)"{-p=,--pidfile=}"[Path to use for daemon PID file]:PID file:_files" \ @@ -676,9 +729,9 @@ __docker_subcommand() { "($help)--selinux-enabled[Enable selinux support]" \ "($help)*--storage-opt=[Storage driver options]:storage driver options: " \ "($help)--tls[Use TLS]" \ - "($help)--tlscacert=[Trust certs signed only by this CA]:PEM file:_files -g "*.(pem|crt)"" \ - "($help)--tlscert=[Path to TLS certificate file]:PEM file:_files -g "*.(pem|crt)"" \ - "($help)--tlskey=[Path to TLS key file]:Key file:_files -g "*.(pem|key)"" \ + "($help)--tlscacert=[Trust certs signed only by this CA]:PEM file:_files -g \"*.(pem|crt)\"" \ + "($help)--tlscert=[Path to TLS certificate file]:PEM file:_files -g \"*.(pem|crt)\"" \ + "($help)--tlskey=[Path to TLS key file]:Key file:_files -g \"*.(pem|key)\"" \ "($help)--tlsverify[Use TLS and verify the remote]" \ "($help)--userns-remap=[User/Group setting for user namespaces]:user\:group:->users-groups" \ "($help)--userland-proxy[Use userland proxy for loopback traffic]" && ret=0 @@ -810,7 +863,8 @@ __docker_subcommand() { (load) _arguments $(__docker_arguments) \ $opts_help \ - "($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))(-.)"" && ret=0 + "($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))(-.)\"" \ + "($help -q --quiet)"{-q,--quiet}"[Suppress the load output]" && ret=0 ;; (login) _arguments $(__docker_arguments) \ @@ -866,7 +920,7 @@ __docker_subcommand() { $opts_help \ "($help -a --all)"{-a,--all}"[Show all containers]" \ "($help)--before=[Show only container created before...]:containers:__docker_containers" \ - "($help)*"{-f=,--filter=}"[Filter values]:filter: " \ + "($help)*"{-f=,--filter=}"[Filter values]:filter:->filter-options" \ "($help)--format[Pretty-print containers using a Go template]:format: " \ "($help -l --latest)"{-l,--latest}"[Show only the latest created container]" \ "($help)-n[Show n last created containers, include non-running one]:n:(1 5 10 25 50)" \ @@ -874,16 +928,24 @@ __docker_subcommand() { "($help -q --quiet)"{-q,--quiet}"[Only show numeric IDs]" \ "($help -s --size)"{-s,--size}"[Display total file sizes]" \ "($help)--since=[Show only containers created since...]:containers:__docker_containers" && ret=0 + + case $state in + (filter-options) + __docker_complete_ps_filters && ret=0 + ;; + esac ;; (pull) _arguments $(__docker_arguments) \ $opts_help \ "($help -a --all-tags)"{-a,--all-tags}"[Download all tagged images]" \ + "($help)--disable-content-trust[Skip image verification]" \ "($help -):name:__docker_search" && ret=0 ;; (push) _arguments $(__docker_arguments) \ $opts_help \ + "($help)--disable-content-trust[Skip image signing]" \ "($help -): :__docker_images" && ret=0 ;; (rename)