You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
6.9 KiB
225 lines
6.9 KiB
function _incus_container {
|
|
incus list --format csv --columns n type=CONTAINER
|
|
}
|
|
|
|
function _incus_running_container {
|
|
incus list --format csv --columns n type=CONTAINER state=RUNNING
|
|
}
|
|
|
|
function _incus_stopped_container {
|
|
incus list --format csv --columns n type=CONTAINER state=STOPPED
|
|
}
|
|
|
|
function _active_users {
|
|
echo root
|
|
miaou-exec "$container" -- awk -F: '$3 >= 1000 && $7 !~ /nologin|false/ {print $1}' /etc/passwd
|
|
}
|
|
|
|
function _miaou_login {
|
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
|
local prev="${COMP_WORDS[COMP_CWORD - 1]}"
|
|
local container="${COMP_WORDS[1]}"
|
|
|
|
case $COMP_CWORD in
|
|
1)
|
|
# first argument — containers
|
|
COMPREPLY=($(compgen -W "$(_incus_running_container)" -- "$cur"))
|
|
;;
|
|
2)
|
|
# second argument - options
|
|
COMPREPLY=($(compgen -W "--user -u" -- "$cur"))
|
|
;;
|
|
3)
|
|
if [[ $prev =~ ^(--user|-u) ]]; then
|
|
# user expected
|
|
COMPREPLY=($(compgen -W "$(_active_users "$container")" -- "$cur"))
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function _miaou_exec() {
|
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
|
local prev="${COMP_WORDS[COMP_CWORD - 1]}"
|
|
local container="${COMP_WORDS[1]}"
|
|
|
|
# find '--' position
|
|
local dashdash_pos=0
|
|
local i
|
|
for ((i = 0; i < ${#COMP_WORDS[@]}; i++)); do
|
|
[[ ${COMP_WORDS[$i]} == "--" ]] && dashdash_pos=$i
|
|
done
|
|
|
|
# complete running container names
|
|
if ((COMP_CWORD == 1)); then
|
|
# first argument — containers
|
|
COMPREPLY=($(compgen -W "$(_incus_running_container)" -- "$cur"))
|
|
return
|
|
fi
|
|
|
|
if ((COMP_CWORD == 2)); then
|
|
# second argument - options
|
|
COMPREPLY=($(compgen -W "--" -- "$cur"))
|
|
return
|
|
fi
|
|
|
|
if ((COMP_CWORD == 3)); then
|
|
# command or file from inside container
|
|
# echo -e "\nCOMMAND or FILE from CONTAINER\n" >&2
|
|
|
|
COMPREPLY_COMMANDS=($(
|
|
incus exec "$container" -- bash << EOF
|
|
bind -f /etc/inputrc 2>/dev/null
|
|
source /etc/bash_completion
|
|
compgen -c -- "$cur"
|
|
EOF
|
|
))
|
|
COMPREPLY_FILES=($(
|
|
incus exec "$container" -- bash << EOF
|
|
bind -f /etc/inputrc 2>/dev/null
|
|
source /etc/bash_completion
|
|
compgen -f -- "$cur"
|
|
EOF
|
|
))
|
|
|
|
COMPREPLY=(${COMPREPLY_COMMANDS[@]} ${COMPREPLY_FILES[@]})
|
|
if [[ ${#COMPREPLY_FILES[@]} -gt 0 ]]; then
|
|
compopt -o filenames
|
|
compopt -o nospace
|
|
fi
|
|
|
|
# echo -e "\nCOMPREPLY=( ${COMPREPLY[@]} ) FILES=${#COMPREPLY_FILES[@]}\n" >&2
|
|
|
|
return
|
|
fi
|
|
|
|
if ((COMP_CWORD > 3)); then
|
|
|
|
command=${COMP_WORDS[dashdash_pos + 1]}
|
|
# echo -e "\nCOMMAND:$command from CONTAINER\n" >&2
|
|
|
|
completion_command=$(
|
|
incus exec "$container" -- bash << EOF
|
|
source /etc/bash_completion
|
|
[[ -f /usr/share/bash-completion/completions/$command ]] && source /usr/share/bash-completion/completions/$command
|
|
complete -p "$command" 2>/dev/null | grep -oP '(?<=-F )\S+'
|
|
EOF
|
|
)
|
|
if [[ -n $completion_command ]]; then
|
|
# Remove first $dashdash_pos items
|
|
COMP_WORDS=("${COMP_WORDS[@]:dashdash_pos+1}")
|
|
COMP_CWORD=$((COMP_CWORD - dashdash_pos - 1))
|
|
COMP_LINE="${COMP_WORDS[@]}"
|
|
COMP_POINT=${#COMP_LINE}
|
|
COMP_POINT=$((COMP_POINT + 1))
|
|
|
|
# _comp_debug completion_command $completion_command
|
|
# _comp_debug prev $prev
|
|
# _comp_debug cur $cur
|
|
# _comp_debug COMP_WORDS "(${COMP_WORDS[@]})"
|
|
# _comp_debug COMP_CWORD $COMP_CWORDS
|
|
|
|
COMPREPLY=($(
|
|
incus exec "$container" -- bash << EOF
|
|
bind -f /etc/inputrc 2>/dev/null
|
|
source /etc/bash_completion
|
|
for i in /etc/bash_completion.d/*; do source \$i; done
|
|
source /usr/share/bash-completion/bash_completion
|
|
[[ -f /usr/share/bash-completion/completions/$command ]] && source /usr/share/bash-completion/completions/$command
|
|
COMP_WORDS=(${COMP_WORDS[@]})
|
|
COMP_CWORD=$COMP_CWORD
|
|
COMP_LINE="$COMP_LINE"
|
|
COMP_POINT=$COMP_POINT
|
|
COMP_TYPE=9
|
|
COMP_KEY=9
|
|
export COMP_WORDS COMP_CWORD COMP_LINE COMP_POINT COMP_TYPE COMP_KEY
|
|
$completion_command 2>/dev/null
|
|
echo \${COMPREPLY[@]}
|
|
EOF
|
|
))
|
|
if [[ $completion_command == '_comp_complete_longopt' ]]; then
|
|
compopt -o filenames
|
|
compopt -o nospace
|
|
fi
|
|
|
|
else
|
|
# _comp_debug "NO completion_command JUST plain files and dirs"
|
|
|
|
compopt -o filenames
|
|
compopt -o nospace
|
|
COMPREPLY=($(
|
|
incus exec "$container" -- bash << EOF
|
|
bind -f /etc/inputrc 2>/dev/null
|
|
source /etc/bash_completion
|
|
compgen -f "$cur" 2>/dev/null
|
|
EOF
|
|
))
|
|
fi
|
|
fi
|
|
|
|
}
|
|
|
|
function _miaou_ls {
|
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
|
if [[ $cur =~ ^- ]]; then
|
|
# options
|
|
COMPREPLY=(--vm)
|
|
elif ((COMP_CWORD == 1)); then
|
|
# containers
|
|
COMPREPLY=(--vm $(compgen -W "$(_incus_container)" -- "$cur"))
|
|
fi
|
|
}
|
|
|
|
function _array_intersect {
|
|
local -n arr1=$1
|
|
local -n arr2=$2
|
|
local -n result=$3
|
|
|
|
declare -A include
|
|
for item in "${arr2[@]}"; do include["$item"]=1; done
|
|
|
|
result=()
|
|
for item in "${arr1[@]}"; do [[ -n ${include["$item"]} ]] && result+=("$item"); done
|
|
}
|
|
|
|
function _array_subtract {
|
|
local -n arr1=$1 # First array
|
|
local -n arr2=$2 # Array to subtract
|
|
local -n result=$3 # Output array
|
|
|
|
[[ ${#arr2[@]} == 0 ]] && result=("${arr1[@]}") && return
|
|
|
|
declare -A exclude
|
|
for item in "${arr2[@]}"; do exclude["$item"]=1; done
|
|
|
|
result=()
|
|
for item in "${arr1[@]}"; do [[ -z ${exclude["$item"]} ]] && result+=("$item"); done
|
|
}
|
|
|
|
function _comp_debug {
|
|
echo -e "\nDEBUG: $@" >&2
|
|
}
|
|
|
|
function _miaou_start {
|
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
|
|
|
# containers...
|
|
local suggestions=($(compgen -W "$(_incus_stopped_container)" -- "$cur"))
|
|
local previous_containers=("${COMP_WORDS[@]:1:${#COMP_WORDS[@]}-2}") # drop first and last items
|
|
_array_subtract suggestions previous_containers COMPREPLY
|
|
}
|
|
|
|
function _miaou_stop {
|
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
|
|
|
# containers...
|
|
local suggestions=($(compgen -W "$(_incus_running_container)" -- "$cur"))
|
|
local previous_containers=("${COMP_WORDS[@]:1:${#COMP_WORDS[@]}-2}") # drop first and last items
|
|
_array_subtract suggestions previous_containers COMPREPLY
|
|
}
|
|
|
|
complete -F _miaou_login "miaou-login"
|
|
complete -F _miaou_exec "miaou-exec"
|
|
complete -F _miaou_ls "miaou-ls"
|
|
complete -F _miaou_start "miaou-start"
|
|
complete -F _miaou_stop "miaou-stop"
|