AppleScript C Perl Shell Xcode Other

Shutting-down all your Macs on power outage

Post Reply
coding / shell     Views: 3584Prev .. Next
Shutting-down all your Macs on power outagePosted: Thursday, June 17, 2010 [16:34:36] - 1
rootPosted by:rootMember Since:
June 16 2010
Posts: 356
If you have more than one Mac at home or in your office and you need to shutdown all of them it could be a time consuming task especially if some of them "headless".
In case of a power failure if more than one Mac hooked-up to one Power Backup unit - setting all of them to shutdown could be tricky.
There are many options to set your macs to power-down in case power goes out but you have to run a separate software to shut down computers by the end of the day and if your Macs all have different OS versions it goes a bit deeper.

In any case, I am not saying I wrote something that has not been done before or not available elsewhere (it's just takes more time to find and then adopt the software that write your own).
And I am sure it has room for improvement.
I run a number of Tiger workstations in the office with central UPS grid. All workstations have custom daemons running at all times.
Only one TIger workstation hooked-up to UPS monitoring. Why Tiger? - If it works - why change it?

First we modify stock /usr/libexec/upsshutdown script in pico editor:
View Code#!/bin/sh

#
# Pick up the email recipient from /etc/hostconfig, if defined.
#
. /etc/hostconfig

#
# Initialize...
#
PATH=/bin:/usr/bin:/sbin:/usr/sbin
SI_PATH=/System/Library/StartupItems
MAIL=mail
MSG="Shutting down due to power loss!"

logger -i -p daemon.emerg -t UPS "${MSG}"

#
# Send notification to the same address used for IP Failover.
#
if ! [ "${FAILOVER_EMAIL_RECIPIENT:=-AUTOMATIC-}" = "-AUTOMATIC-" ] ; then
SUBJECT="UPS Notification: ${MSG}"
${MAIL} -s "${SUBJECT}" ${FAILOVER_EMAIL_RECIPIENT} < /dev/null
fi

# This is our addition to the script - it calls our Perl script that will send shutdown call to all macs
if [ -f /shutdownups.cgi ]
then
perl /shutdownups.cgi
fi

#
# Shutdown services not controlled by watchdog.
#
# (These kill statements should use StartupItem script...)
kill -TERM $(cat /var/run/failoverd.pid)
kill -TERM $(cat /var/run/vpnd-*.pid)
kill -TERM $(cat /var/run/AppleFileServer.pid)
kill -TERM $(cat /var/run/QuickTimeStreamingServer.pid)
kill -TERM $(cat /var/run/smbd.pid)
kill -TERM $(cat /var/run/nmbd.pid)

${SI_PATH}/Apache/Apache stop
servermgrdctl stop

#
# Shutdown watchdog and its services.
#
${SI_PATH}/Watchdog/Watchdog stop

#
# Wait for watchdog and take the system down cleanly.
#
sleep 10
shutdown -h now "${MSG}"


this is our shutdownups.cgi
The same script sits on all Macs with except they do not sent shutdown notices on local network.

View Code#!/usr/bin/perl
unless($ENV{'SECURITYSESSIONID'}) {
$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local:/usr/local/bin';
}
if(-f "/killdaemon1") {unlink "/killdaemon1";}
## triggers daemon exit
`touch /killdaemon`;

#now we let every Mac on a local network to know it's time to shutdown
$brids = 'Mozilla/4.0 local shutdown note';
@allmacs = qw(emac imac imac2 poweapple); # list all Mac names in array
# all macs run Apache server with special URL to accept notes
foreach $mac (@allmacs) {
$url = "/notesLog/shutdown.now http://$mac.local/special_url.cgi";
`curl -A '$brids' -o $url`;
sleep(2);} ## foreach end
$start=time;
# now we watch for 10 minutes to make sure our own daemon is dead
while(1) { #########
if(-f "/http/killdaemon1") {last;}
$now=time;
$runfor=$now-$start;
if($runfor > 600) {last;}
sleep(5);
} ## WHILE END #####

# since it's a power shutdown we want the computer to power-up in a number of seconds
# in out case 1800 (30 minutes)
# besides that all Macs are set to power-up at 8AM
$startlptm=time;
$startlptm += 1800;
my $finaltime = localtime($startlptm);$finaltime =~ tr/ //s;
($wd,$mo,$da,$ti,$ye) = split(/\s/,$finaltime);
($hrZZ,$mnZZ,$sh) = split(/\:/,$ti);
`pmset repeat wakeorpoweron MTWRFSU $hrZZ:$mnZZ:00`;
sleep(1);
# in our case we also want to unmount and shut-down external USB/FireWire HDs
`touch /Unmount2`;`touch /Unmount3`;
`/usr/bin/perl /unmount2.cgi`;sleep(2);`/usr/bin/perl /unmount3.cgi`;sleep(2);
# and finally this is polite way to shutdown the computer
# this procedure is optional and if you do not want it - just uncomment next line
# exit(0);
`osascript /shutdown.computer.scpt`;
# and we give it 35 seconds being polite
sleep(35);
# if it did not work - sorry, that's the hard way to shutdown
`shutdown -h now`;

and here is very simple shutdown AppleScript:
View Codetell application "Finder" to eject (every disk whose ejectable is true or not local volume is true)
delay 5

ignoring application responses
tell application "System Events"
shut down
end tell
end ignoring

tell application "Finder" to shut down


Just make sure you setup UPS software in "Energy Saver" to have enough juice to finish shutdown across all Macs, i.e. initiate power-down when 15 minutes running time left on UPS battery.There's no place like ~
coding / shellPrev .. Next
 
Post Reply
Home - Coding: AppleScript C Perl Shell Xcode Other
Our Telegram Group