#! perl use Cwd; use Config; # # Do a perl check for version >= 5.005. See 'gpt-translate-interpreter' # should you need to alter the invocation path to a valid perl interpreter in # the GPT front-end programs. # if ( ! ( defined eval "require 5.005" ) ) { die "GPT requires at least Perl version 5.005"; } my $gpath = $ENV{GPT_LOCATION}; if (!defined($gpath)) { $gpath = $ENV{GLOBUS_LOCATION}; } if (!defined($gpath)) { die "GPT_LOCATION or needs to be set before running this script"; } @INC = ("$gpath/lib/perl", "$gpath/lib/perl/$Config{'archname'}", @INC); system( "$gpath/sbin/gpt_version" ) == 0 or die "GPT died due to Version mismatch. Check PATH and GPT_LOCATION\n" ; if ( !( defined eval "require Grid::GPT::GPTObject" ) ) { die("$gpath does not appear to hold a valid GPT installation\n"); } require Pod::Usage; my ($srcdir, $tmpdir, $nodeps, $outputfile, $all, @xmlBundle, $sdk, $native, $help, $version, @excludes, $bundlename, $bundleversion, $arch, $nosetups, $man, $workingdir, $bndlFile, $location, $bundlestab, $bundlelabel, $bundledef, $verbose, $debug, $buildno, $rpmprefix, $rpmlicense, $keep); GetOptions( 'srcdir=s' => \$srcdir, 'tmpdir=s' => \$tmpdir, 'bindir=s' => \$tmpdir, 'installdir=s' => \$location, 'xml=s' => \@xmlBundle, 'nodeps' => \$nodeps, 'nosetups' => \$nosetups, 'sdk' => \$sdk, 'native' => \$native, 'keep-bin-pkgs|keep' => \$keep, 'output=s' => \$outputfile, 'bundlename|bn=s' => \$bundlename, 'bundleversion|bv=s' => \$bundleversion, 'bundlestability|bs=s' => \$bundlestab, 'bundlelabel|bl=s' => \$bundlelabel, 'exclude|x=s' => \@excludes, 'all' => \$all, 'help|?' => \$help, 'man' => \$man, 'version' => \$version, 'verbose' => \$verbose, 'debug' => \$debug, 'buildnumber|buildno=i' => \$buildno, 'rpmprefix=s' => \$rpmprefix, 'rpmlicense=s' => \$rpmlicense, 'template' => \$template, 'bundledef=s' => \$bundledef, 'location=s' => \$location ) or Pod::Usage::pod2usage(0); Pod::Usage::pod2usage(0) if $help; Pod::Usage::pod2usage(-verbose => 2) if $man; require Grid::GPT::GPTIdentity; Grid::GPT::GPTIdentity::print_gpt_version() if defined $version; require Grid::GPT::PkgDist; require Grid::GPT::Installation; require Grid::GPT::PkgFileName; require Grid::GPT::FilelistFunctions; require Grid::GPT::Locations; use Getopt::Long; require Archive::Tar; require Grid::GPT::PkgMngmt::Inform; #Functions Prototypes sub cleandir; sub process_bundle; my $log = new Grid::GPT::PkgMngmt::Inform( verbose => $verbose, debug => $debug ); my $locations = new Grid::GPT::Locations( installdir => $location, tmpdir => $tmpdir, bindir => $tmpdir, srcdir => $srcdir ); my %pkgtype2depenv = ( 'data' => ['Runtime', 'Setup'], 'doc' => ['Runtime', 'Setup'], 'dev' => ['Build'], 'pgm' => ['Runtime','Setup'], 'pgm_static' => ['Runtime', 'Setup'], 'rtl' => ['Runtime', 'Setup'], 'sdk' => ['Build'], 'src' => ['Build', 'Runtime', 'Setup'], ); my $dist; my $bundlelist; my $nativebundlelist; my @deporderlist; my @sortedpkgs; my @sortedpkgslist; my @nativesortedpkgs; my $pkgdir; my $preferred_flavor; # # format our exclude and type lists # my $bundleName = undef; my $bundleVersion = undef; my @exclude_queries; my $parsenames = new Grid::GPT::PkgFileName( locations => $locations ); for my $e (@excludes) { push @exclude_queries, $parsenames->parse_name($e); } my @pkg_queries; for my $p (@ARGV) { push @pkg_queries, $parsenames->parse_name($p); } ##my $bndl = new Grid::GPT::V1::Bundle; my $bndl = undef; if( defined($template) ) { $bndl = new Grid::GPT::V1::Bundle; create_bundle(); create_template(); exit 0; } if( @xmlBundle ) { for my $x (@xmlBundle) { $bndl = new Grid::GPT::V1::Bundle; $bndl->read_metadata_file($x); create_bundle(); process_bundle(); } } else { $bndl = new Grid::GPT::V1::Bundle; create_bundle(); process_bundle(); } sub process_bundle { $bndl->clearBundleExcludedPackageList(); $bndl->clearBundleIncludedPackageList(); if( defined $srcdir ) { #### We're obviously looking at making a source bundle: build_src(); } else { ##### we've got a binary bundle build_bin(); } write_bundle(); } sub build_src { $bundlefilename = bundlename('src'); $pkgdir = $locations->{'bindir'}; my $srcdir = $locations->{'srcdir'}; $locations->create_dirs(mode => 'bundle'); $dist = new Grid::GPT::PkgDist( pkgdir => $srcdir, all => 1, log => $log ); my $pkg_pairs = get_ordered_packages( dist => $dist, pkgs => \@pkg_queries, src => 1 ); if (flavored_bundle() eq 'yes') { my $core = $dist->query(pkgname => 'globus_core'); if (! @$core) { my $corename = get_core_src($pkgdir); $dist->load_gpt("$pkgdir/$corename"); $core = $dist->query(pkgname => 'globus_core'); } #### Add globus_core for GPT 1.x compatibility push @$pkg_pairs, { pkg => $core }; } for my $p (@$pkg_pairs) { my $tarpath = $p->{'pkg'}->gptpkgfile(full=>1); my $tarname = $p->{'pkg'}->gptpkgfile(); push @sortedpkgs, $tarname; push @sortedpkgslist, $p->{'pkg'}->pkgname(); $bndl->addIncludedPackage( pkgName => $p->{'pkg'}->pkgname(), pkgVer => $p->{'pkg'}->version_label(), pkgFlav => $p->{'query'}->{'flavor'}, pkgType => $p->{'query'}->{'pkgtype'} ); # print("cp -f $tarpath $pkgdir/$tarname\n"); my $result = system("cp -f $tarpath $pkgdir/$tarname"); } $bndl->{'TypeOfBundle'} = 'src'; $packagelist = "packaging_list"; } #### end source sub build_bin { $bundlefilename = bundlename('bin'); ## $pkgdir = defined $tmpdir ? $tmpdir : $locations->{'bindir'}; $pkgdir = $locations->{'bindir'}; $locations->create_dirs(mode => 'bundle'); cleandir( $pkgdir ) if ! defined $keep; $installation = new Grid::GPT::Installation( locations => $locations, with_filelists => 1, log => $log ); my $pkg_pairs = get_ordered_packages( dist => $installation, pkgs => \@pkg_queries ); my @pkgs = map { $_->{'pkg'} } @$pkg_pairs; my $packager; $packager = create_bin_packages( pkgs => \@pkgs ) if ! defined $bundledef; for my $p (@pkgs) { push @sortedpkgs, $packager->{'gptfiles'}->{$p->label()} if ! defined $bundledef; $bndl->addIncludedPackage( pkgName => $p->pkgname(), pkgVer => $p->version_label(), pkgFlav => $p->flavor(), pkgType => $p->pkgtype() ); if( defined $native and ! defined $bundledef ) { push @nativesortedpkgs,$packager->{'rpmfiles'}->{$p->label()}; } } $bndl->{'TypeOfBundle'} = 'gpt'; $packagelist = "packagelist"; } #### end binary sub write_bundle { if( defined($bundledef) ) { my $file = "$bundledef.gpt-bundle.xml"; $bndl->output_metadata_file( $file ); exit 0; } $bndlFile = "$bndl->{'Name'}_bundle-" . $bndl->version_label() . ".gpt-bundle.xml"; my $tar = Archive::Tar->new(); my $realdir = cwd(); chdir($pkgdir); if (! ($bundlefilename =~ m/^\//)) { $bundlefilename = Grid::GPT::FilelistFunctions::abspath($bundlefilename); } my @nme = split m!/!, $bundlefilename; my $i = @nme; $bndl->setFileName( file_name => $nme[$i-1] ); $bndl->output_metadata_file( $bndlFile ); push @tst, $bndlFile; $tar->add_files(@tst); $tar->add_files(@sortedpkgs); if (defined $srcdir) { $tar->add_data($packagelist, join "", map { "$_\n" }@sortedpkgslist); } else { $tar->add_data($packagelist, join "", map { "$_\n" }@sortedpkgs); } if ($tar->write($bundlefilename,1)) { print "Bundle written as $bundlefilename\n"; } else { print "ERROR writing $bundlefilename. Make sure any directories specified exist\n"; } chdir($realdir); if (defined $native) { my $tar = Archive::Tar->new(); my $realdir = cwd(); $bundlefilename = bundlename('rpm'); $bndl->{'TypeOfBundle'} = 'rpm'; my @nme = split m!/!, $bundlefilename; my $i = @nme; $bndl->setFileName( file_name => $nme[$i-1] ); $bndl->output_metadata_file( $bndlFile ); chdir($pkgdir); $tar->add_files(@nativesortedpkgs, $bndlFile); $tar->add_data($packagelist, join "\n", @nativesortedpkgs); if ($tar->write($bundlefilename,1)) { print "Bundle written as $bundlefilename\n"; } else { print "ERROR writing $bundlefilename. Make sure any directories specified exist\n"; } chdir($realdir); } } sub create_bundle { # Add overrides to bundle definition $bndl->setFlag( flag => "NoDeps" ) if defined $nodeps; $bndl->setFlag( flag => "NoSetups" ) if defined $nosetups; $bndl->{'Name'} = $bundlename if(defined($bundlename)); ##$bndl->setBundleVersion( label => $bundleversion) $bndl->setBundleVersion( version => $bundleversion) if defined $bundleversion; $bndl->{'bundleStab'} = $bundlestab if(defined($bundlestab)); $bndl->{'versionLabel'} = $bundlelabel if(defined($bundlelabel)); if (@exclude_queries) { for $e (@exclude_queries) { $bndl->addExcludedPackage( pkgName => $e->{'pkgname'}, pkgType => $e->{'pkgtype'}, pkgVer => "0.0", pkgFlav => $e->{'flavor'} ); } } if (@pkg_queries) { for $p (@pkg_queries) { $bndl->addIncludedPackage( pkgName => $p->{'pkgname'}, pkgType => $p->{'pkgtype'}, pkgVer => "0.0", pkgFlav => $p->{'flavor'} ); } } # extract combined bundle definition + overrides my @flags = $bndl->getFlags(); $nodeps++ if grep { defined $_ and $_ eq 'NoDeps' } @flags; $nosetups++ if grep { defined $_ and $_ eq 'NoSetups' } @flags; @exclude_queries = (); for my $e (@{$bndl->getFullBundleExcludedPackageList()}) { push @exclude_queries, { pkgname => $e->{'Name'}, flavor => $e->{'Flavor'}, pkgtype => $e->{'Type'} }; } @pkg_queries = (); for my $p (@{$bndl->getFullBundleIncludedPackageList()}) { push @pkg_queries, { pkgname => $p->{'Name'}, flavor => $p->{'Flavor'}, pkgtype => $p->{'Type'} }; } ## $bndl->clearBundleExcludedPackageList(); ## $bndl->clearBundleIncludedPackageList(); } sub create_template { $bndl->{'Name'} = defined $bndl->{'Name'} ? $bndl->{'Name'} : "NEED A NAME"; if (!@exclude_queries) { $bndl->addExcludedPackage( pkgName => "PACKAGE NAME", pkgVer => "0.0", pkgFlav => "PACKAGE FLAV" ); } if (!@pkg_queries) { $bndl->addIncludedPackage( pkgName => "PACKAGE NAME", pkgVer => "0.0", pkgFlav => "PACKAGE FLAV" ); } $bndl->addComponentName( "NEED A NAME" ); $bndl->addComponentVer( "NEED A VERSION" ); $bndl->addComponentDesc( "NEED A DESCRIPTION" ); $bndl->output_metadata_file( "BundleTemplateXML_FILE.xml" ); } sub create_bin_packages { my(%args) = @_; my $packager = new Grid::GPT::PkgMngmt::Archive(locations => $locations, gpt_rpm_prefix => $rpmprefix, buildno => $buildno, license => $rpmlicense, rpm => $native, # verbose=> $verbose, log=> $log, skip => $keep); my $pkgs= $args{'pkgs'}; my $startdir = getcwd(); chdir $pkgdir; $packager->archive($pkgs); chdir $startdir; return $packager; } sub get_ordered_packages { my(%args) = @_; my ( $dist, $pkgnames, $src ) = ( $args{'dist'}, $args{'pkgs'}, $args{'src'} ); my $pkgset = new Grid::GPT::PkgSet(log => $log); my %nodeptypes; # hash which tracks package types for the nodeps my %pkghash; # hash which tracks packages and their deps for my $e (@exclude_queries) { $dist->add_exclusion( query => $e ); } $dist->exclude_setups() if defined $nosetups; if (defined $all) { my $pkgArray = $dist->pkgs(); $nodeps++; # remove duplicates for my $p (@$pkgArray) { my $plabel = $p->label(); next if $plabel =~ m!globus_core!; if ( !defined($pkghash{$plabel}) ) { $pkghash{$plabel} = { query => { pkgname => 'ANY', flavor => 'ANY', pkgtype => 'ANY' }, pkg => $p}; $pkg_count += 1; } } } my $error_messages; my $message; my $result; my @bad; for my $q (@$pkgnames) { my $preferred_flavor = $q->{'flavor'} if $q->{'flavor'} ne 'ANY'; my $pkgs = matchPackage( query => $q, dist => $dist, src => $src ); push @bad, $q if ! @$pkgs; for my $p (@$pkgs) { my $msg = "Matching Query pkgname=>$q->{'pkgname'} flavor=>$q->{'flavor'} pkgtype=>$q->{'pkgtype'} Found:\n"; next if ( $dist->should_exclude( pkg => $p ) ); if ( ! defined($pkghash{$p->label()}) ) { $msg .= $p->label() . "\n"; $pkghash{$p->label()} = {query => $q, pkg => $p}; $pkg_count += 1; $log->inform("Adding: " . $p->label()); } $log->debug($msg); } } if (! defined $nodeps) { my @added_pkgs = map { $_->{'pkg'} } values %pkghash; for my $ap (@added_pkgs) { # get list of depenvs depending on pkgtype. # If the sdk flag is set then use that list instead. my @depenvs = @{$pkgtype2depenv{defined $sdk ? 'sdk' : $ap->pkgtype()}}; $dist->cleardepenv(); for my $d (@depenvs) { next if $d eq 'Setup' and defined $nosetups; $dist->set_depenv( $d ); } my $depset = $dist->extract_pkgset( pkgs => [$ap], preferred_flavor => $preferred_flavor ); $message = ""; $result = $depset->check_missing( log => \$message ); if ($result) { $error_messages .= $message; } # get dependency tree my $deppkgs = $depset->pkgs(); # remove duplicates for my $p (@$deppkgs) { my $plabel = $p->label(); if ( !defined($pkghash{$plabel}) ) { # Include only one flavor of a program package. if ($p->pkgtype() =~ m!pgm!) { my @other_flavors = grep { $_->{'pkg'}->pkgname() eq $p->pkgname() and $_->{'pkg'}->pkgtype() =~ m!pgm! } values %pkghash; next if @other_flavors; } $pkg_count += 1; $pkghash{$plabel} = {query => undef, pkg => $p}; $log->inform( "Adding Dep Pkg: " . $p->label() ); } } } } if (@bad) { $error_messages .= "ERROR: The following queries did not match any packages:\n"; for my $q (@bad) { $error_messages .= "\tpkgname=>$q->{'pkgname'} flavor=>$q->{'flavor'} pkgtype=>$q->{'pkgtype'}\n"; } } if (defined $error_messages and length($error_messages)) { print STDERR $error_messages; die(); } if ($pkg_count < 1 or (defined $srcdir and $pkg_count < 2)) { Pod::Usage::pod2usage( -verbose => 0, -exitval => 1, -output => \*STDERR, -message => "ERROR: no packages found to put in the bundle!"); } map { $pkgset->add_package(pkgnode=> $_) } map { $_->{'pkg'} } values %pkghash; if (defined $sdk or defined $src) { $pkgset->cleardepenv(); $pkgset->set_depenv('Build'); $pkgset->sort_pkgs(); } else { $pkgset->simple_sort_pkgs(); } # Globus_Core games for GPT-1.x compatibility. my @nocorepkgs = grep { $_->pkgname ne 'globus_core' } reverse @{ ( $pkgset->sorted())}; my @corepkgs = grep { $_->pkgname eq 'globus_core' } @{ ( $pkgset->sorted() )}; my @bundledefs; for my $p (@nocorepkgs, @corepkgs) { my @pairs = grep { $p->is_same($_->{'pkg'})} values %pkghash; if (! @pairs) { print STDERR "ERROR: Internal error cannot match ", $p->label(), "\n"; for my $pa (values %pkghash) { my($pkgname, $flavor, $pkgtype, $label) = ($pa->{'query'}->{'pkgname'}, $pa->{'query'}->{'flavor'}, $pa->{'query'}->{'pkgtype'}, $pa->{'pkg'}->label()); print STDERR "/pkgname=$pkgname/flavor=$flavor/pkgtype=$pkgtype->$label\n"; } die; } push @bundledefs, $pairs[0]; } @bundledefs = reverse @bundledefs; return \@bundledefs; } sub matchPackage { my(%args) = @_; my ($pkgname, $flavor, $pkgtype, $src) = ( $args{'query'}->{'pkgname'}, $args{'query'}->{'flavor'}, $args{'query'}->{'pkgtype'}, $args{'src'} ); my $dist = $args{'dist'}; my $pkgs; $pkgtype = 'src' if defined $src; # $pkgtype = $pkgtype eq 'pgm_static' ? 'pgm' : $pkgtype; $log->debug("Query with: \ /pkgname=$pkgname/flavor=$flavor/pkgtype=$pkgtype\n"); $pkgs = $dist->query( pkgname => $pkgname, flavor => $flavor, pkgtype => $pkgtype ); if(!@$pkgs and $pkgtype eq 'pgm') { # check for pgm_static packages $log->debug("pgm_static Query with: \ /pkgname=$pkgname/flavor=$flavor/pkgtype=pgm_static\n"); $pkgs = $dist->query( pkgname => $pkgname, flavor => $flavor, pkgtype => 'pgm_static' ); } if(!@$pkgs and $pkgname =~ m!setup!) { # check for any flavor setup packages $log->debug("Flavor Setup Query with: \ /pkgname=$pkgname/flavor=ANY/pkgtype=$pkgtype\n"); $pkgs = $dist->query( pkgname => $pkgname, pkgtype => $pkgtype ); if(!@$pkgs) { # check for pgm setup packages $newtype = $pkgtype eq 'pgm' ? 'pgm_static' : 'pgm'; $log->debug("Flavor Setup pgm Query with: \ /pkgname=$pkgname/flavor=ANY/pkgtype=$newtype\n"); $pkgs = $dist->query( pkgname => $pkgname, pkgtype => $newtype ); } } my $msg = "Query Results: \n"; for my $p (@$pkgs) { $msg .= "\t" . $p->label() . "\n"; } $log->debug($msg); ## @$pkgs = grep { ! $dist->should_exclude(pkg => $_)} @$pkgs; return $pkgs; } sub bundlename { my ($format) = @_; if (defined $outputfile) { return $outputfile if $format ne 'rpm'; my $nativefile = $outputfile; $nativefile =~ s!\.tar\.gz!_$format\.tar\.gz!; return $nativefile; } if (! defined $arch) { # Add path to LocalEnv module to @INC push @INC,"$gpath/var/lib/perl"; die "ERROR: GPT is not configured. Use gpt-config\n" if ! defined eval ("require Grid::GPT::LocalEnv;"); require Grid::GPT::LocalEnv; $arch = Grid::GPT::LocalEnv::get_target(); } my $version = $bndl->version_label(); my $file = "$bndl->{'Name'}-$version-" . ($format ne 'src' ? "$arch-" : "") . "$format" . ($format eq 'src' ? "_bundle" : "") . ".tar.gz"; return Grid::GPT::FilelistFunctions::abspath($file); } sub cleandir { my ($top) = @_; opendir(DIR, $top); my @contents = readdir DIR; closedir DIR; my @dirs = grep { -d "$top/$_" and ! m!^\.! } @contents; my @files = grep { ! -d $_ } map { "$top/$_" } @contents; for my $f (@files) { unlink($f) or warn "couldn't unlink $f: $!"; } for my $d (@dirs) { cleandir("$top/$d"); } } # This less then glorious hack needs to be done in modules sub get_core_src { my $dir = shift; require Grid::GPT::PkgMngmt::SetupBuildFlavors; my $core_src = Grid::GPT::PkgMngmt::SetupBuildFlavors::get_core_src(); my $pkg=Grid::GPT::PkgDist::get_pkgdata_from_tar($core_src); die "ERROR: Cannot create a source bundle without a globus_core package" if ! defined $pkg; my $corename = "globus_core-" . $pkg->{'Version'}->label() . ".tar.gz"; my $result = system("cp -f $core_src $dir/$corename"); return $corename; } sub flavored_bundle { my ($bundle) = @_; for my $p (map {$_->{'pkg'}} @$bundle) { next if ! defined $p->{'depnode'}->{'With_Flavors'}; return 'yes' if $p->{'depnode'}->{'With_Flavors'} eq 'yes'; } return 'no'; } __END__ =head1 NAME B - Creates binary or source bundles from an installation or a collection of source packages. =head1 SYNOPSIS B [options] packages Options: -verbose Print copious output -help Print usage -man Print man page. -version Print GPT version. -srcdir=PATH Directory containing source packages -tmpdir=PATH Directory used to create binary packages -installdir=PATH Directory containing an installation -bn=NAME Name of the bundle -bv=MAJOR.MINOR Version of the bundle -bs=STABILITY Stability of the bundle contents -bl=VERSION Version Label of the bundle -native Create bundles of native pkgs (RPMs only). -all Bundle everything in the package directory.. -nodeps Don't include any dependent packages. -nosetups Don't include dependent setup packages. -template Outputs empty Bundle Def XML file. -bundledef=FILE Outputs XML file with command line values. -exclude=PACKAGE Don't include PACKAGE in bundle -config=FILE Use bundle options stored in FILE -xml=FILE XML bundle description file -output=FILE Name of the bundle file, -rpmprefix=PATH Absolute path encoded in the RPM. -buildnumber=NUMBER Build number used for pgm_static packages -rpmlicense=LABEL License Label added to the RPM header [packages] List of packages to be bundled =head1 DESCRIPTION B Creates binary or source bundles from an installation or a collection of source packages. These bundles can then distributed be installed using I or I. A bundle consists of a collection of packages and a XML formatted description file. The DTD for this file is found in I<$GPT_LOCATION/etc/gpt_bundle.dtd>. The script accepts a list of packages from the command line or from an inputed bundle description file. It expands this list to include all of the packages that the listed packages depend on. It then uses this expanded list to create a new bundle description file which is then added to the collection of packages to form a bundle. B assumes that all of the packages needed to create a source bundle are found in one subdirectory identified by the I<-srcdir> switch. B assumes that all of the packages need to create a binary bundle are installed in a location identified by the I<-installdir> flag or $GLOBUS_LOCATION. The list of packages that can be entered from the command line are of the form I. The wildcard character '*' can also be used. =head1 OPTIONS =over 8 =item B<-srcdir=PATH> Specifies where the directory containing your source packages is. If this is used, a source bundle will be created. Note that this flag is required to create source bundles. =item B<-installdir=PATH> Specifies where the installation used for creating binary bundles is. $GLOBUS_LOCATION is the default. =item B<-xml=FILE> Specifies the input bundle description file. A new file will be generated using the contents of this file and included in the bundle. =item B<-bundlename=NAME> The name of the bundle. This name is stored in the bundle description file and used as part of the bundle filename if B<-output> is not specified. =item B<-bundleversion=MAJOR.MINOR> This is the bundle version number. It is stored in the bundle description file and used for bundle updates. It is also used for the bundle filename if B<-bundlelabel> is not specified. =item B<-bundlelabel=VERSION> This is the bundle version label. It is stored in the bundle description file as a string and so can accomodate any versioning scheme. The label is used in user queries, and as part of the bundle filename. =item B<-bundlestability=STABILITY> This is the bundle version stability. It is a field that is used to indicate the stability of this version of the bundle. The field can have values of B, B, B, or B. The default vaule is experimental. The field is stored in the bundle description file and used for user queries. =item B<-tmpdir=PATH> Specifies the where the directory is that B should use to store generated binary packages. =item B<-all> Tells B to bundle all of the packages in the source package directory or installation. =item B<-native> Tells B to also bundle packages that are in the native format of the operating system. Presently this only works for RPMS on linux. B will output two bundle giving the native bundle a platform specific extension such as -rpm. =item B<-nodeps> Tells B to only include the packages specified--do not check for or include dependencies. =item B<-nosetups> Tells B to exclude any packages that are pulled in by a setup dependencies. Note that setup packages that are listed on the command line will still be added to the bundle.. =item B<-exclude=package1,package2,...> This option excludes the listed packages from the created bundle. It can be specified multiple times with the final listing used being an aggregate of all the listed packages. This option can be abbreviated as '-exclude=package1,package2,...'. =item B<-output=FILE> This is an alternative way to specify the bundle name. The output file is put in the directory from which B was invoked if no path was given, in a directory relative it if a relative path was given, or in the absolute location, if given. =item B<-template> Creates an empty Bundle XML that can be modified and used to create a new bundle. =item B<-bundledef=FILE> Creates an XML file with name equal to B.gpt-bundle.xml. This file will contain a GPT Bundle definition with values set to those passed in on the command line. =item B<-rpmprefix=> This should be set to the path to your GLOBUS_LOCATION. GPT will use a value of "/usr/grid" if this option is not specified. =item B<-rpmlicense=