Automated Proxmox Virtual Machine Management with Cron Jobs and Shell Scripts

Automating Virtual Machine Management with Cron Jobs & Shell Scripts on Proxmox

In this blog post, we will explore a clever solution for managing virtual machines (VMs) using cron jobs and shell scripts. The script we’ll discuss is designed to start or stop VMs based on specific schedules, ensuring seamless operation of the system without manual intervention.

The heart of our solution lies in two cron job entries:

Lets create a cronjob in crontab:

1
crontab -e

Then input this as contents at the end of the crontab:

1
2
01 08 * * * /root/scripts/start_stop_vm.sh >> /root/scripts/logfile.log 2>&1
01 00 * * * /root/scripts/start_stop_vm.sh >> /root/scripts/logfile.log 2>&1

These cron jobs execute the start_stop_vm.sh script daily at 8:01 AM and 12:01 AM respectively. The output of each execution is redirected to a log file for easy monitoring and troubleshooting.

The script itself (start_stop_vm.sh) is quite straightforward, as shown below:

Now we need to crate a file start_stop_vm.sh:

1
nano /root/scripts/start_stop_vm.sh

Then input this script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/sh

VMID=100
TIME_TO_START="08:00"
TIME_TO_STOP="00:00"
current=$(date +"%H:%M")

# Remove leading zeros from time values to avoid issues with arithmetic
TIME_TO_START=$(echo $TIME_TO_START | sed 's/^0//')
TIME_TO_STOP=$(echo $TIME_TO_STOP | sed 's/^0//')
current=$(echo $current | sed 's/^0//')

# Convert times to minutes since midnight for easier comparison
start_minutes=$(( ${TIME_TO_START%%:*} * 60 + ${TIME_TO_START##*:} ))
stop_minutes=$(( ${TIME_TO_STOP%%:*} * 60 + ${TIME_TO_STOP##*:} ))
current_minutes=$(( ${current%%:*} * 60 + ${current##*:} ))

# Adjust stop time to handle ranges that span past midnight
if [ "$TIME_TO_STOP" = "00:00" ]; then
    stop_minutes=$((24 * 60)) # Represent midnight as 24:00
fi

# Ensure variables have values before proceeding
if [ -z "$start_minutes" ] || [ -z "$stop_minutes" ] || [ -z "$current_minutes" ]; then
    echo "Error: One or more time variables are empty."
    exit 1
fi

# Determine if the current time is within the range
if [ $start_minutes -le $current_minutes ] && [ $current_minutes -lt $stop_minutes ] || \
   [ $start_minutes -gt $stop_minutes ] && { [ $current_minutes -ge $start_minutes ] || [ $current_minutes -lt $stop_minutes ]; }; then
    echo "Starting VM $VMID as it is within the scheduled time."
    /usr/sbin/qm start $VMID
else
    echo "Stopping VM $VMID as it is outside the scheduled time."
    /usr/sbin/qm stop $VMID
fi

The script first sets the VM ID, start time, and end time. Then, it calculates the current minute value using the date command, and removes any leading zeros from the times to facilitate arithmetic calculations. It then converts all times into minutes since midnight for easier comparison.

Using these variables, the script determines if the current time falls within the scheduled start and stop times, and accordingly starts or stops the specified VM using /usr/sbin/qm.

This example demonstrates how cron jobs and shell scripts can be used together to automate repetitive tasks in Linux environments. With a few lines of code, we’ve built a simple yet effective tool for managing our virtual machines. Of course, this is just one possible solution—feel free to adapt the script to suit your specific needs!

As always, when working with system tools, make sure to thoroughly test your scripts and monitor logs for any errors or issues that might arise. Happy automating!

Leave a Reply