Created
December 4, 2023 18:47
-
-
Save EduardoSantanaSeverino/c5b8bf380f23a2e442d1dcf3b6db37a2 to your computer and use it in GitHub Desktop.
Proxmox Turn On Remote Server
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 | |
# This script will be run by crontab every one mint | |
# */1 * * * * /root/scripts/turn-on-pve1-cron/turn-on-pve1-cron.sh 2>&1 | |
# This script will power on a remote server via Wake On Lan, but only 5 mints before the backup job is about to be executed. | |
# This will be reading the job file /etc/pve/jobs.cfg every time: | |
# On a CRON JOB every 1 mint | |
# check if the server is not Power On by checking the file, then | |
# SSH into the pve_node | |
# cat file: /etc/pve/jobs.cfg | |
# iterate loop thorough the vzdump items and for each one: | |
# check if enable, if NOP continue. | |
# check if storage pbs-blaze3-pve1, if NOP continue. | |
# parse schedule property, example: mon..fri 00:00. | |
# from date object calculate how much time is left for that to happen. | |
# if 5 mints or less, turn on server. | |
# wait for the server to be on and able to ssh. | |
# after waiting, create a file indicating server is up. | |
execution_time_print () { | |
local EXECUTION_TIME=$(TZ=America/Toronto date +'%Y-%m-%d %H:%M') | |
echo "$EXECUTION_TIME - [$1] -" | |
} | |
get_date_of_the_week () { | |
local lower=$(echo "$1" | tr '[:upper:]' '[:lower:]') | |
local day_num=0 | |
case $lower in | |
mon) day_num=1;; | |
tue) day_num=2;; | |
wed) day_num=3;; | |
thu) day_num=4;; | |
fri) day_num=5;; | |
sat) day_num=6;; | |
sun) day_num=7;; | |
*) echo "Invalid day"; exit 1;; | |
esac | |
echo $day_num; | |
} | |
get_minutes_from_schedule () { | |
# TODO: | |
# Update function 'get_minutes_from_schedule' with schedule-analyze to get the next date instead of calculating. | |
# https://www.reddit.com/r/Proxmox/comments/189bde8/parse_backup_configuration_file_proxmox/ | |
# https://pve.proxmox.com/pve-docs/api-viewer/index.html#/cluster/jobs/schedule-analyze | |
TZ=America/Toronto | |
day=$(TZ=$TZ date +"%a") | |
# Get the current day of the week | |
current_day=$(TZ=$TZ date +"%a") | |
# Map day names to their numerical equivalents (1=Mon, 2=Tue, ..., 7=Sun) | |
current_day_num=$(get_date_of_the_week $current_day) | |
# Map user input day names to their numerical equivalents | |
target_day_num=$(get_date_of_the_week $day) | |
# Calculate the difference in days | |
days_until_target=$(( (target_day_num - current_day_num + 7) % 7 )) | |
# Combine the date components and calculate the minutes until that time | |
target_date=$(TZ=$TZ date -d "$days_until_target days $1" +"%Y-%m-%d %H:%M:%S") | |
current_time=$(TZ=$TZ date +"%s") | |
target_time=$(TZ=$TZ date -d "$target_date" +"%s") | |
minutes_until_target=$(( (target_time - current_time) / 60 )) | |
# echo "Target Date and Time: $target_date" | |
# echo "Minutes until Target Time: $minutes_until_target" | |
echo $minutes_until_target | |
} | |
HOST_IP_ADDRESS_PVE1="10.10.10.10" | |
HOST_IP_ADDRESS_PVE2="10.10.10.11" | |
HOST_IP_ADDRESS_PBS="10.10.10.12" | |
SCRIPT_DIR='/root/scripts/turn-on-pve1-cron' | |
mkdir -p $SCRIPT_DIR | |
SCRIPT_LOG_FILE="$SCRIPT_DIR/logs.log" | |
SCRIPT_KEY="$SCRIPT_DIR/key.key" | |
SCRIPT_SERVER_EXIST="$SCRIPT_DIR/is.server.on.$HOST_IP_ADDRESS_PBS" | |
PID_FILE="$SCRIPT_DIR/pid.pid" | |
# if file exists exit... because the server is on. | |
if test -f "$SCRIPT_SERVER_EXIST"; then | |
exit 0 | |
fi | |
# check the pid | |
if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then | |
exit 0 | |
fi | |
echo $$ > $PID_FILE | |
JOBS_CFG_FILE_CONTENT=$(ssh -i $SCRIPT_KEY root@$HOST_IP_ADDRESS_PVE2 'cat /etc/pve/jobs.cfg') | |
# Use grep to filter lines containing "enable" and store them in an array | |
mapfile -t JOBS_CFG_ENABLE_ITEMS < <(echo "$JOBS_CFG_FILE_CONTENT" | grep enable) | |
mapfile -t JOBS_CFG_SCHEDULE_ITEMS < <(echo "$JOBS_CFG_FILE_CONTENT" | grep schedule) | |
mapfile -t JOBS_CFG_STORAGE_ITEMS < <(echo "$JOBS_CFG_FILE_CONTENT" | grep storage) | |
TURN_ON_SERVER=false | |
# Iterate through the array using index | |
for ((i = 0; i < ${#JOBS_CFG_ENABLE_ITEMS[@]}; i++)); do | |
# For debbuging purposes to display the current job in the loop. | |
# echo "Element $i: ${JOBS_CFG_ENABLE_ITEMS[i]} and ${JOBS_CFG_SCHEDULE_ITEMS[i]} and ${JOBS_CFG_STORAGE_ITEMS[i]}" | |
# If the Job is NOT enabled | |
if [[ ${JOBS_CFG_ENABLE_ITEMS[i]} == *enabled* && ${JOBS_CFG_ENABLE_ITEMS[i]} == *0* ]]; then | |
continue; # continue Job is NOT enabled | |
fi | |
# If the storage is NOT pbs-blaze3-pve1 | |
if [[ ${JOBS_CFG_STORAGE_ITEMS[i]} != *pbs-blaze3-pve1* ]]; then | |
continue; # continue the storage is NOT pbs-blaze3-pve1 | |
fi | |
schedule_item=${JOBS_CFG_SCHEDULE_ITEMS[i]#* } | |
minutes_to_execute_job=$(get_minutes_from_schedule $schedule_item) | |
# Check if more than 5 minutes for the next job to be executed. | |
if [[ "$minutes_to_execute_job" -gt 5 || "$minutes_to_execute_job" -lt 0 ]]; then | |
continue; # continue becuase it is more than 5 minutes for the next job to be executed. | |
fi | |
TURN_ON_SERVER=true | |
echo "$(execution_time_print INFO) Starting Server -> NO: $i: ${JOBS_CFG_ENABLE_ITEMS[i]} and ${JOBS_CFG_SCHEDULE_ITEMS[i]} and ${JOBS_CFG_STORAGE_ITEMS[i]}." >> $SCRIPT_LOG_FILE | |
break; | |
done | |
if [[ $TURN_ON_SERVER != true ]]; then | |
rm $PID_FILE | |
exit 0 | |
fi | |
echo "$(execution_time_print INFO) Senging: wakeonlan bb:bb:bb:bb:bb:bb && wakeonlan bb:bb:bb:bb:bb:bb." >> $SCRIPT_LOG_FILE | |
echo -n "$(execution_time_print INFO) " >> $SCRIPT_LOG_FILE | |
wakeonlan bb:bb:bb:bb:bb:bb >> $SCRIPT_LOG_FILE | |
echo -n "$(execution_time_print INFO) " >> $SCRIPT_LOG_FILE | |
wakeonlan bb:bb:bb:bb:bb:bb >> $SCRIPT_LOG_FILE | |
SUB='1 received,' | |
COUNTER=1 | |
IS_UP_AND_RUNNING='false' | |
while [ $COUNTER -lt 60 ]; | |
do | |
PING_RESULTS=$(ping $HOST_IP_ADDRESS_PBS -c 1) | |
if [[ "$PING_RESULTS" == *"$SUB"* ]]; then | |
echo "$(execution_time_print INFO) Server $HOST_IP_ADDRESS_PBS is up and running. $SUB WAS FOUND." >> $SCRIPT_LOG_FILE | |
IS_UP_AND_RUNNING='true' | |
COUNTER=60 | |
else | |
echo "$(execution_time_print ERROR) Still Waiting for $HOST_IP_ADDRESS_PBS. $SUB WAS NOT FOUND." >> $SCRIPT_LOG_FILE | |
COUNTER=`expr $COUNTER + 1` | |
sleep 60 | |
fi | |
done | |
if [[ "$IS_UP_AND_RUNNING" != 'true' ]]; then | |
echo "$(execution_time_print ERROR) ENDED. NOT FOUND SERVER. IS_UP_AND_RUNNING: $IS_UP_AND_RUNNING. " | |
rm $PID_FILE | |
exit 2 | |
fi | |
echo "$(execution_time_print INFO) THE SERVER $HOST_IP_ADDRESS_PBS WAS POWERED ON." >> $SCRIPT_LOG_FILE | |
COUNTER=1 | |
IS_UP_AND_RUNNING='false' | |
while [ $COUNTER -lt 60 ]; | |
do | |
status=$(ssh -i $SCRIPT_KEY -o BatchMode=yes -o ConnectTimeout=5 root@$HOST_IP_ADDRESS_PBS echo ok 2>&1) | |
if [[ "$status" == "ok" ]]; then | |
echo "$(execution_time_print INFO) Server $HOST_IP_ADDRESS_PBS , YES, it is able to SSH." >> $SCRIPT_LOG_FILE | |
IS_UP_AND_RUNNING='true' | |
COUNTER=60 | |
else | |
echo "$(execution_time_print ERROR) Still Waiting for $HOST_IP_ADDRESS_PBS , NO, it is NOT able to SSH" >> $SCRIPT_LOG_FILE | |
COUNTER=`expr $COUNTER + 1` | |
sleep 60 | |
fi | |
done | |
if [[ "$IS_UP_AND_RUNNING" != 'true' ]]; then | |
echo "$(execution_time_print ERROR) ENDED. NOT ABLE TO SSH into SERVER $HOST_IP_ADDRESS_PBS . IS_UP_AND_RUNNING: $IS_UP_AND_RUNNING. " | |
rm $PID_FILE | |
exit 2 | |
fi | |
echo "$(execution_time_print INFO) THE SERVER $HOST_IP_ADDRESS_PBS WAS POWERED ON." > $SCRIPT_SERVER_EXIST | |
echo "$(execution_time_print INFO) Finished Exec of Turning On Server." >> $SCRIPT_LOG_FILE | |
rm $PID_FILE | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment