#!/usr/bin/env bash set -u # Colors: try tput; fall back to ANSI if unavailable if command -v tput >/dev/null 2>&1; then RESET="$(tput sgr0)" GREEN="$(tput setaf 2 || true)" # green RED="$(tput setaf 1 || true)" # red # Prefer a true "orange" if 256 colors are available; else use yellow if [ "$(tput colors 2>/dev/null || echo 0)" -ge 256 ]; then ORANGE="$(printf '\033[38;5;214m')" # 214 ~ orange else ORANGE="$(tput setaf 3 || printf '\033[33m')" # yellow fallback fi else RESET=$'\033[0m' GREEN=$'\033[32m' RED=$'\033[31m' ORANGE=$'\033[33m' # yellow as fallback fi pause() { echo; sleep 2; } info() { printf "%b%s%b\n" "$ORANGE" "$1" "$RESET"; } ok() { printf "%b%s%b\n" "$GREEN" "$1" "$RESET"; } fail() { printf "%b%s%b\n" "$RED" "$1" "$RESET"; } # Step 1: clear screen clear # Step 2: prompt for backup filename (expects .xz; will append if missing) info "Backup Filename:" read -r -p "> " USER_INPUT echo if [ -z "${USER_INPUT:-}" ]; then fail "No filename provided. Exiting." exit 1 fi case "$USER_INPUT" in *.xz) FILENAME="$USER_INPUT" ;; *) FILENAME="${USER_INPUT}.xz" ;; esac # Derive safe base (strip .xz, sanitize), temp dir at /temp- BASENAME="${FILENAME%.xz}" BASENAME_SAFE="$(basename -- "$BASENAME")" BASENAME_SAFE="${BASENAME_SAFE//[^A-Za-z0-9._-]/_}" TMPDIR="/temp-${BASENAME_SAFE}" info "Backup Started..." ok "Preparing..." pause # Step 3: make temp folder info "Creating temp folder: ${TMPDIR}" if mkdir -p -- "$TMPDIR"; then ok "Temp folder CREATED." else fail "Failed to create temp folder." exit 1 fi pause # Step 4: copy /etc/pve contents into temp (preserve attributes) info "Copying /etc/pve into ${TMPDIR}/etc-pve" if cp -a /etc/pve/. "${TMPDIR}/etc-pve" 2>/dev/null; then ok "Copy of /etc/pve COMPLETED." else fail "Copy of /etc/pve FAILED. Check permissions." exit 1 fi pause # Step 5: copy system files info "Copying system files into ${TMPDIR}" COPIED_ALL=true for f in /etc/passwd /etc/network/interfaces /etc/resolv.conf; do if [ -e "$f" ]; then if cp -a -- "$f" "$TMPDIR/"; then : else COPIED_ALL=false fail "Failed to copy $f" fi else COPIED_ALL=false fail "Missing $f (skipped)" fi done if $COPIED_ALL; then ok "Copy of system files COMPLETED." else ok "Copy step finished with notes above." fi pause # Step 6: compress the temp folder to requested .xz filename using tar+xz OUTPATH="$(pwd)/${FILENAME}" info "Compressing ${TMPDIR} to ${OUTPATH}" TMP_PARENT="$(dirname "$TMPDIR")" TMP_NAME="$(basename "$TMPDIR")" # Use tar -J (xz) to archive the folder and write to a file named as requested if tar -C "$TMP_PARENT" -cJf "$OUTPATH" "$TMP_NAME" 2>/dev/null; then ok "Compression COMPLETED." else fail "Compression FAILED." exit 1 fi pause # Step 7: delete temp folder info "Clearing temp files that created." if rm -rf -- "$TMPDIR"; then ok "Clearing COMPLETED." else fail "Clearing FAILED. Manual removal may be required: $TMPDIR" exit 1 fi pause # Step 8: show where the archive is stored info "Backup Filename is :" ok "Folder ${OUTPATH}" pause exit 0