Code Search for Developers
 
 
  

nph-coe_image.in from LinuxCOE at Krugle


Show nph-coe_image.in syntax highlighted

#!/usr/bin/perl
##############################################################################################
# File:         nph-coe_image
# Description:  Build a kickstart image
# Author:       Lee Mayes   ( email leem@hp.com )
# Created:      31 Jan 2001
# Language:     perl
# Package:      LinuxCOE
##############################################################################################
# © Copyright 2000-2007 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., 675 Mass Ave, Cambridge, MA 02139, USA.
##############################################################################################
# Create a bootable image
# Init  - Initalize interactive HTML
# Step1 - Create the ks.cfg file
# Step2 - Create the loopback filesys,Insert ks.cfg, cleanup
# Step3 - Copy ks.cfg and boot image to ~ftp/pub/images
# Step4 - Cleanup & Create final HTML
##############################################################################################

use strict;
my $debug = 1;   		
my $nonav = 0;
use CGI;
my $qin = new CGI;
use lib qw (@prefix@/lib @prefix@/includes);
use LinuxCOE;
use sysdes_paths;
use binaries;
my $db = new LinuxCOE;
$db->debug($debug);
$db->nonav($nonav);
use COEHtml;
my $qout = new COEHtml;
my $COE_VER=$db->def('COE_VER');
my $defs = $qin->param('defs');
if ( $defs ) {
  $db->LoadDefs($defs);
}

my $replay = 0;
if ($qin->param('action') eq 'replay') { 
  print STDERR "Replay detected, disabling interactive HTML\n" if $debug;
  $db->def('FINAL_INTERACTIVE',0);
  $replay = 1;
  $nonav = 1;  # no need for lipstick
}
$db->InitDB;


# Disable interactive HTML if requested || SECURITY_LEVEL = SECURE

my $privpath = "image$$";
my $sec_level = $db->def('SECURITY_LEVEL');
if ( $sec_level eq 'SECURE' ) { 
  $db->def('FINAL_INTERACTIVE',0);
  $db->def('FINAL_URL_METHOD','https://');
  my $path = $db->def('FINAL_ABS_PATH');
  if ( $path =~ /\/$/ ) { chop($path) }
  $db->def('FINAL_ABS_PATH',"$path/$privpath");
}


unless ( $db->def('FINAL_INTERACTIVE') ) { $qout->do_nothing(1) }

my @vars = qw(hostname ip method profile os waystation netmask 
              kbd lang timezone mouse gateway namesvr utc);    

my $docroot = $ENV{'DOCUMENT_ROOT'} || $db->def('HTDOCS');
my $iesux = 0;
my $htmlpath = "$docroot/scratch_monkey";
$htmlpath = "$docroot/scratch_monkey/$privpath" if ( $sec_level eq 'SECURE' );
my $htmlfile;
my $ks_filename = "ks$$.cfg";			# Custom ks.cfg
my $ks_file = "$htmlpath/$ks_filename";		# Full path to ks.cfg file
my $replay_file = "$htmlpath/replay$$";		# replay this web session later
my $ftp_dir = $db->def('FINAL_ABS_PATH');	# Where to it when I'm done
my $age = 1800 || $db->def('AGE');		# Delete images older than $age seconds..
my $custimg = "$htmlpath/img$$";		# Custom floppy image
my $imgmount = "$htmlpath/imagedir$$";		# Where I loopback mount $custimg
my $initrdmount = "$htmlpath/initrddir$$";	# Where I loopback mount initrd
my $mounted = 0;				# Image is mounted (for cleanup)
my $ISO = 0;					# Create a ISO image vs. floppy(s)
if ( $qin->param('image') =~ /iso$/ ) { $ISO=1 }

# Drain the form and define variables for things needed globally

my $os = $db->clean_var($qin->param('os'));
my ($distro,$version) = split(' ',$os);
my $arch = $db->clean_var($qin->param('arch'));
my $method = $qin->param('method');
my $profile = $db->clean_var($qin->param('profile'));
my $waystation = $qin->param('waystation');
my $asset = $qin->param('asset');
my $system = $qin->param('system');
my $ip = $qin->param('ip');
my $gw = $qin->param('gateway') || $ip;
my $nm = $qin->param('netmask');
my $ns = $qin->param('namesvr');
my $hostname = $qin->param('hostname');
my $interface = $qin->param('netdev');
my $kbd=$qin->param('kbd');
my $mouse=$qin->param('mouse');
my $lang=$qin->param('lang');
my $timezone=$qin->param('timezone');
my ($serial,@serials);	# SIM placeholders
if ( $db->def('SIM') ) {
  @serials = split(':::',$qin->param('serial'));
  $serial = shift(@serials);
}
my ($path,$parts,@bundles,$rpms,$final,$patch_me,$patch_freq,@coe_bundles,$misc,$final_text,$patch_method,$bundle_error,$sum_this_image,$trig_img,$trig_conf);
my $msgtail = "0c[F1-Main] [F2-Local] [F3-Disk] [F4-RedHat] [F5-COE] [F6-Final]07\n";
my @methods = $db->sw_methods($distro,$version,$arch);
my $APT=0;					# Use APT in post processing
my $YUM=0;					# Use YUM in post processing
if ( grep(/APT/,@methods) ) { $APT=1 }
if ( grep(/YUM/,@methods) ) { $YUM=1 }
print STDERR "\$APT=$APT, \$YUM=$YUM\n" if $debug;


###### MAIN #######
&Init;    # start html
my ($passwd,$userpasswd) = &check_pass;
#if ( $qin->param('action') eq 'express' ) { &Reality_Check }  # No longer implemented
&Step1;   # Create ks.cfg
&Step2;   # Insert ks.cfg into bootdisk image
&Step3;   # Make it ftp'able
&Step4;   # Cleanup and create final HTML
###### End of MAIN #######

sub Step1 {

# OK kids, lets create the kickstart file!!!!

  print STDERR "Entering Step1\n" if $debug;
  $qout->message("Creating ks.cfg file");
  $qout->updatehtml(1);
  if ( $method ne 'CDROM' ) {
    $path = $db->show_os($distro,$version,$arch,$method,$waystation);
    unless ($path) {
      &end_it_now("$waystation is NOT exporting $distro $version via $method");
    }
  } elsif ( $method eq 'CDROM' ) {
# This makes all CDROM installs fetch coe_bundles from default waystation
    $waystation = $db->def('WAYSTATION');
  }

# Extract the profile from DB (profile)  or calling env (Custom) 

  if ( $profile ne 'Custom' ) {

    my ($b,$c);
    ($parts,$misc,$final,$rpms,$patch_me,$patch_freq,$c,$b,$patch_method) = $db->parse_profile($profile,$arch,$version,$distro);
    unless ($parts) {
      &end_it_now($db->errmsg . " No parts..");
    }
    $final_text = $final;
    @coe_bundles = @{$c};
    @bundles = @{$b};
# May have overridden parts/misc
    if ( $qin->param('override')  eq 'YES' ) {
       $parts = $qin->param('parts');
       $misc = $qin->param('misc');
    }

  } else {

    $parts = $qin->param('parts');
    $misc = $qin->param('misc');
    $final = $qin->param('final');
    $rpms = $qin->param('rpms');
    @bundles = $qin->param('bundles');
    @coe_bundles = $qin->param('coe_bundles');
    $patch_me = $qin->param('patch_me');
    $patch_freq = $qin->param('patch_freq');
    $patch_method = $qin->param('patch_method');

  }
  # Strip out all the comments and formatting oddities
  $parts =~ s/
//g;
  $parts =~ s/^#.*$//gm;
  $parts =~ s/\n+/\n/gs;
  $misc =~ s/
//g;
  $misc =~ s/^#.*$//gm;
  $misc =~ s/\n+/\n/gs;
  $final =~ s/
//g;
  $final =~ s/^#.*$//gm;
  $final =~ s/\n+/\n/gs;
  $rpms =~ s/
//g;
  $rpms =~ s/^#.*$//gm;
  $rpms =~ s/\n+/\n/gs;
  #rh62 and rh71 don't include perl in Base, yet we need it
  if ( $version eq '6.2' ) {
    $rpms .= "\nperl\ntcsh\n";
  } elsif ( $version eq '7.1' ) {
    $rpms .= "\nperl\n";
  }
  
# What you say let's generate the file, eh?

  unless ( -d $htmlpath ) { mkdir $htmlpath, 0755 }
  open(KS,">$ks_file") ||
    &end_it_now("Cannot open $ks_file for writing : $!\n");
  print KS "# ks.cfg : Created by LinuxCOE $COE_VER at ".`date`;
  print KS "# COE-Profile used: $profile\n";
  print KS "lang ".$qin->param('lang')."\n";  
  if (( $version ne 'ESX-1.5.2' ) && ( $os ne 'Fedora 7' )){
    print KS "langsupport --default ".$qin->param('lang')."\n";  
  }
  print KS "keyboard ".$qin->param('kbd')."\n";
  print KS "mouse ".$qin->param('mouse')."\n" unless ( $os eq 'Fedora 7' );
  if ( $qin->param('auth') ) {
    print KS $qin->param('auth')."\n";
  } 
  print KS "install\n";
  print KS "timezone "; 
  if ( $qin->param('utc') eq 'Yes' ) { print KS "--utc " }      
  print KS $qin->param('timezone')."\n";  
  my @seeds = ('A'..'Z','a'..'z');                  
  my $seed = $seeds[int(rand(52))] . $seeds[int(rand(52))];
  my $enc_pass = crypt($passwd,$seed);
  print KS "rootpw --iscrypted $enc_pass\n";
  my $network;
  if ( $qin->param('ip') ) {
    $network = "network --bootproto static --ip $ip --netmask $nm --gateway $gw --nameserver $ns";
  } else {
    $network = "network --bootproto dhcp";
  }
  $network .= " --device " . $qin->param('netdev');
  print KS "$network\n";
  if ( $method eq 'CDROM' ) {
    print KS "cdrom\n";
  } elsif ( $method eq 'HTTP' ) {
    print KS "url --url http://${waystation}${path}\n";
  } elsif ( $method eq 'FTP' ) {
    print KS "url --url ftp://$waystation/$path\n";
  } elsif ( $method eq 'NFS' ) {
    print KS "nfs --server $waystation --dir $path\n";
  }

# Add disk partitioning

  print KS "$parts\n";
  print KS "$misc\n" if $misc;

# If VMWare, poke license keys in there....

  if (( $distro eq 'VMWare' ) && ( $version ge 'ESX-2.5.1' )) {
    my $esxkey = $qin->param('esxkey');
    my $esxcpukey = $qin->param('esxcpukey');
    print KS "vmserialnum --esx=$esxkey" if $esxkey;
    if ( $esxcpukey ) { print KS " --esxsmp=$esxkey" }
    print KS "\n";
  }
  if (( $version eq '5Server') || ( $version eq '5Client' )) {
    my $key = $qin->param('esxkey');
    if ( $key ) {
      print KS "key $key\n";
    } else {
      print KS "key --skip\n";
    }
  }

# Add bundle and RPM selections

  print KS "%packages\n";
  if ( @bundles ) {
    print KS "@ ",join("\n@ ",@bundles),"\n";
  } elsif (( $distro ne 'VMWare' ) && ( $profile eq '' )) {
    print KS "@ Base\n";
  }
  if ( $rpms ) {
    print KS "$rpms\n";
  }

# Post section 
  print KS "%post\n\n";

# If DDNS is in play, let's tweak that here
  my $realnic = $interface;
  if ( $version =~ /ESX-3/ ) { $realnic =~ s/eth/vswif/ }
  if ( ( $system ) && (!($ip)) ) {
    print KS qq[/bin/sed -i -e 's/HOSTNAME=.*/HOSTNAME=$system/' /etc/sysconfig/network
echo "DHCP_HOSTNAME=$system" >>/etc/sysconfig/network-scripts/ifcfg-$realnic
];
  }

  if ( $distro ne 'VMWare' ) {

# Add COE Postprosessing

    &coe_final unless ($db->def('NO_COE'));

  }
  

# Add User's Requested Final Script

  if (( $ip ) && ($hostname)) {
    print KS "echo $ip\t$hostname >>/etc/hosts\n";
  } 
  print KS qq[echo "Kickstart-installed $distro $version - LinuxCOE Rev $COE_VER `/bin/date`" > /etc/motd\n ];
  if ( $final ) {
    print KS "$final\n";
  }

# Create a mortal account if requested

  my $uname = $qin->param('User_Name');
  if ( $uname ) { 
     my $string = $db->make_mortal_user($uname,$qin->param('Real_Name'),$userpasswd);
     print STDERR $string if $debug;
     print KS $string;
  }
  close(KS);

} # End of Step1 - ks.cfg is built!

sub Step4 {

# It's done, parse ks_help.html and create final page

  my $title = "LinuxCOE $COE_VER Custom Image - Completed";
  $qout->persist("$title");
  $qout->message("Your image is now ready for retrieval!");

# Who am i?

  my $host = `/bin/hostname`;
  chomp $host;
  my $hostname = (gethostbyname($host))[0];
  $hostname = $db->def('HOSTNAME') || $hostname; 

  my $installer = 'KS';
  my ($image_type,$target,$ks_path,$img_path);
  if ( $ISO ) {
    $image_type = 'ISO';
    $target = "img$$.iso";
  } else {
    $image_type = 'IMG';
    $target = "img$$";
    if ( $distro eq 'VMWare' ) { $installer = 'ESX' }
  }
  if ( $sec_level eq 'SECURE' ) {
   $img_path = "$privpath/$target";
   $ks_path = "$privpath/$ks_filename";
  } else {
   $img_path = $target;
   $ks_path = $ks_filename;
  }
  my $warnings;
  if ( $bundle_error ) {
    $warnings = qq[<P><B><font color=red>Warning:</font></B> One or more bundles you requested have no RPMS associated with them!</P>];
  }
  if (( ! $qin->param('ip') ) && ( $method ne 'CDROM')) {
    $warnings .= qq[ <P><B>Warning:</B> Since you do not have static network information, you <B>MUST</B> have a working <B>DHCP</B> server on your subnet!</P>];
  }

  my %sr_array = (
    COE_WAYSTATION => $hostname,
    WAYSTATION => $waystation,
    IMG_NAME => $target,  
    IMG_PATH => $img_path,
    KS_NAME => $ks_filename,
    KS_PATH => $ks_path,
    LINUXCOE_WARNINGS => $warnings,
    INSTALL_PATH => $path,
  );
  if ($replay) {
    print STDERR "replay detected, emebedding data\n" if $debug;
    my $method = $db->def('FINAL_URL_METHOD') || 'ftp://';
    my $path = $db->def('FINAL_URL_PATH');
    my $url = "${method}${hostname}${path}${img_path}";
    my $msg = "START_OF_LINUXCOE_BEAM_DATA\n";
    $msg .= "$url\n";
    $msg .= "END_OF_LINUXCOE_BEAM_DATA\n";
    print "\n$msg\n";
    print $qin->end_html;
    exit;
  }
  my $msg = $db->Create_Final_HTML($distro,$version,$arch,$installer,$image_type,$sec_level,$htmlpath,$sum_this_image,$serial,%sr_array);
  print STDERR "Calling CleanUp($htmlpath,$ftp_dir,$distro,$version,$arch,$trig_img,$trig_conf)\n" if $debug;
  $db->CleanUp($htmlpath,$ftp_dir,$distro,$version,$arch,$trig_img,$trig_conf);
  if ( $db->def('FINAL_INTERACTIVE') ) {
    $msg .= "\n</body></html>\n";
    $qout->trailer("$msg\n");
    $qout->updatehtml(0);
  } else {
    print $qin->header;
    $db->ShowNav($title);
    print $msg;
    print $qin->end_html;
    $db->ShowFooter;
    exit;
  }
}

sub Step3 {

# Simply copy ks.cfg and img file to ftp directory (unless it's the same place)
#
  $qout->message("Step3 : Making it accessible");
  $qout->updatehtml(1);
  if ( $db->def('SIM') ) {
    my $simdir = $db->def('SIM');
    if ( $ISO ) {
      &my_sys("/bin/mv $custimg $simdir/$serial/boot.iso");
      $trig_img = "$simdir/$serial/boot.iso";
    } else {
      &my_sys("/bin/mv $custimg $simdir/$serial/diskboot.img");
      $trig_img = "$simdir/$serial/diskboot.img";
    }
    &my_sys("/bin/mv $ks_file $simdir/$serial/ks.cfg");
    $trig_conf = "$simdir/$serial/ks.cfg";
    open(SIM,">$simdir/$serial/CUSTOM_SETTINGS");
    my $sdist = uc($distro);
    my $sver = $version;
    $sver =~ s/[AEW]S.*//;
    my $sarch = 'x86'; 
    $sarch = 'x86_64' if ($arch eq 'x86_64');
    print SIM "DISTRO=${sdist}$sver\n";
    print SIM "ARCH=$sarch\n";
    close(SIM);
    open(ARGS,">$simdir/$serial/args");
    foreach my $parm ($qin->param) {
      next if ( $parm =~ /Pass/ );
      my $val = $qin->param($parm);
      $parm = uc($parm);
      print ARGS "$parm=\"$val\"\n";
    }
    close(ARGS);
    
  } elsif ( $ISO ) {
    &my_sys("/bin/mv $custimg ${ftp_dir}/img$$.iso") if ( "$custimg" ne "${ftp_dir}/img$$.iso");
    $sum_this_image = "${ftp_dir}/img$$.iso";
    &my_sys("/bin/mv $ks_file ${ftp_dir}/$ks_filename") if ( "$ks_file" ne "${ftp_dir}/$ks_filename" );
    $trig_img = $sum_this_image;
    $trig_conf = "${ftp_dir}/$ks_filename";
  } else {
    &my_sys("/bin/mv $custimg ${ftp_dir}/img$$") if ( "$custimg" ne "${ftp_dir}/img$$");
    $sum_this_image = "${ftp_dir}/img$$";
    &my_sys("/bin/mv $ks_file ${ftp_dir}/$ks_filename") if ( "$ks_file" ne "${ftp_dir}/$ks_filename" );
    $trig_img = $sum_this_image;
    $trig_conf = "${ftp_dir}/$ks_filename";
  }

}

sub Step2 {

  if (( $db->def('SIM') ) || ( $db->def('ASSET_URL') )){
    $db->Store_Conf($ks_file,$asset);
  }
  unless ( $db->def('CREATE_IMAGE') ) {
    $qout->persist("LinuxCOE $COE_VER $distro $version Template - Completed");
    $qout->message("Your template is now ready for retrieval!");
    my $msg = qq[
Configuation file has been created and stored <a href=/templates/$asset.txt>HERE</a>.
];
    $msg .= "\n</body></html>\n";
    $qout->trailer("$msg\n");
    $qout->updatehtml(0);
    exit;
  }

# Mount the virgin image using loop driver, jam our ks and asst files in there...

  my $uid = $>;            	# What's my UID
  umask 000;
  my ($distro,$version) = split(' ',$qin->param('os'));

  $qout->message("Creating loopback system for ks.cfg insertion");
  $qout->updatehtml(1);
  mkdir("$imgmount",0766) ||
    &end_it_now("Cannot mkdir $imgmount : $!\n");
  unless ( -d "$imgmount" ) {
    &end_it_now("mkdir $imgmount failed?!?!?!\n");
  }
  my $defimage .= "$distro-${version}-$arch-";

# note to leem, changing order of iff statements
# a 'luser' selected CDROM and ISO and got a Jinkees
# I'm gonna check for ISO first, then CDROM (ISO was 3rd)
# let's see what this breaks :)
#
# BTW, if 'luser' seems too harsh a term, consider it's accuracy
# he used your perlcode... threw the dice... and lost!

  if (( $ISO ) && ( $arch ne 'ia64' )) {
    $defimage .= 'iso.tar';
  } elsif ( $qin->param('image') eq 'default' ) {
    $defimage .= 'bootnet.img';
  } elsif (( $ISO ) || ( $qin->param('image') eq 'ISO' )) {
    $defimage .= 'bootnet.img';
  } else {
    $defimage .= $qin->param('image');
  }

  $defimage = $db->find_file("images/$defimage");
  unless ( $defimage ) { &end_it_now("Cannot locate defimage for $distro-$version-$arch") }
  if ((! $ISO ) || ( $arch eq 'ia64' )) {
    print STDERR "Step2: Copying $defimage -> $custimg\n" if $debug;
    open(IN,"$defimage") ||
      &end_it_now("Cannot open defimage $defimage for reading : $!\n");
    open(OUT,">$custimg") ||
      &end_it_now("Cannot open custimage $custimg for writing : $!\n");
    while(<IN>) { print OUT };
    close(IN); close(OUT);
    unless ( -f "$custimg" ) { &end_it_now("Copy of image failed?!?!") }
  }

  my $sys;
  if ( $arch eq 'ia64' ) {
    $sys = "$SUDO /bin/mount -o loop,user,uid=$uid,rw -t vfat $custimg $imgmount";
    $mounted = 1;
  } elsif ( $ISO ) {
    $sys = "$TAR -C $imgmount -xf $defimage";
  } else {
    $sys = "$SUDO /bin/mount -o loop,user,uid=$uid,rw -t msdos $custimg $imgmount";
    $mounted = 1;
  }
  &my_sys("$sys");
  unless (( -f "$custimg" ) || ( $ISO )) {
    &end_it_now("$custimg is not there?!?!?!");
  }
  $qout->message("Inserting ks.cfg into boot image.");
  $qout->updatehtml(1);

# If we have a syslinux.cfg and boot.msg, jam them in:

  my $realdir;
  if (( $ISO ) && ( $arch ne 'ia64' )) {
    $realdir = "$imgmount/isolinux";
  } else {
    $realdir = $imgmount;
  }

  my $no_loop = $db->def('NO_LOOPMOUNT_KS_ISO');

  if (( -r $db->find_file("boot/syslinux.kickstart") ) &&
      ( -r $db->find_file("boot/boot.msg") ) &&
      (( $arch eq 'i386' ) || ( $arch eq 'x86_64' ))) {

    &my_sys("/bin/chown -R $uid $realdir");
    foreach my $gone (qw(rescue.msg syslinux.cfg boot.msg expert.msg general.msg param.msg snake.msg ks.cfg splash.lss)) {
      unlink "$realdir/$gone";
    }
    print STDERR "Inserting custom syslinux.cfg and boot.msg file onto floppy\n" if $debug;
    my $infile;
    if (( $no_loop ) && ( $ISO )) {
      $infile =  $db->find_file("boot/syslinux.kickstart.no_loop");
    } else {
      $infile =  $db->find_file("boot/syslinux.kickstart");
    }
    unless ($infile) {
      &end_it_now("Cannot find syslinux/isolinux.cfg template!");
    }
    if ( $ISO ) {
      &my_sys("/bin/cp -f $infile $realdir/isolinux.cfg");
    } else {
      &my_sys("/bin/cp -f $infile $realdir/syslinux.cfg");
    }
    &my_sys("/bin/cp -f $infile $realdir/isolinux.cfg");

    $db->boot_lipstick($realdir,$distro,$version,$arch,$waystation,$method,$profile,$ip,$nm,$gw,$ns,$final_text,$parts,$msgtail,$interface,$hostname,$kbd,$mouse,$lang,$timezone,\@bundles,\@coe_bundles,$defs);

  }

# Put the ks.cfg file into initrd.img

  if (( $no_loop ) && ( $ISO ) && ( $arch ne 'ia64' ))  {
# Simply drop ks.cfg in root of ISO
    &my_sys("/bin/cp $ks_file $imgmount/ks.cfg");
  } elsif ( $db->is_filesys_initrd($distro,$version,$arch) ) {
    print STDERR "initrd is a filesys, let's loopmount it.\n" if ( $debug );
    &my_sys("/bin/cp $realdir/initrd.img $htmlpath/initrd.img$$.gz");			# Snag initrd.img
    &my_sys("$GUNZIP $htmlpath/initrd.img$$.gz");					# Uncompress it
    mkdir("$initrdmount",0666) || &end_it_now("Cannot mkdir $initrdmount : $!\n");	# Make a playground
    $sys = "$SUDO /bin/mount -o loop,user,rw -t ext2 $htmlpath/initrd.img$$ $initrdmount";
    &my_sys("$sys");									# Loopmount it
    $sys = "$SUDO /bin/chmod 777 $initrdmount";						# Make it writeable
    &my_sys("$sys");
    &my_sys("$SUDO /bin/chmod 666 $initrdmount/ks.cfg") if ( -f "$initrdmount/ks.cfg" ); # Change perms or cp fails
    $sys = "/bin/cp $ks_file $initrdmount/ks.cfg";					# Copy config file in
    &my_sys("$sys");

# unmount the initial ramdisk, lose mountpoint
    &my_sys( "$SUDO /bin/umount $initrdmount" );
    rmdir $initrdmount;

# compress the modified ramdisk image, and poke it back into the boot floppy
    &my_sys("$GZIP -c $htmlpath/initrd.img$$ >$realdir/initrd.img");
  } else {
    print STDERR "initrd is a cpio archive, let's extract it.\n" if ( $debug );
    &my_sys("/bin/cp $realdir/initrd.img $htmlpath/initrd.img$$.gz");
    &my_sys("$GUNZIP $htmlpath/initrd.img$$.gz");					# Uncompress CPIO image
    mkdir("$initrdmount",0766) || &end_it_now("Cannot mkdir $initrdmount : $!\n");      # Make a playground
    &my_sys("cd $initrdmount; $CPIO -i <$htmlpath/initrd.img$$");  			# Extract CPIO image
    &my_sys("/bin/cp $ks_file $initrdmount/ks.cfg");					# Poke in ks.cfg
    &my_sys("cd $initrdmount; $FIND . | $CPIO -H newc -o >$htmlpath/initrd.img$$");	# Create CPIO image back
    &my_sys("$GZIP -c $htmlpath/initrd.img$$ >$realdir/initrd.img");			# Compress it back
    &my_sys("/bin/cp $realdir/initrd.img $realdir/efi/boot/initrd.img") if ( $arch eq 'ia64' );
    &my_sys("/bin/rm -rf $initrdmount");						# What body?

  }  # End of if/if not CPIO
  
# Put ks.cfg on the boot image for ia64 
  if ( $arch eq 'ia64' ) {
    &my_sys("/bin/cp $ks_file $imgmount/KS.CFG");
    my $elilo = $db->find_file("boot/elilo.conf-$distro-$version");
    unless($elilo) { $elilo = $db->find_file("boot/elilo.conf-$distro") }
    unless($elilo) { $elilo = $db->find_file("boot/elilo.conf") }
    unless($elilo) { &end_it_now("Cannot locate elilo.conf for $distro-$version") }
    &my_sys("/bin/cp $elilo $imgmount/elilo.conf");					# Update elilo.conf to ref our lipstick
    &my_sys("/bin/cp $elilo $imgmount/efi/boot/elilo.conf");				# There's 2 copies, figure out the right one later (BUG?)
  } elsif ( $ISO ) {
# Stick a ref copy a / level on the ISO
    system  "/bin/cat $ks_file >> $imgmount/KS.CFG" unless ($no_loop);
    if ( $arch eq 'i386' ) {
      &my_sys("$MKISOFS -o $custimg -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -r -publisher \"LinuxCOE / Hewlett Packard / http://linuxcoe.sourceforge.net\" -A \"LinuxCOE Boot Image\" -p LinuxCOE -J -V LinuxCOE -T $imgmount");
    } elsif ( $arch eq 'x86_64' ) {
      &my_sys("$MKISOFS -pad -o $custimg -b isolinux/isolinux.bin -c isolinux/boot.catalog -no-emul-boot -boot-load-size 4 -boot-info-table -r -publisher \"LinuxCOE / Hewlett Packard / http://linuxcoe.sourceforge.net\" -A \"LinuxCOE Boot Image\" -p LinuxCOE -J -V LinuxCOE -T $imgmount");
    }
  } else  {
# Prepend a depreciation warning on ks.cfg for newer redhats
    my $kswarn = $db->find_file("boot/ks.cfg.warning");
    system "/bin/cp $kswarn $imgmount/KS.CFG" if ($kswarn);
    print STDERR "/bin/cat $ks_file >> $imgmount/KS.CFG\n" if $debug;
    system  "/bin/cat $ks_file >> $imgmount/KS.CFG";
  }

# If it's an ISO and ia64, stick that bootable image and boot.catalog in a dir, mkisofs it...

  if (( $ISO ) && ( $arch eq 'ia64' )) {
    $db->boot_lipstick($imgmount,$distro,$version,$arch,$waystation,$method,$profile,$ip,$nm,$gw,$ns,$final_text,$parts,$msgtail,$interface,$hostname,$kbd,$mouse,$lang,$timezone,\@bundles,\@coe_bundles,$defs);
    $db->boot_lipstick("$imgmount/efi/boot",$distro,$version,$arch,$waystation,$method,$profile,$ip,$nm,$gw,$ns,$final_text,$parts,$msgtail,$interface,$hostname,$kbd,$mouse,$lang,$timezone,\@bundles,\@coe_bundles,$defs);
    &my_sys("$SUDO /bin/umount $imgmount") if ($mounted);
    $mounted = 0;
    &my_sys("/bin/cp $custimg $imgmount/boot.img");
    my $bootcat = $db->find_file("images/$distro-$version-ia64-boot.catalog");
    unless ($bootcat) {
      &end_it_now("Cannot find boot catalog for $distro-$version-$arch!");
    }
    &my_sys("/bin/cp $bootcat $imgmount/boot.catalog");
    system  "/bin/cat $ks_file >> $imgmount/KS.CFG";
    &my_sys("$MKISOFS -o $custimg -b boot.img -c boot.catalog -no-emul-boot -J -r -T -pad $imgmount");
  }

# If SIM is in play, make a tarball

  if ( $db->def('SIM') ) {
    my $simdir = $db->def('SIM');
    unless ( -d "$simdir/$serial") { mkdir "$simdir/$serial",0755 }
    &my_sys("/bin/ln -sf CUSTOM_SETTINGS $simdir/$serial/$serial");
    #set symlinks to the "real" directory
    foreach my $serial_sym (@serials){
      &my_sys("/bin/ln -sf $serial $simdir/$serial_sym");
      &my_sys("/bin/ln -sf CUSTOM_SETTINGS $simdir/$serial/$serial_sym");
    }
    $sys = "cd $imgmount && $TAR -cf $simdir/$serial/boot.tar *";
    &my_sys($sys);
  }

# Cleanup the mount

  &my_sys("$SUDO /bin/umount $imgmount") if ($mounted);
  $mounted = 0;
  &my_sys("/bin/rm -rf $imgmount");

} # End of Step2 - loopback filesys is mounted

sub Init {

# Kick off the interactive HTML stuff

  $htmlfile = "/scratch_monkey/id$$.html";
  my $iesux = 0;
  if (( $ENV{HTTP_USER_AGENT} =~ /MSIE/ ) || ( $ENV{HTTP_USER_AGENT} =~ /Konq/ )) {
    $qout->htmlfile("$htmlfile");
    $iesux = 1;
  }
  $htmlfile = "$docroot/scratch_monkey/id$$.html";
  $qout->title("Linux Install Image Creation");
  $qout->persist("Linux Install Image Creation - working<blink>.</blink>");
  $qout->message("Initalizing");
  $qout->kickstart();            

} # End if Init


sub check_pass {

# Validate root passwd, KISS here, non-null and the same

  my @passwd = $qin->param('Root_Pass');
  if ((! $passwd[0] ) || (! $passwd[1] )) {
    &end_it_now("You must enter a root password, and do it twice!");
  }
  unless ( $passwd[0] eq $passwd[1] ) {
    &end_it_now("Sorry, your two root passwords don't match!");
  }           
  my $upass;
  my @upass = $qin->param('User_Pass');
  if (( $qin->param('User_Name')) && ($upass[0] ne $upass[1] )) {
     &end_it_now("Sorry, your two mortal user passwords don't match!");
  } else {
    $upass = $upass[0];
  }
  return($passwd[0],$upass);

}

sub end_it_now {

# Exit with extreme predjudice

  if ( $mounted ) {
    system "$SUDO /bin/umount $imgmount";
  }
  if ( -f $custimg ) { unlink $custimg }
  if ( -f $ks_filename ) { unlink $ks_filename }
  my $errmsg = shift(@_);
  if ($replay) {
    print "START_OF_LINUXCOE_BEAM_DATA\nERR: $errmsg\nEND_OF_LINUXCOE_BEAM_DATA\n";
  }
  my $admin = $db->def('SITE_ADMIN');
  $errmsg .= "<hr>If this error message looks bogus, contact <a href=\"mailto:$admin>$admin</a>\n" if $admin;
  my $yikes = $db->err_msg;;
  if ( $db->def('FINAL_INTERACTIVE') ) {
    $qout->persist("$yikes A catastrophic error!");
    $qout->message("$errmsg");
    $qout->updatehtml(0);
  } else {
    print $qin->header;
    $db->ShowNav("$yikes A catastrophic error!");
    print "<h2>$yikes A catastrophic error!</h2>\n";
    print $errmsg;
    print $qin->end_html;
    $db->ShowFooter;
  }
  exit;

}    

sub my_sys {

  my $sys = shift;
  system $sys;
  print STDERR "$sys\n" if $debug;
  if ($?) {
    &end_it_now("$sys returned $!");
  }

}

sub coe_final {

# If it's ESX, do it and return (very little done on that distro)

  if ($distro =~ /^VMWare/ ) {
    &coe_final_esx;
    return;
  }

# Add LinuxCOE Bundles

  print KS "mkdir -p /etc/opt/LinuxCOE\n";

# Create a file with all the args we were called with
 
  foreach my $parm ($qin->param) {
    $qin->delete($parm) if ( $parm =~ /Pass/ );  # Skip plaintext passwords :)
  }
  if (open(PARMOUT,">$replay_file")) {
    $qin->save(\*PARMOUT);
    close(PARMOUT);
    print KS "cat >/etc/opt/LinuxCOE/replay <<REPLAY_TERMINATION\n";
    open(IN,"$replay_file");
    while(<IN>) { print KS }
    close(IN);
    unlink $replay_file;
    print KS "REPLAY_TERMINATION\n";
  } else {
    print STDERR "Cannot open PARMOUT ($replay_file) : $!\n";
  }

# What method do we use for SysDes patching?

  print KS "echo $patch_method >/etc/opt/LinuxCOE/patch_method\n";
  print KS "cat >/tmp/LinuxCOE.final <<LINUXCOE_FINAL_TERMINATION\n";
  print KS "# Install COE bundles\n\n";
  print KS "# Create holding dirs for COE info.\n";
  print KS qq[system "/bin/mkdir -p /etc/opt/LinuxCOE/apt.sources";\n];
  print KS qq[system "/bin/mkdir -p /etc/opt/LinuxCOE/yum.sources";\n];
  print KS qq[system "/bin/mkdir -p /etc/opt/LinuxCOE/sw";\n];
 
# Do they want patches @ install time?  If so, touch PATCH_ME

  if ( $patch_me ) {
    print KS qq[ open(PATCH,">/etc/opt/LinuxCOE/sw/PATCH_ME");\n];
    print KS qq[close(PATCH);\n];
  }

# Do they want continued patching?

  if (( $patch_freq ) && ( $patch_freq ne 'never' )) {
    print KS qq[open(OUT,">/etc/cron.${patch_freq}/apt_patch");
    print OUT qq{#!/bin/bash
/bin/touch /etc/opt/LinuxCOE/sw/PATCH_ME
/etc/rc.d/init.d/LinuxCOE-Bundles start
};
system "/bin/chmod +x /etc/cron.${patch_freq}/apt_patch";\n ];
  }

# Let's drop a little file with the tuple we were installed with
   
  print KS qq[open(OUT,">/etc/opt/LinuxCOE/INSTALLED");\n];
  print KS "print OUT qq[$distro $version $arch];\n";
  print KS "close(OUT);\n";

# Populate /etc/opt/LinuxCOE/apt.sources OR yum.sources with what we'll need
# OK, change, we'll use apt.sources to prime /etc/sysconfig/rhn/sources, so build the 
#   apt breadcrumb trail for APT's sources.list even if we're using YUM

# First do the base (OS and Patch Trees)

  my $t = $method;
  if (($t eq 'CDROM' ) || ($t eq 'NFS' )) {
     $t = $db->def('METHOD') || "HTTP";
  }
  $t = lc($t) . '://';
  my $infile = $db->find_file("depots/apt-$distro-$version-$arch");
  unless ($infile) { $infile = $db->find_file("depots/apt-$distro-$version") }
  unless ($infile) { $infile = $db->find_file("depots/apt-$distro") }
  if (open(SOURCES,"$infile")) {
    print KS qq[open(OUT,">/etc/opt/LinuxCOE/apt.sources/COE_BASE");\n];
    print KS "print OUT qq[";
    my $lines;
    while($lines = <SOURCES>) {
      $lines =~ s/\@METHOD\@/$t/g;
      $lines =~ s/\@WAYSTATION\@/$waystation/g;
      $lines =~ s/\@ARCH\@/$arch/g;
      $lines =~ s/\@DISTRO\@/$distro/g;
      $lines =~ s/\@VERSION\@/$version/g;
      print KS "$lines";
    }
    close(SOURCES);
    print KS "];\nclose(OUT);\n";
  }
  $infile = $db->find_file("depots/yum-$distro-$version-$arch");
  unless ($infile) { $infile = $db->find_file("depots/yum-$distro-$version") }
  unless ($infile) { $infile = $db->find_file("depots/yum-$distro") }
  if ( open(SOURCES,"$infile") ) {
    print KS qq[open(OUT,">/etc/opt/LinuxCOE/yum.sources/COE_BASE");\n];
    print KS "print OUT qq[";
    my $lines;
    while($lines = <SOURCES>) {
      $lines =~ s/\@METHOD\@/$t/g;
      $lines =~ s/\@WAYSTATION\@/$waystation/g;
      $lines =~ s/\@ARCH\@/$arch/g;
      $lines =~ s/\@DISTRO\@/$distro/g;
      $lines =~ s/\@VERSION\@/$version/g;
      print KS "$lines";
    }
    close(SOURCES);
    print KS "];\nclose(OUT);\n";
  }

# Then do additional depots/ADDONS

  my @NAMES = split(' ',$db->def('ADDONS'));
  foreach my $addon (@NAMES) {
    my ($config,$helpurl,$rpmapt,$debapt,$rpmyum,@needs) = $db->parse_addon_config($addon,$distro,$version,$arch);
    my ($d,$f,$count) = $db->parse_coe_bundles($arch,$distro,$version,$config);
    print STDERR "Addon $addon has $count entries for $distro $version $arch.\n" if $debug;
    next unless ($count);
    $rpmapt =~ s/\@METHOD\@/$t/g;
    $rpmapt =~ s/\@WAYSTATION\@/$waystation/g;
    $rpmapt =~ s/\@ARCH\@/$arch/g;
    $rpmapt =~ s/\@DISTRO\@/$distro/g;
    $rpmapt =~ s/\@VERSION\@/$version/g;
    print KS qq[open(OUT,">/etc/opt/LinuxCOE/apt.sources/$addon");
print OUT "$rpmapt";
close(OUT);
];
    if ( $YUM ) {
      $rpmyum =~ s/\@METHOD\@/$t/g;
      $rpmyum =~ s/\@WAYSTATION\@/$waystation/g;
      $rpmyum =~ s/\@ARCH\@/$arch/g;
      $rpmyum =~ s/\@DISTRO\@/$distro/g;
      $rpmyum =~ s/\@VERSION\@/$version/g;
      print KS qq[open(OUT,">/etc/opt/LinuxCOE/yum.sources/$addon");
print OUT "$rpmyum";
close(OUT);
];
    }
  }
                                                                                                                   
# Drop coe_bundle breadcrumbs in place and call installer.  

  my ($d,$f) = $db->parse_coe_bundles($arch, $distro, $version, 'ALL');
  foreach my $bundle (@coe_bundles) {
    print STDERR "coe_bundle_roller: I have bundle $bundle!\n" if $debug;
    print STDERR "coe_bundle_roller:   files: ${$f}{$bundle}!\n" if $debug;
    my @files = split(' ',${$f}{$bundle});
    my $archin = shift(@files);
    my $rpms = join(' ',@files);
    $bundle_error = 1 unless ($rpms);   # Bundle requested but does not exist
    my $name = $bundle;
    $bundle =~ tr/a-zA-z0-9/_/cs;
    print KS qq[open(OUT,">/etc/opt/LinuxCOE/sw/$bundle");
print OUT "$name\\n$rpms\\n";
close(OUT);
];
  }

# Create the actual final script (perl) that runs post install by slurping
#  in the skel file and poking BASE rpms in it

  my $skel = $db->find_file("data/final_skel");
  open(IN,"$skel") || &end_it_now("Error opening $skel : $!\n");
  while(<IN>) {
     # Stick in top of file
     last if /^# REAL_DATA_HERE/;
     next if /^#/;  # drop comments
     next if ( $_ eq "\n" ); # drop MT lines
     print KS;
  }
  print KS qq['WaYsTaTiOn' => "$waystation",\n];
  my %extra_rpms = $db->make_Base($method,$waystation,$distro,$version,$arch);
  foreach my $key (sort(keys(%extra_rpms))) {
    next unless ( $extra_rpms{$key} );
    print KS qq["$key" => "$extra_rpms{$key}",\n];
  }
  while(<IN>) {
     next if /^#/;  # drop comments
     next if ( $_ eq "\n" ); # drop MT lines
     print KS;
  }
  close(IN);
  print KS "LINUXCOE_FINAL_TERMINATION\n";
  print KS "/usr/bin/perl /tmp/LinuxCOE.final >/var/log/LinuxCOE.final.log 2>&1\n";

}

sub coe_final_esx {

# If there's a value add RPM for ESX, install it.  Typically vmktree/etc. is in there. For older 2.X
#  it's the actuall installer too (pcidivy, install modules, etc...)

  my $wayip = $db->get_ip($waystation);
  print KS qq{echo -e 'LinuxCOE $COE_VER VMWare $version post installation processing\\r\\n\\n' >/dev/tty1\n};
  print KS qq[echo -e 'Downloading needed binaries from waystation\\r' >/dev/tty1\n];
  my ($esx,$rel) = split('-',$version);
  print KS "rpm -iv http://${wayip}//LinuxCOE/HPCOE/$COE_VER/VMWare/ESX/$rel/i386/RPMS/esx_installer-${rel}-0.rpm\n";
  print KS "perl /tmp/coe_esx_nochroot_install.pl\n";
  print KS "grep -v LANG /etc/sysconfig/i18n >/tmp/i18n\n";
  print KS "echo LANG=C >/etc/sysconfig/i18n\n";
  print KS "cat /tmp/i18n >>/etc/sysconfig/i18n\n";
  #print KS "sleep 300\n"; # for screenshot

}

__END__

sub Reality_Check {
# For coe_express - no longer implemented, but might be brought back to life later
# It's an express, make sure things are kosher....
#  Make sure it's vended...
  my $os = $qin->param('os');
  my $waystation = $qin->param('waystation');
  my $method = $qin->param('method');
  my ($dist,$ver) = split(' ',$os);
  if ( defined $dbh ) {
    my $qdist = $dbh->quote($dist);
    my $qver = $dbh->quote($ver);
    my $qmeth = $dbh->quote($method);
    my $qway = $dbh->quote($waystation);
    my $sql = "select path from osvend where distro = $qdist and version = $qver and method = $qmeth ";
    $sql .= "and hostname = $qway";
    my $sth = $dbh->prepare($sql);
    $sth->execute;
    my $count = $sth->rows;
    $sth->finish;
    unless ($count) {
      my $msg = "<P>Sorry, $os is not vended from $waystation using $method!</P>";
      $msg .= "Please try again!";
      &end_it_now($msg);
    }
  }
}




See more files for this project here

LinuxCOE

The Linux Common Operating Environment (LinuxCOE) facilitates provisioning and lifecycle support of many popular Linux distributions, versions and architectures.

Project homepage: http://sourceforge.net/projects/linuxcoe
Programming language(s): JavaScript,Perl,Shell Script
License: gpl2

  Makefile.am
  Makefile.in
  README
  coe_bootimage.in
  coe_info.in
  coe_profiles.in
  coe_retrofit.in
  nph-coe_image.in
  nph-debian_image.in
  nph-mandriva_image.in
  nph-suse_image.in