Introduction
I have quite some services running on Ymir, and I want to back them up automatically to my backup VM that's running in RAID5, so I can be sure my data is secure and I'll be protected against data loss (except when my apartment burns down, but we will hope that won't happen (ㆆ _ ㆆ)). Sending the actual data is a perfect job for rsync, and automating it is what cron is best for.
The only kind-of challenge with this is: my backups VM is always off. I only turn it on when I want to write a backup to it. So I needed a way to programatically turn it on and off before and after performing a backup. Luckily, you can turn VMs on and off with the qm start
and qm shutdown
commands proxmox offers.
However, I didn't really know about a good way to send commands from one node to the other. After some searching, I came across qvalet. It's a pretty small program that runs on a node and can receive HTTP commands from which it can execute other commands. This is perfect for my use case.
Setting up qvalet
I set up qvalet to run on my proxmox host, and it listens on two endpoints: startbackup
and stopbackup
. each endpoint just calls a script to perform the necessary action: start_backup.sh
to start and stop_backup.sh
to stop the VM. The whole config.yaml
looks like this:
debug: false
port: <your port>
listeners:
/startbackup:
command: bash
args:
- -c
- "cd /root/qvalet; ./start_backup.sh"
return: output
/stopbackup:
command: bash
args:
- -c
- "cd /root/qvalet; ./stop_backup.sh"
return: output
The endpoints can then be called by curl
ing the host, port and endpoint: curl http://localhost:port/startbackup
.
To make sure the VM is not shut off by one process while still receiving a backup from the other, I added a little counter that gets updated every time the start and stop endpoints get called, and this counter is written to the backups_amount
file. The start_backup.sh
file looks like this:
#!/bin/bash
value=$(<backups_amount)
newvalue=$((value+1))
if [[ $newvalue -lt 1 ]]
then
newvalue=1
fi
echo "Amount of running backups: $newvalue"
echo $newvalue > backups_amount
qm start vm-id
qm list | grep vm-id | awk '{print $3}'
the stop_backup.sh
file looks like this:
#!/bin/bash
value=$(<backups_amount)
newvalue=$((value-1))
if [[ $newvalue -lt 0 ]]
then
newvalue=0
fi
echo $newvalue > backups_amount
if [[ $newvalue -gt 0 ]]
then
echo "A backup is still running"
else
echo "Stopping VM"
qm shutdown vm-id
qm list | grep vm-id | awk '{print $3}'
fi
You can replace the vm-id
with the ID of the VM you want to start/stop.