I came up with a way to shut down my VMs with a script that does not rely on ssh to work on the vm. I plan to expand this to also warn / shutdown cliet computers of an impending server shutdown, so their files have a chance to be properly commited to the server before the shutdown. My scripts work fine if I run them from a puTTY terminal and everything happens as I expect it to, but I'm having a heck of a time getting them to run either under init/shutdown scripts or under UPS service. I'm not sure if I'm not getting the syntax correct to call the script, or if there is a permission issue... it's just not working. The one I need to work the most is from a UPS event triggered shutdown, because an admin can easily run the scipt manually before shutting down the server for scheduled reasons.
Below are my scripts - there are 3 of them, the first one is the one I call to initate the shutdown procedure. It checks to see if the client computer is actually running or not with a ping, if it's not running, it simply creates a specific file in a specific location... then it waits for the file to be deleted. Next I have a batch file running on the client computer that just sits around all day checking to see if the specific file exists, then a delay, I start of with testing for the file once a second. If the file exists, I start a 30 second countdown, then I force my monitor batch file to restore from minimize and give the user a chance to extend the countdown to 5 minutes. After the timeout, a shutdown is initiated (I could also launch other commands to shut down other specific processes beforehand) and then the specific file is deleted. So now I have a proper shutdown in progress, but just because I gave the shutdown command, doesn't mean it's all the way down, so the initial script upon detection that the specific file no longer exists, now starts checking the IP address of the client computer up to a maximum of 15 minutes, if it hasn't stopped responding by then, it's determined that something happened to the shutdown, but the server can't wait for a proper shutdown any longer as the clock is ticking on the battery life. Once the IP address is no longer present (or the timeout) there is an addional 30 second delay just to make sure it's down. After this, the script exits.
The third script just launches the first one, waits for it to complete, then issues the shutdown command to the server. I did it this way because I can use the third script to launch the first script on multiple machines, wait for them all to complete, then continue.
I have tried putting ShutDownAll.sh in UPS under shutdown command with full path like this:
/mnt/Kirkland_Audio_4TB/4TB/User Datasets/QB_Server/ShutDownAll.sh
I have tried putting bash in front like this:
bash /mnt/Kirkland_Audio_4TB/4TB/User Datasets/QB_Server/ShutDownAll.sh
I've tried various locations such as /root or /etc
I always get an error "unable to call shutdown command"
so I thought I would let the UPS service just do it's normal shutdown and put my script under init/shutdown tasks and again it just never seems to run my script. I even did a test where I just write a file first thing... with echo test > test but the file never gets created so I know my script is not running. I seem to be missing some important detail on how to launch my script from either of these locations.
Any Help getting this to run is greatly appreciated!
below is the first script that initiates the shutdown
SendShutDown.sh
Code:
#!/usr/local/bin/bash
cd /mnt/Kirkland_Audio_4TB/4TB/User Datasets/QB-Server
RemoteSystem="192.168.0.234"
WaitReceive="118"
WaitShutdown="900"
WaitExtra="30"
echo $Thing
ping -c 1 -o -q $RemoteSystem
if [ $? -eq 0 ]; then
echo Shutdown >> Shutdown
SECONDS=0
sleep 1
while [ -f Shutdown ] && [ "$SECONDS" -le "$WaitReceive" ]; do
clear
printf "$(hostname) "
date
printf "Waiting %01d:%02d for $RemoteSystem to be Receive Shutdown Request\n" "$(($WaitReceive / 60))" "$(($WaitReceive % 60))"
TimeWaiting=$SECONDS
printf "%01d:%02d Elapsed " "$(($TimeWaiting / 60))" "$(($TimeWaiting % 60))"
printf "%01d:%02d Remaining\n" "$((($WaitReceive-$TimeWaiting) / 60))" "$((($WaitReceive-$TimeWaiting) % 60))"
sleep 1
done
PreviousTime=$SECONDS
fi
SECONDS=0
ping -c 1 -o -q $RemoteSystem
while [ $? -eq 0 ] && [ "$SECONDS" -le "$WaitShutdown" ]; do
clear
printf "$(hostname) "
date
if [ "$PreviousTime" -le "$WaitReceive" ]; then
printf "Shutdown Request Received By $RemoteSystem\n"
else
printf "Time allowed of %01d:%02d has been exceeded - No response from $RemoteSystem\n" "$(($WaitReceive / 60))" "$(($WaitReceive % 60))"
fi
printf "Waiting %01d:%02d for $RemoteSystem to be Receive Shutdown Request\n" "$(($WaitShutdown / 60))" "$(($WaitShutdown % 60))"
TimeWaiting=$SECONDS
printf "%01d:%02d Elapsed " "$(($TimeWaiting / 60))" "$(($TimeWaiting % 60))"
printf "%01d:%02d Remaining\n" "$((($WaitShutdown-$TimeWaiting) / 60))" "$((($WaitShutdown-$TimeWaiting) % 60))"
sleep 1
ping -c 1 -o -q $RemoteSystem
done
PreviousTime=$SECONDS
SECONDS=0
while [ "$SECONDS" -le "$WaitExtra" ]; do
clear
printf "$(hostname) "
date
if [ "$PreviousTime" -le "$WaitShutdown" ]; then
printf "$RemoteSystem Is OffLine\n"
printf "Delay %01d:%02d to make sure $RemoteSystem is completly Shutdown\n" "$(($WaitExtra / 60))" "$(($WaitExtra % 60))"
else
printf "$RemoteSystem Is Still Online but MUST Shutdown in %01d:%02d\n$" "$(($WaitExtra / 60))" "$(($WaitExtra % 60))"
fi
TimeWaiting=$SECONDS
printf "%01d:%02d Elapsed " "$(($TimeWaiting / 60))" "$(($TimeWaiting % 60))"
printf "%01d:%02d Remaining\n" "$((($WaitExtra-$TimeWaiting) / 60))" "$((($WaitExtra-$TimeWaiting) % 60))"
sleep 1
done
Here is my batch file that I run on startup on my Windows 10 vm
Wait4Shutdown.cmd
Code:
@Echo off
echo %Date% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2% System started >> Wait4Shutdown.log
if DEFINED IS_MINIMIZED Goto CheckforShutdown
timeout /t 10 /nobreak >Nul
If exist "\\192.168.0.252\QB_Server\SendShutdown.sh" Goto CheckforShutdown
echo [91mUnable to find network share! Will not be able to detect Server Shutdown[0m
echo %Date% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2% Unable to find network share! Will not be able to detect Server Shutdown >> Wait4Shutdown.log
Pause
Exit
:CheckforShutdown
if not DEFINED IS_MINIMIZED set IS_MINIMIZED=1 && start /min %~dpnx0 && exit
echo %Date% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2% Waiting for Shutdown >> Wait4Shutdown.log
:WaitforShutdown
Cls
Echo [92mWaiting for Shutdown[0m
echo [93m%date% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%[0m
If exist "\\192.168.0.252\QB_Server\Shutdown" Goto ShutitDown
timeout /t 1 /nobreak >Nul
Goto WaitforShutdown
:ShutitDown
if %IS_MINIMIZED% == 1 set IS_MINIMIZED=0 && start %~dpnx0 && exit
echo %Date% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2% Shut Down Request Received from Server>> Wait4Shutdown.log
CLS
echo [91mShut Down Request Received from Server at: %Date% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2% [0m
Echo [35m
choice /c ê1234567890qwertyuiopasdfghjklzxcvbnm /T 5 /D ê /n /M "Initiating Shutdown in 30 Seconds. Press a Character for Extended Time"
If Errorlevel=2 goto DelayShutDown
Echo [36m
choice /c ê1234567890qwertyuiopasdfghjklzxcvbnm /T 5 /D ê /n /M "Initiating Shutdown in 25 Seconds. Press a Character for Extended Time"
If Errorlevel=2 goto DelayShutDown
Echo [32m
choice /c ê1234567890qwertyuiopasdfghjklzxcvbnm /T 5 /D ê /n /M "Initiating Shutdown in 20 Seconds. Press a Character for Extended Time"
If Errorlevel=2 goto DelayShutDown
Echo [33m
choice /c ê1234567890qwertyuiopasdfghjklzxcvbnm /T 5 /D ê /n /M "Initiating Shutdown in 15 Seconds. Press a Character for Extended Time"
If Errorlevel=2 goto DelayShutDown
Echo [31m
choice /c ê1234567890qwertyuiopasdfghjklzxcvbnm /T 5 /D ê /n /M "Initiating Shutdown in 10 Seconds. Press a Character for Extended Time"
If Errorlevel=2 goto DelayShutDown
Echo [95m
choice /c ê1234567890qwertyuiopasdfghjklzxcvbnm /T 5 /D ê /n /M "Initiating Shutdown in 5 Seconds. Press a Character for Extended Time"
If Errorlevel=2 goto DelayShutDown
Echo [94m
choice /c ê1234567890qwertyuiopasdfghjklzxcvbnm /T 1 /D ê /n /M "Initiating Shutdown in 4 Seconds. Press a Character for Extended Time"
If Errorlevel=2 goto DelayShutDown
Echo [96m
choice /c ê1234567890qwertyuiopasdfghjklzxcvbnm /T 1 /D ê /n /M "Initiating Shutdown in 3 Seconds. Press a Character for Extended Time"
If Errorlevel=2 goto DelayShutDown
Echo [92m
choice /c ê1234567890qwertyuiopasdfghjklzxcvbnm /T 1 /D ê /n /M "Initiating Shutdown in 2 Seconds. Press a Character for Extended Time"
If Errorlevel=2 goto DelayShutDown
Echo [93m
choice /c ê1234567890qwertyuiopasdfghjklzxcvbnm /T 1 /D ê /n /M "Initiating Shutdown in 1 Seconds. Press a Character for Extended Time"
If Errorlevel=2 goto DelayShutDown
Goto GoShutDown
:DelayShutDown
Echo [92m
Echo Automatic Shutdown Aborted....
Echo [93mServer is will force Shutdown of this VM in [96m5 Minutes[95m
Timeout /t 600
:GoShutDown
Echo [91m
Echo Initiating Shutdown at: %date% %time%[0m
echo %Date% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2% Initiating Shutdown >> Wait4Shutdown.log
Del \\192.168.0.252\QB_Server\Shutdown
Shutdown /s
:Finish
Exit
This is the third script which changes directories to where the first script is and calls it, that way I can call multiple versions of the first script, wait for them all to finish, then issue the shutdown to the server.
ShutDownAll.sh
Code:
#!/bin/bash
cd "/mnt/Kirkland_Audio_4TB/4TB/User Datasets/QB_Server" > /dev/null
/bin/bash SendShutDown.sh
wait
Echo Finished the Script
sleep 10
poweroff