OpenPKG CVS Repository http://cvs.openpkg.org/ ____________________________________________________________________________
Server: cvs.openpkg.org Name: Ralf S. Engelschall Root: /e/openpkg/cvs Email: [EMAIL PROTECTED] Module: openpkg-tools Date: 09-Apr-2004 21:44:21 Branch: HEAD Handle: 2004040920442100 Added files: openpkg-tools/cmd fetch.pl makeproxy.pl Modified files: openpkg-tools/cmd dev.sh Log: add makeproxy and fetch commands here and use them from within dev Summary: Revision Changes Path 1.5 +2 -2 openpkg-tools/cmd/dev.sh 1.1 +256 -0 openpkg-tools/cmd/fetch.pl 1.1 +507 -0 openpkg-tools/cmd/makeproxy.pl ____________________________________________________________________________ patch -p0 <<'@@ .' Index: openpkg-tools/cmd/dev.sh ============================================================================ $ cvs diff -u -r1.4 -r1.5 dev.sh --- openpkg-tools/cmd/dev.sh 9 Apr 2004 08:18:30 -0000 1.4 +++ openpkg-tools/cmd/dev.sh 9 Apr 2004 19:44:21 -0000 1.5 @@ -1682,7 +1682,7 @@ if [ ! -f "$rpmdir/$rpmfile" -o $force -ne 0 ]; then echo "++ building $package ($rpmfile)" opt="`echo ${opt} | tr ' ' '\n' | ${EGREP} . | sed -e 's;^;--define \";' -e 's;=; ;' -e 's;$;\";' | tr '\n' ' '`" - (builtin cd ${OPENPKG_WORK}/src/${name} && rpm --fetch ${name}.spec) + (builtin cd ${OPENPKG_WORK}/src/${name} && openpkg fetch ${name}.spec) (builtin cd ${OPENPKG_WORK}/src/${name} && eval "rpm -ba ${opt} ${name}.spec") if [ ! -f "$rpmdir/$rpmfile" ]; then warn "failed to build $package ($rpmfile)" @@ -1980,7 +1980,7 @@ done fi echo "++ Fetching files for package specification: $file" - rpm --fetch ${file} + openpkg fetch ${file} if [ $? -gt 0 -a $force -ne 1 ]; then die "fetching sources for ${file} failed" fi @@ . patch -p0 <<'@@ .' Index: openpkg-tools/cmd/fetch.pl ============================================================================ $ cvs diff -u -r0 -r1.1 fetch.pl --- /dev/null 2004-04-09 21:44:21.000000000 +0200 +++ fetch.pl 2004-04-09 21:44:21.000000000 +0200 @@ -0,0 +1,256 @@ +## +## openpkg -- OpenPKG Tool Chain +## Copyright (c) 2000-2004 The OpenPKG Project <http://www.openpkg.org/> +## Copyright (c) 2000-2004 Ralf S. Engelschall <[EMAIL PROTECTED]> +## Copyright (c) 2000-2004 Cable & Wireless <http://www.cw.com/> +## +## Permission to use, copy, modify, and distribute this software for +## any purpose with or without fee is hereby granted, provided that +## the above copyright notice and this permission notice appear in all +## copies. +## +## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED +## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR +## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +## SUCH DAMAGE. +## + +require 5; +use strict; +use OpenPKG::Ctx; + +# determine OpenPKG information +my $ctx = new OpenPKG::Ctx; +my $prefix = $ctx->prefix(); +my $me = $ctx->cmdprog() . " " . $ctx->cmdname(); +my $rpm = $ctx->cmdprog() . " " . "rpm"; +my $curl = "$prefix/lib/openpkg/curl"; + +# FIXME: hack for "openpkg dev" +delete $ENV{'OPENPKG_TOOLS'}; + +# command line parsing +if (@ARGV != 1) { + print STDERR "openpkg:fetch:ERROR: requires an argument\n"; + print STDERR "openpkg:fetch:USAGE: \"$me <name>.spec\"\n"; + exit(1); +} +my $spec = @ARGV[0]; +if (not -f $spec) { + print STDERR "openpkg:fetch:ERROR: spec file \"$spec\" not found\n"; + exit(1); +} + +# determine package name +my $name = $spec; +$name =~ s|\.[^.]+$||; +$name =~ s|^.+/([^/]+)$|$1|; + +# determine source directories +my $local_srcdir = `$rpm --define 'name $name' --eval '%_sourcedir'`; +my $local_specdir = `$rpm --define 'name $name' --eval '%_specdir'`; +$local_srcdir =~ s|\n+$||s; +$local_specdir =~ s|\n+$||s; + +# make sure source and spec directory actually exists +if (not -d $local_srcdir) { + print(STDERR "openpkg:fetch: creating directory $local_srcdir\n"); + system("mkdir $local_srcdir"); +} +if (not -d $local_specdir) { + print(STDERR "openpkg:fetch: creating directory $local_specdir\n"); + system("mkdir $local_specdir"); +} + +# determine some RC parameters +my $RC = {}; +my $var; +my $vars = ''; +foreach $var (qw( + _dbpath _rpmdir _srcrpmdir _tmppath + _target + l_prefix + l_fetch_mirror_0 l_fetch_mirror_1 l_fetch_mirror_2 l_fetch_mirror_3 l_fetch_mirror_4 + l_fetch_mirror_5 l_fetch_mirror_6 l_fetch_mirror_7 l_fetch_mirror_8 l_fetch_mirror_9 + l_fetch_backup_0 l_fetch_backup_1 l_fetch_backup_2 l_fetch_backup_3 l_fetch_backup_4 + l_fetch_backup_5 l_fetch_backup_6 l_fetch_backup_7 l_fetch_backup_8 l_fetch_backup_9 + _httpproxy _httpport + _ftpproxy _ftpport +)) { + $vars .= "${var}=\%{${var}};"; +} +my @assign = split(/;/, `$rpm --eval '$vars'`); +foreach my $assign (@assign) { + if ($assign =~ m|^(\S+)=(.*)$|s) { + if ($2 ne '%{'.$1.'}') { + $RC->{$1} = $2; + } + } +} + +# parse spec file +my $DEF = {}; +my $SRC = {}; +open(SPEC, "<$spec"); +while (<SPEC>) { + s|\n+$||s; + if (m/^([a-zA-Z_][a-zA-Z0-9_]*):\s*(.+?)\s*$/) { + $DEF->{lc($1)} = $2; + } + if (m/^%define\s+([a-zA-Z_][a-zA-Z0-9_]*)\s+(.+?)\s*$/) { + $DEF->{lc($1)} = $2; + } + if (m/^((Source|Patch)[0-9]+?):\s*(.+?)\s*$/i) { + my ($remote_srcid, $remote_srcurl) = ($1, $3); + + # determine expanded remote source location + 1 while ($remote_srcurl =~ s|%{?([a-zA-Z_][a-zA-Z0-9_]*)}?|$DEF->{lc($1)}|sge); + my $remote_srcdir = ''; + my $remote_srcfile = $remote_srcurl; + if ($remote_srcfile =~ m|^(.+)/([^/]+)$|) { + $remote_srcdir = $1; + $remote_srcfile = $2; + } + + # display remote source location + my $file = $remote_srcfile; + $file = substr($file, 0, 40) if (length($file) > 40); + printf(STDERR "++ %-9s %-40s ", "$remote_srcid:", $file); + + if (-f "$local_srcdir/$remote_srcfile" or -f "$local_specdir/$remote_srcfile") { + # source already on local filesystem + my $size; + if (-f "$local_srcdir/$remote_srcfile") { + $size = (stat("$local_srcdir/$remote_srcfile"))[7]; + } + else { + $size = (stat("$local_specdir/$remote_srcfile"))[7]; + } + if ($size > 1024*1024) { + $size = sprintf("%.1fMB", $size / (1024*1024)); + } + elsif ($size > 1024) { + $size = sprintf("%.0fKB", $size / 1024); + } + else { + $size = sprintf("%d", $size); + } + print STDERR "...OK [$size]\n"; + } + else { + # fetch source onto local filesystem + print STDERR "...MISSING\n"; + + # determine prioritized list of possible source locations + my @fetch_srcdir = (); + for (my $i = 0; $i <= 9; $i++) { + my $url = $RC->{"l_fetch_mirror_$i"}; + next if (not defined($url) or $url eq '' or $url eq '-'); + 1 while ($url =~ s|%{?([a-zA-Z_][a-zA-Z0-9_]*)}?|$DEF->{lc($1)}|sge); + push(@fetch_srcdir, $url); + } + push(@fetch_srcdir, $remote_srcdir); + for (my $i = 0; $i <= 9; $i++) { + my $url = $RC->{"l_fetch_backup_$i"}; + next if (not defined($url) or $url eq '' or $url eq '-'); + 1 while ($url =~ s|%{?([a-zA-Z_][a-zA-Z0-9_]*)}?|$DEF->{lc($1)}|sge); + push(@fetch_srcdir, $url); + } + + # try to fetch from all possible locations + foreach my $fetch_srcdir (@fetch_srcdir) { + $fetch_srcdir =~ s|/+$||s; + print STDERR "openpkg:fetch: fetching from $fetch_srcdir/\n"; + if ((my $err = &fetch_url("$fetch_srcdir/$remote_srcfile", "$local_srcdir/$remote_srcfile"))) { + $err = substr($err, 0, 37)."..." if (length($err) > 40); + print STDOUT "openpkg:fetch:ERROR: $err\n"; + next; + } + last; + } + if (not -f "$local_srcdir/$remote_srcfile") { + print STDERR "openpkg:fetch: failed to fetch source file `$remote_srcfile'\n"; + return 1; + } + } + } +} +close(SPEC); +exit(0); + +sub fetch_url { + my ($src, $dst) = @_; + + # make sure file URLs have a fully-qualified scheme. + if ($src =~ m|^/.+|) { + $src = "file://$src" + } + + # make sure only schemes curl(1) supports are used. + if ($src !~ m;^(file|http|ftp)://.+;) { + return "invalid URL - only file, http and ftp schemes supported"; + } + + my $rc; + { + my $hpxy = $RC->{"_httpproxy"}; + my $hprt = $RC->{"_httpport"}; + my $fpxy = $RC->{"_ftpproxy"}; + my $fprt = $RC->{"_ftpport"}; + + $hprt = 80 unless $hprt > 0; + $fprt = 21 unless $fprt > 0; + + if (defined $hpxy && defined $hprt) { + $hpxy .= ":$hprt"; + } + if (defined $fpxy && defined $fprt) { + $fpxy .= ":$fprt"; + } + + local($ENV{'http_proxy'}) = $hpxy; + local($ENV{'ftp_proxy'}) = $fpxy; + + # try to fetch the URL + unlink("$dst.hdr"); + $rc = system($curl + " --location" . + " --max-time 1800" . + " --connect-timeout 20" . + " --dump-header $dst.hdr" . + " --output '$dst' '$src'"); + + } + + # check whether command failed + if ($rc != 0) { + return "cURL error"; + } + + # check whether remote sites failed + if (-s "$dst.hdr") { + open(FP, "<$dst.hdr"); + my $response = <FP>; + close(FP); + if ($response =~ m|^HTTP/[\d.]+\s+(\d+)|) { + if ($1 ne 200) { + $response =~ s|\n$||; + unlink($dst); + return $response; + } + } + } + + # cleanup + unlink("$dst.hdr"); + + return ''; +} @@ . patch -p0 <<'@@ .' Index: openpkg-tools/cmd/makeproxy.pl ============================================================================ $ cvs diff -u -r0 -r1.1 makeproxy.pl --- /dev/null 2004-04-09 21:44:21.000000000 +0200 +++ makeproxy.pl 2004-04-09 21:44:21.000000000 +0200 @@ -0,0 +1,507 @@ +## +## openpkg -- OpenPKG Tool Chain +## Copyright (c) 2000-2004 The OpenPKG Project <http://www.openpkg.org/> +## Copyright (c) 2000-2004 Ralf S. Engelschall <[EMAIL PROTECTED]> +## Copyright (c) 2000-2004 Cable & Wireless <http://www.cw.com/> +## +## Permission to use, copy, modify, and distribute this software for +## any purpose with or without fee is hereby granted, provided that +## the above copyright notice and this permission notice appear in all +## copies. +## +## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED +## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR +## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +## SUCH DAMAGE. +## + +require 5.003; +use strict; +use Getopt::Long; +use IO; + +my $progname = "makeproxy"; +my $progvers = "0.9.4"; + +# parameters (defaults) +my $version = 0; +my $verbose = 0; +my $debug = 0; +my $help = 0; +my $rpm = 'rpm'; +my $tmpdir = ($ENV{TMPDIR} || "/tmp") . "/$progname"; +my $output = '.'; +my $input = '-'; +my $prefix = ''; + +# cleanup support +my @cleanup = (); +sub cleanup_remember { + my ($cmd) = @_; + push(@cleanup, $cmd); +} +sub cleanup_perform { + foreach my $cmd (@cleanup) { + &runcmd($cmd); + } +} + +# exception handling support +$SIG{__DIE__} = sub { + my ($err) = @_; + $err =~ s|\s+at\s+.*||s if (not $verbose); + print STDERR "$progname:ERROR: $err ". ($! ? "($!)" : "") . "\n"; + &cleanup_perform() if (not $verbose); + exit(1); +}; + +# verbose message printing +sub verbose { + my ($msg) = @_; + print STDERR "$msg\n" if ($verbose); +} + +# execution of external commands +sub runcmd { + my ($cmd) = @_; + print STDERR "\$ $cmd\n" if ($debug); + $cmd = "($cmd) >/dev/null 2>&1" if (not $debug); + return (system($cmd) == 0); +} + +# expand into a full filesystem path +sub fullpath { + my ($prog) = @_; + my $fullprog = ''; + foreach my $path (split(/:/, $ENV{PATH})) { + if (-x "$path/$prog") { + $fullprog = "$path/$prog"; + last; + } + } + return $fullprog; +} + +# convert a subdirectory (a/b/c/) +# into a corresponding reverse path (../../../) +sub sub2rev { + my ($sub) = @_; + my $rev = ''; + $sub =~ s|^/+||s; + $sub =~ s|/+$||s; + while ($sub =~ s|/[^/]+||) { + $rev .= "../"; + } + if ($sub ne '') { + $rev .= "../"; + } + $rev =~ s|/$||s; + return $rev; +} + +# create a directory (plus its missing parent dirs) +sub mkdirp { + my ($dir) = @_; + my $pdir = $dir; + $pdir =~ s|/[^/]*$||s; + if (not -d $pdir) { + &mkdirp($pdir); + } + if (not -d $dir) { + &runcmd("mkdir $dir"); + } +} + +# command line parsing +Getopt::Long::Configure("bundling"); +my $result = GetOptions( + 'V|version' => \$version, + 'h|help' => \$help, + 'd|debug' => \$debug, + 'v|verbose' => \$verbose, + 'r|rpm=s' => \$rpm, + 't|tmpdir=s' => \$tmpdir, + 'o|output=s' => \$output, + 'p|prefix=s' => \$prefix +) || die "option parsing failed"; +if ($help) { + print "Usage: $progname [options] [FILE]\n" . + "Available options:\n" . + " -h,--help print out this usage page\n" . + " -v,--verbose enable verbose run-time mode\n" . + " -r,--rpm=FILE filesystem path to RPM program\n" . + " -t,--tmpdir=PATH filesystem path to temporary directory\n" . + " -o,--output=FILE filesystem path to output RPM file\n"; + " -p,--prefix=PATH filesystem path to referenced master hierarchy\n"; + exit(0); +} +if ($version) { + print "OpenPKG $progname $progvers\n"; + exit(0); +} +if ($#ARGV == 0) { + $input = shift(@ARGV); +} +if ($#ARGV != -1) { + die "invalid number of command line arguments"; +} + +# prepare temporary location +&verbose("++ prepare temporary directory"); +if (not -d $tmpdir) { + &runcmd("mkdir $tmpdir && chmod 0700 $tmpdir") + || die "cannot create temporary directory '$tmpdir'"; + &cleanup_remember("rmdir $tmpdir"); +} +&verbose("-- $tmpdir"); + +# determine RPM program +if (not -x $rpm) { + $rpm = &fullpath($rpm); +} +my $rpmvers = `$rpm --version 2>/dev/null`; +$rpmvers =~ s|^OpenPKG\s+RPM\s+([0-9.]+)\s*$|$1|s || die "program '$rpm' seems to be not RPM"; +&verbose("++ determining RPM program"); +&verbose("-- $rpm ($rpmvers)"); + +# determine input and output RPM +&verbose("++ determining RPM package files"); +&verbose("-- input/original RPM: $input"); +&verbose("-- output/proxy RPM: $output"); +if ($input eq '-') { + $input = "$tmpdir/input.rpm"; + &runcmd("cat >$input"); +} +if (not -f $input) { + die "input RPM does not exist: '$input'"; +} + +# helper function for parsing the query outputs +sub parseresponse { + my ($r, $o) = @_; + $o =~ s|([SM])-([^:]+):<(.*?)>\n|&parseline($r, $1, $2, $3, '')|egs; + sub parseline { + my ($r, $t, $k, $v) = @_; + $v =~ s|^\s+||s; + $v =~ s|\s+$||s; + if ($t eq 'S') { # single-value results + $r->{$k} = $v; + } + elsif ($t eq 'M') { # multi-value results + $r->{$k} = [] if (not defined($r->{$k})); + push(@{$r->{$k}}, $v); + } + } + return $r; +} + +# query input RPM package +&verbose("++ query information from input RPM"); +my $q = ''; +foreach my $t (qw( + NAME SUMMARY URL VENDOR PACKAGER DISTRIBUTION GROUP LICENSE VERSION RELEASE + DESCRIPTION +)) { + $q .= "S-$t:<%{$t}>\n"; +} +$q .= "[M-PREREQ:<%{REQUIRENAME} %|REQUIREFLAGS?{%{REQUIREFLAGS:depflags} %{REQUIREVERSION}}:{}|>\n]"; +$q .= "[M-PREFIXES:<%{PREFIXES}>\n]"; +my $o = `$rpm -qp --qf "$q" $input`; +$o =~ s|M-PREREQ:<rpmlib\(.*?\).*?>\n||gs; +my $r = {}; +$r = &parseresponse($r, $o); +my $BD = ''; +my $ID = ''; +foreach my $d (@{$r->{PREREQ}}) { + if ($d =~ m|^OpenPKG|i) { + $BD .= ", " if ($BD ne ''); + $BD .= $d; + } + $ID .= ", " if ($ID ne ''); + $ID .= $d; +} +my $rprefix = ${$r->{PREFIXES}}[0]; +$rprefix =~ s|/+$||s; +&verbose("-- remote OpenPKG prefix: $rprefix"); +&verbose("++ query information from target OpenPKG"); +$q = ''; +foreach my $t (qw( + l_prefix +)) { + $q .= "S-$t:<%{$t}>\n"; +} +$o = `$rpm --eval "$q"`; +$r = &parseresponse($r, $o); +my $lprefix = $r->{l_prefix}; +$lprefix =~ s|/+$||s; +&verbose("-- local OpenPKG prefix: $lprefix"); + +# prepare build environment +&verbose("++ establishing temporary RPM environment"); +&runcmd("rm -rf $tmpdir/src; mkdir $tmpdir/src"); +&runcmd("rm -rf $tmpdir/tmp; mkdir $tmpdir/tmp"); +&runcmd("rm -rf $tmpdir/bld; mkdir $tmpdir/bld"); +&runcmd("rm -rf $tmpdir/pkg; mkdir $tmpdir/pkg"); +&cleanup_remember("rm -rf $tmpdir/src"); +&cleanup_remember("rm -rf $tmpdir/tmp"); +&cleanup_remember("rm -rf $tmpdir/bld"); +&cleanup_remember("rm -rf $tmpdir/pkg"); +my $macro = new IO::File (">$tmpdir/.rpmmacros"); +$macro->print("%_sourcedir $tmpdir/src\n" . + "%_specdir $tmpdir/src\n" . + "%_builddir $tmpdir/tmp\n" . + "%_tmppath $tmpdir/tmp\n" . + "%_rpmdir $tmpdir/pkg\n" . + "%_srcrpmdir $tmpdir/pkg\n"); +$macro->close; +$ENV{HOME} = $tmpdir; +&verbose("-- temporary sourcedir/specdir: $tmpdir/src"); +&verbose("-- temporary builddir/tmppath: $tmpdir/tmp"); +&verbose("-- temporary rpmdir/srcrpmdir: $tmpdir/pkg"); + +# generate .spec file for proxy RPM package +&verbose("++ generating RPM specification for proxy RPM"); +my $S = ''; +$S .= "Name: ".$r->{NAME}."\n"; +$S .= "Summary: ".$r->{SUMMARY}."\n"; +$S .= "URL: ".$r->{URL}."\n"; +$S .= "Vendor: ".$r->{VENDOR}."\n"; +$S .= "Packager: ".$r->{PACKAGER}."\n"; +$S .= "Distribution: ".$r->{DISTRIBUTION}."\n"; +$S .= "Group: ".$r->{GROUP}."\n"; +$S .= "License: ".$r->{LICENSE}."\n"; +$S .= "Version: ".$r->{VERSION}."\n"; +$S .= "Release: ".$r->{RELEASE}."+PROXY\n"; +$S .= "\n"; +$S .= "Prefix: %{l_prefix}\n"; +$S .= "BuildRoot: $tmpdir/bld\n"; +$S .= "BuildPreReq: $BD\n"; +$S .= "PreReq: $ID\n"; +$S .= "AutoReq: no\n"; +$S .= "AutoReqProv: no\n"; +#$S .= "Provides: ".$r->{NAME}.", ".$r->{NAME}."-".$r->{VERSION}."-".$r->{RELEASE}."\n"; +$S .= "\n"; +$S .= "%description\n"; +$S .= " ".$r->{DESCRIPTION}."\n"; +$S .= "\n"; +$S .= "%install\n"; +$S .= " %{l_rpmtool} files -v -ofiles -r\$RPM_BUILD_ROOT %{l_files_std}\n"; +$S .= "\n"; +$S .= "%files -f files\n"; +$S .= "\n"; +my $spec = new IO::File (">$tmpdir/src/".$r->{NAME}.".spec"); +$spec->print($S); +$spec->close; +&verbose("-- $tmpdir/src/".$r->{NAME}.".spec"); + +# creating shadow tree of original contents +&verbose("++ creating shadow tree from original contents"); +my @FL = `$rpm -qp --qf '[%{FILEMODES:perms} %{FILENAMES}\n]' $input`; +my $FD = []; +my $FR = []; +foreach my $fl (@FL) { + $fl =~ s|\n$||s; + if ($fl =~ m|^(d\S+)\s+$rprefix(.*)$|) { + &mkdirp("$tmpdir/bld$lprefix$2"); + &verbose("-- | PHYS $1 $lprefix$2"); + } + elsif ($fl =~ m|^(\S+)\s+$rprefix(.*?)([^/\s]+)$|) { + my ($subdir, $file) = ($2, $3); + my $target = sub2rev($subdir)."/.prefix-".$r->{NAME}.$subdir.$file; + &mkdirp("$tmpdir/bld$lprefix$subdir"); + &runcmd("ln -s $target $tmpdir/bld$lprefix$subdir$file"); + &verbose("-- | VIRT $1 $lprefix$subdir$file"); + } +} + +# create master-reference symbolic link +my $xprefix = $rprefix; +$xprefix = $prefix if ($prefix ne ''); +&runcmd("ln -s $xprefix $tmpdir/bld$lprefix/.prefix-".$r->{NAME}); + +# rolling output proxy RPM package +&verbose("++ rolling output proxy RPM package"); +&runcmd("cd $tmpdir/src && $rpm -bb --nodeps ".$r->{NAME}.".spec"); + +# providing output +&verbose("++ providing output"); +if ($output eq '-') { + &runcmd("cat $tmpdir/pkg/*.rpm"); +} +else { + &runcmd("cp $tmpdir/pkg/*.rpm $output"); +} + +# die gracefully... +&verbose("++ cleaning up environment"); +&cleanup_perform(); +exit(0); + +__END__ + +=pod + +=head1 NAME + +B<mkproxyrpm> -- Make OpenPKG Proxy RPM Package + +=head1 SYNOPSIS + +B<mkproxyrpm> +[B<--verbose>] +[B<--debug>] +[B<--help>] +[B<--rpm>=I<FILE>] +[B<--tmpdir>=I<DIR>] +[B<--output>=I<DIR>|I<FILE>|C<->] +[B<--prefix>=I<RPREFIX>] +[I<FILE>|C<->] + +=head1 DESCRIPTION + +B<mkproxyrpm> creates an B<OpenPKG> proxy package by translating a +binary RPM file into a proxy binary RPM file. A proxy package contains +(virtually) the same contents as the original package in the form +of a shadow tree. Such a shadow tree consists of the same physical +directories as the original tree but with all other files replaced by +symbolic links pointing to the original files in the remote B<OpenPKG> +instance. + +A proxy package is useful if multiple B<OpenPKG> instances are installed on +the same system. In this case lots of dependent (and this way required, +although not explicitly wanted) packages have to be installed in every +instance. Think about packages like B<openssl>, B<perl>, B<gcc>, etc. This can +be both very time-consuming and can become a maintainance nightmare. +Instead, you can select a master (or remote) B<OpenPKG> instance, +install those packages physically there only and install a simple proxy +packages for them in all other (local) B<OpenPKG> instances. + +Keep in mind that this obviously works correctly for packages which do not +have hard-coded dependencies to their B<OpenPKG> instance (like configuration +files, etc.). For other packages it might also work, but be at least warned +about side-effects. Additionally, make sure you always keep (local) proxy +packages in sync with the (remote) master package. + +=head1 SHADOW TREE + +The symbolic links in the shadow tree of the proxy package B<foo> are of +the form: + +I<lprefix>[/I<dir>]/I<file> -> I<revdir>C</.prefix->B<foo>[/I<dir>]/I<file> + +And to make them working, there is the following additional symbolic +link installed: + +I<lprefix>C</.prefix->B<foo> -> I<rprefix> + +Here I<lprefix> is the prefix of the local B<OpenPKG> instance and +I<rprefix> is the prefix of the remote B<OpenPKG> instance. This allows +one to redirect a whole package to a different B<OpenPKG> instance by +just changing the I<lprefix>C</.prefix->B<foo> symbolic link. The idea +is that later this link even could be automatically controlled by a +higher-level facility. The I<rprefix> target of the symbolic link can be +overridden at build-time with the B<--prefix>=I<RPREFIX> option. + +=head1 OPTIONS + +The following command line options and arguments are supported: + +=over 4 + +=item B<--verbose> + +Enable verbose messages on F<stderr> summarizing the internal processing. + +=item B<--debug> + +Enable debugging messages on F<stderr> showing the executed shell commands. + +=item B<--help> + +Print the usage message and immediately exit. + +=item B<--rpm>=I<FILE> + +Set a particular B<RPM> program to use. The default is the program +"C<rpm>" in C<$PATH>. This has to be the C<rpm> of the target B<OpenPKG> +instance where the proxy package will be installed later. + +=item B<--tmpdir>=I<DIR> + +Set a particular temporary directory. The default is determined from +C<$TMPDIR>, or C</tmp> (in that order). + +=item B<--output>=I<DIR>|I<FILE>|C<-> + +Set the location where to write the output +proxy RPM package. If the input RPM is named +"I<name>C<->I<version>C<->I<release>C<.>I<arch>C<->I<os>C<->I<id1>C<.rpm +>" the output RPM is named +"I<name>C<->I<version>C<->I<release>C<+PROXY>C<.>I<arch>C<->I<os>C<->I<i +d2>C<.rpm>" (I<id1> is the identification of the master B<OpenPKG> +instance, I<id2> is the identification of the B<OpenPKG> instance for +which the proxy package is built). The special argument "C<->" indicates +that the output RPM is written to F<stdout>. The default is "C<.>" (the +current working directory). + +=item I<FILE>|C<-> + +Set the location where to read the input RPM package. The special +argument "C<->" indicates that the input RPM is read from F<stdin> (the +default). + +=back + +=head1 EXAMPLE + +Assume you have three B<OpenPKG> instances on a system: C</usr/opkg> +(the master instance), C</e/foo/sw> (a project instance), and C</e/bar/sw> +(another project instance). Now let us install the C<bash> package in +all three locations, but only once physically. + + # build and install binary RPM for /usr/opkg instance + $ /usr/opkg/bin/rpm --rebuild \ + ftp://ftp.openpkg.org/release/1.0/SRC/bash-2.05a-1.0.0.src.rpm + $ /usr/opkg/bin/rpm -Uvh \ + /usr/opkg/RPM/PKG/bash-2.05a-1.0.0.*.rpm + + # build and install proxy RPM for /e/foo/sw instance + $ mkproxyrpm --rpm=/e/foo/sw/bin/rpm --output=/e/foo/RPM/PKG/ \ + /usr/opkg/RPM/PKG/bash-2.05a-1.0.0.*.rpm + $ /e/foo/sw/bin/rpm -Uvh \ + /e/foo/RPM/PKG/bash-2.05a-1.0.0+PROXY.*.rpm + + # build and install proxy RPM for /e/bar/sw instance + $ mkproxyrpm --rpm=/e/bar/sw/bin/rpm --output=/e/bar/RPM/PKG/ \ + /usr/opkg/RPM/PKG/bash-2.05a-1.0.0.*.rpm + $ /e/bar/sw/bin/rpm -Uvh \ + /e/bar/RPM/PKG/bash-2.05a-1.0.0+PROXY.*.rpm + +=head1 SEE ALSO + +B<OpenPKG> http://www.openpkg.org/, +rpm(3), ln(1). + +=head1 HISTORY + +B<mkproxyrpm> was developed in February 2002 by Ralf S. +Engelschall E<lt>[EMAIL PROTECTED]<gt> for the B<OpenPKG> +project after an idea for virtual packages by Thomas Lotterer +E<lt>[EMAIL PROTECTED]<gt>. + +=head1 AUTHOR + + Ralf S. Engelschall + [EMAIL PROTECTED] + www.engelschall.com + +=cut + @@ . ______________________________________________________________________ The OpenPKG Project www.openpkg.org CVS Repository Commit List [EMAIL PROTECTED]