Last active
November 6, 2024 11:48
-
-
Save jpawlowski/c8181d4c456563c569ca239ecbd8d143 to your computer and use it in GitHub Desktop.
Proxmox Hourly Snapshot Rotation Script: This Bash script automates the creation of hourly snapshots for running Proxmox VMs, while automatically deleting older snapshots to maintain a manageable rotation. It uses Proxmox CLI commands (pct and qm) without requiring additional libraries, making it lightweight and efficient. The script includes op…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Variables | |
DATE=$(date +"%Y%m%d%H") | |
DEFAULT_KEEP=24 # Default number of snapshots to keep | |
DEFAULT_RETAIN_DAYS=7 # Default days to keep LVM archive files | |
DRY_RUN=false | |
QUIET=false | |
KEEP=$DEFAULT_KEEP | |
RETAIN_DAYS=$DEFAULT_RETAIN_DAYS | |
# Help function | |
function show_help { | |
echo "Usage: $0 [-n | --dry-run for dry-run mode] [-q | --quiet to suppress output] [-k | --keep <number> to set snapshots to keep]" | |
echo " [--retain-days <number> to set days to keep LVM archives] [-h | --help for help]" | |
exit 0 | |
} | |
# Parse parameters | |
while [[ "$#" -gt 0 ]]; do | |
case $1 in | |
-n|--dry-run) DRY_RUN=true ;; | |
-q|--quiet) QUIET=true ;; | |
-k|--keep) KEEP="$2"; shift ;; | |
--retain-days) RETAIN_DAYS="$2"; shift ;; | |
-h|--help) show_help ;; | |
-*|--*) echo "Unrecognized option: $1"; show_help ;; | |
esac | |
shift | |
done | |
# Function to delete old LVM archive files | |
delete_old_lvm_archives() { | |
local archive_path="/etc/lvm/archive" | |
if [ -d "$archive_path" ]; then | |
$QUIET || echo "Cleaning LVM archive files older than $RETAIN_DAYS days..." | |
if [ "$DRY_RUN" = true ]; then | |
find "$archive_path" -type f -mtime +$RETAIN_DAYS -print | |
else | |
find "$archive_path" -type f -mtime +$RETAIN_DAYS -exec rm {} + | |
fi | |
fi | |
} | |
# Apply archive cleanup before snapshot management | |
delete_old_lvm_archives | |
# Main snapshot management logic | |
$QUIET || echo "Fetching VM list from pvesh..." | |
pvesh get /cluster/resources --type vm --output-format text --human-readable 0 --noborder --noheader | \ | |
awk '{split($1, a, "/"); TYPE=a[1]; VMID=a[2]; STATUS=$(NF-2); print TYPE, VMID, STATUS}' | \ | |
while read -r TYPE VMID STATUS; do | |
# Skip VMs that are not running | |
if [ "$STATUS" != "running" ]; then | |
$QUIET || echo "Skipping VM $VMID ($TYPE) - Status: $STATUS" | |
continue | |
fi | |
# Set the snapshot command based on VM type | |
if [ "$TYPE" == "lxc" ]; then | |
SNAP_CMD="pct" | |
elif [ "$TYPE" == "qemu" ]; then | |
SNAP_CMD="qm" | |
else | |
continue | |
fi | |
# Create snapshot in dry-run mode or execute normally | |
if [ "$DRY_RUN" = true ]; then | |
$QUIET || echo "[Dry-Run] Would create snapshot: $SNAP_CMD snapshot $VMID auto_$DATE" | |
else | |
$QUIET || echo "Creating snapshot: $SNAP_CMD snapshot $VMID auto_$DATE" | |
$SNAP_CMD snapshot $VMID auto_$DATE | |
fi | |
# Retrieve snapshots and delete oldest if exceeding the keep limit | |
SNAPSHOTS=($($SNAP_CMD listsnapshot $VMID | grep -oP 'auto_\d{10}' | sort -r)) # Sort newest first | |
SNAP_COUNT=${#SNAPSHOTS[@]} | |
if [ "$SNAP_COUNT" -gt "$KEEP" ]; then | |
for (( i=KEEP; i<SNAP_COUNT; i++ )); do | |
OLD_SNAP="${SNAPSHOTS[$i]}" | |
if [ "$DRY_RUN" = true ]; then | |
$QUIET || echo "[Dry-Run] Would delete snapshot: $SNAP_CMD delsnapshot $VMID $OLD_SNAP" | |
else | |
$QUIET || echo "Deleting snapshot: $SNAP_CMD delsnapshot $VMID $OLD_SNAP" | |
$SNAP_CMD delsnapshot $VMID $OLD_SNAP | |
fi | |
done | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment