Updated and improved, now autosnapshots according to policy via cron.
This commit is contained in:
parent
04d2d424af
commit
60e606d4b5
132
020_sanoid.sh
132
020_sanoid.sh
|
|
@ -41,7 +41,7 @@ conf_print_syncoid_cron() {
|
||||||
*/15 * * * * root [ -f /etc/sanoid/syncoid.conf ] && if [ ! -d /run/systemd/system ]; then TZ=UTC /usr/sbin/syncoid --cron --quiet; fi
|
*/15 * * * * root [ -f /etc/sanoid/syncoid.conf ] && if [ ! -d /run/systemd/system ]; then TZ=UTC /usr/sbin/syncoid --cron --quiet; fi
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
conf_print_syncoid_cron | sudo tee /etc/cron.d/syncoid
|
# conf_print_syncoid_cron | sudo tee /etc/cron.d/syncoid
|
||||||
|
|
||||||
# Copied from /usr/share/doc/sanoid/example.conf
|
# Copied from /usr/share/doc/sanoid/example.conf
|
||||||
sudo mkdir -p /etc/sanoid/
|
sudo mkdir -p /etc/sanoid/
|
||||||
|
|
@ -50,16 +50,15 @@ conf_print_sanoid() {
|
||||||
cat <<-EOF
|
cat <<-EOF
|
||||||
[rpool/docker]
|
[rpool/docker]
|
||||||
use_template = ignore
|
use_template = ignore
|
||||||
recursive = yes
|
|
||||||
|
|
||||||
[rpool/archive]
|
[rpool/archive]
|
||||||
use_template = ignore
|
use_template = ignore
|
||||||
recursive = yes
|
|
||||||
|
[rpool/swap]
|
||||||
|
use_template = ignore
|
||||||
|
|
||||||
[rpool/tmp]
|
[rpool/tmp]
|
||||||
use_template = ignore
|
use_template = ignore
|
||||||
recursive = yes
|
|
||||||
|
|
||||||
|
|
||||||
[rpool/ROOT/devuan-1]
|
[rpool/ROOT/devuan-1]
|
||||||
use_template = root
|
use_template = root
|
||||||
|
|
@ -72,12 +71,14 @@ conf_print_sanoid() {
|
||||||
# rpool/ROOT/devuan-1/var
|
# rpool/ROOT/devuan-1/var
|
||||||
# rpool/ROOT/devuan-1/var_lib
|
# rpool/ROOT/devuan-1/var_lib
|
||||||
|
|
||||||
|
# Specific override for Virtual Machines to use scripts
|
||||||
[rpool/ROOT/devuan-1/var_lib_virt]
|
[rpool/ROOT/devuan-1/var_lib_virt]
|
||||||
use_template = root
|
use_template = root
|
||||||
# Custom script to freeze VMs before snapshotting
|
recursive = no
|
||||||
pre_snapshot_script = /usr/local/bin/virt-freeze-all.sh
|
pre_snapshot_script = /usr/local/bin/virt-freeze-all.sh
|
||||||
post_snapshot_script = /usr/local/bin/virt-thaw-all.sh
|
post_snapshot_script = /usr/local/bin/virt-thaw-all.sh
|
||||||
|
|
||||||
|
# -- User Data --
|
||||||
[rpool/home]
|
[rpool/home]
|
||||||
use_template = production
|
use_template = production
|
||||||
recursive = yes
|
recursive = yes
|
||||||
|
|
@ -89,11 +90,6 @@ conf_print_sanoid() {
|
||||||
# templates below this line #
|
# templates below this line #
|
||||||
#############################
|
#############################
|
||||||
|
|
||||||
# name your templates template_templatename. you can create your own, and
|
|
||||||
# use them in your module definitions above.
|
|
||||||
[template_demo]
|
|
||||||
daily = 60
|
|
||||||
|
|
||||||
[template_production]
|
[template_production]
|
||||||
frequently = 0
|
frequently = 0
|
||||||
hourly = 36
|
hourly = 36
|
||||||
|
|
@ -103,6 +99,20 @@ conf_print_sanoid() {
|
||||||
autosnap = yes
|
autosnap = yes
|
||||||
autoprune = yes
|
autoprune = yes
|
||||||
|
|
||||||
|
[template_root]
|
||||||
|
# Root changes fast; shorter history often suffices
|
||||||
|
hourly = 24
|
||||||
|
daily = 7
|
||||||
|
monthly = 1
|
||||||
|
yearly = 0
|
||||||
|
autosnap = yes
|
||||||
|
autoprune = yes
|
||||||
|
|
||||||
|
[template_ignore]
|
||||||
|
autoprune = no
|
||||||
|
autosnap = no
|
||||||
|
monitor = no
|
||||||
|
|
||||||
[template_backup]
|
[template_backup]
|
||||||
autoprune = yes
|
autoprune = yes
|
||||||
frequently = 0
|
frequently = 0
|
||||||
|
|
@ -162,20 +172,6 @@ conf_print_sanoid() {
|
||||||
#force_post_snapshot_script = yes
|
#force_post_snapshot_script = yes
|
||||||
### limit allowed execution time of scripts before continuing (<= 0: infinite)
|
### limit allowed execution time of scripts before continuing (<= 0: infinite)
|
||||||
script_timeout = 5
|
script_timeout = 5
|
||||||
|
|
||||||
[template_root]
|
|
||||||
# Root changes fast; shorter history often suffices
|
|
||||||
hourly = 24
|
|
||||||
daily = 7
|
|
||||||
monthly = 1
|
|
||||||
yearly = 0
|
|
||||||
autosnap = yes
|
|
||||||
autoprune = yes
|
|
||||||
|
|
||||||
[template_ignore]
|
|
||||||
autoprune = no
|
|
||||||
autosnap = no
|
|
||||||
monitor = no
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
conf_print_sanoid | sudo tee /etc/sanoid/sanoid.conf
|
conf_print_sanoid | sudo tee /etc/sanoid/sanoid.conf
|
||||||
|
|
@ -193,6 +189,8 @@ conf_print_sanoid_init() {
|
||||||
# Provides: sanoid
|
# Provides: sanoid
|
||||||
# Required-Start: $syslog $local_fs $remote_fs
|
# Required-Start: $syslog $local_fs $remote_fs
|
||||||
# Required-Stop: $syslog $local_fs $remote_fs
|
# Required-Stop: $syslog $local_fs $remote_fs
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
# Short-Description: Snapshot ZFS filesystems
|
# Short-Description: Snapshot ZFS filesystems
|
||||||
### END INIT INFO
|
### END INIT INFO
|
||||||
|
|
||||||
|
|
@ -251,8 +249,9 @@ conf_print_sanoid_init() {
|
||||||
esac
|
esac
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
conf_print_sanoid_init | sudo tee /etc/init.d/sanoid
|
# Sandoid doesn't ran as a daemon it runs vi cron
|
||||||
sudo chmod +x /etc/init.d/sanoid
|
# conf_print_sanoid_init | sudo tee /etc/init.d/sanoid
|
||||||
|
# sudo chmod +x /etc/init.d/sanoid
|
||||||
|
|
||||||
# Generated using:
|
# Generated using:
|
||||||
# https://raw.githubusercontent.com/akhilvij/systemd-to-sysvinit-converter/master/converter.py
|
# https://raw.githubusercontent.com/akhilvij/systemd-to-sysvinit-converter/master/converter.py
|
||||||
|
|
@ -323,8 +322,9 @@ conf_print_sanoid-prune_init() {
|
||||||
esac
|
esac
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
conf_print_sanoid-prune_init | sudo tee /etc/init.d/sanoid-prune
|
# Sandoid doesn't ran as a daemon it runs vi cron
|
||||||
sudo chmod +x /etc/init.d/sanoid-prune
|
# conf_print_sanoid-prune_init | sudo tee /etc/init.d/sanoid-prune
|
||||||
|
# sudo chmod +x /etc/init.d/sanoid-prune
|
||||||
|
|
||||||
# Give sudo access to virsh or is part of the libvirt group.
|
# Give sudo access to virsh or is part of the libvirt group.
|
||||||
# qemu-guest-agent must be running in the vm
|
# qemu-guest-agent must be running in the vm
|
||||||
|
|
@ -341,19 +341,27 @@ if [ -z "$VM_NAME" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if the VM is running
|
# Check if the VM is running
|
||||||
STATE=$(virsh domstate "$VM_NAME")
|
STATE=$(virsh domstate "$VM_NAME" 2>/dev/null)
|
||||||
if [ "$STATE" != "running" ]; then
|
if [ "$STATE" != "running" ]; then
|
||||||
echo "VM $VM_NAME is not running. Skipping freeze."
|
echo "VM $VM_NAME is not running or does not exist. Skipping freeze."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Freezing filesystems for $VM_NAME..."
|
echo "Freezing filesystems for $VM_NAME..."
|
||||||
virsh qemu-agent-command "$VM_NAME" '{"execute":"guest-fsfreeze-freeze"}'
|
# domfsfreeze returns the number of frozen filesystems on success
|
||||||
|
if virsh domfsfreeze "$VM_NAME" > /dev/null; then
|
||||||
|
echo "Successfully frozen $VM_NAME."
|
||||||
|
else
|
||||||
|
echo "Error: Failed to freeze $VM_NAME. Ensure qemu-guest-agent is active."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
conf_print_virt_freeze | sudo tee /usr/local/bin/virt-freeze.sh
|
conf_print_virt_freeze | sudo tee /usr/local/bin/virt-freeze.sh
|
||||||
sudo chmod +x /usr/local/bin/virt-freeze.sh
|
sudo chmod +x /usr/local/bin/virt-freeze.sh
|
||||||
|
|
||||||
|
#---
|
||||||
|
|
||||||
conf_print_virt_unfreeze() {
|
conf_print_virt_unfreeze() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
@ -367,26 +375,34 @@ if [ -z "$VM_NAME" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if the VM is running
|
# Check if the VM is running
|
||||||
STATE=$(virsh domstate "$VM_NAME")
|
STATE=$(virsh domstate "$VM_NAME" 2>/dev/null)
|
||||||
if [ "$STATE" != "running" ]; then
|
if [ "$STATE" != "running" ]; then
|
||||||
echo "VM $VM_NAME is not running. Skipping unfreeze."
|
echo "VM $VM_NAME is not running. Skipping unfreeze."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Thawing filesystems for $VM_NAME..."
|
echo "Thawing filesystems for $VM_NAME..."
|
||||||
virsh qemu-agent-command "$VM_NAME" '{"execute":"guest-fsfreeze-thaw"}'
|
# domfsthaw returns the number of thawed filesystems on success
|
||||||
|
if virsh domfsthaw "$VM_NAME" > /dev/null; then
|
||||||
|
echo "Successfully thawed $VM_NAME."
|
||||||
|
else
|
||||||
|
echo "Error: Failed to thaw $VM_NAME."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
conf_print_virt_unfreeze | sudo tee /usr/local/bin/virt-unfreeze.sh
|
conf_print_virt_unfreeze | sudo tee /usr/local/bin/virt-unfreeze.sh
|
||||||
sudo chmod +x /usr/local/bin/virt-unfreeze.sh
|
sudo chmod +x /usr/local/bin/virt-unfreeze.sh
|
||||||
|
|
||||||
conf_print_virt_thaw-all() {
|
#---
|
||||||
|
|
||||||
|
conf_print_virt_thaw_all() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
# /usr/local/bin/virt-thaw-all.sh
|
# /usr/local/bin/virt-thaw-all.sh
|
||||||
|
|
||||||
# 1. Get a list of all running VM names
|
# 1. Get running VM names, filtering out empty lines with awk
|
||||||
RUNNING_VMS=$(virsh list --state-running --name)
|
RUNNING_VMS=$(virsh list --state-running --name | awk 'NF')
|
||||||
|
|
||||||
if [ -z "$RUNNING_VMS" ]; then
|
if [ -z "$RUNNING_VMS" ]; then
|
||||||
echo "No running VMs found."
|
echo "No running VMs found."
|
||||||
|
|
@ -397,30 +413,31 @@ fi
|
||||||
for VM_NAME in $RUNNING_VMS; do
|
for VM_NAME in $RUNNING_VMS; do
|
||||||
echo "Processing $VM_NAME..."
|
echo "Processing $VM_NAME..."
|
||||||
|
|
||||||
# Execute the thaw command via QEMU guest agent
|
# Use the native thaw command.
|
||||||
# Note: This requires the guest-agent to be installed/running inside the VM
|
# It handles the guest agent communication for you.
|
||||||
RESPONSE=$(virsh qemu-agent-command "$VM_NAME" '{"execute":"guest-fsfreeze-thaw"}' 2>&1)
|
if virsh domfsthaw "$VM_NAME" > /dev/null 2>&1; then
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "Successfully thawed $VM_NAME."
|
echo "Successfully thawed $VM_NAME."
|
||||||
else
|
else
|
||||||
echo "Error thawing $VM_NAME: $RESPONSE"
|
# If native fails, we capture the error for the user
|
||||||
|
ERROR=$(virsh domfsthaw "$VM_NAME" 2>&1)
|
||||||
|
echo "Error thawing $VM_NAME: $ERROR"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "Finished processing all VMs."
|
echo "Finished processing all VMs."
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
conf_print_virt_thaw-all | sudo tee /usr/local/bin/virt-thaw-all.sh
|
conf_print_virt_thaw_all | sudo tee /usr/local/bin/virt-thaw-all.sh
|
||||||
sudo chmod +x /usr/local/bin/virt-thaw-all.sh
|
sudo chmod +x /usr/local/bin/virt-thaw-all.sh
|
||||||
|
|
||||||
|
#---
|
||||||
|
|
||||||
conf_print_virt_freeze-all() {
|
conf_print_virt_freeze-all() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
# /usr/local/bin/virt-freeze-all.sh
|
|
||||||
|
|
||||||
# 1. Get a list of all running VM names
|
# 1. Get running VM names, filtering out empty lines
|
||||||
RUNNING_VMS=$(virsh list --state-running --name)
|
RUNNING_VMS=$(virsh list --state-running --name | awk 'NF')
|
||||||
|
|
||||||
if [ -z "$RUNNING_VMS" ]; then
|
if [ -z "$RUNNING_VMS" ]; then
|
||||||
echo "No running VMs found."
|
echo "No running VMs found."
|
||||||
|
|
@ -429,17 +446,14 @@ fi
|
||||||
|
|
||||||
# 2. Loop through each running VM
|
# 2. Loop through each running VM
|
||||||
for VM_NAME in $RUNNING_VMS; do
|
for VM_NAME in $RUNNING_VMS; do
|
||||||
echo "Processing $VM_NAME..."
|
echo "Attempting to freeze $VM_NAME..."
|
||||||
|
|
||||||
# Execute the freeze command via QEMU guest agent
|
# Using the native virsh command is generally cleaner
|
||||||
# This flushes disk buffers and halts I/O
|
# It returns the number of frozen filesystems on success
|
||||||
RESPONSE=$(virsh qemu-agent-command "$VM_NAME" '{"execute":"guest-fsfreeze-freeze"}' 2>&1)
|
if virsh domfsfreeze "$VM_NAME" > /dev/null 2>&1; then
|
||||||
|
echo "Successfully frozen $VM_NAME."
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
# The response usually contains the number of filesystems frozen
|
|
||||||
echo "Successfully frozen $VM_NAME. Details: $RESPONSE"
|
|
||||||
else
|
else
|
||||||
echo "Error freezing $VM_NAME: $RESPONSE"
|
echo "Error: Could not freeze $VM_NAME. Check if QEMU Guest Agent is running."
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
@ -449,6 +463,8 @@ EOF
|
||||||
conf_print_virt_freeze-all | sudo tee /usr/local/bin/virt-freeze-all.sh
|
conf_print_virt_freeze-all | sudo tee /usr/local/bin/virt-freeze-all.sh
|
||||||
sudo chmod +x /usr/local/bin/virt-freeze-all.sh
|
sudo chmod +x /usr/local/bin/virt-freeze-all.sh
|
||||||
|
|
||||||
|
#---
|
||||||
|
|
||||||
# exit 0
|
# exit 0
|
||||||
#
|
#
|
||||||
# # build a debian package from the git repo
|
# # build a debian package from the git repo
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue