#! /bin/bash : ${PROG:=$(basename ${BASH_SOURCE})} __kpod_previous_extglob_setting=$(shopt -p extglob) shopt -s extglob __kpod_q() { kpod ${host:+-H "$host"} ${config:+--config "$config"} 2>/dev/null "$@" } # __kpod_containers returns a list of containers. Additional options to # `kpod ps` may be specified in order to filter the list, e.g. # `__kpod_containers --filter status=running` # By default, only names are returned. # Set KPOD_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. __kpod_containers() { local format if [ "$1" = "--id" ] ; then format='{{.ID}}' shift elif [ "$1" = "--name" ] ; then format='{{.Names}}' shift elif [ "${KPOD_COMPLETION_SHOW_CONTAINER_IDS}" = yes ] ; then format='{{.ID}} {{.Names}}' else format='{{.Names}}' fi __kpod_q ps --format "$format" "$@" } # __kpod_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 `__kpod_containers`. __kpod_complete_containers() { local current="$cur" if [ "$1" = "--cur" ] ; then current="$2" shift 2 fi COMPREPLY=( $(compgen -W "$(__kpod_containers "$@")" -- "$current") ) } __kpod_complete_containers_all() { __kpod_complete_containers "$@" --all } __kpod_complete_containers_running() { __kpod_complete_containers "$@" --filter status=running } __kpod_complete_containers_stopped() { __kpod_complete_containers "$@" --filter status=exited } __kpod_complete_containers_unpauseable() { __kpod_complete_containers "$@" --filter status=paused } __kpod_complete_container_names() { local containers=( $(__kpod_q ps -aq --no-trunc) ) local names=( $(__kpod_q inspect --format '{{.Name}}' "${containers[@]}") ) names=( "${names[@]#/}" ) # trim off the leading "/" from the container names COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") ) } __kpod_complete_container_ids() { local containers=( $(__kpod_q ps -aq) ) COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") ) } __kpod_images() { local images_args="" case "$KPOD_COMPLETION_SHOW_IMAGE_IDS" in all) images_args="--no-trunc -a" ;; non-intermediate) images_args="--no-trunc" ;; esac local repo_print_command if [ "${KPOD_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 "$KPOD_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 __kpod_q images $images_args | awk "$awk_script" | grep -v '$' } __kpod_complete_images() { COMPREPLY=( $(compgen -W "$(__kpod_images)" -- "$cur") ) __ltrim_colon_completions "$cur" } __kpod_complete_image_repos() { local repos="$(__kpod_q images | awk 'NR>1 && $1 != "" { print $1 }')" COMPREPLY=( $(compgen -W "$repos" -- "$cur") ) } __kpod_complete_image_repos_and_tags() { local reposAndTags="$(__kpod_q images | awk 'NR>1 && $1 != "" { print $1; print $1":"$2 }')" COMPREPLY=( $(compgen -W "$reposAndTags" -- "$cur") ) __ltrim_colon_completions "$cur" } # __kpod_networks returns a list of all networks. Additional options to # `kpod network ls` may be specified in order to filter the list, e.g. # `__kpod_networks --filter type=custom` # By default, only names are returned. # Set KPOD_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. __kpod_networks() { local format if [ "$1" = "--id" ] ; then format='{{.ID}}' shift elif [ "$1" = "--name" ] ; then format='{{.Name}}' shift elif [ "${KPOD_COMPLETION_SHOW_NETWORK_IDS}" = yes ] ; then format='{{.ID}} {{.Name}}' else format='{{.Name}}' fi __kpod_q network ls --format "$format" "$@" } # __kpod_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 `__kpod_networks`. __kpod_complete_networks() { local current="$cur" if [ "$1" = "--cur" ] ; then current="$2" shift 2 fi COMPREPLY=( $(compgen -W "$(__kpod_networks "$@")" -- "$current") ) } __kpod_complete_containers_in_network() { local containers=$(__kpod_q network inspect -f '{{range $i, $c := .Containers}}{{$i}} {{$c.Name}} {{end}}' "$1") COMPREPLY=( $(compgen -W "$containers" -- "$cur") ) } __kpod_runtimes() { __kpod_q info | sed -n 's/^Runtimes: \(.*\)/\1/p' } __kpod_complete_runtimes() { COMPREPLY=( $(compgen -W "$(__kpod_runtimes)" -- "$cur") ) } # __kpod_services returns a list of all services. Additional options to # `kpod service ls` may be specified in order to filter the list, e.g. # `__kpod_services --filter name=xxx` # By default, only node names are returned. # Set KPOD_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. __kpod_services() { local fields='$2' # default: service name only [ "${KPOD_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 __kpod_q service ls "$@" | awk "NR>1 {print $fields}" } # __kpod_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 `__kpod_services`. __kpod_complete_services() { local current="$cur" if [ "$1" = "--cur" ] ; then current="$2" shift 2 fi COMPREPLY=( $(compgen -W "$(__kpod_services "$@")" -- "$current") ) } # __kpod_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 __kpod_complete_XXX functions in cases where you need a suffix. __kpod_append_to_completions() { COMPREPLY=( ${COMPREPLY[@]/%/"$1"} ) } # __kpod_is_experimental tests whether the currently configured Kpod daemon # 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). __kpod_is_experimental() { [ "$(__kpod_q version -f '{{.Server.Experimental}}')" = "true" ] } # __kpod_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. __kpod_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 } # __kpod_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. __kpod_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" } # __kpod_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. __kpod_value_of_option() { local option_extglob=$(__kpod_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 } # __kpod_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 __kpod_pos_first_nonflag(). __kpod_to_alternatives() { local parts=( $1 ) local IFS='|' echo "${parts[*]}" } # __kpod_to_extglob transforms a multiline list of options into an extglob pattern # suitable for use in case statements. __kpod_to_extglob() { local extglob=$( __kpod_to_alternatives "$1" ) echo "@($extglob)" } # __kpod_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. __kpod_subcommands() { local subcommands="$1" local counter=$(($command_pos + 1)) while [ $counter -lt $cword ]; do case "${words[$counter]}" in $(__kpod_to_extglob "$subcommands") ) subcommand_pos=$counter local subcommand=${words[$counter]} local completions_func=_kpod_${command}_${subcommand} declare -F $completions_func >/dev/null && $completions_func return 0 ;; esac (( counter++ )) done return 1 } # __kpod_nospace suppresses trailing whitespace __kpod_nospace() { # compopt is not available in ancient bash versions type compopt &>/dev/null && compopt -o nospace } __kpod_complete_resolved_hostname() { command -v host >/dev/null 2>&1 || return COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') ) } __kpod_local_interfaces() { command -v ip >/dev/null 2>&1 || return ip addr show scope global 2>/dev/null | sed -n 's| \+inet \([0-9.]\+\).* \([^ ]\+\)|\1 \2|p' } __kpod_complete_local_interfaces() { local additional_interface if [ "$1" = "--add" ] ; then additional_interface="$2" fi COMPREPLY=( $( compgen -W "$(__kpod_local_interfaces) $additional_interface" -- "$cur" ) ) } __kpod_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" ) ) } __kpod_complete_detach-keys() { case "$prev" in --detach-keys) case "$cur" in *,) COMPREPLY=( $( compgen -W "${cur}ctrl-" -- "$cur" ) ) ;; *) COMPREPLY=( $( compgen -W "ctrl-" -- "$cur" ) ) ;; esac __kpod_nospace return ;; esac return 1 } __kpod_complete_log_drivers() { COMPREPLY=( $( compgen -W " awslogs etwlogs fluentd gcplogs gelf journald json-file logentries none splunk syslog " -- "$cur" ) ) } __kpod_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 logentries_options="logentries-token" local syslog_options="env labels syslog-address syslog-facility syslog-format syslog-tls-ca-cert syslog-tls-cert syslog-tls-key syslog-tls-skip-verify tag" local splunk_options="env labels splunk-caname splunk-capath splunk-format splunk-gzip splunk-gzip-level splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url splunk-verify-connection tag" local all_options="$fluentd_options $gcplogs_options $gelf_options $journald_options $logentries_options $json_file_options $syslog_options $splunk_options" case $(__kpod_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" ) ) ;; logentries) COMPREPLY=( $( compgen -W "$logentries_options" -S = -- "$cur" ) ) ;; syslog) COMPREPLY=( $( compgen -W "$syslog_options" -S = -- "$cur" ) ) ;; splunk) COMPREPLY=( $( compgen -W "$splunk_options" -S = -- "$cur" ) ) ;; *) return ;; esac __kpod_nospace } __kpod_complete_log_driver_options() { local key=$(__kpod_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##*=}" ) ) __kpod_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##*=}" ) ) __kpod_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##*=}" ) ) __kpod_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 } __kpod_complete_log_levels() { COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) ) } # __kpod_complete_signals returns a subset of the available signals that is most likely # relevant in the context of kpod containers __kpod_complete_signals() { local signals=( SIGCONT SIGHUP SIGINT SIGKILL SIGQUIT SIGSTOP SIGTERM SIGUSR1 SIGUSR2 ) COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo $cur | tr '[:lower:]' '[:upper:]')" ) ) } __kpod_complete_user_group() { if [[ $cur == *:* ]] ; then COMPREPLY=( $(compgen -g -- "${cur#*:}") ) else COMPREPLY=( $(compgen -u -S : -- "$cur") ) __kpod_nospace fi } __kpod_list_images() { COMPREPLY=($(compgen -W "$(kpod images -q)" -- $cur)) } __kpod_list_containers() { COMPREPLY=($(compgen -W "$(kpod ps -aq)" -- $cur)) } __kpod_images() { local images_args="" case "$KPOD_COMPLETION_SHOW_IMAGE_IDS" in all) images_args="--no-trunc -a" ;; non-intermediate) images_args="--no-trunc" ;; esac local repo_print_command if [ "${KPOD_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 "$KPOD_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 __kpod_q images $images_args | awk "$awk_script" | grep -v '$' } _kpod_diff() { local options_with_args=" --format " local boolean_options=" " _complete_ "$options_with_args" "$boolean_options" case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; *) __kpod_list_images ;; esac } _kpod_export() { local options_with_args=" --output -o " local boolean_options=" " _complete_ "$options_with_args" "$boolean_options" case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; *) __kpod_list_images ;; esac } _kpod_history() { local options_with_args=" --format " local boolean_options=" --human -H --no-trunc --quiet -q " _complete_ "$options_with_args" "$boolean_options" case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; *) __kpod_list_images ;; esac } _kpod_info() { local boolean_options=" --help -h --debug " local options_with_args=" --format " local all_options="$options_with_args $boolean_options" case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; *) __kpod_list_images ;; esac } _kpod_images() { local boolean_options=" --help -h --quiet -q --noheading -n --no-trunc --digests --filter -f " local options_with_args=" --format " local all_options="$options_with_args $boolean_options" case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; esac } _kpod_inspect() { local boolean_options=" --help -h " local options_with_args=" --format -f --type -t --size " local all_options="$options_with_args $boolean_options" case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; esac } _kpod_kill() { local options_with_args=" --signal -s " local boolean_options=" --help -h" _complete_ "$options_with_args" "$boolean_options" } _kpod_logs() { local options_with_args=" --since --tail " local boolean_options=" --follow -f " _complete_ "$options_with_args" "$boolean_options" case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; *) __kpod_list_containers ;; esac } _kpod_pull() { local options_with_args=" --authfile --creds --cert-dir --signature-policy " local boolean_options=" --all-tags -a --quiet -q --tls-verify " _complete_ "$options_with_args" "$boolean_options" } _kpod_unmount() { _kpod_umount $@ } _kpod_umount() { local boolean_options=" --help -h " local options_with_args=" " local all_options="$options_with_args $boolean_options" case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; esac } _kpod_mount() { local boolean_options=" --help -h --notruncate " local options_with_args=" --label --format " local all_options="$options_with_args $boolean_options" case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; esac } _kpod_push() { local boolean_options=" --disable-compression -D --quiet -q --remove-signatures --tls-verify " local options_with_args=" --authfile --cert-dir --creds --sign-by --signature-policy " local all_options="$options_with_args $boolean_options" case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; esac } _kpod_rename() { local boolean_options=" --help -h " local options_with_args=" " local all_options="$options_with_args $boolean_options" case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; *) __kpod_list_containers ;; esac } _kpod_container_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 --cpu-rt-period --cpu-rt-runtime --cpuset-cpus --cpus --cpuset-mems --cpu-shares -c --device --device-read-bps --device-read-iops --device-write-bps --device-write-iops --dns --dns-option --dns-search --entrypoint --env -e --env-file --expose --group-add --hostname -h --init-path --ip --ip6 --ipc --kernel-memory --label-file --label -l --link-local-ip --log-driver --log-opt --mac-address --memory -m --memory-swap --memory-swappiness --memory-reservation --name --network --network-alias --oom-score-adj --pid --pids-limit --publish -p --runtime --security-opt --shm-size --stop-signal --stop-timeout --storage-opt --tmpfs --sysctl --ulimit --user -u --userns --uts --volumes-from --volume -v --workdir -w " local boolean_options=" --disable-content-trust=false --help --init --interactive -i --oom-kill-disable --privileged --publish-all -P --read-only --tty -t " if [ "$command" = "run" -o "$subcommand" = "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 " __kpod_complete_detach-keys && return fi local all_options="$options_with_args $boolean_options" __kpod_complete_log_driver_options && return local key=$(__kpod_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 __kpod_nospace fi return ;; seccomp) local cur=${cur##*=} _filedir COMPREPLY+=( $( compgen -W "unconfined" -- "$cur" ) ) return ;; esac case "$prev" in --add-host) case "$cur" in *:) __kpod_complete_resolved_hostname return ;; esac ;; --attach|-a) COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) ) return ;; --cap-add|--cap-drop) __kpod_complete_capabilities return ;; --cidfile|--env-file|--init-path|--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" ) ) __kpod_nospace ;; /*) _filedir __kpod_nospace ;; esac return ;; --env|-e) # we do not append a "=" here because "-e VARNAME" is legal systax, too COMPREPLY=( $( compgen -e -- "$cur" ) ) __kpod_nospace return ;; --ipc) case "$cur" in *:*) cur="${cur#*:}" __kpod_complete_containers_running ;; *) COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) if [ "$COMPREPLY" = "container:" ]; then __kpod_nospace fi ;; esac return ;; --log-driver) __kpod_complete_log_drivers return ;; --log-opt) __kpod_complete_log_options return ;; --network) case "$cur" in container:*) __kpod_complete_containers_all --cur "${cur#*:}" ;; *) COMPREPLY=( $( compgen -W "$(__kpod_plugins_bundled --type Network) $(__kpod_networks) container:" -- "$cur") ) if [ "${COMPREPLY[*]}" = "container:" ] ; then __kpod_nospace fi ;; esac return ;; --pid) case "$cur" in *:*) __kpod_complete_containers_running --cur "${cur#*:}" ;; *) COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) if [ "$COMPREPLY" = "container:" ]; then __kpod_nospace fi ;; esac return ;; --runtime) __kpod_complete_runtimes return ;; --security-opt) COMPREPLY=( $( compgen -W "apparmor= label= no-new-privileges seccomp=" -- "$cur") ) if [ "${COMPREPLY[*]}" != "no-new-privileges" ] ; then __kpod_nospace fi return ;; --storage-opt) COMPREPLY=( $( compgen -W "size" -S = -- "$cur") ) __kpod_nospace return ;; --user|-u) __kpod_complete_user_group return ;; --userns) COMPREPLY=( $( compgen -W "host" -- "$cur" ) ) return ;; --volumes-from) __kpod_complete_containers_all return ;; $(__kpod_to_extglob "$options_with_args") ) return ;; esac case "$cur" in -*) COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) ;; *) local counter=$( __kpod_pos_first_nonflag $( __kpod_to_alternatives "$options_with_args" ) ) if [ $cword -eq $counter ]; then __kpod_complete_images fi ;; esac } _kpod_create() { _kpod_container_run } _kpod_run() { _kpod_container_run } _kpod_rm() { local boolean_options=" --force -f " local options_with_args=" " local all_options="$options_with_args $boolean_options" case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; *) __kpod_list_containers ;; esac } _kpod_rmi() { local boolean_options=" --help -h --force -f " case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; *) __kpod_list_images ;; esac } _kpod_stats() { local boolean_options=" --help --all -a --no-stream --format " case "$cur" in -*) COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) ;; *) __kpod_list_containers ;; esac } kpod_tag() { local options_with_args=" " local boolean_options=" " _complete_ "$options_with_args" "$boolean_options" } _kpod_version() { local options_with_args=" " local boolean_options=" " _complete_ "$options_with_args" "$boolean_options" } _kpod_save() { local options_with_args=" --output -o --format " local boolean_options=" --quiet -q " _complete_ "$options_with_args" "$boolean_options" } _kpod_export() { local options_with_args=" --output -o " local boolean_options=" " _complete_ "$options_with_args" "$boolean_options" } _kpod_pause() { local options_with_args=" --help -h " local boolean_options="" _complete_ "$options_with_args" "$boolean_options" } _kpod_ps() { local options_with_args=" --filter -f --format --last -n " local boolean_options=" --all -a --latest -l --no-trunc --quiet -q --size -s --namespace --ns " _complete_ "$options_with_args" "$boolean_options" } _kpod_stop() { local options_with_args=" --timeout -t " local boolean_options="" _complete_ "$options_with_args" "$boolean_options" } _kpod_unpause() { local options_with_args=" --help -h " local boolean_options="" _complete_ "$options_with_args" "$boolean_options" _kpod_wait() { local options_with_args="" local boolean_options="--help -h" _complete_ "$options_with_args" "$boolean_options" } _complete_() { local options_with_args=$1 local boolean_options="$2 -h --help" case "$prev" in $options_with_args) return ;; esac case "$cur" in -*) COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) ;; esac } _kpod_load() { local options_with_args=" --input -i --signature-policy " local boolean_options=" --quiet -q " _complete_ "$options_with_args" "$boolean_options" } _kpod_login() { local options_with_args=" --username -u --password -p --authfile " local boolean_options=" --help -h " _complete_ "$options_with_args" "$boolean_options" } _kpod_logout() { local options_with_args=" --authfile " local boolean_options=" --all -a --help -h " _complete_ "$options_with_args" "$boolean_options" } _kpod_kpod() { local options_with_args=" --config -c --root --runroot --storage-driver --storage-opt --log-level " local boolean_options=" --help -h --version -v " commands=" create diff export history images info inspect kill load login logout logs mount pause ps pull push rename rm rmi run save stats stop tag umount unmount unpause version wait " case "$prev" in $main_options_with_args_glob ) return ;; esac case "$cur" in -*) COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) ;; *) COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) ) ;; esac } _cli_bash_autocomplete() { local cur opts base COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" COMPREPLY=() local cur prev words cword _get_comp_words_by_ref -n : cur prev words cword local command=${PROG} cpos=0 local counter=1 counter=1 while [ $counter -lt $cword ]; do case "!${words[$counter]}" in *) command=$(echo "${words[$counter]}" | sed 's/-/_/g') cpos=$counter (( cpos++ )) break ;; esac (( counter++ )) done local completions_func=_kpod_${command} declare -F $completions_func >/dev/null && $completions_func eval "$previous_extglob_setting" return 0 } complete -F _cli_bash_autocomplete $PROG