nph-mandriva_image.in from LinuxCOE at Krugle
Show nph-mandriva_image.in syntax highlighted
#!/usr/bin/perl
##############################################################################################
# File: nph-mandrake_image
# Description: Build a kickstart image
# Author: Lee Mayes ( email leem@hp.com )
# Created: 30 Aug 2006
# Originally: nph-coe_image (then tweaked for Mandriva/auto_inst)
# Language: perl
# Package: LinuxCOE
##############################################################################################
# © Copyright 2000-2006 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 auto_inst.cfg file
# Step2 - Jam it into the bootimage and clean up
# Step3 - Copy auto_inst.cfg and boot image to their resting places
# 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);
}
$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 = "auto_inst$$.cfg"; # Custom auto_inst.cfg
my $ks_file = "$htmlpath/$ks_filename"; # Full path to auto_inst.cfg file
my $final_filename = "final$$"; # Custom final script
my $final_file = "$htmlpath/$final_filename"; # Full path to final file
my $ftp_dir = $db->def('FINAL_ABS_PATH'); # Where to it when I'm done
my $replay_file = "$htmlpath/replay$$"; # replay this web session later
my $age = 1800 || $db->def('AGE'); # Delete images older than $age seconds.e
my $custimg = "$htmlpath/img$$"; # Custom boot 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)
# What's avail in post processing?
if ( $qin->param('image') =~ /iso$/ ) { $ISO=1 }
my ($distro,$version) = split(' ',$db->clean_var($qin->param('os')));
my $arch = $db->clean_var($qin->param('arch'));
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;
# Drain the form and define variables for things needed globally
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 $wayip = $db->get_ip($waystation);
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";
###### MAIN #######
&Init; # start html
my ($passwd,$userpasswd) = &check_pass;
#if ( $qin->param('action') eq 'express' ) { &Reality_Check } # No longer implemented
&Step1; # Create auto_inst.cfg
&Step2; # Insert auto_inst.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 auto_inst file!!!!
print STDERR "Entering Step1\n" if $debug;
$qout->message("Creating auto_inst.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;
# 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");
# This looks kind of wierd, since we're writing a perl %array with perl...
my $datestr = localtime;
print KS qq[####################################################################################
# auto_inst.cfg - created by LinuxCOE System Designer at $datestr
# http://members.shaw.ca/mandrake/
####################################################################################
\$o = {\n];
# Networking info
print KS qq[
####################################################################################
# Networking parameters
####################################################################################
];
print KS qq[ 'intf' => {
'$interface' => {
'DEVICE' => '$interface',
'ONBOOT' => 'yes',
];
if ( $ip ) {
# STATIC
my ($nw,$bc) = $db->network_bcast($ip,$nm);
print KS qq[ 'BOOTPROTO' => 'static',
'IPADDR' => '$ip',
'NETMASK' => '$nm',
'NETWORK' => '$nw',
'BROADCAST' => '$bc',
];
} else {
# DHCP
print KS qq[ 'BOOTPROTO' => 'dhcp',\n];
}
print KS qq[ },
},
# Additional Network Parms
'netc' => {
'NETWORKING' => 'yes',
'FORWARD_IPV4' => 'false',
];
my $testname = $hostname || $system;
print KS qq[ 'HOSTNAME' => '$testname',\n] if ($testname);
if ($ip) {
print KS qq[ 'GATEWAY' => '$gw',
'GATEWAYDEV' => '$interface',
'dnsServer' => '$ns',\n];
}
print KS " },\n";
# Add Users
# Note, there is a perl module that provides this feature (Crypt::PasswdMD5). It's
# not part of base Perl installs so I'm forking mkpasswd to keep the code more
# portable.
# Also, on RHEL (so I assume Fedora/CentOS/etc.) mkpasswd can't do this, default to
# plaintext passwords as its mkpasswd just can't do a MD5 hash
my $good_mkpasswd = 1; # mkpassword works
my $have_crypt = 0; # user installed Crypt::PasswdMD5
# Test for Crypt::PasswdMD5 here
my $sys = "/usr/bin/mkpasswd -H MD5 test >/dev/null 2>&1";
system $sys;
if ($?) {
$good_mkpasswd = 0;
}
my ($encroot,$encuser);
my $uname = $qin->param('User_Name');
if ($good_mkpasswd) {
open(PASS,"/usr/bin/mkpasswd -H MD5 $passwd |");
$encroot = <PASS>;
close(PASS); wait;
chomp($encroot);
if ( $uname ) {
open(PASS,"/usr/bin/mkpasswd -H MD5 $userpasswd |");
$encuser = <PASS>;
close(PASS); wait;
chomp($encuser);
}
}
print KS qq[
####################################################################################
# User information
####################################################################################
'superuser' => {
'uid' => '0',
'gid' => '0',
'realname' => 'root',
'shell' => '/bin/bash',
'home' => '/root',
'icon' => 'root',
];
if ($good_mkpasswd) {
print KS qq[ 'pw' => '$encroot'\n];
} else {
print KS qq[ 'password' => '$passwd'\n];
}
print KS " },\n";
if ( $uname ) {
my $realname = $qin->param('Real_Name');
print KS " 'users' => [
{
'name' => '$uname',
'uid' => '5000',
'gid' => '5000',
'realname' => '$realname',
'shell' => '/bin/bash',
'home' => '/home/$uname',
'icon' => 'ic-bird',
'groups' => [],\n";
if ($good_mkpasswd) {
print KS qq[ 'pw' => '$encuser'\n];
} else {
print KS qq[ 'password' => '$userpasswd'\n];
}
print KS " }\n ],\n";
}
# Localizations
print KS qq[
####################################################################################
# Localizations
####################################################################################
];
# BUG - HARDCODED FOR US-ENGLISH ONLY AT THIS POINT!!!
my $utc = 0;
if ( $qin->param('utc') eq 'Yes' ) { $utc = 1 }
my $tz = $qin->param('timezone');
print KS qq[# Keyboard
'keyboard' => {
'GRP_TOGGLE' => '',
'KBCHARSET' => 'C',
'KEYBOARD' => 'us'
},
# Locale
'locale' => {
'lang' => 'en_US',
'langs' => {
'en_US' => 1,
},
'utf8' => ''
},
# Time
'timezone' => {
'UTC' => $utc,
'timezone' => '$tz'
},
];
# Some MISC stuff
print KS qq[
####################################################################################
# Misc. autoinstall parms
####################################################################################
];
my $proxy = $qin->param('proxy');
if ( $proxy ) {
$proxy = "'$proxy'";
} else {
$proxy = 'undef';
}
print KS qq[# Misc parms
# Reboot after install
'autoExitInstall' => 1,
# Authentication Parms
'authentication' => {
'shadow' => 1,
'md5' => 1,
'NIS' => undef,
'LDAP' => undef,
'winbind' => undef,
},
'isUpgrade' => 0,
'miscellaneous' => {
'numlock' => 1,
'HDPARM' => 1,
'http_proxy' => $proxy,
'ftp_proxy' => $proxy,
'track_network_id' => undef
},
# Let X probe for best picture
'X' => {
'resolution_wanted' => '1024x768',
'default_depth' => '32'
},
];
# Disk partitioning - BUG - simple only so far
my $device = $qin->param('Device');
$device =~ s/\/dev\///;
print KS qq[
####################################################################################
# Disk Partitioning/Bootloader
####################################################################################
];
print KS qq[# Partitioning
'partitioning' => {
'clearall' => 0,
'clear' => [ '$device' ],
'eraseBadPartitions' => 0,
'auto_allocate' => 1
},
];
# Layout what they want. Here's types:
# 131 (0x83) is ext2, 130 (0x82) is swap, 387 (0x183) is reiserfs, 1155 (0x483) is ext3.
my $part_choice = $qin->param('part_choice');
if ( $part_choice eq 'Simple' ) {
my %types = (
'ext2' => '0x83',
'ext3' => '0x483',
'reiserfs' => '0x183',
'swap' => '0x82',
);
print KS "# Simple Partitioning\n 'partitions' => [\n";
foreach my $i (0 .. 9) {
my $mount = $qin->param("mount$i");
if ($mount) {
my $type = $types{$qin->param("fstype$i")};
my $size = uc($qin->param("size$i"));
my $max = uc($qin->param("max$i"));
my $ratio = $qin->param("grow$i");
$size =~ s/M//;
$size =~ s/G/000/;
$size =~ s/T/000000/;
$size = $size * 2; # Spec in 512k sectors
# Max is in sectors
if ( $max ) {
$max =~ s/M//;
$max =~ s/G/000/;
$max =~ s/T/000000/;
$max = $max*2;
}
print KS " { 'mntpoint' => '$mount', 'type' => $type, size => $size,";
if ($max) { print KS " 'max' => $max," }
if ($ratio ) { print KS " 'ratio' => $ratio," }
print KS " 'hd' => '$device' },\n";
}
}
print KS " ],\n";
}
# Software Selections
print KS qq[
####################################################################################
# Software Selections
####################################################################################
];
if (@bundles) {
print KS " 'compssListLevel' => 5,\n";
print KS " 'compssUsersChoice' => {\n";
foreach my $bundle (@bundles) {
print KS "'$bundle' => 1, ";
}
print KS "\n },\n";
}
if ($rpms) {
print KS " 'default_packages' => [ ";
my @rpms = split(' ',$rpms);
foreach my $rpm (@rpms) {
print KS "'$rpm' ";
}
print KS "],\n";
}
# BUG - scripts not implemented yet
unless ($db->def('NO_COE')) {
&coe_final($patch_me,$patch_freq);
print KS qq[
####################################################################################
# Post install processing
####################################################################################
];
print KS "'postInstall' => qq`mkdir -p /opt/LinuxCOE/bin
# LinuxCOE post install processing\n";
open(IN,"$final_file") || &end_it_now("Cannot open $final_file for reading : $!\n");
while (<IN>) { print KS }
close(IN);
}
# Add User's Requested Final Script
print KS qq[echo "Autoinst-installed $distro $version - LinuxCOE Rev $COE_VER" > /etc/motd\n ];
if ( $final ) {
print KS "$final\n";
}
print KS "`,\n";
print KS "};\n";
} # End of Step1 - auto_inst.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 = 'MAND';
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,
);
my $serial = $qin->param('serial');
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 ( $ftp_dir =~ /\/$/ ) { chop($ftp_dir) } # Drop trailing / if it's there...
&my_sys("/bin/mv $ks_file ${ftp_dir}/$ks_filename") if ( "$ks_file" ne "${ftp_dir}/$ks_filename" );
&my_sys("/bin/mv $final_file ${ftp_dir}/$final_filename") if ( "$final_file" ne "${ftp_dir}/$final_filename" );
if ( $ISO ) {
&my_sys("/bin/mv $custimg ${ftp_dir}/img$$.iso") if ( "$custimg" ne "${ftp_dir}/img$$.iso");
$sum_this_image = "${ftp_dir}/img$$.iso";
} else {
&my_sys("/bin/mv $custimg ${ftp_dir}/img$$") if ( "$custimg" ne "${ftp_dir}/img$$");
$sum_this_image = "${ftp_dir}/img$$";
}
$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("Preparing for auto_inst.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-";
if (( $ISO ) && ( $arch ne 'ia64' )) {
$defimage .= 'iso.tar';
}
$defimage = $db->find_file("images/$defimage");
unless ( $defimage ) { &end_it_now("Cannot locate defimage for $distro-$version-$arch") }
my $sys = "$TAR -C $imgmount -xf $defimage";
&my_sys("$sys");
unless (( -f "$custimg" ) || ( $ISO )) {
&end_it_now("$custimg is not there?!?!?!");
}
$qout->message("Inserting auto_inst.cfg into boot image.");
$qout->updatehtml(1);
# If we have a syslinux.cfg and boot.msg, jam them in:
my $no_loop = $db->def('NO_LOOPMOUNT_KS_ISO');
&my_sys("/bin/chown -R $uid $imgmount");
my $infile = $db->find_file("boot/isolinux.mandriva");
unless (-r "$infile") {
&end_it_now("Cannot find isolinux.cfg file for Mandriva");
}
# Mandrake carries initial network/install stuff in syslinux
open(ISOIN,"$infile") || end_it_now("Error opening $infile for reading : $!\n");
open(ISOOUT,">$imgmount/isolinux.cfg") || end_it_now("Error opening $imgmount/isolinux.cfg for writing : $!\n");
print STDERR "Step2: Translating network parms into isolinux.cfg\n" if $debug;
# automatic=met:@METHOD@,interface:@INTERFACE@,ser:@WAYIP@,dir:@PATH@,netw:@NETWORK@
my $netstring;
if ( $ip ) {
$netstring = "static,ip:$ip,netm:$nm,gat:$gw,dns:$ns";
} else {
$netstring = 'dhcp';
}
my $lmeth = lc($method);
while(<ISOIN>) {
s/\@WAYIP\@/$wayip/;
s/\@INTERFACE\@/$interface/;
s/\@PATH\@/$path/;
s/\@METHOD\@/$lmeth/;
s/\@NETWORK\@/$netstring/;
print ISOOUT;
}
close(ISOOUT); close(ISOIN);
my $kbd=$qin->param('kbd');
my $mouse=$qin->param('mouse');
my $lang=$qin->param('lang');
my $timezone=$qin->param('timezone');
$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);
# Put the ks.cfg file into initrd.img
&my_sys("/bin/cp $ks_file $imgmount/auto_inst.cfg");
&my_sys("/bin/cp $imgmount/alt0/all.rdz $htmlpath/initrd$$.img.gz");
# this tosses an error...
#&my_sys("$GUNZIP $htmlpath/initrd$$.img.gz"); # Uncompress CPIO image
system("$GUNZIP $htmlpath/initrd$$.img.gz"); # Uncompress CPIO image
mkdir("$initrdmount",0766) || &end_it_now("Cannot mkdir $initrdmount : $!\n");
if ( $db->is_filesys_initrd($distro,$version,$arch) ) {
my $uid = $>; # What's my UID
umask 000;
&my_sys("$SUDO mount -oloop,user,rw $htmlpath/initrd$$.img $initrdmount");
&my_sys("$SUDO /bin/cp $ks_file $initrdmount/auto_inst.cfg"); # Poke in ks.cfg
unless ( $db->def("NO_COE") ) {
&my_sys("$SUDO /bin/cp $final_file $initrdmount/LinuxCOE.final"); # Poke in final
&my_sys("$SUDO /bin/cp $replay_file $initrdmount/replay"); # Poke in replay
}
&my_sys("$SUDO umount $initrdmount");
&my_sys("$GZIP -c --best $htmlpath/initrd$$.img >$imgmount/alt0/all.rdz");
} else {
&my_sys("cd $initrdmount; $CPIO -i <$htmlpath/initrd$$.img"); # Extract CPIO image
&my_sys("/bin/cp $ks_file $initrdmount/auto_inst.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 >$imgmount/alt0/all.rdz"); # Compress it back
unlink "$htmlpath/initrd$$.img";
}
# Make the ISO
&my_sys("$MKISOFS -o $custimg -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -r -A \"LinuxCOE Boot Image\" -p LinuxCOE -J -V LinuxCOE -T $imgmount");
# Cleanup the mount
&my_sys("/bin/rm -rf $initrdmount");
unlink "$htmlpath/initrd$$.img";
&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(@_);
my $admin = $db->defs('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 {
open(FINAL,">$final_file") || &end_it_now("Cannot open $final_file for writing : $!\n");
print STDERR "Opened $final_file for writing\n" if $debug;
# Add LinuxCOE Bundles
print FINAL "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);
} else {
print STDERR "Cannot open PARMOUT ($replay_file) : $!\n";
}
# What method do we use for SysDes patching?
print FINAL "echo $patch_method >/etc/opt/LinuxCOE/patch_method\n";
print FINAL "cat >/opt/LinuxCOE/bin/LinuxCOE-final <<LINUXCOE_FINAL_TERMINATION\n";
print FINAL "# Install COE bundles\n\n";
print FINAL "# Create holding dirs for COE info.\n";
print FINAL qq[system "/bin/mkdir -p /etc/opt/LinuxCOE/apt.sources";\n];
print FINAL qq[system "/bin/mkdir -p /etc/opt/LinuxCOE/yum.sources";\n];
print FINAL 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 FINAL qq[ open(PATCH,">/etc/opt/LinuxCOE/sw/PATCH_ME");\n];
print FINAL qq[close(PATCH);\n];
}
# Do they want continued patching?
if (( $patch_freq ) && ( $patch_freq ne 'never' )) {
print FINAL 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 FINAL qq[open(OUT,">/etc/opt/LinuxCOE/INSTALLED");\n];
print FINAL "print OUT qq[$distro $version $arch];\n";
print FINAL "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 FINAL qq[open(OUT,">/etc/opt/LinuxCOE/apt.sources/COE_BASE");\n];
print FINAL "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 FINAL "$lines";
}
close(SOURCES);
print FINAL "];\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 FINAL qq[open(OUT,">/etc/opt/LinuxCOE/yum.sources/COE_BASE");\n];
print FINAL "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 FINAL "$lines";
}
close(SOURCES);
print FINAL "];\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 FINAL 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 FINAL 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 FINAL 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/mandriva_final_skel");
open(IN,"$skel") || &end_it_now("Error opening $skel : $!\n");
while(<IN>) {
s/\$/\\\\\$/g;
# Stick in top of file
last if /^# REAL_DATA_HERE/;
next if /^#/; # drop comments
next if ( $_ eq "\n" ); # drop MT lines
print FINAL;
}
print FINAL 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 FINAL qq["$key" => "$extra_rpms{$key}",\n];
}
while(<IN>) {
s/\$/\\\\\$/g;
next if /^#/; # drop comments
next if ( $_ eq "\n" ); # drop MT lines
print FINAL;
}
print FINAL "LINUXCOE_FINAL_TERMINATION\n";
print FINAL "/usr/bin/perl /opt/LinuxCOE/bin/LinuxCOE-final >/var/log/LinuxCOE-final.log 2>&1\n";
close(IN);
close(FINAL);
}
__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