Code Search for Developers
 
 
  

coe_bootimage.in from LinuxCOE at Krugle


Show coe_bootimage.in syntax highlighted

#!/usr/bin/perl
##############################################################################################
#
# File:         coe_bootimage
# Description:  Gather all the info needed to create an install 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.
##############################################################################################
# Basic process flow
# Step 1 - hostname/distro
# Step 1b - Make 'em click through a EULA/warning if wanted
# Step 2 - method/profile - [optional if hostname]  Network fields
# Step 3 - Source if not CDROM, Localization - keybd, TZ, mouse
# Step 4a - Custom packages
# Step 4b - Custom disk partitioning
# Step 5 - Display ALL stuff for final verification, prompt for root passwd
# Step 6 - Just Do It! (in script nph-coe_image/debian_image/suse_image)
##############################################################################################

use strict;
use CGI;
use lib qw (@prefix@/lib);
use LinuxCOE;   # All our common stuff
my $debug = 0;  # Verbose output in SysDes Logfile
my $nonav = 0;  # No Portal lipstick

my $q = new CGI ();
my $db = new LinuxCOE;
$db->debug($debug);
$db->nonav($nonav);
my $COE_VER = $db->def('COE_VER');
my $cgi='/@PACKAGE_NAME@-cgi-bin/coe_bootimage';
my $defs = $db->clean_var($q->param('defs'));
if ( $defs ) {
  print STDERR "bootimage calling LoadDefs($defs)\n";
  $db->LoadDefs($defs);
  $cgi .= "?defs=$defs";
}
$db->InitDB;
my $default = $db->def('DIST');
$default .= " - " . $db->def('ARCH');
my $docroot = $db->docroot;


# Snag some of craiger's markup
my $tdtag = $db->tdtag;
my $thtag = $db->thtag;
my $tdfont = $db->tdfont;
my $thfont = $db->thfont;

# Are we a redirect?
my $parmfile = $q->param('sysdes_parms');
if ( $parmfile ) {
  print STDERR "Trying new CGI with parmfile = $parmfile\n" if $debug;
  open(PARMIN,"$docroot/scratch_monkey/$parmfile") || die "could not open PARMIN\n";
  $q = new CGI(\*PARMIN);
  close(PARMIN);
  unlink "$docroot/scratch_monkey/$parmfile" unless $debug;
}

# Require SSL?

my $sec_level = $db->def('SECURITY_LEVEL');
my $host = `/bin/hostname`;
chomp $host;
my $securehost = $db->def('SSLHOST') || (gethostbyname($host))[0];
my $defhost =  $db->def('HOSTNAME') || (gethostbyname($host))[0];
my $url = $q->self_url;
my $part_choice = $q->param('part_choice');
my $profile = $q->param('profile');
my $action = $q->param('action');
if (( $url =~ /http:/ ) && ( ( $sec_level eq 'SECURE' ) || 
                             (($sec_level eq 'NORMAL') && ( $action eq '5' )) || 
                             (($sec_level eq 'NORMAL') && ( $action eq '4a') && ($part_choice eq 'NONE')) ||
                             (($sec_level eq 'NORMAL') && ( $action eq '4') && ($profile ne 'Custom')) )) {
  open(PARMOUT,">$docroot/scratch_monkey/parms$$") || die "Cannot open PARMOUT ($docroot/scratch_monkey/parm$$) : $!\n";
  $q->save(\*PARMOUT);
  close(\*PARMOUT);
  if ( $defs ) {
    $url = "https://${securehost}$cgi&"
  } else {
    $url = "https://${securehost}$cgi?";
  }
  $url .= "sysdes_parms=parms$$";
  print $q->redirect($url);
  exit;
} else {
  print $q->header;
}


# Here's the variables we'll keep track of screen to screen in <HIDDEN> tags

my @vars = qw(system hostname ip method profile os waystation netmask parts part_choice ddisk
              defs misc rpms kbd lang timezone mouse gateway namesvr utc bundles netdev coe_bundles 
	      laptop arch sources nosafe image patch_me patch_freq Device asset base override
              patch_method esxkey esxcpukey proxy serial);

# This is what you see vs. the real variable name...
my %varname = (
  'system' => 'Hostname or IP',
  'asset' => 'Asset ID',
  'arch' => 'Architecture',
  'profile' => 'System Profile',
  'method' => 'Install Method',
  'os' => 'Distro, Rev, and Arch',
  'proxy' => 'Proxy Server',
  'netmask' => 'Subnet Mask',
  'namesvr' => 'Name Server',
  'gateway' => 'Gateway',
  'waystation' => 'COE Waystation',
  'netdev' => 'Network Interface',
  'NFS' => 'NFS - NFS mount a waystation and install from there',
  'FTP' => 'FTP - Anonymous FTP',
  'HTTP' => 'HTTP -  Preferred method for network installs',
);

# This is the overlib help text, however, it crashes netscape on resize if enabled :( - so it's disabled for now...
my %help = ( 

  'system' => qq[Leave this field blank for full time DHCP.  If you enter a hostname, it <B>MUST</B> be DNS resolvable, so please fully qualify it. Raw IP addresses, not in DNS, are also OK.],
  'profile' => qq[These are user owned profiles defining what software to install and how to partition your hard drives.<br>Custom lets you interactively select these options.<br>Do not use a profile unless you are sure, it contains disk partitioning information! ],
  'method' => qq[These are the supported installation methods for your chosen distribution, version, and architecture.],
  'os' => qq[Current Linux Distrbutions vended via LinuxCOE Waystations],

);

my $ov1 = qq[<A HREF="javascript:void(0);"  onMouseOut="nd();" onMouseOver="overlib('];
#my $ov2 = qq[',HEIGHT, 40, LEFT, ABOVE, SNAPX, 10, SNAPY, 10)">];
my $ov2 = qq[')">];  #'
my $ov3 = qq[</A>];

my %labels;
foreach my $var (@vars) {

  if ( ($help{$var}) && (! $db->def('NO_OV') ) ) {
    $labels{$var} = $ov1 . $help{$var} . $ov2 . $varname{$var} . $ov3;
  } else {
    $labels{$var} = $varname{$var} || $var;
  }

}

####### MAIN ########
if    (! $action )     { &Step1 }
elsif ($action eq '2') { &Step2 }
elsif ($action eq '3') { &Step3 }
elsif ($action eq '4') { &Step4 }
elsif ($action eq '4a') { &Step4a }
elsif ($action eq '5') { &Step5 }
elsif ($action eq 'replay' ) { &Replay }
else {  $db->end_it_now("Action == $action, Say what???") }
####### End of MAIN ########

sub Replay {

  my $title = "Replay a LinuxCOE $COE_VER Install";
  $db->ShowNav($title);
  $title .= " - <font color=red>$defs</font>" if ($defs);
  &do_ov;
  print $q->h4($title);
  print $q->start_multipart_form(-action=>$cgi);
  $q->delete('action');
  &do_hidden;
  print $q->hidden(-name=>'action', -default=>'5'),"\n";       
  print $q->h3("Upload your replay file:");
  print qq[<TABLE BORDER=0>
<TR>
 <TD #tdtag><FONT $tdfont>Upload replay</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT TYPE="file" NAME="replay" SIZE=50></FONT></TD>
</TR>
</TABLE>
];
  print $q->submit(-value=>'Continue');
  print $q->end_form;
  print $q->end_html;
  $db->ShowFooter;
  exit;

}

sub Step4a {

# Present a page with paritioning choices... (Simple or Advanced)
# Simple is some little fields and checkboxes for grow and  I will
# distro default bootloader/etc. on you
# Advanced dumps a textarea for expert users

  my $part_choice = $q->param('part_choice');
  if ( $part_choice eq 'NONE' ) { &Step5; }
  my $timezone = &reqd('timezone');
  my $os = $db->clean_var($q->param('os'));
  my ($distro,$ver) = split(' ',$os);
  my $arch = $db->clean_var($q->param('arch'));
  my $title = "Create a LinuxCOE $COE_VER $os $arch Install Image, Step 4a - Define disk layout";
  $db->ShowNav($title);
  $title .= " - <font color=red>$defs</font>" if ($defs);
  &do_ov;
  print $q->h4($title);
  print $q->start_form(-action=>$cgi);
  $q->delete('action');
  &do_hidden;
  print $q->hidden(-name=>'action', -default=>'5'),"\n";       
  print $q->h3("Layout your disk scheme:");
  my $disk = $q->param('part_choice');
  my $diskdata = $db->find_file("data/disk_data");
  my %choices;
  unless (open(DISKDATA,$diskdata)) {
    &end_it_now("Cannot open disk info file (data/disk_data) : $!\n");
  }
  while(<DISKDATA>) {
    chomp;
    next if /^#/;
    next unless $_;
    my ($dev,@desc) = split;
    $choices{$dev} = join(' ',@desc);
  }
  close(DISKDATA);
  my @choices = sort(keys(%choices));
  my $ddefault = $db->def('DEF_DISK') || '/dev/hda';
  my ($parts,$misc,@dont_care);
  if ( $q->param('override') ) { 
     $disk = 'Advanced';
     ($parts,$misc,@dont_care) = $db->parse_profile($q->param('profile'),$arch,$ver,$distro);
  } else {
    $parts = $db->make_default_parts($os,$arch);
    $misc = $db->make_default_misc($os,$arch);
  }
  if ( $disk eq 'Advanced' ) {
    $db->Display_Disk_Partition($os,$arch,$parts);
    if ((!($os =~ /Debian/)) && (!($os =~ /buntu/)))  {
      $db->Display_Misc_Box($os,$arch,$misc);
    }
  } elsif (( $disk eq 'Autopartition' ) || ( $disk eq 'Multi-user workstation' ) || ( $disk eq 'Desktop Machine' )) {
# It's SuSE || preseed, pick a hard drive to nuke
    print "<h3>Allow $os to consume this drive using theme $disk:</h3>\n";
    print "<SELECT NAME='parts'>";
    foreach my $choice (@choices) {
      if ($choice eq $ddefault) { print "<OPTION SELECTED VALUE='$choice'>$choices{$choice}\n" }
      else { print "<OPTION VALUE='$choice'>$choices{$choice}\n" }
    }
    print "</SELECT> - <B>REQUIRED!</B></P>\n";
  } else {
    if (($distro =~ /^Mand/ ) || ( $distro =~ /SuSE/i ) || ( $os =~ /Debian/ ) || ( $os =~ /buntu/ )) {
      print "<P><B>Select a drive to partition</B>: ";
      print "<SELECT NAME='Device'>";
      foreach my $choice (@choices) {
        if ($choice eq $ddefault) { print "<OPTION SELECTED VALUE='$choice'>$choices{$choice}\n" }
        else { print "<OPTION VALUE='$choice'>$choices{$choice}\n" }
      }
      print "</SELECT> - <B>REQUIRED!</B></P>\n";
    }
    my ($code,$sparts);
    $sparts = $db->find_file("data/sparts-$distro-$ver-$arch");
    unless ( $sparts ) { $sparts = $db->find_file("data/sparts-$distro-$ver") }
    unless ( $sparts ) { $sparts = $db->find_file("data/sparts-$distro") }
    unless ( $sparts ) { &end_it_now("Cannot find simple partition template for $distro-$ver-$arch") }
    open (IN,"$sparts");
    { local $/; $code = <IN>};     
    close(IN);
    eval $code;           
     
  }
  print $q->p,$q->submit(-value=>'Continue');    
  print $q->end_form;
  print $q->end_html;
  $db->ShowFooter;
  exit;

} # End of Step4a

sub Step4 {

# If we're not doing CDROM, they MUST specify a waystation

  my $method = $q->param('method');
  if ( $method ne 'CDROM' ) {
    &reqd('waystation');
  }

# Check profile

  my $profile = $q->param('profile');
  my $os = $db->clean_var($q->param('os'));
  my $arch = $db->clean_var($q->param('arch'));
  my ($distro,$version) = split(' ',$os);

# If it's recent ESX, snag and format license keys

  if (( $distro eq 'VMWare' ) && (( $version eq 'ESX-2.5.2' ) || ( $version eq 'ESX-2.5.3' ) || ( $version eq 'ESX-2.5.4' )) ) {
    my $esxkey = &reqd('esxkey');
    $esxkey =~ s/\ *//g;  # nuke spaces
    $q->delete('esxkey');
    $q->param('esxkey',$esxkey);
    my $esxcpukey = $q->param('esxcpukey');
    $esxcpukey =~  s/\ *//g;  # nuke spaces
    $q->delete('esxcpukey');
    $q->param('esxcpukey',$esxcpukey);
  } 


# If it's a canned profile, advance to step 5, otherwise, show choices...

  if ( $profile ne 'Custom' ) { 
     my $override = $q->param('override');
     &Step5 unless ( $override eq 'YES' );
     &Step4a;  # Re-prompt for disk/misc info
  } 


# Present a page with bundle choices...

  my $title = "Create a LinuxCOE $COE_VER $os $arch Install Image, Step 4 - Pick $os Bundles";
  $db->ShowNav($title);
  &do_ov;
  $title .= " - <font color=red>$defs</font>" if ($defs);
  print $q->h4($title);
  print $q->start_form(-action=>$cgi,-name=>'form');
  $q->delete('action');
  &do_hidden;
  print $q->hidden(-name=>'action', -default=>'4a'),"\n";       
  $db->Check_Me;
  print $q->h3("Software package selection");
  print "\n<table>\n<tr>\n\n<td valign=top><font size=2>\n";
  $db->Display_Bundles($os,$arch);
  print "</font></td>\n<td valign=top><font size=2>\n";
  $db->Display_RPMS($os);
  print "\n</font></td></tr>\n";
  print "</table>\n";

# Display addon selections (not supported for ESX)

  if (( $distro ne 'VMWare' ) && (! $db->def('NO_COE') )){ 
    my @NAMES = split(' ',$db->def('ADDONS'));
    foreach my $NAME (@NAMES) {
      $db->Display_COE_Bundles($os,$arch,undef,$NAME);
    }
    $db->Show_Patch($distro,$version,0,'',$arch) unless $db->def('NO_COE');
  }
  if (( $os =~ 'Debian' ) || ( $os =~ /buntu/ )) {
    print '<h3>Choose <a target="help" href="http://www.us.debian.org/releases/stable/i386/ch06s03.html.en#di-partition">disk partitioning method</a> additional options</h3>';
  } else {
    print $q->h3("Choose disk partitioning method and additional options");
  }
  my %disk = (
    'Autopartition' => " Autopartition - just swap and / on this drive",
    'Simple' => " Simple - $os will consume your disk drives",
    'Advanced' => " Advanced - Let's you fully customize your disks and other available installation options",
    'NONE' => ' None - I want to do this interactively during install - good for multi-boot/pre-existing OS',
    'Desktop Machine' => ' Desktop Machine (as defined by Debian installer)',
    'Multi-user workstation' => ' Multi-user workstation (as defined by Debian installer)',
  );
  my ($default,@choices);
  if ( $os =~ /Suse/i ) {
    $default = 'Simple';
    @choices = qw(Autopartition Simple);
  } elsif (( $os =~ /3.1/ ) || ( $os =~ /Dapper/ )) {
    $default = 'Autopartition';
    @choices = ('Autopartition','NONE');
  } elsif (( $os =~ /Debian/ ) || ( $os =~ /buntu/ )) {
    $default = 'Autopartition';
    @choices = ('Autopartition','Desktop Machine','Multi-user workstation','NONE');
  } elsif ( ($distro eq 'VMWare' ) && ( $version ge 'ESX-2.5.1' )) {
    $default = 'Advanced';
    @choices = qw(Advanced);
  } else {
    $default = 'Simple';
    @choices = qw(NONE Simple Advanced);
  }
  print $q->radio_group(-name=>'part_choice',
                               -values=>\@choices,
                               -default=>$default,
                               -linebreak=>'true',
                               -labels=>\%disk);
  print $q->submit(-value=>'Continue');    
  print $q->end_form;
  print $q->end_html;
  $db->ShowFooter;
  exit;

} # End of Step4a


sub Step5 {

  if ($q->param('replay')) {
# Replay in progress, slurp in parms from file
    my $uphandle = $q->upload('replay');
    open(PARMOUT,">$docroot/scratch_monkey/parms$$") || die "Cannot open PARMOUT ($docroot/scratch_monkey/parm$$) : $!\n";
    while(<$uphandle>) { print PARMOUT }
    close(\*PARMOUT);
    open(PARMOUT,"$docroot/scratch_monkey/parms$$") || die "Cannot open PARMOUT ($docroot/scratch_monkey/parm$$) : $!\n";
    $q = new CGI(\*PARMOUT);
    unlink "$docroot/scratch_monkey/parms$$";
  }
# Reality check needed vars

  my $os = $db->clean_var($q->param('os'));
  my $arch = $db->clean_var($q->param('arch'));
  my ($dist,$ver) = split(' ',$os);
  my $profile = $q->param('profile');
  my $timezone = &reqd('timezone');
  my $mandrake_simple;
 
  if ( $profile eq 'Custom' ) {

# If it's custom, validate their disk partitioning
  
    my ($parts,@parts,,$phys,$log);
    if (( $q->param('part_choice') eq 'Advanced' ) || ( $q->param('part_choice') eq 'Autopartition' )) {

# It's Advanced partitioning, just pass thru to nph_whatever

      $parts .= $q->param('parts');

    } elsif ( $q->param('part_choice') eq 'None' ) {
      undef($parts);
    } else {

      if (( $os =~ /Debian/ ) || ( $os =~ /buntu/ )) {
        &preseed_part;
      } elsif ( $os =~ /^Mand/ ) {
        # If Simple config, just throw it @ nph-mandrake
	for my $i (0 .. 9) {
	  if ( $q->param("mount$i") ) {
	    for my $fsvar qw(mount size max grow fstype) {
	      my $vname = "${fsvar}${i}";
	      $mandrake_simple .= $q->hidden(-name=>"$vname", -default=>$q->param($vname))."\n";
	    }
	  }
	}
      } else {

# If you're here, it's ks.cfg

        $parts = $q->param('partdefs') . "\n";
        foreach my $i ( 0 .. 9 ) {
          my $mount = $q->param("mount$i");
          next unless ($mount);
          my $size = $q->param("size$i");
          my $max = $q->param("max$i");
          my $type = $q->param("fstype$i");
          $size = uc($size);
          $size =~ s/M//;
          $size =~ s/G/000/;
          $max = uc($max);
          $max =~ s/G/000/;
          $max =~ s/M//;   
          unless ( $size ) {
            $db->end_it_now("Mountpoint $mount has invalid size!");
          }
          my $grow = $q->param("grow$i");
          my $line = "part $mount --size $size ";   
          if ( $grow ) {  $line .= "--grow " }
          if ( $max ) { $line .= "--maxsize $max " }   
          if ( $type ) { $line .= "--fstype $type" }
          $parts .= "$line\n";
        }  # end of foreach part
      } # End of not debian 3.1
    } # End of if simple config

# Just a stub right now

    unless ( $db->validate_parts($parts) ) {
      $db->end_it_now($db->errmsg);
    }

# Add auth line to 'simple' configs kickstart configs

    $q->param('parts',$parts);
    $q->param('auth',"auth --enablemd5 --useshadow");

  } # End of disk tweaker

# Just hurl all the stuff they already picked so they can look it over

  my $method = $q->param('method');
  my $waystation = $q->param('waystation');
  my ($owner,$passwd,$path) = $db->profile_details($dist,$ver,$arch,$profile);
  $path = $db->show_os($dist,$ver,$arch,$method,$waystation);     
  my $laptop;
  if ( $q->param('laptop') )  { $laptop = "Yes" } else { $laptop = "No" }

  my $title = "Create a LinuxCOE $COE_VER $os $arch Install Image, Step 5 - Confirm your intentions";
  $db->ShowNav($title);
  $title .= " - <font color=red>$defs</font>" if ($defs);
  &do_ov;
  print $q->h4($title);
  my $urltag = "?defs=$defs" if ($defs);
  my %urlbase;
  my $mapfile = $db->find_file("data/image_gen.map");
  unless (-r $mapfile) {
    &end_it_now("Cannot locate distro->image generator mapfile 'data/image_gen.map'!");
  }
  open(MAP,$mapfile) || &end_it_now("Cannot open $mapfile : $!\n");
  while(<MAP>) {
    chomp;
    next if /^#/;
    next unless $_;
    my ($key,$val) = split;
    $urlbase{$key} = $val;
  }
  close(MAP);
  my $gen_url = $urlbase{$dist};
  unless ($gen_url) {
    &end_it_now("I cannot determine which final script to call for distro $dist!<p>Please check the contents and validity of data/image_gen.map");
  }
  unless ( $db->def('FINAL_INTERACTIVE') ) { $gen_url =~ s/nph/nonph/ } 
  print $q->start_form('POST',"/@PACKAGE_NAME@-cgi-bin/$gen_url",'');
  my $parts = $q->param('parts');		
  $parts = $q->escape($parts);  # Prepare to hide this
  my $misc = $q->param('misc');
  $misc = $q->escape($misc);  # Prepare to hide this
  print $q->hidden(-name=>'parts', -default=>$parts)."\n"; # Treat parts/misc special (needs to be escaped)
  print $q->hidden(-name=>'misc', -default=>$misc)."\n"; 
  &do_hidden;
  print $mandrake_simple if ($mandrake_simple);

  if ( $dist =~ /SuSE/i ) {

# It's SuSE - just toss values for now 

    foreach my $i ( 0 .. 9 ) {
      last unless ( $q->param("mount$i") );
      if ( $q->param("mount$i") ) {
         foreach my $var qw (mount size fstype grow) {
           print $q->hidden(-name=>"${var}$i", -default=>$q->param("${var}$i")),"\n";
         }
      } 
    }

  }

  print "Here is your data as entered, please confirm:<BR>\n";
  print qq[<TABLE BORDER=1>
<TR>
 <TH $thtag COLSPAN=2 ALIGN=LEFT><FONT $thfont>General</FONT></TH>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>Distro - Arch - Profile</FONT></TD>
 <TD $tdtag><FONT $tdfont>$os - $arch - $profile</FONT></TD>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>Method</FONT></TD>
 <TD $tdtag><FONT $tdfont>];
  if ( $method ne 'CDROM' ) {
    print "$method";
    print "</FONT></TD>\n</TR>\n<TR>\n <TD $tdtag><FONT $tdfont>Path</TD>\n <TD $tdtag><FONT $tdfont>$waystation:$path";
  } else {
    print "Local CD(s)";
  }
  print qq[</FONT></TD>
</TR>
<TR>
 <TH $thtag COLSPAN=2 ALIGN=LEFT><FONT $thfont>Network</FONT></TH>
</TR>
];
  if ( $q->param('ip') ) {
    my $gw = $q->param('gateway');
    unless ( $gw ) {
      $gw = $q->param('ip');
    }
    print "<TR>\n <TD $tdtag><FONT $tdfont>Hostname</FONT></TD><TD $tdtag><FONT $tdfont>".$q->param('hostname') || "<BR>" ."</TD>\n</TR>\n"; 
    print "<TR>\n <TD $tdtag><FONT $tdfont>IP</FONT></TD>\n <TD $tdtag><FONT $tdfont>".$q->param('ip')."</TD>\n</TR>\n"; 
    print "<TR>\n <TD $tdtag><FONT $tdfont>$labels{'netmask'}</FONT></TD>\n <TD $tdtag><FONT $tdfont>".$q->param('netmask')."</TD>\n</TR>\n"; 
    print "<TR>\n <TD $tdtag><FONT $tdfont>$labels{'namesvr'}</FONT></TD>\n <TD $tdtag><FONT $tdfont>".$q->param('namesvr')."</TD>\n</TR>\n"; 
    print "<TR>\n <TD $tdtag><FONT $tdfont>$labels{'gateway'}</FONT></TD>\n <TD $tdtag><FONT $tdfont>$gw</TD>\n</TR>\n"; 
    if (( $ver ge '7.0' ) && ( !($os =~ /Debian/) ) && ( !($os =~ /buntu/)) ) {
      my $netdev = $q->param('netdev');
      print "<TR>\n <TD $tdtag><FONT $tdfont>$labels{'netdev'}</FONT></TD>\n <TD $tdtag><FONT $tdfont>$netdev</TD>\n</TR>\n"; 
    }
  } else {
    print "<TR>\n <TH $thtag COLSPAN=2><FONT $thfont>ALWAYS USE DHCP</FONT></TH>\n</TR>\n";
    if ( $q->param('system') ) {
      print "<TR>\n <TD $tdtag><FONT $tdfont>Request Hostname</FONT></TD><TD $tdtag><FONT $tdfont>".$q->param('system') || "<BR>" ."</TD>\n</TR>\n";
    }
  }
  #  kbd lang timezone mouse
  if (! (($os =~ /Debian/ ) || ($os =~ /buntu/ ))) {
    my $kbd = $q->param('kbd');
    my $lang = $q->param('lang');
    my $mouse = $q->param('mouse');
  
    print qq[<TR>
 <TH $thtag COLSPAN=2 ALIGN=LEFT><FONT $thfont>Localizations</FONT></TH>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>Language</FONT></TD>
 <TD $tdtag><FONT $tdfont>$lang</FONT></TD>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>Keyboard</FONT></TD>
 <TD $tdtag><FONT $tdfont>$kbd</FONT></TD>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>Mouse</FONT></TD>
 <TD $tdtag><FONT $tdfont>$mouse</FONT></TD>
</TR>
];
  }
  if (( $dist eq 'VMWare' ) && (( $ver eq 'ESX-2.5.2' ) || ( $ver eq 'ESX-2.5.3' ) || ( $ver eq 'ESX-2.5.4' )) ) {
    my $esxkey = $q->param('esxkey');
    my $esxcpukey = $q->param('esxcpukey');
    print qq[
<TR>
 <TD $tdtag><FONT $tdfont>ESX Key</FONT></TD>
 <TD $tdtag><FONT $tdfont>$esxkey</FONT></TD>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>ESX SMP Key</FONT></TD>
 <TD $tdtag><FONT $tdfont>$esxcpukey</FONT></TD>
</TR>
];
  }
  my $rec = 'Recommended';
  if (( $os =~ /Debian/ ) || ( $os =~ /buntu/ )) { $rec = 'REQUIRED or you will be prompted interactively!' }
  print qq[<TR>
 <TD $tdtag><FONT $tdfont>TimeZone</FONT></TD>
 <TD $tdtag><FONT $tdfont>$timezone</FONT></TD>
</TR>
];
  unless ( $os =~ /buntu/ ) {
    print qq[<TR>
 <TH $thtag COLSPAN=2 ALIGN=LEFT><FONT $thfont>Set root's post-installation password - REQUIRED!</FONT>];
    if ($db->def("PASS_WARN")) {
      print "<BR><FONT $tdfont>" . $db->def("PASS_WARN") . "</FONT>";
    }
    print qq[</TH>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>Enter root password:</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT NAME="Root_Pass" SIZE=8 MAXLENGTH=8 TYPE="PASSWORD"> - 8 characters MAX!</FONT></TD>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>Confirm root password:</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT NAME="Root_Pass" SIZE=8 MAXLENGTH=8 TYPE="PASSWORD"></FONT></TD>
</TR>
];
  }
  print qq[<TR>
 <TH $thtag COLSPAN=2 ALIGN=LEFT><FONT $thfont>Configure a mortal user account- $rec!</FONT></TH>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>Username/Login:</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT NAME="User_Name" SIZE=12 MAXLENGTH=12></FONT></TD>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>Real Name:</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT NAME="Real_Name" SIZE=30 MAXLENGTH=40></FONT></TD>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>Enter user's password:</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT NAME="User_Pass" SIZE=8 MAXLENGTH=8 TYPE="PASSWORD"> - 8 characters MAX!</FONT></TD>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>Confirm user's password:</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT NAME="User_Pass" SIZE=8 MAXLENGTH=8 TYPE="PASSWORD"></FONT></TD>
</TR>
];  #'
  if ( $os =~ /SuSE/i ) {
    print qq[<TR>
 <TH COLSPAN=2><FONT $thfont>Enable VNC access during installation.<BR>VNC will be on DISPLAY :1</FONT></TH>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>VNC password:</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT NAME="VNC_Pass" SIZE=12 TYPE="PASSWORD"></FONT></TD>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>Confirm VNC password:</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT NAME="VNC_Pass" SIZE=12 TYPE="PASSWORD"></FONT></TD>
</TR>
];  #'

  } 
  print "</TABLE>\n";
  print $q->submit(-value=>'Go For It!');    
  print " - Looking good, create my custom install image<BR>\n";
  print $q->end_form;
  print $q->end_html;
  $db->ShowFooter;
  exit;

} # End of Step5


sub Step2 {

# Split out arch / os 

  my $serial;
  if ($db->def('SIM') && $q->param('eula') ne "Agreed") {

# If serial# file is in play, override single serial # field

    if ($q->param('serialFile')) {

       # assigning $serial twice, once to call reqd() and make sure that the error
       # gets printed properly and once to make sure that $serial has the
       # dual-function filenmae and file-handle that it's supposed to have. For
       # some reason, it doesn't get that when it comes back from reqd()

       my @serials;
       my $uphandle = $q->upload('serialFile');
       while( my $buf = <$uphandle> ) { 
       # Let's cleans the input of non serial # characters.  assume alphanumeric, - _ should suffice
         next if ( $buf =~ /^#/ );  # No comment
         $buf =~ tr/a-zA-Z0-9\-_\ //cd;   
	 push(@serials,$buf) if $buf;  
       }
       $serial = join(':::',@serials);
    } elsif ( $q->param('serial') ) {
       $serial = $q->param('serial');
    } else {
       &end_it_now("A single serial number OR uploaded file of serial numbers is required!");
    }
    $q->delete('serial');
    $q->param('serial',$serial);

  }
  
  my $data = &reqd('os');
  $data = $db->clean_var($data);
  my ($os,$arch) = split(' - ',$data);
  my ($dist,$ver) = split(' ',$os);
  my $agree = $q->param('eula');

# If there's a EULA/WARNING file, display and force click through

  use lib qw (@prefix@/includes);
  use sysdes_paths;
  my $testfile = $db->find_file("html/eulas/$dist-$ver-$arch.html");
  if (( -r "$testfile" ) && ( ! $agree )) {
    &Step1b($testfile);
  }

  $q->param('os',$os);
  $q->param('arch',$arch);

# Pick a profile and install method suitable for your OS choice in Step1
#  If you entered a hostname/IP, I prompt for N/W info here too

  my $system = $db->clean_var($q->param('system'));
  my $title = "Create a LinuxCOE $COE_VER $os $arch Install Image, Step 2";
  $db->ShowNav($title);
  $title .= " - <font color=red>$defs</font>" if ($defs);
  &do_ov;
  my $ddns_ok = $q->param('ddns_ok');
  my ($hostname,$ip);
  if ( $system ) {
    unless ($q->param('dns_override')) {
      ($hostname,$ip) = $db->do_dns($system);
      unless (( $hostname ) || ( $ip )) {  	# do_dns returned nothing, so ill formed IP most likely.
        $db->end_it_now("I'm sorry, I cannot parse the hostname/IP you entered (<i>$system</i>).  Please back up and check your input");
      }
    }
    unless ($ip) {
      if ( $db->def('DDNS') ) {
        if ( ( $q->param('do_ddns') eq '' ) && ( ! $q->param('dns_override')) ) {
          &Step1_DDNS($system);
        } 
      } else {
        $db->end_it_now($db->errmsg);
      }
    }
  }
  $hostname = $db->def('hostname') || $hostname;
  print $q->h4($title);
  $q->delete('action');
  print $q->start_form('POST',$cgi);
  print $q->hidden(-name=>'action', -default=>'3'),"\n";
  &do_hidden;
  $arch = &reqd('arch');
  my @profiles = $db->show_profiles($dist,$ver,$arch);
  print qq[
<TABLE BORDER=0>
<TR>
 <TD $tdtag><FONT $tdfont>$labels{'profile'}:</FONT></TD>
 <TD $tdtag><FONT $tdfont><SELECT NAME="profile">
 <OPTION VALUE="Custom">Custom - You choose what to install];
  foreach my $profile (@profiles) {
    print "<OPTION>$profile";
  }
  print qq[</SELECT></FONT></TD>
</TR>
<TR>
 <TD $tdtag><FONT $tdfont>$labels{'method'}:</FONT></TD>
 <TD $tdtag><FONT $tdfont><SELECT NAME="method">];
  if ((!($os =~ /Debian/)) && (!($os =~ /buntu/)))  { print qq[ <OPTION VALUE="CDROM">CDROM -  I have vendor supplied CDs of this distribution ]; }
  my @choices = $db->show_os($dist,$ver,$arch);  
  unless ( @choices ) { 
    $db->end_it_now("I have no distribution methods for $os?!?!?!");
  }
  my $def_method = $db->def('METHOD');
  my ($distro,$version) = split(' ',$os);
  foreach my $choice (@choices) {
    if ( $choice eq $def_method ) {
      print qq[<OPTION VALUE="$choice" SELECTED> $varname{$choice} ];
    } else {
      print qq[<OPTION VALUE="$choice"> $varname{$choice} ];
    }
  }
  print "</SELECT></FONT></TD>\n</TR>\n";
  if ( $db->def('CREATE_IMAGE') ) {
    my %choices = ($db->valid_entries($os,$arch,'images'));
    print "<TR>\n <TD ALIGN=LEFT><FONT $tdfont>Boot Image: </FONT></TD><TD><SELECT NAME=\"image\">";
    foreach my $choice (sort(keys(%choices))) {
      print "<OPTION VALUE=\"$choice\"";
      if ( $choice eq 'default' ) { print " SELECTED" }
      print ">$choices{$choice}";
    }
    print "</SELECT>\n</TD></TR>\n";
  }

# If you're not DHCP, I need subnet mask, DNS server, and gateway

  if ($ip) {
    print $q->hidden(-name=>'hostname', -default=>$hostname),"\n";       
    print $q->hidden(-name=>'ip', -default=>$ip),"\n";       
    my $defname = $db->def('NAME_SRV');
    my $defgw = $db->def('GATEWAY');
    my $defnm = $db->def('NETMASK');
    print qq[
<TR>
 <TD $tdtag><FONT $tdfont>$labels{'netmask'}:</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT NAME="netmask" SIZE=15 VALUE="$defnm"></FONT></TD>
</TR>
<TR>
  <TD $tdtag><FONT $tdfont>$labels{'namesvr'}:</FONT></TD>
  <TD $tdtag><FONT $tdfont><INPUT TYPE="text" NAME="namesvr" SIZE="15" MAXLENGTH="15" VALUE="$defname"></FONT></TD>
</TR>
<TR>
  <TD $tdtag><FONT $tdfont>$labels{'gateway'}:</FONT></TD>
  <TD $tdtag><FONT $tdfont><INPUT TYPE="text" NAME="gateway" SIZE="15" MAXLENGTH="15" VALUE="$defgw"> - Blank takes own IP</FONT></TD>
</TR>
];
  }
  print qq[<TR>\n<TD $tdtag><FONT $tdfont>$labels{'netdev'}:</FONT></TD>\n <TD $tdtag><FONT $tdfont><SELECT NAME="netdev">];
  my $numnics = $db->def('NUMNIC') || 7;
  my $defnic = $db->def('DEFNIC') || 'eth0';
  my @nictypes = split(' ',$db->def('NICTYPES'));
  @nictypes = 'eth' unless (@nictypes);
  foreach my $nictype (sort(@nictypes)) {
    foreach my $i ( 0 .. $numnics ) {
      if ( "${nictype}$i" eq $defnic ) {
        print "<OPTION SELECTED>${nictype}$i";
      } else {
        print "<OPTION>${nictype}$i";
      }
    }
  }
  print "</SELECT></FONT></TD>\n</TR>\n";
  if ( ( $db->def('SHOW_PROXY') ) && ( ! (($os =~ /Fedora/) || ( $os =~ /RedHat/ ) || ( $os =~ /Scien/ ) || ( $os =~ /CentOS/ ) || ( $os =~ /VMWare/ ) || ( $os =~ /Oracle/ )) )) {
    my $prox = $db->def('DEF_PROXY');
    print qq[<TR>
  <TD $tdtag><FONT $tdfont>$labels{'proxy'}:</FONT></TD>
  <TD $tdtag><FONT $tdfont><INPUT TYPE="text" NAME="proxy" SIZE="35" VALUE="$prox"> - Use a ftp/http proxy during install.  (ex: http://192.168.1.1:8088/)</FONT></TD>
</TR>
];
  }
  print "</TABLE>\n",$q->submit(-value=>'Continue'),$q->end_form, $q->end_html;
  $db->ShowFooter;
  exit;
 
} # End of Step2

sub Step3 {

# localizations - Pick yer closest waystation/keyboard/mouse/etc...

  my $profile = &reqd('profile');
  my $os = $db->clean_var($q->param('os'));
  my $arch = $db->clean_var($q->param('arch'));
  &check_profile($os,$arch,$profile);    
  my $method = &reqd('method');
  my ($distro,$version) = split(' ',$os);

  my %langs = $db->valid_entries($os,$arch,'langs');
  my %mouses = $db->valid_entries($os,$arch,'mouses');
  my %kbds = $db->valid_entries($os,$arch,'kbds');

# Make sure there's a valid waystation for dist/ver/arch/method - (should NEVER fail)

  if ( $method ne 'CDROM' ) {

    my @count = $db->show_os($distro,$version,$arch,$method);
    my $count = @count;
    unless ( $count ) {
      $db->end_it_now("Sorry, no waystations support the $method method on $distro $version, try other methods!");
    }

  }

# Dump table of localization questions

  my $title = "Create a LinuxCOE $COE_VER $os $arch Install Image, Step 3 - Localizations";
  $db->ShowNav($title);
  $title .= " - <font color=red>$defs</font>" if ($defs);
  &do_ov;
  print $q->h4($title);
  $q->delete('action');
  print $q->start_form(-action=>$cgi);
  print $q->hidden(-name=>'action', -default=>'4'),"\n";       
  &do_hidden();
  print "<TABLE BORDER=0>\n";
# If using ESX 'Scripted Install', prompt for licensing info.....
  if (( $distro eq 'VMWare' ) && (( $version eq 'ESX-2.5.2' ) || ( $version eq 'ESX-2.5.3' ) || ( $version eq 'ESX-2.5.4' )) ) {
#  esxkey esxcpukey
  print qq[<TR>
  <TD><FONT $tdfont>ESX license key (<b>REQUIRED</b>)</TD>
  <TD><FONT $tdfont><INPUT NAME="esxkey" SIZE=25> - (-'s reqd, white space OK)</TD>
</TR>
<TR>
  <TD><FONT $tdfont>ESX SMP key (optional)</TD>
  <TD><FONT $tdfont><INPUT NAME="esxcpukey" SIZE=20></TD>
</TR>
];
  }
  if (( $version eq '5Server' ) || ( $version eq '5Client' )) {
    print qq[<TR>
  <TD><FONT $tdfont>Optional Installation Number (subscription):</TD>
  <TD><FONT $tdfont><INPUT NAME="esxkey" SIZE=25> - (Leave blank to skip)</TD>
</TR>];
  }
  if ( $method ne 'CDROM' ) {

    my @waystations = $db->show_os($distro,$version,$arch,$method);
    print qq[
<TR>
 <TD><FONT $tdfont>Select a network waystation from which to download $distro $version via $method:</FONT></TD>
 <TD $tdtag><FONT $tdfont><SELECT NAME="waystation">];
    unless ($db->def('WAYSTATION') ) { print qq[<OPTION VALUE="" SELECTED>Required] }
    foreach my $waystation (@waystations) {
      my ($way,@loc) = split(' ',$waystation);
      if ( $way eq $db->def('WAYSTATION') ) {
        print "<OPTION VALUE=\"$way\" SELECTED>$way";
      } else {
        print "<OPTION VALUE=\"$way\" >$way";
      }
      if ( @loc ) { print " - @loc" }
    }
    print "</SELECT></TD>\n</TR>\n";

  } 
  my $system = $db->clean_var($q->param('system'));
  my ($host,$ip) = $db->do_dns($system);
  print STDERR "$host - $ip\n" if $debug;

    my $defzone = $db->get_defzone($host,$distro);  
    print qq[
<TR>
  <TD $tdtag><FONT $tdfont>TimeZone: - default <B>$defzone</B></FONT></TD>
    <TD $tdtag><FONT $tdfont><SELECT NAME="timezone">
];
#  IF you want a list vs. dropdown <TD $tdtag><FONT $tdfont><SELECT NAME="timezone" SIZE="5">
    my @tzs = &get_tzs($distro);
    foreach my $tz (sort(@tzs)) {
      if ( $tz eq $defzone ) {
        print "<OPTION SELECTED VALUE=\"$tz\">$tz";
      } else {
        print "<OPTION VALUE=\"$tz\">$tz";
      }
    }
    print qq[</SELECT>
  </FONT></TD>
</TR>   
];
  if ( ( !($os =~ /Debian/))  &&  ( !($os =~ /buntu/ )) ) {
    print qq[<TR>
  <TD $tdtag><FONT $tdfont>Hardware clock set to UTC?</FONT></TD>
  <TD $tdtag><FONT $tdfont><SELECT NAME="utc">
];
    my $utc = $db->def('UTC');
    foreach my $ent ( qw(Yes No) ) {
      print "<OPTION";
      if ( $ent eq $utc ) { print " SELECTED" }
      print ">$ent";
    }
    print qq[</SELECT></FONT></TD>
</TR>
];

    print "<TR>\n <TD $tdtag><FONT $tdfont>Select Language:</FONT></TD>\n <TD $tdtag><FONT $tdfont> <SELECT NAME=\"lang\">";
    foreach my $lang (sort(keys(%langs))) {
      if ( $lang eq 'en_US') { print "<OPTION SELECTED VALUE=$lang>$langs{$lang}" }
      else                   { print "<OPTION VALUE=$lang>$langs{$lang}" }    
    }
    print "</SELECT></FONT></TD>\n</TR>\n";

  }
    if (( $os =~ /Debian/ ) || ( $os =~ /buntu/ )) {
      print qq[<TR>
  <TD $tdtag><FONT $tdfont>Hardware clock set to UTC?</FONT></TD>
  <TD $tdtag><FONT $tdfont><SELECT NAME="utc">
];
      my $utc = $db->def('UTC');
      foreach my $ent ( qw(Yes No) ) {
        print "<OPTION";
        if ( $ent eq $utc ) { print " SELECTED" }
        print ">$ent";
      }
      print qq[</SELECT></FONT></TD>
</TR>
];
    }

    print "<TR>\n <TD $tdtag><FONT $tdfont>Additional Language Support:</FONT></TD>\n <TD $tdtag><FONT $tdfont> <SELECT NAME=\"lang\" MULTIPLE=TRUE SIZE=5>";
    foreach my $lang (sort(keys(%langs))) {
      if ( $lang eq 'en_US') { print "<OPTION SELECTED VALUE=$lang>$langs{$lang}" }
      else                   { print "<OPTION VALUE=$lang>$langs{$lang}" }    
    }
    print "</SELECT> - (IE users must hold the CTRL key) </FONT></TD>\n</TR>\n";

 if ( ( !($os =~ /Debian/))  &&  ( !($os =~ /buntu/ )) ) {

    print "<TR>\n <TD $tdtag><FONT $tdfont>Select Keyboard:</FONT></TD>\n <TD $tdtag><FONT $tdfont><SELECT NAME=\"kbd\">";
    my $defkybd = $db->def('KYBD') || 'us';
    if ( $distro =~ /SuSE/i ) { $defkybd = "english-us" }
    foreach my $kbd (sort(keys(%kbds))) {
      if ( $kbd eq $defkybd ) { print qq[<OPTION SELECTED VALUE="$kbd">$kbds{$kbd}] }
      else                    { print qq[<OPTION VALUE="$kbd">$kbds{$kbd}] }    
    }
    print "</SELECT></FONT></TD>\n</TR>\n";
    print "<TR>\n <TD $tdtag><FONT $tdfont>Select Mouse:</FONT></TD>\n <TD $tdtag><FONT $tdfont><SELECT NAME=\"mouse\">";
    foreach my $mouse (sort(keys(%mouses))) {
      if ( $mouse eq 'generic3ps/2') { print "<OPTION SELECTED VALUE=$mouse>$mouses{$mouse}" }
      else                           { print "<OPTION VALUE=$mouse>$mouses{$mouse}" }    
    }
    print "</SELECT></FONT></TD>\n</TR>\n";
  }
  if ( $q->param('profile') ne 'Custom' ) {
    print qq[<TD $tdtag><FONT $tdfont>Let me override disk/misc configuration in this profile:</FONT></TD>\n 
<TD><SELECT name="override"><OPTION SELECTED VALUE=''>no<OPTION>YES</SELECT></TD>];
  }
  print "</TABLE>\n";
  
  print $q->submit(-value=>'Continue');    
  print $q->end_form;
  print $q->end_html;
  $db->ShowFooter;
  exit;

} # End of Step3

sub reqd {

# Ralph if unset required field

  my $var = shift;
  my $val = $q->param($var);
  $val = $db->clean_var($val);
  print STDERR "reqd cleaned $var to val >$val<\n";
  if ( $val ) { return($val) }
  else {
    $db->end_it_now("$labels{$var} is a Required field!<BR>Go back and set it!\n");
  }

}

sub Step1_DDNS {

# Hostname they passed did not resolve, try DDNS?

  my $system = shift;
  my $title = "Create a LinuxCOE $COE_VER install image - Step 1DDNS";
  $db->ShowNav($title);
  $title .= " - <font color=red>$defs</font>" if ($defs);
  &do_ov;
  print $q->h4($title);
  print $q->start_form(-action=>$cgi);
  &do_hidden;
  print $q->hidden(-name=>'action', -default=>'1b'),"\n";       
  print $q->hidden(-name=>'do_ddns', -default=>'Agreed'),"\n";
  print qq[<p>The hostname you entered, <b><i>$system</i></b>, could not be resolved.  If you 
continue with this hostname, the system will use DHCP for an address and 'request'
this name from the DHCP server.   If you made a mistake entering the hostname, please
use the back button and correct or enter the IP address if not externally resolvable.</p>];
  print $q->submit(-value=>'Continue');    
  print $q->end_form;
  print $q->end_html;
  $db->ShowFooter;
  exit;

}

sub Step1b {

# Dump the EULA/warning form

  my $infile = shift;
  my $title = "Create a LinuxCOE $COE_VER install image - Step 1b";
  $db->ShowNav($title);
  $title .= " - <font color=red>$defs</font>" if ($defs);
  &do_ov;
  print $q->h4($title);
  print $q->start_form(-action=>$cgi);
  &do_hidden;
  print $q->hidden(-name=>'action', -default=>'1b'),"\n";       
  print $q->hidden(-name=>'eula', -default=>'Agreed'),"\n";
  open(IN,"$infile");
  my $agree = $q->submit(-value=>'I AGREE');
  while(<IN>) {
     s/AGREE BUTTON/$agree/;
     print;
  }
  close(IN);
  print $q->end_form;
  print $q->end_html;
  $db->ShowFooter;
  exit;

}

sub Step1 {

# Just dump the first form

  my $title = "Create a custom LinuxCOE $COE_VER install image - Step 1";
  $db->ShowNav($title);
  $title .= " - <font color=red>$defs</font>" if ($defs);
  &do_ov;
  print $q->h4($title);
  print "First, provide the target hostname, and select a Linux distribution <P>\n";
  print $q->start_multipart_form(-action=>$cgi);
  &do_hidden;
  print $q->hidden(-name=>'action', -default=>'2'),"\n";       
  my @choices = $db->show_os;
  print qq[

<TABLE BORDER=0>
<TR>
 <TD $tdtag><FONT $tdfont>$labels{'system'}:</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT NAME="system" SIZE=30> - Leave blank for DHCP vended hostname</FONT></TD>
</TR>
];
  if ( $db->def('DDNS') ) {
     print qq[<TR>
 <TD $tdtag COLSPAN=2><FONT $tdfont><INPUT TYPE="checkbox" NAME="dns_override"> - force use of DHCP and request this hostname (DDNS)<FONT></TD>
</TR>
];
  }
  if ( $db->def('SIM') ) {
    print qq[<TR>
 <TD $tdtag><FONT $tdfont>Single Serial Number:</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT NAME="serial" SIZE=30> - Proliant Serial Number</FONT></TD>
</TR>
<TR>
<TH ALIGN=left COLSPAN=2>OR</TH>
</TR>
 <TD #tdtag><FONT $tdfont>Upload a file with multiple Serial Numbers</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT TYPE="file" NAME="serialFile" SIZE=30> - File containing multiple Serial Numbers</FONT></TD>
</TR>
];
  } elsif ( $db->def('SHOW_ASSET') ) {
    print qq[<TR>
 <TD $tdtag><FONT $tdfont>Asset:</FONT></TD>
 <TD $tdtag><FONT $tdfont><INPUT NAME="asset" SIZE=30> - Managed Workspace Asset ID</FONT></TD>
</TR>
];
  }
  print qq[
<TR>
 <TD $tdtag><FONT $tdfont>$labels{'os'}:</FONT></TD>
 <TD $tdtag><FONT $tdfont><SELECT NAME="os">
];

# Add a descriptive field if needed (e.g. Dapper == 6.06)
  my $distmap = $db->find_file("data/distmap");
  my %distmap;
  unless ( -r $distmap ) {
    &end_it_now("Cannot locate Version->Name mapping file 'distmap'");
  }
  open(DIST,"$distmap") || &end_it_now("open $distmap : $!");
  while(<DIST>) {
    next if /^#/;
    chomp;
    next unless $_;
    my ($ver,$dist,$label) = split;
    $distmap{$ver} = $label;
  }
  close(DIST);

  foreach my $os (@choices) { 
    my ($dist,$ver,$bogus,$arch) = split(' ',$os);
    my $val = $os;
    if ( $distmap{$ver} ) {
      $ver .= " ($distmap{$ver})";
      $val = join(' ',$dist,$ver,$bogus,$arch);
    }
    if ( $os eq $default ) {
      print qq[<OPTION  VALUE="$os"SELECTED>$val];
    } else {
      print qq[<OPTION VALUE="$os">$val];
  }
  }
  print qq[</SELECT></FONT></TD>
</TR>
</TABLE>
];

  print $q->submit(-value=>'Continue');    
  print $q->end_form;
  print $q->end_html;
  $db->ShowFooter;
  exit;

} # End of Step1


sub end_it_now {

# Exit with extreme predjudice

  my $errmsg = shift(@_);
  $db->ShowNav("LinuxCOE $COE_VER System Designer Error");
  print $q->h4("$errmsg");
  my $admin = $db->def('SITE_ADMIN');
  print "<hr>If this error message looks bogus, contact <a href=\"mailto:$admin\">$admin</a>\n" if $admin;
  print $q->end_html;
  $db->ShowFooter;
  exit;

}     

sub do_hidden {

# populate the form with hidden variables if set

  foreach my $var (@vars) {
    if ( $q->param($var) ) {
      	print $q->hidden(-name=>"$var", -default=>$q->param($var)),"\n";
    }
  }

}

sub check_profile {

# make sure the profile select is valid for the OS

  my ($os,$arch,$profile) = @_;
  return if ($profile eq 'Custom');
  my ($dist,$ver) = split(' ',$os);
  my $file = $db->get_filename($dist,$ver,$arch,$profile);
  $file = $db->profbase . "/$file";
  unless ( -r "$file" ) {
    my $msg = "Danger!  A metaphysical dichotomy has occurred.<P>While profile $profile ";
    $msg .= "is registered in the database for $os, the master template file:</P><I>$file</I><P>";
    $msg .= "cannot be found. </P>Eyesight fading,  Exiting....";
    $db->end_it_now($msg);
  }

}

sub get_tzs {

# Generate a list of valid TimeZones...

  my $distro = shift;
  opendir(TZDIR,"/usr/share/zoneinfo");
  my @files = sort(readdir(TZDIR));
  closedir(DIR);
  my @tzs;
  foreach my $file (@files) {
    next unless ($file =~ /^[A-Z]/);
    if ( -d "/usr/share/zoneinfo/$file" ) {
      opendir(DIR,"/usr/share/zoneinfo/$file");
      my @subs = sort(readdir(DIR));
      closedir(DIR);
      shift(@subs); shift(@subs);
      foreach my $sub (@subs) { push(@tzs,"$file/$sub") }
    } else {
      push(@tzs,$file) unless (( $distro eq 'Debian' ) || ( $distro =~ /buntu/ ));
    }
  }
  return(sort(@tzs));

}

sub do_ov {

  return if ( $db->def('NO_OV') );
  print qq[
<DIV ID="overDiv" STYLE="position:absolute; visibility:hide; z-index:2;"></DIV>
<SCRIPT LANGUAGE="JavaScript" SRC="/overlib.js"></SCRIPT>
];

}

sub preseed_part {

# If you're here, it's preseed

  my $ddisk = $q->param('Device');  # Store the disk we're gonna partition
  $q->param('ddisk',$ddisk);
  if ( $q->param('part_choice') ne 'Simple' ) {
    $q->param('ddisk',$ddisk);
    return;
  }
  my (@minsize,@maxsize,@mount,@fstype,@part);
  for (my $i=0; $i<10; $i++ ) {
    my $min = $q->param("size$i");
    if ( $min )   {
      push(@minsize,uc($min));
      my $max = $q->param("max$i");
      print STDERR "Min $min, Max $max\n" if $debug;
      if ( $max ) { push(@maxsize,uc($max)) }
      else { push(@maxsize,uc($min)) }
      push(@fstype,$q->param("fstype$i"));
      push(@mount,$q->param("mount$i"));
      push(@part,$q->param("part$i"));
    }
  }

# Turn alpha suffixes into bytes

  map(s/P/000000000/,@minsize);
  map(s/T/000000/,@minsize);
  map(s/G/000/,@minsize);
  map(s/M//,@minsize);
  map(s/P/000000000/,@maxsize);
  map(s/T/000000/,@maxsize);
  map(s/G/000/,@maxsize);
  map(s/M//,@maxsize);

# At this point we have 4 arrays loaded, call PxT's most excellent part.pl script

# Basically the format is "min_size priority max_size parted_fs other_stuff"
# partitions created in order specified

  my $i = 0;
  my $bootpart = 0;
  my $priority;
  my $partstr;

  if (grep { /\/boot/ } @mount) {
   $bootpart = 1;
  }
  $partstr .= "d-i  partman-auto/expert_recipe  string linuxcoe-custom ::";
  while ($i <= $#mount) {
    if($minsize[$i] == $maxsize[$i] || $mount[$i] eq "/") {
              # make sure fixed-sized partitions end up the size we want
              # bump up root too, otherwise its possible to create
              # a scenario in which the root fs doesn't get created (bug?)
              $priority = 10000;
    } else {
              $priority = 1000;
    }

    $partstr .= " $minsize[$i] $priority $maxsize[$i] ";
    if($fstype[$i] eq "swap") {
              $partstr .= "linux-swap ";
    } else {
              $partstr .= "$fstype[$i] ";
    }
    if ($part[$i] eq "primary") {
      $partstr .= "\$primary{ } ";
    }
    if ($mount[$i] eq "/boot" || ($mount[$i] eq "/" && $bootpart == 0)) {
      $partstr .= "\$bootable{ } ";
    }
    if ($mount[$i] eq "swap") {
      $partstr .= "method{ swap } format{ } .";
    } else {
      $partstr .= "method{ format } format{ } use_filesystem{ } ";
      $partstr .= "filesystem{ $fstype[$i] } mountpoint{ $mount[$i] } .";
    }

    $i++;
  }
  $partstr .= "\n";
  $q->delete('parts');
  $q->param('parts',$partstr);
  $q->param('ddisk',$ddisk);

} # end of preseed_part




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