#!/bin/bash # --- CONFIGURATION --- # The user that runs paru inside the Arch LXCs AUR_USER="liph" # 1. EXCLUDE LIST: Put CTIDs here that you want the script to TOTALLY ignore # Example: EXCLUDE_LIST=( 105 110 ) EXCLUDE_LIST=(106 113 114 115 116) declare -A CONTAINER_MAP CONTAINER_MAP[100]="/mnt/flash1/podman/lxc_servarr/" CONTAINER_MAP[101]="/mnt/flash1/podman/lxc_second/" CONTAINER_MAP[108]="/mnt/flash1/podman/lxc_dns/" # Multiple paths allowed CONTAINER_MAP[109]="/mnt/flash1/podman/lxc_immich/" CONTAINER_MAP[111]="/mnt/flash1/podman/lxc_ollama/" ALL_CTIDS=$(pct list | awk 'NR>1 {print $1}') for CTID in $ALL_CTIDS; do if [[ " ${EXCLUDE_LIST[@]} " =~ " ${CTID} " ]]; then continue; fi if pct config $CTID | grep -q "template: 1"; then continue; fi NAME=$(pct config $CTID | grep "hostname:" | awk '{print $2}') STATUS=$(pct status $CTID | awk '{print $2}') echo "=======================================================" echo " PROCESSING LXC: $NAME (ID: $CTID)" echo "=======================================================" WAS_STOPPED=false if [ "$STATUS" == "stopped" ]; then pct start $CTID sleep 10 WAS_STOPPED=true fi # 1. OS UPDATER (Handling Paru correctly) echo "[+] Updating Arch packages..." # We use -Syu. We run it via 'sudo -u user' but because pct exec is root, # it won't ask for a password. pct exec $CTID -- sudo -u $AUR_USER paru -Syu --noconfirm --cleanafter # 2. PODMAN SCAN & AUTO-DETECT COMMAND if [[ -n "${CONTAINER_MAP[$CTID]}" ]]; then ROOT_DIR=${CONTAINER_MAP[$CTID]} # Detect which command works: 'podman compose' (V2) or 'podman-compose' (Python) # We test this inside the LXC if pct exec $CTID -- podman compose version >/dev/null 2>&1; then FINAL_CMD="podman compose" elif pct exec $CTID -- podman-compose version >/dev/null 2>&1; then FINAL_CMD="podman-compose" elif pct exec $CTID -- docker-compose version >/dev/null 2>&1; then FINAL_CMD="docker-compose" else FINAL_CMD="" fi if [ -z "$FINAL_CMD" ]; then echo "[ERROR] No compose command found in LXC $CTID!" else echo "[#] Using command: $FINAL_CMD" COMPOSE_FILES=$(pct exec $CTID -- find "$ROOT_DIR" -maxdepth 2 -name "docker-compose.y*ml") for FILE in $COMPOSE_FILES; do DIR=$(dirname "$FILE") echo " -> Updating: $DIR" # Run the pull and up # Note: No 'sudo' here because pct exec is already root full pct exec $CTID -- bash -c "cd $DIR && $FINAL_CMD pull" if [ "$WAS_STOPPED" = false ]; then pct exec $CTID -- bash -c "cd $DIR && $FINAL_CMD up -d" fi done fi echo "[+] Pruning images..." pct exec $CTID -- podman image prune -f fi # 3. MAINTENANCE pct exec $CTID -- journalctl --rotate pct exec $CTID -- journalctl --vacuum-time=7d pct exec $CTID -- bash -c 'orphans=$(pacman -Qtdq); if [ -n "$orphans" ]; then pacman -Rns $orphans --noconfirm; fi' if [ "$WAS_STOPPED" = true ]; then pct shutdown $CTID fi done