From f4e6a2688495d5249fefdf17f7fbc766ea8fdc45 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sun, 11 Feb 2024 11:07:51 +0900 Subject: [PATCH 1/3] completions: Add docker completion files from the upstream --- completions/fallback/docker-compose.bash | 676 +++ completions/fallback/docker.bash | 5603 ++++++++++++++++++++++ 2 files changed, 6279 insertions(+) create mode 100644 completions/fallback/docker-compose.bash create mode 100644 completions/fallback/docker.bash diff --git a/completions/fallback/docker-compose.bash b/completions/fallback/docker-compose.bash new file mode 100644 index 000000000..c3b6157d3 --- /dev/null +++ b/completions/fallback/docker-compose.bash @@ -0,0 +1,676 @@ +#!/bin/bash +# +# bash completion for docker-compose +# +# This work is based on the completion for the docker command. +# +# This script provides completion of: +# - commands and their options +# - service names +# - filepaths +# +# To enable the completions either: +# - place this file in /etc/bash_completion.d +# or +# - copy this file to e.g. ~/.docker-compose-completion.sh and add the line +# below to your .bashrc after bash completion features are loaded +# . ~/.docker-compose-completion.sh + +__docker_compose_previous_extglob_setting=$(shopt -p extglob) +shopt -s extglob + +__docker_compose_q() { + docker-compose 2>/dev/null "${top_level_options[@]}" "$@" +} + +# Transforms a multiline list of strings into a single line string +# with the words separated by "|". +__docker_compose_to_alternatives() { + local parts=( $1 ) + local IFS='|' + echo "${parts[*]}" +} + +# Transforms a multiline list of options into an extglob pattern +# suitable for use in case statements. +__docker_compose_to_extglob() { + local extglob=$( __docker_compose_to_alternatives "$1" ) + echo "@($extglob)" +} + +# Determines whether the option passed as the first argument exist on +# the commandline. The option may be a pattern, e.g. `--force|-f`. +__docker_compose_has_option() { + local pattern="$1" + for (( i=2; i < $cword; ++i)); do + if [[ ${words[$i]} =~ ^($pattern)$ ]] ; then + return 0 + fi + done + return 1 +} + +# Returns `key` if we are currently completing the value of a map option (`key=value`) +# which matches the extglob passed in as an argument. +# This function is needed for key-specific completions. +__docker_compose_map_key_of_current_option() { + local glob="$1" + + local key glob_pos + if [ "$cur" = "=" ] ; then # key= case + key="$prev" + glob_pos=$((cword - 2)) + elif [[ $cur == *=* ]] ; then # key=value case (OSX) + key=${cur%=*} + glob_pos=$((cword - 1)) + elif [ "$prev" = "=" ] ; then + key=${words[$cword - 2]} # key=value case + glob_pos=$((cword - 3)) + else + return + fi + + [ "${words[$glob_pos]}" = "=" ] && ((glob_pos--)) # --option=key=value syntax + + [[ ${words[$glob_pos]} == @($glob) ]] && echo "$key" +} + +# suppress trailing whitespace +__docker_compose_nospace() { + # compopt is not available in ancient bash versions + type compopt &>/dev/null && compopt -o nospace +} + + +# Outputs a list of all defined services, regardless of their running state. +# Arguments for `docker-compose ps` may be passed in order to filter the service list, +# e.g. `status=running`. +__docker_compose_services() { + __docker_compose_q ps --services "$@" +} + +# Applies completion of services based on the current value of `$cur`. +# Arguments for `docker-compose ps` may be passed in order to filter the service list, +# see `__docker_compose_services`. +__docker_compose_complete_services() { + COMPREPLY=( $(compgen -W "$(__docker_compose_services "$@")" -- "$cur") ) +} + +# The services for which at least one running container exists +__docker_compose_complete_running_services() { + local names=$(__docker_compose_services --filter status=running) + COMPREPLY=( $(compgen -W "$names" -- "$cur") ) +} + + +_docker_compose_build() { + case "$prev" in + --build-arg) + COMPREPLY=( $( compgen -e -- "$cur" ) ) + __docker_compose_nospace + return + ;; + --memory|-m) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--build-arg --compress --force-rm --help --memory -m --no-cache --no-rm --pull --parallel -q --quiet" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services --filter source=build + ;; + esac +} + + +_docker_compose_config() { + case "$prev" in + --hash) + if [[ $cur == \\* ]] ; then + COMPREPLY=( '\*' ) + else + COMPREPLY=( $(compgen -W "$(__docker_compose_services) \\\* " -- "$cur") ) + fi + return + ;; + esac + + COMPREPLY=( $( compgen -W "--hash --help --no-interpolate --profiles --quiet -q --resolve-image-digests --services --volumes" -- "$cur" ) ) +} + + +_docker_compose_create() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--build --force-recreate --help --no-build --no-recreate" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services + ;; + esac +} + + +_docker_compose_docker_compose() { + case "$prev" in + --tlscacert|--tlscert|--tlskey) + _filedir + return + ;; + --file|-f) + _filedir "y?(a)ml" + return + ;; + --ansi) + COMPREPLY=( $( compgen -W "never always auto" -- "$cur" ) ) + return + ;; + --log-level) + COMPREPLY=( $( compgen -W "debug info warning error critical" -- "$cur" ) ) + return + ;; + --profile) + COMPREPLY=( $( compgen -W "$(__docker_compose_q config --profiles)" -- "$cur" ) ) + return + ;; + --project-directory) + _filedir -d + return + ;; + --env-file) + _filedir + return + ;; + $(__docker_compose_to_extglob "$daemon_options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$daemon_boolean_options $daemon_options_with_args $top_level_options_with_args --help -h --no-ansi --verbose --version -v" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) + ;; + esac +} + + +_docker_compose_down() { + case "$prev" in + --rmi) + COMPREPLY=( $( compgen -W "all local" -- "$cur" ) ) + return + ;; + --timeout|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --rmi --timeout -t --volumes -v --remove-orphans" -- "$cur" ) ) + ;; + esac +} + + +_docker_compose_events() { + case "$prev" in + --json) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --json" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services + ;; + esac +} + + +_docker_compose_exec() { + case "$prev" in + --index|--user|-u|--workdir|-w) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "-d --detach --help --index --privileged -T --user -u --workdir -w" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_running_services + ;; + esac +} + + +_docker_compose_help() { + COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) +} + +_docker_compose_images() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --quiet -q" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services + ;; + esac +} + +_docker_compose_kill() { + case "$prev" in + -s) + COMPREPLY=( $( compgen -W "SIGHUP SIGINT SIGKILL SIGUSR1 SIGUSR2" -- "$(echo $cur | tr '[:lower:]' '[:upper:]')" ) ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help -s" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_running_services + ;; + esac +} + + +_docker_compose_logs() { + case "$prev" in + --tail) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--follow -f --help --no-color --no-log-prefix --tail --timestamps -t" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services + ;; + esac +} + + +_docker_compose_pause() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_running_services + ;; + esac +} + + +_docker_compose_port() { + case "$prev" in + --protocol) + COMPREPLY=( $( compgen -W "tcp udp" -- "$cur" ) ) + return; + ;; + --index) + return; + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --index --protocol" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services + ;; + esac +} + + +_docker_compose_ps() { + local key=$(__docker_compose_map_key_of_current_option '--filter') + case "$key" in + source) + COMPREPLY=( $( compgen -W "build image" -- "${cur##*=}" ) ) + return + ;; + status) + COMPREPLY=( $( compgen -W "paused restarting running stopped" -- "${cur##*=}" ) ) + return + ;; + esac + + case "$prev" in + --filter) + COMPREPLY=( $( compgen -W "source status" -S "=" -- "$cur" ) ) + __docker_compose_nospace + return; + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --filter --help --quiet -q --services" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services + ;; + esac +} + + +_docker_compose_pull() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --ignore-pull-failures --include-deps --no-parallel --quiet -q" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services --filter source=image + ;; + esac +} + + +_docker_compose_push() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --ignore-push-failures" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services + ;; + esac +} + + +_docker_compose_restart() { + case "$prev" in + --timeout|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_running_services + ;; + esac +} + + +_docker_compose_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help --stop -s -v" -- "$cur" ) ) + ;; + *) + if __docker_compose_has_option "--stop|-s" ; then + __docker_compose_complete_services + else + __docker_compose_complete_services --filter status=stopped + fi + ;; + esac +} + + +_docker_compose_run() { + case "$prev" in + -e) + COMPREPLY=( $( compgen -e -- "$cur" ) ) + __docker_compose_nospace + return + ;; + --entrypoint|--label|-l|--name|--user|-u|--volume|-v|--workdir|-w) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--detach -d --entrypoint -e --help --label -l --name --no-deps --publish -p --rm --service-ports -T --use-aliases --user -u --volume -v --workdir -w" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services + ;; + esac +} + + +_docker_compose_scale() { + case "$prev" in + =) + COMPREPLY=("$cur") + return + ;; + --timeout|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $(compgen -S "=" -W "$(__docker_compose_services)" -- "$cur") ) + __docker_compose_nospace + ;; + esac +} + + +_docker_compose_start() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services --filter status=stopped + ;; + esac +} + + +_docker_compose_stop() { + case "$prev" in + --timeout|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_running_services + ;; + esac +} + + +_docker_compose_top() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_running_services + ;; + esac +} + + +_docker_compose_unpause() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services --filter status=paused + ;; + esac +} + + +_docker_compose_up() { + case "$prev" in + =) + COMPREPLY=("$cur") + return + ;; + --exit-code-from) + __docker_compose_complete_services + return + ;; + --scale) + COMPREPLY=( $(compgen -S "=" -W "$(__docker_compose_services)" -- "$cur") ) + __docker_compose_nospace + return + ;; + --timeout|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--abort-on-container-exit --always-recreate-deps --attach-dependencies --build -d --detach --exit-code-from --force-recreate --help --no-build --no-color --no-deps --no-log-prefix --no-recreate --no-start --renew-anon-volumes -V --remove-orphans --scale --timeout -t" -- "$cur" ) ) + ;; + *) + __docker_compose_complete_services + ;; + esac +} + + +_docker_compose_version() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--short" -- "$cur" ) ) + ;; + esac +} + + +_docker_compose() { + local previous_extglob_setting=$(shopt -p extglob) + shopt -s extglob + + local commands=( + build + config + create + down + events + exec + help + images + kill + logs + pause + port + ps + pull + push + restart + rm + run + scale + start + stop + top + unpause + up + version + ) + + # Options for the docker daemon that have to be passed to secondary calls to + # docker-compose executed by this script. + local daemon_boolean_options=" + --skip-hostname-check + --tls + --tlsverify + " + local daemon_options_with_args=" + --context -c + --env-file + --file -f + --host -H + --project-directory + --project-name -p + --tlscacert + --tlscert + --tlskey + " + + # These options require special treatment when searching the command. + local top_level_options_with_args=" + --ansi + --log-level + --profile + " + + COMPREPLY=() + local cur prev words cword + _get_comp_words_by_ref -n : cur prev words cword + + # search subcommand and invoke its handler. + # special treatment of some top-level options + local command='docker_compose' + local top_level_options=() + local counter=1 + + while [ $counter -lt $cword ]; do + case "${words[$counter]}" in + $(__docker_compose_to_extglob "$daemon_boolean_options") ) + local opt=${words[counter]} + top_level_options+=($opt) + ;; + $(__docker_compose_to_extglob "$daemon_options_with_args") ) + local opt=${words[counter]} + local arg=${words[++counter]} + top_level_options+=($opt $arg) + ;; + $(__docker_compose_to_extglob "$top_level_options_with_args") ) + (( counter++ )) + ;; + -*) + ;; + *) + command="${words[$counter]}" + break + ;; + esac + (( counter++ )) + done + + local completions_func=_docker_compose_${command//-/_} + declare -F $completions_func >/dev/null && $completions_func + + eval "$previous_extglob_setting" + return 0 +} + +eval "$__docker_compose_previous_extglob_setting" +unset __docker_compose_previous_extglob_setting + +complete -F _docker_compose docker-compose docker-compose.exe diff --git a/completions/fallback/docker.bash b/completions/fallback/docker.bash new file mode 100644 index 000000000..b8fa557cb --- /dev/null +++ b/completions/fallback/docker.bash @@ -0,0 +1,5603 @@ +#!/usr/bin/env bash +# shellcheck disable=SC2016,SC2119,SC2155,SC2206,SC2207,SC2254 +# +# Shellcheck ignore list: +# - SC2016: Expressions don't expand in single quotes, use double quotes for that. +# - SC2119: Use foo "$@" if function's $1 should mean script's $1. +# - SC2155: Declare and assign separately to avoid masking return values. +# - SC2206: Quote to prevent word splitting, or split robustly with mapfile or read -a. +# - SC2207: Prefer mapfile or read -a to split command output (or quote to avoid splitting). +# - SC2254: Quote expansions in case patterns to match literally rather than as a glob. +# +# You can find more details for each warning at the following page: +# https://github.com/koalaman/shellcheck/wiki/ +# +# bash completion file for core docker commands +# +# This script provides completion of: +# - commands and their options +# - container ids and names +# - image repos and tags +# - filepaths +# +# To enable the completions either: +# - place this file in /etc/bash_completion.d +# or +# - copy this file to e.g. ~/.docker-completion.sh and add the line +# below to your .bashrc after bash completion features are loaded +# . ~/.docker-completion.sh +# +# Configuration: +# +# For several commands, the amount of completions can be configured by +# setting environment variables. +# +# DOCKER_COMPLETION_SHOW_CONFIG_IDS +# DOCKER_COMPLETION_SHOW_CONTAINER_IDS +# DOCKER_COMPLETION_SHOW_NETWORK_IDS +# DOCKER_COMPLETION_SHOW_NODE_IDS +# DOCKER_COMPLETION_SHOW_PLUGIN_IDS +# DOCKER_COMPLETION_SHOW_SECRET_IDS +# DOCKER_COMPLETION_SHOW_SERVICE_IDS +# "no" - Show names only (default) +# "yes" - Show names and ids +# +# You can tailor completion for the "events", "history", "inspect", "run", +# "rmi" and "save" commands by settings the following environment +# variables: +# +# DOCKER_COMPLETION_SHOW_IMAGE_IDS +# "none" - Show names only (default) +# "non-intermediate" - Show names and ids, but omit intermediate image IDs +# "all" - Show names and ids, including intermediate image IDs +# +# DOCKER_COMPLETION_SHOW_TAGS +# "yes" - include tags in completion options (default) +# "no" - don't include tags in completion options + +# +# Note: +# Currently, the completions will not work if the docker daemon is not +# bound to the default communication port/socket +# If the docker daemon is using a unix socket for communication your user +# must have access to the socket for the completions to function correctly +# +# Note for developers: +# Please arrange options sorted alphabetically by long name with the short +# options immediately following their corresponding long form. +# This order should be applied to lists, alternatives and code blocks. + +__docker_previous_extglob_setting=$(shopt -p extglob) +shopt -s extglob + +__docker_q() { + docker ${host:+--host "$host"} ${config:+--config "$config"} ${context:+--context "$context"} 2>/dev/null "$@" +} + +# __docker_configs returns a list of configs. Additional options to +# `docker config ls` may be specified in order to filter the list, e.g. +# `__docker_configs --filter label=stage=production`. +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_CONFIG_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. +__docker_configs() { + local format + if [ "${1-}" = "--id" ] ; then + format='{{.ID}}' + shift + elif [ "${1-}" = "--name" ] ; then + format='{{.Name}}' + shift + elif [ "${DOCKER_COMPLETION_SHOW_CONFIG_IDS-}" = yes ] ; then + format='{{.ID}} {{.Name}}' + else + format='{{.Name}}' + fi + + __docker_q config ls --format "$format" "$@" +} + +# __docker_complete_configs applies completion of configs based on the current value +# of `$cur` or the value of the optional first option `--cur`, if given. +__docker_complete_configs() { + local current="$cur" + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_configs "$@")" -- "$current") ) +} + +# __docker_containers returns a list of containers. Additional options to +# `docker ps` may be specified in order to filter the list, e.g. +# `__docker_containers --filter status=running` +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_CONTAINER_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. +__docker_containers() { + local format + if [ "${1-}" = "--id" ] ; then + format='{{.ID}}' + shift + elif [ "${1-}" = "--name" ] ; then + format='{{.Names}}' + shift + elif [ "${DOCKER_COMPLETION_SHOW_CONTAINER_IDS-}" = yes ] ; then + format='{{.ID}} {{.Names}}' + else + format='{{.Names}}' + fi + __docker_q ps --format "$format" "$@" +} + +# __docker_complete_containers applies completion of containers based on the current +# value of `$cur` or the value of the optional first option `--cur`, if given. +# Additional filters may be appended, see `__docker_containers`. +__docker_complete_containers() { + local current="$cur" + if [ "${1-}" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_containers "$@")" -- "$current") ) +} + +__docker_complete_containers_all() { + __docker_complete_containers "$@" --all +} + +# shellcheck disable=SC2120 +__docker_complete_containers_removable() { + __docker_complete_containers "$@" --filter status=created --filter status=exited +} + +__docker_complete_containers_running() { + __docker_complete_containers "$@" --filter status=running +} + +# shellcheck disable=SC2120 +__docker_complete_containers_stoppable() { + __docker_complete_containers "$@" --filter status=running --filter status=paused +} + +# shellcheck disable=SC2120 +__docker_complete_containers_stopped() { + __docker_complete_containers "$@" --filter status=exited +} + +# shellcheck disable=SC2120 +__docker_complete_containers_unpauseable() { + __docker_complete_containers "$@" --filter status=paused +} + +__docker_complete_container_names() { + local containers=( $(__docker_q ps -aq --no-trunc) ) + local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") ) + names=( "${names[@]#/}" ) # trim off the leading "/" from the container names + COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") ) +} + +__docker_complete_container_ids() { + local containers=( $(__docker_q ps -aq) ) + COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") ) +} + +# __docker_contexts returns a list of contexts without the special "default" context. +# Completions may be added with `--add`, e.g. `--add default`. +__docker_contexts() { + local add=() + while true ; do + case "${1-}" in + --add) + add+=("$2") + shift 2 + ;; + *) + break + ;; + esac + done + __docker_q context ls -q + echo "${add[@]}" +} + +__docker_complete_contexts() { + local contexts=( $(__docker_contexts "$@") ) + COMPREPLY=( $(compgen -W "${contexts[*]}" -- "$cur") ) +} + + +# __docker_images returns a list of images. For each image, up to three representations +# can be generated: the repository (e.g. busybox), repository:tag (e.g. busybox:latest) +# and the ID (e.g. sha256:ee22cbbd4ea3dff63c86ba60c7691287c321e93adfc1009604eb1dde7ec88645). +# +# The optional arguments `--repo`, `--tag` and `--id` select the representations that +# may be returned. Whether or not a particular representation is actually returned +# depends on the user's customization through several environment variables: +# - image IDs are only shown if DOCKER_COMPLETION_SHOW_IMAGE_IDS=all|non-intermediate. +# - tags can be excluded by setting DOCKER_COMPLETION_SHOW_TAGS=no. +# - repositories are always shown. +# +# In cases where an exact image specification is needed, `--force-tag` can be used. +# It ignores DOCKER_COMPLETION_SHOW_TAGS and only lists valid repository:tag combinations, +# avoiding repository names that would default to a potentially missing default tag. +# +# Additional arguments to `docker image ls` may be specified in order to filter the list, +# e.g. `__docker_images --filter dangling=true`. +# +__docker_images() { + local repo_format='{{.Repository}}' + local tag_format='{{.Repository}}:{{.Tag}}' + local id_format='{{.ID}}' + local all + local format + + if [ "${DOCKER_COMPLETION_SHOW_IMAGE_IDS-}" = "all" ] ; then + all='--all' + fi + + while true ; do + case "${1-}" in + --repo) + format+="$repo_format\n" + shift + ;; + --tag) + if [ "${DOCKER_COMPLETION_SHOW_TAGS:-yes}" = "yes" ]; then + format+="$tag_format\n" + fi + shift + ;; + --id) + if [[ ${DOCKER_COMPLETION_SHOW_IMAGE_IDS-} =~ ^(all|non-intermediate)$ ]] ; then + format+="$id_format\n" + fi + shift + ;; + --force-tag) + # like `--tag` but ignores environment setting + format+="$tag_format\n" + shift + ;; + *) + break + ;; + esac + done + + __docker_q image ls --no-trunc --format "${format%\\n}" ${all-} "$@" | grep -v '$' +} + +# __docker_complete_images applies completion of images based on the current value of `$cur` or +# the value of the optional first option `--cur`, if given. +# See __docker_images for customization of the returned items. +__docker_complete_images() { + local current="$cur" + if [ "${1-}" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_images "$@")" -- "$current") ) + __ltrim_colon_completions "$current" +} + +# __docker_networks returns a list of all networks. Additional options to +# `docker network ls` may be specified in order to filter the list, e.g. +# `__docker_networks --filter type=custom` +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_NETWORK_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. +__docker_networks() { + local format + if [ "${1-}" = "--id" ] ; then + format='{{.ID}}' + shift + elif [ "${1-}" = "--name" ] ; then + format='{{.Name}}' + shift + elif [ "${DOCKER_COMPLETION_SHOW_NETWORK_IDS-}" = yes ] ; then + format='{{.ID}} {{.Name}}' + else + format='{{.Name}}' + fi + __docker_q network ls --format "$format" "$@" +} + +# __docker_complete_networks applies completion of networks based on the current +# value of `$cur` or the value of the optional first option `--cur`, if given. +# Additional filters may be appended, see `__docker_networks`. +__docker_complete_networks() { + local current="$cur" + if [ "${1-}" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_networks "$@")" -- "$current") ) +} + +__docker_complete_containers_in_network() { + local containers=($(__docker_q network inspect -f '{{range $i, $c := .Containers}}{{$i}} {{$c.Name}} {{end}}' "$1")) + COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") ) +} + +# __docker_volumes returns a list of all volumes. Additional options to +# `docker volume ls` may be specified in order to filter the list, e.g. +# `__docker_volumes --filter dangling=true` +# Because volumes do not have IDs, this function does not distinguish between +# IDs and names. +__docker_volumes() { + __docker_q volume ls -q "$@" +} + +# __docker_complete_volumes applies completion of volumes based on the current +# value of `$cur` or the value of the optional first option `--cur`, if given. +# Additional filters may be appended, see `__docker_volumes`. +__docker_complete_volumes() { + local current="$cur" + if [ "${1-}" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_volumes "$@")" -- "$current") ) +} + +# __docker_plugins_bundled returns a list of all plugins of a given type. +# The type has to be specified with the mandatory option `--type`. +# Valid types are: Network, Volume, Authorization. +# Completions may be added or removed with `--add` and `--remove` +# This function only deals with plugins that come bundled with Docker. +# For plugins managed by `docker plugin`, see `__docker_plugins_installed`. +__docker_plugins_bundled() { + local type add=() remove=() + while true ; do + case "${1-}" in + --type) + type="$2" + shift 2 + ;; + --add) + add+=("$2") + shift 2 + ;; + --remove) + remove+=("$2") + shift 2 + ;; + *) + break + ;; + esac + done + + local plugins=($(__docker_q info --format "{{range \$i, \$p := .Plugins.$type}}{{.}} {{end}}")) + for del in "${remove[@]}" ; do + plugins=(${plugins[@]/$del/}) + done + echo "${plugins[@]}" "${add[@]}" +} + +# __docker_complete_plugins_bundled applies completion of plugins based on the current +# value of `$cur` or the value of the optional first option `--cur`, if given. +# The plugin type has to be specified with the next option `--type`. +# This function only deals with plugins that come bundled with Docker. +# For completion of plugins managed by `docker plugin`, see +# `__docker_complete_plugins_installed`. +__docker_complete_plugins_bundled() { + local current="$cur" + if [ "${1-}" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_plugins_bundled "$@")" -- "$current") ) +} + +# __docker_plugins_installed returns a list of all plugins that were installed with +# the Docker plugin API. +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_PLUGIN_IDS=yes to also complete IDs. +# Additional options to `docker plugin ls` may be specified in order to filter the list, +# e.g. `__docker_plugins_installed --filter enabled=true` +# For built-in pugins, see `__docker_plugins_bundled`. +__docker_plugins_installed() { + local format + if [ "${DOCKER_COMPLETION_SHOW_PLUGIN_IDS-}" = yes ] ; then + format='{{.ID}} {{.Name}}' + else + format='{{.Name}}' + fi + __docker_q plugin ls --format "$format" "$@" +} + +# __docker_complete_plugins_installed applies completion of plugins that were installed +# with the Docker plugin API, based on the current value of `$cur` or the value of +# the optional first option `--cur`, if given. +# Additional filters may be appended, see `__docker_plugins_installed`. +# For completion of built-in pugins, see `__docker_complete_plugins_bundled`. +__docker_complete_plugins_installed() { + local current="$cur" + if [ "${1-}" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_plugins_installed "$@")" -- "$current") ) +} + +__docker_runtimes() { + __docker_q info | sed -n 's/^Runtimes: \(.*\)/\1/p' +} + +__docker_complete_runtimes() { + COMPREPLY=( $(compgen -W "$(__docker_runtimes)" -- "$cur") ) +} + +# __docker_secrets returns a list of secrets. Additional options to +# `docker secret ls` may be specified in order to filter the list, e.g. +# `__docker_secrets --filter label=stage=production` +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_SECRET_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. +__docker_secrets() { + local format + if [ "${1-}" = "--id" ] ; then + format='{{.ID}}' + shift + elif [ "${1-}" = "--name" ] ; then + format='{{.Name}}' + shift + elif [ "${DOCKER_COMPLETION_SHOW_SECRET_IDS-}" = yes ] ; then + format='{{.ID}} {{.Name}}' + else + format='{{.Name}}' + fi + + __docker_q secret ls --format "$format" "$@" +} + +# __docker_complete_secrets applies completion of secrets based on the current value +# of `$cur` or the value of the optional first option `--cur`, if given. +__docker_complete_secrets() { + local current="$cur" + if [ "${1-}" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_secrets "$@")" -- "$current") ) +} + +# __docker_stacks returns a list of all stacks. +__docker_stacks() { + __docker_q stack ls | awk 'NR>1 {print $1}' +} + +# __docker_complete_stacks applies completion of stacks based on the current value +# of `$cur` or the value of the optional first option `--cur`, if given. +__docker_complete_stacks() { + local current="$cur" + if [ "${1-}" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_stacks "$@")" -- "$current") ) +} + +# __docker_nodes returns a list of all nodes. Additional options to +# `docker node ls` may be specified in order to filter the list, e.g. +# `__docker_nodes --filter role=manager` +# By default, only node names are returned. +# Set DOCKER_COMPLETION_SHOW_NODE_IDS=yes to also complete node IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. +# Completions may be added with `--add`, e.g. `--add self`. +__docker_nodes() { + local format + if [ "${DOCKER_COMPLETION_SHOW_NODE_IDS-}" = yes ] ; then + format='{{.ID}} {{.Hostname}}' + else + format='{{.Hostname}}' + fi + + local add=() + + while true ; do + case "${1-}" in + --id) + format='{{.ID}}' + shift + ;; + --name) + format='{{.Hostname}}' + shift + ;; + --add) + add+=("$2") + shift 2 + ;; + *) + break + ;; + esac + done + + echo "$(__docker_q node ls --format "$format" "$@")" "${add[@]}" +} + +# __docker_complete_nodes applies completion of nodes based on the current +# value of `$cur` or the value of the optional first option `--cur`, if given. +# Additional filters may be appended, see `__docker_nodes`. +__docker_complete_nodes() { + local current="$cur" + if [ "${1-}" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_nodes "$@")" -- "$current") ) +} + +# __docker_services returns a list of all services. Additional options to +# `docker service ls` may be specified in order to filter the list, e.g. +# `__docker_services --filter name=xxx` +# By default, only node names are returned. +# Set DOCKER_COMPLETION_SHOW_SERVICE_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. +__docker_services() { + local format='{{.Name}}' # default: service name only + [ "${DOCKER_COMPLETION_SHOW_SERVICE_IDS-}" = yes ] && format='{{.ID}} {{.Name}}' # ID & name + + if [ "${1-}" = "--id" ] ; then + format='{{.ID}}' # IDs only + shift + elif [ "${1-}" = "--name" ] ; then + format='{{.Name}}' # names only + shift + fi + + __docker_q service ls --quiet --format "$format" "$@" +} + +# __docker_complete_services applies completion of services based on the current +# value of `$cur` or the value of the optional first option `--cur`, if given. +# Additional filters may be appended, see `__docker_services`. +__docker_complete_services() { + local current="$cur" + if [ "${1-}" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(__docker_services "$@" --filter "name=$current") ) +} + +# __docker_tasks returns a list of all task IDs. +__docker_tasks() { + __docker_q service ps --format '{{.ID}}' "" +} + +# __docker_complete_services_and_tasks applies completion of services and task IDs. +# shellcheck disable=SC2120 +__docker_complete_services_and_tasks() { + COMPREPLY=( $(compgen -W "$(__docker_services "$@") $(__docker_tasks)" -- "$cur") ) +} + +# __docker_append_to_completions appends the word passed as an argument to every +# word in `$COMPREPLY`. +# Normally you do this with `compgen -S` while generating the completions. +# This function allows you to append a suffix later. It allows you to use +# the __docker_complete_XXX functions in cases where you need a suffix. +__docker_append_to_completions() { + COMPREPLY=( ${COMPREPLY[@]/%/"$1"} ) +} + +# __docker_fetch_info fetches information about the configured Docker server and updates +# several variables with the results. +# The result is cached for the duration of one invocation of bash completion. +__docker_fetch_info() { + if [ -z "${info_fetched-}" ] ; then + read -r server_experimental server_os <<< "$(__docker_q version -f '{{.Server.Experimental}} {{.Server.Os}}')" + info_fetched=true + fi +} + +# __docker_server_is_experimental tests whether the currently configured Docker +# server runs in experimental mode. If so, the function exits with 0 (true). +# Otherwise, or if the result cannot be determined, the exit value is 1 (false). +__docker_server_is_experimental() { + __docker_fetch_info + [ "$server_experimental" = "true" ] +} + +# __docker_server_os_is tests whether the currently configured Docker server runs +# on the operating system passed in as the first argument. +# Known operating systems: linux, windows. +__docker_server_os_is() { + local expected_os="$1" + __docker_fetch_info + [ "$server_os" = "$expected_os" ] +} + +# __docker_pos_first_nonflag finds the position of the first word that is neither +# option nor an option's argument. If there are options that require arguments, +# you should pass a glob describing those options, e.g. "--option1|-o|--option2" +# Use this function to restrict completions to exact positions after the argument list. +__docker_pos_first_nonflag() { + local argument_flags=${1-} + + local counter=$((${subcommand_pos:-${command_pos}} + 1)) + while [ "$counter" -le "$cword" ]; do + if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then + (( counter++ )) + # eat "=" in case of --option=arg syntax + [ "${words[$counter]}" = "=" ] && (( counter++ )) + else + case "${words[$counter]}" in + -*) + ;; + *) + break + ;; + esac + fi + + # Bash splits words at "=", retaining "=" as a word, examples: + # "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words + while [ "${words[$counter + 1]}" = "=" ] ; do + counter=$(( counter + 2)) + done + + (( counter++ )) + done + + echo "$counter" +} + +# __docker_map_key_of_current_option returns `key` if we are currently completing the +# value of a map option (`key=value`) which matches the extglob given as an argument. +# This function is needed for key-specific completions. +__docker_map_key_of_current_option() { + local glob="$1" + + local key glob_pos + if [ "$cur" = "=" ] ; then # key= case + key="$prev" + glob_pos=$((cword - 2)) + elif [[ $cur == *=* ]] ; then # key=value case (OSX) + key=${cur%=*} + glob_pos=$((cword - 1)) + elif [ "$prev" = "=" ] ; then + key=${words[$cword - 2]} # key=value case + glob_pos=$((cword - 3)) + else + return + fi + + [ "${words[$glob_pos]}" = "=" ] && ((glob_pos--)) # --option=key=value syntax + + [[ ${words[$glob_pos]} == @($glob) ]] && echo "$key" +} + +# __docker_value_of_option returns the value of the first option matching `option_glob`. +# Valid values for `option_glob` are option names like `--log-level` and globs like +# `--log-level|-l` +# Only positions between the command and the current word are considered. +__docker_value_of_option() { + local option_extglob=$(__docker_to_extglob "$1") + + local counter=$((command_pos + 1)) + while [ "$counter" -lt "$cword" ]; do + case ${words[$counter]} in + $option_extglob ) + echo "${words[$counter + 1]}" + break + ;; + esac + (( counter++ )) + done +} + +# __docker_to_alternatives transforms a multiline list of strings into a single line +# string with the words separated by `|`. +# This is used to prepare arguments to __docker_pos_first_nonflag(). +__docker_to_alternatives() { + local parts=( $1 ) + local IFS='|' + echo "${parts[*]}" +} + +# __docker_to_extglob transforms a multiline list of options into an extglob pattern +# suitable for use in case statements. +__docker_to_extglob() { + local extglob=$( __docker_to_alternatives "$1" ) + echo "@($extglob)" +} + +# __docker_subcommands processes subcommands +# Locates the first occurrence of any of the subcommands contained in the +# first argument. In case of a match, calls the corresponding completion +# function and returns 0. +# If no match is found, 1 is returned. The calling function can then +# continue processing its completion. +# +# TODO if the preceding command has options that accept arguments and an +# argument is equal ot one of the subcommands, this is falsely detected as +# a match. +__docker_subcommands() { + local subcommands="$1" + + local counter=$((command_pos + 1)) + while [ "$counter" -lt "$cword" ]; do + case "${words[$counter]}" in + $(__docker_to_extglob "$subcommands") ) + subcommand_pos=$counter + local subcommand=${words[$counter]} + local completions_func=_docker_${command}_${subcommand//-/_} + declare -F "$completions_func" >/dev/null && "$completions_func" + return 0 + ;; + esac + (( counter++ )) + done + return 1 +} + +# __docker_nospace suppresses trailing whitespace +__docker_nospace() { + # compopt is not available in ancient bash versions + type compopt &>/dev/null && compopt -o nospace +} + +__docker_complete_resolved_hostname() { + command -v host >/dev/null 2>&1 || return + COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') ) +} + +# __docker_local_interfaces returns a list of the names and addresses of all +# local network interfaces. +# If `--ip-only` is passed as a first argument, only addresses are returned. +__docker_local_interfaces() { + command -v ip >/dev/null 2>&1 || return + + local format + if [ "${1-}" = "--ip-only" ] ; then + format='\1' + shift + else + format='\1 \2' + fi + + ip addr show scope global 2>/dev/null | sed -n "s| \+inet \([0-9.]\+\).* \([^ ]\+\)|$format|p" +} + +# __docker_complete_local_interfaces applies completion of the names and addresses of all +# local network interfaces based on the current value of `$cur`. +# An additional value can be added to the possible completions with an `--add` argument. +__docker_complete_local_interfaces() { + local additional_interface + if [ "${1-}" = "--add" ] ; then + additional_interface="$2" + shift 2 + fi + + COMPREPLY=( $( compgen -W "$(__docker_local_interfaces "$@") $additional_interface" -- "$cur" ) ) +} + +# __docker_complete_local_ips applies completion of the addresses of all local network +# interfaces based on the current value of `$cur`. +__docker_complete_local_ips() { + __docker_complete_local_interfaces --ip-only +} + +# __docker_complete_capabilities_addable completes Linux capabilities which are +# not granted by default and may be added. +# see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities +__docker_complete_capabilities_addable() { + local capabilities=( + ALL + CAP_AUDIT_CONTROL + CAP_AUDIT_READ + CAP_BLOCK_SUSPEND + CAP_BPF + CAP_CHECKPOINT_RESTORE + CAP_DAC_READ_SEARCH + CAP_IPC_LOCK + CAP_IPC_OWNER + CAP_LEASE + CAP_LINUX_IMMUTABLE + CAP_MAC_ADMIN + CAP_MAC_OVERRIDE + CAP_NET_ADMIN + CAP_NET_BROADCAST + CAP_PERFMON + CAP_SYS_ADMIN + CAP_SYS_BOOT + CAP_SYSLOG + CAP_SYS_MODULE + CAP_SYS_NICE + CAP_SYS_PACCT + CAP_SYS_PTRACE + CAP_SYS_RAWIO + CAP_SYS_RESOURCE + CAP_SYS_TIME + CAP_SYS_TTY_CONFIG + CAP_WAKE_ALARM + RESET + ) + COMPREPLY=( $( compgen -W "${capabilities[*]} ${capabilities[*]#CAP_}" -- "$cur" ) ) +} + +# __docker_complete_capabilities_droppable completes Linux capability options which are +# allowed by default and can be dropped. +# see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities +__docker_complete_capabilities_droppable() { + local capabilities=( + ALL + CAP_AUDIT_WRITE + CAP_CHOWN + CAP_DAC_OVERRIDE + CAP_FOWNER + CAP_FSETID + CAP_KILL + CAP_MKNOD + CAP_NET_BIND_SERVICE + CAP_NET_RAW + CAP_SETFCAP + CAP_SETGID + CAP_SETPCAP + CAP_SETUID + CAP_SYS_CHROOT + RESET + ) + COMPREPLY=( $( compgen -W "${capabilities[*]} ${capabilities[*]#CAP_}" -- "$cur" ) ) +} + +__docker_complete_detach_keys() { + case "$prev" in + --detach-keys) + case "$cur" in + *,) + COMPREPLY=( $( compgen -W "${cur}ctrl-" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "ctrl-" -- "$cur" ) ) + ;; + esac + + __docker_nospace + return + ;; + esac + return 1 +} + +__docker_complete_isolation() { + COMPREPLY=( $( compgen -W "default hyperv process" -- "$cur" ) ) +} + +__docker_complete_log_drivers() { + COMPREPLY=( $( compgen -W " + awslogs + etwlogs + fluentd + gcplogs + gelf + journald + json-file + local + none + splunk + syslog + " -- "$cur" ) ) +} + +__docker_complete_log_options() { + # see https://docs.docker.com/config/containers/logging/configure/ + + # really global options, defined in https://github.com/moby/moby/blob/master/daemon/logger/factory.go + local common_options1="max-buffer-size mode" + # common options defined in https://github.com/moby/moby/blob/master/daemon/logger/loginfo.go + # but not implemented in all log drivers + local common_options2="env env-regex labels" + + # awslogs does not implement the $common_options2. + local awslogs_options="$common_options1 awslogs-create-group awslogs-credentials-endpoint awslogs-datetime-format awslogs-group awslogs-multiline-pattern awslogs-region awslogs-stream tag" + + local fluentd_options="$common_options1 $common_options2 fluentd-address fluentd-async fluentd-buffer-limit fluentd-request-ack fluentd-retry-wait fluentd-max-retries fluentd-sub-second-precision tag" + local gcplogs_options="$common_options1 $common_options2 gcp-log-cmd gcp-meta-id gcp-meta-name gcp-meta-zone gcp-project" + local gelf_options="$common_options1 $common_options2 gelf-address gelf-compression-level gelf-compression-type gelf-tcp-max-reconnect gelf-tcp-reconnect-delay tag" + local journald_options="$common_options1 $common_options2 tag" + local json_file_options="$common_options1 $common_options2 compress max-file max-size" + local local_options="$common_options1 compress max-file max-size" + local splunk_options="$common_options1 $common_options2 splunk-caname splunk-capath splunk-format splunk-gzip splunk-gzip-level splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url splunk-verify-connection tag" + local syslog_options="$common_options1 $common_options2 syslog-address syslog-facility syslog-format syslog-tls-ca-cert syslog-tls-cert syslog-tls-key syslog-tls-skip-verify tag" + + local all_options="$fluentd_options $gcplogs_options $gelf_options $journald_options $json_file_options $syslog_options $splunk_options" + + case $(__docker_value_of_option --log-driver) in + '') + COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) ) + ;; + awslogs) + COMPREPLY=( $( compgen -W "$awslogs_options" -S = -- "$cur" ) ) + ;; + fluentd) + COMPREPLY=( $( compgen -W "$fluentd_options" -S = -- "$cur" ) ) + ;; + gcplogs) + COMPREPLY=( $( compgen -W "$gcplogs_options" -S = -- "$cur" ) ) + ;; + gelf) + COMPREPLY=( $( compgen -W "$gelf_options" -S = -- "$cur" ) ) + ;; + journald) + COMPREPLY=( $( compgen -W "$journald_options" -S = -- "$cur" ) ) + ;; + json-file) + COMPREPLY=( $( compgen -W "$json_file_options" -S = -- "$cur" ) ) + ;; + local) + COMPREPLY=( $( compgen -W "$local_options" -S = -- "$cur" ) ) + ;; + syslog) + COMPREPLY=( $( compgen -W "$syslog_options" -S = -- "$cur" ) ) + ;; + splunk) + COMPREPLY=( $( compgen -W "$splunk_options" -S = -- "$cur" ) ) + ;; + *) + return + ;; + esac + + __docker_nospace +} + +__docker_complete_log_driver_options() { + local key=$(__docker_map_key_of_current_option '--log-opt') + case "$key" in + awslogs-create-group) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + awslogs-credentials-endpoint) + COMPREPLY=( $( compgen -W "/" -- "${cur##*=}" ) ) + __docker_nospace + return + ;; + compress|fluentd-async-connect) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + fluentd-sub-second-precision) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + gelf-address) + COMPREPLY=( $( compgen -W "tcp udp" -S "://" -- "${cur##*=}" ) ) + __docker_nospace + return + ;; + gelf-compression-level) + COMPREPLY=( $( compgen -W "1 2 3 4 5 6 7 8 9" -- "${cur##*=}" ) ) + return + ;; + gelf-compression-type) + COMPREPLY=( $( compgen -W "gzip none zlib" -- "${cur##*=}" ) ) + return + ;; + line-only) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + mode) + COMPREPLY=( $( compgen -W "blocking non-blocking" -- "${cur##*=}" ) ) + return + ;; + syslog-address) + COMPREPLY=( $( compgen -W "tcp:// tcp+tls:// udp:// unix://" -- "${cur##*=}" ) ) + __docker_nospace + __ltrim_colon_completions "${cur}" + return + ;; + syslog-facility) + COMPREPLY=( $( compgen -W " + auth + authpriv + cron + daemon + ftp + kern + local0 + local1 + local2 + local3 + local4 + local5 + local6 + local7 + lpr + mail + news + syslog + user + uucp + " -- "${cur##*=}" ) ) + return + ;; + syslog-format) + COMPREPLY=( $( compgen -W "rfc3164 rfc5424 rfc5424micro" -- "${cur##*=}" ) ) + return + ;; + syslog-tls-ca-cert|syslog-tls-cert|syslog-tls-key) + _filedir + return + ;; + syslog-tls-skip-verify) + COMPREPLY=( $( compgen -W "true" -- "${cur##*=}" ) ) + return + ;; + splunk-url) + COMPREPLY=( $( compgen -W "http:// https://" -- "${cur##*=}" ) ) + __docker_nospace + __ltrim_colon_completions "${cur}" + return + ;; + splunk-gzip|splunk-insecureskipverify|splunk-verify-connection) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + splunk-format) + COMPREPLY=( $( compgen -W "inline json raw" -- "${cur##*=}" ) ) + return + ;; + esac + return 1 +} + +__docker_complete_log_levels() { + COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) ) +} + +__docker_complete_restart() { + case "$prev" in + --restart) + case "$cur" in + on-failure:*) + ;; + *) + COMPREPLY=( $( compgen -W "always no on-failure on-failure: unless-stopped" -- "$cur") ) + ;; + esac + return + ;; + esac + return 1 +} + +# __docker_complete_signals returns a subset of the available signals that is most likely +# relevant in the context of docker containers +__docker_complete_signals() { + local signals=( + SIGCONT + SIGHUP + SIGINT + SIGKILL + SIGQUIT + SIGSTOP + SIGTERM + SIGUSR1 + SIGUSR2 + ) + COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo "$cur" | tr '[:lower:]' '[:upper:]')" ) ) +} + +__docker_complete_ulimits() { + local limits=" + as + chroot + core + cpu + data + fsize + locks + maxlogins + maxsyslogins + memlock + msgqueue + nice + nofile + nproc + priority + rss + rtprio + sigpending + stack + " + if [ "${1-}" = "--rm" ] ; then + COMPREPLY=( $( compgen -W "$limits" -- "$cur" ) ) + else + COMPREPLY=( $( compgen -W "$limits" -S = -- "$cur" ) ) + __docker_nospace + fi +} + +__docker_complete_user_group() { + if [[ $cur == *:* ]] ; then + COMPREPLY=( $(compgen -g -- "${cur#*:}") ) + else + COMPREPLY=( $(compgen -u -S : -- "$cur") ) + __docker_nospace + fi +} + +__docker_plugins_path() { + local docker_plugins_path=$(docker info --format '{{range .ClientInfo.Plugins}}{{.Path}}:{{end}}') + echo "${docker_plugins_path//:/ }" +} + +__docker_complete_plugin() { + local path=$1 + local completionCommand="__completeNoDesc" + local resultArray=($path $completionCommand) + for value in "${words[@]:2}"; do + if [ -z "$value" ]; then + resultArray+=( "''" ) + else + resultArray+=( "$value" ) + fi + done + local rawResult=$(eval "${resultArray[*]}" 2> /dev/null) + local result=$(grep -v '^:[0-9]*$' <<< "$rawResult") + + # Compose V2 completions sometimes returns returns `:8` (ShellCompDirectiveFilterFileExt) + # with the expected file extensions (such as `yml`, `yaml`) to indicate that the shell should + # provide autocompletions for files with matching extensions + local completionFlag=$(tail -1 <<< "$rawResult") + if [ "$completionFlag" == ":8" ]; then + # format a valid glob pattern for the provided file extensions + local filePattern=$(tr '\n' '|' <<< "$result") + + _filedir "$filePattern" + return + fi + + # if result empty, just use filename completion as fallback + if [ -z "$result" ]; then + _filedir + else + COMPREPLY=( $(compgen -W "${result}" -- "${current-}") ) + fi +} + +_docker_docker() { + # global options that may appear after the docker command + local boolean_options=" + $global_boolean_options + --help + --version -v + " + + case "$prev" in + --config) + _filedir -d + return + ;; + --context|-c) + __docker_complete_contexts + return + ;; + --log-level|-l) + __docker_complete_log_levels + return + ;; + $(__docker_to_extglob "$global_options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$boolean_options $global_options_with_args" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag "$(__docker_to_extglob "$global_options_with_args")" ) + if [ "$cword" -eq "$counter" ]; then + __docker_server_is_experimental && commands+=(${experimental_server_commands[*]}) + COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) ) + fi + ;; + esac +} + +_docker_attach() { + _docker_container_attach +} + +_docker_build() { + _docker_image_build +} + + +_docker_builder() { + local subcommands=" + build + prune + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_builder_build() { + _docker_image_build +} + +_docker_builder_prune() { + case "$prev" in + --filter) + COMPREPLY=( $( compgen -S = -W "description id inuse parent private shared type until unused-for" -- "$cur" ) ) + __docker_nospace + return + ;; + --keep-storage) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --filter --force -f --help --keep-storage" -- "$cur" ) ) + ;; + esac +} + +_docker_checkpoint() { + local subcommands=" + create + ls + rm + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_checkpoint_create() { + case "$prev" in + --checkpoint-dir) + _filedir -d + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--checkpoint-dir --help --leave-running" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--checkpoint-dir') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_running + fi + ;; + esac +} + +_docker_checkpoint_ls() { + case "$prev" in + --checkpoint-dir) + _filedir -d + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--checkpoint-dir --help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--checkpoint-dir') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_all + fi + ;; + esac +} + +_docker_checkpoint_rm() { + case "$prev" in + --checkpoint-dir) + _filedir -d + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--checkpoint-dir --help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--checkpoint-dir') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_all + elif [ "$cword" -eq "$((counter + 1))" ]; then + COMPREPLY=( $( compgen -W "$(__docker_q checkpoint ls "$prev" | sed 1d)" -- "$cur" ) ) + fi + ;; + esac +} + + +_docker_config() { + local subcommands=" + create + inspect + ls + rm + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_config_create() { + case "$prev" in + --label|-l) + return + ;; + --template-driver) + COMPREPLY=( $( compgen -W "golang" -- "$cur" ) ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --label -l --template-driver" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--label|-l|--template-driver') + if [ "$cword" -eq "$((counter + 1))" ]; then + _filedir + fi + ;; + esac +} + +_docker_config_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) + ;; + *) + __docker_complete_configs + ;; + esac +} + +_docker_config_list() { + _docker_config_ls +} + +_docker_config_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + __docker_complete_configs --cur "${cur##*=}" --id + return + ;; + name) + __docker_complete_configs --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format --filter -f --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_config_remove() { + _docker_config_rm +} + +_docker_config_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_configs + ;; + esac +} + + +_docker_container() { + local subcommands=" + attach + commit + cp + create + diff + exec + export + inspect + kill + logs + ls + pause + port + prune + rename + restart + rm + run + start + stats + stop + top + unpause + update + wait + " + local aliases=" + list + ps + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_container_attach() { + __docker_complete_detach_keys && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy=false" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--detach-keys') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_running + fi + ;; + esac +} + +_docker_container_commit() { + case "$prev" in + --author|-a|--change|-c|--message|-m) + return + ;; + esac + + case "$cur" in + -*) + 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') + + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_all + return + elif [ "$cword" -eq "$((counter + 1))" ]; then + __docker_complete_images --repo --tag + return + fi + ;; + esac +} + +_docker_container_cp() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--archive -a --follow-link -L --help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + case "$cur" in + *:) + return + ;; + *) + # combined container and filename completion + _filedir + local files=( ${COMPREPLY[@]} ) + + __docker_complete_containers_all + COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) + local containers=( ${COMPREPLY[@]} ) + + COMPREPLY=( $( compgen -W "${files[*]} ${containers[*]}" -- "$cur" ) ) + if [[ "${COMPREPLY[*]}" = *: ]]; then + __docker_nospace + fi + return + ;; + esac + fi + (( counter++ )) + + if [ "$cword" -eq "$counter" ]; then + if [ -e "$prev" ]; then + __docker_complete_containers_all + COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) + __docker_nospace + else + _filedir + fi + return + fi + ;; + esac +} + +_docker_container_create() { + _docker_container_run_and_create +} + +_docker_container_diff() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_all + fi + ;; + esac +} + +_docker_container_exec() { + __docker_complete_detach_keys && return + + case "$prev" in + --env|-e) + # we do not append a "=" here because "-e VARNAME" is legal syntax, too + COMPREPLY=( $( compgen -e -- "$cur" ) ) + __docker_nospace + return + ;; + --env-file) + _filedir + return + ;; + --user|-u) + __docker_complete_user_group + return + ;; + --workdir|-w) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--detach -d --detach-keys --env -e --env-file --help --interactive -i --privileged -t --tty -u --user --workdir -w" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_running + ;; + esac +} + +_docker_container_export() { + case "$prev" in + --output|-o) + _filedir + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_all + fi + ;; + esac +} + +_docker_container_inspect() { + _docker_inspect --type container +} + +_docker_container_kill() { + case "$prev" in + --signal|-s) + __docker_complete_signals + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --signal -s" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_running + ;; + esac +} + +_docker_container_logs() { + case "$prev" in + --since|--tail|-n|--until) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--details --follow -f --help --since --tail -n --timestamps -t --until" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--since|--tail|-n|--until') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_all + fi + ;; + esac +} + +_docker_container_list() { + _docker_container_ls +} + +_docker_container_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + ancestor) + __docker_complete_images --cur "${cur##*=}" --repo --tag --id + return + ;; + before) + __docker_complete_containers_all --cur "${cur##*=}" + return + ;; + expose|publish) + return + ;; + id) + __docker_complete_containers_all --cur "${cur##*=}" --id + return + ;; + health) + COMPREPLY=( $( compgen -W "healthy starting none unhealthy" -- "${cur##*=}" ) ) + return + ;; + is-task) + COMPREPLY=( $( compgen -W "true false" -- "${cur##*=}" ) ) + return + ;; + name) + __docker_complete_containers_all --cur "${cur##*=}" --name + return + ;; + network) + __docker_complete_networks --cur "${cur##*=}" + return + ;; + since) + __docker_complete_containers_all --cur "${cur##*=}" + return + ;; + status) + COMPREPLY=( $( compgen -W "created dead exited paused restarting running removing" -- "${cur##*=}" ) ) + return + ;; + volume) + __docker_complete_volumes --cur "${cur##*=}" + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "ancestor before exited expose health id is-task label name network publish since status volume" -- "$cur" ) ) + __docker_nospace + return + ;; + --format|--last|-n) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --filter -f --format --help --last -n --latest -l --no-trunc --quiet -q --size -s" -- "$cur" ) ) + ;; + esac +} + +_docker_container_pause() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_running + ;; + esac +} + +_docker_container_port() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_all + fi + ;; + esac +} + +_docker_container_prune() { + case "$prev" in + --filter) + COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --filter --help" -- "$cur" ) ) + ;; + esac +} + +_docker_container_ps() { + _docker_container_ls +} + +_docker_container_rename() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_all + fi + ;; + esac +} + +_docker_container_restart() { + case "$prev" in + --time|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_all + ;; + esac +} + +_docker_container_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help --link -l --volumes -v" -- "$cur" ) ) + ;; + *) + for arg in "${COMP_WORDS[@]}"; do + case "$arg" in + --force|-f) + __docker_complete_containers_all + return + ;; + esac + done + __docker_complete_containers_removable + ;; + esac +} + +_docker_container_run() { + _docker_container_run_and_create +} + +# _docker_container_run_and_create is the combined completion for `_docker_container_run` +# and `_docker_container_create` +_docker_container_run_and_create() { + local options_with_args=" + --add-host + --annotation + --attach -a + --blkio-weight + --blkio-weight-device + --cap-add + --cap-drop + --cgroupns + --cgroup-parent + --cidfile + --cpu-period + --cpu-quota + --cpu-rt-period + --cpu-rt-runtime + --cpuset-cpus + --cpus + --cpuset-mems + --cpu-shares -c + --device + --device-cgroup-rule + --device-read-bps + --device-read-iops + --device-write-bps + --device-write-iops + --dns + --dns-option + --dns-search + --domainname + --entrypoint + --env -e + --env-file + --expose + --gpus + --group-add + --health-cmd + --health-interval + --health-retries + --health-start-period + --health-timeout + --hostname -h + --ip + --ip6 + --ipc + --kernel-memory + --label-file + --label -l + --link + --link-local-ip + --log-driver + --log-opt + --mac-address + --memory -m + --memory-swap + --memory-swappiness + --memory-reservation + --mount + --name + --network + --network-alias + --oom-score-adj + --pid + --pids-limit + --platform + --publish -p + --pull + --restart + --runtime + --security-opt + --shm-size + --stop-signal + --stop-timeout + --storage-opt + --tmpfs + --sysctl + --ulimit + --user -u + --userns + --uts + --volume-driver + --volumes-from + --volume -v + --workdir -w + " + __docker_server_os_is windows && options_with_args+=" + --cpu-count + --cpu-percent + --io-maxbandwidth + --io-maxiops + --isolation + " + + local boolean_options=" + --disable-content-trust=false + --help + --init + --interactive -i + --no-healthcheck + --oom-kill-disable + --privileged + --publish-all -P + --quiet -q + --read-only + --tty -t + " + + if [ "$command" = "run" ] || [ "$subcommand" = "run" ] ; then + options_with_args="$options_with_args + --detach-keys + " + boolean_options="$boolean_options + --detach -d + --rm + --sig-proxy=false + " + __docker_complete_detach_keys && return + fi + + local all_options="$options_with_args $boolean_options" + + + __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 + *:) + __docker_complete_resolved_hostname + return + ;; + esac + ;; + --attach|-a) + COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) ) + return + ;; + --cap-add) + __docker_complete_capabilities_addable + return + ;; + --cap-drop) + __docker_complete_capabilities_droppable + return + ;; + --cidfile|--env-file|--label-file) + _filedir + return + ;; + --cgroupns) + COMPREPLY=( $( compgen -W "host private" -- "$cur" ) ) + return + ;; + --device|--tmpfs|--volume|-v) + case "$cur" in + *:*) + # TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine) + ;; + '') + COMPREPLY=( $( compgen -W '/' -- "$cur" ) ) + __docker_nospace + ;; + /*) + _filedir + __docker_nospace + ;; + esac + return + ;; + --env|-e) + # we do not append a "=" here because "-e VARNAME" is legal syntax, too + COMPREPLY=( $( compgen -e -- "$cur" ) ) + __docker_nospace + return + ;; + --ipc) + case "$cur" in + *:*) + cur="${cur#*:}" + __docker_complete_containers_running + ;; + *) + COMPREPLY=( $( compgen -W 'none host private shareable container:' -- "$cur" ) ) + if [ "${COMPREPLY[*]}" = "container:" ]; then + __docker_nospace + fi + ;; + esac + return + ;; + --isolation) + if __docker_server_os_is windows ; then + __docker_complete_isolation + return + fi + ;; + --link) + case "$cur" in + *:*) + ;; + *) + __docker_complete_containers_running + COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) + __docker_nospace + ;; + esac + return + ;; + --log-driver) + __docker_complete_log_drivers + return + ;; + --log-opt) + __docker_complete_log_options + return + ;; + --network) + case "$cur" in + container:*) + __docker_complete_containers_all --cur "${cur#*:}" + ;; + *) + COMPREPLY=( $( compgen -W "$(__docker_plugins_bundled --type Network) $(__docker_networks) container:" -- "$cur") ) + if [ "${COMPREPLY[*]}" = "container:" ] ; then + __docker_nospace + fi + ;; + esac + return + ;; + --pid) + case "$cur" in + *:*) + __docker_complete_containers_running --cur "${cur#*:}" + ;; + *) + COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) + if [ "${COMPREPLY[*]}" = "container:" ]; then + __docker_nospace + fi + ;; + esac + return + ;; + --pull) + COMPREPLY=( $( compgen -W 'always missing never' -- "$cur" ) ) + return + ;; + --runtime) + __docker_complete_runtimes + return + ;; + --security-opt) + COMPREPLY=( $( compgen -W "apparmor= label= no-new-privileges seccomp= systempaths=unconfined" -- "$cur") ) + if [[ ${COMPREPLY[*]} = *= ]] ; then + __docker_nospace + fi + return + ;; + --stop-signal) + __docker_complete_signals + return + ;; + --storage-opt) + COMPREPLY=( $( compgen -W "size" -S = -- "$cur") ) + __docker_nospace + return + ;; + --ulimit) + __docker_complete_ulimits + return + ;; + --user|-u) + __docker_complete_user_group + return + ;; + --userns) + COMPREPLY=( $( compgen -W "host" -- "$cur" ) ) + return + ;; + --volume-driver) + __docker_complete_plugins_bundled --type Volume + return + ;; + --volumes-from) + __docker_complete_containers_all + return + ;; + $(__docker_to_extglob "$options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images --repo --tag --id + fi + ;; + esac +} + +_docker_container_start() { + __docker_complete_detach_keys && return + case "$prev" in + --checkpoint) + if __docker_server_is_experimental ; then + return + fi + ;; + --checkpoint-dir) + if __docker_server_is_experimental ; then + _filedir -d + return + fi + ;; + esac + + case "$cur" in + -*) + local options="--attach -a --detach-keys --help --interactive -i" + __docker_server_is_experimental && options+=" --checkpoint --checkpoint-dir" + COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_stopped + ;; + esac +} + +_docker_container_stats() { + case "$prev" in + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --format --help --no-stream --no-trunc" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_running + ;; + esac +} + +_docker_container_stop() { + case "$prev" in + --time|-t) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_stoppable + ;; + esac +} + +_docker_container_top() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_running + fi + ;; + esac +} + +_docker_container_unpause() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_containers_unpauseable + fi + ;; + esac +} + +_docker_container_update() { + local options_with_args=" + --blkio-weight + --cpu-period + --cpu-quota + --cpu-rt-period + --cpu-rt-runtime + --cpus + --cpuset-cpus + --cpuset-mems + --cpu-shares -c + --kernel-memory + --memory -m + --memory-reservation + --memory-swap + --pids-limit + --restart + " + + local boolean_options=" + --help + " + + local all_options="$options_with_args $boolean_options" + + __docker_complete_restart && return + + case "$prev" in + $(__docker_to_extglob "$options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_all + ;; + esac +} + +_docker_container_wait() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_containers_all + ;; + esac +} + + +_docker_context() { + local subcommands=" + create + export + import + inspect + ls + rm + update + use + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_context_create() { + case "$prev" in + --description|--docker) + return + ;; + --from) + __docker_complete_contexts + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--description --docker --from --help" -- "$cur" ) ) + ;; + esac +} + +_docker_context_export() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_contexts + elif [ "$cword" -eq "$((counter + 1))" ]; then + _filedir + fi + ;; + esac +} + +_docker_context_import() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + : + elif [ "$cword" -eq "$((counter + 1))" ]; then + _filedir + fi + ;; + esac +} + +_docker_context_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) + ;; + *) + __docker_complete_contexts + ;; + esac +} + +_docker_context_list() { + _docker_context_ls +} + +_docker_context_ls() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_context_remove() { + _docker_context_rm +} + +_docker_context_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) + ;; + *) + __docker_complete_contexts + ;; + esac +} + +_docker_context_update() { + case "$prev" in + --description|--docker) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--description --docker --help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_contexts + fi + ;; + esac +} + +_docker_context_use() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_contexts --add default + fi + ;; + esac +} + + +_docker_commit() { + _docker_container_commit +} + +_docker_cp() { + _docker_container_cp +} + +_docker_create() { + _docker_container_create +} + +_docker_daemon() { + local boolean_options=" + $global_boolean_options + --experimental + --help + --icc=false + --init + --ip-forward=false + --ip-masq=false + --iptables=false + --ip6tables + --ipv6 + --live-restore + --no-new-privileges + --raw-logs + --selinux-enabled + --userland-proxy=false + --validate + --version -v + " + local options_with_args=" + $global_options_with_args + --add-runtime + --allow-nondistributable-artifacts + --api-cors-header + --authorization-plugin + --bip + --bridge -b + --cgroup-parent + --config-file + --containerd + --containerd-namespace + --containerd-plugins-namespace + --cpu-rt-period + --cpu-rt-runtime + --data-root + --default-address-pool + --default-gateway + --default-gateway-v6 + --default-runtime + --default-shm-size + --default-ulimit + --dns + --dns-search + --dns-opt + --exec-opt + --exec-root + --fixed-cidr + --fixed-cidr-v6 + --group -G + --init-path + --insecure-registry + --ip + --label + --log-driver + --log-opt + --max-concurrent-downloads + --max-concurrent-uploads + --max-download-attempts + --metrics-addr + --mtu + --network-control-plane-mtu + --node-generic-resource + --oom-score-adjust + --pidfile -p + --registry-mirror + --seccomp-profile + --shutdown-timeout + --storage-driver -s + --storage-opt + --swarm-default-advertise-addr + --userland-proxy-path + --userns-remap + " + + __docker_complete_log_driver_options && return + + local key=$(__docker_map_key_of_current_option '--storage-opt') + case "$key" in + dm.blkdiscard|dm.override_udev_sync_check|dm.use_deferred_removal|dm.use_deferred_deletion) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + dm.directlvm_device|dm.thinpooldev) + cur=${cur##*=} + _filedir + return + ;; + dm.fs) + COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur##*=}" ) ) + return + ;; + dm.libdm_log_level) + COMPREPLY=( $( compgen -W "2 3 4 5 6 7" -- "${cur##*=}" ) ) + return + ;; + esac + + case "$prev" in + --authorization-plugin) + __docker_complete_plugins_bundled --type Authorization + return + ;; + --config-file|--containerd|--init-path|--pidfile|-p|--tlscacert|--tlscert|--tlskey|--userland-proxy-path) + _filedir + return + ;; + --default-ulimit) + __docker_complete_ulimits + return + ;; + --exec-root|--data-root) + _filedir -d + return + ;; + --log-driver) + __docker_complete_log_drivers + return + ;; + --storage-driver|-s) + COMPREPLY=( $( compgen -W "btrfs overlay2 vfs zfs" -- "$(echo "$cur" | tr '[:upper:]' '[:lower:]')" ) ) + return + ;; + --storage-opt) + local btrfs_options="btrfs.min_space" + local overlay2_options="overlay2.size" + local zfs_options="zfs.fsname" + + local all_options="$btrfs_options $overlay2_options $zfs_options" + + case $(__docker_value_of_option '--storage-driver|-s') in + '') + COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) ) + ;; + btrfs) + COMPREPLY=( $( compgen -W "$btrfs_options" -S = -- "$cur" ) ) + ;; + overlay2) + COMPREPLY=( $( compgen -W "$overlay2_options" -S = -- "$cur" ) ) + ;; + zfs) + COMPREPLY=( $( compgen -W "$zfs_options" -S = -- "$cur" ) ) + ;; + *) + return + ;; + esac + __docker_nospace + return + ;; + --log-level|-l) + __docker_complete_log_levels + return + ;; + --log-opt) + __docker_complete_log_options + return + ;; + --metrics-addr) + __docker_complete_local_ips + __docker_append_to_completions ":" + __docker_nospace + return + ;; + --seccomp-profile) + _filedir json + return + ;; + --swarm-default-advertise-addr) + __docker_complete_local_interfaces + return + ;; + --userns-remap) + __docker_complete_user_group + return + ;; + $(__docker_to_extglob "$options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) + ;; + esac +} + +_docker_diff() { + _docker_container_diff +} + + +_docker_events() { + _docker_system_events +} + +_docker_exec() { + _docker_container_exec +} + +_docker_export() { + _docker_container_export +} + +_docker_help() { + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) + fi +} + +_docker_history() { + _docker_image_history +} + + +_docker_image() { + local subcommands=" + build + history + import + inspect + load + ls + prune + pull + push + rm + save + tag + " + local aliases=" + images + list + remove + rmi + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_image_build() { + local options_with_args=" + --add-host + --build-arg + --cache-from + --cgroup-parent + --cpuset-cpus + --cpuset-mems + --cpu-shares -c + --cpu-period + --cpu-quota + --file -f + --iidfile + --label + --memory -m + --memory-swap + --network + --platform + --shm-size + --tag -t + --target + --ulimit + " + __docker_server_os_is windows && options_with_args+=" + --isolation + " + + local boolean_options=" + --disable-content-trust=false + --force-rm + --help + --no-cache + --pull + --quiet -q + --rm + " + + if __docker_server_is_experimental ; then + boolean_options+=" + --squash + " + fi + + if [ "${DOCKER_BUILDKIT-}" = "1" ] ; then + options_with_args+=" + --output -o + --progress + --secret + --ssh + " + else + boolean_options+=" + --compress + " + fi + + local all_options="$options_with_args $boolean_options" + + case "$prev" in + --add-host) + case "$cur" in + *:) + __docker_complete_resolved_hostname + return + ;; + esac + ;; + --build-arg) + COMPREPLY=( $( compgen -e -- "$cur" ) ) + __docker_nospace + return + ;; + --cache-from) + __docker_complete_images --repo --tag --id + return + ;; + --file|-f|--iidfile) + _filedir + return + ;; + --isolation) + if __docker_server_os_is windows ; then + __docker_complete_isolation + return + fi + ;; + --network) + case "$cur" in + container:*) + __docker_complete_containers_all --cur "${cur#*:}" + ;; + *) + COMPREPLY=( $( compgen -W "$(__docker_plugins_bundled --type Network) $(__docker_networks) container:" -- "$cur") ) + if [ "${COMPREPLY[*]}" = "container:" ] ; then + __docker_nospace + fi + ;; + esac + return + ;; + --progress) + COMPREPLY=( $( compgen -W "auto plain tty" -- "$cur" ) ) + return + ;; + --tag|-t) + __docker_complete_images --repo --tag + return + ;; + --target) + local context_pos=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) + local context="${words[$context_pos]}" + context="${context:-.}" + + local file="$( __docker_value_of_option '--file|f' )" + local default_file="${context%/}/Dockerfile" + local dockerfile="${file:-$default_file}" + + local targets="$( sed -n 's/^FROM .\+ AS \(.\+\)/\1/p' "$dockerfile" 2>/dev/null )" + COMPREPLY=( $( compgen -W "$targets" -- "$cur" ) ) + return + ;; + --ulimit) + __docker_complete_ulimits + return + ;; + $(__docker_to_extglob "$options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) + if [ "$cword" -eq "$counter" ]; then + _filedir -d + fi + ;; + esac +} + +_docker_image_history() { + case "$prev" in + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format --help --human=false -H=false --no-trunc --quiet -q" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--format') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images --force-tag --id + fi + ;; + esac +} + +_docker_image_images() { + _docker_image_ls +} + +_docker_image_import() { + case "$prev" in + --change|-c|--message|-m|--platform) + return + ;; + esac + + case "$cur" in + -*) + local options="--change -c --help --message -m --platform" + COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--change|-c|--message|-m') + if [ "$cword" -eq "$counter" ]; then + _filedir + return + elif [ "$cword" -eq "$((counter + 1))" ]; then + __docker_complete_images --repo --tag + return + fi + ;; + esac +} + +_docker_image_inspect() { + _docker_inspect --type image +} + +_docker_image_load() { + case "$prev" in + --input|-i|"<") + _filedir + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --input -i --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_image_list() { + _docker_image_ls +} + +_docker_image_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + before|since) + __docker_complete_images --cur "${cur##*=}" --force-tag --id + return + ;; + dangling) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + label) + return + ;; + reference) + __docker_complete_images --cur "${cur##*=}" --repo --tag + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "before dangling label reference since" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --digests --filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) + ;; + =) + return + ;; + *) + __docker_complete_images --repo --tag + ;; + esac +} + +_docker_image_prune() { + case "$prev" in + --filter) + COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --force -f --filter --help" -- "$cur" ) ) + ;; + esac +} + +_docker_image_pull() { + case "$prev" in + --platform) + return + ;; + esac + + case "$cur" in + -*) + local options="--all-tags -a --disable-content-trust=false --help --platform --quiet -q" + COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag --platform) + if [ "$cword" -eq "$counter" ]; then + for arg in "${COMP_WORDS[@]}"; do + case "$arg" in + --all-tags|-a) + __docker_complete_images --repo + return + ;; + esac + done + __docker_complete_images --repo --tag + fi + ;; + esac +} + +_docker_image_push() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all-tags -a --disable-content-trust=false --help --quiet -q" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images --repo --tag + fi + ;; + esac +} + +_docker_image_remove() { + _docker_image_rm +} + +_docker_image_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help --no-prune" -- "$cur" ) ) + ;; + *) + __docker_complete_images --force-tag --id + ;; + esac +} + +_docker_image_rmi() { + _docker_image_rm +} + +_docker_image_save() { + case "$prev" in + --output|-o|">") + _filedir + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) ) + ;; + *) + __docker_complete_images --repo --tag --id + ;; + esac +} + +_docker_image_tag() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images --force-tag --id + return + elif [ "$cword" -eq "$((counter + 1))" ]; then + __docker_complete_images --repo --tag + return + fi + ;; + esac +} + + +_docker_images() { + _docker_image_ls +} + +_docker_import() { + _docker_image_import +} + +_docker_info() { + _docker_system_info +} + +_docker_inspect() { + local preselected_type + local type + + if [ "${1-}" = "--type" ] ; then + preselected_type=yes + type="$2" + else + type=$(__docker_value_of_option --type) + fi + + case "$prev" in + --format|-f) + return + ;; + --type) + if [ -z "$preselected_type" ] ; then + COMPREPLY=( $( compgen -W "container image network node plugin secret service volume" -- "$cur" ) ) + return + fi + ;; + esac + + case "$cur" in + -*) + local options="--format -f --help --size -s" + if [ -z "$preselected_type" ] ; then + options+=" --type" + fi + COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) + ;; + *) + case "$type" in + '') + COMPREPLY=( $( compgen -W " + $(__docker_containers --all) + $(__docker_images --force-tag --id) + $(__docker_networks) + $(__docker_nodes) + $(__docker_plugins_installed) + $(__docker_secrets) + $(__docker_services) + $(__docker_volumes) + " -- "$cur" ) ) + __ltrim_colon_completions "$cur" + ;; + container) + __docker_complete_containers_all + ;; + image) + __docker_complete_images --force-tag --id + ;; + network) + __docker_complete_networks + ;; + node) + __docker_complete_nodes + ;; + plugin) + __docker_complete_plugins_installed + ;; + secret) + __docker_complete_secrets + ;; + service) + __docker_complete_services + ;; + volume) + __docker_complete_volumes + ;; + esac + esac +} + +_docker_kill() { + _docker_container_kill +} + +_docker_load() { + _docker_image_load +} + +_docker_login() { + case "$prev" in + --password|-p|--username|-u) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --password -p --password-stdin --username -u" -- "$cur" ) ) + ;; + esac +} + +_docker_logout() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + esac +} + +_docker_logs() { + _docker_container_logs +} + +_docker_network_connect() { + local options_with_args=" + --alias + --ip + --ip6 + --link + --link-local-ip + " + + local boolean_options=" + --help + " + + case "$prev" in + --link) + case "$cur" in + *:*) + ;; + *) + __docker_complete_containers_running + COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) + __docker_nospace + ;; + esac + return + ;; + $(__docker_to_extglob "$options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_networks + elif [ "$cword" -eq "$((counter + 1))" ]; then + __docker_complete_containers_all + fi + ;; + esac +} + +_docker_network_create() { + case "$prev" in + --aux-address|--gateway|--ip-range|--ipam-opt|--ipv6|--opt|-o|--subnet) + return + ;; + --config-from) + __docker_complete_networks + return + ;; + --driver|-d) + # remove drivers that allow one instance only, add drivers missing in `docker info` + __docker_complete_plugins_bundled --type Network --remove host --remove null --add macvlan + return + ;; + --ipam-driver) + COMPREPLY=( $( compgen -W "default" -- "$cur" ) ) + return + ;; + --label) + return + ;; + --scope) + COMPREPLY=( $( compgen -W "local swarm" -- "$cur" ) ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--attachable --aux-address --config-from --config-only --driver -d --gateway --help --ingress --internal --ip-range --ipam-driver --ipam-opt --ipv6 --label --opt -o --scope --subnet" -- "$cur" ) ) + ;; + esac +} + +_docker_network_disconnect() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_networks + elif [ "$cword" -eq "$((counter + 1))" ]; then + __docker_complete_containers_in_network "$prev" + fi + ;; + esac +} + +_docker_network_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --verbose" -- "$cur" ) ) + ;; + *) + __docker_complete_networks + esac +} + +_docker_network_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + dangling) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + driver) + __docker_complete_plugins_bundled --cur "${cur##*=}" --type Network --add macvlan + return + ;; + id) + __docker_complete_networks --cur "${cur##*=}" --id + return + ;; + name) + __docker_complete_networks --cur "${cur##*=}" --name + return + ;; + scope) + COMPREPLY=( $( compgen -W "global local swarm" -- "${cur##*=}" ) ) + return + ;; + type) + COMPREPLY=( $( compgen -W "builtin custom" -- "${cur##*=}" ) ) + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "dangling driver id label name scope type" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_network_prune() { + case "$prev" in + --filter) + COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --filter --help" -- "$cur" ) ) + ;; + esac +} + +_docker_network_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) + ;; + *) + __docker_complete_networks --filter type=custom + esac +} + +_docker_network() { + local subcommands=" + connect + create + disconnect + inspect + ls + prune + rm + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_service() { + local subcommands=" + create + inspect + logs + ls + rm + rollback + scale + ps + update + " + + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_service_create() { + _docker_service_update_and_create +} + +_docker_service_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) + ;; + *) + __docker_complete_services + esac +} + +_docker_service_logs() { + case "$prev" in + --since|--tail|-n) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--details --follow -f --help --no-resolve --no-task-ids --no-trunc --raw --since --tail -n --timestamps -t" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--since|--tail|-n') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_services_and_tasks + fi + ;; + esac +} + +_docker_service_list() { + _docker_service_ls +} + +_docker_service_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + __docker_complete_services --cur "${cur##*=}" --id + return + ;; + mode) + COMPREPLY=( $( compgen -W "global global-job replicated replicated-job" -- "${cur##*=}" ) ) + return + ;; + name) + __docker_complete_services --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "id label mode name" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_service_remove() { + _docker_service_rm +} + +_docker_service_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_services + esac +} + +_docker_service_rollback() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--detach -d --help --quit -q" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag ) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_services + fi + ;; + esac +} + +_docker_service_scale() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--detach -d --help" -- "$cur" ) ) + ;; + *) + __docker_complete_services + __docker_append_to_completions "=" + __docker_nospace + ;; + esac +} + +_docker_service_ps() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + desired-state) + COMPREPLY=( $( compgen -W "accepted running shutdown" -- "${cur##*=}" ) ) + return + ;; + name) + __docker_complete_services --cur "${cur##*=}" --name + return + ;; + node) + __docker_complete_nodes --cur "${cur##*=}" --add self + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "desired-state id name node" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --no-resolve --no-trunc --quiet -q" -- "$cur" ) ) + ;; + *) + __docker_complete_services + ;; + esac +} + +_docker_service_update() { + _docker_service_update_and_create +} + +# _docker_service_update_and_create is the combined completion for `docker service create` +# and `docker service update` +_docker_service_update_and_create() { + local options_with_args=" + --cap-add + --cap-drop + --endpoint-mode + --entrypoint + --health-cmd + --health-interval + --health-retries + --health-start-period + --health-timeout + --hostname + --isolation + --limit-cpu + --limit-memory + --limit-pids + --log-driver + --log-opt + --max-replicas + --replicas + --replicas-max-per-node + --reserve-cpu + --reserve-memory + --restart-condition + --restart-delay + --restart-max-attempts + --restart-window + --rollback-delay + --rollback-failure-action + --rollback-max-failure-ratio + --rollback-monitor + --rollback-order + --rollback-parallelism + --stop-grace-period + --stop-signal + --update-delay + --update-failure-action + --update-max-failure-ratio + --update-monitor + --update-order + --update-parallelism + --user -u + --workdir -w + " + __docker_server_os_is windows && options_with_args+=" + --credential-spec + " + + local boolean_options=" + --detach -d + --help + --init + --no-healthcheck + --no-resolve-image + --read-only + --tty -t + --with-registry-auth + " + + __docker_complete_log_driver_options && return + + if [ "$subcommand" = "create" ] ; then + options_with_args="$options_with_args + --config + --constraint + --container-label + --dns + --dns-option + --dns-search + --env -e + --env-file + --generic-resource + --group + --host + --label -l + --mode + --mount + --name + --network + --placement-pref + --publish -p + --secret + --sysctl + --ulimit + " + + case "$prev" in + --env-file) + _filedir + return + ;; + --mode) + COMPREPLY=( $( compgen -W "global global-job replicated replicated-job" -- "$cur" ) ) + return + ;; + esac + fi + if [ "$subcommand" = "update" ] ; then + options_with_args="$options_with_args + --args + --config-add + --config-rm + --constraint-add + --constraint-rm + --container-label-add + --container-label-rm + --dns-add + --dns-option-add + --dns-option-rm + --dns-rm + --dns-search-add + --dns-search-rm + --env-add + --env-rm + --generic-resource-add + --generic-resource-rm + --group-add + --group-rm + --host-add + --host-rm + --image + --label-add + --label-rm + --mount-add + --mount-rm + --network-add + --network-rm + --placement-pref-add + --placement-pref-rm + --publish-add + --publish-rm + --rollback + --secret-add + --secret-rm + --sysctl-add + --sysctl-rm + --ulimit-add + --ulimit-rm + " + + boolean_options="$boolean_options + --force + " + + case "$prev" in + --env-rm) + COMPREPLY=( $( compgen -e -- "$cur" ) ) + return + ;; + --image) + __docker_complete_images --repo --tag --id + return + ;; + esac + fi + + local strategy=$(__docker_map_key_of_current_option '--placement-pref|--placement-pref-add|--placement-pref-rm') + case "$strategy" in + spread) + COMPREPLY=( $( compgen -W "engine.labels node.labels" -S . -- "${cur##*=}" ) ) + __docker_nospace + return + ;; + esac + + case "$prev" in + --cap-add) + __docker_complete_capabilities_addable + return + ;; + --cap-drop) + __docker_complete_capabilities_droppable + return + ;; + --config|--config-add|--config-rm) + __docker_complete_configs + return + ;; + --endpoint-mode) + COMPREPLY=( $( compgen -W "dnsrr vip" -- "$cur" ) ) + return + ;; + --env|-e|--env-add) + # we do not append a "=" here because "-e VARNAME" is legal systax, too + COMPREPLY=( $( compgen -e -- "$cur" ) ) + __docker_nospace + return + ;; + --group|--group-add|--group-rm) + COMPREPLY=( $(compgen -g -- "$cur") ) + return + ;; + --host|--host-add|--host-rm) + case "$cur" in + *:) + __docker_complete_resolved_hostname + return + ;; + esac + ;; + --isolation) + __docker_complete_isolation + return + ;; + --log-driver) + __docker_complete_log_drivers + return + ;; + --log-opt) + __docker_complete_log_options + return + ;; + --network|--network-add|--network-rm) + __docker_complete_networks + return + ;; + --placement-pref|--placement-pref-add|--placement-pref-rm) + COMPREPLY=( $( compgen -W "spread" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --restart-condition) + COMPREPLY=( $( compgen -W "any none on-failure" -- "$cur" ) ) + return + ;; + --rollback-failure-action) + COMPREPLY=( $( compgen -W "continue pause" -- "$cur" ) ) + return + ;; + --secret|--secret-add|--secret-rm) + __docker_complete_secrets + return + ;; + --stop-signal) + __docker_complete_signals + return + ;; + --update-failure-action) + COMPREPLY=( $( compgen -W "continue pause rollback" -- "$cur" ) ) + return + ;; + --ulimit|--ulimit-add) + __docker_complete_ulimits + return + ;; + --ulimit-rm) + __docker_complete_ulimits --rm + return + ;; + --update-order|--rollback-order) + COMPREPLY=( $( compgen -W "start-first stop-first" -- "$cur" ) ) + return + ;; + --user|-u) + __docker_complete_user_group + return + ;; + $(__docker_to_extglob "$options_with_args") ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) + if [ "$subcommand" = "update" ] ; then + if [ "$cword" -eq "$counter" ]; then + __docker_complete_services + fi + else + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images --repo --tag --id + fi + fi + ;; + esac +} + +_docker_swarm() { + local subcommands=" + ca + init + join + join-token + leave + unlock + unlock-key + update + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_ca() { + case "$prev" in + --ca-cert|--ca-key) + _filedir + return + ;; + --cert-expiry|--external-ca) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--ca-cert --ca-key --cert-expiry --detach -d --external-ca --help --quiet -q --rotate" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_init() { + case "$prev" in + --advertise-addr) + if [[ $cur == *: ]] ; then + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + else + __docker_complete_local_interfaces + __docker_nospace + fi + return + ;; + --availability) + COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) ) + return + ;; + --cert-expiry|--data-path-port|--default-addr-pool|--default-addr-pool-mask-length|--dispatcher-heartbeat|--external-ca|--max-snapshots|--snapshot-interval|--task-history-limit ) + return + ;; + --data-path-addr) + __docker_complete_local_interfaces + return + ;; + --listen-addr) + if [[ $cur == *: ]] ; then + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + else + __docker_complete_local_interfaces --add 0.0.0.0 + __docker_nospace + fi + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--advertise-addr --autolock --availability --cert-expiry --data-path-addr --data-path-port --default-addr-pool --default-addr-pool-mask-length --dispatcher-heartbeat --external-ca --force-new-cluster --help --listen-addr --max-snapshots --snapshot-interval --task-history-limit " -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_join() { + case "$prev" in + --advertise-addr) + if [[ $cur == *: ]] ; then + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + else + __docker_complete_local_interfaces + __docker_nospace + fi + return + ;; + --availability) + COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) ) + return + ;; + --data-path-addr) + __docker_complete_local_interfaces + return + ;; + --listen-addr) + if [[ $cur == *: ]] ; then + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + else + __docker_complete_local_interfaces --add 0.0.0.0 + __docker_nospace + fi + return + ;; + --token) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--advertise-addr --availability --data-path-addr --help --listen-addr --token" -- "$cur" ) ) + ;; + *:) + COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) + ;; + esac +} + +_docker_swarm_join_token() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag ) + if [ "$cword" -eq "$counter" ]; then + COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) ) + fi + ;; + esac +} + +_docker_swarm_leave() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_unlock() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_unlock_key() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) ) + ;; + esac +} + +_docker_swarm_update() { + case "$prev" in + --cert-expiry|--dispatcher-heartbeat|--external-ca|--max-snapshots|--snapshot-interval|--task-history-limit) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--autolock --cert-expiry --dispatcher-heartbeat --external-ca --help --max-snapshots --snapshot-interval --task-history-limit" -- "$cur" ) ) + ;; + esac +} + +_docker_manifest() { + local subcommands=" + annotate + create + inspect + push + rm + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_manifest_annotate() { + case "$prev" in + --arch) + COMPREPLY=( $( compgen -W " + 386 + amd64 + arm + arm64 + mips64 + mips64le + ppc64le + riscv64 + s390x" -- "$cur" ) ) + return + ;; + --os) + COMPREPLY=( $( compgen -W " + darwin + dragonfly + freebsd + linux + netbsd + openbsd + plan9 + solaris + windows" -- "$cur" ) ) + return + ;; + --os-features|--variant) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--arch --help --os --os-features --variant" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag "--arch|--os|--os-features|--variant" ) + if [ "$cword" -eq "$counter" ] || [ "$cword" -eq "$((counter + 1))" ]; then + __docker_complete_images --force-tag --id + fi + ;; + esac +} + +_docker_manifest_create() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--amend -a --help --insecure" -- "$cur" ) ) + ;; + *) + __docker_complete_images --force-tag --id + ;; + esac +} + +_docker_manifest_inspect() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --insecure --verbose -v" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag ) + if [ "$cword" -eq "$counter" ] || [ "$cword" -eq "$((counter + 1))" ]; then + __docker_complete_images --force-tag --id + fi + ;; + esac +} + +_docker_manifest_push() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --insecure --purge -p" -- "$cur" ) ) + ;; + *) + local counter=$( __docker_pos_first_nonflag ) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images --force-tag --id + fi + ;; + esac +} + +_docker_manifest_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_images --force-tag --id + ;; + esac +} + +_docker_node() { + local subcommands=" + demote + inspect + ls + promote + rm + ps + update + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_node_demote() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes --filter role=manager + esac +} + +_docker_node_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes --add self + esac +} + +_docker_node_list() { + _docker_node_ls +} + +_docker_node_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + __docker_complete_nodes --cur "${cur##*=}" --id + return + ;; + label|node.label) + return + ;; + membership) + COMPREPLY=( $( compgen -W "accepted pending" -- "${cur##*=}" ) ) + return + ;; + name) + __docker_complete_nodes --cur "${cur##*=}" --name + return + ;; + role) + COMPREPLY=( $( compgen -W "manager worker" -- "${cur##*=}" ) ) + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "id label membership name node.label role" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_node_promote() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes --filter role=worker + esac +} + +_docker_node_remove() { + _docker_node_rm +} + +_docker_node_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes + esac +} + +_docker_node_ps() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + desired-state) + COMPREPLY=( $( compgen -W "accepted running shutdown" -- "${cur##*=}" ) ) + return + ;; + name) + __docker_complete_services --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -W "desired-state id label name" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --no-resolve --no-trunc --quiet -q" -- "$cur" ) ) + ;; + *) + __docker_complete_nodes --add self + ;; + esac +} + +_docker_node_update() { + case "$prev" in + --availability) + COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) ) + return + ;; + --role) + COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) ) + return + ;; + --label-add|--label-rm) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--availability --help --label-add --label-rm --role" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--availability|--label-add|--label-rm|--role') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_nodes + fi + ;; + esac +} + +_docker_pause() { + _docker_container_pause +} + +_docker_plugin() { + local subcommands=" + create + disable + enable + inspect + install + ls + push + rm + set + upgrade + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_plugin_create() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--compress --help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + # reponame + return + elif [ "$cword" -eq "$((counter + 1))" ]; then + _filedir -d + fi + ;; + esac +} + +_docker_plugin_disable() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_plugins_installed --filter enabled=true + fi + ;; + esac +} + +_docker_plugin_enable() { + case "$prev" in + --timeout) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --timeout" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--timeout') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_plugins_installed --filter enabled=false + fi + ;; + esac +} + +_docker_plugin_inspect() { + case "$prev" in + --format|f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) + ;; + *) + __docker_complete_plugins_installed + ;; + esac +} + +_docker_plugin_install() { + case "$prev" in + --alias) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--alias --disable --disable-content-trust=false --grant-all-permissions --help" -- "$cur" ) ) + ;; + esac +} + +_docker_plugin_list() { + _docker_plugin_ls +} + +_docker_plugin_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + capability) + COMPREPLY=( $( compgen -W "authz ipamdriver logdriver metricscollector networkdriver volumedriver" -- "${cur##*=}" ) ) + return + ;; + enabled) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "capability enabled" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_plugin_push() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_plugins_installed + fi + ;; + esac +} + +_docker_plugin_remove() { + _docker_plugin_rm +} + +_docker_plugin_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) + ;; + *) + __docker_complete_plugins_installed + ;; + esac +} + +_docker_plugin_set() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_plugins_installed + fi + ;; + esac +} + +_docker_plugin_upgrade() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--disable-content-trust --grant-all-permissions --help --skip-remote-check" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_plugins_installed + __ltrim_colon_completions "$cur" + elif [ "$cword" -eq "$((counter + 1))" ]; then + local plugin_images="$(__docker_plugins_installed)" + COMPREPLY=( $(compgen -S : -W "${plugin_images%:*}" -- "$cur") ) + __docker_nospace + fi + ;; + esac +} + + +_docker_port() { + _docker_container_port +} + +_docker_ps() { + _docker_container_ls +} + +_docker_pull() { + _docker_image_pull +} + +_docker_push() { + _docker_image_push +} + +_docker_rename() { + _docker_container_rename +} + +_docker_restart() { + _docker_container_restart +} + +_docker_rm() { + _docker_container_rm +} + +_docker_rmi() { + _docker_image_rm +} + +_docker_run() { + _docker_container_run +} + +_docker_save() { + _docker_image_save +} + + +_docker_secret() { + local subcommands=" + create + inspect + ls + rm + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_secret_create() { + case "$prev" in + --driver|-d|--label|-l) + return + ;; + --template-driver) + COMPREPLY=( $( compgen -W "golang" -- "$cur" ) ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--driver -d --help --label -l --template-driver" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--driver|-d|--label|-l|--template-driver') + if [ "$cword" -eq "$((counter + 1))" ]; then + _filedir + fi + ;; + esac +} + +_docker_secret_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) + ;; + *) + __docker_complete_secrets + ;; + esac +} + +_docker_secret_list() { + _docker_secret_ls +} + +_docker_secret_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + __docker_complete_secrets --cur "${cur##*=}" --id + return + ;; + name) + __docker_complete_secrets --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format --filter -f --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_secret_remove() { + _docker_secret_rm +} + +_docker_secret_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_secrets + ;; + esac +} + + + +_docker_search() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + is-automated) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + is-official) + COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "is-automated is-official stars" -- "$cur" ) ) + __docker_nospace + return + ;; + --format|--limit) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --limit --no-trunc" -- "$cur" ) ) + ;; + esac +} + + +_docker_stack() { + local subcommands=" + config + deploy + ls + ps + rm + services + " + local aliases=" + down + list + remove + up + " + + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_stack_config() { + case "$prev" in + --compose-file|-c) + _filedir yml + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--compose-file -c --help --skip-interpolation" -- "$cur" ) ) + ;; + esac +} + +_docker_stack_deploy() { + case "$prev" in + --compose-file|-c) + _filedir yml + return + ;; + --resolve-image) + COMPREPLY=( $( compgen -W "always changed never" -- "$cur" ) ) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--compose-file -c --help --prune --resolve-image --with-registry-auth" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--compose-file|-c|--resolve-image') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_stacks + fi + ;; + esac +} + +_docker_stack_down() { + _docker_stack_rm +} + +_docker_stack_list() { + _docker_stack_ls +} + +_docker_stack_ls() { + case "$prev" in + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format --help" -- "$cur" ) ) + ;; + esac +} + +_docker_stack_ps() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + desired-state) + COMPREPLY=( $( compgen -W "accepted running shutdown" -- "${cur##*=}" ) ) + return + ;; + id) + __docker_complete_stacks --cur "${cur##*=}" --id + return + ;; + name) + __docker_complete_stacks --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "id name desired-state" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --no-resolve --no-trunc --quiet -q" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--filter|-f|--format') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_stacks + fi + ;; + esac +} + +_docker_stack_remove() { + _docker_stack_rm +} + +_docker_stack_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_stacks + ;; + esac +} + +_docker_stack_services() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + __docker_complete_services --cur "${cur##*=}" --id + return + ;; + label) + return + ;; + name) + __docker_complete_services --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--filter|-f|--format') + if [ "$cword" -eq "$counter" ]; then + __docker_complete_stacks + fi + ;; + esac +} + +_docker_stack_up() { + _docker_stack_deploy +} + + +_docker_start() { + _docker_container_start +} + +_docker_stats() { + _docker_container_stats +} + +_docker_stop() { + _docker_container_stop +} + + +_docker_system() { + local subcommands=" + df + events + info + prune + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_system_df() { + case "$prev" in + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format --help --verbose -v" -- "$cur" ) ) + ;; + esac +} + +_docker_system_events() { + local key=$(__docker_map_key_of_current_option '-f|--filter') + case "$key" in + container) + __docker_complete_containers_all --cur "${cur##*=}" + return + ;; + daemon) + local name=$(__docker_q info | sed -n 's/^\(ID\|Name\): //p') + COMPREPLY=( $( compgen -W "$name" -- "${cur##*=}" ) ) + return + ;; + event) + COMPREPLY=( $( compgen -W " + attach + commit + connect + copy + create + delete + destroy + detach + die + disable + disconnect + enable + exec_create + exec_detach + exec_die + exec_start + export + health_status + import + install + kill + load + mount + oom + pause + pull + push + reload + remove + rename + resize + restart + save + start + stop + tag + top + unmount + unpause + untag + update + " -- "${cur##*=}" ) ) + return + ;; + image) + __docker_complete_images --cur "${cur##*=}" --repo --tag + return + ;; + network) + __docker_complete_networks --cur "${cur##*=}" + return + ;; + node) + __docker_complete_nodes --cur "${cur##*=}" + return + ;; + scope) + COMPREPLY=( $( compgen -W "local swarm" -- "${cur##*=}" ) ) + return + ;; + type) + COMPREPLY=( $( compgen -W "config container daemon image network node plugin secret service volume" -- "${cur##*=}" ) ) + return + ;; + volume) + __docker_complete_volumes --cur "${cur##*=}" + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "container daemon event image label network node scope type volume" -- "$cur" ) ) + __docker_nospace + return + ;; + --since|--until) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --help --since --until --format" -- "$cur" ) ) + ;; + esac +} + +_docker_system_info() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) + ;; + esac +} + +_docker_system_prune() { + case "$prev" in + --filter) + COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --force -f --filter --help --volumes" -- "$cur" ) ) + ;; + esac +} + + +_docker_tag() { + _docker_image_tag +} + + +_docker_trust() { + local subcommands=" + inspect + revoke + sign + " + __docker_subcommands "$subcommands" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_trust_inspect() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --pretty" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images --repo --tag + fi + ;; + esac +} + +_docker_trust_revoke() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --yes -y" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images --repo --tag + fi + ;; + esac +} + +_docker_trust_sign() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --local" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag) + if [ "$cword" -eq "$counter" ]; then + __docker_complete_images --force-tag --id + fi + ;; + esac +} + + +_docker_unpause() { + _docker_container_unpause +} + +_docker_update() { + _docker_container_update +} + +_docker_top() { + _docker_container_top +} + +_docker_version() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) + ;; + esac +} + +_docker_volume_create() { + case "$prev" in + --driver|-d) + __docker_complete_plugins_bundled --type Volume + return + ;; + --label|--opt|-o) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--driver -d --help --label --opt -o" -- "$cur" ) ) + ;; + esac +} + +_docker_volume_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) + ;; + *) + __docker_complete_volumes + ;; + esac +} + +_docker_volume_list() { + _docker_volume_ls +} + +_docker_volume_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + dangling) + COMPREPLY=( $( compgen -W "true false" -- "${cur##*=}" ) ) + return + ;; + driver) + __docker_complete_plugins_bundled --cur "${cur##*=}" --type Volume + return + ;; + name) + __docker_complete_volumes --cur "${cur##*=}" + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "dangling driver label name" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_volume_prune() { + case "$prev" in + --filter) + COMPREPLY=( $( compgen -W "label label!" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--all -a --filter --force -f --help" -- "$cur" ) ) + ;; + esac +} + +_docker_volume_remove() { + _docker_volume_rm +} + +_docker_volume_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) + ;; + *) + __docker_complete_volumes + ;; + esac +} + +_docker_volume() { + local subcommands=" + create + inspect + ls + prune + rm + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_wait() { + _docker_container_wait +} + +_docker() { + local previous_extglob_setting=$(shopt -p extglob) + shopt -s extglob + + local management_commands=( + builder + config + container + context + image + manifest + network + node + plugin + secret + service + stack + swarm + system + trust + volume + ) + + local top_level_commands=( + build + login + logout + run + search + version + ) + + local legacy_commands=( + attach + commit + cp + create + diff + events + exec + export + history + images + import + info + inspect + kill + load + logs + pause + port + ps + pull + push + rename + restart + rm + rmi + save + start + stats + stop + tag + top + unpause + update + wait + ) + + # Create completion functions for all registered plugins + local known_plugin_commands=() + local plugin_name="" + for plugin_path in $(__docker_plugins_path); do + plugin_name=$(basename "$plugin_path" | sed 's/ *$//') + plugin_name=${plugin_name#docker-} + plugin_name=${plugin_name%%.*} + eval "_docker_${plugin_name}() { __docker_complete_plugin \"${plugin_path}\"; }" + known_plugin_commands+=(${plugin_name}) + done + + local experimental_server_commands=( + checkpoint + ) + + local commands=(${management_commands[*]} ${top_level_commands[*]} ${known_plugin_commands[*]}) + [ -z "${DOCKER_HIDE_LEGACY_COMMANDS-}" ] && commands+=(${legacy_commands[*]}) + + # These options are valid as global options for all client commands + # and valid as command options for `docker daemon` + local global_boolean_options=" + --debug -D + --tls + --tlsverify + " + local global_options_with_args=" + --config + --context -c + --host -H + --log-level -l + --tlscacert + --tlscert + --tlskey + " + + # variables to cache server info, populated on demand for performance reasons + local info_fetched server_experimental server_os + + local host config context + + COMPREPLY=() + local cur prev words cword + _get_comp_words_by_ref -n : cur prev words cword + + local command='docker' command_pos=0 subcommand_pos + local counter=1 + while [ "$counter" -lt "$cword" ]; do + case "${words[$counter]}" in + docker) + return 0 + ;; + # save host so that completion can use custom daemon + --host|-H) + (( counter++ )) + host="${words[$counter]}" + ;; + # save config so that completion can use custom configuration directories + --config) + (( counter++ )) + config="${words[$counter]}" + ;; + # save context so that completion can use custom daemon + --context|-c) + (( counter++ )) + context="${words[$counter]}" + ;; + $(__docker_to_extglob "$global_options_with_args") ) + (( counter++ )) + ;; + -*) + ;; + =) + (( counter++ )) + ;; + *) + command="${words[$counter]}" + command_pos=$counter + break + ;; + esac + (( counter++ )) + done + + local binary="${words[0]}" + if [[ $binary == ?(*/)dockerd ]] ; then + # for the dockerd binary, we reuse completion of `docker daemon`. + # dockerd does not have subcommands and global options. + command=daemon + command_pos=0 + fi + + local completions_func=_docker_${command//-/_} + declare -F $completions_func >/dev/null && $completions_func + + eval "$previous_extglob_setting" + return 0 +} + +eval "$__docker_previous_extglob_setting" +unset __docker_previous_extglob_setting + +complete -F _docker docker docker.exe dockerd dockerd.exe From 065071b598b57585609417f5f6b590b3df3ec46f Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sun, 11 Feb 2024 11:17:08 +0900 Subject: [PATCH 2/3] completions/fallback: Adjust docker completions --- completions/fallback/docker-compose.bash | 87 ++-- completions/fallback/docker.bash | 572 ++++++++++++----------- 2 files changed, 338 insertions(+), 321 deletions(-) diff --git a/completions/fallback/docker-compose.bash b/completions/fallback/docker-compose.bash index c3b6157d3..d3da53ee2 100644 --- a/completions/fallback/docker-compose.bash +++ b/completions/fallback/docker-compose.bash @@ -1,4 +1,13 @@ -#!/bin/bash +#! bash oh-my-bash.module +#------------------------------------------------------------------------------ +# Note by OMB: This file is taken from the following version of Docker Compose +# v1: +# +# https://github.com/docker/compose/blob/30fcb72cf3b136598883752edfa6ea4f3b8643d4/contrib/completion/bash/docker-compose +# +# Licence: Apache-2.0 license +# Copyright: original authors of Docker Compose v1 +#------------------------------------------------------------------------------ # # bash completion for docker-compose # @@ -19,13 +28,13 @@ __docker_compose_previous_extglob_setting=$(shopt -p extglob) shopt -s extglob -__docker_compose_q() { +function __docker_compose_q { docker-compose 2>/dev/null "${top_level_options[@]}" "$@" } # Transforms a multiline list of strings into a single line string # with the words separated by "|". -__docker_compose_to_alternatives() { +function __docker_compose_to_alternatives { local parts=( $1 ) local IFS='|' echo "${parts[*]}" @@ -33,14 +42,14 @@ __docker_compose_to_alternatives() { # Transforms a multiline list of options into an extglob pattern # suitable for use in case statements. -__docker_compose_to_extglob() { +function __docker_compose_to_extglob { local extglob=$( __docker_compose_to_alternatives "$1" ) echo "@($extglob)" } # Determines whether the option passed as the first argument exist on # the commandline. The option may be a pattern, e.g. `--force|-f`. -__docker_compose_has_option() { +function __docker_compose_has_option { local pattern="$1" for (( i=2; i < $cword; ++i)); do if [[ ${words[$i]} =~ ^($pattern)$ ]] ; then @@ -53,7 +62,7 @@ __docker_compose_has_option() { # Returns `key` if we are currently completing the value of a map option (`key=value`) # which matches the extglob passed in as an argument. # This function is needed for key-specific completions. -__docker_compose_map_key_of_current_option() { +function __docker_compose_map_key_of_current_option { local glob="$1" local key glob_pos @@ -76,34 +85,34 @@ __docker_compose_map_key_of_current_option() { } # suppress trailing whitespace -__docker_compose_nospace() { +function __docker_compose_nospace { # compopt is not available in ancient bash versions - type compopt &>/dev/null && compopt -o nospace + _omb_util_command_exists compopt && compopt -o nospace } # Outputs a list of all defined services, regardless of their running state. # Arguments for `docker-compose ps` may be passed in order to filter the service list, # e.g. `status=running`. -__docker_compose_services() { +function __docker_compose_services { __docker_compose_q ps --services "$@" } # Applies completion of services based on the current value of `$cur`. # Arguments for `docker-compose ps` may be passed in order to filter the service list, # see `__docker_compose_services`. -__docker_compose_complete_services() { +function __docker_compose_complete_services { COMPREPLY=( $(compgen -W "$(__docker_compose_services "$@")" -- "$cur") ) } # The services for which at least one running container exists -__docker_compose_complete_running_services() { +function __docker_compose_complete_running_services { local names=$(__docker_compose_services --filter status=running) COMPREPLY=( $(compgen -W "$names" -- "$cur") ) } -_docker_compose_build() { +function _docker_compose_build { case "$prev" in --build-arg) COMPREPLY=( $( compgen -e -- "$cur" ) ) @@ -126,7 +135,7 @@ _docker_compose_build() { } -_docker_compose_config() { +function _docker_compose_config { case "$prev" in --hash) if [[ $cur == \\* ]] ; then @@ -142,7 +151,7 @@ _docker_compose_config() { } -_docker_compose_create() { +function _docker_compose_create { case "$cur" in -*) COMPREPLY=( $( compgen -W "--build --force-recreate --help --no-build --no-recreate" -- "$cur" ) ) @@ -154,7 +163,7 @@ _docker_compose_create() { } -_docker_compose_docker_compose() { +function _docker_compose_docker_compose { case "$prev" in --tlscacert|--tlscert|--tlskey) _filedir @@ -200,7 +209,7 @@ _docker_compose_docker_compose() { } -_docker_compose_down() { +function _docker_compose_down { case "$prev" in --rmi) COMPREPLY=( $( compgen -W "all local" -- "$cur" ) ) @@ -219,7 +228,7 @@ _docker_compose_down() { } -_docker_compose_events() { +function _docker_compose_events { case "$prev" in --json) return @@ -237,7 +246,7 @@ _docker_compose_events() { } -_docker_compose_exec() { +function _docker_compose_exec { case "$prev" in --index|--user|-u|--workdir|-w) return @@ -255,11 +264,11 @@ _docker_compose_exec() { } -_docker_compose_help() { +function _docker_compose_help { COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) } -_docker_compose_images() { +function _docker_compose_images { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help --quiet -q" -- "$cur" ) ) @@ -270,7 +279,7 @@ _docker_compose_images() { esac } -_docker_compose_kill() { +function _docker_compose_kill { case "$prev" in -s) COMPREPLY=( $( compgen -W "SIGHUP SIGINT SIGKILL SIGUSR1 SIGUSR2" -- "$(echo $cur | tr '[:lower:]' '[:upper:]')" ) ) @@ -289,7 +298,7 @@ _docker_compose_kill() { } -_docker_compose_logs() { +function _docker_compose_logs { case "$prev" in --tail) return @@ -307,7 +316,7 @@ _docker_compose_logs() { } -_docker_compose_pause() { +function _docker_compose_pause { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -319,7 +328,7 @@ _docker_compose_pause() { } -_docker_compose_port() { +function _docker_compose_port { case "$prev" in --protocol) COMPREPLY=( $( compgen -W "tcp udp" -- "$cur" ) ) @@ -341,7 +350,7 @@ _docker_compose_port() { } -_docker_compose_ps() { +function _docker_compose_ps { local key=$(__docker_compose_map_key_of_current_option '--filter') case "$key" in source) @@ -373,7 +382,7 @@ _docker_compose_ps() { } -_docker_compose_pull() { +function _docker_compose_pull { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help --ignore-pull-failures --include-deps --no-parallel --quiet -q" -- "$cur" ) ) @@ -385,7 +394,7 @@ _docker_compose_pull() { } -_docker_compose_push() { +function _docker_compose_push { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help --ignore-push-failures" -- "$cur" ) ) @@ -397,7 +406,7 @@ _docker_compose_push() { } -_docker_compose_restart() { +function _docker_compose_restart { case "$prev" in --timeout|-t) return @@ -415,7 +424,7 @@ _docker_compose_restart() { } -_docker_compose_rm() { +function _docker_compose_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--force -f --help --stop -s -v" -- "$cur" ) ) @@ -431,7 +440,7 @@ _docker_compose_rm() { } -_docker_compose_run() { +function _docker_compose_run { case "$prev" in -e) COMPREPLY=( $( compgen -e -- "$cur" ) ) @@ -454,7 +463,7 @@ _docker_compose_run() { } -_docker_compose_scale() { +function _docker_compose_scale { case "$prev" in =) COMPREPLY=("$cur") @@ -477,7 +486,7 @@ _docker_compose_scale() { } -_docker_compose_start() { +function _docker_compose_start { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -489,7 +498,7 @@ _docker_compose_start() { } -_docker_compose_stop() { +function _docker_compose_stop { case "$prev" in --timeout|-t) return @@ -507,7 +516,7 @@ _docker_compose_stop() { } -_docker_compose_top() { +function _docker_compose_top { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -519,7 +528,7 @@ _docker_compose_top() { } -_docker_compose_unpause() { +function _docker_compose_unpause { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -531,7 +540,7 @@ _docker_compose_unpause() { } -_docker_compose_up() { +function _docker_compose_up { case "$prev" in =) COMPREPLY=("$cur") @@ -562,7 +571,7 @@ _docker_compose_up() { } -_docker_compose_version() { +function _docker_compose_version { case "$cur" in -*) COMPREPLY=( $( compgen -W "--short" -- "$cur" ) ) @@ -571,7 +580,7 @@ _docker_compose_version() { } -_docker_compose() { +function _docker_compose { local previous_extglob_setting=$(shopt -p extglob) shopt -s extglob @@ -664,7 +673,7 @@ _docker_compose() { done local completions_func=_docker_compose_${command//-/_} - declare -F $completions_func >/dev/null && $completions_func + _omb_util_function_exists "$completions_func" && "$completions_func" eval "$previous_extglob_setting" return 0 diff --git a/completions/fallback/docker.bash b/completions/fallback/docker.bash index b8fa557cb..342c89aea 100644 --- a/completions/fallback/docker.bash +++ b/completions/fallback/docker.bash @@ -1,5 +1,13 @@ -#!/usr/bin/env bash +#! bash oh-my-bash.module # shellcheck disable=SC2016,SC2119,SC2155,SC2206,SC2207,SC2254 +#------------------------------------------------------------------------------ +# Note by OMB: This file is taken from the following version of Docker CLI: +# +# https://github.com/docker/cli/blob/34797d167891c11d2e10c1339b072166b77a3378/contrib/completion/bash/docker +# +# Licence: Apache-2.0 license +# Copyright: original authors of Docker CLI +#------------------------------------------------------------------------------ # # Shellcheck ignore list: # - SC2016: Expressions don't expand in single quotes, use double quotes for that. @@ -70,7 +78,7 @@ __docker_previous_extglob_setting=$(shopt -p extglob) shopt -s extglob -__docker_q() { +function __docker_q { docker ${host:+--host "$host"} ${config:+--config "$config"} ${context:+--context "$context"} 2>/dev/null "$@" } @@ -82,7 +90,7 @@ __docker_q() { # An optional first option `--id|--name` may be used to limit the # output to the IDs or names of matching items. This setting takes # precedence over the environment setting. -__docker_configs() { +function __docker_configs { local format if [ "${1-}" = "--id" ] ; then format='{{.ID}}' @@ -101,7 +109,7 @@ __docker_configs() { # __docker_complete_configs applies completion of configs based on the current value # of `$cur` or the value of the optional first option `--cur`, if given. -__docker_complete_configs() { +function __docker_complete_configs { local current="$cur" if [ "$1" = "--cur" ] ; then current="$2" @@ -118,7 +126,7 @@ __docker_complete_configs() { # An optional first option `--id|--name` may be used to limit the # output to the IDs or names of matching items. This setting takes # precedence over the environment setting. -__docker_containers() { +function __docker_containers { local format if [ "${1-}" = "--id" ] ; then format='{{.ID}}' @@ -137,7 +145,7 @@ __docker_containers() { # __docker_complete_containers applies completion of containers based on the current # value of `$cur` or the value of the optional first option `--cur`, if given. # Additional filters may be appended, see `__docker_containers`. -__docker_complete_containers() { +function __docker_complete_containers { local current="$cur" if [ "${1-}" = "--cur" ] ; then current="$2" @@ -146,49 +154,49 @@ __docker_complete_containers() { COMPREPLY=( $(compgen -W "$(__docker_containers "$@")" -- "$current") ) } -__docker_complete_containers_all() { +function __docker_complete_containers_all { __docker_complete_containers "$@" --all } # shellcheck disable=SC2120 -__docker_complete_containers_removable() { +function __docker_complete_containers_removable { __docker_complete_containers "$@" --filter status=created --filter status=exited } -__docker_complete_containers_running() { +function __docker_complete_containers_running { __docker_complete_containers "$@" --filter status=running } # shellcheck disable=SC2120 -__docker_complete_containers_stoppable() { +function __docker_complete_containers_stoppable { __docker_complete_containers "$@" --filter status=running --filter status=paused } # shellcheck disable=SC2120 -__docker_complete_containers_stopped() { +function __docker_complete_containers_stopped { __docker_complete_containers "$@" --filter status=exited } # shellcheck disable=SC2120 -__docker_complete_containers_unpauseable() { +function __docker_complete_containers_unpauseable { __docker_complete_containers "$@" --filter status=paused } -__docker_complete_container_names() { +function __docker_complete_container_names { local containers=( $(__docker_q ps -aq --no-trunc) ) local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") ) names=( "${names[@]#/}" ) # trim off the leading "/" from the container names COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") ) } -__docker_complete_container_ids() { +function __docker_complete_container_ids { local containers=( $(__docker_q ps -aq) ) COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") ) } # __docker_contexts returns a list of contexts without the special "default" context. # Completions may be added with `--add`, e.g. `--add default`. -__docker_contexts() { +function __docker_contexts { local add=() while true ; do case "${1-}" in @@ -205,7 +213,7 @@ __docker_contexts() { echo "${add[@]}" } -__docker_complete_contexts() { +function __docker_complete_contexts { local contexts=( $(__docker_contexts "$@") ) COMPREPLY=( $(compgen -W "${contexts[*]}" -- "$cur") ) } @@ -229,7 +237,7 @@ __docker_complete_contexts() { # Additional arguments to `docker image ls` may be specified in order to filter the list, # e.g. `__docker_images --filter dangling=true`. # -__docker_images() { +function __docker_images { local repo_format='{{.Repository}}' local tag_format='{{.Repository}}:{{.Tag}}' local id_format='{{.ID}}' @@ -275,7 +283,7 @@ __docker_images() { # __docker_complete_images applies completion of images based on the current value of `$cur` or # the value of the optional first option `--cur`, if given. # See __docker_images for customization of the returned items. -__docker_complete_images() { +function __docker_complete_images { local current="$cur" if [ "${1-}" = "--cur" ] ; then current="$2" @@ -293,7 +301,7 @@ __docker_complete_images() { # An optional first option `--id|--name` may be used to limit the # output to the IDs or names of matching items. This setting takes # precedence over the environment setting. -__docker_networks() { +function __docker_networks { local format if [ "${1-}" = "--id" ] ; then format='{{.ID}}' @@ -312,7 +320,7 @@ __docker_networks() { # __docker_complete_networks applies completion of networks based on the current # value of `$cur` or the value of the optional first option `--cur`, if given. # Additional filters may be appended, see `__docker_networks`. -__docker_complete_networks() { +function __docker_complete_networks { local current="$cur" if [ "${1-}" = "--cur" ] ; then current="$2" @@ -321,7 +329,7 @@ __docker_complete_networks() { COMPREPLY=( $(compgen -W "$(__docker_networks "$@")" -- "$current") ) } -__docker_complete_containers_in_network() { +function __docker_complete_containers_in_network { local containers=($(__docker_q network inspect -f '{{range $i, $c := .Containers}}{{$i}} {{$c.Name}} {{end}}' "$1")) COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") ) } @@ -331,14 +339,14 @@ __docker_complete_containers_in_network() { # `__docker_volumes --filter dangling=true` # Because volumes do not have IDs, this function does not distinguish between # IDs and names. -__docker_volumes() { +function __docker_volumes { __docker_q volume ls -q "$@" } # __docker_complete_volumes applies completion of volumes based on the current # value of `$cur` or the value of the optional first option `--cur`, if given. # Additional filters may be appended, see `__docker_volumes`. -__docker_complete_volumes() { +function __docker_complete_volumes { local current="$cur" if [ "${1-}" = "--cur" ] ; then current="$2" @@ -353,7 +361,7 @@ __docker_complete_volumes() { # Completions may be added or removed with `--add` and `--remove` # This function only deals with plugins that come bundled with Docker. # For plugins managed by `docker plugin`, see `__docker_plugins_installed`. -__docker_plugins_bundled() { +function __docker_plugins_bundled { local type add=() remove=() while true ; do case "${1-}" in @@ -388,7 +396,7 @@ __docker_plugins_bundled() { # This function only deals with plugins that come bundled with Docker. # For completion of plugins managed by `docker plugin`, see # `__docker_complete_plugins_installed`. -__docker_complete_plugins_bundled() { +function __docker_complete_plugins_bundled { local current="$cur" if [ "${1-}" = "--cur" ] ; then current="$2" @@ -404,7 +412,7 @@ __docker_complete_plugins_bundled() { # Additional options to `docker plugin ls` may be specified in order to filter the list, # e.g. `__docker_plugins_installed --filter enabled=true` # For built-in pugins, see `__docker_plugins_bundled`. -__docker_plugins_installed() { +function __docker_plugins_installed { local format if [ "${DOCKER_COMPLETION_SHOW_PLUGIN_IDS-}" = yes ] ; then format='{{.ID}} {{.Name}}' @@ -419,7 +427,7 @@ __docker_plugins_installed() { # the optional first option `--cur`, if given. # Additional filters may be appended, see `__docker_plugins_installed`. # For completion of built-in pugins, see `__docker_complete_plugins_bundled`. -__docker_complete_plugins_installed() { +function __docker_complete_plugins_installed { local current="$cur" if [ "${1-}" = "--cur" ] ; then current="$2" @@ -428,11 +436,11 @@ __docker_complete_plugins_installed() { COMPREPLY=( $(compgen -W "$(__docker_plugins_installed "$@")" -- "$current") ) } -__docker_runtimes() { +function __docker_runtimes { __docker_q info | sed -n 's/^Runtimes: \(.*\)/\1/p' } -__docker_complete_runtimes() { +function __docker_complete_runtimes { COMPREPLY=( $(compgen -W "$(__docker_runtimes)" -- "$cur") ) } @@ -444,7 +452,7 @@ __docker_complete_runtimes() { # An optional first option `--id|--name` may be used to limit the # output to the IDs or names of matching items. This setting takes # precedence over the environment setting. -__docker_secrets() { +function __docker_secrets { local format if [ "${1-}" = "--id" ] ; then format='{{.ID}}' @@ -463,7 +471,7 @@ __docker_secrets() { # __docker_complete_secrets applies completion of secrets based on the current value # of `$cur` or the value of the optional first option `--cur`, if given. -__docker_complete_secrets() { +function __docker_complete_secrets { local current="$cur" if [ "${1-}" = "--cur" ] ; then current="$2" @@ -473,13 +481,13 @@ __docker_complete_secrets() { } # __docker_stacks returns a list of all stacks. -__docker_stacks() { +function __docker_stacks { __docker_q stack ls | awk 'NR>1 {print $1}' } # __docker_complete_stacks applies completion of stacks based on the current value # of `$cur` or the value of the optional first option `--cur`, if given. -__docker_complete_stacks() { +function __docker_complete_stacks { local current="$cur" if [ "${1-}" = "--cur" ] ; then current="$2" @@ -497,7 +505,7 @@ __docker_complete_stacks() { # output to the IDs or names of matching items. This setting takes # precedence over the environment setting. # Completions may be added with `--add`, e.g. `--add self`. -__docker_nodes() { +function __docker_nodes { local format if [ "${DOCKER_COMPLETION_SHOW_NODE_IDS-}" = yes ] ; then format='{{.ID}} {{.Hostname}}' @@ -533,7 +541,7 @@ __docker_nodes() { # __docker_complete_nodes applies completion of nodes based on the current # value of `$cur` or the value of the optional first option `--cur`, if given. # Additional filters may be appended, see `__docker_nodes`. -__docker_complete_nodes() { +function __docker_complete_nodes { local current="$cur" if [ "${1-}" = "--cur" ] ; then current="$2" @@ -550,7 +558,7 @@ __docker_complete_nodes() { # An optional first option `--id|--name` may be used to limit the # output to the IDs or names of matching items. This setting takes # precedence over the environment setting. -__docker_services() { +function __docker_services { local format='{{.Name}}' # default: service name only [ "${DOCKER_COMPLETION_SHOW_SERVICE_IDS-}" = yes ] && format='{{.ID}} {{.Name}}' # ID & name @@ -568,7 +576,7 @@ __docker_services() { # __docker_complete_services applies completion of services based on the current # value of `$cur` or the value of the optional first option `--cur`, if given. # Additional filters may be appended, see `__docker_services`. -__docker_complete_services() { +function __docker_complete_services { local current="$cur" if [ "${1-}" = "--cur" ] ; then current="$2" @@ -578,13 +586,13 @@ __docker_complete_services() { } # __docker_tasks returns a list of all task IDs. -__docker_tasks() { +function __docker_tasks { __docker_q service ps --format '{{.ID}}' "" } # __docker_complete_services_and_tasks applies completion of services and task IDs. # shellcheck disable=SC2120 -__docker_complete_services_and_tasks() { +function __docker_complete_services_and_tasks { COMPREPLY=( $(compgen -W "$(__docker_services "$@") $(__docker_tasks)" -- "$cur") ) } @@ -593,14 +601,14 @@ __docker_complete_services_and_tasks() { # Normally you do this with `compgen -S` while generating the completions. # This function allows you to append a suffix later. It allows you to use # the __docker_complete_XXX functions in cases where you need a suffix. -__docker_append_to_completions() { +function __docker_append_to_completions { COMPREPLY=( ${COMPREPLY[@]/%/"$1"} ) } # __docker_fetch_info fetches information about the configured Docker server and updates # several variables with the results. # The result is cached for the duration of one invocation of bash completion. -__docker_fetch_info() { +function __docker_fetch_info { if [ -z "${info_fetched-}" ] ; then read -r server_experimental server_os <<< "$(__docker_q version -f '{{.Server.Experimental}} {{.Server.Os}}')" info_fetched=true @@ -610,7 +618,7 @@ __docker_fetch_info() { # __docker_server_is_experimental tests whether the currently configured Docker # server runs in experimental mode. If so, the function exits with 0 (true). # Otherwise, or if the result cannot be determined, the exit value is 1 (false). -__docker_server_is_experimental() { +function __docker_server_is_experimental { __docker_fetch_info [ "$server_experimental" = "true" ] } @@ -618,7 +626,7 @@ __docker_server_is_experimental() { # __docker_server_os_is tests whether the currently configured Docker server runs # on the operating system passed in as the first argument. # Known operating systems: linux, windows. -__docker_server_os_is() { +function __docker_server_os_is { local expected_os="$1" __docker_fetch_info [ "$server_os" = "$expected_os" ] @@ -628,7 +636,7 @@ __docker_server_os_is() { # option nor an option's argument. If there are options that require arguments, # you should pass a glob describing those options, e.g. "--option1|-o|--option2" # Use this function to restrict completions to exact positions after the argument list. -__docker_pos_first_nonflag() { +function __docker_pos_first_nonflag { local argument_flags=${1-} local counter=$((${subcommand_pos:-${command_pos}} + 1)) @@ -662,7 +670,7 @@ __docker_pos_first_nonflag() { # __docker_map_key_of_current_option returns `key` if we are currently completing the # value of a map option (`key=value`) which matches the extglob given as an argument. # This function is needed for key-specific completions. -__docker_map_key_of_current_option() { +function __docker_map_key_of_current_option { local glob="$1" local key glob_pos @@ -688,7 +696,7 @@ __docker_map_key_of_current_option() { # Valid values for `option_glob` are option names like `--log-level` and globs like # `--log-level|-l` # Only positions between the command and the current word are considered. -__docker_value_of_option() { +function __docker_value_of_option { local option_extglob=$(__docker_to_extglob "$1") local counter=$((command_pos + 1)) @@ -706,7 +714,7 @@ __docker_value_of_option() { # __docker_to_alternatives transforms a multiline list of strings into a single line # string with the words separated by `|`. # This is used to prepare arguments to __docker_pos_first_nonflag(). -__docker_to_alternatives() { +function __docker_to_alternatives { local parts=( $1 ) local IFS='|' echo "${parts[*]}" @@ -714,7 +722,7 @@ __docker_to_alternatives() { # __docker_to_extglob transforms a multiline list of options into an extglob pattern # suitable for use in case statements. -__docker_to_extglob() { +function __docker_to_extglob { local extglob=$( __docker_to_alternatives "$1" ) echo "@($extglob)" } @@ -729,7 +737,7 @@ __docker_to_extglob() { # TODO if the preceding command has options that accept arguments and an # argument is equal ot one of the subcommands, this is falsely detected as # a match. -__docker_subcommands() { +function __docker_subcommands { local subcommands="$1" local counter=$((command_pos + 1)) @@ -739,7 +747,7 @@ __docker_subcommands() { subcommand_pos=$counter local subcommand=${words[$counter]} local completions_func=_docker_${command}_${subcommand//-/_} - declare -F "$completions_func" >/dev/null && "$completions_func" + _omb_util_function_exists "$completions_func" && "$completions_func" return 0 ;; esac @@ -749,21 +757,21 @@ __docker_subcommands() { } # __docker_nospace suppresses trailing whitespace -__docker_nospace() { +function __docker_nospace { # compopt is not available in ancient bash versions - type compopt &>/dev/null && compopt -o nospace + _omb_util_command_exists compopt && compopt -o nospace } -__docker_complete_resolved_hostname() { - command -v host >/dev/null 2>&1 || return +function __docker_complete_resolved_hostname { + _omb_util_command_exists host || return COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') ) } # __docker_local_interfaces returns a list of the names and addresses of all # local network interfaces. # If `--ip-only` is passed as a first argument, only addresses are returned. -__docker_local_interfaces() { - command -v ip >/dev/null 2>&1 || return +function __docker_local_interfaces { + _omb_util_command_exists ip || return local format if [ "${1-}" = "--ip-only" ] ; then @@ -779,7 +787,7 @@ __docker_local_interfaces() { # __docker_complete_local_interfaces applies completion of the names and addresses of all # local network interfaces based on the current value of `$cur`. # An additional value can be added to the possible completions with an `--add` argument. -__docker_complete_local_interfaces() { +function __docker_complete_local_interfaces { local additional_interface if [ "${1-}" = "--add" ] ; then additional_interface="$2" @@ -791,14 +799,14 @@ __docker_complete_local_interfaces() { # __docker_complete_local_ips applies completion of the addresses of all local network # interfaces based on the current value of `$cur`. -__docker_complete_local_ips() { +function __docker_complete_local_ips { __docker_complete_local_interfaces --ip-only } # __docker_complete_capabilities_addable completes Linux capabilities which are # not granted by default and may be added. # see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities -__docker_complete_capabilities_addable() { +function __docker_complete_capabilities_addable { local capabilities=( ALL CAP_AUDIT_CONTROL @@ -836,7 +844,7 @@ __docker_complete_capabilities_addable() { # __docker_complete_capabilities_droppable completes Linux capability options which are # allowed by default and can be dropped. # see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities -__docker_complete_capabilities_droppable() { +function __docker_complete_capabilities_droppable { local capabilities=( ALL CAP_AUDIT_WRITE @@ -858,7 +866,7 @@ __docker_complete_capabilities_droppable() { COMPREPLY=( $( compgen -W "${capabilities[*]} ${capabilities[*]#CAP_}" -- "$cur" ) ) } -__docker_complete_detach_keys() { +function __docker_complete_detach_keys { case "$prev" in --detach-keys) case "$cur" in @@ -877,11 +885,11 @@ __docker_complete_detach_keys() { return 1 } -__docker_complete_isolation() { +function __docker_complete_isolation { COMPREPLY=( $( compgen -W "default hyperv process" -- "$cur" ) ) } -__docker_complete_log_drivers() { +function __docker_complete_log_drivers { COMPREPLY=( $( compgen -W " awslogs etwlogs @@ -897,7 +905,7 @@ __docker_complete_log_drivers() { " -- "$cur" ) ) } -__docker_complete_log_options() { +function __docker_complete_log_options { # see https://docs.docker.com/config/containers/logging/configure/ # really global options, defined in https://github.com/moby/moby/blob/master/daemon/logger/factory.go @@ -959,7 +967,7 @@ __docker_complete_log_options() { __docker_nospace } -__docker_complete_log_driver_options() { +function __docker_complete_log_driver_options { local key=$(__docker_map_key_of_current_option '--log-opt') case "$key" in awslogs-create-group) @@ -1061,11 +1069,11 @@ __docker_complete_log_driver_options() { return 1 } -__docker_complete_log_levels() { +function __docker_complete_log_levels { COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) ) } -__docker_complete_restart() { +function __docker_complete_restart { case "$prev" in --restart) case "$cur" in @@ -1083,7 +1091,7 @@ __docker_complete_restart() { # __docker_complete_signals returns a subset of the available signals that is most likely # relevant in the context of docker containers -__docker_complete_signals() { +function __docker_complete_signals { local signals=( SIGCONT SIGHUP @@ -1098,7 +1106,7 @@ __docker_complete_signals() { COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo "$cur" | tr '[:lower:]' '[:upper:]')" ) ) } -__docker_complete_ulimits() { +function __docker_complete_ulimits { local limits=" as chroot @@ -1128,7 +1136,7 @@ __docker_complete_ulimits() { fi } -__docker_complete_user_group() { +function __docker_complete_user_group { if [[ $cur == *:* ]] ; then COMPREPLY=( $(compgen -g -- "${cur#*:}") ) else @@ -1137,12 +1145,12 @@ __docker_complete_user_group() { fi } -__docker_plugins_path() { +function __docker_plugins_path { local docker_plugins_path=$(docker info --format '{{range .ClientInfo.Plugins}}{{.Path}}:{{end}}') echo "${docker_plugins_path//:/ }" } -__docker_complete_plugin() { +function __docker_complete_plugin { local path=$1 local completionCommand="__completeNoDesc" local resultArray=($path $completionCommand) @@ -1176,7 +1184,7 @@ __docker_complete_plugin() { fi } -_docker_docker() { +function _docker_docker { # global options that may appear after the docker command local boolean_options=" $global_boolean_options @@ -1216,16 +1224,16 @@ _docker_docker() { esac } -_docker_attach() { +function _docker_attach { _docker_container_attach } -_docker_build() { +function _docker_build { _docker_image_build } -_docker_builder() { +function _docker_builder { local subcommands=" build prune @@ -1242,11 +1250,11 @@ _docker_builder() { esac } -_docker_builder_build() { +function _docker_builder_build { _docker_image_build } -_docker_builder_prune() { +function _docker_builder_prune { case "$prev" in --filter) COMPREPLY=( $( compgen -S = -W "description id inuse parent private shared type until unused-for" -- "$cur" ) ) @@ -1265,7 +1273,7 @@ _docker_builder_prune() { esac } -_docker_checkpoint() { +function _docker_checkpoint { local subcommands=" create ls @@ -1287,7 +1295,7 @@ _docker_checkpoint() { esac } -_docker_checkpoint_create() { +function _docker_checkpoint_create { case "$prev" in --checkpoint-dir) _filedir -d @@ -1308,7 +1316,7 @@ _docker_checkpoint_create() { esac } -_docker_checkpoint_ls() { +function _docker_checkpoint_ls { case "$prev" in --checkpoint-dir) _filedir -d @@ -1329,7 +1337,7 @@ _docker_checkpoint_ls() { esac } -_docker_checkpoint_rm() { +function _docker_checkpoint_rm { case "$prev" in --checkpoint-dir) _filedir -d @@ -1353,7 +1361,7 @@ _docker_checkpoint_rm() { } -_docker_config() { +function _docker_config { local subcommands=" create inspect @@ -1376,7 +1384,7 @@ _docker_config() { esac } -_docker_config_create() { +function _docker_config_create { case "$prev" in --label|-l) return @@ -1400,7 +1408,7 @@ _docker_config_create() { esac } -_docker_config_inspect() { +function _docker_config_inspect { case "$prev" in --format|-f) return @@ -1417,11 +1425,11 @@ _docker_config_inspect() { esac } -_docker_config_list() { +function _docker_config_list { _docker_config_ls } -_docker_config_ls() { +function _docker_config_ls { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in id) @@ -1452,11 +1460,11 @@ _docker_config_ls() { esac } -_docker_config_remove() { +function _docker_config_remove { _docker_config_rm } -_docker_config_rm() { +function _docker_config_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -1468,7 +1476,7 @@ _docker_config_rm() { } -_docker_container() { +function _docker_container { local subcommands=" attach commit @@ -1512,7 +1520,7 @@ _docker_container() { esac } -_docker_container_attach() { +function _docker_container_attach { __docker_complete_detach_keys && return case "$cur" in @@ -1528,7 +1536,7 @@ _docker_container_attach() { esac } -_docker_container_commit() { +function _docker_container_commit { case "$prev" in --author|-a|--change|-c|--message|-m) return @@ -1553,7 +1561,7 @@ _docker_container_commit() { esac } -_docker_container_cp() { +function _docker_container_cp { case "$cur" in -*) COMPREPLY=( $( compgen -W "--archive -a --follow-link -L --help" -- "$cur" ) ) @@ -1598,11 +1606,11 @@ _docker_container_cp() { esac } -_docker_container_create() { +function _docker_container_create { _docker_container_run_and_create } -_docker_container_diff() { +function _docker_container_diff { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -1616,7 +1624,7 @@ _docker_container_diff() { esac } -_docker_container_exec() { +function _docker_container_exec { __docker_complete_detach_keys && return case "$prev" in @@ -1649,7 +1657,7 @@ _docker_container_exec() { esac } -_docker_container_export() { +function _docker_container_export { case "$prev" in --output|-o) _filedir @@ -1670,11 +1678,11 @@ _docker_container_export() { esac } -_docker_container_inspect() { +function _docker_container_inspect { _docker_inspect --type container } -_docker_container_kill() { +function _docker_container_kill { case "$prev" in --signal|-s) __docker_complete_signals @@ -1692,7 +1700,7 @@ _docker_container_kill() { esac } -_docker_container_logs() { +function _docker_container_logs { case "$prev" in --since|--tail|-n|--until) return @@ -1712,11 +1720,11 @@ _docker_container_logs() { esac } -_docker_container_list() { +function _docker_container_list { _docker_container_ls } -_docker_container_ls() { +function _docker_container_ls { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in ancestor) @@ -1782,7 +1790,7 @@ _docker_container_ls() { esac } -_docker_container_pause() { +function _docker_container_pause { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -1793,7 +1801,7 @@ _docker_container_pause() { esac } -_docker_container_port() { +function _docker_container_port { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -1807,7 +1815,7 @@ _docker_container_port() { esac } -_docker_container_prune() { +function _docker_container_prune { case "$prev" in --filter) COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) @@ -1823,11 +1831,11 @@ _docker_container_prune() { esac } -_docker_container_ps() { +function _docker_container_ps { _docker_container_ls } -_docker_container_rename() { +function _docker_container_rename { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -1841,7 +1849,7 @@ _docker_container_rename() { esac } -_docker_container_restart() { +function _docker_container_restart { case "$prev" in --time|-t) return @@ -1858,7 +1866,7 @@ _docker_container_restart() { esac } -_docker_container_rm() { +function _docker_container_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--force -f --help --link -l --volumes -v" -- "$cur" ) ) @@ -1877,13 +1885,13 @@ _docker_container_rm() { esac } -_docker_container_run() { +function _docker_container_run { _docker_container_run_and_create } # _docker_container_run_and_create is the combined completion for `_docker_container_run` # and `_docker_container_create` -_docker_container_run_and_create() { +function _docker_container_run_and_create { local options_with_args=" --add-host --annotation @@ -2208,7 +2216,7 @@ _docker_container_run_and_create() { esac } -_docker_container_start() { +function _docker_container_start { __docker_complete_detach_keys && return case "$prev" in --checkpoint) @@ -2236,7 +2244,7 @@ _docker_container_start() { esac } -_docker_container_stats() { +function _docker_container_stats { case "$prev" in --format) return @@ -2253,7 +2261,7 @@ _docker_container_stats() { esac } -_docker_container_stop() { +function _docker_container_stop { case "$prev" in --time|-t) return @@ -2270,7 +2278,7 @@ _docker_container_stop() { esac } -_docker_container_top() { +function _docker_container_top { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -2284,7 +2292,7 @@ _docker_container_top() { esac } -_docker_container_unpause() { +function _docker_container_unpause { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -2298,7 +2306,7 @@ _docker_container_unpause() { esac } -_docker_container_update() { +function _docker_container_update { local options_with_args=" --blkio-weight --cpu-period @@ -2341,7 +2349,7 @@ _docker_container_update() { esac } -_docker_container_wait() { +function _docker_container_wait { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -2353,7 +2361,7 @@ _docker_container_wait() { } -_docker_context() { +function _docker_context { local subcommands=" create export @@ -2380,7 +2388,7 @@ _docker_context() { esac } -_docker_context_create() { +function _docker_context_create { case "$prev" in --description|--docker) return @@ -2398,7 +2406,7 @@ _docker_context_create() { esac } -_docker_context_export() { +function _docker_context_export { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -2414,7 +2422,7 @@ _docker_context_export() { esac } -_docker_context_import() { +function _docker_context_import { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -2430,7 +2438,7 @@ _docker_context_import() { esac } -_docker_context_inspect() { +function _docker_context_inspect { case "$prev" in --format|-f) return @@ -2447,11 +2455,11 @@ _docker_context_inspect() { esac } -_docker_context_list() { +function _docker_context_list { _docker_context_ls } -_docker_context_ls() { +function _docker_context_ls { case "$prev" in --format|-f) return @@ -2465,11 +2473,11 @@ _docker_context_ls() { esac } -_docker_context_remove() { +function _docker_context_remove { _docker_context_rm } -_docker_context_rm() { +function _docker_context_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) @@ -2480,7 +2488,7 @@ _docker_context_rm() { esac } -_docker_context_update() { +function _docker_context_update { case "$prev" in --description|--docker) return @@ -2500,7 +2508,7 @@ _docker_context_update() { esac } -_docker_context_use() { +function _docker_context_use { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -2515,19 +2523,19 @@ _docker_context_use() { } -_docker_commit() { +function _docker_commit { _docker_container_commit } -_docker_cp() { +function _docker_cp { _docker_container_cp } -_docker_create() { +function _docker_create { _docker_container_create } -_docker_daemon() { +function _docker_daemon { local boolean_options=" $global_boolean_options --experimental @@ -2715,36 +2723,36 @@ _docker_daemon() { esac } -_docker_diff() { +function _docker_diff { _docker_container_diff } -_docker_events() { +function _docker_events { _docker_system_events } -_docker_exec() { +function _docker_exec { _docker_container_exec } -_docker_export() { +function _docker_export { _docker_container_export } -_docker_help() { +function _docker_help { local counter=$(__docker_pos_first_nonflag) if [ "$cword" -eq "$counter" ]; then COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) fi } -_docker_history() { +function _docker_history { _docker_image_history } -_docker_image() { +function _docker_image { local subcommands=" build history @@ -2777,7 +2785,7 @@ _docker_image() { esac } -_docker_image_build() { +function _docker_image_build { local options_with_args=" --add-host --build-arg @@ -2920,7 +2928,7 @@ _docker_image_build() { esac } -_docker_image_history() { +function _docker_image_history { case "$prev" in --format) return @@ -2940,11 +2948,11 @@ _docker_image_history() { esac } -_docker_image_images() { +function _docker_image_images { _docker_image_ls } -_docker_image_import() { +function _docker_image_import { case "$prev" in --change|-c|--message|-m|--platform) return @@ -2969,11 +2977,11 @@ _docker_image_import() { esac } -_docker_image_inspect() { +function _docker_image_inspect { _docker_inspect --type image } -_docker_image_load() { +function _docker_image_load { case "$prev" in --input|-i|"<") _filedir @@ -2988,11 +2996,11 @@ _docker_image_load() { esac } -_docker_image_list() { +function _docker_image_list { _docker_image_ls } -_docker_image_ls() { +function _docker_image_ls { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in before|since) @@ -3036,7 +3044,7 @@ _docker_image_ls() { esac } -_docker_image_prune() { +function _docker_image_prune { case "$prev" in --filter) COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) @@ -3052,7 +3060,7 @@ _docker_image_prune() { esac } -_docker_image_pull() { +function _docker_image_pull { case "$prev" in --platform) return @@ -3081,7 +3089,7 @@ _docker_image_pull() { esac } -_docker_image_push() { +function _docker_image_push { case "$cur" in -*) COMPREPLY=( $( compgen -W "--all-tags -a --disable-content-trust=false --help --quiet -q" -- "$cur" ) ) @@ -3095,11 +3103,11 @@ _docker_image_push() { esac } -_docker_image_remove() { +function _docker_image_remove { _docker_image_rm } -_docker_image_rm() { +function _docker_image_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--force -f --help --no-prune" -- "$cur" ) ) @@ -3110,11 +3118,11 @@ _docker_image_rm() { esac } -_docker_image_rmi() { +function _docker_image_rmi { _docker_image_rm } -_docker_image_save() { +function _docker_image_save { case "$prev" in --output|-o|">") _filedir @@ -3132,7 +3140,7 @@ _docker_image_save() { esac } -_docker_image_tag() { +function _docker_image_tag { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -3152,19 +3160,19 @@ _docker_image_tag() { } -_docker_images() { +function _docker_images { _docker_image_ls } -_docker_import() { +function _docker_import { _docker_image_import } -_docker_info() { +function _docker_info { _docker_system_info } -_docker_inspect() { +function _docker_inspect { local preselected_type local type @@ -3238,15 +3246,15 @@ _docker_inspect() { esac } -_docker_kill() { +function _docker_kill { _docker_container_kill } -_docker_load() { +function _docker_load { _docker_image_load } -_docker_login() { +function _docker_login { case "$prev" in --password|-p|--username|-u) return @@ -3260,7 +3268,7 @@ _docker_login() { esac } -_docker_logout() { +function _docker_logout { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -3268,11 +3276,11 @@ _docker_logout() { esac } -_docker_logs() { +function _docker_logs { _docker_container_logs } -_docker_network_connect() { +function _docker_network_connect { local options_with_args=" --alias --ip @@ -3318,7 +3326,7 @@ _docker_network_connect() { esac } -_docker_network_create() { +function _docker_network_create { case "$prev" in --aux-address|--gateway|--ip-range|--ipam-opt|--ipv6|--opt|-o|--subnet) return @@ -3352,7 +3360,7 @@ _docker_network_create() { esac } -_docker_network_disconnect() { +function _docker_network_disconnect { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -3368,7 +3376,7 @@ _docker_network_disconnect() { esac } -_docker_network_inspect() { +function _docker_network_inspect { case "$prev" in --format|-f) return @@ -3384,7 +3392,7 @@ _docker_network_inspect() { esac } -_docker_network_ls() { +function _docker_network_ls { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in dangling) @@ -3431,7 +3439,7 @@ _docker_network_ls() { esac } -_docker_network_prune() { +function _docker_network_prune { case "$prev" in --filter) COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) @@ -3447,7 +3455,7 @@ _docker_network_prune() { esac } -_docker_network_rm() { +function _docker_network_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) @@ -3457,7 +3465,7 @@ _docker_network_rm() { esac } -_docker_network() { +function _docker_network { local subcommands=" connect create @@ -3483,7 +3491,7 @@ _docker_network() { esac } -_docker_service() { +function _docker_service { local subcommands=" create inspect @@ -3512,11 +3520,11 @@ _docker_service() { esac } -_docker_service_create() { +function _docker_service_create { _docker_service_update_and_create } -_docker_service_inspect() { +function _docker_service_inspect { case "$prev" in --format|-f) return @@ -3532,7 +3540,7 @@ _docker_service_inspect() { esac } -_docker_service_logs() { +function _docker_service_logs { case "$prev" in --since|--tail|-n) return @@ -3552,11 +3560,11 @@ _docker_service_logs() { esac } -_docker_service_list() { +function _docker_service_list { _docker_service_ls } -_docker_service_ls() { +function _docker_service_ls { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in id) @@ -3591,11 +3599,11 @@ _docker_service_ls() { esac } -_docker_service_remove() { +function _docker_service_remove { _docker_service_rm } -_docker_service_rm() { +function _docker_service_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -3605,7 +3613,7 @@ _docker_service_rm() { esac } -_docker_service_rollback() { +function _docker_service_rollback { case "$cur" in -*) COMPREPLY=( $( compgen -W "--detach -d --help --quit -q" -- "$cur" ) ) @@ -3619,7 +3627,7 @@ _docker_service_rollback() { esac } -_docker_service_scale() { +function _docker_service_scale { case "$cur" in -*) COMPREPLY=( $( compgen -W "--detach -d --help" -- "$cur" ) ) @@ -3632,7 +3640,7 @@ _docker_service_scale() { esac } -_docker_service_ps() { +function _docker_service_ps { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in desired-state) @@ -3670,13 +3678,13 @@ _docker_service_ps() { esac } -_docker_service_update() { +function _docker_service_update { _docker_service_update_and_create } # _docker_service_update_and_create is the combined completion for `docker service create` # and `docker service update` -_docker_service_update_and_create() { +function _docker_service_update_and_create { local options_with_args=" --cap-add --cap-drop @@ -3957,7 +3965,7 @@ _docker_service_update_and_create() { esac } -_docker_swarm() { +function _docker_swarm { local subcommands=" ca init @@ -3980,7 +3988,7 @@ _docker_swarm() { esac } -_docker_swarm_ca() { +function _docker_swarm_ca { case "$prev" in --ca-cert|--ca-key) _filedir @@ -3998,7 +4006,7 @@ _docker_swarm_ca() { esac } -_docker_swarm_init() { +function _docker_swarm_init { case "$prev" in --advertise-addr) if [[ $cur == *: ]] ; then @@ -4038,7 +4046,7 @@ _docker_swarm_init() { esac } -_docker_swarm_join() { +function _docker_swarm_join { case "$prev" in --advertise-addr) if [[ $cur == *: ]] ; then @@ -4081,7 +4089,7 @@ _docker_swarm_join() { esac } -_docker_swarm_join_token() { +function _docker_swarm_join_token { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) ) @@ -4095,7 +4103,7 @@ _docker_swarm_join_token() { esac } -_docker_swarm_leave() { +function _docker_swarm_leave { case "$cur" in -*) COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) @@ -4103,7 +4111,7 @@ _docker_swarm_leave() { esac } -_docker_swarm_unlock() { +function _docker_swarm_unlock { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -4111,7 +4119,7 @@ _docker_swarm_unlock() { esac } -_docker_swarm_unlock_key() { +function _docker_swarm_unlock_key { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) ) @@ -4119,7 +4127,7 @@ _docker_swarm_unlock_key() { esac } -_docker_swarm_update() { +function _docker_swarm_update { case "$prev" in --cert-expiry|--dispatcher-heartbeat|--external-ca|--max-snapshots|--snapshot-interval|--task-history-limit) return @@ -4133,7 +4141,7 @@ _docker_swarm_update() { esac } -_docker_manifest() { +function _docker_manifest { local subcommands=" annotate create @@ -4153,7 +4161,7 @@ _docker_manifest() { esac } -_docker_manifest_annotate() { +function _docker_manifest_annotate { case "$prev" in --arch) COMPREPLY=( $( compgen -W " @@ -4199,7 +4207,7 @@ _docker_manifest_annotate() { esac } -_docker_manifest_create() { +function _docker_manifest_create { case "$cur" in -*) COMPREPLY=( $( compgen -W "--amend -a --help --insecure" -- "$cur" ) ) @@ -4210,7 +4218,7 @@ _docker_manifest_create() { esac } -_docker_manifest_inspect() { +function _docker_manifest_inspect { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help --insecure --verbose -v" -- "$cur" ) ) @@ -4224,7 +4232,7 @@ _docker_manifest_inspect() { esac } -_docker_manifest_push() { +function _docker_manifest_push { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help --insecure --purge -p" -- "$cur" ) ) @@ -4238,7 +4246,7 @@ _docker_manifest_push() { esac } -_docker_manifest_rm() { +function _docker_manifest_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -4249,7 +4257,7 @@ _docker_manifest_rm() { esac } -_docker_node() { +function _docker_node { local subcommands=" demote inspect @@ -4275,7 +4283,7 @@ _docker_node() { esac } -_docker_node_demote() { +function _docker_node_demote { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -4285,7 +4293,7 @@ _docker_node_demote() { esac } -_docker_node_inspect() { +function _docker_node_inspect { case "$prev" in --format|-f) return @@ -4301,11 +4309,11 @@ _docker_node_inspect() { esac } -_docker_node_list() { +function _docker_node_list { _docker_node_ls } -_docker_node_ls() { +function _docker_node_ls { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in id) @@ -4347,7 +4355,7 @@ _docker_node_ls() { esac } -_docker_node_promote() { +function _docker_node_promote { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -4357,11 +4365,11 @@ _docker_node_promote() { esac } -_docker_node_remove() { +function _docker_node_remove { _docker_node_rm } -_docker_node_rm() { +function _docker_node_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) @@ -4371,7 +4379,7 @@ _docker_node_rm() { esac } -_docker_node_ps() { +function _docker_node_ps { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in desired-state) @@ -4405,7 +4413,7 @@ _docker_node_ps() { esac } -_docker_node_update() { +function _docker_node_update { case "$prev" in --availability) COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) ) @@ -4433,11 +4441,11 @@ _docker_node_update() { esac } -_docker_pause() { +function _docker_pause { _docker_container_pause } -_docker_plugin() { +function _docker_plugin { local subcommands=" create disable @@ -4466,7 +4474,7 @@ _docker_plugin() { esac } -_docker_plugin_create() { +function _docker_plugin_create { case "$cur" in -*) COMPREPLY=( $( compgen -W "--compress --help" -- "$cur" ) ) @@ -4483,7 +4491,7 @@ _docker_plugin_create() { esac } -_docker_plugin_disable() { +function _docker_plugin_disable { case "$cur" in -*) COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) @@ -4497,7 +4505,7 @@ _docker_plugin_disable() { esac } -_docker_plugin_enable() { +function _docker_plugin_enable { case "$prev" in --timeout) return @@ -4517,7 +4525,7 @@ _docker_plugin_enable() { esac } -_docker_plugin_inspect() { +function _docker_plugin_inspect { case "$prev" in --format|f) return @@ -4534,7 +4542,7 @@ _docker_plugin_inspect() { esac } -_docker_plugin_install() { +function _docker_plugin_install { case "$prev" in --alias) return @@ -4548,11 +4556,11 @@ _docker_plugin_install() { esac } -_docker_plugin_list() { +function _docker_plugin_list { _docker_plugin_ls } -_docker_plugin_ls() { +function _docker_plugin_ls { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in capability) @@ -4583,7 +4591,7 @@ _docker_plugin_ls() { esac } -_docker_plugin_push() { +function _docker_plugin_push { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -4597,11 +4605,11 @@ _docker_plugin_push() { esac } -_docker_plugin_remove() { +function _docker_plugin_remove { _docker_plugin_rm } -_docker_plugin_rm() { +function _docker_plugin_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) @@ -4612,7 +4620,7 @@ _docker_plugin_rm() { esac } -_docker_plugin_set() { +function _docker_plugin_set { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -4626,7 +4634,7 @@ _docker_plugin_set() { esac } -_docker_plugin_upgrade() { +function _docker_plugin_upgrade { case "$cur" in -*) COMPREPLY=( $( compgen -W "--disable-content-trust --grant-all-permissions --help --skip-remote-check" -- "$cur" ) ) @@ -4646,48 +4654,48 @@ _docker_plugin_upgrade() { } -_docker_port() { +function _docker_port { _docker_container_port } -_docker_ps() { +function _docker_ps { _docker_container_ls } -_docker_pull() { +function _docker_pull { _docker_image_pull } -_docker_push() { +function _docker_push { _docker_image_push } -_docker_rename() { +function _docker_rename { _docker_container_rename } -_docker_restart() { +function _docker_restart { _docker_container_restart } -_docker_rm() { +function _docker_rm { _docker_container_rm } -_docker_rmi() { +function _docker_rmi { _docker_image_rm } -_docker_run() { +function _docker_run { _docker_container_run } -_docker_save() { +function _docker_save { _docker_image_save } -_docker_secret() { +function _docker_secret { local subcommands=" create inspect @@ -4710,7 +4718,7 @@ _docker_secret() { esac } -_docker_secret_create() { +function _docker_secret_create { case "$prev" in --driver|-d|--label|-l) return @@ -4734,7 +4742,7 @@ _docker_secret_create() { esac } -_docker_secret_inspect() { +function _docker_secret_inspect { case "$prev" in --format|-f) return @@ -4751,11 +4759,11 @@ _docker_secret_inspect() { esac } -_docker_secret_list() { +function _docker_secret_list { _docker_secret_ls } -_docker_secret_ls() { +function _docker_secret_ls { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in id) @@ -4786,11 +4794,11 @@ _docker_secret_ls() { esac } -_docker_secret_remove() { +function _docker_secret_remove { _docker_secret_rm } -_docker_secret_rm() { +function _docker_secret_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -4803,7 +4811,7 @@ _docker_secret_rm() { -_docker_search() { +function _docker_search { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in is-automated) @@ -4835,7 +4843,7 @@ _docker_search() { } -_docker_stack() { +function _docker_stack { local subcommands=" config deploy @@ -4863,7 +4871,7 @@ _docker_stack() { esac } -_docker_stack_config() { +function _docker_stack_config { case "$prev" in --compose-file|-c) _filedir yml @@ -4878,7 +4886,7 @@ _docker_stack_config() { esac } -_docker_stack_deploy() { +function _docker_stack_deploy { case "$prev" in --compose-file|-c) _filedir yml @@ -4903,15 +4911,15 @@ _docker_stack_deploy() { esac } -_docker_stack_down() { +function _docker_stack_down { _docker_stack_rm } -_docker_stack_list() { +function _docker_stack_list { _docker_stack_ls } -_docker_stack_ls() { +function _docker_stack_ls { case "$prev" in --format) return @@ -4925,7 +4933,7 @@ _docker_stack_ls() { esac } -_docker_stack_ps() { +function _docker_stack_ps { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in desired-state) @@ -4966,11 +4974,11 @@ _docker_stack_ps() { esac } -_docker_stack_remove() { +function _docker_stack_remove { _docker_stack_rm } -_docker_stack_rm() { +function _docker_stack_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -4981,7 +4989,7 @@ _docker_stack_rm() { esac } -_docker_stack_services() { +function _docker_stack_services { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in id) @@ -5021,25 +5029,25 @@ _docker_stack_services() { esac } -_docker_stack_up() { +function _docker_stack_up { _docker_stack_deploy } -_docker_start() { +function _docker_start { _docker_container_start } -_docker_stats() { +function _docker_stats { _docker_container_stats } -_docker_stop() { +function _docker_stop { _docker_container_stop } -_docker_system() { +function _docker_system { local subcommands=" df events @@ -5058,7 +5066,7 @@ _docker_system() { esac } -_docker_system_df() { +function _docker_system_df { case "$prev" in --format) return @@ -5072,7 +5080,7 @@ _docker_system_df() { esac } -_docker_system_events() { +function _docker_system_events { local key=$(__docker_map_key_of_current_option '-f|--filter') case "$key" in container) @@ -5174,7 +5182,7 @@ _docker_system_events() { esac } -_docker_system_info() { +function _docker_system_info { case "$prev" in --format|-f) return @@ -5188,7 +5196,7 @@ _docker_system_info() { esac } -_docker_system_prune() { +function _docker_system_prune { case "$prev" in --filter) COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) @@ -5205,12 +5213,12 @@ _docker_system_prune() { } -_docker_tag() { +function _docker_tag { _docker_image_tag } -_docker_trust() { +function _docker_trust { local subcommands=" inspect revoke @@ -5228,7 +5236,7 @@ _docker_trust() { esac } -_docker_trust_inspect() { +function _docker_trust_inspect { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help --pretty" -- "$cur" ) ) @@ -5242,7 +5250,7 @@ _docker_trust_inspect() { esac } -_docker_trust_revoke() { +function _docker_trust_revoke { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help --yes -y" -- "$cur" ) ) @@ -5256,7 +5264,7 @@ _docker_trust_revoke() { esac } -_docker_trust_sign() { +function _docker_trust_sign { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help --local" -- "$cur" ) ) @@ -5271,19 +5279,19 @@ _docker_trust_sign() { } -_docker_unpause() { +function _docker_unpause { _docker_container_unpause } -_docker_update() { +function _docker_update { _docker_container_update } -_docker_top() { +function _docker_top { _docker_container_top } -_docker_version() { +function _docker_version { case "$prev" in --format|-f) return @@ -5297,7 +5305,7 @@ _docker_version() { esac } -_docker_volume_create() { +function _docker_volume_create { case "$prev" in --driver|-d) __docker_complete_plugins_bundled --type Volume @@ -5315,7 +5323,7 @@ _docker_volume_create() { esac } -_docker_volume_inspect() { +function _docker_volume_inspect { case "$prev" in --format|-f) return @@ -5332,11 +5340,11 @@ _docker_volume_inspect() { esac } -_docker_volume_list() { +function _docker_volume_list { _docker_volume_ls } -_docker_volume_ls() { +function _docker_volume_ls { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in dangling) @@ -5371,7 +5379,7 @@ _docker_volume_ls() { esac } -_docker_volume_prune() { +function _docker_volume_prune { case "$prev" in --filter) COMPREPLY=( $( compgen -W "label label!" -S = -- "$cur" ) ) @@ -5387,11 +5395,11 @@ _docker_volume_prune() { esac } -_docker_volume_remove() { +function _docker_volume_remove { _docker_volume_rm } -_docker_volume_rm() { +function _docker_volume_rm { case "$cur" in -*) COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) @@ -5402,7 +5410,7 @@ _docker_volume_rm() { esac } -_docker_volume() { +function _docker_volume { local subcommands=" create inspect @@ -5426,11 +5434,11 @@ _docker_volume() { esac } -_docker_wait() { +function _docker_wait { _docker_container_wait } -_docker() { +function _docker { local previous_extglob_setting=$(shopt -p extglob) shopt -s extglob @@ -5591,7 +5599,7 @@ _docker() { fi local completions_func=_docker_${command//-/_} - declare -F $completions_func >/dev/null && $completions_func + _omb_util_function_exists "$completions_func" && "$completions_func" eval "$previous_extglob_setting" return 0 From 767238b86f3c5a55ff1bad57298407a30057430c Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sun, 11 Feb 2024 11:56:49 +0900 Subject: [PATCH 3/3] completion/docker{,-compose}: Search completion in the system first --- completions/docker-compose.completion.sh | 600 +---- completions/docker.completion.sh | 3013 +--------------------- 2 files changed, 91 insertions(+), 3522 deletions(-) diff --git a/completions/docker-compose.completion.sh b/completions/docker-compose.completion.sh index b6121055b..e5d4488a7 100644 --- a/completions/docker-compose.completion.sh +++ b/completions/docker-compose.completion.sh @@ -1,561 +1,43 @@ #! bash oh-my-bash.module -# -# bash completion for docker-compose -# -# This work is based on the completion for the docker command. -# -# This script provides completion of: -# - commands and their options -# - service names -# - filepaths -# -# To enable the completions either: -# - place this file in /etc/bash_completion.d -# or -# - copy this file to e.g. ~/.docker-compose-completion.sh and add the line -# below to your .bashrc after bash completion features are loaded -# . ~/.docker-compose-completion.sh - -function __docker_compose_q { - docker-compose 2>/dev/null $daemon_options "$@" -} - -# Transforms a multiline list of strings into a single line string -# with the words separated by "|". -function __docker_compose_to_alternatives { - local parts=( $1 ) - local IFS='|' - echo "${parts[*]}" -} - -# Transforms a multiline list of options into an extglob pattern -# suitable for use in case statements. -function __docker_compose_to_extglob { - local extglob=$( __docker_compose_to_alternatives "$1" ) - echo "@($extglob)" -} - -# suppress trailing whitespace -function __docker_compose_nospace { - # compopt is not available in ancient bash versions - _omb_util_command_exists compopt && compopt -o nospace -} - -# Extracts all service names from the compose file. -function ___docker_compose_all_services_in_compose_file { - __docker_compose_q config --services -} - -# All services, even those without an existing container -function __docker_compose_services_all { - COMPREPLY=( $(compgen -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") ) -} - -# All services that have an entry with the given key in their compose_file section -function ___docker_compose_services_with_key { - # flatten sections under "services" to one line, then filter lines containing the key and return section name - __docker_compose_q config \ - | sed -n -e '/^services:/,/^[^ ]/p' \ - | sed -n 's/^ //p' \ - | awk '/^[a-zA-Z0-9]/{printf "\n"};{printf $0;next;}' \ - | awk -F: -v key=": +$1:" '$0 ~ key {print $1}' -} - -# All services that are defined by a Dockerfile reference -function __docker_compose_services_from_build { - COMPREPLY=( $(compgen -W "$(___docker_compose_services_with_key build)" -- "$cur") ) -} - -# All services that are defined by an image -function __docker_compose_services_from_image { - COMPREPLY=( $(compgen -W "$(___docker_compose_services_with_key image)" -- "$cur") ) -} - -# The services for which containers have been created, optionally filtered -# by a boolean expression passed in as argument. -function __docker_compose_services_with { - local containers names - containers="$(__docker_compose_q ps -q)" - names=$(docker 2>/dev/null inspect -f "{{if ${1:-true}}}{{range \$k, \$v := .Config.Labels}}{{if eq \$k \"com.docker.compose.service\"}}{{\$v}}{{end}}{{end}}{{end}}" $containers) - COMPREPLY=( $(compgen -W "$names" -- "$cur") ) -} - -# The services for which at least one paused container exists -function __docker_compose_services_paused { - __docker_compose_services_with '.State.Paused' -} - -# The services for which at least one running container exists -function __docker_compose_services_running { - __docker_compose_services_with '.State.Running' -} - -# The services for which at least one stopped container exists -function __docker_compose_services_stopped { - __docker_compose_services_with 'not .State.Running' -} - - -function _docker_compose_build { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force-rm --help --no-cache --pull" -- "$cur" ) ) - ;; - *) - __docker_compose_services_from_build - ;; - esac -} - - -function _docker_compose_bundle { - case "$prev" in - --output|-o) - _filedir - return - ;; - esac - - COMPREPLY=( $( compgen -W "--fetch-digests --help --output -o" -- "$cur" ) ) -} - - -function _docker_compose_config { - COMPREPLY=( $( compgen -W "--help --quiet -q --services" -- "$cur" ) ) -} - - -function _docker_compose_create { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force-recreate --help --no-build --no-recreate" -- "$cur" ) ) - ;; - *) - __docker_compose_services_all - ;; - esac -} - - -function _docker_compose_docker_compose { - case "$prev" in - --tlscacert|--tlscert|--tlskey) - _filedir - return - ;; - --file|-f) - _filedir "y?(a)ml" - return - ;; - $(__docker_compose_to_extglob "$daemon_options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$daemon_boolean_options $daemon_options_with_args --help -h --verbose --version -v" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) - ;; - esac -} - - -function _docker_compose_down { - case "$prev" in - --rmi) - COMPREPLY=( $( compgen -W "all local" -- "$cur" ) ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --rmi --volumes -v --remove-orphans" -- "$cur" ) ) - ;; - esac -} - - -function _docker_compose_events { - case "$prev" in - --json) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --json" -- "$cur" ) ) - ;; - *) - __docker_compose_services_all - ;; - esac -} - - -function _docker_compose_exec { - case "$prev" in - --index|--user) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "-d --help --index --privileged -T --user" -- "$cur" ) ) - ;; - *) - __docker_compose_services_running - ;; - esac -} - - -function _docker_compose_help { - COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) -} - - -function _docker_compose_kill { - case "$prev" in - -s) - COMPREPLY=( $( compgen -W "SIGHUP SIGINT SIGKILL SIGUSR1 SIGUSR2" -- "$(echo $cur | tr '[:lower:]' '[:upper:]')" ) ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help -s" -- "$cur" ) ) - ;; - *) - __docker_compose_services_running - ;; - esac -} - - -function _docker_compose_logs { - case "$prev" in - --tail) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--follow -f --help --no-color --tail --timestamps -t" -- "$cur" ) ) - ;; - *) - __docker_compose_services_all - ;; - esac -} - - -function _docker_compose_pause { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_compose_services_running - ;; - esac -} - - -function _docker_compose_port { - case "$prev" in - --protocol) - COMPREPLY=( $( compgen -W "tcp udp" -- "$cur" ) ) - return; - ;; - --index) - return; - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --index --protocol" -- "$cur" ) ) - ;; - *) - __docker_compose_services_all - ;; - esac -} - - -function _docker_compose_ps { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help -q" -- "$cur" ) ) - ;; - *) - __docker_compose_services_all - ;; - esac -} - - -function _docker_compose_pull { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --ignore-pull-failures" -- "$cur" ) ) - ;; - *) - __docker_compose_services_from_image - ;; - esac -} - - -function _docker_compose_push { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --ignore-push-failures" -- "$cur" ) ) - ;; - *) - __docker_compose_services_all - ;; - esac -} - - -function _docker_compose_restart { - case "$prev" in - --timeout|-t) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) ) - ;; - *) - __docker_compose_services_running - ;; - esac -} - - -function _docker_compose_rm { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --help -v" -- "$cur" ) ) - ;; - *) - __docker_compose_services_stopped - ;; - esac -} - - -function _docker_compose_run { - case "$prev" in - -e) - COMPREPLY=( $( compgen -e -- "$cur" ) ) - __docker_compose_nospace - return - ;; - --entrypoint|--name|--user|-u|--workdir|-w) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "-d --entrypoint -e --help --name --no-deps --publish -p --rm --service-ports -T --user -u --workdir -w" -- "$cur" ) ) - ;; - *) - __docker_compose_services_all - ;; - esac -} - - -function _docker_compose_scale { - case "$prev" in - =) - COMPREPLY=("$cur") - return - ;; - --timeout|-t) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") ) - __docker_compose_nospace - ;; - esac -} - - -function _docker_compose_start { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_compose_services_stopped - ;; - esac -} - - -function _docker_compose_stop { - case "$prev" in - --timeout|-t) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) ) - ;; - *) - __docker_compose_services_running - ;; - esac -} - - -function _docker_compose_unpause { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_compose_services_paused - ;; - esac -} - - -function _docker_compose_up { - case "$prev" in - --timeout|-t) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--abort-on-container-exit --build -d --force-recreate --help --no-build --no-color --no-deps --no-recreate --timeout -t --remove-orphans" -- "$cur" ) ) - ;; - *) - __docker_compose_services_all - ;; - esac -} - - -function _docker_compose_version { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--short" -- "$cur" ) ) - ;; - esac -} - - -function _docker_compose { - local previous_extglob_setting=$(shopt -p extglob) - shopt -s extglob - - local commands=( - build - bundle - config - create - down - events - exec - help - kill - logs - pause - port - ps - pull - push - restart - rm - run - scale - start - stop - unpause - up - version - ) - - # options for the docker daemon that have to be passed to secondary calls to - # docker-compose executed by this script - local daemon_boolean_options=" - --skip-hostname-check - --tls - --tlsverify - " - local daemon_options_with_args=" - --file -f - --host -H - --project-name -p - --tlscacert - --tlscert - --tlskey - " - - COMPREPLY=() - local cur prev words cword - _get_comp_words_by_ref -n : cur prev words cword - - # search subcommand and invoke its handler. - # special treatment of some top-level options - local command='docker_compose' - local daemon_options=() - local counter=1 - - while [ $counter -lt $cword ]; do - case "${words[$counter]}" in - $(__docker_compose_to_extglob "$daemon_boolean_options") ) - local opt=${words[counter]} - daemon_options+=($opt) - ;; - $(__docker_compose_to_extglob "$daemon_options_with_args") ) - local opt=${words[counter]} - local arg=${words[++counter]} - daemon_options+=($opt $arg) - ;; - -*) - ;; - *) - command="${words[$counter]}" - break - ;; - esac - (( counter++ )) - done - - local completions_func=_docker_compose_${command//-/_} - _omb_util_function_exists "$completions_func" && "$completions_func" - - eval "$previous_extglob_setting" - return 0 -} - -complete -F _docker_compose docker-compose +function _omb_completion_docker_compose_has_completion { + local complete + complete=$(complete -p docker-compose 2>/dev/null) && [[ $complete ]] || return 1 + + unset -f _omb_completion_docker_compose_has_completion + unset -f _omb_completion_docker_compose_try + return 0 +} + +function _omb_completion_docker_compose_try { + if [[ -s $1 ]]; then + source "$1" + _omb_completion_docker_compose_has_completion && return 0 + elif [[ -s $1.sh ]]; then + source "$1.sh" + _omb_completion_docker_compose_has_completion && return 0 + elif [[ -s $1.bash ]]; then + source "$1.bash" + _omb_completion_docker_compose_has_completion && return 0 + fi + return 1 +} + +_omb_completion_docker_compose_has_completion && return 0 + +if _omb_util_function_exists _comp_load; then + # bash-completion 2.12 + _comp_load -- docker-compose + _omb_completion_docker_compose_has_completion && return 0 +elif _omb_util_function_exists __load_completion; then + # bash-completion <= 2.11 + __load_completion docker-compose + _omb_completion_docker_compose_has_completion && return 0 +fi + +_omb_completion_docker_compose_try /usr/share/bash-completion/completions/docker-compose && return 0 +_omb_completion_docker_compose_try /etc/bash_completion.d/docker-compose && return 0 + +unset -f _omb_completion_docker_compose_has_completion +unset -f _omb_completion_docker_compose_try +source "$OSH/completions/fallback/docker-compose.bash" diff --git a/completions/docker.completion.sh b/completions/docker.completion.sh index bac3b7cb0..ae02819bf 100644 --- a/completions/docker.completion.sh +++ b/completions/docker.completion.sh @@ -1,2965 +1,52 @@ #! bash oh-my-bash.module -# -# bash completion file for core docker commands -# -# This script provides completion of: -# - commands and their options -# - container ids and names -# - image repos and tags -# - filepaths -# -# To enable the completions either: -# - place this file in /etc/bash_completion.d -# or -# - copy this file to e.g. ~/.docker-completion.sh and add the line -# below to your .bashrc after bash completion features are loaded -# . ~/.docker-completion.sh -# -# Configuration: -# -# For several commands, the amount of completions can be configured by -# setting environment variables. -# -# DOCKER_COMPLETION_SHOW_NETWORK_IDS -# DOCKER_COMPLETION_SHOW_NODE_IDS -# DOCKER_COMPLETION_SHOW_SERVICE_IDS -# "no" - Show names only (default) -# "yes" - Show names and ids -# -# You can tailor completion for the "events", "history", "inspect", "run", -# "rmi" and "save" commands by settings the following environment -# variables: -# -# DOCKER_COMPLETION_SHOW_IMAGE_IDS -# "none" - Show names only (default) -# "non-intermediate" - Show names and ids, but omit intermediate image IDs -# "all" - Show names and ids, including intermediate image IDs -# -# DOCKER_COMPLETION_SHOW_TAGS -# "yes" - include tags in completion options (default) -# "no" - don't include tags in completion options -# -# Note: -# Currently, the completions will not work if the docker daemon is not -# bound to the default communication port/socket -# If the docker daemon is using a unix socket for communication your user -# must have access to the socket for the completions to function correctly -# -# Note for developers: -# Please arrange options sorted alphabetically by long name with the short -# options immediately following their corresponding long form. -# This order should be applied to lists, alternatives and code blocks. - -__docker_previous_extglob_setting=$(shopt -p extglob) -shopt -s extglob - -function __docker_q { - docker ${host:+-H "$host"} ${config:+--config "$config"} 2>/dev/null "$@" -} - -function __docker_complete_containers_all { - local IFS=$'\n' - local containers=( $(__docker_q ps -aq --no-trunc) ) - if [ "$1" ]; then - containers=( $(__docker_q inspect --format "{{if $1}}{{.Id}}{{end}}" "${containers[@]}") ) - fi - local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") ) - names=( "${names[@]#/}" ) # trim off the leading "/" from the container names - unset IFS - COMPREPLY=( $(compgen -W "${names[*]} ${containers[*]}" -- "$cur") ) -} - -function __docker_complete_containers_running { - __docker_complete_containers_all '.State.Running' -} - -function __docker_complete_containers_stopped { - __docker_complete_containers_all 'not .State.Running' -} - -function __docker_complete_containers_pauseable { - __docker_complete_containers_all 'and .State.Running (not .State.Paused)' -} - -function __docker_complete_containers_unpauseable { - __docker_complete_containers_all '.State.Paused' -} - -function __docker_complete_container_names { - local containers=( $(__docker_q ps -aq --no-trunc) ) - local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") ) - names=( "${names[@]#/}" ) # trim off the leading "/" from the container names - COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") ) -} - -function __docker_complete_container_ids { - local containers=( $(__docker_q ps -aq) ) - COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") ) -} - -function __docker_complete_images { - local images_args="" - - case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in - all) - images_args="--no-trunc -a" - ;; - non-intermediate) - images_args="--no-trunc" - ;; - esac - - local repo_print_command - if [ "${DOCKER_COMPLETION_SHOW_TAGS:-yes}" = "yes" ]; then - repo_print_command='print $1; print $1":"$2' - else - repo_print_command='print $1' - fi - - local awk_script - case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in - all|non-intermediate) - awk_script='NR>1 { print $3; if ($1 != "") { '"$repo_print_command"' } }' - ;; - none|*) - awk_script='NR>1 && $1 != "" { '"$repo_print_command"' }' - ;; - esac - - local images=$(__docker_q images $images_args | awk "$awk_script") - COMPREPLY=( $(compgen -W "$images" -- "$cur") ) - __ltrim_colon_completions "$cur" -} - -function __docker_complete_image_repos { - local repos="$(__docker_q images | awk 'NR>1 && $1 != "" { print $1 }')" - COMPREPLY=( $(compgen -W "$repos" -- "$cur") ) -} - -function __docker_complete_image_repos_and_tags { - local reposAndTags="$(__docker_q images | awk 'NR>1 && $1 != "" { print $1; print $1":"$2 }')" - COMPREPLY=( $(compgen -W "$reposAndTags" -- "$cur") ) - __ltrim_colon_completions "$cur" -} - -function __docker_complete_containers_and_images { - __docker_complete_containers_all - local containers=( "${COMPREPLY[@]}" ) - __docker_complete_images - COMPREPLY+=( "${containers[@]}" ) -} - -# Returns the names and optionally IDs of networks. -# The selection can be narrowed by an optional filter parameter, e.g. 'type=custom' -function __docker_networks { - local filter="$1" - # By default, only network names are completed. - # Set DOCKER_COMPLETION_SHOW_NETWORK_IDS=yes to also complete network IDs. - local fields='$2' - [ "${DOCKER_COMPLETION_SHOW_NETWORK_IDS}" = yes ] && fields='$1,$2' - __docker_q network ls --no-trunc ${filter:+-f "$filter"} | awk "NR>1 {print $fields}" - #__docker_q network ls --no-trunc | awk "NR>1 {print $fields}" -} - -function __docker_complete_networks { - COMPREPLY=( $(compgen -W "$(__docker_networks $@)" -- "$cur") ) -} - -function __docker_complete_network_ids { - COMPREPLY=( $(compgen -W "$(__docker_q network ls -q --no-trunc)" -- "$cur") ) -} - -function __docker_complete_network_names { - COMPREPLY=( $(compgen -W "$(__docker_q network ls | awk 'NR>1 {print $2}')" -- "$cur") ) -} - -function __docker_complete_containers_in_network { - local containers=$(__docker_q network inspect -f '{{range $i, $c := .Containers}}{{$i}} {{$c.Name}} {{end}}' "$1") - COMPREPLY=( $(compgen -W "$containers" -- "$cur") ) -} - -function __docker_complete_volumes { - COMPREPLY=( $(compgen -W "$(__docker_q volume ls -q)" -- "$cur") ) -} - -function __docker_plugins { - __docker_q info | sed -n "/^Plugins/,/^[^ ]/s/ $1: //p" -} - -function __docker_complete_plugins { - COMPREPLY=( $(compgen -W "$(__docker_plugins $1)" -- "$cur") ) -} - -function __docker_runtimes { - __docker_q info | sed -n 's/^Runtimes: \(.*\)/\1/p' -} - -function __docker_complete_runtimes { - COMPREPLY=( $(compgen -W "$(__docker_runtimes)" -- "$cur") ) -} - -# Returns a list of all nodes. Additional arguments to `docker node` -# may be specified in order to filter the node list, e.g. -# `__docker_nodes --filter role=manager` -# By default, only node names are completed. -# Set DOCKER_COMPLETION_SHOW_NODE_IDS=yes to also complete node IDs. -# An optional first argument `--id|--name` may be used to limit -# the output to the IDs or names of matching nodes. This setting takes -# precedence over the environment setting. -function __docker_nodes { - local fields='$2' # default: node name only - [ "${DOCKER_COMPLETION_SHOW_NODE_IDS}" = yes ] && fields='$1,$2' # ID and name - - if [ "$1" = "--id" ] ; then - fields='$1' # IDs only - shift - elif [ "$1" = "--name" ] ; then - fields='$2' # names only - shift - fi - __docker_q node ls "$@" | tr -d '*' | awk "NR>1 {print $fields}" -} - -# Applies completion of nodes based on the current value of `$cur` or -# the value of the optional first argument `--cur`, if given. -# Additional filters may be appended, see `__docker_nodes`. -function __docker_complete_nodes { - local current=$cur - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__docker_nodes "$@")" -- "$current") ) -} - -function __docker_complete_nodes_plus_self { - __docker_complete_nodes "$@" - COMPREPLY+=( self ) -} - -# Returns a list of all services. Additional arguments to `docker service ls` -# may be specified in order to filter the service list, e.g. -# `__docker_services --filter name=xxx` -# By default, only node names are completed. -# Set DOCKER_COMPLETION_SHOW_SERVICE_IDS=yes to also complete service IDs. -# An optional first argument `--id|--name` may be used to limit -# the output to the IDs or names of matching services. This setting takes -# precedence over the environment setting. -function __docker_services { - local fields='$2' # default: service name only - [ "${DOCKER_COMPLETION_SHOW_SERVICE_IDS}" = yes ] && fields='$1,$2' # ID & name - - if [ "$1" = "--id" ] ; then - fields='$1' # IDs only - shift - elif [ "$1" = "--name" ] ; then - fields='$2' # names only - shift - fi - __docker_q service ls "$@" | awk "NR>1 {print $fields}" -} - -# Applies completion of services based on the current value of `$cur` or -# the value of the optional first argument `--cur`, if given. -# Additional filters may be appended, see `__docker_services`. -function __docker_complete_services { - local current=$cur - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__docker_services "$@")" -- "$current") ) -} - -# Appends the word passed as an argument to every word in `$COMPREPLY`. -# Normally you do this with `compgen -S`. This function exists so that you can use -# the __docker_complete_XXX functions in cases where you need a suffix. -function __docker_append_to_completions { - COMPREPLY=( ${COMPREPLY[@]/%/"$1"} ) -} - -# Finds the position of the first word that is neither option nor an option's argument. -# If there are options that require arguments, you should pass a glob describing those -# options, e.g. "--option1|-o|--option2" -# Use this function to restrict completions to exact positions after the argument list. -function __docker_pos_first_nonflag { - local argument_flags=$1 - - local counter=$((${subcommand_pos:-${command_pos}} + 1)) - while [ $counter -le $cword ]; do - if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then - (( counter++ )) - # eat "=" in case of --option=arg syntax - [ "${words[$counter]}" = "=" ] && (( counter++ )) - else - case "${words[$counter]}" in - -*) - ;; - *) - break - ;; - esac - fi - - # Bash splits words at "=", retaining "=" as a word, examples: - # "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words - while [ "${words[$counter + 1]}" = "=" ] ; do - counter=$(( counter + 2)) - done - - (( counter++ )) - done - - echo $counter -} - -# If we are currently completing the value of a map option (key=value) -# which matches the extglob given as an argument, returns key. -# This function is needed for key-specific completions. -function __docker_map_key_of_current_option { - local glob="$1" - - local key glob_pos - if [ "$cur" = "=" ] ; then # key= case - key="$prev" - glob_pos=$((cword - 2)) - elif [[ $cur == *=* ]] ; then # key=value case (OSX) - key=${cur%=*} - glob_pos=$((cword - 1)) - elif [ "$prev" = "=" ] ; then - key=${words[$cword - 2]} # key=value case - glob_pos=$((cword - 3)) - else - return - fi - - [ "${words[$glob_pos]}" = "=" ] && ((glob_pos--)) # --option=key=value syntax - - [[ ${words[$glob_pos]} == @($glob) ]] && echo "$key" -} - -# Returns the value of the first option matching option_glob. -# Valid values for option_glob are option names like '--log-level' and -# globs like '--log-level|-l' -# Only positions between the command and the current word are considered. -function __docker_value_of_option { - local option_extglob=$(__docker_to_extglob "$1") - - local counter=$((command_pos + 1)) - while [ $counter -lt $cword ]; do - case ${words[$counter]} in - $option_extglob ) - echo ${words[$counter + 1]} - break - ;; - esac - (( counter++ )) - done -} - -# Transforms a multiline list of strings into a single line string -# with the words separated by "|". -# This is used to prepare arguments to __docker_pos_first_nonflag(). -function __docker_to_alternatives { - local parts=( $1 ) - local IFS='|' - echo "${parts[*]}" -} - -# Transforms a multiline list of options into an extglob pattern -# suitable for use in case statements. -function __docker_to_extglob { - local extglob=$( __docker_to_alternatives "$1" ) - echo "@($extglob)" -} - -# Subcommand processing. -# Locates the first occurrence of any of the subcommands contained in the -# first argument. In case of a match, calls the corresponding completion -# function and returns 0. -# If no match is found, 1 is returned. The calling function can then -# continue processing its completion. -# -# TODO if the preceding command has options that accept arguments and an -# argument is equal ot one of the subcommands, this is falsely detected as -# a match. -function __docker_subcommands { - local subcommands="$1" - - local counter=$(($command_pos + 1)) - while [ $counter -lt $cword ]; do - case "${words[$counter]}" in - $(__docker_to_extglob "$subcommands") ) - subcommand_pos=$counter - local subcommand=${words[$counter]} - local completions_func=_docker_${command}_${subcommand} - _omb_util_function_exists "$completions_func" && "$completions_func" - return 0 - ;; - esac - (( counter++ )) - done - return 1 -} - -# suppress trailing whitespace -function __docker_nospace { - # compopt is not available in ancient bash versions - _omb_util_command_exists compopt && compopt -o nospace -} - -function __docker_complete_resolved_hostname { - _omb_util_command_exists host || return - COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') ) -} - -function __docker_complete_capabilities { - # The list of capabilities is defined in types.go, ALL was added manually. - COMPREPLY=( $( compgen -W " - ALL - AUDIT_CONTROL - AUDIT_WRITE - AUDIT_READ - BLOCK_SUSPEND - CHOWN - DAC_OVERRIDE - DAC_READ_SEARCH - FOWNER - FSETID - IPC_LOCK - IPC_OWNER - KILL - LEASE - LINUX_IMMUTABLE - MAC_ADMIN - MAC_OVERRIDE - MKNOD - NET_ADMIN - NET_BIND_SERVICE - NET_BROADCAST - NET_RAW - SETFCAP - SETGID - SETPCAP - SETUID - SYS_ADMIN - SYS_BOOT - SYS_CHROOT - SYSLOG - SYS_MODULE - SYS_NICE - SYS_PACCT - SYS_PTRACE - SYS_RAWIO - SYS_RESOURCE - SYS_TIME - SYS_TTY_CONFIG - WAKE_ALARM - " -- "$cur" ) ) -} - -function __docker_complete_detach-keys { - case "$prev" in - --detach-keys) - case "$cur" in - *,) - COMPREPLY=( $( compgen -W "${cur}ctrl-" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "ctrl-" -- "$cur" ) ) - ;; - esac - - __docker_nospace - return - ;; - esac - return 1 -} - -function __docker_complete_isolation { - COMPREPLY=( $( compgen -W "default hyperv process" -- "$cur" ) ) -} - -function __docker_complete_log_drivers { - COMPREPLY=( $( compgen -W " - awslogs - etwlogs - fluentd - gcplogs - gelf - journald - json-file - none - splunk - syslog - " -- "$cur" ) ) -} - -function __docker_complete_log_options { - # see docs/reference/logging/index.md - local awslogs_options="awslogs-region awslogs-group awslogs-stream" - local fluentd_options="env fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries labels tag" - local gcplogs_options="env gcp-log-cmd gcp-project labels" - local gelf_options="env gelf-address gelf-compression-level gelf-compression-type labels tag" - local journald_options="env labels tag" - local json_file_options="env labels max-file max-size" - local syslog_options="syslog-address syslog-format syslog-tls-ca-cert syslog-tls-cert syslog-tls-key syslog-tls-skip-verify syslog-facility tag" - local splunk_options="env labels splunk-caname splunk-capath splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url tag" - - local all_options="$fluentd_options $gcplogs_options $gelf_options $journald_options $json_file_options $syslog_options $splunk_options" - - case $(__docker_value_of_option --log-driver) in - '') - COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) ) - ;; - awslogs) - COMPREPLY=( $( compgen -W "$awslogs_options" -S = -- "$cur" ) ) - ;; - fluentd) - COMPREPLY=( $( compgen -W "$fluentd_options" -S = -- "$cur" ) ) - ;; - gcplogs) - COMPREPLY=( $( compgen -W "$gcplogs_options" -S = -- "$cur" ) ) - ;; - gelf) - COMPREPLY=( $( compgen -W "$gelf_options" -S = -- "$cur" ) ) - ;; - journald) - COMPREPLY=( $( compgen -W "$journald_options" -S = -- "$cur" ) ) - ;; - json-file) - COMPREPLY=( $( compgen -W "$json_file_options" -S = -- "$cur" ) ) - ;; - syslog) - COMPREPLY=( $( compgen -W "$syslog_options" -S = -- "$cur" ) ) - ;; - splunk) - COMPREPLY=( $( compgen -W "$splunk_options" -S = -- "$cur" ) ) - ;; - *) - return - ;; - esac - - __docker_nospace -} - -function __docker_complete_log_driver_options { - local key=$(__docker_map_key_of_current_option '--log-opt') - case "$key" in - fluentd-async-connect) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - gelf-address) - COMPREPLY=( $( compgen -W "udp" -S "://" -- "${cur##*=}" ) ) - __docker_nospace - return - ;; - gelf-compression-level) - COMPREPLY=( $( compgen -W "1 2 3 4 5 6 7 8 9" -- "${cur##*=}" ) ) - return - ;; - gelf-compression-type) - COMPREPLY=( $( compgen -W "gzip none zlib" -- "${cur##*=}" ) ) - return - ;; - syslog-address) - COMPREPLY=( $( compgen -W "tcp:// tcp+tls:// udp:// unix://" -- "${cur##*=}" ) ) - __docker_nospace - __ltrim_colon_completions "${cur}" - return - ;; - syslog-facility) - COMPREPLY=( $( compgen -W " - auth - authpriv - cron - daemon - ftp - kern - local0 - local1 - local2 - local3 - local4 - local5 - local6 - local7 - lpr - mail - news - syslog - user - uucp - " -- "${cur##*=}" ) ) - return - ;; - syslog-format) - COMPREPLY=( $( compgen -W "rfc3164 rfc5424 rfc5424micro" -- "${cur##*=}" ) ) - return - ;; - syslog-tls-ca-cert|syslog-tls-cert|syslog-tls-key) - _filedir - return - ;; - syslog-tls-skip-verify) - COMPREPLY=( $( compgen -W "true" -- "${cur##*=}" ) ) - return - ;; - splunk-url) - COMPREPLY=( $( compgen -W "http:// https://" -- "${cur##*=}" ) ) - __docker_nospace - __ltrim_colon_completions "${cur}" - return - ;; - splunk-insecureskipverify) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - esac - return 1 -} - -function __docker_complete_log_levels { - COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) ) -} - -function __docker_complete_restart { - case "$prev" in - --restart) - case "$cur" in - on-failure:*) - ;; - *) - COMPREPLY=( $( compgen -W "always no on-failure on-failure: unless-stopped" -- "$cur") ) - ;; - esac - return - ;; - esac - return 1 -} - -# a selection of the available signals that is most likely of interest in the -# context of docker containers. -function __docker_complete_signals { - local signals=( - SIGCONT - SIGHUP - SIGINT - SIGKILL - SIGQUIT - SIGSTOP - SIGTERM - SIGUSR1 - SIGUSR2 - ) - COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo $cur | tr '[:lower:]' '[:upper:]')" ) ) -} - -function __docker_complete_user_group { - if [[ $cur == *:* ]] ; then - COMPREPLY=( $(compgen -g -- "${cur#*:}") ) - else - COMPREPLY=( $(compgen -u -S : -- "$cur") ) - __docker_nospace - fi -} - -# global options that may appear after the docker command -function _docker_docker { - local boolean_options=" - $global_boolean_options - --help - --version -v - " - - case "$prev" in - --config) - _filedir -d - return - ;; - --log-level|-l) - __docker_complete_log_levels - return - ;; - $(__docker_to_extglob "$global_options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$boolean_options $global_options_with_args" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag "$(__docker_to_extglob "$global_options_with_args")" ) - if [ $cword -eq $counter ]; then - COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) ) - fi - ;; - esac -} - -function _docker_attach { - __docker_complete_detach-keys && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy=false" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--detach-keys') - if [ $cword -eq $counter ]; then - __docker_complete_containers_running - fi - ;; - esac -} - -function _docker_build { - local options_with_args=" - --build-arg - --cgroup-parent - --cpuset-cpus - --cpuset-mems - --cpu-shares -c - --cpu-period - --cpu-quota - --file -f - --isolation - --label - --memory -m - --memory-swap - --shm-size - --tag -t - --ulimit - " - - local boolean_options=" - --disable-content-trust=false - --force-rm - --help - --no-cache - --pull - --quiet -q - --rm - " - - local all_options="$options_with_args $boolean_options" - - case "$prev" in - --build-arg) - COMPREPLY=( $( compgen -e -- "$cur" ) ) - __docker_nospace - return - ;; - --file|-f) - _filedir - return - ;; - --isolation) - __docker_complete_isolation - return - ;; - --tag|-t) - __docker_complete_image_repos_and_tags - return - ;; - $(__docker_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) ) - if [ $cword -eq $counter ]; then - _filedir -d - fi - ;; - esac -} - -function _docker_commit { - case "$prev" in - --author|-a|--change|-c|--message|-m) - return - ;; - esac - - case "$cur" in - -*) - 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') - - if [ $cword -eq $counter ]; then - __docker_complete_containers_all - return - fi - (( counter++ )) - - if [ $cword -eq $counter ]; then - __docker_complete_image_repos_and_tags - return - fi - ;; - esac -} - -function _docker_cp { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--follow-link -L --help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - case "$cur" in - *:) - return - ;; - *) - # combined container and filename completion - _filedir - local files=( ${COMPREPLY[@]} ) - - __docker_complete_containers_all - COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) - local containers=( ${COMPREPLY[@]} ) - - COMPREPLY=( $( compgen -W "${files[*]} ${containers[*]}" -- "$cur" ) ) - if [[ "$COMPREPLY" == *: ]]; then - __docker_nospace - fi - return - ;; - esac - fi - (( counter++ )) - - if [ $cword -eq $counter ]; then - if [ -e "$prev" ]; then - __docker_complete_containers_all - COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) - __docker_nospace - else - _filedir - fi - return - fi - ;; - esac -} - -function _docker_create { - _docker_run -} - -function _docker_daemon { - local boolean_options=" - $global_boolean_options - --disable-legacy-registry - --help - --icc=false - --ip-forward=false - --ip-masq=false - --iptables=false - --ipv6 - --live-restore - --raw-logs - --selinux-enabled - --userland-proxy=false - " - local options_with_args=" - $global_options_with_args - --add-runtime - --api-cors-header - --authorization-plugin - --bip - --bridge -b - --cgroup-parent - --cluster-advertise - --cluster-store - --cluster-store-opt - --config-file - --containerd - --default-gateway - --default-gateway-v6 - --default-ulimit - --dns - --dns-search - --dns-opt - --exec-opt - --exec-root - --fixed-cidr - --fixed-cidr-v6 - --graph -g - --group -G - --insecure-registry - --ip - --label - --log-driver - --log-opt - --max-concurrent-downloads - --max-concurrent-uploads - --mtu - --pidfile -p - --registry-mirror - --storage-driver -s - --storage-opt - --userns-remap - " - - __docker_complete_log_driver_options && return - - key=$(__docker_map_key_of_current_option '--cluster-store-opt') - case "$key" in - kv.*file) - cur=${cur##*=} - _filedir - return - ;; - esac - - local key=$(__docker_map_key_of_current_option '--storage-opt') - case "$key" in - dm.blkdiscard|dm.override_udev_sync_check|dm.use_deferred_removal|dm.use_deferred_deletion) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - dm.fs) - COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur##*=}" ) ) - return - ;; - dm.thinpooldev) - cur=${cur##*=} - _filedir - return - ;; - esac - - case "$prev" in - --authorization-plugin) - __docker_complete_plugins Authorization - return - ;; - --cluster-store) - COMPREPLY=( $( compgen -W "consul etcd zk" -S "://" -- "$cur" ) ) - __docker_nospace - return - ;; - --cluster-store-opt) - COMPREPLY=( $( compgen -W "discovery.heartbeat discovery.ttl kv.cacertfile kv.certfile kv.keyfile kv.path" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - --exec-root|--graph|-g) - _filedir -d - return - ;; - --log-driver) - __docker_complete_log_drivers - return - ;; - --config-file|--containerd|--pidfile|-p|--tlscacert|--tlscert|--tlskey) - _filedir - return - ;; - --storage-driver|-s) - COMPREPLY=( $( compgen -W "aufs btrfs devicemapper overlay overlay2 vfs zfs" -- "$(echo $cur | tr '[:upper:]' '[:lower:]')" ) ) - return - ;; - --storage-opt) - local btrfs_options="btrfs.min_space" - local devicemapper_options=" - dm.basesize - dm.blkdiscard - dm.blocksize - dm.fs - dm.loopdatasize - dm.loopmetadatasize - dm.min_free_space - dm.mkfsarg - dm.mountopt - dm.override_udev_sync_check - dm.thinpooldev - dm.use_deferred_deletion - dm.use_deferred_removal - " - local zfs_options="zfs.fsname" - - case $(__docker_value_of_option '--storage-driver|-s') in - '') - COMPREPLY=( $( compgen -W "$btrfs_options $devicemapper_options $zfs_options" -S = -- "$cur" ) ) - ;; - btrfs) - COMPREPLY=( $( compgen -W "$btrfs_options" -S = -- "$cur" ) ) - ;; - devicemapper) - COMPREPLY=( $( compgen -W "$devicemapper_options" -S = -- "$cur" ) ) - ;; - zfs) - COMPREPLY=( $( compgen -W "$zfs_options" -S = -- "$cur" ) ) - ;; - *) - return - ;; - esac - __docker_nospace - return - ;; - --log-level|-l) - __docker_complete_log_levels - return - ;; - --log-opt) - __docker_complete_log_options - return - ;; - --userns-remap) - __docker_complete_user_group - return - ;; - $(__docker_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) - ;; - esac -} - -function _docker_diff { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -function _docker_events { - local key=$(__docker_map_key_of_current_option '-f|--filter') - case "$key" in - container) - cur="${cur##*=}" - __docker_complete_containers_all - return - ;; - daemon) - local name=$(__docker_q info | sed -n 's/^\(ID\|Name\): //p') - COMPREPLY=( $( compgen -W "$name" -- "${cur##*=}" ) ) - return - ;; - event) - COMPREPLY=( $( compgen -W " - attach - commit - connect - copy - create - delete - destroy - detach - die - disconnect - exec_create - exec_detach - exec_start - export - import - kill - load - mount - oom - pause - pull - push - reload - rename - resize - restart - save - start - stop - tag - top - unmount - unpause - untag - update - " -- "${cur##*=}" ) ) - return - ;; - image) - cur="${cur##*=}" - __docker_complete_images - return - ;; - network) - cur="${cur##*=}" - __docker_complete_networks - return - ;; - type) - COMPREPLY=( $( compgen -W "container daemon image network volume" -- "${cur##*=}" ) ) - return - ;; - volume) - cur="${cur##*=}" - __docker_complete_volumes - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "container daemon event image label network type volume" -- "$cur" ) ) - __docker_nospace - return - ;; - --since|--until) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --help --since --until" -- "$cur" ) ) - ;; - esac -} - -function _docker_exec { - __docker_complete_detach-keys && return - - case "$prev" in - --user|-u) - __docker_complete_user_group - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--detach -d --detach-keys --help --interactive -i --privileged -t --tty -u --user" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_running - ;; - esac -} - -function _docker_export { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -function _docker_help { - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) - fi -} - -function _docker_history { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --human=false -H=false --no-trunc --quiet -q" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_images - fi - ;; - esac -} - -function _docker_images { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - before) - cur="${cur##*=}" - __docker_complete_images - return - ;; - dangling) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - label) - return - ;; - since) - cur="${cur##*=}" - __docker_complete_images - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "before dangling label since" -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --digests --filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) - ;; - =) - return - ;; - *) - __docker_complete_image_repos - ;; - esac -} - -function _docker_import { - case "$prev" in - --change|-c|--message|-m) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--change -c --help --message -m" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--change|-c|--message|-m') - if [ $cword -eq $counter ]; then - return - fi - (( counter++ )) - - if [ $cword -eq $counter ]; then - __docker_complete_image_repos_and_tags - return - fi - ;; - esac -} - -function _docker_info { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - esac -} - -function _docker_inspect { - case "$prev" in - --format|-f) - return - ;; - --type) - COMPREPLY=( $( compgen -W "image container" -- "$cur" ) ) - return - ;; - - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help --size -s --type" -- "$cur" ) ) - ;; - *) - case $(__docker_value_of_option --type) in - '') - __docker_complete_containers_and_images - ;; - container) - __docker_complete_containers_all - ;; - image) - __docker_complete_images - ;; - esac - esac -} - -function _docker_kill { - case "$prev" in - --signal|-s) - __docker_complete_signals - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --signal -s" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_running - ;; - esac -} - -function _docker_load { - case "$prev" in - --input|-i) - _filedir - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --input -i --quiet -q" -- "$cur" ) ) - ;; - esac -} - -function _docker_login { - case "$prev" in - --password|-p|--username|-u) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --password -p --username -u" -- "$cur" ) ) - ;; - esac -} - -function _docker_logout { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - esac -} - -function _docker_logs { - case "$prev" in - --since|--tail) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--details --follow -f --help --since --tail --timestamps -t" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--tail') - if [ $cword -eq $counter ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -function _docker_network_connect { - local options_with_args=" - --alias - --ip - --ip6 - --link - --link-local-ip - " - - local boolean_options=" - --help - " - - case "$prev" in - --link) - case "$cur" in - *:*) - ;; - *) - __docker_complete_containers_running - COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) - __docker_nospace - ;; - esac - return - ;; - $(__docker_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) ) - if [ $cword -eq $counter ]; then - __docker_complete_networks - elif [ $cword -eq $(($counter + 1)) ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -function _docker_network_create { - case "$prev" in - --aux-address|--gateway|--internal|--ip-range|--ipam-opt|--ipv6|--opt|-o|--subnet) - return - ;; - --ipam-driver) - COMPREPLY=( $( compgen -W "default" -- "$cur" ) ) - return - ;; - --driver|-d) - local plugins=" $(__docker_plugins Network) " - # remove drivers that allow one instance only - plugins=${plugins/ host / } - plugins=${plugins/ null / } - 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 --label --opt -o --subnet" -- "$cur" ) ) - ;; - esac -} - -function _docker_network_disconnect { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_networks - elif [ $cword -eq $(($counter + 1)) ]; then - __docker_complete_containers_in_network "$prev" - fi - ;; - esac -} - -function _docker_network_inspect { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) - ;; - *) - __docker_complete_networks - esac -} - -function _docker_network_ls { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - driver) - local plugins=" $(__docker_plugins Network) " - COMPREPLY=( $(compgen -W "$plugins" -- "${cur##*=}") ) - return - ;; - id) - cur="${cur##*=}" - __docker_complete_network_ids - return - ;; - name) - cur="${cur##*=}" - __docker_complete_network_names - return - ;; - type) - COMPREPLY=( $( compgen -W "builtin custom" -- "${cur##*=}" ) ) - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "driver id label name type" -- "$cur" ) ) - __docker_nospace - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --help --no-trunc --quiet -q" -- "$cur" ) ) - ;; - esac -} - -function _docker_network_rm { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_networks type=custom - esac -} - -function _docker_network { - local subcommands=" - connect - create - disconnect - inspect - ls - rm - " - __docker_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -function _docker_service { - local subcommands=" - create - inspect - ls list - rm remove - scale - tasks - update - " - __docker_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -function _docker_service_create { - _docker_service_update -} - -function _docker_service_inspect { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help --pretty -p" -- "$cur" ) ) - ;; - *) - __docker_complete_services - esac -} - -function _docker_service_list { - _docker_service_ls -} - -function _docker_service_ls { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - id) - __docker_complete_services --cur "${cur##*=}" --id - return - ;; - name) - __docker_complete_services --cur "${cur##*=}" --name - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -W "id label name" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --help --quiet -q" -- "$cur" ) ) - ;; - esac -} - -function _docker_service_remove { - _docker_service_rm -} - -function _docker_service_rm { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_services - esac -} - -function _docker_service_scale { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_services - __docker_append_to_completions "=" - __docker_nospace - ;; - esac -} - -function _docker_service_tasks { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - desired-state) - COMPREPLY=( $( compgen -W "accepted running" -- "${cur##*=}" ) ) - return - ;; - name) - __docker_complete_services --cur "${cur##*=}" --name - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -W "desired-state id name" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --filter -f --help --no-resolve -n" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--filter|-f') - if [ $cword -eq $counter ]; then - __docker_complete_services - fi - ;; - esac -} - -function _docker_service_update { - local $subcommand="${words[$subcommand_pos]}" - - local options_with_args=" - --constraint - --endpoint-mode - --env -e - --label -l - --limit-cpu - --limit-memory - --mode - --mount -m - --name - --network - --publish -p - --replicas - --reserve-cpu - --reserve-memory - --restart-condition - --restart-delay - --restart-max-attempts - --restart-window - --stop-grace-period - --update-delay - --update-parallelism - --user -u - --workdir -w - " - - local boolean_options=" - --help - " - - if [ "$subcommand" = "update" ] ; then - options_with_args="$options_with_args - --arg - --command - --image - " - - case "$prev" in - --image) - __docker_complete_image_repos_and_tags - return - ;; - esac - fi - - case "$prev" in - --endpoint-mode) - COMPREPLY=( $( compgen -W "DNSRR VIP" -- "$cur" ) ) - return - ;; - --env|-e) - COMPREPLY=( $( compgen -e -S = -- "$cur" ) ) - __docker_nospace - return - ;; - --mode) - COMPREPLY=( $( compgen -W "global replicated" -- "$cur" ) ) - return - ;; - --network) - __docker_complete_networks - return - ;; - --restart-condition) - COMPREPLY=( $( compgen -W "any none on-failure" -- "$cur" ) ) - return - ;; - --user|-u) - __docker_complete_user_group - return - ;; - $(__docker_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) - ;; - *) - if [ "$subcommand" = "update" ] ; then - __docker_complete_services - fi - esac -} - -function _docker_swarm { - local subcommands=" - init - inspect - join - leave - update - " - __docker_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -function _docker_swarm_init { - case "$prev" in - --auto-accept) - COMPREPLY=( $( compgen -W "manager none worker" -- "$cur" ) ) - return - ;; - --listen-addr) - if [[ $cur == *: ]] ; then - COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) - fi - return - ;; - --secret) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--auto-accept --force-new-cluster --help --listen-addr --secret" -- "$cur" ) ) - ;; - esac -} - -function _docker_swarm_inspect { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) - ;; - esac -} - -function _docker_swarm_join { - case "$prev" in - --ca-hash|--secret) - return - ;; - --listen-addr) - if [[ $cur == *: ]] ; then - COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) - fi - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--ca-hash --help --listen-addr --manager --secret" -- "$cur" ) ) - ;; - *:) - COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) - ;; - esac -} - -function _docker_swarm_leave { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force --help" -- "$cur" ) ) - ;; - esac -} - -function _docker_swarm_update { - case "$prev" in - --auto-accept) - COMPREPLY=( $( compgen -W "manager none worker" -- "$cur" ) ) - return - ;; - --cert-expiry|--dispatcher-heartbeat|--secret|--task-history-limit) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--auto-accept --cert-expiry --dispatcher-heartbeat --help --secret --task-history-limit" -- "$cur" ) ) - ;; - esac -} - -function _docker_node { - local subcommands=" - accept - demote - inspect - ls list - promote - rm remove - tasks - update - " - __docker_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -function _docker_node_accept { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_nodes --id --filter membership=pending - esac -} - -function _docker_node_demote { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_nodes --filter role=manager - esac -} - -function _docker_node_inspect { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help --pretty -p" -- "$cur" ) ) - ;; - *) - __docker_complete_nodes - esac -} - -function _docker_node_list { - _docker_node_ls -} - -function _docker_node_ls { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - id) - __docker_complete_nodes --cur "${cur##*=}" --id - return - ;; - name) - __docker_complete_nodes --cur "${cur##*=}" --name - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -W "id label name" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --help --quiet -q" -- "$cur" ) ) - ;; - esac -} - -function _docker_node_promote { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_nodes --filter role=worker - esac -} - -function _docker_node_remove { - _docker_node_rm -} - -function _docker_node_rm { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_nodes - esac -} - -function _docker_node_tasks { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - desired-state) - COMPREPLY=( $( compgen -W "accepted running" -- "${cur##*=}" ) ) - return - ;; - name) - __docker_complete_services --cur "${cur##*=}" --name - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -W "desired-state id label name" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --filter -f --help --no-resolve -n" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--filter|-f') - if [ $cword -eq $counter ]; then - __docker_complete_nodes_plus_self - fi - ;; - esac -} - -function _docker_node_update { - case "$prev" in - --availability) - COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) ) - return - ;; - --membership) - COMPREPLY=( $( compgen -W "accepted rejected" -- "$cur" ) ) - return - ;; - --role) - COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--availability --help --membership --role" -- "$cur" ) ) - ;; - *) - __docker_complete_nodes - esac -} - -function _docker_pause { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_containers_pauseable - fi - ;; - esac -} - -function _docker_port { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -function _docker_ps { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - ancestor) - cur="${cur##*=}" - __docker_complete_images - return - ;; - before) - cur="${cur##*=}" - __docker_complete_containers_all - return - ;; - id) - cur="${cur##*=}" - __docker_complete_container_ids - return - ;; - name) - cur="${cur##*=}" - __docker_complete_container_names - return - ;; - network) - cur="${cur##*=}" - __docker_complete_networks - return - ;; - since) - cur="${cur##*=}" - __docker_complete_containers_all - return - ;; - status) - COMPREPLY=( $( compgen -W "created dead exited paused restarting running" -- "${cur##*=}" ) ) - return - ;; - volume) - cur="${cur##*=}" - __docker_complete_volumes - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "ancestor before exited id label name network since status volume" -- "$cur" ) ) - __docker_nospace - return - ;; - --format|--last|-n) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --filter -f --format --help --last -n --latest -l --no-trunc --quiet -q --size -s" -- "$cur" ) ) - ;; - esac -} - -function _docker_pull { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all-tags -a --disable-content-trust=false --help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - for arg in "${COMP_WORDS[@]}"; do - case "$arg" in - --all-tags|-a) - __docker_complete_image_repos - return - ;; - esac - done - __docker_complete_image_repos_and_tags - fi - ;; - esac -} - -function _docker_push { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--disable-content-trust=false --help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_image_repos_and_tags - fi - ;; - esac -} - -function _docker_rename { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -function _docker_restart { - case "$prev" in - --time|-t) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_all - ;; - esac -} - -function _docker_rm { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --help --link -l --volumes -v" -- "$cur" ) ) - ;; - *) - for arg in "${COMP_WORDS[@]}"; do - case "$arg" in - --force|-f) - __docker_complete_containers_all - return - ;; - esac - done - __docker_complete_containers_stopped - ;; - esac -} - -function _docker_rmi { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --help --no-prune" -- "$cur" ) ) - ;; - *) - __docker_complete_images - ;; - esac -} - -function _docker_run { - local options_with_args=" - --add-host - --attach -a - --blkio-weight - --blkio-weight-device - --cap-add - --cap-drop - --cgroup-parent - --cidfile - --cpu-period - --cpu-quota - --cpuset-cpus - --cpuset-mems - --cpu-shares -c - --device - --device-read-bps - --device-read-iops - --device-write-bps - --device-write-iops - --dns - --dns-opt - --dns-search - --entrypoint - --env -e - --env-file - --expose - --group-add - --hostname -h - --ip - --ip6 - --ipc - --isolation - --kernel-memory - --label-file - --label -l - --link - --link-local-ip - --log-driver - --log-opt - --mac-address - --memory -m - --memory-swap - --memory-swappiness - --memory-reservation - --name - --net - --net-alias - --oom-score-adj - --pid - --pids-limit - --publish -p - --restart - --runtime - --security-opt - --shm-size - --stop-signal - --storage-opt - --tmpfs - --sysctl - --ulimit - --user -u - --userns - --uts - --volume-driver - --volumes-from - --volume -v - --workdir -w - " - - local boolean_options=" - --disable-content-trust=false - --help - --interactive -i - --oom-kill-disable - --privileged - --publish-all -P - --read-only - --tty -t - " - - if [ "$command" = "run" ] ; then - options_with_args="$options_with_args - --detach-keys - --health-cmd - --health-interval - --health-retries - --health-timeout - " - boolean_options="$boolean_options - --detach -d - --no-healthcheck - --rm - --sig-proxy=false - " - __docker_complete_detach-keys && return - fi - - local all_options="$options_with_args $boolean_options" - - - __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 - *:) - __docker_complete_resolved_hostname - return - ;; - esac - ;; - --attach|-a) - COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) ) - return - ;; - --cap-add|--cap-drop) - __docker_complete_capabilities - return - ;; - --cidfile|--env-file|--label-file) - _filedir - return - ;; - --device|--tmpfs|--volume|-v) - case "$cur" in - *:*) - # TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine) - ;; - '') - COMPREPLY=( $( compgen -W '/' -- "$cur" ) ) - __docker_nospace - ;; - /*) - _filedir - __docker_nospace - ;; - esac - return - ;; - --env|-e) - COMPREPLY=( $( compgen -e -- "$cur" ) ) - __docker_nospace - return - ;; - --ipc) - case "$cur" in - *:*) - cur="${cur#*:}" - __docker_complete_containers_running - ;; - *) - COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) - if [ "$COMPREPLY" = "container:" ]; then - __docker_nospace - fi - ;; - esac - return - ;; - --isolation) - __docker_complete_isolation - return - ;; - --link) - case "$cur" in - *:*) - ;; - *) - __docker_complete_containers_running - COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) - __docker_nospace - ;; - esac - return - ;; - --log-driver) - __docker_complete_log_drivers - return - ;; - --log-opt) - __docker_complete_log_options - return - ;; - --net) - case "$cur" in - container:*) - local cur=${cur#*:} - __docker_complete_containers_all - ;; - *) - COMPREPLY=( $( compgen -W "$(__docker_plugins Network) $(__docker_networks) container:" -- "$cur") ) - if [ "${COMPREPLY[*]}" = "container:" ] ; then - __docker_nospace - fi - ;; - esac - return - ;; - --pid) - case "$cur" in - *:*) - cur="${cur#*:}" - __docker_complete_containers_running - ;; - *) - COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) - if [ "$COMPREPLY" = "container:" ]; then - __docker_nospace - fi - ;; - esac - return - ;; - --runtime) - __docker_complete_runtimes - return - ;; - --security-opt) - COMPREPLY=( $( compgen -W "apparmor= label= no-new-privileges seccomp=" -- "$cur") ) - if [ "${COMPREPLY[*]}" != "no-new-privileges" ] ; then - __docker_nospace - fi - return - ;; - --storage-opt) - COMPREPLY=( $( compgen -W "size" -S = -- "$cur") ) - __docker_nospace - return - ;; - --user|-u) - __docker_complete_user_group - return - ;; - --userns) - COMPREPLY=( $( compgen -W "host" -- "$cur" ) ) - return - ;; - --volume-driver) - __docker_complete_plugins Volume - return - ;; - --volumes-from) - __docker_complete_containers_all - return - ;; - $(__docker_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) ) - if [ $cword -eq $counter ]; then - __docker_complete_images - fi - ;; - esac -} - -function _docker_save { - case "$prev" in - --output|-o) - _filedir - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) ) - ;; - *) - __docker_complete_images - ;; - esac -} - -function _docker_search { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - is-automated) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - is-official) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "is-automated is-official stars" -- "$cur" ) ) - __docker_nospace - return - ;; - --limit) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter --help --limit --no-trunc" -- "$cur" ) ) - ;; - esac -} - -function _docker_start { - __docker_complete_detach-keys && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--attach -a --detach-keys --help --interactive -i" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_stopped - ;; - esac -} - -function _docker_stats { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --help --no-stream" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_running - ;; - esac -} - -function _docker_stop { - case "$prev" in - --time|-t) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_running - ;; - esac -} - -function _docker_tag { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - - if [ $cword -eq $counter ]; then - __docker_complete_image_repos_and_tags - return - fi - (( counter++ )) - - if [ $cword -eq $counter ]; then - __docker_complete_image_repos_and_tags - return - fi - ;; - esac -} - -function _docker_unpause { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_containers_unpauseable - fi - ;; - esac -} - -function _docker_update { - local options_with_args=" - --blkio-weight - --cpu-period - --cpu-quota - --cpuset-cpus - --cpuset-mems - --cpu-shares -c - --kernel-memory - --memory -m - --memory-reservation - --memory-swap - --restart - " - - local boolean_options=" - --help - " - - local all_options="$options_with_args $boolean_options" - - __docker_complete_restart && return - - case "$prev" in - $(__docker_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_all - ;; - esac -} - -function _docker_top { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then - __docker_complete_containers_running - fi - ;; - esac -} - -function _docker_version { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - esac -} - -function _docker_volume_create { - case "$prev" in - --driver|-d) - __docker_complete_plugins Volume - return - ;; - --label|--name|--opt|-o) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--driver -d --help --label --name --opt -o" -- "$cur" ) ) - ;; - esac -} - -function _docker_volume_inspect { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) - ;; - *) - __docker_complete_volumes - ;; - esac -} - -function _docker_volume_ls { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - dangling) - COMPREPLY=( $( compgen -W "true false" -- "${cur##*=}" ) ) - return - ;; - driver) - cur=${cur##*=} - __docker_complete_plugins Volume - return - ;; - name) - cur=${cur##*=} - __docker_complete_volumes - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "dangling driver name" -- "$cur" ) ) - __docker_nospace - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --help --quiet -q" -- "$cur" ) ) - ;; - esac -} - -function _docker_volume_rm { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_volumes - ;; - esac -} - -function _docker_volume { - local subcommands=" - create - inspect - ls - rm - " - __docker_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -function _docker_wait { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_all - ;; - esac -} - -function _docker { - local previous_extglob_setting=$(shopt -p extglob) - shopt -s extglob - - local commands=( - attach - build - commit - cp - create - daemon - diff - events - exec - export - history - images - import - info - inspect - kill - load - login - logout - logs - network - node - pause - port - ps - pull - push - rename - restart - rm - rmi - run - save - search - service - start - stats - stop - swarm - tag - top - unpause - update - version - volume - wait - ) - - # These options are valid as global options for all client commands - # and valid as command options for `docker daemon` - local global_boolean_options=" - --debug -D - --tls - --tlsverify - " - local global_options_with_args=" - --config - --host -H - --log-level -l - --tlscacert - --tlscert - --tlskey - " - - local host config - - COMPREPLY=() - local cur prev words cword - _get_comp_words_by_ref -n : cur prev words cword - - local command='docker' command_pos=0 subcommand_pos - local counter=1 - while [ $counter -lt $cword ]; do - case "${words[$counter]}" in - # save host so that completion can use custom daemon - --host|-H) - (( counter++ )) - host="${words[$counter]}" - ;; - # save config so that completion can use custom configuration directories - --config) - (( counter++ )) - config="${words[$counter]}" - ;; - $(__docker_to_extglob "$global_options_with_args") ) - (( counter++ )) - ;; - -*) - ;; - =) - (( counter++ )) - ;; - *) - command="${words[$counter]}" - command_pos=$counter - break - ;; - esac - (( counter++ )) - done - - local binary="${words[0]}" - if [[ $binary == ?(*/)dockerd ]] ; then - # for the dockerd binary, we reuse completion of `docker daemon`. - # dockerd does not have subcommands and global options. - command=daemon - command_pos=0 - fi - - local completions_func=_docker_${command} - _omb_util_function_exists "$completions_func" && "$completions_func" - - eval "$previous_extglob_setting" - return 0 -} - -eval "$__docker_previous_extglob_setting" -unset __docker_previous_extglob_setting - -complete -F _docker docker dockerd +function _omb_completion_docker_has_completion { + local complete + complete=$(complete -p docker 2>/dev/null) && [[ $complete ]] || return 1 + + # bash-completion runs $(docker completion bash) as a fallback, but the + # official docker completion is not provided through $(docker completion + # bash), which is automatically generated by cobra's bash completion V2. In + # this case, we can instead use the completion file bundled with OMB. + if [[ $complete == *__start_docker* ]]; then + complete -r docker + return 1 + fi + + unset -f _omb_completion_docker_has_completion + unset -f _omb_completion_docker_try + return 0 +} + +function _omb_completion_docker_try { + if [[ -s $1 ]]; then + source "$1" + _omb_completion_docker_has_completion && return 0 + elif [[ -s $1.sh ]]; then + source "$1.sh" + _omb_completion_docker_has_completion && return 0 + elif [[ -s $1.bash ]]; then + source "$1.bash" + _omb_completion_docker_has_completion && return 0 + fi + return 1 +} + +_omb_completion_docker_has_completion && return 0 + +if _omb_util_function_exists _comp_load; then + # bash-completion 2.12 + _comp_load -- docker-compose + _omb_completion_docker_has_completion && return 0 +elif _omb_util_function_exists __load_completion; then + # bash-completion <= 2.11 + __load_completion docker-compose + _omb_completion_docker_has_completion && return 0 +fi + +_omb_completion_docker_try /usr/share/bash-completion/completions/docker && return 0 +_omb_completion_docker_try /etc/bash_completion.d/docker && return 0 + +unset -f _omb_completion_docker_has_completion +unset -f _omb_completion_docker_try +source "$OSH/completions/fallback/docker.bash"