xcat-core/xCAT-buildkit/bin/buildkit
2013-04-30 18:39:19 +00:00

3452 lines
120 KiB
Perl
Executable File

#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#
#-----------------------------------------------------------------------------
=head1 buildkit
xCAT/PCM Kit Build utilities
usage: buildkit [-h|-v] [command [-V]]
This tool is used to create and build a new Kit.
The options are:
-h - Provide usage info.
-v - Provide the version info.
command - Several commands are supported. See the list below.
-V - Verbose mode. Outputs additional debug messages.
Supported commands:
create <kit basename> - creates a new Kit with the specified basename
chkconfig - checks the Kit build file
buildrepo <reponame> - builds the specified Kit package repository
buildrepo all - builds all the Kit package repositories
listrepo - lists the Kit package repositories in the Kit
build file, and their build status
cleanrepo <reponame> - 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
cleanall - equivalent to buildkit cleanrepo all and
buildkit cleantar
addpkgs -p <packagedir> [-k|--kitversion <version>] [-r|--kitrelease <release>] <kit tarfile>
- used by customer to add external product
packages when they are not built into the
shipped kit tar file
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 - buildkit is not supported on AIX \n";
exit 1;
# if AIX - make sure we include perl 5.8.2 in INC path.
# Needed to find perl dependencies shipped in deps tarball.
# unshift(@INC, qw(/usr/opt/perl5/lib/5.8.2/aix-thread-multi /usr/opt/perl5/lib/5.8.2 /usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi /usr/opt/perl5/lib/site_perl/5.8.2));
}
use lib "$::XCATROOT/lib/perl";
require xCAT::BuildKitUtils;
use Getopt::Long;
use Expect;
use Socket;
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();
$::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";
%::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} },
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,
'p|pkgdir=s' => \$::PKGDIR,
'k|kitversion=s' => \$::KITVERSION,
'r|kitrelease=s' => \$::KITRELEASE,
)
)
{
&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 pakcage. Version info is not available. \n";
}
if ( system($versioncmd) ) {
# non-zero return from system call
print $message;
exit 1;
}
exit 0;
}
my $arg=shift(@ARGV);
if ( ! $arg ) {
&usage;
exit (0);
}
while ($arg) {
my $command = $arg;
$command =~ tr/A-Z/a-z/; # convert to lowercase
if ( $command eq 'create' ) {
$::KIT_CREATE=shift(@ARGV);
if ( ! $::KIT_CREATE ) {
print "kit basename not specified for 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 "kit package repository name 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: <kit tarfile> must be specified with \'buildkit addpkgs\' \n";
&usage;
exit (1);
}
if (!($::PKGDIR)){
print "Missing option: -p <pkgdir> must be specified with \'buildkit addpkgs\' \n";
&usage;
exit (1);
}
} else {
print "buildkit command $arg 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|-v] [command [-V]]
This tool is used to create and build a new Kit.
The options are:
-h - Provide usage info.
-v - Provide the version info.
command - Several commands are supported. See the list below.
-V - Verbose mode. Outputs additional debug messages.
Supported commands:
create <kit basename> - 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 <reponame> - builds the specified Kit package repository
buildrepo all - builds all the Kit package repositories
cleanrepo <reponame> - 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 <pkgdir> <kit tarfile>
- 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=$::workdir."/$kitname";
if ( -d $kitdir ) {
print "Another directory alredy exists with the name $kitname in the current working directory. Not able to create new Kit directory $kitdir. \n";
exit 1;
}
if ( ! mkdir($kitdir) ) {
print "Error creating Kit directory $kitdir. Verify that the current user has write privileges in the current working 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";
}
#-----------------------------------------------------------------------------
=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;
$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; }
}
}
}
#-----------------------------------------------------------------------------
=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/ ) &&
( $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 {
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";
}
last;
}
}
}
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;
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 $kitfilename successfully built \n";
return 0;
}
#-----------------------------------------------------------------------------
=head3 kit_cleantar
buildkit cleantar
=cut
#-----------------------------------------------------------------------------
sub kit_cleantar
{
my $kitfilename = $::bldkit_config->{kit}{entries}[0]->{kitname};
if ( defined($::bldkit_config->{kit}{entries}[0]->{kittarfilename}) ) {
$kitfilename = $::bldkit_config->{kit}{entries}[0]->{kittarfilename};
$kitfilename =~ s/tar\.bz2\s*$//;
}
my $findcmd = "find $::current_dir -name \"$kitfilename.\*tar.bz2\"";
my $tarfile = `$findcmd`;
chomp ($tarfile);
if ( -r $tarfile ) {
if ( system("rm -f $tarfile ") ) {
print "Error removing kit tar file $tarfile \n";
} else {
print "Kit tar file $tarfile has been successfully removed \n";
}
}
if ( -d $::deploy_dir ) {
if ( system("rm -Rf $::deploy_dir ") ) {
print "Error removing contents of $::deploy_dir \n";
} else {
print "All $::deploy_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");
}
}
#-----------------------------------------------------------------------------
=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/<<<INSERT_kitbasename_HERE>>>/$kitname/;
s/<<<INSERT_kitrepoid_HERE>>>/$kitrepoid/;
s/<<<INSERT_osbasename_HERE>>>/$osbasename/;
s/<<<INSERT_osmajorversion_HERE>>>/$osmajorversion/;
s/<<<INSERT_osminorversion_HERE>>>/$osminorversion/;
s/<<<INSERT_osarch_HERE>>>/$osarch/;
s/<<<INSERT_kitcomponent_basename_HERE>>>/$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 = '<end of file>';
} elsif ( !($::bldkit_config->{'kitrepo'}{'exists'})) {
$syntax_error = "No \"kitrepo:\" section found. At least one section required. ";
$bad_line = '<end of file>';
} 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 " <section name>: \n";
print " <attr>=<val> \n";
print " <attr>=<val> \n";
print " ... \n";
print " <section name>: \n";
print " <attr>=<val> \n";
print " <attr>=<val> \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\" mandadory 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 $repo = 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';
}
# $pkgname .= '-'.$repo->{osmajorversion};
# if (defined($repo->{osminorversion})) {
# $pkgname .= '.'.$repo->{osminorversion};
# }
# $pkgname .= '-'.$repo->{osarch};
# $pkgname .= '.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; }
# Create spec file for this kit component
if ( &gen_kitcomp_spec($comp,\%repo) ) { 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;
}
}
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})) {
my $new_kitpkgdeps = '';
foreach my $d (split(/,/, $comp->{kitpkgdeps})) {
$d =~ s/\s+//g;
my $d_short = $d;
$d_short =~ s/^([\w\.\-]+)[<>=]*.*$/$1/;
if ( $d_short eq $d ) {
# no version-release comparisons specified for this kitpkgdep
# do we have an rpm file in the repo?
my $cmd = "rpm -q --qf \"%{NAME} >= %{VERSION}-%{RELEASE},\" -p $repodir/$d-\[0-9\]\*.rpm 2>/dev/null";
if ($::VERBOSE) {
print "running rpm query to get version-release info: \n $cmd \n";
}
my $new_d = `$cmd`;
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 $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 (defined($comp->{preinstall})) {
$prescript = &load_script("$scriptdir$comp->{preinstall}");
$prescript = "if [ \"\$1\" = \"1\" ] ; then\n" . $prescript . "\nfi";}
if (defined($comp->{postinstall})) {
$postscript = &load_script("$scriptdir$comp->{postinstall}");
$postscript = "if [ \"\$1\" = \"1\" ] ; then\n" . $postscript . "\nfi"; }
if (defined($comp->{preupgrade})) {
$preupscript = &load_script("$scriptdir$comp->{preupgrade}");
$preupscript = "if [ \"\$1\" = \"2\" ] ; then\n" . $preupscript . "\nfi";}
if (defined($comp->{postupgrade})) {
$postupscript = &load_script("$scriptdir$comp->{postupgrade}");
$postupscript = "if [ \"\$1\" = \"2\" ] ; then\n" . $postupscript . "\nfi";}
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";
$sourcetar = "Source: $comp->{basename}.tar.gz";
$setup = "\%setup -q -n $comp->{basename}";
$files = "/opt/xcat/kits";
}
for (@lines) {
chomp;
s/<<<INSERT_kitbasename_HERE>>>/$kitname/;
s/<<<INSERT_kitcomponent_basename_HERE>>>/$comp->{basename}/;
s/<<<INSERT_kitcomponent_version_HERE>>>/$comp->{version}/;
s/<<<INSERT_kitcomponent_release_HERE>>>/$comp->{release}/;
s/<<<INSERT_kit_license_HERE>>>/$::bldkit_config->{kit}{entries}[0]->{kitlicense}/;
s/<<<INSERT_kitcomponent_ospkgdeps_HERE>>>/$comp->{ospkgdeps}/;
s/<<<INSERT_kitcomponent_kitpkgdeps_HERE>>>/$comp->{kitpkgdeps}/;
s/<<<INSERT_kitcomponent_kitcompdeps_HERE>>>/$comp->{kitcompdeps}/;
s/<<<INSERT_kitcomponent_desc_HERE>>>/$comp->{description}/;
s/<<<INSERT_kitcomponent_non_native_pkgs_HERE>>>/$nonnativepkgs/;
s/<<<INSERT_kitcomponent_sourcetar_HERE>>>/$sourcetar/;
s/<<<INSERT_kitcomponent_setup_HERE>>>/$setup/;
s/<<<INSERT_kitcomponent_files_HERE>>>/$files/;
s/<<<INSERT_kitcomponent_preinstall_script_HERE>>>/$prescript/;
s/<<<INSERT_kitcomponent_postinstall_script_HERE>>>/$postscript/;
s/<<<INSERT_kitcomponent_preupgrade_script_HERE>>>/$preupscript/;
s/<<<INSERT_kitcomponent_postupgrade_script_HERE>>>/$postupscript/;
s/<<<INSERT_kitcomponent_preuninstall_script_HERE>>>/$preunscript/;
s/<<<INSERT_kitcomponent_postuninstall_script_HERE>>>/$postunscript/;
}
# Write the generated spec file
my $joined_lines = join("\n",@lines);
@lines = split(/\\n/,$joined_lines);
mkpath($tmpdir);
my $NSF;
unless ( open( $NSF, ">$tmpdir/$comp->{kitcompname}.spec" ) ) {
return 1;
}
if ($::VERBOSE) {
print "Created kitcomponent spec file $tmpdir/$comp->{basename}.spec \n";
}
print $NSF @lines;
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 = <FH>;
close(FH);
for(@lines) {
chomp;
s/<<<INSERT_kitcomponent_basename_HERE>>>/$comp->{basename}/;
s/<<<INSERT_kitcomponent_ospkgdeps_HERE>>>/$comp->{ospkgdeps}/;
s/<<<INSERT_kitcomponent_kitpkgdeps_HERE>>>/$comp->{kitpkgdeps}/;
s/<<<INSERT_kitcomponent_kitcompdeps_HERE>>>/$comp->{kitcompdeps}/;
s/<<<INSERT_kitcomponent_desc_HERE>>>/$comp->{description}/;
s/<<<INSERT_kitcomponent_upgrade_flag_HERE>>>/$upgradeflag/;
s/<<<INSERT_kitcomponent_preinstall_script_HERE>>>/$prescript/;
s/<<<INSERT_kitcomponent_postinstall_script_HERE>>>/$postscript/;
s/<<<INSERT_kitcomponent_preupgrade_script_HERE>>>/$preupscript/;
s/<<<INSERT_kitcomponent_postupgrade_script_HERE>>>/$postupscript/;
s/<<<INSERT_kitcomponent_preuninstall_script_HERE>>>/$preunscript/;
s/<<<INSERT_kitcomponent_postuninstall_script_HERE>>>/$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('\n', @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};
}
$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 = 1 \n";
$lines[$li++] = " compatible_kitframeworks = 0,1 \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/<<<buildkit_WILL_INSERT_kit_name_HERE>>>/$::bldkit_config->{kit}{entries}[0]->{kitname}/g;
s/<<<buildkit_WILL_INSERT_kit_basename_HERE>>>/$::bldkit_config->{kit}{entries}[0]->{basename}/g;
s/<<<buildkit_WILL_INSERT_kit_version_HERE>>>/$::bldkit_config->{kit}{entries}[0]->{version}/g;
s/<<<buildkit_WILL_INSERT_kit_release_HERE>>>/$::bldkit_config->{kit}{entries}[0]->{release}/g;
if ( defined ($kitcomp) ) {
s/<<<buildkit_WILL_INSERT_kitcomponent_name_HERE>>>/$kitcomp->{kitcompname}/g;
s/<<<buildkit_WILL_INSERT_kitcomponent_basename_HERE>>>/$kitcomp->{basename}/g;
s/<<<buildkit_WILL_INSERT_kitcomponent_version_HERE>>>/$kitcomp->{version}/g;
s/<<<buildkit_WILL_INSERT_kitcomponent_release_HERE>>>/$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/<<<buildkit_WILL_INSERT_kitname_HERE>>>/$kitname/g;
s/<<<buildkit_WILL_INSERT_modified_kitname_HERE>>>/$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 $rpmdir = $::PKGDIR;
my $kitbfname = basename($kittarfile);
$kitbfname =~ s/.tar.bz2$//;
$kitbfname =~ s/.NEED_PRODUCT_PKGS$//;
my $tmpdir_base = "/tmp/buildkit_workdir/$kitbfname";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir/$kitbfname");
if ( !(-r $kittarfile) ) {
print "The Kit tar file $kittarfile could not be read. \n";
return 1;
}
$kittarfile = abs_path($kittarfile);
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;
}
if ( system("cd $tmpdir_base; tar -jxf $kittarfile ") ) {
print "Error extracting tarfile $kittarfile \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
return 1;
}
my $tmp_kit_conf = `find $tmpdir_base -name kit.conf`;
chomp($tmp_kit_conf);
my $tmpdir = dirname($tmp_kit_conf);
### 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;
}
# 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 /tmp/buildkit_workdir");
return 1;
}
my @lines = <$CKF>;
close $CKF;
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 /tmp/buildkit_workdir");
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 /tmp/buildkit_workdir");
return 1;
}
if (system("cp -fp $fromfile $repodir")) {
print "Error copying package file $fromfile to $repodir \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
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 /tmp/buildkit_workdir");
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 /tmp/buildkit_workdir");
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 /tmp/buildkit_workdir");
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 /tmp/buildkit_workdir");
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 /tmp/buildkit_workdir");
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 /tmp/buildkit_workdir");
return 1;
}
print "Kit tar file $new_tarfile successfully built \n";
# Cleanup
# system ("rm -Rf /tmp/buildkit_workdir");
}
#-----------------------------------------------------------------------------
=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;
my $rpmdir = $::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 $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 /tmp/buildkit_workdir");
return 1;
}
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 /tmp/buildkit_workdir");
return 1;
}
if (system("cp -fp $fromfile $repodir")) {
print "Error copying package file $fromfile to $repodir \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
return 1;
}
}
}
}
}
# Handle non_native_pkgs
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 $fromfile = $rpmdir."/".$nnpkg;
if ( system("ls $fromfile > /dev/null") ){
print "The product package file $nnpkg could not be read from the package directory $rpmdir. \n";
return 1;
}
if (system("cp -fp $fromfile $to_source_dir")) {
print "Error copying package file $fromfile to $to_source_dir \n";
return 1;
}
}
}
}
}
}
# 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/ ) &&
( $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;
if ($buildtar_rc) {
print "Error building full kit tarfile \n";
return 1;
}
}