From 8b035a35700ecf8cad1182cd1b328065e041555d Mon Sep 17 00:00:00 2001 From: wanghuaz Date: Tue, 15 Oct 2013 02:31:01 -0700 Subject: [PATCH 01/15] fixing bug 3510: remove useless repos after genimage. --- xCAT-client/pods/man1/addkitcomp.1.pod | 4 +-- xCAT-server/share/xcat/netboot/rh/genimage | 10 +++++--- xCAT-server/share/xcat/netboot/sles/genimage | 26 +++++++++++++++----- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/xCAT-client/pods/man1/addkitcomp.1.pod b/xCAT-client/pods/man1/addkitcomp.1.pod index cff400964..821d403fd 100644 --- a/xCAT-client/pods/man1/addkitcomp.1.pod +++ b/xCAT-client/pods/man1/addkitcomp.1.pod @@ -15,9 +15,9 @@ The B command will assign kit components to an xCAT osimage. The kit Note: The xCAT support for Kits is only available for Linux operating systems. =head1 OPTIONS - -=over 10 +=over 10 + =item B<-a|--adddeps> Assign kitcomponent dependencies to the osimage. diff --git a/xCAT-server/share/xcat/netboot/rh/genimage b/xCAT-server/share/xcat/netboot/rh/genimage index d99271dd1..6b75afe34 100755 --- a/xCAT-server/share/xcat/netboot/rh/genimage +++ b/xCAT-server/share/xcat/netboot/rh/genimage @@ -408,13 +408,15 @@ unless ($onlyinitrd) { } } $yumcmd = $yumcmd_base; + + # run yum update to update any installed rpms + # needed when running genimage again after updating software in repositories + my $yumcmd_update = $yumcmd_base . " update "; + $rc = system("$yumcmd_update"); + } } - # run yum update to update any installed rpms - # needed when running genimage again after updating software in repositories - my $yumcmd_update = $yumcmd_base . " update "; - $rc = system("$yumcmd_update"); # ignore any return code postscripts(); #run 'postscripts' diff --git a/xCAT-server/share/xcat/netboot/sles/genimage b/xCAT-server/share/xcat/netboot/sles/genimage index d22bf48eb..aa3eda6d6 100755 --- a/xCAT-server/share/xcat/netboot/sles/genimage +++ b/xCAT-server/share/xcat/netboot/sles/genimage @@ -544,17 +544,31 @@ unless ($onlyinitrd) { $rc = system("$envlist $yumcmd_remove $rm_packges"); } } + + # run zypper update to update any installed rpms + # needed when running genimage again after updating software in repositories + my $yumcmd_update; + if ($osver_host == 11) { + $yumcmd_update = "zypper -R $rootimg_dir $non_interactive update "; + } else { + $yumcmd_update = "zypper -R $rootimg_dir $non_interactive update "; + } + $rc = system("$yumcmd_update"); } - # run zypper update to update any installed rpms - # needed when running genimage again after updating software in repositories - my $yumcmd_update; + #remove the old repository for extra packages if ($osver_host == 11) { - $yumcmd_update = "zypper -R $rootimg_dir $non_interactive update "; + my $result=`zypper -R $rootimg_dir $non_interactive lr |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`; + if ($result =~ /\S/) { + system("zypper -R $rootimg_dir $non_interactive rr $result"); + } } else { - $yumcmd_update = "zypper -R $rootimg_dir $non_interactive update "; + my $result=`zypper -R $rootimg_dir $non_interactive sl |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`; + if ($result =~ /\S/) { + system("zypper -R $rootimg_dir $non_interactive sd $result"); + } } - $rc = system("$yumcmd_update"); + # ignore any return code postscripts(); #run 'postscripts' From 84f4f2c7c96bf8c29b8a5f526695c48c2dc6fad6 Mon Sep 17 00:00:00 2001 From: John Simpson Date: Fri, 25 Oct 2013 12:17:17 -0400 Subject: [PATCH 02/15] update to add the configfpc man page --- xCAT-client/pods/man1/configfpc.1.pod | 55 +++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 xCAT-client/pods/man1/configfpc.1.pod diff --git a/xCAT-client/pods/man1/configfpc.1.pod b/xCAT-client/pods/man1/configfpc.1.pod new file mode 100644 index 000000000..a426275c5 --- /dev/null +++ b/xCAT-client/pods/man1/configfpc.1.pod @@ -0,0 +1,55 @@ +=head1 NAME + +B - discover the Fan Power Controllers (FPCs) and configure the FPC interface + +=head1 SYNOPSIS + +B B<-i> I + +B [B<-V>|B<--verbose>] + +B [B<-h>|B<--help>|B<-?>] + +=head1 DESCRIPTION + +B will discover and configure all FPCs that are set to the default IP address. + +The B<-i> B is required to direct B to the xCAT MN interface which is on the same VLAN as the FPCs. + +There are several bits of information that must be included in the xCAT database before running this command. + +You must create the FPC node definitions for all FPCs being discovered including the IP address and switch port information. + +The B command discovers the FPCs and collects the MAC address. The MAC address is used to relate the FPC to a FPC node using the switch information for this MAC. Once the relationship is discovered the FPC is configured with the FPC node IP settings. + +This process is repeated until no more FPCs are discovered. + +For more information on xCAT support of NeXtScale and configfpc see: +https://sourceforge.net/apps/mediawiki/xcat/index.php?title=XCAT_NeXtScale_Clusters + +=head1 OPTIONS + +=over 6 + +=item B<-i> I + +Use this flag to specify which xCAT MN interface (example: eth4) that is connected to the NeXtScale FPCs. This option is required. + +=item B<-V>|B<--verbose> + +Verbose mode + +=back + +=head1 Example + +=over 6 + +=item 1 + +To discover and configure all NeXtScale Fan Power Controllers (FPCs) connected on eth0 interface. + +B B<-i> I + +=back + From ca3e7da99bf9fb8bfff93d110c96d2e3dd2f0a87 Mon Sep 17 00:00:00 2001 From: John Simpson Date: Wed, 23 Oct 2013 17:01:35 -0400 Subject: [PATCH 03/15] update to configfpc to add support for verbose and -i option and a ping verification --- xCAT-server/lib/xcat/plugins/configfpc.pm | 230 +++++++++++++++++----- 1 file changed, 177 insertions(+), 53 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/configfpc.pm b/xCAT-server/lib/xcat/plugins/configfpc.pm index 7ba94c4ff..e74f78d7d 100644 --- a/xCAT-server/lib/xcat/plugins/configfpc.pm +++ b/xCAT-server/lib/xcat/plugins/configfpc.pm @@ -17,6 +17,7 @@ use xCAT::NetworkUtils; use Data::Dumper; use xCAT::MacMap; use Socket; +use Net::Ping; ########################################################################## ## Command handler method from tables @@ -34,6 +35,41 @@ sub process_request { $::CALLBACK = $callback; + if ( defined( @{$::args} ) ) { + @ARGV = @{$::args}; + } + Getopt::Long::Configure( "bundling", "no_ignore_case", "no_pass_through" ); + my $getopt_success = Getopt::Long::GetOptions( + 'help|h|?' => \$::opt_h, + 'i|I=s' => \$::opt_I, + 'verbose|V' => \$::opt_V, + 'version|v' => \$::opt_v, + ); + + # Option -h for Help + if ( defined($::opt_h) || (!$getopt_success) ) { + &configfpc_usage; + return 0; + } + + if ( (!$::opt_I) ) { # missing required option - msg and return + my $rsp; + push @{ $rsp->{data} }, "Missing required option -i \n"; + xCAT::MsgUtils->message( "I", $rsp, $::CALLBACK ); + &configfpc_usage; + return 0; + } + + # Option -V for verbose output + if ( defined($::opt_V) ) { + $::VERBOSE=$::opt_V; + } + + # Option -i for kit component attributes + if ( defined($::opt_I) ) { + $::interface = $::opt_I; + } + my $command = $request->{command}->[0]; my $localhostname = hostname(); @@ -53,6 +89,19 @@ sub process_request { return 0; } +sub configfpc_usage { + my $rsp; + push @{ $rsp->{data} }, + "\nUsage: configfpc - Configure the NeXtScale FPCs.i This command requires the -i option to give specify which network adapter to use to look for the FPCs.\n"; + push @{ $rsp->{data} }, + " configfpc -i interface_adapter \n "; + push @{ $rsp->{data} }, + " configfpc [-V|--verbose] -i adapter_interface \n "; + push @{ $rsp->{data} }, " configfpc [-h|--help|-?] \n"; + xCAT::MsgUtils->message( "I", $rsp, $::CALLBACK ); + return 0; +} + # # Main process subroutine # @@ -87,6 +136,14 @@ sub configfpc { # This is the default FPC IP that we are looking for my $foundfpc = 0; + + # Setup routing to 182.168.0.100 network + if($::VERBOSE){ + my %rsp = {}; + push@{ $rsp{data} }, "Adding route definition for $::interface and 192.168.0.101 network"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + } + my $setroute = `ip addr add dev $::interface 192.168.0.101/16`; # # check for an FPC - this ping will also add the FPC IP and MAC to the ARP table @@ -96,33 +153,25 @@ sub configfpc { if ( $res =~ /100% packet loss/g) { # xCAT::MsgUtils->message ("I", "There are no default $fpcip FPC IP addresses to process"); $foundfpc = 0; + + my %rsp = {}; + push@{ $rsp{data} }, "No nodes Found FPC with $fpcip address"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); exit; # EXIT if we find no more default IP addresses on the network } else { # xCAT::MsgUtils->message ("I", "Found $fpcip FPC IP addresses to process"); + if($::VERBOSE){ + my %rsp = {}; + push@{ $rsp{data} }, "Found FPC with $fpcip address"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + } $foundfpc = 1; } - # - # make the FPC node definition - this is removed at the end of processing the FPCs - # this default FPC node definition is used by rspconfig to change the netmask, default route, and IP address of the default FPC - # - # Object name: deffpc - # bmc=deffpc - # bmcpassword=PASSW0RD - # bmcusername=USERID - # cons=ipmi - # groups=deffpc - # mgt=ipmi - # mpa=deffpc - # - my $out = xCAT::Utils->runxcmd( - { - command => ["mkdef"], - arg => [ "-t","node","-o",$defnode,"bmc=deffpc","bmcpassword=Passw0rd","bmcusername=USERID","cons=ipmi","groups=deffpc","mgt=ipmi","mpa=deffpc" ] - }, - $subreq, 0,1); - + + my $addnode = &add_node($defnode,$callback); + # # Main loop - check to see if we found an FPC and continue to set the FPC infomration and look for the next one # @@ -139,46 +188,55 @@ sub configfpc { # Change the FPC network netmask, gateway, and ip &set_FPC_network_parms($defnode,$netmask,$gateway,$newfpcip,$callback,$subreq); + + # message changed network settings + my %rsp = {}; + push@{ $rsp{data} }, "Configured FPC with MAC $fpcmac as $node ($newfpcip)"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); - # sleep for 4 seconds to allow rspconfig to change the IP value before validating with ping - sleep 5; - - # # Validate that new IP is working - Use ping to check if the new IP has been set - # - $res = `LANG=C ping -c 1 -w 5 $newfpcip`; - #$res = system("LANG=C ping -c 1 -w 5 $fpcip 2>&1"); - if ( $res =~ /100% packet loss/g) { - my %rsp; - push@{ $rsp{data} }, "The new ip $newfpcip was not accessible"; - xCAT::MsgUtils->message( "I", \%rsp, $callback ); - #xCAT::MsgUtils->message("I","The new ip $newfpcip was not accessible"); - } else { - my %rsp; - push@{ $rsp{data} }, "Changed the IP address for the FPC with $fpcmac MAC to $newfpcip IP for node $node"; - xCAT::MsgUtils->message( "I", \%rsp, $callback ); - #xCAT::MsgUtils->message("I","Changed the IP address for the FPC with $fpcmac MAC to $newfpcip IP for node $node"); + my $p = Net::Ping->new(); + my $ping_success=1; + while ($ping_success) { + if ($p->ping($newfpcip)) { + my %rsp = {}; + push@{ $rsp{data} }, "Verified the FPC with MAC $fpcmac is responding to the new IP $newfpcip as node $node"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + $ping_success=0; + } + else { + if($::VERBOSE){ + my %rsp = {}; + push@{ $rsp{data} }, "ping to $newfpcip is unsuccessful. Retrying "; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + } + } } + $p->close(); + # The Node associated with this MAC was not found - print an infomrational message and continue } else { my %rsp; - push@{ $rsp{data} }, "No FPC node found that is associated with MAC address $fpcmac\nCheck to see if the switch and switch table conta ins the information needed to locate this FPC MAC"; + push@{ $rsp{data} }, "No FPC found that is associated with MAC address $fpcmac.\nCheck to see if the switch and switch table contain the information needed to locate this FPC MAC"; xCAT::MsgUtils->message( "I", \%rsp, $callback ); - # xCAT::MsgUtils->message("I","No FPC node found that is associated with MAC address $fpcmac\nCheck to see if the switch and switch table contains the information needed to locate this FPC MAC"); } # # Delete this FPC default IP Arp entry to get ready to look for another defautl FPC # + if($::VERBOSE){ + my %rsp = {}; + push@{ $rsp{data} }, "Removing default IP $fpcip from the arp table"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + } my $arpout = `arp -d $fpcip`; # check for another FPC $res = `LANG=C ping -c 1 -w 5 $fpcip 2>&1`; if ( $res =~ /100% packet loss/g) { my %rsp; - push@{ $rsp{data} }, "There are no more default $fpcip FPC IP addresses to process"; + push@{ $rsp{data} }, "There are no more FPCs with the default IP address to process"; xCAT::MsgUtils->message( "I", \%rsp, $callback ); - #xCAT::MsgUtils->message("I","There are no more default $fpcip FPC IP addresses to process"); $foundfpc = 0; } else { @@ -187,12 +245,30 @@ sub configfpc { } # - # Cleanup on the way out - Remove the deffpc node definition + # Cleanup on the way out - Delete route and remove the deffpc node definition # - $out=xCAT::Utils->runxcmd( + # Delete routing to 182.168.0.100 network + if($::VERBOSE){ + my %rsp = {}; + push@{ $rsp{data} }, "Deleting route definition for $::interface and 192.168.0.101 network"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + } + my $setroute = `ip addr del dev $::interface 192.168.0.101/16`; + + # Delete routing to 182.168.0.100 network + if($::VERBOSE){ + my %rsp = {}; + push@{ $rsp{data} }, "Removing default FPC node definition $defnode"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + } + + if($::VERBOSE){ $::VERBOSE = {}; } + #if($::VERBOSE){ undef $::VERBOSE; } + + my $out=xCAT::Utils->runxcmd( { command => ['rmdef'], - arg => [ "deffpc"] + arg => [ $defnode ] }, $subreq, 0,1); @@ -265,16 +341,18 @@ sub set_FPC_network_parms { # Proceed with changing the FPC network parameters. # Set FPC Netmask - - + if($::VERBOSE){ + my %rsp = {}; + push@{ $rsp{data} }, "Use rspconfig to set the FPC netmask $netmask for node $defnode"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + } my $netmaskout = xCAT::Utils->runxcmd( { command => ["rspconfig"], - node => [$defnode], + node => ["$defnode"], arg => [ "netmask=$netmask" ] }, $request, 0,1); - if ($::RUNCMD_RC != 0) { my %rsp; push@{ $rsp{data} }, "Could not change nemask $netmask on default FPC"; @@ -283,14 +361,18 @@ sub set_FPC_network_parms { } # Set FPC gateway + if($::VERBOSE){ + my %rsp = {}; + push@{ $rsp{data} }, "Use rspconfig to set the FPC gateway $gateway"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + } my $gatewayout = xCAT::Utils->runxcmd( { command => ["rspconfig"], - node => [$defnode], + node => ["$defnode"], arg => [ "gateway=$gateway" ] }, $request, 0,1); - if ($::RUNCMD_RC != 0) { my %rsp; push@{ $rsp{data} }, "Could not change gateway $gateway on default FPC"; @@ -298,16 +380,19 @@ sub set_FPC_network_parms { $error++; } - # Set FPC Ip address + if($::VERBOSE){ + my %rsp = {}; + push@{ $rsp{data} }, "Use rspconfig to set the FPC IP address $newfpcip"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + } my $ipout = xCAT::Utils->runxcmd( { command => ["rspconfig"], - node => [$defnode], + node => ["$defnode"], arg => [ "ip=$newfpcip" ] }, $request, 0,1); - if ($::RUNCMD_RC != 0) { my %rsp; push@{ $rsp{data} }, "Could not change ip address $newfpcip on default FPC"; @@ -344,7 +429,46 @@ sub get_node { my $macmap = xCAT::MacMap->new(); my $node = ''; $node = $macmap->find_mac($fpcmac,0); + # verbose + if($::VERBOSE){ + my %rsp = {}; + push@{ $rsp{data} }, "Found FPC with MAC $fpcmac associated with node $node"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + } return ($node,$fpcmac); } + +# +# This subroutine adds the deffpc node entry for use by rspconfig +# +sub add_node { + my $defnode = shift; + my $callback = shift; +# add this node entry +# Object name: feihu-fpc +# bmc=feihu-fpc (Table:ipmi - Key:node - Column:bmc) +# bmcpassword=PASSW0RD (Table:ipmi - Key:node - Column:password) +# bmcusername=USERID (Table:ipmi - Key:node - Column:username) +# cons=ipmi (Table:nodehm - Key:node - Column:cons) +# groups=fpc (Table:nodelist - Key:node - Column:groups) +# mgt=ipmi (Table:nodehm - Key:node - Column:mgt) +# + + if($::VERBOSE){ + my %rsp = {}; + push@{ $rsp{data} }, "Creating default FPC node deffpc with IP 192.168.0.100 for later use with rspconfig"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + } + + my $nodelisttab = xCAT::Table->new('nodelist',-create=>1); + $nodelisttab->setNodeAttribs($defnode, {groups =>'defaultfpc'}); + my $nodehmtab = xCAT::Table->new('nodehm',-create=>1); + $nodehmtab->setNodeAttribs($defnode, {mgt => 'ipmi'}); + my $ipmitab = xCAT::Table->new('ipmi',-create=>1); + $ipmitab->setNodeAttribs($defnode, {bmc => $defnode, username => 'USERID', password => 'PASSW0RD'}); + +return 0; +} + 1; From ec85d061177f460c1f100c35f1e735ef325d4e0a Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 28 Oct 2013 10:43:08 -0400 Subject: [PATCH 04/15] Suppress warnings about ssh/tech support shell --- xCAT-server/share/xcat/install/esxi/hypervisor.tmpl | 1 + 1 file changed, 1 insertion(+) diff --git a/xCAT-server/share/xcat/install/esxi/hypervisor.tmpl b/xCAT-server/share/xcat/install/esxi/hypervisor.tmpl index 0f3d2a6b2..6a200daa6 100644 --- a/xCAT-server/share/xcat/install/esxi/hypervisor.tmpl +++ b/xCAT-server/share/xcat/install/esxi/hypervisor.tmpl @@ -52,6 +52,7 @@ echo -e "\nnextdestiny\n" | /bin/o chkconfig SSH on chkconfig ESXShell on esxcli system settings advanced set --int-value 0 --option /VMFS3/EnableBlockDelete +esxcli system settings advanced set --int-value 1 --option /UserVars/SuppressShellWarning esxcli network ip set -e y esxcli network firewall ruleset set -r DHCPv6 -e y esxcli network firewall ruleset set -r sshServer -e y From b0ddf05865bfce26d54084f462f30b4d6acc4068 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 28 Oct 2013 10:44:40 -0400 Subject: [PATCH 05/15] Fix stateless esxi warning about ssh --- xCAT-server/share/xcat/netboot/esxi/48.esxifixup | 1 + 1 file changed, 1 insertion(+) diff --git a/xCAT-server/share/xcat/netboot/esxi/48.esxifixup b/xCAT-server/share/xcat/netboot/esxi/48.esxifixup index df4500688..dc99ab1e6 100644 --- a/xCAT-server/share/xcat/netboot/esxi/48.esxifixup +++ b/xCAT-server/share/xcat/netboot/esxi/48.esxifixup @@ -1,6 +1,7 @@ #!/bin/sh #first off, let's ditch UNMAP, per vwmare's recall... localcli system settings advanced set --int-value 0 --option /VMFS3/EnableBlockDelete +localcli system settings advanced set --int-value 1 --option /UserVars/SuppressShellWarning #ok, now let's turn on some SSH and ESXShell fun localcli network firewall ruleset set -r sshServer -e y chkconfig ESXShell on From fbce5a6a000b009ccb8ed40cde3cdbad5e8eecdf Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 28 Oct 2013 16:07:06 -0400 Subject: [PATCH 06/15] Add formatdisk to esx plugin, to be called by mkstorage --- xCAT-server/lib/xcat/plugins/esx.pm | 36 ++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/xCAT-server/lib/xcat/plugins/esx.pm b/xCAT-server/lib/xcat/plugins/esx.pm index 1f4af072e..44bf57902 100644 --- a/xCAT-server/lib/xcat/plugins/esx.pm +++ b/xCAT-server/lib/xcat/plugins/esx.pm @@ -125,6 +125,7 @@ sub handled_commands{ rpower => 'nodehm:power,mgt', rsetboot => 'nodehm:power,mgt', rmigrate => 'nodehm:power,mgt', + formatdisk => "nodetype:os=(esxi.*)", mkvm => 'nodehm:mgt', rmvm => 'nodehm:mgt', clonevm => 'nodehm:mgt', @@ -210,7 +211,7 @@ sub preprocess_request { my $vmtabhash = $vmtab->getNodesAttribs($noderange,['host','migrationdest']); foreach my $node (@$noderange){ - if ($command eq "rmhypervisor" or $command eq 'lsvm' or $command eq 'rshutdown' or $command eq "chhypervisor") { + if ($command eq "rmhypervisor" or $command eq 'lsvm' or $command eq 'rshutdown' or $command eq "chhypervisor" or $command eq "formatdisk") { $hyp_hash{$node}{nodes} = [$node]; } else { my $ent = $vmtabhash->{$node}->[0]; @@ -636,6 +637,8 @@ sub do_cmd { generic_vm_operation(['config.name','runtime.host'],\&setboot,@exargs); } elsif ($command eq 'rinv') { generic_vm_operation(['config.name','config','runtime.host','layoutEx'],\&inv,@exargs); + } elsif ($command eq 'formatdisk') { + generic_hyp_operation(\&formatdisk,@exargs); } elsif ($command eq 'rmhypervisor') { generic_hyp_operation(\&rmhypervisor,@exargs); } elsif ($command eq 'rshutdown') { @@ -2173,6 +2176,37 @@ sub rshutdown_inmaintenance { return; } +sub formatdisk { + my %args = @_; + my $hyp = $args{hyp}; + $hyphash{$hyp}->{hostview} = get_hostview(hypname=>$hyp,conn=>$hyphash{$hyp}->{conn},properties=>['config','configManager']); + @ARGV = @{$args{exargs}}; + my $nid; + my $name; + GetOptions( + 'id=s' => \$nid, + 'name=s' => \$name, + ); + my $hostview = $hyphash{$hyp}->{hostview}; + if (defined $hyphash{$hyp}->{hostview}) { + my $hdss = $hostview->{vim}->get_view(mo_ref=>$hostview->configManager->storageSystem); + $hdss->RescanAllHba(); + my $dss = $hostview->{vim}->get_view(mo_ref=>$hostview->configManager->datastoreSystem); + my $diskList = $dss->QueryAvailableDisksForVmfs(); + foreach my $disk (@$diskList) { + foreach my $id (@{$disk->{descriptor}}) { + if (lc($id->{id}) eq lc('naa.'.$nid)) { + my $options = $dss->QueryVmfsDatastoreCreateOptions(devicePath => $disk->devicePath); + @$options[0]->spec->vmfs->volumeName($name); + my $newDatastore = $dss->CreateVmfsDatastore(spec => @$options[0]->spec ); + } + } + } + + } + return; +} + sub rmhypervisor { my %args = @_; my $hyp = $args{hyp}; From 952ff38ce42385b3797a15bebc128812c597836c Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 28 Oct 2013 16:15:25 -0400 Subject: [PATCH 07/15] Add --format to mkstorage --- xCAT-server/lib/xcat/plugins/svc.pm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/xCAT-server/lib/xcat/plugins/svc.pm b/xCAT-server/lib/xcat/plugins/svc.pm index 98352215b..e3830a975 100644 --- a/xCAT-server/lib/xcat/plugins/svc.pm +++ b/xCAT-server/lib/xcat/plugins/svc.pm @@ -133,12 +133,14 @@ sub mkstorage { my $pool; my $size; my $boot = 0; + my $format = 0; unless (ref $request->{arg}) { die "TODO: usage"; } my $name; @ARGV = @{$request->{arg}}; unless (GetOptions( + 'format' => \$format, 'shared' => \$shared, 'controller=s' => \$controller, 'boot' => \$boot, @@ -183,6 +185,16 @@ sub mkstorage { my %namemap = makehosts($wwns, controller=>$controller, cfg=>$storents); my @names = values %namemap; bindhosts(\@names, $lun, controller=>$controller); + if ($format) { + my %request = ( + node => [$nodes[0]], + command => [ 'formatdisk' ], + arg => [ '--id', $lun->{wwn}, '--name', $lun->{name} ] + ); + use Data::Dumper; + print Dumper($request{arg}); + $dorequest->(\%request, $callback); + } } else { foreach my $node (@nodes) { mkstorage_single(node=>$node, size=>$size, pool=>$pool, From 08accdf517c51f39ed7224b462c1a774e1c01667 Mon Sep 17 00:00:00 2001 From: John Simpson Date: Mon, 28 Oct 2013 16:14:27 -0400 Subject: [PATCH 08/15] update to configfpc to add support for verbose and -i option and a ping verification --- xCAT-server/lib/xcat/plugins/configfpc.pm | 31 +++++++++++++---------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/configfpc.pm b/xCAT-server/lib/xcat/plugins/configfpc.pm index e74f78d7d..de1ed3692 100644 --- a/xCAT-server/lib/xcat/plugins/configfpc.pm +++ b/xCAT-server/lib/xcat/plugins/configfpc.pm @@ -43,7 +43,6 @@ sub process_request { 'help|h|?' => \$::opt_h, 'i|I=s' => \$::opt_I, 'verbose|V' => \$::opt_V, - 'version|v' => \$::opt_v, ); # Option -h for Help @@ -94,9 +93,9 @@ sub configfpc_usage { push @{ $rsp->{data} }, "\nUsage: configfpc - Configure the NeXtScale FPCs.i This command requires the -i option to give specify which network adapter to use to look for the FPCs.\n"; push @{ $rsp->{data} }, - " configfpc -i interface_adapter \n "; + " configfpc -i interface \n "; push @{ $rsp->{data} }, - " configfpc [-V|--verbose] -i adapter_interface \n "; + " configfpc [-V|--verbose] -i interface \n "; push @{ $rsp->{data} }, " configfpc [-h|--help|-?] \n"; xCAT::MsgUtils->message( "I", $rsp, $::CALLBACK ); return 0; @@ -218,7 +217,8 @@ sub configfpc { } else { my %rsp; push@{ $rsp{data} }, "No FPC found that is associated with MAC address $fpcmac.\nCheck to see if the switch and switch table contain the information needed to locate this FPC MAC"; - xCAT::MsgUtils->message( "I", \%rsp, $callback ); + xCAT::MsgUtils->message( "E", \%rsp, $callback ); + $foundfpc = 0; } # @@ -231,16 +231,19 @@ sub configfpc { } my $arpout = `arp -d $fpcip`; - # check for another FPC - $res = `LANG=C ping -c 1 -w 5 $fpcip 2>&1`; - if ( $res =~ /100% packet loss/g) { - my %rsp; - push@{ $rsp{data} }, "There are no more FPCs with the default IP address to process"; - xCAT::MsgUtils->message( "I", \%rsp, $callback ); - $foundfpc = 0; - } - else { - $foundfpc = 1; + if ( ($foundfpc==1) ) { # if the last FPC was found and processed + + # check for another FPC + $res = `LANG=C ping -c 1 -w 5 $fpcip 2>&1`; + if ( ($res =~ /100% packet loss/g) && ($foundfpc==1) ) { + my %rsp; + push@{ $rsp{data} }, "There are no more FPCs with the default IP address to process"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + $foundfpc = 0; + } + else { + $foundfpc = 1; + } } } From 3664f1d5c3290b988581864303fefe9bfd7e4ac6 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 28 Oct 2013 20:26:40 -0400 Subject: [PATCH 09/15] Implement rescansan in esx.pm and wire up svc.pm to issue rescansan --- xCAT-server/lib/xcat/plugins/esx.pm | 21 ++++++++++++++++----- xCAT-server/lib/xcat/plugins/svc.pm | 9 ++++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/esx.pm b/xCAT-server/lib/xcat/plugins/esx.pm index 44bf57902..168fa6515 100644 --- a/xCAT-server/lib/xcat/plugins/esx.pm +++ b/xCAT-server/lib/xcat/plugins/esx.pm @@ -126,6 +126,7 @@ sub handled_commands{ rsetboot => 'nodehm:power,mgt', rmigrate => 'nodehm:power,mgt', formatdisk => "nodetype:os=(esxi.*)", + rescansan => "nodetype:os=(esxi.*)", mkvm => 'nodehm:mgt', rmvm => 'nodehm:mgt', clonevm => 'nodehm:mgt', @@ -211,7 +212,7 @@ sub preprocess_request { my $vmtabhash = $vmtab->getNodesAttribs($noderange,['host','migrationdest']); foreach my $node (@$noderange){ - if ($command eq "rmhypervisor" or $command eq 'lsvm' or $command eq 'rshutdown' or $command eq "chhypervisor" or $command eq "formatdisk") { + if ($command eq "rmhypervisor" or $command eq 'lsvm' or $command eq 'rshutdown' or $command eq "chhypervisor" or $command eq "formatdisk" or $command eq 'rescansan') { $hyp_hash{$node}{nodes} = [$node]; } else { my $ent = $vmtabhash->{$node}->[0]; @@ -320,6 +321,7 @@ sub process_request { if ($request->{_xcat_authname}->[0]) { $requester=$request->{_xcat_authname}->[0]; } + %vcenterhash = ();#A data structure to reflect the state of vcenter connectivity to hypervisors my $level = shift; my $distname = undef; my $arch = undef; @@ -639,6 +641,8 @@ sub do_cmd { generic_vm_operation(['config.name','config','runtime.host','layoutEx'],\&inv,@exargs); } elsif ($command eq 'formatdisk') { generic_hyp_operation(\&formatdisk,@exargs); + } elsif ($command eq 'rescansan') { + generic_hyp_operation(\&rescansan,@exargs); } elsif ($command eq 'rmhypervisor') { generic_hyp_operation(\&rmhypervisor,@exargs); } elsif ($command eq 'rshutdown') { @@ -2176,6 +2180,17 @@ sub rshutdown_inmaintenance { return; } +sub rescansan { + my %args = @_; + my $hyp = $args{hyp}; + my $hostview = get_hostview(hypname=>$hyp,conn=>$hyphash{$hyp}->{conn},properties=>['config','configManager']); + if (defined $hostview) { + my $hdss = $hostview->{vim}->get_view(mo_ref=>$hostview->configManager->storageSystem); + $hdss->RescanAllHba(); + $hdss->RescanVmfs(); + } +} + sub formatdisk { my %args = @_; my $hyp = $args{hyp}; @@ -4959,7 +4974,6 @@ sub cpNetbootImages { chdir($tmpDir); xCAT::SvrUtils::sendmsg("extracting netboot files from OS image. This may take about a minute or two...hopefully you have ~1GB free in your /tmp dir\n", $output_handler); my $cmd = "tar zxf $srcDir/image.tgz"; - print "\n$cmd\n"; if(system($cmd)){ xCAT::SvrUtils::sendmsg([1,"Unable to extract $srcDir/image.tgz\n"], $output_handler); } @@ -4971,13 +4985,11 @@ sub cpNetbootImages { # now we need to get partition 5 which has the installation goods in it. my $scmd = "fdisk -lu $tmpDir/usr/lib/vmware/installer/*dd 2>&1 | grep dd5 | awk '{print \$2}'"; - print "running: $scmd\n"; my $sector = `$scmd`; chomp($sector); my $offset = $sector * 512; mkdir "/mnt/xcat"; my $mntcmd = "mount $tmpDir/usr/lib/vmware/installer/*dd /mnt/xcat -o loop,offset=$offset"; - print "$mntcmd\n"; if(system($mntcmd)){ xCAT::SvrUtils::sendmsg([1,"unable to mount partition 5 of the ESX netboot image to /mnt/xcat"], $output_handler); return; @@ -4999,7 +5011,6 @@ sub cpNetbootImages { } chdir("/tmp"); system("umount /mnt/xcat"); - print "tempDir: $tmpDir\n"; system("rm -rf $tmpDir"); } elsif (-r "$srcDir/cim.vgz" and -r "$srcDir/vmkernel.gz" and -r "$srcDir/vmkboot.gz" and -r "$srcDir/sys.vgz") { use File::Basename; diff --git a/xCAT-server/lib/xcat/plugins/svc.pm b/xCAT-server/lib/xcat/plugins/svc.pm index e3830a975..c807b87ba 100644 --- a/xCAT-server/lib/xcat/plugins/svc.pm +++ b/xCAT-server/lib/xcat/plugins/svc.pm @@ -185,14 +185,17 @@ sub mkstorage { my %namemap = makehosts($wwns, controller=>$controller, cfg=>$storents); my @names = values %namemap; bindhosts(\@names, $lun, controller=>$controller); - if ($format) { + if ($format) { my %request = ( node => [$nodes[0]], command => [ 'formatdisk' ], arg => [ '--id', $lun->{wwn}, '--name', $lun->{name} ] ); - use Data::Dumper; - print Dumper($request{arg}); + $dorequest->(\%request, $callback); + %request = ( + node => \@nodes, + command => [ 'rescansan' ], + ); $dorequest->(\%request, $callback); } } else { From cac2677c1cfe4c3936a037c1a36994043153ae56 Mon Sep 17 00:00:00 2001 From: ligc Date: Tue, 29 Oct 2013 10:48:31 +0800 Subject: [PATCH 10/15] temp fix for bug 3792: multiple nics in the same subnet, use the first nic that in the subnet for dhcp --- xCAT-server/lib/xcat/plugins/dhcp.pm | 12 ++++++++++++ 1 file changed, 12 insertions(+) mode change 100644 => 100755 xCAT-server/lib/xcat/plugins/dhcp.pm diff --git a/xCAT-server/lib/xcat/plugins/dhcp.pm b/xCAT-server/lib/xcat/plugins/dhcp.pm old mode 100644 new mode 100755 index 46963a50e..90f3b55db --- a/xCAT-server/lib/xcat/plugins/dhcp.pm +++ b/xCAT-server/lib/xcat/plugins/dhcp.pm @@ -1998,6 +1998,11 @@ sub addnet if ($ent[0] eq $net and $ent[2] eq $mask) { $nic = $ent[1]; + # The first nic that matches the network, + # what will happen if there are more than one nics in the same subnet, + # and we want to use the second nic as the dhcp interfaces? + # this is a TODO + last; } } #print " add $net $mask under $nic\n"; @@ -2014,6 +2019,13 @@ sub addnet } unless ($dhcpconf[$idx] =~ /\} # $nic nic_end\n/) { + $callback->( + { + error => + ["Could not add the subnet $net/$mask for nic $nic into $dhcpconffile."], + errorcode => [1] + } + ); return 1; #TODO: this is an error condition } } From 0eb918b7bdfb0e4f6d510c612466baf05db3cc76 Mon Sep 17 00:00:00 2001 From: lissav Date: Tue, 29 Oct 2013 11:08:40 -0400 Subject: [PATCH 11/15] 3865,3864 --- xCAT-server/sbin/xcatsnap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xCAT-server/sbin/xcatsnap b/xCAT-server/sbin/xcatsnap index 500f62b06..64f8b07de 100755 --- a/xCAT-server/sbin/xcatsnap +++ b/xCAT-server/sbin/xcatsnap @@ -102,7 +102,7 @@ sub run_cmd { print "\n\tExecuting: $Command \n"; eval { local $SIG{ALRM} = sub { die "Timeout\n" }; - alarm 60; + alarm 600; @output = `$Command`; alarm 0; }; @@ -238,7 +238,7 @@ sub snap_it { "ls $installdir","/usr/bin/crontab -l", "find /tftpboot -size -32k","ls -lR $xcatroot", "arp -a","ps -edlf","ps -aux","ulimit -a","df -k", - "cat /etc/issue","lsxcatd -a"); + "cat /etc/issue","lsxcatd -a","cat /proc/meminfo", "cat /proc/cpuinfo"); } foreach my $item (@Commands_array) { $Command = $item; From 13e7903b436b68e3c625271eee3f99886e663a76 Mon Sep 17 00:00:00 2001 From: nott Date: Tue, 29 Oct 2013 14:45:14 -0400 Subject: [PATCH 12/15] buildkit fixes 3845, 3855, 3857 --- xCAT-buildkit/bin/buildkit | 29 +- xCAT-buildkit/bin/buildkit.fix | 3766 ++++++++++++++++++++++++++++++++ 2 files changed, 3785 insertions(+), 10 deletions(-) create mode 100755 xCAT-buildkit/bin/buildkit.fix diff --git a/xCAT-buildkit/bin/buildkit b/xCAT-buildkit/bin/buildkit index 02ca942cb..e717029f6 100755 --- a/xCAT-buildkit/bin/buildkit +++ b/xCAT-buildkit/bin/buildkit @@ -949,9 +949,14 @@ sub kit_buildtar my $tarfile = $::deploy_dir."/".$kitfilename; - if ( system("cd $::deploy_dir; cd ..; cp -r build_input $kitname" ) ) { - print "Error: Could not copy building tarfile $tarfile \n"; - return 1; + my $dir = dirname($::deploy_dir); + my $bidir = "$dir/build_input"; + + if ( -d "$bidir") { + if ( system("cd $::deploy_dir; cd ..; cp -r build_input $kitname" ) ) { + print "Error: Could not copy building tarfile $tarfile \n"; + return 1; + } } print "Creating tar file $tarfile.\n"; @@ -1940,9 +1945,10 @@ sub build_kitcomp my $specfile = $::workdir."/tmp/$comp->{kitcompname}-prep.spec"; my $rpmbuild_cmd = "rpmbuild --define \"_topdir $rpmbuild_dir\" -ba $specfile"; - if (!$::VERBOSE) { + # don't want debug info - 3845 +# if (!$::VERBOSE) { $rpmbuild_cmd .= ' --quiet '; - } +# } if ( system($rpmbuild_cmd) ) { print "Error running rpmbuild command for kit component $comp->{kitcompname} meta package\n"; return 1; @@ -1955,7 +1961,7 @@ sub build_kitcomp return 1; } } - + $::VALID_PRER_COMPONENT = 1; } @@ -2012,9 +2018,12 @@ sub build_kitcomp return 1; } } - if (!$::VERBOSE) { + + # - don't want debug info - 3845 +# if (!$::VERBOSE) { $rpmbuild_cmd .= ' --quiet '; - } +# } + if ( system($rpmbuild_cmd) ) { print "Error running rpmbuild command for kit component $comp->{kitcompname} meta package\n"; return 1; @@ -2056,7 +2065,7 @@ sub update_kitcomp_kitpkgdeps my $repodir = shift; if (defined($comp->{kitpkgdeps})) { - # we have some rpms listed -n buildkit.conf file + # we have some rpms listed in buildkit.conf file my $new_kitpkgdeps = ''; foreach my $d (split(/,/, $comp->{kitpkgdeps})) { $d =~ s/\s+//g; @@ -2073,7 +2082,6 @@ sub update_kitcomp_kitpkgdeps my @rpmlist = `$lscmd`; if ( scalar(@rpmlist) == 0) { - print "Error: Could not find rpm named $d in $repodir. \n"; next; } @@ -3542,6 +3550,7 @@ sub NEW_kit_addpkgs system ("rm -Rf $tmpdir_base"); return 1; } + my @fromfiles=@$files; foreach my $repo (split(/,/, $ext_reponames)) { diff --git a/xCAT-buildkit/bin/buildkit.fix b/xCAT-buildkit/bin/buildkit.fix new file mode 100755 index 000000000..e717029f6 --- /dev/null +++ b/xCAT-buildkit/bin/buildkit.fix @@ -0,0 +1,3766 @@ +#!/usr/bin/env perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html +# + +#----------------------------------------------------------------------------- + +=head1 buildkit + + xCAT/PCM Kit Build utilities + +This script is designed to run on a non-xCAT system so that Kits can be +built on any product build machine. + +=cut + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; + $::XCATDIR = $ENV{'XCATDIR'} ? $ENV{'XCATDIR'} : '/etc/xcat'; + $::XCATSHARE = $::XCATROOT.'/share/xcat'; +} + +if ($^O =~ /^aix/i) { + print "ERROR - the buildkit command is not supported on AIX \n"; + exit 1; +} + +use lib "$::XCATROOT/lib/perl"; +require xCAT::BuildKitUtils; +use Getopt::Long; +use strict; +use Cwd; +use Cwd 'abs_path'; +use File::Path; +use File::Basename; + +#----------------------------------------------------------------------------- +# Main + +$::progname = "buildkit"; +$::buildkit_conf = "buildkit.conf"; +$::kit_conf = "kit.conf"; +$::current_dir = cwd(); + +# this code will build a kit using framework 1. +$::KITFRAMEWORK ="2"; + +# this code is compatible with other kits that are at framework 0 or 1. +$::COMPATIBLE_KITFRAMEWORKS = "0,1,2"; + +%::buildkit_def = ( + kit => { basename => { + description=>'The kit base name (e.g., kit-lsf)', + value_desc=>'Must be: Generic Name String', + mandatory=>1, + cp_to_kitconfig=>1}, + description => { + description=>'The kit description', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>1}, + version => { + description=>'The kit version (e.g., 9.0)', + value_desc=>'Must be: Generic Name String', + mandatory=>1, + cp_to_kitconfig=>1}, + release => { + description=>'The kit release (e.g., 1)', + value_desc=>'Must be: Generic Name String', + mandatory=>0, + cp_to_kitconfig=>1}, + ostype => { + description=>'The kit OS type (e.g., Linux)', + value_desc=>'Must be: OS Type String', + mandatory=>1, + cp_to_kitconfig=>1}, + osbasename => { + description=>'The kit OS basename', + value_desc=>'Must be: Generic Name String', + mandatory=>0, + cp_to_kitconfig=>0}, + osmajorversion => { + description=>'The kit OS majorversion', + value_desc=>'Must be: Generic Name String', + mandatory=>0, + cp_to_kitconfig=>0}, + osminorversion => { + description=>'The kit OS minorversion', + value_desc=>'Must be: Generic Name String', + mandatory=>0, + cp_to_kitconfig=>0}, + osarch => { + description=>'The kit OS architecture', + value_desc=>'Must be: Generic Name String', + mandatory=>0, + cp_to_kitconfig=>0}, + isinternal=> { + description=>'Flag to say if this Kit is used for internal use only. It is only used for information purposes.', + value_desc=>'Must be: empty string or boolean string', + mandatory=>0, + cp_to_kitconfig=>1}, + kitdeployparams=> { + description=>'The path to the Kit Deployment Parameters file.', + value_desc=>'Must be: empty string or relative path string', + mandatory=>0, + base_dir=>'other_files', + cp_to_kitconfig=>2}, # 2 = rename with KIT_KITNAME_ on cp + kitlicense=> { + description=>'The Kit license string to be built into all kitcomponent packages.', + value_desc=>'any string', + mandatory=>1, + cp_to_kitconfig=>0}, + kittarfilename=> { + description=>'The filename to use for the generated kit.', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + vendor=> { + description=>'The Vendor value to use when building the rpms.', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + packager=> { + description=>'The Packager value to use when building the rpms.', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + url=> { + description=>'The URL value to use when building the rpms.', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}}, + kitrepo => {kitrepoid => { + description=>'The Kit Package Repository ID. (e.g., rhels-6.2-x86_64)', + value_desc=>'Must be: Generic Name String, unique in kit', + mandatory=>1, + cp_to_kitconfig=>0}, + osbasename => { + description=>'The OS distro base name (e.g., rhels)', + value_desc=>'Must be OS Name String', + mandatory=>1, + cp_to_kitconfig=>1}, + osmajorversion => { + description=>'The OS distro major version (e.g., 6)', + value_desc=>'Must be Generic Number String', + mandatory=>1, + cp_to_kitconfig=>1}, + osminorversion => { + description=>'The OS distro minor version (e.g., 3)', + value_desc=>'Must be Generic Number String', + mandatory=>0, + cp_to_kitconfig=>1}, + osarch => { + description=>'The OS distro architecture (e.g., x86_64)', + value_desc=>'Must be OS Arch String', + mandatory=>1, + cp_to_kitconfig=>1}, + compat_osbasenames => { + description=>'Comma-separated list of compatible OS base names. ', + value_desc=>'Must be Empty String or list of OS Name Strings', + mandatory=>0, + cp_to_kitconfig=>1} }, + kitcomponent => {basename => { + description=>'The component name. It is used as the meta-package name.', + value_desc=>'any string', + mandatory=>1, + cp_to_kitconfig=>1}, + description => { + description=>'The component description. The description is added to the meta-package.', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>1}, + version => { + description=>'The component version (e.g., 9.0). It is used as the meta-package version.', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>1}, + release => { + description=>'The component release number (e.g., 1). It is used as the meta-package release number.', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>1}, + serverroles => { + description=>'tbd', + value_desc=>'any string', + mandatory=>1, + cp_to_kitconfig=>1}, + kitrepoid => { + description=>'tbd', + value_desc=>'any string', + mandatory=>1, + cp_to_kitconfig=>0}, + kitcompdeps => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>1}, + ospkgdeps => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + kitpkgdeps => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>1}, + non_native_pkgs => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + driverpacks => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>1}, + exlist => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + base_dir=>'other_files', + cp_to_kitconfig=>2}, + preinstall => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + postinstall => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + preuninstall => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + postuninstall => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + preupgrade => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + postupgrade => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + postbootscripts => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + base_dir=>'scripts', + cp_to_kitconfig=>2}, + genimage_postinstall => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + base_dir=>'scripts', + cp_to_kitconfig=>2} }, + kitpackage => {filename => { + description=>'tbd', + value_desc=>'any string', + mandatory=>1, + cp_to_kitconfig=>0}, + kitrepoid => { + description=>'tbd', + value_desc=>'any string', + mandatory=>1, + cp_to_kitconfig=>0}, + rpm_spec => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + rpm_srcdir => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + rpm_srctarball => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + rpm_srpm => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + rpm_prebuiltdir => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}, + isexternalpkg => { + description=>'tbd', + value_desc=>'any string', + mandatory=>0, + cp_to_kitconfig=>0}} +); + + +my $args = join ' ', @ARGV; +$::command = "$0 $args"; +Getopt::Long::Configure("bundling"); +$Getopt::Long::ignorecase = 0; + +# parse the options +if ( + !GetOptions( + 'h|help' => \$::HELP, + 'v|version' => \$::VERSION, + 'V|verbose' => \$::VERBOSE, + 'n|noprerequisite' => \$::PREREQUISITE, + 'p|pkgdir=s' => \$::PKGDIR, + 'k|kitversion=s' => \$::KITVERSION, + 'r|kitrelease=s' => \$::KITRELEASE, + 'l|kitloc=s' => \$::KITLOC, + ) + ) +{ + &usage; + exit(1); +} + +# display the usage if -h or --help is specified +if ($::HELP) +{ + &usage; + exit(0); +} + +my $debianflag = 0; +my $tempstring = xCAT::BuildKitUtils->osver(); +if ( $tempstring =~ /debian/ || $tempstring =~ /ubuntu/ ){ + $debianflag = 1; +} + +# display the version statement if -v or --version is specified +if ($::VERSION) +{ + my $versioncmd = "rpm -q --qf \"%{NAME}: %{VERSION}-%{RELEASE} \n\" xCAT-buildkit"; + my $message = "Error quering xCAT-buildkit rpm. Version info is not available. \n"; + if ( $debianflag ){ + $versioncmd = "dpkg-query --show -f='\${PackageSpec}: \${Version}\n' xcat-buildkit"; + $message = "Error quering xcat-buildkit package. Version info is not available. \n"; + } + if ( system($versioncmd) ) { + # non-zero return from system call + print $message; + exit 1; + } + # add framework info to output + print "\tkitframework = $::KITFRAMEWORK\n"; + print "\tcompatible_frameworks = $::COMPATIBLE_KITFRAMEWORKS\n"; + + exit 0; +} + +my $arg=shift(@ARGV); +if ( ! $arg ) { + &usage; + exit (0); +} + +# set kit location +if ($::KITLOC) { + $::workdir = $::KITLOC; + $::current_dir = $::workdir; +} else { + $::workdir = $::current_dir; +} + +$::full_buildkit_conf = $::workdir."/".$::buildkit_conf; +$::build_dir = $::workdir."/build"; +$::deploy_dir = $::build_dir; #kitname appended by validate_bldkitconf routine +$::base_repodir = $::build_dir."/kit_repodir"; + +while ($arg) { + my $command = $arg; + $command =~ tr/A-Z/a-z/; # convert to lowercase + if ( $command eq 'create' ) { + $::KIT_CREATE=shift(@ARGV); + if ($::KITLOC) { + $::workdir = dirname($::KITLOC); + $::current_dir = $::workdir; + } + if ( ! $::KIT_CREATE ) { + print "The Kit basename was not specified for the buildkit create command.\n"; + &usage; + exit 1; + } + } elsif ( $command eq 'chkconfig' ) { + $::KIT_CHKCONFIG=1; + } elsif ( $command eq 'buildrepo' ) { + $::KIT_BUILDREPO=shift(@ARGV); + if ( ! $::KIT_BUILDREPO ) { + print "The Kit package repository name was not specified for buildkit buildrepo command.\n"; + &usage; + exit 1; + } + } elsif ( $command eq 'listrepo' ) { + $::KIT_LISTREPO=1; + } elsif ( $command eq 'cleanrepo' ) { + $::KIT_CLEANREPO=shift(@ARGV); + if ( ! $::KIT_CLEANREPO ) { + print "kit package repository name not specified for buildkit cleanrepo command \n"; + &usage; + exit 1; + } + } elsif ( $command eq 'buildtar' ) { + $::KIT_BUILDTAR=1; + } elsif ( $command eq 'cleantar' ) { + $::KIT_CLEANTAR=1; + } elsif ( $command eq 'cleanall' ) { + $::KIT_CLEANALL=1; + } elsif ( $command eq 'addpkgs' ) { + $::KIT_ADDPKGS=shift(@ARGV); + if (!($::KIT_ADDPKGS)){ + print "Missing parameter: the name must be specified when using the \'buildkit addpkgs\' command.\n"; + &usage; + exit (1); + } + if (!($::PKGDIR)){ + print "Missing option: the -p option must be specified with \'buildkit addpkgs\' command. \n"; + &usage; + exit (1); + } + } else { + print "The buildkit command $arg is not recognized.\n"; + &usage; + exit (1); + } + $arg=shift(@ARGV); +} + +my $rc = 0; +if ( $::KIT_CREATE ) { + $rc = &kit_create; +} +if ( $::KIT_CHKCONFIG ) { + unless ($rc = &kit_chkconfig) { + print "No errors were found in Kit Build File $::full_buildkit_conf. \n"; + } +} +if ( $::KIT_LISTREPO ) { + unless ($rc = &kit_chkconfig) { $rc = &kit_listrepo; } +} +if ( $::KIT_BUILDREPO ) { + unless ($rc = &kit_chkconfig) { $rc = &kit_buildrepo; } +} +if ( $::KIT_CLEANREPO ) { + unless ($rc = &kit_chkconfig) { $rc = &kit_cleanrepo; } +} +if ( $::KIT_BUILDTAR ) { + unless ($rc = &kit_chkconfig) { $rc = &kit_buildtar; } +} +if ( $::KIT_CLEANTAR ) { + unless ($rc = &kit_chkconfig) { $rc = &kit_cleantar; } +} +if ( $::KIT_CLEANALL ) { + unless ($rc = &kit_chkconfig) { $rc = &kit_cleanall; } +} +if ( $::KIT_ADDPKGS ) { $rc = &kit_addpkgs; } + +exit $rc; + +##################################### +# subroutines +##################################### + +#----------------------------------------------------------------------------- + +=head3 usage + + Displays message for -h option + +=cut + +#----------------------------------------------------------------------------- +sub usage +{ + print "Usage: + buildkit [-?│-h│--help] [-v│--version] + + To build a new Kit + + buildkit [-V│--verbose] [] [│all] + [-l│--kitloc ] + + To add packages to an existing Kit. + + buildkit [-V│--verbose] addpkgs [-p│--pkgdir ] [-k│--kitversion ] [-r│--kitrelease ] + + This tool is used to build and manage a Kit package. + The options are: + -h - Provide usage info. + -k - Kit version. + -l - Location of kit files. (Including kit name.) + -p - RPM package directory locations. + -r - Kit release. + -v - Provide the version info. + command - Several commands are supported. See the list below. + -V - Verbose mode. Outputs additional debug messages. + + Supported subcommands: + create - creates a new Kit with the specified basename + chkconfig - checks the Kit build file + listrepo - lists the Kit package repositories in the Kit + build file, and their build status + buildrepo - builds the specified Kit package repository + buildrepo all - builds all the Kit package repositories + cleanrepo - deletes the build files for the specified Kit + package repository + cleanrepo all - deletes the build files for all Kit package + repositories + buildtar - builds the Kit tarfile + cleantar - deletes the Kit deployment directory and Kit + tarfile + cleanall - equivalent to buildkit cleanrepo all and + buildkit cleantar + addpkgs -p + - add product package rpms to a shipped tarfile + named kitname.NEEDS_PRODUCT_PKGS.tar.bz2 + \n"; +} + +#----------------------------------------------------------------------------- + +=head3 kit_create + + buildkit create + +=cut + +#----------------------------------------------------------------------------- + +sub kit_create + +{ + # create Kit directory in pwd + my $kitname=$::KIT_CREATE; + my $kitdir; + if ($::KITLOC ) { + $kitdir=$::KITLOC; + } else { + $kitdir=$::workdir."/$kitname"; + } + + if ( -d $kitdir ) { + print "Another directory already exists with the name $kitdir. Not able to create new Kit. \n"; + exit 1; + } + if ( ! mkdir($kitdir) ) { + print "Error creating Kit directory $kitdir. Verify that the current user has privileges to create the directory. \n"; + exit 1; + } + + # Recursive copy the shipped template directory to the Kit directory + if ( system("cp -fRp $::XCATSHARE/kits/kit_template/* $kitdir") ) { + # non-zero return from system call + print "Error copying sample Kit template files from $::XCAT_SHARE/kits/kit_template to $kitdir \n"; + exit 1; + } + + if (&edit_bldkitconf($kitdir."/".$::buildkit_conf,$kitname)) { + exit 1; + } + + print "Kit template for $kitname created in $kitdir directory \n"; + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 kit_chkconfig + + buildkit chkconfig + +=cut + +#----------------------------------------------------------------------------- + +sub kit_chkconfig + +{ + if ( $::CHKCONFIG_DONE ) { return 0; } + my $bldkitconf = $::full_buildkit_conf; + + my $chkrc = &load_bldkitconf($bldkitconf); + if ( $chkrc != 0 ) { return 1; }; + + $chkrc = &validate_bldkitconf(); + if ( $chkrc != 0 ) { return 1; }; + + $::CHKCONFIG_DONE=1; + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 kit_buildrepo + + buildkit buildrepo + +=cut + +#----------------------------------------------------------------------------- + +sub kit_buildrepo +{ + my $rc = 0; + my $repoid = $::KIT_BUILDREPO; + + if ( !$debianflag ){ + # Check if createrepo exists or not. Fail at the beginning. + #- don't use specific path - may not be correct in build env + my $rcmd = "createrepo -h > /dev/null"; + if ( system( $rcmd ) ) { + print "Error: the createrepo command does not seem to be installed. Make sure createrepo is installed before running the buildkit command. \n"; + return 1; + } + } + + $repoid =~ s/\s+//g; + $repoid =~ tr/A-Z/a-z/; # convert to lowercase + if ( $repoid ne 'all' ) { + return &kit_buildrepo1($::KIT_BUILDREPO); + } else { + foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) { + if ( &kit_buildrepo1($kr->{kitrepoid}) ) { return 1; } + } + } + return $rc; +} + +#----------------------------------------------------------------------------- + +=head3 kit_buildrepo1 + + + +=cut + +#----------------------------------------------------------------------------- +sub kit_buildrepo1 +{ + my $rc = 0; + my $repoid = shift; + $repoid =~ s/\s+//g; + my $repodir = $::base_repodir; + my $srcdir = $::workdir."/source_packages/"; + my $basedir = $repodir; + my $repo; + + # find the repo + my $found = 0; + foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) { + if ( $kr->{kitrepoid} eq $repoid ) { + $found = 1; + $repo = $kr; + if ( &validate_os($kr)) { + print "The buildrepo operation will continue, but errors may occur. You may need to run this command on a host with the same OS.\n"; + } + $repodir .= "/$kr->{kitreponame}"; + last; + } + } + if (! $found) { + print "The specified Kit Package Repository \"$repoid\" does not exist in the Kit Build File. \n"; + return 1; + } + + # Create repo build directory + if ( (! -d $repodir) && (! mkpath($repodir)) ) { + print "Error creating build repository directory $repodir.\n"; + return 1; + } + + # Build kitpackages first + my $kitrepohash; + foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) { + $kitrepohash->{$kr->{kitrepoid}} = $kr->{kitreponame}; + } + + foreach my $kp (@{$::bldkit_config->{kitpackage}{entries}}) { + # For this kitrepo? + my $found = 0; + foreach my $kprid (split(/,/, $kp->{kitrepoid})) { + $kprid =~ s/\s+//g; + if ($repoid eq $kprid) { + $found = 1; + last; + } + } + if (!$found) { next; } + + # is this package already built? + my $rpm = "$repodir/$kp->{filename}"; + if ( -r $rpm) { next; } + + my $kprid; + my $rpm_built; + foreach $kprid (split(/,/, $kp->{kitrepoid})) { + if ($repoid eq $kprid) { + next; + } + if ( (-d "$basedir/$kitrepohash->{$kprid}") and (-f "$basedir/$kitrepohash->{$kprid}/$kp->{filename}") ) { + $rpm_built = $kitrepohash->{$kprid}; + last; + } + } + + + # determine build method + if ($kp->{isexternalpkg} eq 'yes') { + if ($::VERBOSE) { print "skipping build of external kitpackage $kp->{filename} \n";} + next; + } else { + if ($::VERBOSE) { print "building kitpackage $kp->{filename} \n";} + } + if (defined($kp->{rpm_prebuiltdir})) { + # simply copy the file to the build directory + my $full_prebuiltrpm = $srcdir.$kp->{rpm_prebuiltdir}."/".$kp->{filename}; + + if ( $rpm_built ) { + if (system("cd $repodir;ln -sf ../$rpm_built/$kp->{filename} $kp->{filename}")) { + # non-zero return from system call + print "Error create symlink for prebuilt rpm $kp->{filename} to Kit Build directory. \n"; + return; + } + } else { + if (system("cp -fp $full_prebuiltrpm $repodir")) { + # non-zero return from system call + print "Error copying prebuilt rpm $kp->{filename} to Kit Build directory. \n"; + return 1; + } + } + } elsif (defined($kp->{rpm_srpm})) { + # run rpmbuild --rebuild on the source rpm + print "SKIPPING BUILD FOR KIT PACKAGE $kp->{filename} \n"; + print "TBD - only buildrepo for prebuilt rpms is available at this time \n\n"; + } elsif (defined($kp->{rpm_srctarball}) && + defined($kp->{rpm_spec}) ) { + # run rpmbuild + print "SKIPPING BUILD FOR KIT PACKAGE $kp->{filename} \n"; + print "TBD - only buildrepo for prebuilt rpms is available at this time \n\n"; + } elsif (defined($kp->{rpm_srcdir}) && + defined($kp->{rpm_spec}) ) { + # build tarfile and run rpmbuild + print "SKIPPING BUILD FOR KIT PACKAGE $kp->{filename} \n"; + print "TBD - only buildrepo for prebuilt rpms is available at this time \n\n"; + } else { + print "Cannot determine build method for Kit Package $kp->{filename}. Verify that your Kit Build File is correct. \n"; + return 1; + } + } + + # Build kitcomponent metapackages + if ( $debianflag ){ + foreach my $kc (@{$::bldkit_config->{kitcomponent}{entries}}) { + if ($repoid ne $kc->{kitrepoid}) { next; } + my $debname = "$repodir/".&comppkgname($kc); + if (-r $debname) { next; } + if ($::VERBOSE) { print "building kitcomponent metapackage for $kc->{basename} \n";} + if (&build_kitcomp_debian($kc)) { + print "Error building kitcomponent metapackage for $kc->{basename} \n"; + return 1; + } + } + if ( system("dpkg-scanpackages $repodir > $repodir/Packages") ) { + print "Error building the repository meta-data with the dpkg-scanpackages command \n"; + return 1; + } + } + else{ + foreach my $kc (@{$::bldkit_config->{kitcomponent}{entries}}) { + # Check if this kitcomponent is in the requested repo + if ($repoid ne $kc->{kitrepoid}) { next; } + + # Check if already built + my $rpm = "$repodir/".&comppkgname($kc); + if (-r $rpm) { next; } + + # Build it + if ($::VERBOSE) { print "building kitcomponent metapackage for $kc->{basename} \n";} + if (&build_kitcomp($kc)) { + print "Error building kitcomponent metapackage for $kc->{basename} \n"; + return 1; + } + } + + # run createrepo + my $cr_opts = ''; + if (( $repo->{osbasename} =~ m/rh|RH|centos|CentOS/ ) && + ( $repo->{osmajorversion} eq '5') ) { + $cr_opts = '-s md5'; + } + if ( system("createrepo $cr_opts $repodir") ) { + print "Error building the repository meta-data with the createrepo command \n"; + return 1; + } + } + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 kit_listrepo + + buildkit listrepo + +=cut + +#----------------------------------------------------------------------------- +sub kit_listrepo +{ + # print "Kit Repository: Status \n"; + foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) { + my $rc = 0; + my $status = "NOT DONE"; + unless ($rc = &validate_repo($kr)) {$status = "DONE";} + print "$kr->{kitrepoid}: $status \n"; + } + + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 kit_cleanrepo + + buildkit cleanrepo + +=cut + +#----------------------------------------------------------------------------- +sub kit_cleanrepo +{ + my $repoid = $::KIT_CLEANREPO; + my $tmp_repoid = $repoid; + $tmp_repoid =~ tr/A-Z/a-z/; # convert to lowercase + + if (($tmp_repoid eq 'all') && + -d $::base_repodir ) { + if ( system("rm -Rf $::base_repodir ") ) { + print "Error removing contents of $::base_repodir \n"; + return 1; + } else { + print "Contents of $::base_repodir has been successfully removed. \n"; + } + } else { + my $got_one = 0; + foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) { + if ($repoid eq $kr->{kitrepoid}) { + my $repodir = $::base_repodir.'/'.$kr->{kitreponame}; + if ( -d $repodir ){ + if ( system("rm -Rf $repodir ") ) { + print "Error removing directory $repodir \n"; + return 1; + } else { + print "Kit repository $kr->{kitrepoid} has been removed. \n"; + } + } else { + print "Kit repository $kr->{kitrepoid} directory $repodir does not exist. Nothing to remove for this repository. \n"; + } + $got_one = 1; + last; + } + } + if ( !$got_one ) { + print "Kit repository $repoid does not exist.\n"; + return 1; + } + } + if ( -d "$::workdir/rpmbuild" ) { + system("rm -Rf $::workdir/rpmbuild "); + } + if ( -d "$::workdir/tmp" ) { + system("rm -Rf $::workdir/tmp "); + } + if ( -d "$::workdir/debbuild" ){ + system("rm -Rf $::workdir/debbuild"); + } + + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 kit_buildtar + + buildkit buildtar + +=cut + +#----------------------------------------------------------------------------- +sub kit_buildtar +{ + foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) { + if (&validate_repo($kr)) { + print "Kit Repository $kr->{kitrepoid} not built. Run: \n"; + print " buildkit buildrepo $kr->{kitrepoid} \n"; + return 1; + } + } + + if (&create_kitconf) { + print "Error creating kit configuration file \n"; + return 1; + } + + if ($::HAVE_EXTERNAL_PKG or $::HAVE_NON_NATIVE_PKGS) { + if (&create_PARTIAL_builddir) { + print "Error creating PARTIAL kit build directory contents \n"; + return 1; + } + } else { + if (&create_builddir) { + print "Error creating kit build directory contents \n"; + return 1; + } + } + + if (! -d "$::deploy_dir/repos") { + symlink "$::build_dir/kit_repodir","$::deploy_dir/repos"; + } + + # build the tarfile + my $extpkgs = ''; + if ($::HAVE_EXTERNAL_PKG or $::HAVE_NON_NATIVE_PKGS) { + $extpkgs = '.NEED_PRODUCT_PKGS'; + } + my $kitname = $::bldkit_config->{kit}{entries}[0]->{kitname}; + my $kitfilename = $kitname; + if ( defined($::bldkit_config->{kit}{entries}[0]->{kittarfilename}) ) { + $kitfilename = $::bldkit_config->{kit}{entries}[0]->{kittarfilename}; + $kitfilename =~ s/tar\.bz2\s*$//; + } + $kitfilename = $kitfilename.$extpkgs.".tar.bz2"; + + my $tarfile = $::deploy_dir."/".$kitfilename; + + my $dir = dirname($::deploy_dir); + my $bidir = "$dir/build_input"; + + if ( -d "$bidir") { + if ( system("cd $::deploy_dir; cd ..; cp -r build_input $kitname" ) ) { + print "Error: Could not copy building tarfile $tarfile \n"; + return 1; + } + } + + print "Creating tar file $tarfile.\n"; + + if ( system("cd $::deploy_dir; cd ..; tar -cjhf $tarfile $kitname/*") ) { + print "Error building tarfile $tarfile \n"; + return 1; + } + + system("mv $tarfile $::current_dir"); + print "Kit tar file $::current_dir/$kitfilename successfully built. \n"; + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 kit_cleantar + + buildkit cleantar + + Remove tar files from the kit location directory. + + This removes all tar files - not just the last one created! + + Also clean up several other files/dirs + +=cut + +#----------------------------------------------------------------------------- +sub kit_cleantar +{ + my $basename = $::bldkit_config->{kit}{entries}[0]->{basename}; + my $rmfiles = "$basename\*tar.bz2"; + + my $tarfile = "$::workdir/$rmfiles"; + + if ( $rmfiles ) { + if ( system("rm -f $tarfile ") ) { + print "Error removing kit tar files in $::workdir.\n"; + } else { + print "Kit tar files have been successfully removed from $::workdir.\n"; + } + } + + if ( -d $::deploy_dir ) { + if ( system("rm -Rf $::deploy_dir ") ) { + print "Error removing contents of $::deploy_dir \n"; + } else { + print "Removed $::deploy_dir.\n"; + } + } + if ( -d "$::workdir/rpmbuild" ) { + if ( system("rm -Rf $::workdir/rpmbuild ")) { + # print "Error removing $::workdir/rpmbuild\n"; + } else { + print "Removed $::workdir/rpmbuild\n"; + } + } + if ( -d "$::workdir/tmp" ) { + if ( system("rm -Rf $::workdir/tmp ") ) { + # print "Error removing $::workdir/tmp \n"; + } else { + print "Removed $::workdir/tmp \n"; + } + } + if ( -d "$::workdir/debbuild" ){ + if ( system("rm -Rf $::workdir/debbuild")) { + # print "Error removing $::workdir/debbuild.\n"; + } else { + print "Removed $::workdir/debbuild\n"; + } + } + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 kit_cleanall + + buildkit cleanall + +=cut + +#----------------------------------------------------------------------------- +sub kit_cleanall +{ + print "Running buildkit cleanall... \n"; + + &kit_cleantar; + + if ( -d $::build_dir ) { + if ( system("rm -Rf $::build_dir/* ") ) { + print "Error removing contents of $::build_dir \n"; + } else { + print "All $::build_dir contents have been successfully removed \n"; + } + } + if ( -d "$::workdir/rpmbuild" ) { + system("rm -Rf $::workdir/rpmbuild "); + } + if ( -d "$::workdir/tmp" ) { + system("rm -Rf $::workdir/tmp "); + } + if ( -d "$::workdir/debbuild" ){ + system("rm -Rf $::workdir/debbuild"); + } + + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 edit_bldkitconf + + edit the shipped template buildkit.conf file to insert initial values + for the new kit +=cut + +#----------------------------------------------------------------------------- +sub edit_bldkitconf +{ + my $bldkitconf = shift; + my $kitname = shift; + + # read in the buildkit.conf file + my $CF; + unless ( open( $CF, "<", $bldkitconf ) ) { + print "The Kit build file $bldkitconf does not exist. \n"; + return 1; + } + if ($::VERBOSE) { + print "Reading kit configuration file $bldkitconf \n"; + } + my @lines = <$CF>; + close $CF; + + my $osinfo = xCAT::BuildKitUtils->osver(); + my $kitrepoid = $osinfo; + $kitrepoid =~ s/\,//; + my ($osbasename,$osmore) = split(/\,/, $osinfo); + my ($osmajorversion,$osminorversion) = split(/\./, $osmore); + my $osarch=`uname -p`; + my $kitcomponent_basename = $kitname."_compute"; + + for (@lines) { + s/<<>>/$kitname/; + s/<<>>/$kitrepoid/; + s/<<>>/$osbasename/; + s/<<>>/$osmajorversion/; + s/<<>>/$osminorversion/; + s/<<>>/$osarch/; + s/<<>>/$kitcomponent_basename/; + if ($debianflag){ + s/(filename=.*?)\-(.*)\.noarch\.rpm/$1_$2_all.deb/; + } + } + + # Write the buildkit.conf back out + my $NCF; + unless ( open( $NCF, ">$bldkitconf" ) ) { + return 1; + } + if ($::VERBOSE) { + print "Inserted initial values into $bldkitconf \n"; + } + print $NCF @lines; + close($NCF); + + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 load_bldkitconf + + load the kitbuild.conf file into a global data structure and + verify that the general syntax is correct. + +=cut + +#----------------------------------------------------------------------------- +sub load_bldkitconf +{ + my $bldkitconf = shift; + + # read in the buildkit.conf file + my $CF; + unless ( open( $CF, "<", $bldkitconf ) ) { + print "The Kit build file $bldkitconf does not exist in the current directory. \n"; + return 1; + } + if ($::VERBOSE) { + print "Reading kit configuration file $bldkitconf \n"; + } + my @lines = <$CF>; + close $CF; + + my $current_section = 'no section'; + my %current_entry; + my $syntax_error = ''; + my $bad_line = ''; + my $line_number = 0; + foreach my $l (@lines) { + $line_number++; + # skip blank and comment lines + next if ( $l =~ /^\s*$/ || $l =~ /^\s*#/ ); + + # process a real line + # new section? + if ( $l =~ /^\s*(\w+)\s*:/ ) { + my $section = $1; + if ( defined( $::buildkit_def{$section} ) ) { + if (($section eq 'kit') && + ($::bldkit_config->{$section}{'exists'})) { + $syntax_error = "More than one \"$section:\" section exists "; + $bad_line = $l; + last; + } + $::bldkit_config->{$section}{'exists'} = 1; + push ( @{ $::bldkit_config->{$current_section}{'entries'} }, {%current_entry}); + $current_section = $section; + undef %current_entry; + next; + } + } + if ( $l =~ /^\s*(\w+)\s*=\s*(.*)\s*/ ) { + my $attr = $1; + my $val = $2; + my $orig_attr = $attr; + my $orig_val = $val; + $attr =~ s/^\s*//; # Remove any leading whitespace + $attr =~ s/\s*$//; # Remove any trailing whitespace + $attr =~ tr/A-Z/a-z/; # Convert to lowercase + $val =~ s/^\s*//; + $val =~ s/\s*$//; + + if ( defined( $::buildkit_def{$current_section}{$attr} ) ) { + if ( $val ne '') { $current_entry{$attr} = $val; } + } else { + if ( $current_section eq 'no section' ) { + $syntax_error = "No section specified for attribute $attr."; + } else { + my $valid_attrs = join (', ', (keys (%{$::buildkit_def{$current_section}}))); + $syntax_error = "Attribute \"$attr\" is not valid for section \"$current_section\". Valid attributes are: $valid_attrs.\n"; + } + $bad_line = $l; + last; + } + + } else { + $syntax_error = "Invalid line format"; + $bad_line = $l; + last; + + } + } + + # Need at least one kit and one kitrepo section + if (! $syntax_error) { + if ( !($::bldkit_config->{'kit'}{'exists'})) { + $syntax_error = "No \"kit:\" section found. At least one section required. "; + $bad_line = ''; + } elsif ( !($::bldkit_config->{'kitrepo'}{'exists'})) { + $syntax_error = "No \"kitrepo:\" section found. At least one section required. "; + $bad_line = ''; + } else { + push ( @{ $::bldkit_config->{$current_section}{'entries'} }, {%current_entry}); + } + } + + if ($syntax_error) { + print "Error processing file $bldkitconf \n"; + print "Syntax error found on line $line_number:\n"; + print "$bad_line \n"; + print "$syntax_error \n"; + print "\n"; + print "The Kit build file does not have the correct format. \n"; + print "The format should be: \n"; + print "
: \n"; + print " = \n"; + print " = \n"; + print " ... \n"; + print "
: \n"; + print " = \n"; + print " = \n"; + print " ... \n"; + print "The valid section names are: kit, kitrepo, kitcomponent, kitpackages. \n"; + print "There must be exactly one kit, and must be at least one kitrepo section. \n"; + return 1; + } + + # Check for mandatory attributes + foreach my $s (keys %{$::bldkit_config}) { + if (! defined($::buildkit_def{$s}) ) { next;} + foreach my $se (@{$::bldkit_config->{$s}{entries}}) { + foreach my $a (keys %{$::buildkit_def{$s}}) { + if (( $::buildkit_def{$s}{$a}->{mandatory} ) && + ( ! defined ($se->{$a}) ) ) { + print "The \"$a\" mandatory attribute must be defined in the \"$s\" section of the Kit build file \n"; + return 1; + } + } + } + } + +#use Data::Dumper; +#print Dumper($::bldkit_config); + + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 validate_bldkitconf + + validate the loaded buildkit configuration data + +=cut + +#----------------------------------------------------------------------------- +sub validate_bldkitconf +{ + my $kitname = $::bldkit_config->{kit}{entries}[0]->{basename}; + my $full_kitname = $kitname; + $full_kitname .= '-'.$::bldkit_config->{kit}{entries}[0]->{version}; + if (defined($::bldkit_config->{kit}{entries}[0]->{release})) { + $full_kitname .= '-'.$::bldkit_config->{kit}{entries}[0]->{release}; + } + my $short_kitname = $full_kitname; + if (defined($::bldkit_config->{kit}{entries}[0]->{osbasename})) { + $full_kitname .= '-'.$::bldkit_config->{kit}{entries}[0]->{osbasename}; + } + if (defined($::bldkit_config->{kit}{entries}[0]->{osmajorversion})) { + if ( ! defined($::bldkit_config->{kit}{entries}[0]->{osbasename})) { + print "Error: Kit osmajorversion attribute was specified but Kit osbasename was not set. \n"; + return 1; + } + $full_kitname .= '-'.$::bldkit_config->{kit}{entries}[0]->{osmajorversion}; + } + if (defined($::bldkit_config->{kit}{entries}[0]->{osminorversion})) { + if ( ( ! defined($::bldkit_config->{kit}{entries}[0]->{osbasename})) || + ( ! defined($::bldkit_config->{kit}{entries}[0]->{osmajorversion}))) { + print "Error: Kit osminorversion attribute was specified but either Kit osbasename or Kit osmajorversion were not set. \n"; + return 1; + } + $full_kitname .= '-'.$::bldkit_config->{kit}{entries}[0]->{osminorversion}; + } + if (defined($::bldkit_config->{kit}{entries}[0]->{osarch})) { + $full_kitname .= '-'.$::bldkit_config->{kit}{entries}[0]->{osarch}; + } + $::bldkit_config->{kit}{entries}[0]->{kitname} = $full_kitname; + $::deploy_dir .= "/".$full_kitname; + + # Make sure each kit kitdeployparams file exists + if (defined($::bldkit_config->{kit}{entries}[0]->{kitdeployparams})){ + my $kd_file = $::workdir."/other_files/".$::bldkit_config->{kit}{entries}[0]->{kitdeployparams}; + if (! -r $kd_file ) { + print "Kit Deployment Parameters file $kd_file does not exist or is not readable\n"; + return 1; + } + if (&edit_deployparams($kd_file,1)) { return 1;} + } + + # Make sure each kitrepo has unique distro info + my $kr_count = scalar @{$::bldkit_config->{kitrepo}{entries}}; + if ($kr_count > 1) { + foreach my $kri (0..$kr_count-2) { + foreach my $kri2 ($kri+1..$kr_count-1) { + my $kr = $::bldkit_config->{kitrepo}{entries}[$kri]; + my $kr2 = $::bldkit_config->{kitrepo}{entries}[$kri2]; + if ( $kr->{kitrepoid} eq $kr2->{kitrepoid} ) { + print "There are two or more kitrepo sections with the same kitrepoid \"$kr->{kitrepoid}\". \n"; + return 1; + } + if ( ($kr->{osbasename} eq $kr2->{osbasename}) && + ($kr->{osmajorversion} eq $kr2->{osmajorversion}) && + ($kr->{osarch} eq $kr2->{osarch}) ) { + if( ( defined ($kr->{osminorversion}) && + defined ($kr2->{osminorversion}) && + ($kr->{osminorversion} eq $kr2->{osminorversion}) ) || + ( ! defined ($kr->{osminorversion}) && + ! defined ($kr2->{osminorversion}) ) ) { + print "There are two or more kitrepo sections which are defined with the same OS name, major/minor version, and architecture. \n"; + return 1; + } + } + } + } + } + + # Kitcomponent version/release are now optional - + # default to kit version/release + foreach my $kc (@{$::bldkit_config->{kitcomponent}{entries}}) { + if (! defined($kc->{version})) { + $kc->{version} = $::bldkit_config->{kit}{entries}[0]->{version}; + } + if (! defined($kc->{release})) { + if (! defined($::bldkit_config->{kit}{entries}[0]->{release})) { + print "Kitcomponent $kc->{basename} does not have a release specified and there is no Kit release value set to use as a default. \n"; + return 1; + } else { + $kc->{release} = $::bldkit_config->{kit}{entries}[0]->{release}; + } + } + + } + + # Make sure each kitcomponent has unique basename/repoid + # If same basename, make sure version/release are same, too + my $kc_count = scalar @{$::bldkit_config->{kitcomponent}{entries}}; + if ($kc_count > 1) { + foreach my $kci (0..$kc_count-2) { + foreach my $kci2 ($kci+1..$kc_count-1) { + if ( $::bldkit_config->{kitcomponent}{entries}[$kci]->{basename} + eq $::bldkit_config->{kitcomponent}{entries}[$kci2]->{basename} ) { + if ( $::bldkit_config->{kitcomponent}{entries}[$kci]->{kitrepoid} + eq $::bldkit_config->{kitcomponent}{entries}[$kci2]->{kitrepoid} ) { + + print "Two or more kitcomponents are defined with the same basename \"$::bldkit_config->{kitcomponent}{entries}[$kci]->{basename}\" and the same repoid \"$::bldkit_config->{kitcomponent}{entries}[$kci]->{kitrepoid}\". \n"; + return 1; + } + if ( ($::bldkit_config->{kitcomponent}{entries}[$kci]->{version} + ne $::bldkit_config->{kitcomponent}{entries}[$kci2]->{version}) || + ($::bldkit_config->{kitcomponent}{entries}[$kci]->{release} + ne $::bldkit_config->{kitcomponent}{entries}[$kci2]->{release}) + ) { + print "Two or more kitcomponents are defined with the same basename \"$::bldkit_config->{kitcomponent}{entries}[$kci]->{basename}\" but with different version or release. \n"; + return 1; + } + } + } + } + } + + # Kitrepo checks + foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) { + my $reponame = $short_kitname; + if ((defined($::bldkit_config->{kit}{entries}[0]->{osbasename})) && + ($::bldkit_config->{kit}{entries}[0]->{osbasename} ne + $kr->{osbasename} ) ) { + print "Warning: Kit osbasename is set to \"$::bldkit_config->{kit}{entries}[0]->{osbasename}\", but this does not match kitrepo $kr->{kitrepoid} osbasename \"$kr->{osbasename}\". Processing will continue, but verify that you do not have an error in your buildkit configuration file. \n"; + } + $reponame .= '-'.$kr->{osbasename}; + if ( (defined($::bldkit_config->{kit}{entries}[0]->{osmajorversion})) && + ($::bldkit_config->{kit}{entries}[0]->{osmajorversion} ne + $kr->{osmajorversion} ) ) { + print "Warning: Kit osmajorversion is set to \"$::bldkit_config->{kit}{entries}[0]->{osmajorversion}\", but this does not match kitrepo $kr->{kitrepoid} osmajorversion \"$kr->{osmajorversion}\". Processing will continue, but verify that you do not have an error in your buildkit configuration file. \n"; + } + $reponame .= '-'.$kr->{osmajorversion}; + if (defined($kr->{osminorversion})){ + if ( (defined($::bldkit_config->{kit}{entries}[0]->{osminorversion})) && + ($::bldkit_config->{kit}{entries}[0]->{osminorversion} ne + $kr->{osminorversion} ) ) { + print "Warning: Kit osminorversion is set to \"$::bldkit_config->{kit}{entries}[0]->{osminorversion}\", but this does not match kitrepo $kr->{kitrepoid} osminorversion \"$kr->{osminorversion}\". Processing will continue, but verify that you do not have an error in your buildkit configuration file. \n"; + } + $reponame .= '.'.$kr->{osminorversion}; + } + if ( (defined($::bldkit_config->{kit}{entries}[0]->{osarch})) && + ($::bldkit_config->{kit}{entries}[0]->{osarch} ne + $kr->{osarch} ) ) { + print "Warning: Kit osarch is set to \"$::bldkit_config->{kit}{entries}[0]->{osarch}\", but this does not match kitrepo $kr->{kitrepoid} osarch \"$kr->{osarch}\". Processing will continue, but verify that you do not have an error in your buildkit configuration file. \n"; + } + $reponame .= '-'.$kr->{osarch}; + $kr->{kitreponame} = $reponame; + } + + # Kitcomponent checks + foreach my $kc (@{$::bldkit_config->{kitcomponent}{entries}}) { + # Make sure all kitcomponent kitrepoids are defined + my $found = 0; + my %repo; + if ($debianflag){ + if ($kc->{basename} =~ /_/){ + print "Kit Component basename can not contain underscore.\n"; + return 1; + } + } + foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) { + if ($kc->{kitrepoid} eq $kr->{kitrepoid}) { + $found = 1; + %repo = %{$kr}; + $kc->{kitreponame} = $kr->{kitreponame}; + push (@{$kr->{packages}}, &comppkgname($kc,$kr)); + last; + } + } + if ( ! $found ) { + print "Kit Repository \"$kc->{kitrepoid}\" required by the Kit Component \"$kc->{basename}\" not defined in the Kit Build file.\n"; + return 1; + } + # Create full kitcomponent name + my $compname = $kc->{basename}; + $compname .= '-'.$kc->{version}; + $compname .= '-'.$kc->{release}; + $compname .= '-'.$repo{osbasename}; + $compname .= '-'.$repo{osmajorversion}; + if ( defined($repo{osminorversion}) ) { + $compname .= '.'.$repo{osminorversion}; + } + $compname .= '-'.$repo{osarch}; + $kc->{kitcompname} = $compname; + # Make sure all kitcomponent kitpkgdeps are defined + if (defined($kc->{kitpkgdeps})) { + foreach my $d (split(/,/, $kc->{kitpkgdeps})) { + $d =~ s/\s+//g; + $d =~ s/^([\w\.\-]+)[<>=]*.*$/$1/; + my $found = 0; + foreach my $kp (@{$::bldkit_config->{kitpackage}{entries}}) { + if ( $kp->{filename} =~ /^$d[\.\-]?/ ) { + foreach my $kprid (split(/,/, $kp->{kitrepoid})) { + $kprid =~ s/\s+//g; + if ($kc->{kitrepoid} eq $kprid) { + $found = 1; + last; + } + } + } + if ($found) { last; } + } + if ( !$found ) { + print "Kit Package \"$d\" required by the Kit Component \"$kc->{basename}\" was not found in the Kit Component\'s repository \"$kc->{kitrepoid}\".\n"; + return 1; + } + } + } + # Make sure all kitcomponent driverpacks are defined + if (defined($kc->{driverpacks})) { + my @drvs = split(/,/, $kc->{driverpacks}); + foreach my $d (@drvs) { + $d =~ s/\s+//g; + my $found = 0; + foreach my $kp (@{$::bldkit_config->{kitpackage}{entries}}) { + if ( $kp->{filename} eq $d ) { + foreach my $kprid (split(/,/, $kp->{kitrepoid})) { + $kprid =~ s/\s+//g; + if ($kc->{kitrepoid} eq $kprid) { + $found = 1; + last; + } + } + } + if ($found) { last; } + } + if ( !$found ) { + print "Driver package \"$d\" required by the Kit Component \"$kc->{basename}\" was not found in the Kit Component\'s repository \"$kc->{kitrepoid}\".\n"; + return 1; + } + } + } + # Make sure files exist + if (defined($kc->{exlist})){ + my $ck_file = $::workdir."/other_files/".$kc->{exlist}; + if (! -r $ck_file ) { + print "Exclude List file $ck_file defined in Kit Componenet \"$kc->{basename}\" does not exist or is not readable\n"; + return 1; + } + } + if (defined($kc->{preinstall})){ + my $ck_file = $::workdir."/scripts/".$kc->{preinstall}; + if (! -r $ck_file ) { + print "Pre-Install script $ck_file defined in Kit Componenet \"$kc->{basename}\" does not exist or is not readable\n"; + return 1; + } + } + if (defined($kc->{postinstall})){ + my $ck_file = $::workdir."/scripts/".$kc->{postinstall}; + if (! -r $ck_file ) { + print "Post-Install script $ck_file defined in Kit Componenet \"$kc->{basename}\" does not exist or is not readable\n"; + return 1; + } + } + if (defined($kc->{preuninstall})){ + my $ck_file = $::workdir."/scripts/".$kc->{preuninstall}; + if (! -r $ck_file ) { + print "Pre-Uninstall script $ck_file defined in Kit Componenet \"$kc->{basename}\" does not exist or is not readable\n"; + return 1; + } + } + if (defined($kc->{postuninstall})){ + my $ck_file = $::workdir."/scripts/".$kc->{postuninstall}; + if (! -r $ck_file ) { + print "Post-Uninstall script $ck_file defined in Kit Componenet \"$kc->{basename}\" does not exist or is not readable\n"; + return 1; + } + } + if (defined($kc->{preupgrade})){ + my $ck_file = $::workdir."/scripts/".$kc->{preupgrade}; + if (! -r $ck_file ) { + print "Pre-Upgrade script $ck_file defined in Kit Componenet \"$kc->{basename}\" does not exist or is not readable\n"; + return 1; + } + } + if (defined($kc->{postupgrade})){ + my $ck_file = $::workdir."/scripts/".$kc->{postupgrade}; + if (! -r $ck_file ) { + print "Post-Upgrade script $ck_file defined in Kit Componenet \"$kc->{basename}\" does not exist or is not readable\n"; + return 1; + } + } + if (defined($kc->{genimage_postinstall})){ + foreach my $script (split(/\,/, $kc->{genimage_postinstall})){ + $script =~ s/\s+//g; + my $ck_file = $::workdir."/scripts/".$script; + if (! -r $ck_file ) { + print "genimage_postinstall script $ck_file defined in Kit Componenet \"$kc->{basename}\" does not exist or is not readable\n"; + return 1; + } + } + } + if (defined($kc->{postbootscripts})){ + foreach my $script (split(/\,/, $kc->{postbootscripts})){ + $script =~ s/\s+//g; + my $ck_file = $::workdir."/scripts/".$script; + if (! -r $ck_file ) { + print "Postboot script $ck_file defined in Kit Componenet \"$kc->{basename}\" does not exist or is not readable\n"; + return 1; + } + } + } + if (defined($kc->{non_native_pkgs})){ + if ($kc->{non_native_pkgs} =~ /EXTERNALPKGS/) { + $::NON_NATIVE_PKGS->{$kc->{kitcompname}} = 1; + $::HAVE_NON_NATIVE_PKGS = 1; + } + } + } + + # Kitpackage checks + foreach my $kp (@{$::bldkit_config->{kitpackage}{entries}}) { + # determine if valid build method + if ( (defined($kp->{isexternalpkg})) || + (defined($kp->{rpm_prebuiltdir})) ) { + if ((defined($kp->{rpm_srpm})) || + (defined($kp->{rpm_srctarball})) || + (defined($kp->{rpm_spec})) || + (defined($kp->{rpm_srcdir})) ) { + print "Cannot determine build method for Kit Package $kp->{filename}. Conflicting attributes were specified.\n"; + return 1; + } + if ( !(defined($kp->{isexternalpkg})) ) { $kp->{isexternalpkg} = 'no'; } + my $orig_isext = $kp->{isexternalpkg}; + $kp->{isexternalpkg} =~ s/\s+//g; + $kp->{isexternalpkg} =~ tr/A-Z/a-z/; # convert to lowercase + if ( $kp->{isexternalpkg} eq '0' ) { $kp->{isexternalpkg} = 'no'; } + if ( $kp->{isexternalpkg} eq '1' ) { $kp->{isexternalpkg} = 'yes'; } + if ( ( $kp->{isexternalpkg} ne 'yes' ) && + ( $kp->{isexternalpkg} ne 'no' ) ) { + print "Error in definition for Kit Package $kp->{filename}. Invalid attribute value \'isexternalpkg=$orig_isext\'. Valid values are \'no\'|\'0\' or \'yes\'|\'1\'.\n"; + return 1; + } + if ( ( $kp->{isexternalpkg} eq 'yes' ) ) { + $::HAVE_EXTERNAL_PKG=1; + } + if ( ( $kp->{isexternalpkg} eq 'yes' ) && + (defined($kp->{rpm_prebuiltdir})) ) { + print "Error in definition for Kit Package $kp->{filename}. Do not specify \'isexternalpkg=$orig_isext\' with 'rpm_prebuiltdir'.\n"; + return 1; + } + } elsif (defined($kp->{rpm_srpm})) { + if ((defined($kp->{rpm_prebuiltdir})) || + (defined($kp->{rpm_srctarball})) || + (defined($kp->{rpm_spec})) || + (defined($kp->{rpm_srcdir})) ) { + print "Cannot determine build method for Kit Package $kp->{filename}. Conflicting attributes were specified.\n"; + return 1; + } + } elsif (defined($kp->{rpm_srctarball}) && + defined($kp->{rpm_spec}) ) { + if ((defined($kp->{rpm_prebuiltdir})) || + (defined($kp->{rpm_srpm})) || + (defined($kp->{rpm_srcdir})) ) { + print "Cannot determine build method for Kit Package $kp->{filename}. Conflicting attributes were specified.\n"; + return 1; + } + } elsif (defined($kp->{rpm_srcdir}) && + defined($kp->{rpm_spec}) ) { + if ((defined($kp->{rpm_prebuiltdir})) || + (defined($kp->{rpm_srpm})) || + (defined($kp->{rpm_srctarball})) ) { + print "Cannot determine build method for Kit Package $kp->{filename}. Conflicting attributes were specified.\n"; + return 1; + } + } else { + print "Cannot determine build method for Kit Package $kp->{filename}. Verify that your Kit Build File is correct. \n"; + return 1; + } + # Make sure all kitpackage kitrepoids are defined + foreach my $kprid (split(/,/, $kp->{kitrepoid})) { + my $found = 0; + $kprid =~ s/\s+//g; + foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) { + if ($kprid eq $kr->{kitrepoid}) { + $found = 1; + $kp->{kitreponame}.=",".$kr->{kitreponame}; + if ( !( $kp->{isexternalpkg} eq 'yes' ) ) { + push (@{$kr->{packages}}, $kp->{filename}); + } + last; + } + } + if ( ! $found ) { + print "Kit Repository \"$kprid\" required by the Kit Package \"$kp->{filename}\" is not defined in the Kit Build file.\n"; + return 1; + } + } + $kp->{kitreponame} =~ s/^,//; + if (!$::NEW_PARTIAL_KIT) { + # Make sure files exist + if (defined($kp->{rpm_spec})){ + my $ck_file = $::workdir."/source_packages/".$kp->{rpm_spec}; + if (! -r $ck_file ) { + print "RPM spec file $ck_file defined in Kit Package \"$kp->{filename}\" does not exist or is not readable\n"; + return 1; + } + } + if (defined($kp->{rpm_srcdir})){ + my $ck_dir = $::workdir."/source_packages/".$kp->{rpm_srcdir}; + if (! -d $ck_dir ) { + print "RPM source directory $ck_dir defined in Kit Package \"$kp->{filename}\" does not exist or is not readable\n"; + return 1; + } + } + if (defined($kp->{rpm_srctarball})){ + my $ck_file = $::workdir."/source_packages/".$kp->{rpm_srctarball}; + if (! -r $ck_file ) { + print "RPM source tarfile $ck_file defined in Kit Package \"$kp->{filename}\" does not exist or is not readable\n"; + return 1; + } + } + if (defined($kp->{rpm_srpm})){ + my $ck_file = $::workdir."/source_packages/".$kp->{rpm_srpm}; + if (! -r $ck_file ) { + print "Source RPM $ck_file defined in Kit Package \"$kp->{filename}\" does not exist or is not readable\n"; + return 1; + } + } + if (defined($kp->{rpm_prebuiltdir})){ + my $ck_dir = $::workdir."/source_packages/".$kp->{rpm_prebuiltdir}; + if (! -d $ck_dir ) { + print "Pre-built RPM directory $ck_dir defined in Kit Package \"$kp->{filename}\" does not exist or is not readable\n"; + return 1; + } + my $ck_file = $ck_dir."/".$kp->{filename}; + if ( system("ls $ck_file > /dev/null") ) { +# if (! -r $ck_file ) { + print "Pre-built rpm $ck_file defined in Kit Package \"$kp->{filename}\" does not exist or is not readable\n"; + return 1; + } + } + } + } +#use Data::Dumper; +#print Dumper($::bldkit_config->{kitrepo}); + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 comppkgname + + build a metapkg rpm filename for this kitcomponent + input: kitcomponent hash + kitrepo hash that this kitcomponent belongs to + +=cut + +#----------------------------------------------------------------------------- +sub comppkgname +{ + my $comp = shift; + + my $pkgname = $comp->{basename}; + if ($debianflag) { + $pkgname .= '_'.$comp->{version}; + $pkgname .= '-'.$comp->{release}; + $pkgname .= '_all.deb'; + } + else{ + $pkgname .= '-'.$comp->{version}; + $pkgname .= '-'.$comp->{release}; + $pkgname .= '.noarch.rpm'; + } + return $pkgname; +} + +#----------------------------------------------------------------------------- + +=head3 validate_repo + + validate whether a kit repo has been built + input: repo hash + returns rc: + 0 - repo status is DONE + 1 - repo status is NOT DONE + verbose mode displays message for first rpm not built + +=cut + +#----------------------------------------------------------------------------- +sub validate_repo +{ + my $repo = shift; + + my $repodir = $::base_repodir."/".$repo->{kitreponame}; + if ( ! -d $repodir ) { + if ($::VERBOSE) { + print "\n$repodir does not exist. No rpms have been built for this kitrepo. \n"; + } + return 1; + } + + # Make sure each repo pkg exists + foreach my $pkg (@{$repo->{packages}}){ + # skip check for kit component meta rpm if it includes + # external non-native pkgs + my $skip_check = 0; + foreach my $kc (@{$::bldkit_config->{kitcomponent}{entries}}) { + if ($repo->{kitrepoid} eq $kc->{kitrepoid}) { + my $kitpkgname = comppkgname($kc); + if (($kitpkgname eq $pkg) && + ($::NON_NATIVE_PKGS->{$kc->{kitcompname}}) ) { + $skip_check = 1; + last; + } + } + } + if ( ! $skip_check ) { + my $pkg_filename = $repodir.'/'.$pkg; + if ( system("ls $pkg_filename > /dev/null") ) { + if ($::VERBOSE) { + print "\nFile $pkg in directory $repodir does not exist or is not readable. \n"; + } + return 1; + } + } + } + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 validate_os + + validate whether a kit repo matches the current OS + input: repo hash + returns rc: + 0 - match + 1 - no match + verbose mode displays message for mismatch details + +=cut + +#----------------------------------------------------------------------------- +sub validate_os +{ + my $repo = shift; + + my $osinfo = xCAT::BuildKitUtils->osver(); + my ($osbasename,$osmore) = split(/\,/, $osinfo); + my ($osmajorversion,$osminorversion) = split(/\./, $osmore); + my $osarch=`uname -p`; + chomp($osarch); + $osinfo =~ s/\,//; + my $repo_osinfo = "$repo->{osbasename}$repo->{osmajorversion}"; + if (defined($repo->{osminorversion})){ + $repo_osinfo .= ".$repo->{osminorversion}"; + } + $repo_osinfo .= "-$repo->{osarch} "; + my $mismatch_msg = "The local host is running $osinfo-$osarch. This does not match the Kit Repository \"$repo->{kitrepoid}\" data: $repo_osinfo"; + if (defined($repo->{compat_osbasenames})){ + $mismatch_msg .= " or the compatible OS distros: $repo->{compat_osbasenames} "; + } + + + my $compat_match = 0; + if ($repo->{osbasename} ne $osbasename) { + if (defined($repo->{compat_osbasenames})){ + foreach my $cos (split(/,/, $repo->{compat_osbasenames})) { + if ($cos eq $osbasename) { + $compat_match = 1; + last; + } + } + } + if (!$compat_match) { + print "$mismatch_msg \n"; + if ($::VERBOSE) { + print "\n Local OS basename $osbasename does not match repository.\n"; + } + return 1; + } + } + if ( ($repo->{osmajorversion} ne $osmajorversion) && + (!$compat_match) ) { + print "$mismatch_msg \n"; + if ($::VERBOSE) { + print "\n Local OS major version $osmajorversion does not match repository.\n"; + } + return 1; + } + if (defined($repo->{osminorversion})) { + if ( ($repo->{osminorversion} ne $osminorversion) && + (!$compat_match) ) { + print "$mismatch_msg \n"; + if ($::VERBOSE) { + print "\n Local OS minor version $osminorversion does not match repository.\n"; + } + return 1; + } + } + if ($repo->{osarch} ne $osarch) { + print "$mismatch_msg \n"; + if ($::VERBOSE) { + print "\n Local OS arch $osarch does not match repository.\n"; + } + return 1; + } + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 build_kitcomp + + build a metapkg rpm for this kitcomponent + input: kitcomponent hash + +=cut + +#----------------------------------------------------------------------------- +sub build_kitcomp +{ + my $comp = shift; + my %repo; + my $rpmbuild_dir = $::workdir."/rpmbuild"; + my $tmpdir = $::workdir."/tmp/$comp->{kitcompname}"; + my $kcmetaname = comppkgname($comp); + + # If this kitcomponent has external non-native pkgs, + # skip the meta rpm build + if ( defined($::NON_NATIVE_PKGS) && + defined($::NON_NATIVE_PKGS->{$comp->{kitcompname}}) && + $::NON_NATIVE_PKGS->{$comp->{kitcompname}} ) { + if ($::VERBOSE) { + print "Kit component $comp->{kitcompname} has external non-native packages. Skipping rpm build for $kcmetaname. \n"; + } + return 0; + } + + # find the kitrepo hash for this component + foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) { + if ($comp->{kitrepoid} eq $kr->{kitrepoid}) { + %repo = %{$kr}; + last; + } + } + my $repodir = $::base_repodir."/".$repo{kitreponame}; + + # Fix the kitpkgdeps value for this kitcomponent + # For any kitpkgdep that has an rpm file in the repo, + # specifically reference it's version-release + if ( &update_kitcomp_kitpkgdeps($comp,$repodir) ) { return 1; } + + $::VALID_PRER_COMPONENT = 0; + + if ( !$::PREREQUISITE ) { + if ( $comp->{ospkgdeps} || $comp->{preinstall} || $comp->{preupgrade} || $comp->{preuninstall} ) { + if ( &gen_kitcomp_spec($comp,\%repo, 'PREREQUISITE') ) { return 1; } + + # run the rpmbuild command + my $curdir = $::workdir; + my $cmd = "rm -Rf $curdir/rpmbuild"; + system($cmd); + my $avoiderr = $rpmbuild_dir."/BUILDROOT/prep_".$comp->{basename}; + $avoiderr .= "-$comp->{version}-$comp->{release}.$repo{osarch}"; + mkpath($avoiderr); + $avoiderr = $rpmbuild_dir."/BUILD/"; + mkpath($avoiderr); + $avoiderr = $rpmbuild_dir."/SRPMS/"; + mkpath($avoiderr); + $avoiderr = $rpmbuild_dir."/RPMS/noarch/"; + mkpath($avoiderr); + + # Read the kit component prerequisite rpm name + + my $specfile = $::workdir."/tmp/$comp->{kitcompname}-prep.spec"; + my $rpmbuild_cmd = "rpmbuild --define \"_topdir $rpmbuild_dir\" -ba $specfile"; + + # don't want debug info - 3845 +# if (!$::VERBOSE) { + $rpmbuild_cmd .= ' --quiet '; +# } + if ( system($rpmbuild_cmd) ) { + print "Error running rpmbuild command for kit component $comp->{kitcompname} meta package\n"; + return 1; + } + my @built_rpms = `find $rpmbuild_dir/RPMS -name "*.rpm"`; + foreach my $rpm (@built_rpms) { + chomp($rpm); + if ( system ("cp -fp $rpm $repodir") ) { + print "Error copying rpm $rpm to build repo directory $repodir \n"; + return 1; + } + } + + $::VALID_PRER_COMPONENT = 1; + + } + + if ( &gen_kitcomp_spec($comp,\%repo, 'METARPM') ) { return 1; } + } else { + # Create spec file for this kit component + if ( &gen_kitcomp_spec($comp,\%repo, 'ALL') ) { return 1; } + } + + # run the rpmbuild command + my $curdir = $::workdir; + my $cmd = "rm -Rf $curdir/rpmbuild"; + system($cmd); + my $avoiderr = $rpmbuild_dir."/BUILDROOT/".$comp->{basename}; + $avoiderr .= "-$comp->{version}-$comp->{release}.$repo{osarch}"; + mkpath($avoiderr); + $avoiderr = $rpmbuild_dir."/BUILD/"; + mkpath($avoiderr); + $avoiderr = $rpmbuild_dir."/SRPMS/"; + mkpath($avoiderr); + $avoiderr = $rpmbuild_dir."/RPMS/noarch/"; + mkpath($avoiderr); + + # Read the kit component meta rpm name + + my $specfile = $::workdir."/tmp/$comp->{kitcompname}.spec"; + my $rpmbuild_cmd = "rpmbuild --define \"_topdir $rpmbuild_dir\" -ba $specfile"; + + # Copy in any non-native packages + if (defined($comp->{non_native_pkgs}) ) { + mkpath($tmpdir); + mkpath("$rpmbuild_dir/SOURCES"); + my $sourcedir = $::workdir."/source_packages"; + + foreach my $pkgfile (split(/,/, $comp->{non_native_pkgs})) { + my $pkg_file; + my ($key,$value) = split /:/,$pkgfile; + if ("$key" =~ /EXTERNALPKGS/) { + $pkg_file = $value; + } else { + $pkg_file = $key; + } + + $cmd = "cp -p $sourcedir/$pkg_file $tmpdir"; + if ( system($cmd) ) { + print "Error copying non-native package file $sourcedir/$pkg_file to $tmpdir\n"; + return 1; + } + } + $cmd = "cd $tmpdir/..;mv $comp->{kitcompname} $comp->{basename}; tar -czf $rpmbuild_dir/SOURCES/$comp->{basename}.tar.gz $comp->{basename};mv $comp->{basename} $comp->{kitcompname}"; + if ( system($cmd) ) { + print "Error creating tarfile $rpmbuild_dir/SOURCES/$comp->{kitreponame}-$comp->{kitcompname}.tar from $sourcedir/*"; + return 1; + } + } + + # - don't want debug info - 3845 +# if (!$::VERBOSE) { + $rpmbuild_cmd .= ' --quiet '; +# } + + if ( system($rpmbuild_cmd) ) { + print "Error running rpmbuild command for kit component $comp->{kitcompname} meta package\n"; + return 1; + } + my @built_rpms = `find $rpmbuild_dir/RPMS -name "*.rpm"`; + foreach my $rpm (@built_rpms) { + chomp($rpm); + if ( system ("cp -fp $rpm $repodir") ) { + print "Error copying rpm $rpm to build repo directory $repodir \n"; + return 1; + } + } + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 update_kitcomp_kitpkgdeps + + Update the kitcomponent kitpkgdeps string + For any kitpkgdep that does not explicitly specify a version-release + comparison string and for which an rpm exists in the repo, + query the rpm for its version-release info and set an explicit + comparison string. + Reason we need to do all this: We need to force yum/zypper to update + the product rpms. A simple package name in the kitcomponent meta rpm + REQUIRES entry will not cause the product to get updated if an older + version is already installed. Need to explicitly require this version + and release of the product package. + input: kitcomponent hash + kitrepo directory + +=cut + +#----------------------------------------------------------------------------- +sub update_kitcomp_kitpkgdeps +{ + my $comp = shift; + my $repodir = shift; + + if (defined($comp->{kitpkgdeps})) { + # we have some rpms listed in buildkit.conf file + my $new_kitpkgdeps = ''; + foreach my $d (split(/,/, $comp->{kitpkgdeps})) { + $d =~ s/\s+//g; + my $d_short = $d; + # strip off everything after ">=" + $d_short =~ s/^([\w\.\-]+)[<>=]*.*$/$1/; + + # if they are the same then there was no v/r info provided + if ( $d_short eq $d ) { + # no version-release comparisons specified for this kitpkgdep + # do we have this rpm file? + # get a list of any matches + my $lscmd = "cd $repodir; /bin/ls $d-\[0-9\]\*.rpm 2>/dev/null"; + my @rpmlist = `$lscmd`; + + if ( scalar(@rpmlist) == 0) { + next; + } + + # get the newest version there is + my $newestrpm = xCAT::BuildKitUtils->get_latest_version($repodir, \@rpmlist); + + if (!$newestrpm) { + print "Error: Could not determine the latest version of rpm $d contained in $repodir. \n"; + next; + } + + # get the Version and release values for this rpm + my $cmd = "rpm -q --qf \"%{NAME} >= %{VERSION}-%{RELEASE}\" -p $repodir/$newestrpm 2>/dev/null"; + if ($::VERBOSE) { + print "running rpm query to get version-release info: \n $cmd \n"; + } + + my $new_d = `$cmd`; + if (!$new_d) { + print "Error: Could not determine the latest version of rpm $d. \n"; + next; + } + + chomp($new_d); + if ($::VERBOSE) { + print "output: \n \'$new_d\' \n"; + } + if ( $new_d ne '' ) { + $new_kitpkgdeps .= "$new_d,"; + } else { + $new_kitpkgdeps .= "$d,"; + } + } else { + $new_kitpkgdeps .= "$d,"; + } + } + + $new_kitpkgdeps =~ s/(\,)*$//; + $comp->{kitpkgdeps} = $new_kitpkgdeps; + } + + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 gen_kitcomp_spec + + generate the rpm spec file for the kitcomponent metapkg rpm + input: kitcomponent hash + kitrepo hash + +=cut + +#----------------------------------------------------------------------------- +sub gen_kitcomp_spec +{ + my $comp = shift; + my $repo = shift; + my $level = shift; + my $scriptdir = $::workdir."/scripts/"; + my $tmpdir = $::workdir."/tmp/"; + + # read in the template spec file + my $spec_template = $::XCATSHARE."/kits/kitcomponent.spec.template"; + my $SF; + unless ( open( $SF, "<", $spec_template ) ) { + print "Error attempting to open the xCAT Kit Component template file $spec_template. \n"; + return 1; + } + if ($::VERBOSE) { + print "Reading the xCAT Kit Component template file $spec_template. \n"; + } + my @lines = <$SF>; + close $SF; + + my $kitname = $::bldkit_config->{kit}{entries}[0]->{basename}; + my $kitcompname = $comp->{kitcompname}; + + my ($prescript,$postscript,$preupscript,$postupscript,$preunscript,$postunscript,$nonnativepkgs,$sourcetar,$setup,$files) = ' '; + if ( $level eq 'PREREQUISITE' || $level eq 'ALL' ) { + if (defined($comp->{preinstall})) { + $prescript = &load_script("$scriptdir$comp->{preinstall}"); + $prescript = "if [ \"\$1\" = \"1\" ] ; then\n" . $prescript . "\nfi";} + if (defined($comp->{preupgrade})) { + $preupscript = &load_script("$scriptdir$comp->{preupgrade}"); + $preupscript = "if [ \"\$1\" = \"2\" ] ; then\n" . $preupscript . "\nfi";} + if (defined($comp->{preuninstall})) { + $preunscript = &load_script("$scriptdir$comp->{preuninstall}"); } + } + if ( $level eq 'METARPM' || $level eq 'ALL' ) { + if (defined($comp->{postinstall})) { + $postscript = &load_script("$scriptdir$comp->{postinstall}"); + $postscript = "if [ \"\$1\" = \"1\" ] ; then\n" . $postscript . "\nfi"; } + if (defined($comp->{postupgrade})) { + $postupscript = &load_script("$scriptdir$comp->{postupgrade}"); + $postupscript = "if [ \"\$1\" = \"2\" ] ; then\n" . $postupscript . "\nfi";} + if (defined($comp->{postuninstall})) { + $postunscript = &load_script("$scriptdir$comp->{postuninstall}"); } + if (defined($comp->{non_native_pkgs})) { + $nonnativepkgs = "\n"; + $nonnativepkgs .= "mkdir -p \$RPM_BUILD_ROOT/opt/xcat/kits/$kitname/$kitcompname \n"; + $nonnativepkgs .= "cp -a * \$RPM_BUILD_ROOT/opt/xcat/kits/$kitname/$kitcompname \n"; + $sourcetar = "Source: $comp->{basename}.tar.gz"; + $setup = "\%setup -q -n $comp->{basename}"; + $files = "/opt/xcat/kits"; + } + } + + # remove lines that correspond to optional tags that have no values + # in this instance. Adding lines to the spec file that have + # no values will cause a build error. + my @newlines; + foreach my $l (@lines) { + chomp; + # don't add vendor,packager,url to spec file unless we have a value + if ($l =~ /INSERT_vendor_HERE/) { + if (!$::bldkit_config->{kit}{entries}[0]->{vendor} ) { + next; + } + } + if ($l =~ /INSERT_packager_HERE/) { + if (!$::bldkit_config->{kit}{entries}[0]->{packager} ) { + next; + } + } + if ($l =~ /INSERT_url_HERE/) { + if (!$::bldkit_config->{kit}{entries}[0]->{url}) { + next; + } + } + push @newlines, $l; + } + @lines=@newlines; + + if ( $level eq 'ALL' ) { + for (@lines) { + chomp; + s/<<>>/$kitname/; + s/<<>>/$comp->{basename}/; + s/<<>>/$comp->{version}/; + s/<<>>/$comp->{release}/; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{kitlicense}/; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{vendor}/; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{packager}/; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{url}/; + s/<<>>/$comp->{ospkgdeps}/; + s/<<>>/$comp->{kitpkgdeps}/; + s/<<>>/$comp->{kitcompdeps}/; + s/<<>>/$comp->{description}/; + s/<<>>/$nonnativepkgs/; + s/<<>>/$sourcetar/; + s/<<>>/$setup/; + s/<<>>/$files/; + s/<<>>/$prescript/; + s/<<>>/$postscript/; + s/<<>>/$preupscript/; + s/<<>>/$postupscript/; + s/<<>>/$preunscript/; + s/<<>>/$postunscript/; + } + } elsif ( $level eq 'PREREQUISITE' ) { + for (@lines) { + chomp; + s/<<>>/$kitname/; + s/<<>>/prep_$comp->{basename}/; + s/<<>>/$comp->{version}/; + s/<<>>/$comp->{release}/; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{kitlicense}/; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{vendor}/; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{packager}/; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{url}/; + s/<<>>/$comp->{ospkgdeps}/; + s/<<>>//; + s/<<>>//; + s/<<>>/$comp->{description}/; + s/<<>>//; + s/<<>>//; + s/<<>>//; + s/<<>>//; + s/<<>>/$prescript/; + s/<<>>//; + s/<<>>/$preupscript/; + s/<<>>//; + s/<<>>/$preunscript/; + s/<<>>//; + } + + } elsif ( $level eq 'METARPM' ) { + for (@lines) { + chomp; + s/<<>>/$kitname/; + s/<<>>/$comp->{basename}/; + s/<<>>/$comp->{version}/; + s/<<>>/$comp->{release}/; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{kitlicense}/; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{vendor}/; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{packager}/; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{url}/; + s/<<>>//; + s/<<>>/$comp->{kitpkgdeps}/; + #Update kitcompdeps for prep_ + if ( $::VALID_PRER_COMPONENT ) { + s/<<>>/$comp->{kitcompdeps},prep_$comp->{basename}/; + } else { + s/<<>>/$comp->{kitcompdeps}/; + } + s/<<>>/$comp->{description}/; + s/<<>>/$nonnativepkgs/; + s/<<>>/$sourcetar/; + s/<<>>/$setup/; + s/<<>>/$files/; + s/<<>>//; + s/<<>>/$postscript/; + s/<<>>//; + s/<<>>/$postupscript/; + s/<<>>//; + s/<<>>/$postunscript/; + } + } + + # Write the generated spec file + mkpath($tmpdir); + + my $fn; + my $NSF; + if ( $level eq 'PREREQUISITE' ) { + $fn = $comp->{kitcompname}."-prep.spec" + } else { + $fn = $comp->{kitcompname}.".spec" + } + unless ( open( $NSF, ">$tmpdir$fn" ) ) { + return 1; + } + if ($::VERBOSE) { + print "Created kitcomponent spec file \'$tmpdir$fn\'\n"; + + } + foreach my $line (@lines) { + print $NSF $line,"\n"; + } + + close($NSF); + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 build_kitcomp_debian + + + +=cut + +#----------------------------------------------------------------------------- +sub build_kitcomp_debian{ + my $comp = shift; + my %repo; + my $debbuilddir = $::workdir."/debbuild/".$comp->{kitcompname}; + my $kcmetaname = comppkgname($comp); + + #If this kitcomponent has external non-native pkgs, + #skip the meta package build + if ( defined($::NON_NATIVE_PKGS) && + defined($::NON_NATIVE_PKGS->{$comp->{kitcompname}}) && + $::NON_NATIVE_PKGS->{$comp->{kitcompname}} ) { + if ($::VERBOSE) { + print "Kit component $comp->{kitcompname} has external non-native packages. Skipping rpm build for $kcmetaname. \n"; + } + return 0; + } + # find the kitrepo hash for this component + foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) { + if ($comp->{kitrepoid} eq $kr->{kitrepoid}) { + %repo = %{$kr}; + last; + } + } + + #run the dpkg-buildpackage command + my $curdir = $::workdir; + my $cmd = "rm -Rf $debbuilddir"; + system($cmd); + mkpath($debbuilddir); + + #Create debian directory for this kit component + if ( &gen_kitcomp_debdir($comp,\%repo) ) { return 1; } + + if (defined($comp->{non_native_pkgs}) ) { + my $sourcedir = $::workdir."/source_packages"; + + foreach my $pkgfile (split(/,/, $comp->{non_native_pkgs})) { + my $pkg_file; + my ($key,$value) = split /:/,$pkgfile; + if ("$key" =~ /EXTERNALPKGS/) { + $pkg_file = $value; + } else { + $pkg_file = $key; + } + + $cmd = "cp -p $sourcedir/$pkg_file $debbuilddir"; + if ( system($cmd) ) { + print "Error copying non-native package file $sourcedir/$pkg_file to debbuilddir\n"; + return 1; + } + } + } + my $compversion = $comp->{version} . "-" . $comp->{release}; + my $buildstring = "Kit component build package."; + my $debianbuildcmd = "cd $debbuilddir;dch -v $compversion -b -c debian/changelog $buildstring;dpkg-buildpackage -uc -us"; + if ( !$::NON_NATIVE_PKGS->{$comp->{kitcompname}} ) { + if ( system($debianbuildcmd) ) { + print "Error running \"dpkg-buildpackage -uc -us\" command for kit component $comp->{kitcompname} meta package\n"; + return 1; + } + my $repodir = $::base_repodir."/".$repo{kitreponame}; + my @builtdebs = `find $::workdir/debbuild -maxdepth 1 -name "*.deb"`; + foreach my $deb (@builtdebs) { + chomp($deb); + if ( system ("cp -fp $deb $repodir") ) { + print "Error copying package $deb to build repo directory $repodir \n"; + return 1; + } + } + } + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 gen_kitcomp_debdir + + + +=cut + +#----------------------------------------------------------------------------- +sub gen_kitcomp_debdir{ + my $comp = shift; + my $repo = shift; + my $scriptdir = $::workdir."/scripts/"; + my $combuilddir = $::workdir."/debbuild/".$comp->{kitcompname}; + + #copy the debian dir template to the build path + mkpath("$combuilddir/debian"); + my $cmd = "cp -Rf " . $::XCATSHARE . "/kits/debian_template/* $combuilddir/debian/"; + system($cmd); + + my $kitname = $::bldkit_config->{kit}{entries}[0]->{basename}; + my $kitcompname = $comp->{kitcompname}; + my $upgradeflag = $comp->{basename} . ".tmp"; + + my ($prescript,$postscript,$preupscript,$postupscript,$preunscript,$postunscript,$nonnativepkgs) = ''; + if (defined($comp->{preinstall})) { + $prescript = &load_script("$scriptdir$comp->{preinstall}"); + } + if (defined($comp->{postinstall})) { + $postscript = &load_script("$scriptdir$comp->{postinstall}"); + } + if (defined($comp->{preupgrade})) { + $preupscript = &load_script("$scriptdir$comp->{preupgrade}"); + } + if (defined($comp->{postupgrade})) { + $postupscript = &load_script("$scriptdir$comp->{postupgrade}"); + } + if (defined($comp->{preuninstall})) { + $preunscript = &load_script("$scriptdir$comp->{preuninstall}"); + } + if (defined($comp->{postuninstall})) { + $postunscript = &load_script("$scriptdir$comp->{postuninstall}"); + } + if (defined($comp->{non_native_pkgs})) { + $nonnativepkgs = "\n"; + $nonnativepkgs .= "mkdir -p \$RPM_BUILD_ROOT/opt/xcat/kits/$kitname/$kitcompname \n"; + $nonnativepkgs .= "cp -a * \$RPM_BUILD_ROOT/opt/xcat/kits/$kitname/$kitcompname \n"; + } + + #replace all special sub string in all files under debian + unless (opendir(DH, "${combuilddir}/debian/")){ + print "Can not open the xCAT Kit Component debian dir: ${combuilddir}/debian/"; + return 1; + } + + foreach (readdir(DH)){ + my $file = "${combuilddir}/debian/$_"; + if ( -d $file){ + next; + } + + unless ( open ( FH, "<", $file )){ + print "Error attempting to open the xCAT Kit Component ${kitcompname}'s debian template file $file.\n"; + close(DH); + return 1; + } + + if ($::VERBOSE){ + print "Reading the xCAT Kit Component ${kitcompname}'s debian template file $file. \n"; + } + my @lines = ; + close(FH); + for(@lines) { + chomp; + s/<<>>/$comp->{basename}/; + s/<<>>/$comp->{ospkgdeps}/; + s/<<>>/$comp->{kitpkgdeps}/; + s/<<>>/$comp->{kitcompdeps}/; + s/<<>>/$comp->{description}/; + s/<<>>/$upgradeflag/; + s/<<>>/$prescript/; + s/<<>>/$postscript/; + s/<<>>/$preupscript/; + s/<<>>/$postupscript/; + s/<<>>/$preunscript/; + s/<<>>/$postunscript/; + } + my $joined_lines = join("\n", @lines); + @lines = split(/\\n/,$joined_lines); + + open (FH, ">", $file); + if ($::VERBOSE){ + print "Created kitcomponent ${kitcompname}'s build file under debian dir $file"; + } + print FH @lines; + close(FH); + } + closedir(DH); + + if (defined($comp->{non_native_pkgs})) { + unless (open (FH, ">", "${combuilddir}/debian/dir")) { + print "Error attempting to open the xCAT Kit Component ${kitcompname}'s debian file dir.\n"; + return 1; + } + print FH "opt/xcat/kits/$kitname/$kitcompname/"; + close (FH); + + unless ( open (FH, ">", "${combuilddir}/debian/install") ){ + print "Error attempting to open the xCAT Kit Component ${kitcompname}'s debian file dir.\n"; + return 1; + } + foreach my $pkgfile (split(/,/, $comp->{non_native_pkgs})) { + my $pkgname = ''; + my ($key,$value) = split /:/,$pkgfile; + if ("$key" =~ /EXTERNALPKGS/) { + $pkgname = $value; + } else { + $pkgname = $key; + } + print FH "$pkgname opt/xcat/kits/$kitname/$kitcompname/ \n"; + } + close(FH); + } + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 load_script + + load a kitcomponent script into a single return string + with imbedded newline chars + input: fullpath of scriptname + +=cut + +#----------------------------------------------------------------------------- +sub load_script +{ + my $scriptname = shift; + my $SF; + unless ( open( $SF, "<", $scriptname ) ) { + print "Error attempting to open the file $scriptname. \n"; + return; + } + if ($::VERBOSE) { + print "Reading the file $scriptname. \n"; + } + my @lines = <$SF>; + close $SF; + + my $script_contents = join('', @lines); + return $script_contents; +} + +#----------------------------------------------------------------------------- + +=head3 create_kitconf + + Create the kit configuration file to put into the kit tar file. + +=cut + +#----------------------------------------------------------------------------- +sub create_kitconf +{ + # Build kit config file entries from buildkit config input + my $kitname = $::bldkit_config->{kit}{entries}[0]->{kitname}; + foreach my $s (keys %{$::bldkit_config}) { + if (! defined($::buildkit_def{$s}) ) { next;} + if ( $s eq 'kitpackage' ) { next; } + my $li = 0; + foreach my $se (@{$::bldkit_config->{$s}{entries}}) { + $::kit_config->{$s}{entries}[$li]->{kitname} = $kitname; + # copy all defined attrs over + foreach my $a (keys %{$::buildkit_def{$s}}) { + if (( $::buildkit_def{$s}{$a}->{cp_to_kitconfig} eq '1' ) && + ( defined ($se->{$a}) ) ) { + if ( $s eq 'kitcomponent' ) { + if ($a eq 'kitpkgdeps') { + my $value; + foreach my $d (split(/,/, $se->{$a})) { + $d =~ s/\s+//g; + $d =~ s/^([\w\.\-]+)[<>=]*.*$/$1/; + $value .= "$d,"; + } + $value =~ s/(\,)*$//; + $se->{$a} = $value; + } + } + $::kit_config->{$s}{entries}[$li]->{$a} = $se->{$a}; + } + # cp_to_kitconfig=2 means copy the file to the new kit + # but only do the copy if this is a final kit build + if (( $::buildkit_def{$s}{$a}->{cp_to_kitconfig} eq '2' ) && + ( defined ($se->{$a}) ) && + !$::HAVE_EXTERNAL_PKG && !$::HAVE_NON_NATIVE_PKGS ) { + my $prefix = "$kitname"; + if ( $s eq 'kitcomponent' ) { + $prefix = "$::bldkit_config->{$s}{entries}[$li]->{kitcompname}"; + if (($a eq 'postbootscripts') || + ($a eq 'genimage_postinstall')) { + $prefix = "KIT_".$prefix; + } + if ( !($::kit_config->{$s}{entries}[$li]->{$a} = + &cp_to_builddir($a,$se->{$a},$::workdir.'/'.$::buildkit_def{$s}{$a}->{base_dir},$prefix, $::bldkit_config->{$s}{entries}[$li])) ) { + return 1; + } + } else { + if ( !($::kit_config->{$s}{entries}[$li]->{$a} = + &cp_to_builddir($a,$se->{$a},$::workdir.'/'.$::buildkit_def{$s}{$a}->{base_dir},$prefix)) ) { + return 1; + } + } + } + } + # Handle special attrs, these 3 attributes did not defined in the buildkit.conf, special cases. + if ( $s eq 'kitrepo' ) { + $::kit_config->{$s}{entries}[$li]->{kitreponame} = + $se->{kitreponame}; + } elsif ( $s eq 'kitcomponent' ) { + $::kit_config->{$s}{entries}[$li]->{kitcompname} = + $se->{kitcompname}; + $::kit_config->{$s}{entries}[$li]->{kitreponame} = + $se->{kitreponame}; + if ( !$::PREREQUISITE and ($se->{ospkgdeps} || $se->{preinstall} || $se->{preupgrade} || $se->{preuninstall}) ) { + $::kit_config->{$s}{entries}[$li]->{prerequisite} = + "prep_" . $se->{basename}; + } + } + $li++; + } + } + + # Handle external packages + if ($::HAVE_EXTERNAL_PKG) { + foreach my $kp (@{$::bldkit_config->{kitpackage}{entries}}) { + if ($kp->{isexternalpkg} eq 'yes') { + my %current_entry; + $current_entry{filename} = $kp->{filename}; + $current_entry{kitreponame} = $kp->{kitreponame}; + push ( @{ $::kit_config->{EXTERNALPKG}{'entries'} }, {%current_entry}); + } + } + } + + + # Handle non_native_pkgs + foreach my $kc (@{$::bldkit_config->{kitcomponent}{entries}}) { + if ($::NON_NATIVE_PKGS->{$kc->{kitcompname}}) { + my @nativefiles; + foreach my $pkgfile (split(/,/, $kc->{non_native_pkgs})) { + my ($key,$value) = split /:/,$pkgfile; + if ("$key" =~ /EXTERNALPKGS/) { + push (@nativefiles, $value); + } + } + + my %current_entry; + $current_entry{filename} = join ',', @nativefiles; + $current_entry{kitcompname} = $kc->{kitcompname}; + $current_entry{basename} = $kc->{basename}; + $current_entry{kitreponame} = $kc->{kitreponame}; + push ( @{ $::kit_config->{NONNATIVEPKGS}{'entries'} }, {%current_entry}); + } + } + + + # Write Kit Config File + my @lines; + my $li=0; + $lines[$li++] = "# Kit Configuration File for $kitname generated by buildkit\n"; + $lines[$li++] = "kitbuildinfo: \n"; + my $xCAT_buildkit_version = ''; + if ( $debianflag ){ + $xCAT_buildkit_version = `dpkg-query --show -f='\${Version}' xcat-buildkit`; + } + else{ + $xCAT_buildkit_version = `rpm -q --qf \"%{VERSION}-%{RELEASE}\" xCAT-buildkit`; + } + $lines[$li++] = " xCAT_version = $xCAT_buildkit_version \n"; + $lines[$li++] = " build_date = ".localtime()."\n"; + $lines[$li++] = " kitframework = $::KITFRAMEWORK \n"; + $lines[$li++] = " compatible_kitframeworks = $::COMPATIBLE_KITFRAMEWORKS \n"; + + foreach my $s ('kit','kitrepo','kitcomponent','EXTERNALPKG', 'NONNATIVEPKGS') { + foreach my $se (@{$::kit_config->{$s}{entries}}) { + $lines[$li++] = "$s: \n"; + foreach my $a (keys %{$se}) { + $lines[$li++] = " $a = $se->{$a} \n"; + } + } + } + + if ( (! -d $::deploy_dir) && (! mkpath($::deploy_dir)) ) { + print "Error creating build directory $::deploy_dir.\n"; + return; + } + + my $full_kit_conf = $::deploy_dir."/".$::kit_conf; + my $NCF; + unless ( open( $NCF, ">$full_kit_conf" ) ) { + return 1; + } + if ($::VERBOSE) { + print "Wrote new kit configuration file $full_kit_conf \n"; + } + print $NCF @lines; + close($NCF); + + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 cp_to_builddir + + Copy specified files into the build directory renaming as indicated + and substituting strings if needed + +=cut + +#----------------------------------------------------------------------------- +sub cp_to_builddir +{ + my $type = shift; + my $files = shift; + my $from_dir = shift; + my $prefix = shift; + my $kitcomp = shift; + + my $copied_files; + my $other_files = $::deploy_dir."/other_files"; + if ( (! -d $other_files) && (! mkpath($other_files)) ) { + print "Error creating build directory $other_files.\n"; + return; + } + foreach my $file (split(/\,/, $files)) { + $file =~ s/\s+//g; + my $from_file = $from_dir."/".$file; + my $from_file_base = basename($file); + my $to_file_base = $prefix."_".$from_file_base; + my $to_file = $other_files."/".$to_file_base; + + # Read in the file + my $FF; + unless ( open( $FF, "<", $from_file ) ) { + print "The Kit file $from_file could not be read. \n"; + return 1; + } + my @lines = <$FF>; + for (@lines) { + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{kitname}/g; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{basename}/g; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{version}/g; + s/<<>>/$::bldkit_config->{kit}{entries}[0]->{release}/g; + if ( defined ($kitcomp) ) { + s/<<>>/$kitcomp->{kitcompname}/g; + s/<<>>/$kitcomp->{basename}/g; + s/<<>>/$kitcomp->{version}/g; + s/<<>>/$kitcomp->{release}/g; + } + } + # Write the file back out + my $TF; + unless ( open( $TF, ">$to_file" ) ) { + print "Error copying file $from_file to build directory $other_files \n"; + return 1; + } + if ($::VERBOSE) { + print "Copied $from_file to $to_file replacing kit and kitcomponent strings as needed. \n"; + } + print $TF @lines; + close($TF); + + $copied_files .= ",$to_file_base"; + + if (($type eq 'postbootscripts') || + ($type eq 'genimage_postinstall')) { + system("chmod 755 $to_file"); + } + } + $copied_files =~ s/^\,//; + return $copied_files; +} + +#----------------------------------------------------------------------------- + +=head3 create_builddir + + Create the build directory and copy in all required files for building + the kit tar file. + +=cut + +#----------------------------------------------------------------------------- +sub create_builddir +{ + my $kitname = $::bldkit_config->{kit}{entries}[0]->{kitname}; + + # Note: + # - repos already created and validated + # - kit.conf file already created + # - exlists, postbootscripts, and deployparams already copied + + # copy plugins to build dir and edit to insert correct plugin and kit names + my $plugin_dir = $::deploy_dir."/plugins"; + if ( -d "$::workdir/plugins" ) { + if ( (! -d $plugin_dir) && (! mkpath($plugin_dir)) ) { + print "Error creating build directory $plugin_dir.\n"; + return 1; + } + + foreach my $plugin (<$::workdir/plugins/*.pm>){ + my $plugin_base = basename($plugin); + my $mod_kitname = $kitname; + $mod_kitname =~ s/\-/\_/g; + $mod_kitname =~ s/\./\_/g; + my $to_plugin = $plugin_dir."/".$mod_kitname."_".$plugin_base; + + if ( system("cp -fp $plugin $to_plugin") ) { + # non-zero return from system call + print "Error copying plugin file $plugin to build directory $plugin_dir \n"; + return 1; + } + if (&edit_plugin($to_plugin)) { return 1;} + } + } + + # copy docs to build dir + if ( -d "$::workdir/docs" ) { + if ( system("cp -fRp $::workdir/docs $::deploy_dir") ) { + # non-zero return from system call + print "Error copying doc files $::workdir/docs to build directory $::deploy_dir \n"; + return 1; + } + } + + # Edit deploy params file to make sure correct format for xCAT + if (defined($::kit_config->{kit}{entries}[0]->{kitdeployparams})){ + my $kd_file = $::deploy_dir."/other_files/".$::kit_config->{kit}{entries}[0]->{kitdeployparams}; + if (&edit_deployparams($kd_file)) { return 1;} + } + + if ($::HAVE_EXTERNAL_PKG or $::HAVE_NON_NATIVE_PKGS) { + # Copy the kitcomponent meta rpm spec if there is external non_native_pkgs. + if ( $debianflag ) { + foreach my $comp (keys %{$::NON_NATIVE_PKGS}) { + my $kitrepo; + foreach my $kc (@{$::bldkit_config->{kitcomponent}{entries}}) { + if ($comp eq $kc->{kitcompname}) { + $kitrepo = $kc->{kitreponame} + } + } + mkpath("$::deploy_dir/tmp/"); + my $cmd = "cp -fRP $::workdir/debbuild/$comp $::deploy_dir/tmp/$comp"; + if ( system("$cmd") ) { + print "Error copying kitcomponent meta debian build file $::workdir/debbuild/$comp to build directory $::deploy_dir \n"; + return 1; + } + } + } + + # Copy over the original buildkit.conf file and input files + # to help make addpkgs processing easier later + mkpath("$::deploy_dir/build_input/"); + if ( system("cp -fp $::full_buildkit_conf $::deploy_dir/build_input") ) { + # non-zero return from system call + print "Error copying buildkit config file $::full_buildkit_conf to build directory $::deploy_dir/build_input \n"; + return 1; + } + } + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 create_PARTIAL_builddir + + Create the build directory for a PARTIAL kit (needs external pkgs) + and copy in all required files for building the kit tar file. + This includes most build input without editting files since + they will need to be generated at addpkgs time. + +=cut + +#----------------------------------------------------------------------------- +sub create_PARTIAL_builddir +{ + my $kitname = $::bldkit_config->{kit}{entries}[0]->{kitname}; + + # Note: + # - repos already created and validated + # - kit.conf file already created + # - exlists, postbootscripts, and deployparams already copied + + # copy docs to build dir + if ( -d "$::workdir/docs" ) { + if ( system("cp -fRp $::workdir/docs $::deploy_dir") ) { + # non-zero return from system call + print "Error copying doc files $::workdir/docs to build directory $::deploy_dir \n"; + return 1; + } + } + + # Copy over the original buildkit.conf file and input files + # to help make addpkgs processing easier later + mkpath("$::deploy_dir/build_input/"); + if ( system("cp -fp $::full_buildkit_conf $::deploy_dir/build_input") ) { + # non-zero return from system call + print "Error copying buildkit config file $::full_buildkit_conf to build directory $::deploy_dir/build_input \n"; + return 1; + } + if ( -d "$::workdir/other_files" ) { + if ( system("cp -fpR $::workdir/other_files $::deploy_dir/build_input") ) { + # non-zero return from system call + print "Error copying $::workdir/otherfiles to build directory $::deploy_dir/build_input \n"; + return 1; + } + } + if ( -d "$::workdir/plugins" ) { + if ( system("cp -fpR $::workdir/plugins $::deploy_dir/build_input") ) { + # non-zero return from system call + print "Error copying $::workdir/plugins to build directory $::deploy_dir/build_input \n"; + return 1; + } + } + if ( -d "$::workdir/scripts" ) { + if ( system("cp -fpR $::workdir/scripts $::deploy_dir/build_input") ) { + # non-zero return from system call + print "Error copying $::workdir/scripts to build directory $::deploy_dir/build_input \n"; + return 1; + } + } + # Copy over any provided non-native packages + my $to_source_dir = "$::deploy_dir/build_input/source_packages"; + mkpath("$to_source_dir"); + foreach my $kc (@{$::bldkit_config->{kitcomponent}{entries}}) { + if (defined($kc->{non_native_pkgs}) ) { + my $sourcedir = $::workdir."/source_packages"; + foreach my $pkgfile (split(/,/, $kc->{non_native_pkgs})) { + my $pkg_file; + my ($key,$value) = split /:/,$pkgfile; + if ("$key" =~ /EXTERNALPKGS/) { + next; + } else { + $pkg_file = $key; + } + + my $cmd = "cp -p $sourcedir/$pkg_file $to_source_dir"; + if ( system($cmd) ) { + print "Error copying non-native package file $sourcedir/$pkg_file to $to_source_dir \n"; + return 1; + } + } + } + } + + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 edit_deployparams + + Edit the kit deployment parameters to make sure it has correct + syntax for xCAT otherpkglist support + + +=cut + +#----------------------------------------------------------------------------- +sub edit_deployparams +{ + my $file = shift; + my $validate_only = shift; + + # read in the file + my $DF; + unless ( open( $DF, "<", $file ) ) { + print "The Kit deployment parameters file $file could not be read. \n"; + return 1; + } + my @lines = <$DF>; + close $DF; + + # Edit the files + my $changed = 0; + my @new_lines; + my $ln = 0; + foreach my $l (@lines) { + $ln++; + # skip blank lines + if ( $l =~ /^\s*$/ ) { + push (@new_lines, $l); + next; + } + # #ENV lines + $l =~ s/^\s+//; # compress leading blanks + if ( $l =~ /^\#ENV\:/ ) { + if ( !($l =~ /\#\s*$/) ) { + chomp $l; + $l .= "#\n"; + $changed = 1; + } + push (@new_lines, $l); + next; + } + # skip all other comments + if ( $l =~ /^\s*#/ ) { + push (@new_lines, $l); + next; + } + # Add #ENV if not specified + if ( $l =~ /^\w*\s*\=/ ) { + chomp $l; + $l = "#ENV: $l #"; + $changed = 1; + push (@new_lines, $l); + next; + } + # Syntax error + print "Syntax error in kit deployment parameters file $file \n"; + print "line $ln: \n"; + print "$l \n"; + return 1; + } + + # Write the file back out + if ($changed && !$validate_only) { + my $NDF; + unless ( open( $NDF, ">$file" ) ) { + return 1; + } + if ($::VERBOSE) { + print "Editted kit deployment parameters file $file \n"; + } + print $NDF @lines; + close($NDF); + } + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 edit_plugin + + Edit the kit plugin file to insert the full kit name + + +=cut + +#----------------------------------------------------------------------------- +sub edit_plugin +{ + my $file = shift; + my $kitname = $::bldkit_config->{kit}{entries}[0]->{kitname}; + # convert dashes to underscore since the kitname is used as perl pkg names + # in the plugin and this causes perl syntax errors + my $mod_kitname = $kitname; + $mod_kitname =~ s/\-/\_/g; + $mod_kitname =~ s/\./\_/g; + + # read in the file + my $PF; + unless ( open( $PF, "<", $file ) ) { + print "The Kit plugin file $file could not be read. \n"; + return 1; + } + my @lines = <$PF>; + close $PF; + + for (@lines) { + s/<<>>/$kitname/g; + s/<<>>/$mod_kitname/g; + } + + # Write the plugin back out + my $NPF; + unless ( open( $NPF, ">$file" ) ) { + return 1; + } + if ($::VERBOSE) { + print "Inserted kitname values into $file \n"; + } + print $NPF @lines; + close($NPF); + + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 kit_addpkgs + + buildkit addpkgs + +=cut + +#----------------------------------------------------------------------------- +sub kit_addpkgs +{ + # add RPM pkgs to an existing kit tarfile + my $kittarfile=$::KIT_ADDPKGS; + my $kitbfname = basename($kittarfile); + $kitbfname =~ s/.tar.bz2$//; + $kitbfname =~ s/.NEED_PRODUCT_PKGS$//; + my $tmpdir_base = "/tmp/$kitbfname"; + + # - could be list of pkgdir s + my @pkgdirlist = split(",", $::PKGDIR); + + # Cleanup - should have been removed when last command ran + # - but just in case + system ("rm -Rf $tmpdir_base"); + + # the tar file may not be in the current dir + $kittarfile = "$::workdir/$kittarfile"; + + if ( !(-r $kittarfile) ) { + print "The Kit tar file $kittarfile could not be read. \n"; + return 1; + } + $kittarfile = abs_path($kittarfile); + + foreach my $rpmdir (@pkgdirlist) { + if ( !(-d $rpmdir) ) { + print "The package directory $rpmdir could not be read. \n"; + return 1; + } + } + + # Create work directory + if ( (! -d $tmpdir_base) && (! mkpath($tmpdir_base)) ) { + print "Error creating temporary work directory $tmpdir_base\n"; + return 1; + } + + print "Extracting tar file $kittarfile. Please wait.\n"; + + if ( system("cd $tmpdir_base; tar -jxf $kittarfile ") ) { + print "Error extracting tarfile $kittarfile \n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + + my $tmp_kit_conf = `find $tmpdir_base -name kit.conf`; + chomp($tmp_kit_conf); + my $tmpdir = dirname($tmp_kit_conf); + + # read in the file + my $CKF; + unless ( open( $CKF, "<", $tmp_kit_conf ) ) { + print "The Kit configuration file $tmp_kit_conf could not be read or was not included in the kit tar file. \n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + my @lines = <$CKF>; + close $CKF; + + $::PREREQUISITE = 1; + foreach my $l (@lines) { + # skip blank and comment lines + if ( $l =~ /^\s*$/ || $l =~ /^\s*#/ ) { + next; + } + if ($l =~ /prerequisite/ ) { + $::PREREQUISITE = 0; + } + } + + # + # check contents of kit.conf to make sure the framework + # is compatible with this codes framework + $::kitframework = &check_framework(\@lines); + if (!defined($::kitframework)) { + return 1; + } + + # if this in not a partial kit then the framework must be 2 or greater + my $kit_name = basename($kittarfile); + if ( (!($kit_name =~ /NEED_PRODUCT_PKGS/)) && ($::kitframework < 2) ) { + print "This kit cannot be updated. To update a complete kit the kit framework\n value must be greater than or equal to 2. You can use the\n\t\'lskit -F \' \ncommand to check the framework value of the kit.\n"; + return 1; + } + + ### Check if this is a new partial kit built with xCAT 2.8.1 or newer + if (-d "$tmpdir/build_input") { + system ("mv $tmpdir/build_input $tmpdir_base"); + return &NEW_kit_addpkgs($tmpdir_base,$tmpdir); + } + + ### OLD KITS BUILT PRIOR TO xCAT 2.8.1 + ### this code will eventually become obsolete and should be removed + ### do not update + if (defined($::KITVERSION) || defined($::KITRELEASE)) { + print "kitversion and kitrelease substitution is not supported for this incomplete kit. Run \"buildkit addpkgs\" without the \"-k|--kitversion\" and \"-r| --kitrelease\" options. \n"; + exit 1; + } + + my $rpmdir=$::PKGDIR; + + my $ext_filename = ''; + my $ext_reponames = ''; + my $non_native_filename = ''; + my $non_native_kitcompname = ''; + my $non_native_basename = ''; + my $non_native_kitreponame = ''; + my %create_repodata_list; + my @new_lines; + my $section = ''; + my $kitname = ''; + my $kitbasename = ''; + my $kitversion = ''; + my $kitostype = ''; + foreach my $l (@lines) { + # skip blank and comment lines + if ( $l =~ /^\s*$/ || $l =~ /^\s*#/ ) { + push(@new_lines, $l); + next; + } + # new section? + if ( $l =~ /^\s*(\w+)\s*:/ ) { + $section = $1; + if ($section eq 'EXTERNALPKG') { + $ext_filename = ''; + $ext_reponames = ''; + next; + } + if ($section eq 'NONNATIVEPKGS') { + $non_native_filename = ''; + $non_native_kitcompname = ''; + $non_native_basename = ''; + $non_native_kitreponame = ''; + next; + } + push(@new_lines, $l); + next; + } + if ( $l =~ /^\s*(\w+)\s*=\s*(.*)\s*/ ) { + my $attr = $1; + my $val = $2; + my $orig_attr = $attr; + my $orig_val = $val; + $attr =~ s/^\s*//; # Remove any leading whitespace + $attr =~ s/\s*$//; # Remove any trailing whitespace + $attr =~ tr/A-Z/a-z/; # Convert to lowercase + $val =~ s/^\s*//; + $val =~ s/\s*$//; + + + if ($section eq 'kit') { + if ( $attr eq 'basename' ) { $kitbasename = $val; } + if ( $attr eq 'version' ) { $kitversion = $val; } + if ( $attr eq 'ostype' ) { $kitostype = $val; } + if ( ($kitbasename ne '') && ($kitversion ne '') && + ($kitostype ne '') ) { + $kitname = "$kitbasename-$kitversion-$kitostype"; + } + } + + if ($section eq 'EXTERNALPKG') { + if ($attr eq 'filename') { + $ext_filename = $val; + } elsif ($attr eq 'kitreponame') { + $ext_reponames = $val; + } else { + next; + } + if ( ($ext_filename ne '') && ($ext_reponames ne '') ){ + my $fromfile = $rpmdir."/".$ext_filename; + if ( system("ls $fromfile > /dev/null") ){ + print "The product package file $ext_filename could not be read from the package directory $rpmdir. \n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + foreach my $repo (split(/,/, $ext_reponames)) { + my $repodir = $tmpdir."/repos/".$repo; + if ( ! -d ($repodir) && (! mkpath($repodir)) ) { + print "Error creating repository directory $repodir\n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + if (system("cp -fp $fromfile $repodir")) { + print "Error copying package file $fromfile to $repodir \n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + $create_repodata_list{$repodir}=1; + } + } + next; + } + + if ($section eq 'NONNATIVEPKGS') { + if ( $attr eq 'filename' ) { + $non_native_filename = $val; + } elsif ($attr eq 'kitcompname') { + $non_native_kitcompname = $val; + } elsif ($attr eq 'basename') { + $non_native_basename = $val; + } elsif ($attr eq 'kitreponame') { + $non_native_kitreponame = $val; + } else { + next; + } + if ( ($non_native_filename ne '') + && ($non_native_kitcompname ne '') + && ($non_native_basename ne '') + && ($non_native_kitreponame ne '')) { + #find out the useful dir + my $tdir = $tmpdir."/tmp/"; + my $source_dir = "$tdir/$non_native_kitcompname"; + my $spec = "$tdir/$non_native_kitcompname.spec"; + if (!-d "$tdir" or !-d "$source_dir") { + print "Error open kitcomponent rpm build direcotry $tdir or $tdir/$non_native_kitcompname \n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + + #copy the nan_native_pkgs to the source dir + foreach my $tepmfilename (split(/,/, $non_native_filename)){ + #the $non_native_filename may contain several pkgs, can check and copy at the same time + my $fromfile = $rpmdir."/".$tepmfilename; + if ( system("ls $fromfile > /dev/null") ){ + print "The product package file $non_native_filename could not be read from the package directory $rpmdir. \n"; + system ("rm -Rf $tmpdir_base"); + return 1; + } + if (system("cp -fp $fromfile $tdir/$non_native_kitcompname")) { + print "Error copying package file $fromfile to $tdir/$non_native_kitcompname \n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + } + #for debian/ubuntu + my $repodir = $tmpdir . "/repos/".$non_native_kitreponame; + if ( $debianflag ){ + my $debbuildcmd = "cd $source_dir;dpkg-buildpackage -uc -us"; + if ( system($debbuildcmd) ){ + print "error running debian build cmd for kit component $non_native_basename meta package.\n"; + return 1; + } + my @debs = `find $tdir -maxdepth 1 -name "*.deb"`; + foreach my $debname (@debs){ + chomp($debname); + if ( system("mv -f $debname $repodir") ){ + print "Error copying package $debname to build repo directory $repodir. \n"; + return 1; + } + } + } + else{ + if (!-r "$spec") { + print "Error open kitcomponent rpm build spec $tdir/$non_native_kitcompname.spec \n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + my $rpmbuild_dir = $tmpdir."/rpmbuild"; + my $cmd = "rm -Rf $rpmbuild_dir"; + system($cmd); + + my $avoiderr = $rpmbuild_dir."/BUILDROOT/"; + mkpath($avoiderr); + $avoiderr = $rpmbuild_dir."/BUILD/"; + mkpath($avoiderr); + $avoiderr = $rpmbuild_dir."/SRPMS/"; + mkpath($avoiderr); + $avoiderr = $rpmbuild_dir."/RPMS/noarch/"; + mkpath($avoiderr); + + unless ( open( SF, "<", $spec ) ) { + print "Error attempting to open spec $spec of kitcomponent $non_native_basename. \n"; + return 1; + } + + mkpath("$rpmbuild_dir/SOURCES"); + $cmd = "cd $source_dir/..;mv $non_native_kitcompname $non_native_basename; tar -czf $rpmbuild_dir/SOURCES/$non_native_basename.tar.gz $non_native_basename;mv $non_native_basename $non_native_kitcompname;"; + if ( system($cmd) ) { + print "Error creating tarfile $rpmbuild_dir/SOURCES/$non_native_basename.tar from $source_dir/*"; + return 1; + } + my $rpmbuild_cmd = "rpmbuild --define \"_topdir $rpmbuild_dir\" -ba $spec"; + if (!$::VERBOSE) { + $rpmbuild_cmd .= ' --quiet '; + } + if ( system($rpmbuild_cmd) ) { + print "Error running rpmbuild command for kit component $non_native_basename meta package\n"; + return 1; + } + + # Copy the built meta rpm to repo + my @built_rpms = `find $rpmbuild_dir/RPMS -name "*.rpm"`; + foreach my $rpm (@built_rpms) { + chomp($rpm); + if ( system ("cp -fp $rpm $repodir") ) { + print "Error copying rpm $rpm to build repo directory $repodir \n"; + return 1; + } + } + } + $create_repodata_list{$repodir}=1; + } + next; + } + + push(@new_lines, $l); + } + } + + # Re-write kit.conf with EXTERNALPKG and NONNATIVEPKGS sections removed + my $NCF; + unless ( open( $NCF, ">$tmp_kit_conf" ) ) { + return 1; + } + print $NCF @new_lines; + close($NCF); + + # Clean up RPMBUILD and tmp in kit directory + my $cmd = "rm -Rf $tmpdir/tmp"; + system("$cmd"); + unless ( $debianflag ){ + $cmd = "rm -Rf $tmpdir/rpmbuild"; + system("$cmd"); + } + + # Run createrepo for each updated directory + foreach my $repo (keys(%create_repodata_list)) { + my $createrepocmd = ''; + if ( $debianflag ){ + $createrepocmd = "cd $repo;dpkg-scanpackages . > Packages"; + } + else{ + $createrepocmd = "createrepo $repo"; + } + if (system( $createrepocmd )) { + print "Error running $createrepocmd. \n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + } + + # Create new tar file in current directory + my $new_tarfile = $::workdir.'/'.$kitbfname.'.tar.bz2'; + if ( system("cd $tmpdir; cd ..; tar -cjhf $new_tarfile $kitname/*") ) { + print "Error building tarfile $new_tarfile \n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + print "Kit tar file $new_tarfile successfully built \n"; + + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 NEW_kit_addpkgs + + buildkit addpkgs + +=cut + +#----------------------------------------------------------------------------- +sub NEW_kit_addpkgs +{ + # add RPM pkgs to an existing kit tarfile + my $tmpdir_base = shift; + my $tmpdir = shift; + + # - could be list of pkgdir dirs + my @pkgdirlist = split(",", $::PKGDIR); + + $::NEW_PARTIAL_KIT = 1; + $::workdir = "$tmpdir_base/build_input"; + $::full_buildkit_conf = $::workdir."/".$::buildkit_conf; + $::deploy_dir = $tmpdir_base; #kitname appended by validate_bldkitconf routine + + my $tmp_buildkit_conf = `find $tmpdir_base -name $::buildkit_conf`; + + chomp($tmp_buildkit_conf); + if ($tmp_buildkit_conf ne $::full_buildkit_conf) { + print "$tmp_buildkit_conf should match $::full_buildkit_conf .... error??? \n"; + } + + my $loadrc = &load_bldkitconf($tmp_buildkit_conf); + if ( $loadrc != 0 ) { + print "Error reading buildkit config file $tmp_buildkit_conf \n"; + return 1; + } + + if ( defined($::KITVERSION) ) { + $::bldkit_config->{kit}{entries}[0]->{version} = $::KITVERSION; + } + if ( defined($::KITRELEASE) ) { + $::bldkit_config->{kit}{entries}[0]->{release} = $::KITRELEASE; + } + + my $chkrc = &validate_bldkitconf(); + if ( $chkrc != 0 ) { + print "Error validating buildkit config file $tmp_buildkit_conf \n"; + return 1; + } + + if ($tmpdir ne $::deploy_dir) { + if (system ("mv $tmpdir $::deploy_dir ") ) { + print "Error moving $tmpdir to $::deploy_dir \n"; + return 1; + } + } + $::build_dir = $::deploy_dir; + $::base_repodir = "$::deploy_dir/repos"; + my $kitname = $::bldkit_config->{kit}{entries}[0]->{kitname}; + + # Handle external packages + if ($::HAVE_EXTERNAL_PKG) { + foreach my $kp (@{$::bldkit_config->{kitpackage}{entries}}) { + if ($kp->{isexternalpkg} eq 'yes') { + my $ext_filename = $kp->{filename}; + my $ext_reponames = $kp->{kitreponame}; + + my $files = xCAT::BuildKitUtils->find_latest_pkg(\@pkgdirlist, $ext_filename); + + if (!defined($files) ) { + print "Error: The product package file $ext_filename was not found in the package directory(s) @pkgdirlist.\n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + + my @fromfiles=@$files; + + foreach my $repo (split(/,/, $ext_reponames)) { + my $repodir = $::base_repodir."/".$repo; + if ( ! -d ($repodir) && (! mkpath($repodir)) ) { + print "Error creating repository directory $repodir\n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + + foreach my $fromfile (@fromfiles) { + if (system("cp -fp $fromfile $repodir")) { + print "Error copying package file $fromfile to $repodir \n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + return 1; + } + } + if ($::VERBOSE) { + print "Copied @fromfiles\n to $repodir\n"; + } + } + } + } + } + + # Handle non_native_pkgs + # Comma-separated list of non-native package + # paths that will be included as files in this kit + # component. + # these are not RPMs! + my $to_source_dir = "$::workdir/source_packages"; + mkpath("$to_source_dir"); + foreach my $kc (@{$::bldkit_config->{kitcomponent}{entries}}) { + if ($::NON_NATIVE_PKGS->{$kc->{kitcompname}}) { + my @nativefiles; + foreach my $pkgfile (split(/,/, $kc->{non_native_pkgs})) { + my ($key,$value) = split /:/,$pkgfile; + if ("$key" =~ /EXTERNALPKGS/) { + #the $non_native_filename may contain several pkgs, can check and copy at the same time + foreach my $nnpkg (split(/,/, $value)){ + my $found=0; + foreach my $pdir (@pkgdirlist) { + my $fromfile = $pdir."/".$nnpkg; + if ( system("ls $fromfile > /dev/null") ){ + next; + } else { + $found++; + if (system("cp -fp $fromfile $to_source_dir")) { + print "Error copying package file $fromfile to $to_source_dir \n"; + # Cleanup + system ("rm -Rf $tmpdir_base"); + next; + } else { + if ($::VERBOSE) { + print "Copied $fromfile to $to_source_dir\n"; + } + } + } + } + if (!$found) { + print "Could not find $nnpkg.\n"; + } + } + } + } + } + } + + # Turn off external pkg flags and build the kit component meta pkgs + $::HAVE_EXTERNAL_PKG = ''; + $::HAVE_NON_NATIVE_PKGS = ''; + $::NON_NATIVE_PKGS = {}; + + foreach my $kc (@{$::bldkit_config->{kitcomponent}{entries}}) { + my $rc=0; + if ( $debianflag ){ + $rc = &build_kitcomp_debian($kc); + } + else{ + $rc = &build_kitcomp($kc); + } + if ( $rc ) { + print "Error building kitcomponent metapackage for $kc->{basename} \n"; + return 1; + } + } + + # run createrepo + foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) { + my $repodir = "$::base_repodir/$kr->{kitreponame}"; + if ( -d $repodir ) { + my $cr_opts = ''; + if (( $kr->{osbasename} =~ m/rh|RH|centos|CentOS/ ) && + ( $kr->{osmajorversion} eq '5') ) { + $cr_opts = '-s md5'; + } + my $repocmd = ""; + if ( $debianflag ){ + $repocmd = "cd $repodir;dpkg-scanpackages . > Packages"; + } + else{ + $repocmd = "createrepo $cr_opts $repodir"; + } + if ( system( $repocmd ) ) { + print "Error building the repository meta-data with the createrepo command \n"; + return 1; + } + } + } + + # Build the full kit tar file + my $buildtar_rc = &kit_buildtar; + + # clean out the tmp dir + system ("rm -Rf $tmpdir_base"); + + if ($buildtar_rc) { + print "Error building full kit tarfile \n"; + return 1; + } + return 0; +} + +#----------------------------------------------------------------------------- + +=head3 check_framework + + Check the compatible frameworks of the kit to see if it is + compatible with the running code. + + If one of the compatible frameworks of the kit matches one of the + compatible frameworks of the running code then we're good. + + NOTE: compatible_kitframeworks are the kitframeworks that I can add + and kit frameworks that I can be added to. + + Returns: + 0 - kit framework value + undef - error + + Example: + my $kitframework = &check_framework(\@lines); + +=cut + +#----------------------------------------------------------------------------- +sub check_framework +{ + my $lines = shift; + + my @kitconflines = @$lines; + + my $kitbasename; + my $kitcompat; + my $kitframework; + my $section = ''; + foreach my $l (@kitconflines) { + # skip blank and comment lines + if ( $l =~ /^\s*$/ || $l =~ /^\s*#/ ) { + next; + } + + if ( $l =~ /^\s*(\w+)\s*:/ ) { + $section = $1; + next; + } + + if ( $l =~ /^\s*(\w+)\s*=\s*(.*)\s*/ ) { + my $attr = $1; + my $val = $2; + $attr =~ s/^\s*//; # Remove any leading whitespace + $attr =~ s/\s*$//; # Remove any trailing whitespace + $attr =~ tr/A-Z/a-z/; # Convert to lowercase + $val =~ s/^\s*//; + $val =~ s/\s*$//; + + if ($section eq 'kitbuildinfo') { + if ( $attr eq 'compatible_kitframeworks' ) { + $kitcompat = $val; + } + if ( $attr eq 'kitframework' ) { + $kitframework = $val; + } + } + if ($section eq 'kit') { + if ( $attr eq 'basename' ) { $kitbasename = $val; } + } + } + } + + if (!$kitcompat) { + print "Warning: Could not determine the kit compatible framework values for \'$kitbasename\' from the kit.conf file. Continuing for now.\n"; + return 0; + } + + my @kit_compat_list = split (',', $kitcompat); + my @my_compat_list = split (',', $::COMPATIBLE_KITFRAMEWORKS); + + foreach my $myfw (@my_compat_list) { + chomp $myfw; + foreach my $kitfw (@kit_compat_list) { + chomp $kitfw; + + if ($myfw eq $kitfw) { + return $kitframework; + } + } + } + print "Error: The kit named \'$kitbasename\' is not compatible with this version of the buildkit command. \'$kitbasename\' is compatible with \'$kitcompat\' and the buildkit command is compatible with \'$::COMPATIBLE_KITFRAMEWORKS\'\n"; + return undef; +} From 213556c27f5c8fa5c8aac64e5cbed1e7ccf8f1a4 Mon Sep 17 00:00:00 2001 From: wanghuaz Date: Wed, 30 Oct 2013 01:46:24 -0700 Subject: [PATCH 13/15] fixing bug 3867 --- xCAT-server/lib/xcat/plugins/kit.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/kit.pm b/xCAT-server/lib/xcat/plugins/kit.pm index 40d6e92d9..656367dde 100644 --- a/xCAT-server/lib/xcat/plugins/kit.pm +++ b/xCAT-server/lib/xcat/plugins/kit.pm @@ -1730,7 +1730,7 @@ sub validate_os{ return 1; } - if ( $osimage->{arch} ne $kitcomp->{osarch} ) { + if ( $osimage->{arch} ne $kitcomp->{osarch} && $kitcomp->{osarch} ne 'noarch' ) { # my %rsp; # push@{ $rsp{data} }, "osimage $os is not compatible with kit component $kitcomp->{kitcompname} with attribute arch"; # xCAT::MsgUtils->message( "E", \%rsp, $::CALLBACK ); @@ -2013,7 +2013,7 @@ sub addkitcomp return 1; } - if ( $os{$osimage}{arch} ne $kitcomps{$kitcomp}{osarch} ) { + if ( $os{$osimage}{arch} ne $kitcomps{$kitcomp}{osarch} && $kitcomps{$kitcomp}{osarch} ne 'noarch' ) { my %rsp; push@{ $rsp{data} }, "osimage $osimage is not compatible with kit component $kitcomp with attribute arch"; xCAT::MsgUtils->message( "E", \%rsp, $callback ); @@ -3328,7 +3328,7 @@ sub chkkitcomp return 1; } - if ( $os{$osimage}{arch} ne $kitcomps{$kitcomp}{osarch} ) { + if ( $os{$osimage}{arch} ne $kitcomps{$kitcomp}{osarch} && $kitcomps{$kitcomp}{osarch} ne 'noarch' ) { my %rsp; push@{ $rsp{data} }, "kit component $kitcomp is not compatible with osimage $osimage with attribute arch"; xCAT::MsgUtils->message( "E", \%rsp, $callback ); @@ -4516,7 +4516,7 @@ sub get_compat_kitreponames { if (defined($kitrepo->{osminorversion}) && $kitrepo->{osminorversion} ne $osdistro->{minorversion}) { next; } - if (defined($kitrepo->{osarch}) && $kitrepo->{osarch} ne $osdistro->{arch}) { + if (defined($kitrepo->{osarch}) && $kitrepo->{osarch} ne $osdistro->{arch} && $kitrepo->{osarch} ne 'noarch') { next; } From 0e54237c42ca2685e2e368f770c26642ff618541 Mon Sep 17 00:00:00 2001 From: xq2005 Date: Wed, 30 Oct 2013 03:05:27 -0700 Subject: [PATCH 14/15] bug 3831: install ubuntu hang --- .../share/xcat/install/scripts/pre.ubuntu | 41 ------------------- .../share/xcat/install/ubuntu/compute.tmpl | 2 + .../share/xcat/install/ubuntu/kvm.tmpl | 2 + 3 files changed, 4 insertions(+), 41 deletions(-) diff --git a/xCAT-server/share/xcat/install/scripts/pre.ubuntu b/xCAT-server/share/xcat/install/scripts/pre.ubuntu index f6c9efd44..ccc9b5a47 100644 --- a/xCAT-server/share/xcat/install/scripts/pre.ubuntu +++ b/xCAT-server/share/xcat/install/scripts/pre.ubuntu @@ -4,48 +4,7 @@ if [ ! -c /dev/vcs ]; then mknod /dev/vcs c 7 0 fi -while [ -z "$instdisk" ]; do -VIRTDISKS=`ls /dev/vd*|wc -l` -if [ $VIRTDISKS -gt 0 ]; then -for disk in /dev/vd*[^0-9]; do - if [ -z "$firstdirectdisk" ]; then firstdirectdisk=$disk; fi #remember first disk as a guess of medium resort - #no edd_id in debian installer, no edd hints supported -done -fi -if [ -z "$firstdirectdisk" ]; then - SCSIDISKS=`ls /dev/sd*|wc -l` - if [ $SCSIDISKS -gt 0 ]; then - for disk in /dev/sd*[^0-9]; do - currdriver=`udevadm info --attribute-walk --name $disk |grep DRIVERS|grep -v '""'|grep -v '"sd"'|head -n 1|sed -e 's/[^"]*"//' -e 's/"//'` - case "$currdriver" in - "ata_piix4"|"PMC MaxRAID"|"ahci"|"megaraid_sas") #certainly direct - if [ -z "$firstdirectdisk" ]; then firstdirectdisk=$disk; fi #remember first disk as a guess of medium resor - ;; - "mptsas"|"mpt2sas") #*PROBABLY* not SAN, but SAS SAN is possible - if [ -z "$probablyfirstdirectdisk" ]; then probablyfirstdirectdisk=$disk; fi - ;; - *) # could be san or who knows what, use it as a last resort - if [ -z "$firstdisk" ]; then firstdisk=$disk; fi - ;; - esac - done - fi -fi -if [ -z "$instdisk" ]; then - if [ ! -z "$firstdirectdisk" ]; then - instdisk=$firstdirectdisk - elif [ ! -z "$probablyfirstdirectdisk" ]; then - instdisk=$probablyfirstdirectdisk - elif [ ! -z "$firstdisk" ]; then - instdisk=$firstdisk - fi -fi -if [ ! -z "$instdisk" ]; then debconf-set partman-auto/disk "$instdisk"; fi debconf-get open-iscsi/targets > /tmp/q -sleep 0.1 -done & - - cat >/tmp/foo.sh < Date: Wed, 30 Oct 2013 07:12:35 -0700 Subject: [PATCH 15/15] fix defect #3393 xcat 2.8 mgt server(rhels6.4-ppc64) hang on Generating /etc/rndc.key during reboot --- xCAT-server/sbin/xcatconfig | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/xCAT-server/sbin/xcatconfig b/xCAT-server/sbin/xcatconfig index 3106f2b90..117e19caa 100755 --- a/xCAT-server/sbin/xcatconfig +++ b/xCAT-server/sbin/xcatconfig @@ -1051,6 +1051,20 @@ sub is_debian return 0; } +sub is_redhat6sp4 +{ + if( -e "/etc/redhat-release" ){ + open(my $relfile, "<", "/etc/redhat-release"); + my $line = <$relfile>; + close($relfile); + if ( $line =~ /Red Hat Enterprise Linux Server release 6.4/i ){ + return 1; + } + } + return 0; +} + + # on Ubuntu need to painstakingly compare /etc/localtime with files under # /usr/share/zoneinfo since /etc/localtime # isn't always a symbolic link sub discover_timezone_ubuntu @@ -2233,6 +2247,13 @@ sub startnamedonboot $serv = "bind9"; $cmd = "update-rc.d $serv enable"; } + + #"service named start" is very slowly,sometimes hang in rhels6.4 after installation + #a work around is to generate /etc/rndc-key during xCAT installation + if( is_redhat6sp4() ){ + system("rndc-confgen -a -r /dev/urandom"); + } + my $outref = xCAT::Utils->runcmd("$cmd", 0); if ($::RUNCMD_RC != 0) {