#!/opt/SUNWstade/bin/perl -I/opt/SUNWstade/lib
#<copyright>
# ----------------------------------------------------------
# Sun Proprietary/Confidential Code
# Copyright 2001, Sun Microsystems, Inc. All rights reserved.
# ----------------------------------------------------------
#</copyright>

use System;
use PPRO;
use Util;
use PDM::ConfigFile;
use Getopt::Std;
use strict;
use Process;

#
# runs locally, started from the GUI.
#
my(%opts);

sub usage {
  print <<EOF;
Usage: ras_upgrade -s -i ip_list -p  -S session_id -h
                    
		    -i <ip list separated by colons>
                    -S <session> , should be 'storade'
                    -c : use CD ROM as the patch source.
		    -s : status
                    -p : print report.
                    -h : Help.
                    -b : run background, default is foreground
Example:
       ras_upgrade -S storade -i \"ip_address1:ip_addtess2\" -b

EOF
}

if (!getopts("S:spm:i:cbh", \%opts) || $opts{h}) {
    usage();
    exit(1);
}

#close(STDERR); close(SDTOUT); close(STDIN);
my $HOME    = "/opt/SUNWstade";
my $RASPORT = System->getConfigPort($HOME);

System->set_home($HOME);
System->set_rasport($RASPORT);

my($renv, $devs, $hosts,$notifs) = PDM::ConfigFile->read;
System->set_renv($renv);
if ($renv->{solution} eq "N") {
   print "Function not available yet outside of a Sun Solution product!\n";
   exit;
}
require Inventory;

my $PRINTERR = $opts{P};
my $IPS      = $opts{i};
my $SID      = $opts{S};
my $ID      = "Upgrade";
my @REPORTS;

if ($opts{s}) {
   my $st = Process->status($opts{h}, $ID);
   print "$st \n";
   exit;
}

my $done = 0;
if ($opts{i}) {
  my $st = Process->status($opts{h}, $ID);
  if ($st =~ /Running/) {
     print "Revision Upgrade already running!\n";
     exit(1);
  }

  Process->run($opts{h}, "bin/ras_upgrade -m $opts{m} -i $opts{i} -S $SID", \&run, !$opts{b}, 60*60, \&printnew);
  $done = 1;
  $opts{p} = 1 if (!$opts{b});
}

if ($opts{p} || $opts{P}) {
   &printit($opts{h}, $ID, $opts{P});
  $done = 1;
}
if (!$done) {
  usage();
  exit(1);
}

sub printnew {
  my($new) = @_;
  # print $new;
}

sub store_passwords {
  my $array_p = System->getPassword("array");
  my $D = "/opt/SUNWppro/lib";
  if ( -d $D) {
     for my $i (40,41,42,43,44,50,51,52,53,54,55) {
         open(W, ">$D/.192.168.0.${i}pw");
         print W "$array_p\n";
         close(W);
     }

     my $array_p = System->getPassword("dsp");
     for my $i (10) {
         open(W, ">$D/.192.168.0.${i}pw");
         print W "$array_p\n";
         close(W);
     }

  }
  

}

sub run {
   my $debug;
   &store_passwords();
   
   Process->start($ID);
   my $lock  = LockManager->new();
   my $locki = $lock->exists("system", 1) || {};
   my $date  = Util->get_today();
   my ($err_cnt, $REPORT);

   if ($locki->{info}) {
      # LOG to SUNWstade/log/cron_patch.log
      $debug = "$date Conflict, system already reserved: $locki->{info}\n";
      $err_cnt++; $REPORT = {};

   } else {
     my $mins = 6 * 60;  # 6 hours
     my $info = "revision_maintenance|ras_upgrade|Manual Upgrade|$date|$mins|$$";
     my $rc   = $lock->lock("system", 60*60*6, 0, $info);
  
     my $cli = PPRO->cli_path();
     
     if ($opts{c}) {
   	$cli   .= " -c patchpro_cdrom.conf ";
     } else {
        $cli   .= PPRO->add_cdrom();
     }

     my $LOG = System->get_home() . "/DATA/tmp/Upgrade.log";
     my @ips = split(/\:/, $IPS);
     foreach my $ip0 (@ips) {
        my($ip, $patch1) = split(/\#/, $ip0, 2);
        my $command;
        if ($ip =~ /_ALL/) {
           $command = "$cli -i -s $SID -r upgrade >$LOG 2>&1";
        } elsif ($patch1) {
           $command = "$cli -i -o $ip -p $patch1 -s $SID -r upgrade >$LOG 2>&1";
        } else {
           $command = "$cli -i -o $ip -s $SID -r upgrade >$LOG 2>&1";
        }
        $debug .= "Running patch upgrade:\n";
  
        my($err, $out)= Util->run_command($command, "test", 100*60*60); # 2 hour timeout
        my $ppro = PPRO->parseFromFile("/var/tmp/pprosvc_$SID/upgrade");

	# Errors can occur during upgrade
        if ($ppro->{ERRORS}) {
	    $err_cnt++; # Top level errors
        } else {
          foreach my $dev (@{$ppro->devices()}) {
             foreach my $patch (@{$dev->patches()}) {
	          # errors at patch level
                  $err_cnt++ if ($patch->{error});
             }
	  }
        }
        if ($ppro) {
           if (!$REPORT) {
              $REPORT = $ppro;
           } else {
              foreach my $k (keys %$ppro) {
                $REPORT->{$k} = $ppro->{$k};
              }
           }
        }
     }
     if (open(OO, $LOG)) {
        my $l;
        while ($l = <OO>) {
           $debug .= $l;
        }
        close(OO);
     }
   }

   my ($result, $report);
   $report->{debug}  = 1;
   $report->{error_cnt}  = $err_cnt;
   $report->{data}   = {trace => $debug, report => $REPORT};
   $report->{display_method} = "Service::Upgrade::report";
   $report->{date}   = Util->get_today();

   Process->write($report, $ID);
   Inventory->upgradeMaserati() if (!$err_cnt);
   $lock->unlock("system");

   sleep(10);
   Process->done($ID);
   Process->email($report, "Solution Upgrade");
}

sub printit {
  my($host, $ID, $error_only) = @_;  
  my $R = Process->read($host, $ID);

}

