#!/usr/bin/perl
##############################################################################################
# © Copyright 2000-2009 Hewlett-Packard Development Company, L.P
#
# This program is free software; you can redistribute it and/or modify it under the terms of 
# the GNU General Public License as published by the Free Software Foundation; either version 
# 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with this program; 
# if not, write to the Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
##############################################################################################

# Create a logfile so we can help troubleshoot errors
my $log = "/var/log/LinuxCOE-base.log";
open(LOG,">$log") ||  print STDERR "Cannot open $log : $!\n What's up with that? :)\n\n";

# Make everything hot, I'm forking...
select(LOG); $|=1;
select(STDOUT); $|=1;
select(STDERR); $|=1;
my $chvt = `which chvt`;
chomp($chvt);
system "$chvt 5; exec < /dev/tty5 > /dev/tty5";

# Send in MAC (should be unique and innocent) for mgmt counter

print LOG "Scroll down to ===START=== for the real action.\n";

# Load an %array of installed rpms....
print STDERR "Creating a list of installed rpms for comparison.\n";
my %installed = &load_installed;

my %bundles = (

# REAL_DATA_HERE

);

# Snatch the waystation they selected
#  note to self: do not name a valid bundle 'WaYsTaTiOn' ;p

my $waystation = $bundles{'WaYsTaTiOn'};
delete($bundles{'WaYsTaTiOn'}); # let's not load this one!

print LOG " ===START=== \n";
print LOG "My Waystation is $waystation\n";

unless ( -d "/etc/opt/LinuxCOE" ) { system "/bin/mkdir -p /etc/opt/LinuxCOE" }
open(WAY,">/etc/opt/LinuxCOE/waystation");
print WAY "$waystation\n";
close(WAY);

# Update suseservers in case they want to use YOU
open(YOU,">>/etc/suseservers");
print YOU "http://$waystation/LinuxCOE/SuSE-updates\n";
close(YOU);

# Update YOU config file
open(IN,"/etc/sysconfig/onlineupdate");
open(OUT,">/etc/sysconfig/onlineupdate.new");
while(<IN>) {
  if ( /^YAST2_LOADFTPSERVER/ ) { 
    print OUT qq[YAST2_LOADFTPSERVER="no"\n];
  } else {
    print OUT;
  }
}
close(IN);
close(OUT);
rename("/etc/sysconfig/onlineupdate.new","/etc/sysconfig/onlineupdate");

#
# main()  - here's the meat!
#

# Force LinuxCOE Base (config files, MAC again)

# Walk the bundles they selected and load them as needed

system "/bin/echo -e '\033[44;37;1m\\033[H\\033[JLinuxCOE 4.X post installation processing\r\n\n' >/dev/tty5";

foreach $bundle (sort(keys(%bundles))) {
  &load_bundle($bundle,$bundles{$bundle},$waystation);
}

# At this point, apt should be installed, create the files for coe_bundles
unless ( -d "/etc/opt/LinuxCOE/apt" ) {
  my $syscall = "/bin/mkdir -p /etc/opt/LinuxCOE/apt";
  if ( $dont_do_it ) {
    print STDERR "I would have executed:\n\n$syscall\n\n";
  } else {
    system $syscall;
  }
}

print STDERR "Done!  Thanks for choosing LinuxCOE!\n";
if ( -x "/opt/LinuxCOE/bin/install_bundles" ) {
  system "/opt/LinuxCOE/bin/install_bundles INSTALL >/dev/tty5";
}
system "$chvt 1";


#
# End of main() - the rest is gravy...
#

sub load_bundle {

# Cycle through rpms associated with this bundle, load as needed.

  my ($bundle,$files,$waystation) = @_;
  print LOG "Installing $bundle bundle from $waystation\n";
  print STDERR "Please wait, installing $bundle bundle from $waystation - ";
  my $test = $bundle;
  my $step = chop($test);
  system "/bin/echo -n 'Initial processing step $step of 3                                       ' >/dev/tty5";
  my @needem;
  my @rpms = split(' ',$files);

# Foreach rpm, see if it's needed
  foreach $rpm (@rpms) {
    if ( &need_it($rpm) ) { 
      print LOG " will install\n";
      push(@needem,$rpm); 
    } else {
      print LOG " already got it\n";
    }
  }

# Do we need any?  If so, attempt to install them
  if (@needem) {
    my $line = join(" ",@needem);
    &load_rpms($bundle,$line); 
  } else {
    print LOG "$bundle is installed or superseded...\n";
    print STDERR "already got it, continuing...\n";
  }

}

sub need_it {

# is the rpm passed needed?

  my $rpm = shift;
  # Rip off all the leading path cruft;
  my @data = split('\/',$rpm);
  $rpm = pop(@data);        # grab the rpm name sans path
  (@data) = split('\.',$rpm);
  pop(@data); pop(@data);   # Get rid of .arch.rpm
  my ($name,$ver) = &parse_rpm(join('.',@data));
  print LOG "$name, comparing new $ver to installed $installed{$name}";
  if ( $ver gt $installed{$name} ) { return(1) }  # we need it!
  return;  # they got it!

}

sub parse_rpm {

#  autorpm does this better, but I can't force Patch_Mgmt  

  my $data = shift(@_);
  my @arr = split('-',$data);
  my ($test,@p);
  while ( $test = shift(@arr) ) {
    last if ( $test =~ /^[0-9]/ );
    push(@p,$test);
  }
  return(join('-',@p),join('-',$test,@arr));

}

sub load_installed {

# Create the %array of installed rpms.

 my %installed;
  open(IN,"/bin/rpm -qa |") ||
    die "Cannot fork rpm : $!\n";
  while(<IN>) {
    chomp;
    my ($product,$rev) = &parse_rpm($_);
    $installed{$product} = $rev;
    print LOG "Found installed product $product - $rev\n";
  }
  return(%installed);

}

sub make_snippet {

# Create a /etc/init.d/init.d snippet to try again next reboot

  ($bundle,$rpms) = @_;
  open(RC,">/etc/init.d/LinuxCOE-$bundle");
  print RC qq{#!/bin/sh
/bin/rpm --force -Uvh $rpms
if [ \$? -eq 0 ]
then
  /bin/rm /etc/init.d/*/*LinuxCOE-$bundle
  /bin/rm /etc/init.d/LinuxCOE-$bundle
fi
};
my $count = 99;
if ($bundle eq 'BASE-1') { $count = 97 }
elsif ($bundle eq 'BASE-2') { $count = 98 }
system "/bin/chmod +x /etc/init.d/LinuxCOE-$bundle";
system "/bin/ln -s /etc/init.d/LinuxCOE-$bundle /etc/init.d/rc2.d/S${count}LinuxCOE-$bundle";
system "/bin/ln -s /etc/init.d/LinuxCOE-$bundle /etc/init.d/rc3.d/S${count}LinuxCOE-$bundle";
system "/bin/ln -s /etc/init.d/LinuxCOE-$bundle /etc/init.d/rc4.d/S${count}LinuxCOE-$bundle";
system "/bin/ln -s /etc/init.d/LinuxCOE-$bundle /etc/init.d/rc5.d/S${count}LinuxCOE-$bundle";

}

sub load_rpms {

# Attempt to install the rpms passed via HTTP

  my ($bundle,$line) = @_;
  my $syscall = "/bin/rpm --force -Uvh $line >>${log}.rpmlog 2>&1";
  print LOG "Installing $bundle with:\n ";
  print LOG "$syscall\n";
  if ( $dont_do_it ) {
    print STDERR "I would have executed:\n\n$syscall\n\n";
  } else {
    system $syscall;
  }
  if ( $? != 0 ) {
    print LOG " $bundle failed, making rc.d snippet, will retry on next boot.\n";
    &make_snippet("$bundle","$line");
    print STDERR " failed. :(  Will retry on next boot.\n  See $log for details.\n";
    system "/bin/echo '[Failed]' >/dev/tty5";
  } else {
    print STDERR " succeeded!\n" unless ($dont_do_it);
    system "/bin/echo '[OK]' >/dev/tty5";
  }

}
