#!/bin/bash # Default parameter file DEFAULT_PARAM_FILE="params.conf" # Function to load parameters from a file load_params() { local param_file=$1 if [ -f "$param_file" ]; then source "$param_file" else echo "Parameter file $param_file does not exist." exit 1 fi } # Function to find the lowest free container ID starting from MIN_ID find_lowest_free_id() { local id=$MIN_ID while pct status $id &>/dev/null || qm status $id &>/dev/null; do ((id++)) done echo $id } # Parse command line arguments while [[ "$#" -gt 0 ]]; do case $1 in --param-file) PARAM_FILE="$2"; shift ;; --template) TEMPLATE="$2"; shift ;; --ram) RAM="$2"; shift ;; --swap) SWAP="$2"; shift ;; --cores) CORES="$2"; shift ;; --bridge) BRIDGE="$2"; shift ;; --ip) IP="$2"; shift ;; --ctid) CTID="$2"; shift ;; --hostname) HOSTNAME="$2"; shift ;; --export-name) EXPORT_NAME="$2"; shift ;; --export-path) EXPORT_PATH="$2"; shift ;; --min-id) MIN_ID="$2"; shift ;; --storage) STORAGE="$2"; shift ;; --disk-size) DISK_SIZE="$2"; shift ;; --mount-point) MOUNT_POINT="$2"; shift ;; --privileged) PRIVILEGED="$2"; shift ;; *) echo "Unknown parameter passed: $1"; exit 1 ;; esac shift done # Load parameters from the parameter file if specified, otherwise use default PARAM_FILE=${PARAM_FILE:-$DEFAULT_PARAM_FILE} load_params "$PARAM_FILE" # Set defaults for parameters if not provided by the parameter file or command line TEMPLATE=${TEMPLATE:-"adastor:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst"} RAM=${RAM:-1024} SWAP=${SWAP:-512} CORES=${CORES:-2} BRIDGE=${BRIDGE:-vmbr0} IP=${IP:-dhcp} CTID=${CTID:-$(find_lowest_free_id)} HOSTNAME=${HOSTNAME:-nginx-debian} EXPORT_NAME=${EXPORT_NAME:-mycontainer_backup} CURRENT_DIR=$(pwd) EXPORT_PATH=${EXPORT_PATH:-$CURRENT_DIR} MIN_ID=${MIN_ID:-200} STORAGE=${STORAGE:-local-btrfs} DISK_SIZE=${DISK_SIZE:-8} MOUNT_POINT=${MOUNT_POINT:-} PRIVILEGED=${PRIVILEGED:-0} ROOTFS="${STORAGE}:${DISK_SIZE}" # Check if the script content is provided if [ -z "$SCRIPT_CONTENT" ]; then echo "Script content not provided in the parameter file." exit 1 fi # Write the script content to a temporary file TEMP_SCRIPT=$(mktemp) echo "$SCRIPT_CONTENT" > "$TEMP_SCRIPT" chmod +x "$TEMP_SCRIPT" # Check if the container already exists on the local node if pct status $CTID &>/dev/null; then echo "VM $CTID already exists on this node." rm "$TEMP_SCRIPT" exit 1 fi # Create the container with the correct storage format if ! pct create $CTID $TEMPLATE --rootfs $ROOTFS --cores $CORES --memory $RAM --swap $SWAP --net0 name=eth0,bridge=$BRIDGE,ip=$IP --hostname $HOSTNAME --unprivileged $PRIVILEGED; then echo "Failed to create the container." rm "$TEMP_SCRIPT" exit 1 fi # Set the mount point if specified if [ -n "$MOUNT_POINT" ]; then if ! pct set $CTID -mp0 $MOUNT_POINT,backup=1; then echo "Failed to set the mount point." rm "$TEMP_SCRIPT" exit 1 fi fi # Start the container if ! pct start $CTID; then echo "Failed to start the container." rm "$TEMP_SCRIPT" exit 1 fi # Copy the temporary script file to the container pct push $CTID $TEMP_SCRIPT /root/script.sh -perms 755 # Run the script inside the container if ! pct exec $CTID -- /root/script.sh; then echo "Failed to run the script inside the container." pct stop $CTID rm "$TEMP_SCRIPT" exit 1 fi # Stop the container if ! pct stop $CTID; then echo "Failed to stop the container." rm "$TEMP_SCRIPT" exit 1 fi # Export the container as a tar.gz file BACKUP_FILE=$EXPORT_PATH/$EXPORT_NAME.tar.gz if ! vzdump $CTID --dumpdir $EXPORT_PATH --compress gzip; then echo "Failed to export the container." rm "$TEMP_SCRIPT" exit 1 fi # Cleanup rm "$TEMP_SCRIPT" echo "Container $CTID has been created, configured, and exported to $BACKUP_FILE"