|
|
@ -5,128 +5,128 @@ MIAOU_INCUS_DIR=${MIAOU_INCUS_DIR:-/opt/miaou-incus} |
|
|
# FUNCTIONS |
|
|
# FUNCTIONS |
|
|
|
|
|
|
|
|
function _incus_container { |
|
|
function _incus_container { |
|
|
incus list --format csv --columns n type=CONTAINER |
|
|
|
|
|
|
|
|
incus list --format csv --columns n type=CONTAINER |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function _incus_running_container { |
|
|
function _incus_running_container { |
|
|
incus list --format csv --columns n type=CONTAINER state=RUNNING |
|
|
|
|
|
|
|
|
incus list --format csv --columns n type=CONTAINER state=RUNNING |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function _incus_stopped_container { |
|
|
function _incus_stopped_container { |
|
|
incus list --format csv --columns n type=CONTAINER state=STOPPED |
|
|
|
|
|
|
|
|
incus list --format csv --columns n type=CONTAINER state=STOPPED |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function _active_users { |
|
|
function _active_users { |
|
|
echo root |
|
|
|
|
|
miaou-exec "$container" -- awk -F: '$3 >= 1000 && $7 !~ /nologin|false/ {print $1}' /etc/passwd |
|
|
|
|
|
|
|
|
echo root |
|
|
|
|
|
miaou-exec "$container" -- awk -F: '$3 >= 1000 && $7 !~ /nologin|false/ {print $1}' /etc/passwd |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function _miaou_login { |
|
|
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 |
|
|
|
|
|
|
|
|
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() { |
|
|
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 |
|
|
|
|
|
|
|
|
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 |
|
|
bind -f /etc/inputrc 2>/dev/null |
|
|
source /etc/bash_completion |
|
|
source /etc/bash_completion |
|
|
compgen -c -- "$cur" |
|
|
compgen -c -- "$cur" |
|
|
EOF |
|
|
EOF |
|
|
)) |
|
|
|
|
|
COMPREPLY_FILES=($( |
|
|
|
|
|
incus exec "$container" -- bash << EOF |
|
|
|
|
|
|
|
|
)) |
|
|
|
|
|
COMPREPLY_FILES=($( |
|
|
|
|
|
incus exec "$container" -- bash << EOF |
|
|
bind -f /etc/inputrc 2>/dev/null |
|
|
bind -f /etc/inputrc 2>/dev/null |
|
|
source /etc/bash_completion |
|
|
source /etc/bash_completion |
|
|
compgen -f -- "$cur" |
|
|
compgen -f -- "$cur" |
|
|
EOF |
|
|
EOF |
|
|
)) |
|
|
|
|
|
|
|
|
)) |
|
|
|
|
|
|
|
|
COMPREPLY=(${COMPREPLY_COMMANDS[@]} ${COMPREPLY_FILES[@]}) |
|
|
|
|
|
if [[ ${#COMPREPLY_FILES[@]} -gt 0 ]]; then |
|
|
|
|
|
compopt -o filenames |
|
|
|
|
|
compopt -o nospace |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
# echo -e "\nCOMPREPLY=( ${COMPREPLY[@]} ) FILES=${#COMPREPLY_FILES[@]}\n" >&2 |
|
|
|
|
|
|
|
|
return |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
return |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
if ((COMP_CWORD > 3)); then |
|
|
|
|
|
|
|
|
if ((COMP_CWORD > 3)); then |
|
|
|
|
|
|
|
|
command=${COMP_WORDS[dashdash_pos + 1]} |
|
|
|
|
|
# echo -e "\nCOMMAND:$command from CONTAINER\n" >&2 |
|
|
|
|
|
|
|
|
command=${COMP_WORDS[dashdash_pos + 1]} |
|
|
|
|
|
# echo -e "\nCOMMAND:$command from CONTAINER\n" >&2 |
|
|
|
|
|
|
|
|
completion_command=$( |
|
|
|
|
|
incus exec "$container" -- bash << EOF |
|
|
|
|
|
|
|
|
completion_command=$( |
|
|
|
|
|
incus exec "$container" -- bash << EOF |
|
|
source /etc/bash_completion |
|
|
source /etc/bash_completion |
|
|
[[ -f /usr/share/bash-completion/completions/$command ]] && source /usr/share/bash-completion/completions/$command |
|
|
[[ -f /usr/share/bash-completion/completions/$command ]] && source /usr/share/bash-completion/completions/$command |
|
|
complete -p "$command" 2>/dev/null | grep -oP '(?<=-F )\S+' |
|
|
complete -p "$command" 2>/dev/null | grep -oP '(?<=-F )\S+' |
|
|
EOF |
|
|
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 |
|
|
|
|
|
|
|
|
) |
|
|
|
|
|
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 |
|
|
bind -f /etc/inputrc 2>/dev/null |
|
|
source /etc/bash_completion |
|
|
source /etc/bash_completion |
|
|
for i in /etc/bash_completion.d/*; do source \$i; done |
|
|
for i in /etc/bash_completion.d/*; do source \$i; done |
|
|
@ -142,84 +142,100 @@ EOF |
|
|
$completion_command 2>/dev/null |
|
|
$completion_command 2>/dev/null |
|
|
echo \${COMPREPLY[@]} |
|
|
echo \${COMPREPLY[@]} |
|
|
EOF |
|
|
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 |
|
|
|
|
|
|
|
|
)) |
|
|
|
|
|
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 |
|
|
bind -f /etc/inputrc 2>/dev/null |
|
|
source /etc/bash_completion |
|
|
source /etc/bash_completion |
|
|
compgen -f "$cur" 2>/dev/null |
|
|
compgen -f "$cur" 2>/dev/null |
|
|
EOF |
|
|
EOF |
|
|
)) |
|
|
|
|
|
fi |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
)) |
|
|
|
|
|
fi |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function _miaou_ls { |
|
|
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 |
|
|
|
|
|
|
|
|
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 _comp_debug { |
|
|
function _comp_debug { |
|
|
echo -e "\nDEBUG: $@" >&2 |
|
|
|
|
|
|
|
|
echo -e "\nDEBUG: $@" >&2 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function _miaou_start { |
|
|
function _miaou_start { |
|
|
local cur="${COMP_WORDS[COMP_CWORD]}" |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
# 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 { |
|
|
function _miaou_stop { |
|
|
local cur="${COMP_WORDS[COMP_CWORD]}" |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
# 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 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function _miaou_destroy { |
|
|
function _miaou_destroy { |
|
|
local cur suggestions previous_words |
|
|
|
|
|
|
|
|
|
|
|
cur="${COMP_WORDS[COMP_CWORD]}" |
|
|
|
|
|
if [[ $cur =~ ^- ]]; then |
|
|
|
|
|
suggestions=(--yes --force) |
|
|
|
|
|
else |
|
|
|
|
|
_array_contains COMP_WORDS --force && suggestions=($(_incus_container)) || suggestions=($(_incus_stopped_container)) |
|
|
|
|
|
[[ ${#suggestions[@]} == 0 ]] && suggestions=(--force) |
|
|
|
|
|
fi |
|
|
|
|
|
suggestions=($(compgen -W "${suggestions[*]}" -- "$cur")) |
|
|
|
|
|
previous_words=("${COMP_WORDS[@]:1:${#COMP_WORDS[@]}-2}") # drop first and last items |
|
|
|
|
|
_array_subtract suggestions previous_words COMPREPLY |
|
|
|
|
|
|
|
|
local cur suggestions previous_words |
|
|
|
|
|
|
|
|
|
|
|
cur="${COMP_WORDS[COMP_CWORD]}" |
|
|
|
|
|
if [[ $cur =~ ^- ]]; then |
|
|
|
|
|
suggestions=(--yes --force) |
|
|
|
|
|
else |
|
|
|
|
|
_array_contains COMP_WORDS --force && suggestions=($(_incus_container)) || suggestions=($(_incus_stopped_container)) |
|
|
|
|
|
[[ ${#suggestions[@]} == 0 ]] && suggestions=(--force) |
|
|
|
|
|
fi |
|
|
|
|
|
suggestions=($(compgen -W "${suggestions[*]}" -- "$cur")) |
|
|
|
|
|
previous_words=("${COMP_WORDS[@]:1:${#COMP_WORDS[@]}-2}") # drop first and last items |
|
|
|
|
|
_array_subtract suggestions previous_words COMPREPLY |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function _miaou_recipe { |
|
|
|
|
|
local cur="${COMP_WORDS[COMP_CWORD]}" |
|
|
|
|
|
|
|
|
|
|
|
# containers... |
|
|
|
|
|
if [[ $COMP_CWORD == 1 ]]; then |
|
|
|
|
|
COMPREPLY=($(compgen -W "$(_incus_running_container)" -- "$cur")) |
|
|
|
|
|
elif [[ $COMP_CWORD == 2 ]]; then |
|
|
|
|
|
COMPREPLY=($(compgen -f -- "$cur")) |
|
|
|
|
|
compopt -o filenames |
|
|
|
|
|
elif [[ $COMP_CWORD == 3 ]]; then |
|
|
|
|
|
COMPREPLY=($(compgen -W "--" -- "$cur")) |
|
|
|
|
|
fi |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
# MAIN |
|
|
# MAIN |
|
|
|
|
|
|
|
|
# shellcheck source=/opt/miaou-incus/lib/functions.bash |
|
|
|
|
|
source "$MIAOU_INCUS_DIR/lib/functions.bash" |
|
|
|
|
|
|
|
|
# shellcheck source=/opt/miaou-bash/lib/functions.bash |
|
|
|
|
|
source "$MIAOU_BASH_DIR/lib/functions.bash" |
|
|
|
|
|
|
|
|
complete -F _miaou_login "miaou-login" |
|
|
complete -F _miaou_login "miaou-login" |
|
|
complete -F _miaou_exec "miaou-exec" |
|
|
complete -F _miaou_exec "miaou-exec" |
|
|
complete -F _miaou_ls "miaou-ls" |
|
|
complete -F _miaou_ls "miaou-ls" |
|
|
complete -F _miaou_start "miaou-start" |
|
|
complete -F _miaou_start "miaou-start" |
|
|
complete -F _miaou_stop "miaou-stop" |
|
|
complete -F _miaou_stop "miaou-stop" |
|
|
complete -F _miaou_destroy "miaou-destroy" |
|
|
complete -F _miaou_destroy "miaou-destroy" |
|
|
|
|
|
complete -F _miaou_recipe "miaou-recipe" |