From 563950ff7f20faddf13c70a6bf875c26605074da Mon Sep 17 00:00:00 2001 From: pvincent Date: Thu, 9 Apr 2026 16:37:49 +0400 Subject: [PATCH] miaou-start and miaou-stop --- lib/miaou.completion | 85 ++++++++++++++++++++++++++++++++++++++++++-- tools/miaou-login | 4 +-- tools/miaou-start | 43 ++++++++++++++++++++++ tools/miaou-stop | 43 ++++++++++++++++++++++ 4 files changed, 171 insertions(+), 4 deletions(-) create mode 100755 tools/miaou-start create mode 100755 tools/miaou-stop diff --git a/lib/miaou.completion b/lib/miaou.completion index 320aebe..74e41b8 100644 --- a/lib/miaou.completion +++ b/lib/miaou.completion @@ -6,6 +6,10 @@ 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 @@ -109,7 +113,12 @@ EOF COMP_POINT=${#COMP_LINE} COMP_POINT=$((COMP_POINT + 1)) - # echo -e "\ncompletion_command $completion_command \nprev=$prev \ncur=$cur \nCOMP_WORDS=(${COMP_WORDS[@]}) \nCOMP_CWORD=$COMP_CWORD \nCOMP_LINE=$COMP_LINE \nCOMP_POINT=$COMP_POINT" >&2 + # _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 @@ -134,7 +143,8 @@ EOF fi else - # echo -e "\nNO completion_command JUST plain files and dirs\n" >&2 + # _comp_debug "NO completion_command JUST plain files and dirs" + compopt -o filenames compopt -o nospace COMPREPLY=($( @@ -164,6 +174,77 @@ function _miaou_ls { } +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 done=() + local suggestions=($(compgen -W "$(_incus_stopped_container)" -- "$cur")) + local selected=("${COMP_WORDS[@]:1}") + selected=("${selected[@]:0:${#selected[@]}-1}") + _array_subtract suggestions selected done + COMPREPLY=("${done[@]}") +} + +function _miaou_start { + local cur="${COMP_WORDS[COMP_CWORD]}" + + # containers... + local suggestions=($(compgen -W "$(_incus_stopped_container)" -- "$cur")) + COMP_WORDS=("${COMP_WORDS[@]:1:${#COMP_WORDS[@]}-2}") # drop first and last items + _array_subtract suggestions COMP_WORDS COMPREPLY +} + +function _miaou_stop { + local cur="${COMP_WORDS[COMP_CWORD]}" + + # containers... + local suggestions=($(compgen -W "$(_incus_running_container)" -- "$cur")) + COMP_WORDS=("${COMP_WORDS[@]:1:${#COMP_WORDS[@]}-2}") # drop first and last items + _array_subtract suggestions COMP_WORDS 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" diff --git a/tools/miaou-login b/tools/miaou-login index 26dc031..4f39fe8 100755 --- a/tools/miaou-login +++ b/tools/miaou-login @@ -3,8 +3,8 @@ # CONSTANTS BASEDIR=$(dirname "$0") -CONTAINER='' -USER='' +CONTAINER= +USER= # FUNCTIONS diff --git a/tools/miaou-start b/tools/miaou-start new file mode 100755 index 0000000..1136ae6 --- /dev/null +++ b/tools/miaou-start @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# CONSTANTS + +BASEDIR=$(dirname "$0") +CONTAINERS=() +USER= + +# FUNCTIONS + +function usage { + echo "$(basename "$0") ..." +} + +function parse_options { + while [[ $# -gt 0 ]]; do + case "$1" in + --help | -h) + usage && exit 0 + ;; + -*) + echo >&2 "Error: unknown option: $1" && usage && exit 2 + ;; + *) + CONTAINERS+=("$1") + ;; + esac + + shift 1 # Move to the next argument + done + + [[ ${#CONTAINERS[@]} == 0 ]] && usage && exit 1 || true +} + +function start { + incus start "${CONTAINERS[@]}" +} + +# MAIN + +set -Eue +parse_options $* +start diff --git a/tools/miaou-stop b/tools/miaou-stop new file mode 100755 index 0000000..6519cba --- /dev/null +++ b/tools/miaou-stop @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# CONSTANTS + +BASEDIR=$(dirname "$0") +CONTAINERS=() +USER= + +# FUNCTIONS + +function usage { + echo "$(basename "$0") ..." +} + +function parse_options { + while [[ $# -gt 0 ]]; do + case "$1" in + --help | -h) + usage && exit 0 + ;; + -*) + echo >&2 "Error: unknown option: $1" && usage && exit 2 + ;; + *) + CONTAINERS+=("$1") + ;; + esac + + shift 1 # Move to the next argument + done + + [[ ${#CONTAINERS[@]} == 0 ]] && usage && exit 1 || true +} + +function stop { + incus stop "${CONTAINERS[@]}" +} + +# MAIN + +set -Eue +parse_options $* +stop