add support for using the system's zypp repos
authorLudwig Nussel <ludwig.nussel@suse.de>
Fri, 22 Jan 2010 12:24:56 +0000 (13:24 +0100)
committerLudwig Nussel <ludwig.nussel@suse.de>
Fri, 22 Jan 2010 13:14:59 +0000 (14:14 +0100)
Build/Zypp.pm [new file with mode: 0644]
Makefile
build
createrepomddeps
createyastdeps
download [new file with mode: 0755]
expanddeps
init_buildsystem

diff --git a/Build/Zypp.pm b/Build/Zypp.pm
new file mode 100644 (file)
index 0000000..bc0340f
--- /dev/null
@@ -0,0 +1,32 @@
+package Build::Zypp;
+
+use strict;
+
+our $root = '';
+
+sub parsecfg($)
+{
+  my $file = shift;
+  my $repocfg = "$root/etc/zypp/repos.d/$file.repo";
+  open(REPO, '<', $repocfg) or return undef;
+  my $name;
+  my $repo = {};
+  while(<REPO>) {
+    chomp;
+    if(/^\[(.+)\]/) {
+      $name = $1;
+    } else {
+      my ($key, $value) = split(/=/,$_,2);
+      $repo->{$key} = $value;
+    }
+  }
+  return undef unless $name;
+  $repo->{'description'} = $repo->{'name'} if exists $repo->{'name'};
+  $repo->{'name'} = $name;
+  close(REPO);
+  return $repo;
+}
+
+1;
+
+# vim: sw=2
index b3b2286..b087bef 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -49,6 +49,7 @@ install:
            createrepomddeps \
            createyastdeps \
            changelog2spec \
+           download \
            spectool \
            unrpm \
            $(DESTDIR)$(pkglibdir)
diff --git a/build b/build
index f949cab..6142516 100755 (executable)
--- a/build
+++ b/build
@@ -1239,8 +1239,7 @@ for SPECFILE in "${SPECFILES[@]}" ; do
     fi
 
     if test -z "$BUILD_DIST" -a -e "$BUILD_ROOT/.guessed_dist" ; then
-       BUILD_DIST=`cat $BUILD_ROOT/.guessed_dist`
-       echo "assuming dist $BUILD_DIST"
+       read BUILD_DIST < $BUILD_ROOT/.guessed_dist
     fi
 
     #
index 9258262..61c604a 100755 (executable)
@@ -360,21 +360,41 @@ my $p = new XML::Parser(
   });
 
 #my $url = '/mounts/mirror/SuSE/ftp.suse.com/pub/suse/update/10.1/';
-foreach my $url (@ARGV) {
-  $url .= '/' unless $url =~ /\/$/;
+for my $url (@ARGV) {
+  my $dir;
+  if ($url =~ /^zypp:\/\/([^\/]*)\/?/) {
+    use Build::Zypp;
+    my $repo = Build::Zypp::parsecfg($1);
+    die "can't parse $1\n" unless $repo;
+    my $type = $repo->{'type'};
+    if($type eq 'rpm-md') {
+      my $name = $repo->{'name'};
+      $dir = "/var/cache/zypp/raw/$name/";
+      $baseurl = $url;
+      $baseurl .= '/' unless $baseurl =~ /\/$/;
+    } elsif ($type eq 'yast2') {
+      # XXX
+      exec ($INC[0].'/createyastdeps', $url);
+    } else {
+      die "unsupported repo type: $type\n";
+    }
+  } else {
+    $dir = $url;
+    $dir .= '/' unless $dir =~ /\/$/;
+    $baseurl = $dir;
+  }
 
-  $baseurl = $url;
   @primaryfiles = ();
   @cursor = ([undef, $repomdparser]);
 
-  $p->parsefile($url . 'repodata/repomd.xml');
+  $p->parsefile($dir . 'repodata/repomd.xml');
 
 #  print Dumper(\@primaryfiles);
 
   foreach my $f (@primaryfiles) {
     @cursor = ([undef, $primaryparser]);
 
-    my $u = $url . $f->{'location'};
+    my $u = $dir . $f->{'location'};
     $u = 'gzip -cd ' . $u . '|' if ($u =~ /\.gz$/); # XXX
 
     my $fh;
index 9208024..a17bd74 100755 (executable)
@@ -60,10 +60,18 @@ sub callback
   return 0;
 }
 
-while (@ARGV)
-{
-  my $url = shift;
-  $url .= '/' unless $url =~ /\/$/;
+for my $url (@ARGV) {
+  my $dir;
+  if ($url =~ /^zypp:\/\/([^\/]*)\/?/) {
+    use Build::Zypp;
+    my $repo = Build::Zypp::parsecfg($1);
+    die "can't parse $1\n" unless $repo;
+    die "only yast2 repos supported\n" unless $repo->{'type'} eq 'yast2';
+    my $name = $repo->{'name'};
+    $dir = "/var/cache/zypp/raw/$name/";
+  } else {
+    $dir = $url;
+  }
 
 # a really fucked up system
 #  if (-e $url."/yast/order") {
@@ -85,7 +93,9 @@ while (@ARGV)
 #    }
 #  }
   # XXX: location is actually defined in content file
-  my $packages = $url.'suse/setup/descr/packages';
+  my $packages = $dir.'/suse/setup/descr/packages';
+  
+  $url .= '/' unless $url =~ /\/$/;
 
   my @order = ();
   my $pkgs = Build::Susetags::parse($packages,
diff --git a/download b/download
new file mode 100755 (executable)
index 0000000..223022d
--- /dev/null
+++ b/download
@@ -0,0 +1,41 @@
+#!/usr/bin/perl -w
+
+BEGIN {
+  unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
+}
+
+use LWP::UserAgent;
+use URI;
+use File::Path;
+use File::Basename;
+
+use strict;
+
+die "USAGE: $0 DIR URLS..." unless $#ARGV >= 1;
+
+my $dir = shift @ARGV;
+
+my $ua = LWP::UserAgent->new(
+  agent => "openSUSE build script",
+  env_proxy => 1,
+  timeout => 42);
+
+for my $url (@ARGV) {
+  my $dest = $dir;
+  if ($url =~ /^zypp:\/\/([^\/]*)\/?/) {
+    use Build::Zypp;
+    my $repo = Build::Zypp::parsecfg($1);
+    die "can't parse $1\n" unless $repo;
+    die "missing url in repo ".$repo->{'name'}."\n" unless exists $repo->{'baseurl'};
+    my $u = $repo->{'baseurl'};
+    $u .= '/' unless substr($u, -1, 1) eq '/';
+    $url =~ s/^zypp:\/\/[^\/]*\/*//;
+    $url = URI->new($u.$url)
+  } else {
+    $url = URI->new($url);
+  }
+  my $res = $ua->mirror($url, $dest.'/'.basename($url->path));
+  die "reqesting $url failed: ".$res->status_line."\n" unless $res->is_success;
+}
+
+# vim:sw=2
index 73b977b..90ab6fe 100755 (executable)
@@ -137,8 +137,11 @@ if (!defined($dist) || $dist eq '') {
     $dist = 'default';
   } else {
     my $rpmfn = $fn{"rpm.$rpmarch"};
-    my %res = Build::Rpm::rpmq($rpmfn, 1010);
-    my $rpmdist = $res{1010}->[0] || '';
+    my $rpmdist = '';
+    if ($rpmfn =~ /^\// && -e $rpmfn) {
+      my %res = Build::Rpm::rpmq($rpmfn, 1010);
+      $rpmdist = $res{1010}->[0] || '';
+    }
     $rpmdist = lc($rpmdist);
     $rpmdist =~ s/-/_/g;
     $rpmdist =~ s/opensuse/suse linux/;
@@ -162,6 +165,7 @@ if (!defined($dist) || $dist eq '') {
       $dist = 'default';
     }
   }
+  print STDERR "Warning: distribution not specified, assuming '$dist' (see $configdir).\n";
 }
 
 my $cf = Build::read_config_dist($dist, $archs[0], $configdir);
index 84eadcc..de52995 100755 (executable)
@@ -262,7 +262,9 @@ function validate_cache_file {
                continue
            fi
            test -z "$SRC" && SRC=`pwd`
-           if [ ! -e "$SRC" ]; then
+           if [ "${SRC#zypp://}" != "$SRC" ]; then
+               set -- $BUILD_DIR/createrepomddeps "$SRC"
+           elif [ ! -e "$SRC" ]; then
                echo "*** $SRC does not exist" >&2
                cleanup_and_exit 1
            elif [ -z "$findonly" -a -e "$SRC"/suse/setup/descr/packages -o -e "$SRC"/suse/setup/descr/packages.gz ]; then
@@ -312,6 +314,32 @@ fail_exit()
   cleanup_and_exit 1
 }
 
+# modify $SRC
+download_zypp()
+{
+    local url="$1"
+    local zd="/var/cache/zypp/packages/"
+    SRC=$zd${url#zypp://}
+    if [ ! -e "$SRC" ]; then
+       local destdir="$zd/tmp"
+       mkdir -p "$destdir"
+       echo "downloading $url ... ";
+       $BUILD_DIR/download "$destdir" "$url" || cleanup_and_exit 1
+       local destfile="$destdir/${url##*/}"
+       if [ ! -e "$destfile" ]; then
+           echo "expected $destfile after download but it's missing" >&2
+           cleanup_and_exit 1
+       fi
+       rpm -K "$destfile" > $destfile.v || { echo "rpm verify failed" >&2; rm -rf "$destdir"; cleanup_and_exit 1; }
+       if grep "NOT OK" $destfile.v; then
+           rm -rf "$destdir"
+           cleanup_and_exit 1
+       fi
+       rm -f "$destfile.v"
+       mv "$destfile" "$SRC" || cleanup_and_exit 1
+    fi
+}
+
 set_build_arch
 
 trap fail_exit EXIT
@@ -442,6 +470,18 @@ else
            echo "${SRC#*:}" > $BUILD_ROOT/.init_b_cache/rpms/${SRC%%:*}.id
            continue
        fi
+       if [ "${SRC#/}" = "$SRC" ]; then
+           url="$SRC"
+           case "$url" in
+               zypp://*)
+                   download_zypp "$url"
+                   ;;
+               *)
+                   echo "unsupported url: $url" >&2
+                   cleanup_and_exit 1
+                   ;;
+           esac
+       fi
        ln -s "$SRC" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.${SRC##*.}"
        PACKAGES_TO_INSTALL="$PACKAGES_TO_INSTALL $PKG"
     done < $RPMLIST