From 1259c869fb673cebc301e90ed98998f48ed235cd Mon Sep 17 00:00:00 2001 From: pvincent Date: Fri, 19 Dec 2025 07:08:21 +0400 Subject: [PATCH] miaou-tools --- bin/pct-create | 43 +++++++++++++++++++++++++++---- tools/miaou-create | 64 ++++++++++++++++++++++++++++++++++++++++++++++ tools/miaou-exec | 53 ++++++++++++++++++++++++++++++++++++++ tools/miaou-login | 62 ++++++++++++++++++++++++++++++++++++++++++++ tools/miaou-push | 50 ++++++++++++++++++++++++++++++++++++ tools/miaou-recipe | 60 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 327 insertions(+), 5 deletions(-) create mode 100755 tools/miaou-create create mode 100755 tools/miaou-exec create mode 100755 tools/miaou-login create mode 100755 tools/miaou-push create mode 100755 tools/miaou-recipe diff --git a/bin/pct-create b/bin/pct-create index ced5e68..5a63858 100755 --- a/bin/pct-create +++ b/bin/pct-create @@ -3,7 +3,9 @@ # CONSTANTS BASEDIR=$(dirname "$0") -CONTAINER_NAME=$1 +CONTAINER_NAME='' +START=true + TEMPLATE_DIR=/var/lib/vz/template/cache TAG_NAME=debian13 SSH_PUBKEYS="$BASEDIR/../config/admin.pubkeys" @@ -12,7 +14,31 @@ CONFIG_FILE="$BASEDIR/../config/default.conf" # FUNCTIONS function usage { - echo "$(basename "$0") " + echo "$(basename "$0") [--no-start]" +} + +function parse_options { + while [[ $# -gt 0 ]]; do + case "$1" in + --help | -h) + usage && exit 0 + ;; + --no-start) + START=false + ;; + *) + if [[ -z $CONTAINER_NAME ]]; then + CONTAINER_NAME=$1 + else + echo >&2 "Unknown option: $1" && usage && exit 2 + fi + ;; + esac + + shift 1 # Move to the next argument + done + [[ -n $CONTAINER_NAME ]] || (usage && exit 1) + } function debian13_template { @@ -37,6 +63,14 @@ function optional_public_keys { fi } +function optional_start { + if [[ $START == true ]]; then + echo "--start" + else + echo + fi +} + function create_container { local new_id=$($BASEDIR/pct-nextid) local template_file="$TEMPLATE_DIR/$(debian13_template)" @@ -54,7 +88,7 @@ function create_container { --swap $swp_in_mb \ --hostname $CONTAINER_NAME \ --net0 name=eth0,bridge=$BRIDGE,ip=dhcp,firewall=1 \ - --start \ + $(optional_start) \ --onboot true \ $(optional_public_keys) \ --unprivileged true \ @@ -77,9 +111,8 @@ function existing_container { # MAIN set -Eue -[[ "$#" -lt 1 ]] && usage && exit 1 +parse_options $* source "$CONFIG_FILE" - existing_container && false || create_container diff --git a/tools/miaou-create b/tools/miaou-create new file mode 100755 index 0000000..c8b9076 --- /dev/null +++ b/tools/miaou-create @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +# CONSTANTS + +BASEDIR=$(dirname "$0") +CONTAINER='' + +# FUNCTIONS + +function usage { + echo "$(basename "$0") " +} + +function parse_options { + while [[ $# -gt 0 ]]; do + case "$1" in + --help | -h) + usage && exit 0 + ;; + *) + if [[ -z $CONTAINER ]]; then + CONTAINER=$1 + else + echo >&2 "Unknown option: $1" && usage && exit 2 + fi + ;; + esac + + shift 1 # Move to the next argument + done + [[ -n $CONTAINER ]] || (usage && exit 1) + +} + +function before_start { + # cold changes + if [[ -v MIAOU_BASH_DIR ]]; then + pct set $CONTAINER_ID -mp0 $MIAOU_BASH_DIR,mp=/opt/miaou-bash + else + echo >&2 "Warn: variable MIAOU_BASH_DIR missing!" + fi +} + +function after_start { + # hot changes + if [[ -v MIAOU_BASH_DIR ]]; then + pct exec "$CONTAINER_ID" -- /opt/miaou-bash/init.sh + fi + pct exec "$CONTAINER_ID" -- apt-get remove -y postfix +} + +function create { + CONTAINER_ID=$(pct-create $CONTAINER --no-start | grep "container: $CONTAINER succesfully created" | cut -d= -f2 | cut -d! -f1) + before_start + pct start $CONTAINER_ID + after_start +} + +# MAIN + +set -Eue +parse_options $* +create +echo Success diff --git a/tools/miaou-exec b/tools/miaou-exec new file mode 100755 index 0000000..f9b368a --- /dev/null +++ b/tools/miaou-exec @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +# CONSTANTS + +BASEDIR=$(dirname "$0") +CONTAINER='' +COMMAND='' + +# FUNCTIONS + +function usage { + echo "$(basename "$0") " +} + +function parse_options { + while [[ $# -gt 0 ]]; do + case "$1" in + --help | -h) + usage && exit 0 + ;; + --) + # don't care with -- + ;; + *) + if [[ -z $CONTAINER ]]; then + CONTAINER=$1 + elif [[ -z $COMMAND ]]; then + # FIXME: quite tricky + COMMAND=("$@") + for i in "${!COMMAND[@]}"; do + local value=${COMMAND[$i]} + [[ $value == *" "* ]] && COMMAND[$i]="'$value'" || true # add quote when space detected! + done + break + fi + ;; + esac + shift 1 + done + + [[ -n $CONTAINER ]] || [[ -n $COMMAND ]] || (usage && exit 1) +} + +function exec { + eval "pct exec $vmid -- ${COMMAND[@]}" +} + +# MAIN + +set -Eue +parse_options "$@" +vmid=$($BASEDIR/../bin/pct-lookup "$CONTAINER") +exec diff --git a/tools/miaou-login b/tools/miaou-login new file mode 100755 index 0000000..4e61d86 --- /dev/null +++ b/tools/miaou-login @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +# CONSTANTS + +BASEDIR=$(dirname "$0") +CONTAINER='' +USER='' + +# FUNCTIONS + +function usage { + echo "$(basename "$0") [--user|-u USER]" +} + +function parse_options { + while [[ $# -gt 0 ]]; do + case "$1" in + --help | -h) + usage && exit 0 + ;; + --user | -u) + shift 1 + [[ -z ${1:-} ]] && >&2 echo 'ERROR: user expected!' && usage && exit 5 + USER="$1" + ;; + *) + if [[ -z $CONTAINER ]]; then + CONTAINER=$1 + else + echo >&2 "Unknown option: $1" && usage && exit 2 + fi + ;; + esac + + shift 1 # Move to the next argument + done + [[ -n $CONTAINER ]] || (usage && exit 1) +} + +function pct_su { + pct exec "$vmid" -- su - $1 +} + +function pct_user_exists { + pct exec "$vmid" -- id $1 &> /dev/null +} + +function login { + if [[ -n $USER ]]; then + pct_su $USER + else + local current=$(whoami) + pct_user_exists $current && pct_su $current || pct_su root + fi +} + +# MAIN + +set -Eue +parse_options $* +vmid=$($BASEDIR/../bin/pct-lookup "$CONTAINER") +login diff --git a/tools/miaou-push b/tools/miaou-push new file mode 100755 index 0000000..bd14259 --- /dev/null +++ b/tools/miaou-push @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +# CONSTANTS + +BASEDIR=$(dirname "$0") +CONTAINER='' +SOURCE_FILE='' +DESTINATION_FOLDER='' + +# FUNCTIONS + +function usage { + echo "$(basename "$0") " +} + +function parse_options { + while [[ $# -gt 0 ]]; do + case "$1" in + --help | -h) + usage && exit 0 + ;; + *) + if [[ -z $CONTAINER ]]; then + CONTAINER=$1 + elif [[ -z $SOURCE_FILE ]]; then + SOURCE_FILE=$1 + elif [[ -z $DESTINATION_FOLDER ]]; then + DESTINATION_FOLDER=$1 + else + echo >&2 "Unknown option: $1" && usage && exit 2 + fi + ;; + esac + + shift 1 # Move to the next argument + done + + [[ -n $CONTAINER ]] || [[ -n $SOURCE_FILE ]] || [[ -n $DESTINATION_FOLDER ]] || (usage && exit 1) +} + +function copy { + pct push $vmid "$SOURCE_FILE" "$DESTINATION_FOLDER/$(basename $SOURCE_FILE)" --user 0 --group 0 +} + +# MAIN + +set -Eue +parse_options $* +vmid=$($BASEDIR/../bin/pct-lookup "$CONTAINER") +copy diff --git a/tools/miaou-recipe b/tools/miaou-recipe new file mode 100755 index 0000000..5068915 --- /dev/null +++ b/tools/miaou-recipe @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +# CONSTANTS + +BASEDIR=$(dirname "$0") +CONTAINER='' +SCRIPT='' +DEBUG=false +FORCE=${FORCE:-false} + +# FUNCTIONS + +function usage { + echo "$(basename "$0") {CONTAINER_NAME} {PATH_TO_SCRIPT} [[--debug|-d]]" +} + +function parse_options { + while [[ $# -gt 0 ]]; do + case "$1" in + --help | -h) + usage && exit 0 + ;; + --debug | -d) + DEBUG=true + ;; + *) + if [[ -z $CONTAINER ]]; then + CONTAINER=$1 + elif [[ -z $SCRIPT ]]; then + SCRIPT=$1 + else + echo >&2 "Unknown option: $1" && usage && exit 2 + fi + ;; + esac + + shift 1 # Move to the next argument + done + [[ -n $CONTAINER ]] && [[ -n $SCRIPT ]] || (usage && exit 1) +} + +function debug_option { + [[ $DEBUG == 'true' ]] && echo "-x" || true +} + +function recipe { + [[ ! -f $SCRIPT ]] && echo >&2 "Script not found: $SCRIPT" && exit 3 + + # hot changes + cat "$SCRIPT" | pct exec "$vmid" -- env FORCE="$FORCE" bash $(debug_option) + +} + +# MAIN + +set -Eue +parse_options $* +vmid=$($BASEDIR/../bin/pct-lookup "$CONTAINER") +recipe +echo "Recipe <$(basename "$SCRIPT")> successfully performed on container <$CONTAINER>"