From 13e7903b436b68e3c625271eee3f99886e663a76 Mon Sep 17 00:00:00 2001 From: nott Date: Tue, 29 Oct 2013 14:45:14 -0400 Subject: [PATCH] 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; +}