diff --git a/misc/completions/bash/kubecfg b/misc/completions/bash/kubecfg new file mode 100644 index 00000000000..93f05fbf817 --- /dev/null +++ b/misc/completions/bash/kubecfg @@ -0,0 +1,202 @@ +#!bash +# +# bash completion file for core kubecfg commands +# +# This script provides completion of non replication controller options +# +# To enable the completions either: +# - place this file in /etc/bash_completion.d +# or +# - copy this file and add the line below to your .bashrc after +# bash completion features are loaded +# . kubecfg +# +# Note: +# Currently, the completions will not work if the apiserver daemon is not +# running on localhost on the standard port 8080 + +__contains_word () { + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done + return 1 +} + +# This should be provided by the bash-completions, but give a really simple +# stoopid version just in case. It works most of the time. +if ! declare -F _get_comp_words_by_ref >/dev/null 2>&1; then +_get_comp_words_by_ref () +{ + while [ $# -gt 0 ]; do + case "$1" in + cur) + cur=${COMP_WORDS[COMP_CWORD]} + ;; + prev) + prev=${COMP_WORDS[COMP_CWORD-1]} + ;; + words) + words=("${COMP_WORDS[@]}") + ;; + cword) + cword=$COMP_CWORD + ;; + -n) + shift # we don't handle excludes + ;; + esac + shift + done +} +fi + + +__has_service() { + local i + for ((i=0; i < cword; i++)); do + local word=${words[i]} + # strip everything after a / so things like pods/[id] match + word=${word%%/*} + if __contains_word "${word}" "${services[@]}" && + ! __contains_word "${words[i-1]}" "${opts[@]}"; then + return 0 + fi + done + return 1 +} + +# call kubecfg list $1, +# exclude blank lines +# skip the header stuff kubecfg prints on the first 2 lines +# append $1/ to the first column and use that in compgen +__kubecfg_parse_list() +{ + local kubecfg_output + if kubecfg_output=$(kubecfg list "$1" 2>/dev/null); then + out=($(echo "${kubecfg_output}" | awk -v prefix="$1" '/^$/ {next} NR > 2 {print prefix"/"$1}')) + COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) ) + fi +} + +_kubecfg_specific_service_match() +{ + case "$cur" in + pods/*) + __kubecfg_parse_list pods + ;; + minions/*) + __kubecfg_parse_list minions + ;; + replicationControllers/*) + __kubecfg_parse_list replicationControllers + ;; + services/*) + __kubecfg_parse_list services + ;; + *) + if __has_service; then + return 0 + fi + compopt -o nospace + COMPREPLY=( $( compgen -S / -W "${services[*]}" -- "$cur" ) ) + ;; + esac +} + +_kubecfg_service_match() +{ + if __has_service; then + return 0 + fi + + COMPREPLY=( $( compgen -W "${services[*]}" -- "$cur" ) ) +} + +_kubecfg() +{ + local opts=( + -h + -c + ) + local -A all_services=( + [CREATE]="pods replicationControllers services" + [UPDATE]="replicationControllers" + [ALL]="pods replicationControllers services minions" + ) + local services=(${all_services[ALL]}) + local -A all_commands=( + [WITH_JSON]="create update" + [ALL]="create update get list delete stop rm rollingupdate resize" + ) + local commands=(${all_commands[ALL]}) + + COMPREPLY=() + local command + local cur prev words cword + _get_comp_words_by_ref -n : cur prev words cword + + if __contains_word "$prev" "${opts[@]}"; then + case $prev in + -c) + _filedir '@(json|yml|yaml)' + return 0 + ;; + -h) + return 0 + ;; + esac + fi + + if [[ "$cur" = -* ]]; then + COMPREPLY=( $(compgen -W "${opts[*]}" -- "$cur") ) + return 0 + fi + + # if you passed -c, you are limited to create or update + if __contains_word "-c" "${words[@]}"; then + services=(${all_services[CREATE]} ${all_services[UPDATE]}) + commands=(${all_commands[WITH_JSON]}) + fi + + # figure out which command they are running, remembering that arguments to + # options don't count as the command! So a hostname named 'create' won't + # trip things up + local i + for ((i=0; i < cword; i++)); do + if __contains_word "${words[i]}" "${commands[@]}" && + ! __contains_word "${words[i-1]}" "${opts[@]}"; then + command=${words[i]} + break + fi + done + + # tell the list of possible commands + if [[ -z ${command} ]]; then + COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) + return 0 + fi + + # remove services which you can't update given your command + if [[ ${command} == "create" ]]; then + services=(${all_services[CREATE]}) + elif [[ ${command} == "update" ]]; then + services=(${all_services[UPDATE]}) + fi + + case $command in + create | list) + _kubecfg_service_match + ;; + update | get | delete) + _kubecfg_specific_service_match + ;; + *) + ;; + esac + + return 0 +} + +complete -F _kubecfg kubecfg +# ex: ts=4 sw=4 et filetype=sh