#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html

use IO::Socket;

#-----------------------------------------------------------------------------

=head1   send_reboot_request

This program is run by a job command scheduler such as LoadLeveler
to send a rebootnodes request to the xcatiport so the xcatd daemon
can initiate a shutdown and reboot of the nodes for rolling updates.
The request will be ignored if the nodes are not in the correct state.

See the rollupdate man page and documentation for more information.


Syntax:
   send_reboot_request <waittime> <scheduler> <xcatserver> <xcatport> <nodelist>
where:
    <waittime> is a number in minutes this command will sleep after sending
                the request to xcatd.  For LL, this will give xCAT time to
                drain the schedd on the nodelist.  Otherwise, when this job
                ends, LL may submit new jobs to the nodes and those jobs will
                die when the node is shutdown.  Default is 10 minutes.
    [--verbose|-V] optional verbose indicator which if set will tell the 
                xcatd daemon to log status messages in the log file
                /var/log/xcat/rollupdate.log on the xCAT management node.
    <scheduler> is the job scheduler plugin to be invoked.  'loadleveler' is
                currently the only scheduler supported by xCAT.
    <xcatserver> is the xcatd service node for the node running this script.
    <xcatport> is the xcatiport the xcatd is listening on.
    <nodelist> is a comma-delimited list of xCAT nodenames in this update group
               that will be updated at the same time.			
	
=cut

#-----------------------------------------------------------------------------
# Main

# send a request to the xcatd daemon to request a reboot

$| = 1;    # autoflush stdout
my $hostname = `/usr/bin/hostname -s`;
print "running on $hostname  \n";
system "date";

my $sleeptime = 60 * ( shift @ARGV );
if ( $sleeptime <= 0 ) { $sleeptime = 600; }
my $scheduler    = shift @ARGV;
my $verbose = "";
if ( ($scheduler eq '--verbose') || ($scheduler eq '-V') ) {
	$verbose = $scheduler;
	$scheduler = shift @ARGV;
}
my $xcatd_server = shift @ARGV;
my $port         = shift @ARGV;
my $nodelist     = shift @ARGV;

print "opening port to $xcatd_server : $port \n";
my $remote = IO::Socket::INET->new(
                                    Proto    => "tcp",
                                    PeerAddr => $xcatd_server,
                                    PeerPort => $port,
);
unless ($remote) {
    print "Cannot connect to host \'$xcatd_server \'\n";
    exit 1;
}
$remote->autoflush(1);
while ( defined( $line = <$remote> ) ) {
    chomp $line;
    system "date";
    print "read from port:  $line\n";
    if ( $line eq "ready" ) {
        system "date";
        print "sending:  rebootnodes $verbose $scheduler $nodelist\n";
        print $remote "rebootnodes $verbose $scheduler $nodelist\n";
    }
    if ( $line eq "done" ) { last; }
}
close $remote;

print "sleeping for $sleeptime seconds \n";
sleep $sleeptime;
print "job is done \n";
system "date";
exit 0;
