#! /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_import() { local options_with_args=" --change -c --message -m " local boolean_options=" --help -h " _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=" --all -a --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 -a --all " 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_start() { local options_with_args=" --detach-keys " local boolean_options=" -h --help -a --attach -i --interactive" _complete_ "$options_with_args" "$boolean_options" } _kpod_stop() { local options_with_args=" --timeout -t " local boolean_options=" --all -a" _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 --cpu-profile --root --runroot --storage-driver --storage-opt --log-level " local boolean_options=" --help -h --version -v " commands=" create diff export history images import info inspect kill load login logout logs mount pause ps pull push rename rm rmi run save start 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