update to upstream 20150115
authorSoonKyu Park <sk7.park@samsung.com>
Wed, 15 Jun 2016 05:18:44 +0000 (14:18 +0900)
committerSoonKyu Park <sk7.park@samsung.com>
Wed, 15 Jun 2016 05:18:44 +0000 (14:18 +0900)
Change-Id: I8943d5a8c98049843e6753c38beac89927690d72

88 files changed:
Build.pm
Build/Arch.pm
Build/Archrepo.pm [new file with mode: 0644]
Build/Deb.pm
Build/Debrepo.pm [new file with mode: 0644]
Build/Kiwi.pm
Build/LiveBuild.pm [new file with mode: 0644]
Build/Repo.pm [new file with mode: 0644]
Build/Rpm.pm
Build/Rpmmd.pm [new file with mode: 0644]
Build/Susetags.pm
Build/Zypp.pm
COPYING [new file with mode: 0644]
Makefile
README
build
build-pkg [new file with mode: 0644]
build-pkg-arch [new file with mode: 0644]
build-pkg-deb [new file with mode: 0644]
build-pkg-rpm [new file with mode: 0644]
build-recipe [new file with mode: 0644]
build-recipe-arch [new file with mode: 0644]
build-recipe-debootstrap [new file with mode: 0644]
build-recipe-dsc [new file with mode: 0644]
build-recipe-kiwi [new file with mode: 0644]
build-recipe-livebuild [new file with mode: 0644]
build-recipe-mock [new file with mode: 0644]
build-recipe-preinstallimage [new file with mode: 0644]
build-recipe-spec [new file with mode: 0644]
build-vm [new file with mode: 0644]
build-vm-ec2 [new file with mode: 0644]
build-vm-emulator [new file with mode: 0644]
build-vm-kvm [new file with mode: 0644]
build-vm-lxc [new file with mode: 0644]
build-vm-openstack [new file with mode: 0644]
build-vm-qemu [new file with mode: 0644]
build-vm-uml [new file with mode: 0644]
build-vm-xen [new file with mode: 0644]
build-vm-zvm [new file with mode: 0644]
build.1
changelog2spec
common_functions
computeblocklists
configs/arch.conf
configs/sl13.2.conf
configs/sles12.conf [new file with mode: 0644]
createarchdeps
createdebdeps [new file with mode: 0755]
createdirdeps [new file with mode: 0755]
createrepomddeps
createyastdeps
createzyppdeps [new file with mode: 0755]
debian/changelog
debtransform
debtransformbz2
debtransformzip
download
emulator/emulator.sh
expanddeps
extractbuild
getbinaryid
init_buildsystem
initvm.c
killchroot
listinstalled [new file with mode: 0755]
livebuild_pre_run.template [new file with mode: 0755]
mkbaselibs
mkdrpms
order
packaging/build.spec
qemu-reg
queryconfig [new file with mode: 0755]
signdummy
spec2changelog
spec_add_patch
spectool
substitutedeps
t/bad.livebuild [new file with mode: 0644]
t/directory.livebuild [new file with mode: 0644]
t/dist
t/live-build [new file with mode: 0755]
t/standard.livebuild [new file with mode: 0644]
test/common
test/testbuild.sh [new file with mode: 0755]
unrpm
unrpm.1 [new file with mode: 0644]
vc
vc.1 [new file with mode: 0644]

index 565e54e02b01efac968a7e30116208193d418364..f058ede17faa90b838827f77f0bd857010378c85 100644 (file)
--- a/Build.pm
+++ b/Build.pm
@@ -1,3 +1,23 @@
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 package Build;
 
 use strict;
@@ -11,6 +31,7 @@ our $do_rpm;
 our $do_deb;
 our $do_kiwi;
 our $do_arch;
+our $do_livebuild;
 
 sub import {
   for (@_) {
@@ -18,8 +39,9 @@ sub import {
     $do_deb = 1 if $_ eq ':deb';
     $do_kiwi = 1 if $_ eq ':kiwi';
     $do_arch = 1 if $_ eq ':arch';
+    $do_livebuild = 1 if $_ eq ':livebuild';
   }
-  $do_rpm = $do_deb = $do_kiwi = $do_arch = 1 if !$do_rpm && !$do_deb && !$do_kiwi && !$do_arch;
+  $do_rpm = $do_deb = $do_kiwi = $do_arch = $do_livebuild = 1 if !$do_rpm && !$do_deb && !$do_kiwi && !$do_arch && !$do_livebuild;
   if ($do_deb) {
     require Build::Deb;
   }
@@ -29,6 +51,9 @@ sub import {
   if ($do_arch) {
     require Build::Arch;
   }
+  if ($do_livebuild) {
+    require Build::LiveBuild;
+  }
 }
 
 package Build::Features;
@@ -204,6 +229,7 @@ sub read_config {
   $config->{'fileprovides'} = {};
   $config->{'constraint'} = [];
   $config->{'expandflags'} = [];
+  $config->{'buildflags'} = [];
   for my $l (@spec) {
     $l = $l->[1] if ref $l;
     next unless defined $l;
@@ -220,7 +246,7 @@ sub read_config {
       }
       next;
     }
-    if ($l0 eq 'preinstall:' || $l0 eq 'vminstall:' || $l0 eq 'required:' || $l0 eq 'support:' || $l0 eq 'keep:' || $l0 eq 'prefer:' || $l0 eq 'ignore:' || $l0 eq 'conflict:' || $l0 eq 'runscripts:' || $l0 eq 'expandflags:') {
+    if ($l0 eq 'preinstall:' || $l0 eq 'vminstall:' || $l0 eq 'required:' || $l0 eq 'support:' || $l0 eq 'keep:' || $l0 eq 'prefer:' || $l0 eq 'ignore:' || $l0 eq 'conflict:' || $l0 eq 'runscripts:' || $l0 eq 'expandflags:' || $l0 eq 'buildflags:') {
       my $t = substr($l0, 0, -1);
       for my $l (@l) {
        if ($l eq '!*') {
@@ -271,13 +297,15 @@ sub read_config {
          $config->{'order'}->{$l} = 1;
        }
       }
-    } elsif ($l0 eq 'repotype:') { #type of generated repository data
+    } elsif ($l0 eq 'repotype:') { # type of generated repository data
       $config->{'repotype'} = [ @l ];
-    } elsif ($l0 eq 'type:') { #kind of packaging system (spec,dsc,arch,kiwi,...)
+    } elsif ($l0 eq 'type:') { # kind of recipe system (spec,dsc,arch,kiwi,...)
       $config->{'type'} = $l[0];
-    } elsif ($l0 eq 'binarytype:') { #rpm,deb,arch,...
+    } elsif ($l0 eq 'buildengine:') { # build engine (build,mock)
+      $config->{'buildengine'} = $l[0];
+    } elsif ($l0 eq 'binarytype:') { # kind of binary packages (rpm,deb,arch,...)
       $config->{'binarytype'} = $l[0];
-    } elsif ($l0 eq 'patterntype:') { #kind of generated patterns in repository
+    } elsif ($l0 eq 'patterntype:') { # kind of generated patterns in repository
       $config->{'patterntype'} = [ @l ];
     } elsif ($l0 eq 'release:') {
       $config->{'release'} = $l[0];
@@ -285,6 +313,8 @@ sub read_config {
       $config->{'cicntstart'} = $l[0];
     } elsif ($l0 eq 'releaseprg:') {
       $config->{'releaseprg'} = $l[0];
+    } elsif ($l0 eq 'releasesuffix:') {
+      $config->{'releasesuffix'} = join(' ', @l);
     } elsif ($l0 eq 'changetarget:' || $l0 eq 'target:') {
       $config->{'target'} = join(' ', @l);
       push @macros, "%define _target_cpu ".(split('-', $config->{'target'}))[0] if $config->{'target'};
@@ -297,8 +327,6 @@ sub read_config {
       } else {
        push @{$config->{'constraint'}}, $l;
       }
-    } elsif ($l0 eq 'rpmbuildstage:') { # use the rpmbuild --stage option
-      $config->{'rpmbuildstage'} = $l[0];
     } elsif ($l0 !~ /^[#%]/) {
       warn("unknown keyword in config: $l0\n");
     }
@@ -326,7 +354,7 @@ sub read_config {
   }
   if (!$config->{'binarytype'}) {
     $config->{'binarytype'} = 'rpm' if $config->{'type'} eq 'spec' || $config->{'type'} eq 'kiwi';
-    $config->{'binarytype'} = 'deb' if $config->{'type'} eq 'dsc';
+    $config->{'binarytype'} = 'deb' if $config->{'type'} eq 'dsc' || $config->{'type'} eq 'livebuild';
     $config->{'binarytype'} = 'arch' if $config->{'type'} eq 'arch';
     $config->{'binarytype'} ||= 'UNDEFINED';
   }
@@ -353,6 +381,13 @@ sub read_config {
       $config->{"expandflags:$_"} = 1;
     }
   }
+  for (@{$config->{'buildflags'} || []}) {
+    if (/^([^:]+):(.*)$/s) {
+      $config->{"buildflags:$1"} = $2;
+    } else {
+      $config->{"buildflags:$_"} = 1;
+    }
+  }
   return $config;
 }
 
@@ -396,32 +431,94 @@ sub do_subst_vers {
   return @res;
 }
 
+sub add_livebuild_packages {
+  my ($config, @deps) = @_;
+
+  if ($config->{'substitute'}->{'build-packages:livebuild'}) {
+    push @deps, @{$config->{'substitute'}->{'build-packages:livebuild'}};
+  } else {
+    # defaults live-build package dependencies base on 4.0~a26 gathered with:
+    # grep Check_package -r /usr/lib/live/build
+    push @deps, (
+      'apt-utils', 'dctrl-tools', 'debconf', 'dosfstools', 'e2fsprogs', 'grub',
+      'librsvg2-bin', 'live-boot', 'live-config', 'mtd-tools', 'parted',
+      'squashfs-tools', 'syslinux', 'syslinux-common', 'wget', 'xorriso',
+      'zsync' );
+  }
+  return @deps;
+}
+
 # Delivers all packages which get used for building
 sub get_build {
   my ($config, $subpacks, @deps) = @_;
+
+  @deps = add_livebuild_packages($config, @deps) if $config->{'type'} eq 'livebuild';
   my @ndeps = grep {/^-/} @deps;
+  my %ndeps = map {$_ => 1} @ndeps;
+  my @directdepsend;
+  if ($ndeps{'--directdepsend--'}) {
+    @directdepsend = @deps;
+    for (splice @deps) {
+      last if $_ eq '--directdepsend--';
+      push @deps, $_;
+    }
+    @directdepsend = grep {!/^-/} splice(@directdepsend, @deps + 1);
+  }
   my @extra = (@{$config->{'required'}}, @{$config->{'support'}});
   if (@{$config->{'keep'} || []}) {
     my %keep = map {$_ => 1} (@deps, @{$config->{'keep'} || []}, @{$config->{'preinstall'}});
     for (@{$subpacks || []}) {
-      push @ndeps, "-$_" unless $keep{$_};
+      next if $keep{$_};
+      push @ndeps, "-$_";
+      $ndeps{"-$_"} = 1;
     }
   } else {
     # new "empty keep" mode, filter subpacks from required/support
     my %subpacks = map {$_ => 1} @{$subpacks || []};
     @extra = grep {!$subpacks{$_}} @extra;
   }
-  my %ndeps = map {$_ => 1} @ndeps;
   @deps = grep {!$ndeps{$_}} @deps;
   push @deps, @{$config->{'preinstall'}};
   push @deps, @extra;
   @deps = grep {!$ndeps{"-$_"}} @deps;
   @deps = do_subst($config, @deps);
   @deps = grep {!$ndeps{"-$_"}} @deps;
-  @deps = expand($config, @deps, @ndeps);
+  if (@directdepsend) {
+    @directdepsend = do_subst($config, @directdepsend);
+    @directdepsend = grep {!$ndeps{"-$_"}} @directdepsend;
+    unshift @directdepsend, '--directdepsend--' if @directdepsend;
+  }
+  @deps = expand($config, @deps, @ndeps, @directdepsend);
   return @deps;
 }
 
+# return the package needed for setting up the build environment.
+# an empty result means that the packages from get_build should
+# be used instead.
+sub get_sysbuild {
+  my ($config, $buildtype) = @_;
+  my $engine = $config->{'buildengine'} || '';
+  $buildtype ||= $config->{'type'} || '';
+  my @sysdeps;
+  if ($engine eq 'mock' && $buildtype ne 'kiwi') {
+    @sysdeps = @{$config->{'substitute'}->{'system-packages:mock'} || []};
+    @sysdeps = ('mock', 'createrepo') unless @sysdeps;
+  } elsif ($engine eq 'debootstrap' && $buildtype ne 'kiwi') {
+    @sysdeps = @{$config->{'substitute'}->{'system-packages:debootstrap'} || []};
+    @sysdeps = ('debootstrap', 'lsb-release') unless @sysdeps;
+  } elsif ($buildtype eq 'livebuild') {
+    # packages used for build environment setup (build-recipe-livebuild deps)
+    @sysdeps = @{$config->{'substitute'}->{'system-packages:livebuild'} || []};
+    @sysdeps = ('apt-utils', 'cpio', 'dpkg-dev', 'live-build', 'lsb-release', 'tar') unless @sysdeps;
+  }
+  return () unless @sysdeps;
+  @sysdeps = Build::get_build($config, [], @sysdeps);
+  return @sysdeps unless $sysdeps[0];
+  shift @sysdeps;
+  @sysdeps = unify(@sysdeps, get_preinstalls($config));
+  return (1, @sysdeps);
+}
+
 # Delivers all packages which shall have an influence to other package builds (get_build reduced by support packages)
 sub get_deps {
   my ($config, $subpacks, @deps) = @_;
@@ -478,23 +575,40 @@ sub get_cbinstalls { return @{[]}; }
 sub readdeps {
   my ($config, $pkginfo, @depfiles) = @_;
 
-  my %requires = ();
+  my %requires;
   local *F;
   my %provides;
-  my $dofileprovides = %{$config->{'fileprovides'}};
+  my %pkgconflicts;
+  my %pkgobsoletes;
+  my $dofileprovides = %{$config->{'fileprovides'} || {}};
   for my $depfile (@depfiles) {
     if (ref($depfile) eq 'HASH') {
       for my $rr (keys %$depfile) {
        $provides{$rr} = $depfile->{$rr}->{'provides'};
        $requires{$rr} = $depfile->{$rr}->{'requires'};
+       $pkgconflicts{$rr} = $depfile->{$rr}->{'conflicts'};
+       $pkgobsoletes{$rr} = $depfile->{$rr}->{'obsoletes'};
       }
       next;
     }
     # XXX: we don't support different architectures per file
-    open(F, "<$depfile") || die("$depfile: $!\n");
+    open(F, '<', $depfile) || die("$depfile: $!\n");
     while(<F>) {
       my @s = split(' ', $_);
       my $s = shift @s;
+      if ($pkginfo && ($s =~ /^I:(.*)\.(.*)-\d+\/\d+\/\d+:$/)) {
+       my $pkgid = $1;
+       my $arch = $2; 
+       my $evr = $s[0];
+       $pkginfo->{$pkgid}->{'arch'} = $1 if $s[1] && $s[1] =~ s/-(.*)$//;
+       $pkginfo->{$pkgid}->{'buildtime'} = $s[1] if $s[1];
+       if ($evr =~ s/^\Q$pkgid-//) {
+         $pkginfo->{$pkgid}->{'epoch'} = $1 if $evr =~ s/^(\d+)://;
+         $pkginfo->{$pkgid}->{'release'} = $1 if $evr =~ s/-([^-]*)$//;
+         $pkginfo->{$pkgid}->{'version'} = $evr;
+       }
+       next;
+      }
       my @ss;
       while (@s) {
        if (!$dofileprovides && $s[0] =~ /^\//) {
@@ -506,48 +620,94 @@ sub readdeps {
            next;
        }
        push @ss, shift @s;
-       while (@s) {
-         if ($s[0] =~ /^[\(<=>|]/) {
-           $ss[-1] .= " $s[0] $s[1]";
-           $ss[-1] =~ s/ \((.*)\)/ $1/;
-           $ss[-1] =~ s/(<|>){2}/$1/;
-           splice(@s, 0, 2);
-         } else {
-           last;
-         }
+       while (@s && $s[0] =~ /^[\(<=>|]/) {
+         $ss[-1] .= " $s[0] $s[1]";
+         $ss[-1] =~ s/ \((.*)\)/ $1/;
+         $ss[-1] =~ s/(<|>){2}/$1/;
+         splice(@s, 0, 2);
        }
       }
       my %ss;
       @ss = grep {!$ss{$_}++} @ss;
-      if ($s =~ /^(P|R):(.*)\.(.*)-\d+\/\d+\/\d+:$/) {
+      if ($s =~ /^(P|R|C|O):(.*)\.(.*)-\d+\/\d+\/\d+:$/) {
        my $pkgid = $2;
        my $arch = $3;
+       if ($1 eq "P") {
+         $provides{$pkgid} = \@ss;
+         if ($pkginfo) {
+           $pkginfo->{$pkgid}->{'name'} = $pkgid;
+           $pkginfo->{$pkgid}->{'arch'} = $arch;
+           $pkginfo->{$pkgid}->{'provides'} = \@ss;
+         }
+       }
        if ($1 eq "R") {
          $requires{$pkgid} = \@ss;
          $pkginfo->{$pkgid}->{'requires'} = \@ss if $pkginfo;
          next;
        }
-       # handle provides
-       $provides{$pkgid} = \@ss;
-       if ($pkginfo) {
-         # extract ver and rel from self provides
-         my ($v, $r) = map { /\Q$pkgid\E = ([^-]+)(?:-(.+))?$/ } @ss;
-         die("$pkgid: no self provides\n") unless defined($v) && $v ne '';
-         $pkginfo->{$pkgid}->{'name'} = $pkgid;
-         $pkginfo->{$pkgid}->{'version'} = $v;
-         $pkginfo->{$pkgid}->{'release'} = $r if defined($r);
-         $pkginfo->{$pkgid}->{'arch'} = $arch;
-         $pkginfo->{$pkgid}->{'provides'} = \@ss;
+       if ($1 eq "C") {
+         $pkgconflicts{$pkgid} = \@ss;
+         $pkginfo->{$pkgid}->{'conflicts'} = \@ss if $pkginfo;
+         next;
+       }
+       if ($1 eq "O") {
+         $pkgobsoletes{$pkgid} = \@ss;
+         $pkginfo->{$pkgid}->{'obsoletes'} = \@ss if $pkginfo;
+         next;
        }
       }
     }
     close F;
   }
+  if ($pkginfo) {
+    # extract evr from self provides if there is no 'I' line
+    for my $pkg (values %$pkginfo) {
+      next if defined $pkg->{'version'};
+      my $n = $pkg->{'name'};
+      next unless defined $n;
+      my @sp = grep {/^\Q$n\E\s*=\s*/} @{$pkg->{'provides'} || []};
+      next unless @sp;
+      my $evr = $sp[-1];
+      $evr =~ s/^\Q$n\E\s*=\s*//;
+      $pkg->{'epoch'} = $1 if $evr =~ s/^(\d+)://;
+      $pkg->{'release'} = $1 if $evr =~ s/-([^-]*)$//;
+      $pkg->{'version'} = $evr;
+    }
+  }
   $config->{'providesh'} = \%provides;
   $config->{'requiresh'} = \%requires;
+  $config->{'pkgconflictsh'} = \%pkgconflicts;
+  $config->{'pkgobsoletesh'} = \%pkgobsoletes;
   makewhatprovidesh($config);
 }
 
+sub getbuildid {
+  my ($q) = @_;
+  my $evr = $q->{'version'};
+  $evr = "$q->{'epoch'}:$evr" if $q->{'epoch'};
+  $evr .= "-$q->{'release'}" if defined $q->{'release'};;
+  my $buildtime = $q->{'buildtime'} || 0;
+  $evr .= " $buildtime";
+  $evr .= "-$q->{'arch'}" if defined $q->{'arch'};
+  return "$q->{'name'}-$evr";
+}
+
+sub writedeps {
+  my ($fh, $pkg, $url) = @_;
+  $url = '' unless defined $url;
+  return unless defined($pkg->{'name'}) && defined($pkg->{'arch'});
+  return if $pkg->{'arch'} eq 'src' || $pkg->{'arch'} eq 'nosrc';
+  my $id = $pkg->{'id'};
+  $id = ($pkg->{'buildtime'} || 0)."/".($pkg->{'filetime'} || 0)."/0" unless $id;
+  $id = "$pkg->{'name'}.$pkg->{'arch'}-$id: ";
+  print $fh "F:$id$url$pkg->{'location'}\n";
+  print $fh "P:$id".join(' ', @{$pkg->{'provides'} || []})."\n";
+  print $fh "R:$id".join(' ', @{$pkg->{'requires'}})."\n" if $pkg->{'requires'};
+  print $fh "C:$id".join(' ', @{$pkg->{'conflicts'}})."\n" if $pkg->{'conflicts'};
+  print $fh "O:$id".join(' ', @{$pkg->{'obsoletes'}})."\n" if $pkg->{'obsoletes'};
+  print $fh "I:$id".getbuildid($pkg)."\n";
+}
+
 sub makewhatprovidesh {
   my ($config) = @_;
 
@@ -578,6 +738,8 @@ sub forgetdeps {
   delete $config->{'providesh'};
   delete $config->{'whatprovidesh'};
   delete $config->{'requiresh'};
+  delete $config->{'pkgconflictsh'};
+  delete $config->{'pkgobsoletesh'};
 }
 
 my %addproviders_fm = (
@@ -649,24 +811,69 @@ sub addproviders {
   return \@p;
 }
 
+# XXX: should also check the package EVR
+sub nevrmatch {
+  my ($config, $r, @p) = @_;
+  my $rn = $r;
+  $rn =~ s/\s*([<=>]{1,2}).*$//;
+  return grep {$_ eq $rn} @p;
+}
+
+sub checkconflicts {
+  my ($config, $ins, $q, $eq, @r) = @_;
+  my $whatprovides = $config->{'whatprovidesh'};
+  for my $r (@r) {
+    my @eq = grep {$ins->{$_}} @{$whatprovides->{$r} || addproviders($config, $r)};
+    next unless @eq;
+    push @$eq, map {"provider $q conflicts with installed $_"} @eq;
+    return 1;
+  }
+  return 0;
+}
+
+sub checkobsoletes {
+  my ($config, $ins, $q, $eq, @r) = @_;
+  my $whatprovides = $config->{'whatprovidesh'};
+  for my $r (@r) {
+    my @eq = grep {$ins->{$_}} nevrmatch($config, $r, @{$whatprovides->{$r} || addproviders($config, $r)});
+    next unless @eq;
+    push @$eq, map {"provider $q is obsoleted by installed $_"} @eq;
+    return 1;
+  }
+  return 0;
+}
+
 sub expand {
   my ($config, @p) = @_;
 
   my $conflicts = $config->{'conflicth'};
+  my $pkgconflicts = $config->{'pkgconflictsh'} || {};
+  my $pkgobsoletes = $config->{'pkgobsoletesh'} || {};
   my $prefer = $config->{'preferh'};
   my $ignore = $config->{'ignoreh'};
+  my $ignoreconflicts = $config->{'expandflags:ignoreconflicts'};
 
   my $whatprovides = $config->{'whatprovidesh'};
   my $requires = $config->{'requiresh'};
 
   my %xignore = map {substr($_, 1) => 1} grep {/^-/} @p;
+  my @directdepsend;
+  if ($xignore{'-directdepsend--'}) {
+    delete $xignore{'-directdepsend--'};
+    my @directdepsend = @p;
+    for my $p (splice @p) {
+      last if $p eq '--directdepsend--';
+      push @p, $p;
+    }
+    @directdepsend = grep {!/^-/} splice(@directdepsend, @p + 1);
+  }
   @p = grep {!/^-/} @p;
 
   my %p;               # expanded packages
   my %aconflicts;      # packages we are conflicting with
 
   # add direct dependency packages. this is different from below,
-  # because we add packages even if to dep is already provided and
+  # because we add packages even if the dep is already provided and
   # we break ambiguities if the name is an exact match.
   for my $p (splice @p) {
     my @q = @{$whatprovides->{$p} || addproviders($config, $p)};
@@ -679,11 +886,21 @@ sub expand {
       push @p, $p;
       next;
     }
+    return (undef, "$q[0] $aconflicts{$q[0]}") if $aconflicts{$q[0]};
     print "added $q[0] because of $p (direct dep)\n" if $expand_dbg;
     push @p, $q[0];
     $p{$q[0]} = 1;
-    $aconflicts{$_} = 1 for @{$conflicts->{$q[0]} || []};
+    $aconflicts{$_} = "conflict from project config with $q[0]" for @{$conflicts->{$q[0]} || []};
+    if (!$ignoreconflicts) {
+      for my $r (@{$pkgconflicts->{$q[0]}}) {
+       $aconflicts{$_} = "conflicts with installed $q[0]" for @{$whatprovides->{$r} || addproviders($config, $r)};
+      }
+      for my $r (@{$pkgobsoletes->{$q[0]}}) {
+       $aconflicts{$_} = "is obsoleted by installed $q[0]" for nevrmatch($config, $r, @{$whatprovides->{$r} || addproviders($config, $r)});
+      }
+    }
   }
+  push @p, @directdepsend;
 
   my @pamb = ();
   my $doamb = 0;
@@ -699,13 +916,24 @@ sub expand {
        next if grep {$p{$_}} @q;
        next if grep {$xignore{$_}} @q;
        next if grep {$ignore->{"$p:$_"} || $xignore{"$p:$_"}} @q;
+       my @eq = map {"provider $_ $aconflicts{$_}"} grep {$aconflicts{$_}} @q;
        @q = grep {!$aconflicts{$_}} @q;
+       if (!$ignoreconflicts) {
+         for my $q (splice @q) {
+           push @q, $q unless @{$pkgconflicts->{$q} || []} && checkconflicts($config, \%p, $q, \@eq, @{$pkgconflicts->{$q}});
+         }
+         for my $q (splice @q) {
+           push @q, $q unless @{$pkgobsoletes->{$q} || []} && checkobsoletes($config, \%p, $q, \@eq, @{$pkgobsoletes->{$q}});
+         }
+       }
        if (!@q) {
+         my $eq = @eq ? " (".join(', ', @eq).")" : '';
+         my $msg = @eq ? 'conflict for providers of' : 'nothing provides';
          if ($r eq $p) {
-           push @rerror, "nothing provides $r";
+           push @rerror, "$msg $r$eq";
          } else {
-           next if $r =~ /^\//;
-           push @rerror, "nothing provides $r needed by $p";
+           next if $r =~ /^\// && !@eq;
+           push @rerror, "$msg $r needed by $p$eq";
          }
          next;
        }
@@ -748,7 +976,15 @@ sub expand {
        push @p, $q[0];
        print "added $q[0] because of $p:$r\n" if $expand_dbg;
        $p{$q[0]} = 1;
-       $aconflicts{$_} = 1 for @{$conflicts->{$q[0]} || []};
+       $aconflicts{$_} = "conflict from project config with $q[0]" for @{$conflicts->{$q[0]} || []};
+       if (!$ignoreconflicts) {
+         for my $r (@{$pkgconflicts->{$q[0]}}) {
+           $aconflicts{$_} = "conflicts with installed $q[0]" for @{$whatprovides->{$r} || addproviders($config, $r)};
+         }
+         for my $r (@{$pkgobsoletes->{$q[0]}}) {
+           $aconflicts{$_} = "is obsoleted by installed $q[0]" for nevrmatch($config, $r, @{$whatprovides->{$r} || addproviders($config, $r)});
+         }
+        }
        @error = ();
        $doamb = 0;
       }
@@ -883,6 +1119,16 @@ sub add_all_providers {
 
 ###########################################################################
 
+sub recipe2buildtype {
+  my ($recipe) = @_;
+  return $1 if $recipe =~ /\.(spec|dsc|kiwi|livebuild)$/;
+  $recipe =~ s/.*\///;
+  $recipe =~ s/^_service:.*://;
+  return 'arch' if $recipe eq 'PKGBUILD';
+  return 'preinstallimage' if $recipe eq '_preinstallimage';
+  return undef;
+}
+
 sub show {
   my ($conffile, $fn, $field, $arch) = @ARGV;
   my $cf = read_config($arch, $conffile);
@@ -908,8 +1154,25 @@ sub parse {
   return Build::Deb::parse($cf, $fn, @args) if $do_deb && $fn =~ /\.dsc$/;
   return Build::Kiwi::parse($cf, $fn, @args) if $do_kiwi && $fn =~ /config\.xml$/;
   return Build::Kiwi::parse($cf, $fn, @args) if $do_kiwi && $fn =~ /\.kiwi$/;
-  return Build::Arch::parse($cf, $fn, @args) if $do_arch && $fn =~ /(^|\/|-)PKGBUILD$/;
-  return parse_preinstallimage($cf, $fn, @args) if $fn =~ /(^|\/|-)_preinstallimage$/;
+  return Build::LiveBuild::parse($cf, $fn, @args) if $do_livebuild && $fn =~ /\.livebuild$/;
+  my $fnx = $fn;
+  $fnx =~ s/.*\///;
+  $fnx =~ s/^[0-9a-f]{32,}-//; # hack for OBS srcrep implementation
+  $fnx =~ s/^_service:.*://;
+  return Build::Arch::parse($cf, $fn, @args) if $do_arch && $fnx eq 'PKGBUILD';
+  return parse_preinstallimage($cf, $fn, @args) if $fnx eq '_preinstallimage';
+  return undef;
+}
+
+sub parse_typed {
+  my ($cf, $fn, $buildtype, @args) = @_;
+  $buildtype ||= '';
+  return Build::Rpm::parse($cf, $fn, @args) if $do_rpm && $buildtype eq 'spec';
+  return Build::Deb::parse($cf, $fn, @args) if $do_deb && $buildtype eq 'dsc';
+  return Build::Kiwi::parse($cf, $fn, @args) if $do_kiwi && $buildtype eq 'kiwi';
+  return Build::LiveBuild::parse($cf, $fn, @args) if $do_livebuild && $buildtype eq 'livebuild';
+  return Build::Arch::parse($cf, $fn, @args) if $do_arch && $buildtype eq 'arch';
+  return parse_preinstallimage($cf, $fn, @args) if $buildtype eq 'preinstallimage';
   return undef;
 }
 
@@ -928,6 +1191,24 @@ sub query {
   return undef;
 }
 
+sub showquery {
+  my ($fn, $field) = @ARGV;
+  my %opts;
+  $opts{'evra'} = 1 if grep {$_ eq $field} qw{epoch version release arch buildid};
+  $opts{'weakdeps'} = 1 if grep {$_ eq $field} qw{suggests enhances recommends supplements};
+  $opts{'conflicts'} = 1 if grep {$_ eq $field} qw{conflicts obsoletes};
+  $opts{'description'} = 1 if grep {$_ eq $field} qw{summary description};
+  $opts{'filelist'} = 1 if $field eq 'filelist';
+  $opts{'buildtime'} = 1 if grep {$_ eq $field} qw{buildtime buildid};
+  my $d = Build::query($fn, %opts);
+  die("cannot query $fn\n") unless $d;
+  $d->{'buildid'} = getbuildid($d);
+  my $x = $d->{$field};
+  $x = [] unless defined $x;
+  $x = [ $x ] unless ref $x;
+  print "$_\n" for @$x;
+}
+
 sub queryhdrmd5 {
   my ($binname) = @_;
   return Build::Rpm::queryhdrmd5(@_) if $do_rpm && $binname =~ /\.rpm$/;
@@ -940,4 +1221,12 @@ sub queryhdrmd5 {
   return undef;
 }
 
+sub queryinstalled {
+  my ($binarytype, @args) = @_;
+  return Build::Rpm::queryinstalled(@args) if $binarytype eq 'rpm';
+  return Build::Deb::queryinstalled(@args) if $binarytype eq 'deb';
+  return Build::Arch::queryinstalled(@args) if $binarytype eq 'arch';
+  return undef;
+}
+
 1;
index 8e561c3215772e91071161ec305f0064df925650..e685a24c294c12fee91639a4fec3b5d269e978d1 100644 (file)
@@ -1,3 +1,23 @@
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 package Build::Arch;
 
 use strict;
@@ -55,7 +75,7 @@ sub parse {
     my $var = $1;
     my $val = $3;
     if ($2) {
-      while ($val !~ s/\)\s*$//s) {
+      while ($val !~ s/\)\s*(?:#.*)?$//s) {
        my $nextline = <PKG>;
        last unless defined $nextline;
        chomp $nextline;
@@ -68,6 +88,7 @@ sub parse {
   $ret->{'name'} = $vars{'pkgname'}->[0] if $vars{'pkgname'};
   $ret->{'version'} = $vars{'pkgver'}->[0] if $vars{'pkgver'};
   $ret->{'deps'} = $vars{'makedepends'} || [];
+  push @{$ret->{'deps'}}, @{$vars{'checkdepends'} || []};
   push @{$ret->{'deps'}}, @{$vars{'depends'} || []};
   $ret->{'source'} = $vars{'source'} if $vars{'source'};
   return $ret;
@@ -147,7 +168,7 @@ sub query {
   $ret->{'hdrmd5'} = Digest::MD5::md5_hex($vars->{'_pkginfo'});
   $ret->{'provides'} = $vars->{'provides'} || [];
   $ret->{'requires'} = $vars->{'depend'} || [];
-  if ($vars->{'pkgname'}) {
+  if ($vars->{'pkgname'} && $opts{'addselfprovides'}) {
     my $selfprovides = $vars->{'pkgname'}->[0];
     $selfprovides .= "=$vars->{'pkgver'}->[0]" if $vars->{'pkgver'};
     push @{$ret->{'provides'}}, $selfprovides unless @{$ret->{'provides'} || []} && $ret->{'provides'}->[-1] eq $selfprovides;
@@ -170,9 +191,19 @@ sub query {
   if ($opts{'description'}) {
     $ret->{'description'} = $vars->{'pkgdesc'}->[0] if $vars->{'pkgdesc'};
   }
+  if ($opts{'conflicts'}) {
+    $ret->{'conflicts'} = $vars->{'conflict'} if $vars->{'conflict'};
+    $ret->{'obsoletes'} = $vars->{'replaces'} if $vars->{'replaces'};
+  }
+  if ($opts{'weakdeps'}) {
+    my @suggests = @{$vars->{'optdepend'} || []};
+    s/:.*// for @suggests;
+    $ret->{'suggests'} = \@suggests if @suggests;
+  }
   # arch packages don't seem to have a source :(
   # fake it so that the package isn't confused with a src package
   $ret->{'source'} = $ret->{'name'} if defined $ret->{'name'};
+  $ret->{'buildtime'} = $vars->{'builddate'}->[0] if $opts{'buildtime'} && $vars->{'builddate'};
   return $ret;
 }
 
@@ -214,9 +245,42 @@ sub parserepodata {
       push @{$d->{'provides'}}, @p;
     } elsif ($p eq '%DEPENDS%') {
       push @{$d->{'requires'}}, @p;
+    } elsif ($p eq '%CONFLICTS%') {
+      push @{$d->{'conflicts'}}, @p;
+    } elsif ($p eq '%REPLACES%') {
+      push @{$d->{'obsoletes'}}, @p;
     }
   }
   return $d;
 }
 
+sub queryinstalled {
+  my ($root, %opts) = @_; 
+
+  $root = '' if !defined($root) || $root eq '/';
+  local *D;
+  local *F;
+  opendir(D, "$root/var/lib/pacman/local") || return [];
+  my @pn = sort(grep {!/^\./} readdir(D));
+  closedir(D);
+  my @pkgs;
+  for my $pn (@pn) {
+    next unless open(F, '<', "$root/var/lib/pacman/local/$pn/desc");
+    my $data = '';
+    1 while sysread(F, $data, 8192, length($data));
+    close F;
+    my $d = parserepodata(undef, $data);
+    next unless defined $d->{'name'};
+    my $q = {};
+    for (qw{name arch buildtime version}) {
+      $q->{$_} = $d->{$_} if defined $d->{$_};
+    }
+    $q->{'epoch'} = $1 if $q->{'version'} =~ s/^(\d+)://s;
+    $q->{'release'} = $1 if $q->{'version'} =~ s/-([^-]*)$//s;
+    push @pkgs, $q;
+  }
+  return \@pkgs;
+}
+
+
 1;
diff --git a/Build/Archrepo.pm b/Build/Archrepo.pm
new file mode 100644 (file)
index 0000000..b2b0ee4
--- /dev/null
@@ -0,0 +1,75 @@
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+package Build::Archrepo;
+
+use strict;
+use Build::Arch;
+
+eval { require Archive::Tar; };
+*Archive::Tar::new = sub {die("Archive::Tar is not available\n")} unless defined &Archive::Tar::new;
+
+sub addpkg {
+  my ($res, $data, $options) = @_;
+  return unless defined $data->{'version'};
+  if ($options->{'addselfprovides'}) {
+    my $selfprovides = $data->{'name'};
+    $selfprovides .= "=$data->{'version'}" if defined $data->{'version'};
+    push @{$data->{'provides'}}, $selfprovides unless @{$data->{'provides'} || []} && $data->{'provides'}->[-1] eq $selfprovides;
+  }
+  if (defined($data->{'version'})) {
+    # split version into evr
+    $data->{'epoch'} = $1 if $data->{'version'} =~ s/^(\d+)://s;
+    $data->{'release'} = $1 if $data->{'version'} =~ s/-([^-]*)$//s;
+  }
+  $data->{'location'} = delete($data->{'filename'}) if exists $data->{'filename'};
+  if (ref($res) eq 'CODE') {
+    $res->($data);
+  } else {
+    push @$res, $data;
+  }
+}
+
+sub parse {
+  my ($in, $res, %options) = @_;
+  $res ||= [];
+  die("Build::Archrepo::parse needs a filename\n") if ref($in);
+  die("$in: $!\n") unless -e $in;
+  my $repodb = Archive::Tar->iter($in, 1);
+  die("$in is not a tar archive\n") unless $repodb;
+  my $e;
+  my $lastfn = '';
+  my $d;
+  while ($e = $repodb->()) {
+    next unless $e->type() == Archive::Tar::Constant::FILE;
+    my $fn = $e->name();
+    next unless $fn =~ s/\/(?:depends|desc|files)$//s;
+    if ($lastfn ne $fn) {
+      addpkg($res, $d, \%options) if $d->{'name'};
+      $d = {};
+      $lastfn = $fn;
+    }
+    Build::Arch::parserepodata($d, $e->get_content());
+  }
+  addpkg($res, $d, \%options) if $d->{'name'};
+  return $res;
+}
+
+1;
index 3878fd46b660ffbf133b52dbbbea9e25da4841b9..f7c9958551228b6b515048ab39c6ee6b4bb1017e 100644 (file)
@@ -1,3 +1,23 @@
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 package Build::Deb;
 
 use strict;
@@ -9,6 +29,31 @@ eval {
   $have_zlib = 1;
 };
 
+my %obs2debian = (
+  "i486"    => "i386",
+  "i586"    => "i386",
+  "i686"    => "i386",
+  "ppc"     => "powerpc",
+  "ppc64le" => "ppc64el",
+  "x86_64"  => "amd64",
+  "armv4l"  => "armel",
+  "armv5l"  => "armel",
+  "armv6l"  => "armel",
+  "armv7l"  => "armel",
+  "armv7hl" => "armhf"
+);
+
+sub basearch {
+  my ($arch) = @_;
+  return 'all' if !defined($arch) || $arch eq 'noarch';
+  return $obs2debian{$arch} || $arch;
+}
+
+sub obsarch {
+  my ($arch) = @_;
+  return grep {$obs2debian{$_} eq $arch} sort keys %obs2debian;
+}
+
 sub parse {
   my ($bconf, $fn) = @_;
   my $ret;
@@ -22,12 +67,7 @@ sub parse {
   }
   # map to debian names
   $os = 'linux' if !defined($os);
-  $arch = 'all' if !defined($arch) || $arch eq 'noarch';
-  $arch = 'i386' if $arch =~ /^i[456]86$/;
-  $arch = 'powerpc' if $arch eq 'ppc';
-  $arch = 'amd64' if $arch eq 'x86_64';
-  $arch = 'armel' if $arch =~ /^armv[4567]l$/;
-  $arch = 'armhf' if $arch eq 'armv7hl';
+  $arch = basearch($arch);
 
   if (ref($fn) eq 'ARRAY') {
     @control = @$fn;
@@ -45,6 +85,7 @@ sub parse {
   my $name;
   my $version;
   my @deps;
+  my @exclarch;
   while (@control) {
     my $c = shift @control;
     last if $c eq '';   # new paragraph
@@ -59,10 +100,18 @@ sub parse {
     if ($tag eq 'VERSION') {
       $version = $data;
       $version =~ s/-[^-]+$//;
+    } elsif ($tag eq 'ARCHITECTURE') {
+      my @archs = split('\s+', $data);
+      map { s/$os-//; s/any-// } @archs;
+      next if grep { $_ eq "any" || $_ eq "all" } @archs;
+      @exclarch = map { obsarch($_) } @archs;
+      # unify
+      my %exclarch = map {$_ => 1} @exclarch;
+      @exclarch = sort keys %exclarch;
     } elsif ($tag eq 'SOURCE') {
       $name = $data;
     } elsif ($tag eq 'BUILD-DEPENDS' || $tag eq 'BUILD-CONFLICTS' || $tag eq 'BUILD-IGNORE' || $tag eq 'BUILD-DEPENDS-INDEP') {
-      my @d = split(/,\s*/, $data);
+      my @d = split(/\s*,\s*/, $data);
       for my $d (@d) {
         my @alts = split('\s*\|\s*', $d);
         my @needed;
@@ -75,11 +124,11 @@ sub parse {
               $isneg = 1 if $q =~ s/^\!//;
               $bad = 1 if !defined($bad) && !$isneg;
               if ($isneg) {
-                if ($q eq $arch || $q eq 'any' || $q eq "$os-$arch" || $q eq "$os-any") {
+                if ($q eq $arch || $q eq 'any' || $q eq "$os-$arch" || $q eq "$os-any" || $q eq "any-$arch") {
                   $bad = 1;
                   last;
                 }
-              } elsif ($q eq $arch || $q eq 'any' || $q eq "$os-$arch" || $q eq "$os-any") {
+              } elsif ($q eq $arch || $q eq 'any' || $q eq "$os-$arch" || $q eq "$os-any" || $q eq "any-$arch") {
                 $bad = 0;
               }
             }
@@ -104,6 +153,7 @@ sub parse {
   $ret->{'name'} = $name;
   $ret->{'version'} = $version;
   $ret->{'deps'} = \@deps;
+  $ret->{'exclarch'} = \@exclarch if @exclarch;
   return $ret;
 }
 
@@ -127,6 +177,26 @@ sub ungzip {
   return $data;
 }
 
+sub control2res {
+  my ($control) = @_;
+  my %res;
+  my @control = split("\n", $control);
+  while (@control) {
+    my $c = shift @control;
+    last if $c eq '';   # new paragraph
+    my ($tag, $data) = split(':', $c, 2);
+    next unless defined $data;
+    $tag = uc($tag);
+    while (@control && $control[0] =~ /^\s/) {
+      $data .= "\n".substr(shift @control, 1);
+    }
+    $data =~ s/^\s+//s;
+    $data =~ s/\s+$//s;
+    $res{$tag} = $data;
+  }
+  return %res;
+}
+
 sub debq {
   my ($fn) = @_;
 
@@ -202,21 +272,7 @@ sub debq {
     }
     $data = substr($data, $blen);
   }
-  my %res;
-  my @control = split("\n", $control);
-  while (@control) {
-    my $c = shift @control;
-    last if $c eq '';   # new paragraph
-    my ($tag, $data) = split(':', $c, 2);
-    next unless defined $data;
-    $tag = uc($tag);
-    while (@control && $control[0] =~ /^\s/) {
-      $data .= "\n".substr(shift @control, 1);
-    }
-    $data =~ s/^\s+//s;
-    $data =~ s/\s+$//s;
-    $res{$tag} = $data;
-  }
+  my %res = control2res($control);
   $res{'CONTROL_MD5'} = $controlmd5;
   return %res;
 }
@@ -233,22 +289,27 @@ sub query {
     $src =~ s/\s.*$//;
   }
   my @provides = split(',\s*', $res{'PROVIDES'} || '');
-  push @provides, "$name = $res{'VERSION'}";
+  if ($opts{'addselfprovides'}) {
+    push @provides, "$name (= $res{'VERSION'})";
+  }
   my @depends = split(',\s*', $res{'DEPENDS'} || '');
-  my @predepends = split(',\s*', $res{'PRE-DEPENDS'} || '');
-  push @depends, @predepends;
-  s/ \(([^\)]*)\)/ $1/g for @provides;
-  s/ \(([^\)]*)\)/ $1/g for @depends;
-  s/>>/>/g for @provides;
-  s/<</</g for @provides;
-  s/>>/>/g for @depends;
-  s/<</</g for @depends;
+  push @depends, split(',\s*', $res{'PRE-DEPENDS'} || '');
   my $data = {
     name => $name,
     hdrmd5 => $res{'CONTROL_MD5'},
     provides => \@provides,
     requires => \@depends,
   };
+  if ($opts{'conflicts'}) {
+    my @conflicts = split(',\s*', $res{'CONFLICTS'} || '');
+    push @conflicts, split(',\s*', $res{'BREAKS'} || '');
+    $data->{'conflicts'} = \@conflicts if @conflicts;
+  }
+  if ($opts{'weakdeps'}) {
+    for my $dep ('SUGGESTS', 'RECOMMENDS', 'ENHANCES') {
+      $data->{lc($dep)} = [ split(',\s*', $res{$dep} || '') ] if defined $res{$dep};
+    }
+  }
   $data->{'source'} = $src if $src ne '';
   if ($opts{'evra'}) {
     $res{'VERSION'} =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
@@ -260,6 +321,16 @@ sub query {
   if ($opts{'description'}) {
     $data->{'description'} = $res{'DESCRIPTION'};
   }
+  if ($opts{'normalizedeps'}) {
+    for my $dep (qw{provides requires conflicts suggests enhances recommends}) {
+      next unless $data->{$dep};
+      for (@{$data->{$dep}}) {
+        s/ \(([^\)]*)\)/ $1/g;
+        s/<</</g;
+        s/>>/>/g;
+      }
+    }
+  }
   return $data;
 }
 
@@ -340,4 +411,34 @@ sub verscmp {
   return verscmp_part($r1, $r2);
 }
 
+sub queryinstalled {
+  my ($root, %opts) = @_;
+
+  $root = '' if !defined($root) || $root eq '/';
+  my @pkgs;
+  local *F;
+  if (open(F, '<', "$root/var/lib/dpkg/status")) {
+    my $ctrl = '';
+    while(<F>) {
+      if ($_ eq "\n") {
+       my %res = control2res($ctrl);
+       if (defined($res{'PACKAGE'})) {
+         my $data = {'name' => $res{'PACKAGE'}};
+         $res{'VERSION'} =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
+         $data->{'epoch'} = $1 if defined $1;
+         $data->{'version'} = $2;
+         $data->{'release'} = $3 if defined $3;
+         $data->{'arch'} = $res{'ARCHITECTURE'};
+         push @pkgs, $data;
+       }
+        $ctrl = '';
+       next;
+      }
+      $ctrl .= $_;
+    }
+    close F;
+  }
+  return \@pkgs;
+}
+
 1;
diff --git a/Build/Debrepo.pm b/Build/Debrepo.pm
new file mode 100644 (file)
index 0000000..2f30dfd
--- /dev/null
@@ -0,0 +1,116 @@
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+package Build::Debrepo;
+
+use strict;
+
+sub addpkg {
+  my ($res, $data, $options) = @_;
+  return unless defined $data->{'version'};
+  my $selfprovides;
+  $selfprovides = "= $data->{'version'}" if $options->{'addselfprovides'};
+  # split version into evr
+  $data->{'epoch'} = $1 if $data->{'version'} =~ s/^(\d+)://s;
+  $data->{'release'} = $1 if $data->{'version'} =~ s/-([^-]*)$//s;
+  for my $d (qw{provides requires conflicts recommends suggests enhances breaks prerequires}) {
+    next unless $data->{$d};
+    if ($options->{'normalizedeps'}) {
+      $data->{$d} =~ s/\(([^\)]*)\)/$1/g;
+      $data->{$d} =~ s/<</</g;
+      $data->{$d} =~ s/>>/>/g;
+    }
+    $data->{$d} = [ split(/\s*,\s*/, $data->{$d}) ];
+  }
+  push @{$data->{'requires'}}, @{$data->{'prerequires'}} if $data->{'prerequires'};
+  delete $data->{'prerequires'};
+  push @{$data->{'conflicts'}}, @{$data->{'breaks'}} if $data->{'breaks'};
+  delete $data->{'breaks'};
+  if (defined($selfprovides)) {
+    $selfprovides = "($selfprovides)" unless $options->{'normalizedeps'};
+    $selfprovides = "$data->{'name'} $selfprovides";
+    push @{$data->{'provides'}}, $selfprovides  unless @{$data->{'provides'} || []} && $data->{'provides'}->[-1] eq $selfprovides;
+  }
+  if (ref($res) eq 'CODE') {
+    $res->($data);
+  } else {
+    push @$res, $data;
+  }
+}
+
+my %tmap = (
+  'package' => 'name',
+  'version' => 'version',
+  'architecture' => 'arch',
+  'provides' => 'provides',
+  'depends' => 'requires',
+  'pre-depends' => 'prerequires',
+  'conflicts' => 'conflicts',
+  'breaks' => 'breaks',
+  'recommends' => 'recommends',
+  'suggests' => 'suggests',
+  'enhances' => 'enhances',
+  'filename' => 'location',
+  'source' => 'source',
+);
+
+sub parse {
+  my ($in, $res, %options) = @_;
+  $res ||= [];
+  my $fd;
+  if (ref($in)) {
+    $fd = $in;
+  } else {
+    if ($in =~ /\.gz$/) {
+      open($fd, '-|', "gzip", "-dc", $in) || die("$in: $!\n");
+    } else {
+      open($fd, '<', $in) || die("$in: $!\n");
+    }
+  }
+  my $pkg = {};
+  my $tag;
+  while (<$fd>) {
+    chomp;
+    if ($_ eq '') {
+      addpkg($res, $pkg, \%options) if %$pkg;
+      $pkg = {};
+      next;
+    }
+    if (/^\s/) {
+      next unless $tag;
+      $pkg->{$tag} .= "\n".substr($_, 1);
+      next;
+    }
+    my $data;
+    ($tag, $data) = split(':', $_, 2);
+    next unless defined $data;
+    $tag = $tmap{lc($tag)};
+    next unless $tag;
+    $data =~ s/^\s*//;
+    $pkg->{$tag} = $data;
+  }
+  addpkg($res, $pkg, \%options) if %$pkg;
+  if (!ref($in)) {
+    close($fd) || die("close $in: $!\n");
+  }
+  return $res;
+}
+
+1;
index f9760298422b3edac3b97e8213e491e332ed7723..5d730d7f40d9cfd5f3bc3b368557799c36ea7377 100644 (file)
@@ -1,3 +1,23 @@
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 package Build::Kiwi;
 
 use strict;
@@ -188,6 +208,7 @@ sub kiwiparse {
     if ($instsource->{'productoptions'}) {
       my $productoptions = $instsource->{'productoptions'}->[0] || {};
       for my $po (@{$productoptions->{'productvar'} || []}) {
+       $ret->{'drop_repository'} = $po->{'_content'} if $po->{'name'} eq 'DROP_REPOSITORY';
        $ret->{'version'} = $po->{'_content'} if $po->{'name'} eq 'VERSION';
       }
       for my $po (@{$productoptions->{'productoption'} || []}) {
diff --git a/Build/LiveBuild.pm b/Build/LiveBuild.pm
new file mode 100644 (file)
index 0000000..fbc66d9
--- /dev/null
@@ -0,0 +1,102 @@
+################################################################
+#
+# Author: Jan Blunck <jblunck@infradead.org>
+#
+# This file is part of build.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+#################################################################
+
+package Build::LiveBuild;
+
+use strict;
+
+eval { require Archive::Tar; };
+*Archive::Tar::new = sub {die("Archive::Tar is not available\n")} unless defined &Archive::Tar::new;
+
+sub filter {
+  my ($content) = @_;
+
+  return '' unless defined $content;
+
+  $content =~ s/^#.*$//mg;
+  $content =~ s/^!.*$//mg;
+  $content =~ s/^\s*//mg;
+  return $content;
+}
+
+sub parse_package_list {
+  my ($content) = @_;
+  my @packages = split /\n/, filter($content);
+
+  return @packages;
+};
+
+sub parse_archive {
+  my ($content) = @_;
+  my @repos;
+
+  my @lines = split /\n/, filter($content);
+  for (@lines) {
+    next if /^deb-src /;
+
+    die("bad path using not obs:/ URL: $_\n") unless $_ =~ /^deb\s+obs:\/\/\/?([^\s\/]+)\/([^\s\/]+)\/?\s+.*$/;
+    push @repos, "$1/$2";
+  }
+
+  return @repos;
+}
+
+sub unify {
+  my %h = map {$_ => 1} @_;
+  return grep(delete($h{$_}), @_);
+}
+
+sub parse {
+  my ($config, $filename, @args) = @_;
+  my $ret = {};
+
+  # check that filename is a tar
+  my $tar = Archive::Tar->new;
+  unless($tar->read($filename)) {
+    warn("$filename: " . $tar->error . "\n");
+    $ret->{'error'} = "$filename: " . $tar->error;
+    return $ret;
+  }
+
+  # check that directory layout matches live-build directory structure
+  for my $file ($tar->list_files('')) {
+    next unless $file =~ /^(.*\/)?config\/archives\/.*\.list.*/;
+    warn("$filename: config/archives/*.list* files not allowed!\n");
+    $ret->{'error'} = "$filename: config/archives/*.list* files not allowed!";
+    return $ret;
+  }
+
+  # always require the list of packages required by live-boot for
+  # bootstrapping the target distribution image (e.g. with debootstrap)
+  my @packages = ( 'live-build-desc' );
+
+  for my $file ($tar->list_files('')) {
+    next unless $file =~ /^(.*\/)?config\/package-lists\/.*\.list.*/;
+    push @packages, parse_package_list($tar->get_content($file));
+  }
+
+  ($ret->{'name'} = $filename) =~ s/\.[^.]+$//;
+  $ret->{'deps'} = [ unify(@packages) ];
+  return $ret;
+}
+
+1;
diff --git a/Build/Repo.pm b/Build/Repo.pm
new file mode 100644 (file)
index 0000000..7cd495f
--- /dev/null
@@ -0,0 +1,61 @@
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+package Build::Repo;
+
+use strict;
+
+our $do_rpmmd;
+our $do_deb;
+our $do_arch;
+our $do_susetags;
+
+sub import {
+  for (@_) {
+    $do_rpmmd = 1 if $_ eq ':rpmmd';
+    $do_deb = 1 if $_ eq ':deb';
+    $do_arch = 1 if $_ eq ':arch';
+    $do_susetags = 1 if $_ eq ':susetags';
+  }
+  $do_rpmmd = $do_deb = $do_arch = $do_susetags = 1 unless $do_rpmmd || $do_deb || $do_arch || $do_susetags;
+  if ($do_rpmmd) {
+    require Build::Rpmmd;
+  }
+  if ($do_susetags) {
+    require Build::Susetags;
+  }
+  if ($do_deb) {
+    require Build::Debrepo;
+  }
+  if ($do_arch) {
+    require Build::Archrepo;
+  }
+}
+
+sub parse {
+  my ($type, @args) = @_;
+  return Build::Rpmmd::parse(@args) if $do_rpmmd && $type eq 'rpmmd';
+  return Build::Susetags::parse(@args) if $do_susetags && $type eq 'susetags';
+  return Build::Debrepo::parse(@args) if $do_deb && $type eq 'deb';
+  return Build::Archrepo::parse(@args) if $do_arch && $type eq 'arch';
+  die("parse repo: unknown type '$type'\n");
+}
+
+1;
index e6a18153383548b1427014d47bb1fbaa1856d646..d9c6028b59f3de29bca15b741488e8e0fa8c8a87 100644 (file)
@@ -1,3 +1,23 @@
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 package Build::Rpm;
 
 our $unfilteredprereqs = 0;
@@ -108,6 +128,9 @@ sub expr {
       ($v2, $expr) = expr(substr($expr, 1), 4);
       return undef unless defined $v2 && 0 + $v2;
       $v /= $v2;
+    } elsif ($expr =~ /^([=&|])/) {
+      warn("syntax error while parsing $1$1\n");
+      return ($v, $expr);
     } else {
       return ($v, $expr);
     }
@@ -130,7 +153,8 @@ sub grabargs {
   my %m;
   $m{'0'} = $macname;
   $m{'**'} = join(' ', @args);
-  my %go = (split(/(:?)/, $getopt, -1), undef);
+  my %go;
+  %go = ($getopt =~ /(.)(:*)/sg) if defined $getopt;
   while (@args && $args[0] =~ s/^-//) {
     my $o = shift @args;
     last if $o eq '-';
@@ -341,17 +365,27 @@ reexpand:
              $line = $2;
            }
            push @expandstack, ($expandedline, $line, $optmacros);
-           $optmacros = adaptmacros(\%macros, $optmacros, grabargs($macname, $macros_args{$macname}, split(/ /, $macdata)));
+           $optmacros = adaptmacros(\%macros, $optmacros, grabargs($macname, $macros_args{$macname}, split(' ', $macdata)));
            $line = $macros{$macname};
            $expandedline = '';
            next;
          }
          $macalt = $macros{$macname} unless defined $macalt;
          $macalt = '' if $mactest == -1;
-         $line = "$macalt$line";
+         if ($macalt =~ /%/) {
+           push @expandstack, ('', $line, 1) if $line ne '';
+           $line = $macalt;
+         } else {
+           $expandedline .= $macalt;
+         }
        } elsif ($mactest) {
          $macalt = '' if !defined($macalt) || $mactest == 1;
-         $line = "$macalt$line";
+         if ($macalt =~ /%/) {
+           push @expandstack, ('', $line, 1) if $line ne '';
+           $line = $macalt;
+         } else {
+           $expandedline .= $macalt;
+         }
        } else {
          $expandedline .= "%$macorig" unless $macname =~ /^-/;
        }
@@ -360,12 +394,15 @@ reexpand:
       if (@expandstack) {
        my $m = pop(@expandstack);
        if ($m) {
-         $optmacros = adaptmacros(\%macros, $optmacros, $m);
+         $optmacros = adaptmacros(\%macros, $optmacros, $m) if ref $m;
          $expandstack[-2] .= $line;
-         $line = '';
+         $line = pop(@expandstack);
+         $expandedline = pop(@expandstack);
+       } else {
+         my $todo = pop(@expandstack);
+         $expandedline = pop(@expandstack);
+         push @expandstack, ('', $todo, 1) if $todo ne '';
        }
-       $line = $line . pop(@expandstack);
-       $expandedline = pop(@expandstack);
        goto reexpand;
       }
     }
@@ -565,6 +602,7 @@ my %rpmstag = (
   "EPOCH"          => 1003,
   "SUMMARY"        => 1004,
   "DESCRIPTION"    => 1005,
+  "BUILDTIME"      => 1006,
   "ARCH"           => 1022,
   "OLDFILENAMES"   => 1027,
   "SOURCERPM"      => 1044,
@@ -580,6 +618,31 @@ my %rpmstag = (
   "DIRINDEXES"     => 1116,
   "BASENAMES"      => 1117,
   "DIRNAMES"       => 1118,
+  "DISTURL"        => 1123,
+  "CONFLICTFLAGS"  => 1053,
+  "CONFLICTNAME"   => 1054,
+  "CONFLICTVERSION" => 1055,
+  "OBSOLETENAME"   => 1090,
+  "OBSOLETEFLAGS"  => 1114,
+  "OBSOLETEVERSION" => 1115,
+  "OLDSUGGESTSNAME" => 1156,
+  "OLDSUGGESTSVERSION" => 1157,
+  "OLDSUGGESTSFLAGS" => 1158,
+  "OLDENHANCESNAME" => 1159,
+  "OLDENHANCESVERSION" => 1160,
+  "OLDENHANCESFLAGS" => 1161,
+  "RECOMMENDNAME" => 5046,
+  "RECOMMENDVERSION" => 5047,
+  "RECOMMENDFLAGS" => 5048,
+  "SUGGESTNAME"    => 5049,
+  "SUGGESTVERSION" => 5050,
+  "SUGGESTFLAGS"   => 5051,
+  "SUPPLEMENTNAME" => 5052,
+  "SUPPLEMENTVERSION" => 5053,
+  "SUPPLEMENTFLAGS" => 5054,
+  "ENHANCENAME"    => 5055,
+  "ENHANCEVERSION" => 5056,
+  "ENHANCEFLAGS"   => 5057,
 );
 
 sub rpmq {
@@ -744,12 +807,9 @@ sub rpmq {
 }
 
 sub add_flagsvers {
-  my $res = shift;
-  my $name = shift;
-  my $flags = shift;
-  my $vers = shift;
+  my ($res, $name, $flags, $vers) = @_;
 
-  return unless $res;
+  return unless $res && $res->{$name};
   my @flags = @{$res->{$flags} || []};
   my @vers = @{$res->{$vers} || []};
   for (@{$res->{$name}}) {
@@ -765,6 +825,25 @@ sub add_flagsvers {
   }
 }
 
+sub filteroldweak {
+  my ($res, $name, $flags, $data, $strong, $weak) = @_;
+
+  return unless $res && $res->{$name};
+  my @flags = @{$res->{$flags} || []};
+  my @strong;
+  my @weak;
+  for (@{$res->{$name}}) {
+    if (@flags && ($flags[0] & 0x8000000)) {
+      push @strong, $_;
+    } else {
+      push @weak, $_;
+    }
+    shift @flags;
+  }
+  $data->{$strong} = \@strong if @strong;
+  $data->{$weak} = \@weak if @weak;
+}
+
 sub verscmp_part {
   my ($s1, $s2) = @_;
   if (!defined($s1)) {
@@ -842,6 +921,11 @@ sub query {
   push @tags, qw{EPOCH VERSION RELEASE ARCH};
   push @tags, qw{FILENAMES} if $opts{'filelist'};
   push @tags, qw{SUMMARY DESCRIPTION} if $opts{'description'};
+  push @tags, qw{DISTURL} if $opts{'disturl'};
+  push @tags, qw{BUILDTIME} if $opts{'buildtime'};
+  push @tags, qw{CONFLICTNAME CONFLICTVERSION CONFLICTFLAGS OBSOLETENAME OBSOLETEVERSION OBSOLETEFLAGS} if $opts{'conflicts'};
+  push @tags, qw{RECOMMENDNAME RECOMMENDVERSION RECOMMENDFLAGS SUGGESTNAME SUGGESTVERSION SUGGESTFLAGS SUPPLEMENTNAME SUPPLEMENTVERSION SUPPLEMENTFLAGS ENHANCENAME ENHANCEVERSION ENHANCEFLAGS OLDSUGGESTSNAME OLDSUGGESTSVERSION OLDSUGGESTSFLAGS OLDENHANCESNAME OLDENHANCESVERSION OLDENHANCESFLAGS} if $opts{'weakdeps'};
+
   my %res = rpmq($handle, @tags);
   return undef unless %res;
   my $src = $res{'SOURCERPM'}->[0];
@@ -860,6 +944,27 @@ sub query {
     $data->{'provides'} = [ grep {!/^rpmlib\(/ && !/^\//} @{$res{'PROVIDENAME'} || []} ];
     $data->{'requires'} = [ grep {!/^rpmlib\(/ && !/^\//} @{$res{'REQUIRENAME'} || []} ];
   }
+  if ($opts{'conflicts'}) {
+    add_flagsvers(\%res, 'CONFLICTNAME', 'CONFLICTFLAGS', 'CONFLICTVERSION');
+    add_flagsvers(\%res, 'OBSOLETENAME', 'OBSOLETEFLAGS', 'OBSOLETEVERSION');
+    $data->{'conflicts'} = [ @{$res{'CONFLICTNAME'}} ] if $res{'CONFLICTNAME'};
+    $data->{'obsoletes'} = [ @{$res{'OBSOLETENAME'}} ] if $res{'OBSOLETENAME'};
+  }
+  if ($opts{'weakdeps'}) {
+    for (qw{RECOMMEND SUGGEST SUPPLEMENT ENHANCE}) {
+      next unless $res{"${_}NAME"};
+      add_flagsvers(\%res, "${_}NAME", "${_}FLAGS", "${_}VERSION");
+      $data->{lc($_)."s"} = [ @{$res{"${_}NAME"}} ];
+    }
+    if ($res{'OLDSUGGESTSNAME'}) {
+      add_flagsvers(\%res, 'OLDSUGGESTSNAME', 'OLDSUGGESTSFLAGS', 'OLDSUGGESTSVERSION');
+      filteroldweak(\%res, 'OLDSUGGESTSNAME', 'OLDSUGGESTSFLAGS', $data, 'recommends', 'suggests');
+    }
+    if ($res{'OLDENHANCESNAME'}) {
+      add_flagsvers(\%res, 'OLDENHANCESNAME', 'OLDENHANCESFLAGS', 'OLDENHANCESVERSION');
+      filteroldweak(\%res, 'OLDENHANCESNAME', 'OLDENHANCESFLAGS', $data, 'supplements', 'enhances');
+    }
+  }
 
   # rpm3 compatibility: retrofit missing self provides
   if ($src ne '') {
@@ -894,6 +999,8 @@ sub query {
     $data->{'summary'} = $res{'SUMMARY'}->[0];
     $data->{'description'} = $res{'DESCRIPTION'}->[0];
   }
+  $data->{'buildtime'} = $res{'BUILDTIME'}->[0] if $opts{'buildtime'};
+  $data->{'disturl'} = $res{'DISTURL'}->[0] if $opts{'disturl'} && $res{'DISTURL'};
   return $data;
 }
 
@@ -950,4 +1057,48 @@ sub queryhdrmd5 {
   return unpack("\@${md5off}H32", $buf);
 }
 
+sub queryinstalled {
+  my ($root, %opts) = @_;
+
+  $root = '' if !defined($root) || $root eq '/';
+  local *F;
+  my $dochroot = $root ne '' && !$opts{'nochroot'} && !$< ? 1 : 0;
+  my $pid = open(F, '-|');
+  die("fork: $!\n") unless defined $pid;
+  if (!$pid) {
+    if ($dochroot && chroot($root)) {
+      chdir('/') || die("chdir: $!\n");
+      $root = '';
+    }
+    my @args;
+    unshift @args, '--nodigest', '--nosignature' if -e "$root/usr/bin/rpmquery ";
+    unshift @args, '--dbpath', "$root/var/lib/rpm" if $root ne '';
+    push @args, '--qf', '%{NAME}/%{ARCH}/%|EPOCH?{%{EPOCH}}:{0}|/%{VERSION}/%{RELEASE}/%{BUILDTIME}\n';
+    if (-x "$root/usr/bin/rpm") {
+      exec("$root/usr/bin/rpm", '-qa', @args);
+      die("$root/usr/bin/rpm: $!\n");
+    }
+    if (-x "$root/bin/rpm") {
+      exec("$root/bin/rpm", '-qa', @args);
+      die("$root/bin/rpm: $!\n");
+    }
+    die("rpm: command not found\n");
+  }
+  my @pkgs;
+  while (<F>) {
+    chomp;
+    my @s = split('/', $_);
+    next unless @s >= 5;
+    my $q = {'name' => $s[0], 'arch' => $s[1], 'version' => $s[3], 'release' => $s[4]};
+    $q->{'epoch'} = $s[2] if $s[2];
+    $q->{'buildtime'} = $s[5] if $s[5];
+    push @pkgs, $q;
+  }
+  if (!close(F)) {
+    return queryinstalled($root, %opts, 'nochroot' => 1) if !@pkgs && $dochroot;
+    die("rpm: exit status $?\n");
+  }
+  return \@pkgs;
+}
+
 1;
diff --git a/Build/Rpmmd.pm b/Build/Rpmmd.pm
new file mode 100644 (file)
index 0000000..de5cfb6
--- /dev/null
@@ -0,0 +1,205 @@
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+package Build::Rpmmd;
+
+use strict;
+
+use XML::Parser;
+
+sub generic_parse {
+  my ($how, $in, $res, %options) = @_;
+  $res ||= [];
+  my @cursor = ([undef, $how, undef, $res, undef, \%options]);
+  my $p = new XML::Parser(Handlers => {
+    Start => sub {
+      my ($p, $el) = @_;
+      my $h = $cursor[-1]->[1];
+      return unless exists $h->{$el};
+      $h = $h->{$el};
+      push @cursor, [$el, $h];
+      $cursor[-1]->[2] = '' if $h->{'_text'};
+      $h->{'_start'}->($h, \@cursor, @_) if exists $h->{'_start'};
+    },
+    End => sub {
+      my ($p, $el) = @_;
+      if ($cursor[-1]->[0] eq $el) {
+       my $h = $cursor[-1]->[1];
+       $h->{'_end'}->($h, \@cursor, @_) if exists $h->{'_end'};
+       pop @cursor;
+      }
+    },
+    Char => sub {
+      my ($p, $text) = @_;
+      $cursor[-1]->[2] .= $text if defined $cursor[-1]->[2];
+    },
+  }, ErrorContext => 2);
+  if (ref($in)) {
+    $p->parse($in);
+  } else {
+    $p->parsefile($in);
+  }
+  return $res;
+}
+
+sub generic_store_text {
+  my ($h, $c, $p, $el) = @_;
+  my $data = $c->[0]->[4];
+  $data->{$h->{'_tag'}} = $c->[-1]->[2] if defined $c->[-1]->[2];
+}
+
+sub generic_store_attr {
+  my ($h, $c, $p, $el, %attr) = @_;
+  my $data = $c->[0]->[4];
+  $data->{$h->{'_tag'}} = $attr{$h->{'_attr'}} if defined $attr{$h->{'_attr'}};
+}
+
+sub generic_new_data {
+  my ($h, $c, $p, $el, %attr) = @_;
+  $c->[0]->[4] = {};
+  generic_store_attr(@_) if $h->{'_attr'};
+}
+
+sub generic_add_result {
+  my ($h, $c, $p, $el) = @_;
+  my $data = $c->[0]->[4];
+  return unless $data;
+  my $res = $c->[0]->[3];
+  if (ref($res) eq 'CODE') {
+    $res->($data);
+  } else {
+    push @$res, $data;
+  }
+  undef $c->[0]->[4];
+}
+
+my $repomdparser = {
+  repomd => {
+    data => {
+      _start => \&generic_new_data,
+      _attr => 'type',
+      _tag => 'type',
+      _end => \&generic_add_result,
+      location => { _start => \&generic_store_attr, _attr => 'href', _tag => 'location'},
+      size => { _text => 1, _end => \&generic_store_text, _tag => 'size'},
+    },
+  },
+};
+
+my $primaryparser = {
+  metadata => {
+    'package' => {
+      _start => \&generic_new_data,
+      _attr => 'type',
+      _tag => 'type',
+      _end => \&primary_add_result,
+      name => { _text => 1, _end => \&generic_store_text, _tag => 'name' },
+      arch => { _text => 1, _end => \&generic_store_text, _tag => 'arch' },
+      version => { _start => \&primary_handle_version },
+      'time' => { _start => \&primary_handle_time },
+      format => {
+        'rpm:provides' =>    { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'provides' }, },
+        'rpm:requires' =>    { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'requires' }, },
+        'rpm:conflicts' =>   { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'conflicts' }, },
+        'rpm:recommends' =>  { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'recommends' }, },
+        'rpm:suggests' =>    { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'suggests' }, },
+        'rpm:supplements' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'supplements' }, },
+        'rpm:enhances' =>    { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'enhances' }, },
+        'rpm:obsoletes' =>   { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'obsoletes' }, },
+        'rpm:buildhost' => { _text => 1, _end => \&generic_store_text, _tag => 'buildhost' },
+        'rpm:sourcerpm' => { _text => 1, _end => \&primary_handle_sourcerpm , _tag => 'source' },
+### currently commented out, as we ignore file provides in expanddeps
+#       file => { _text => 1, _end => \&primary_handle_file_end, _tag => 'provides' },
+      },
+      location => { _start => \&generic_store_attr, _attr => 'href', _tag => 'location'},
+    },
+  },
+};
+
+sub primary_handle_sourcerpm {
+  my ($h, $c, $p, $el, %attr) = @_;
+  my $data = $c->[0]->[4];
+  return unless defined $c->[-1]->[2];
+  $c->[-1]->[2] =~ s/-[^-]*-[^-]*\.[^\.]*\.rpm$//;
+  $data->{$h->{'_tag'}} = $c->[-1]->[2];
+}
+
+sub primary_handle_version {
+  my ($h, $c, $p, $el, %attr) = @_;
+  my $data = $c->[0]->[4];
+  $data->{'epoch'} = $attr{'epoch'} if $attr{'epoch'};
+  $data->{'version'} = $attr{'ver'};
+  $data->{'release'} = $attr{'rel'};
+}
+
+sub primary_handle_time {
+  my ($h, $c, $p, $el, %attr) = @_;
+  my $data = $c->[0]->[4];
+  $data->{'filetime'} = $attr{'file'} if $attr{'file'};
+  $data->{'buildtime'} = $attr{'build'} if $attr{'build'};
+}
+
+sub primary_handle_file_end {
+  my ($h, $c, $p, $el) = @_;
+  primary_handle_dep($h, $c, $p, $el, 'name', $c->[-1]->[2]);
+}
+
+my %flagmap = ( EQ => '=', LE => '<=', GE => '>=', GT => '>', LT => '<', NE => '!=' );
+
+sub primary_handle_dep {
+  my ($h, $c, $p, $el, %attr) = @_;
+  my $dep = $attr{'name'};
+  return if $dep =~ /^rpmlib\(/;
+  if(exists $attr{'flags'}) {
+    my $evr = $attr{'ver'};
+    return unless defined($evr) && exists($flagmap{$attr{'flags'}});
+    $evr = "$attr{'epoch'}:$evr" if $attr{'epoch'};
+    $evr .= "-$attr{'rel'}" if defined $attr{'rel'};
+    $dep .= " $flagmap{$attr{'flags'}} $evr";
+  }
+  my $data = $c->[0]->[4];
+  push @{$data->{$h->{'_tag'}}}, $dep;
+}
+
+sub primary_add_result {
+  my ($h, $c, $p, $el) = @_;
+  my $options = $c->[0]->[5] || {};
+  my $data = $c->[0]->[4];
+  if ($options->{'addselfprovides'} && defined($data->{'name'}) && defined($data->{'version'})) {
+    if (($data->{'arch'} || '') ne 'src' && ($data->{'arch'} || '') ne 'nosrc') {
+      my $evr = $data->{'version'};
+      $evr = "$data->{'epoch'}:$evr" if $data->{'epoch'};
+      $evr = "$evr-$data->{'release'}" if defined $data->{'release'};
+      my $s = "$data->{'name'} = $evr";
+      push @{$data->{'provides'}}, $s unless grep {$_ eq $s} @{$data->{'provides'} || []};
+    }
+  }
+  return generic_add_result(@_);
+}
+
+sub parse_repomd {
+  return generic_parse($repomdparser, @_);
+}
+
+sub parse {
+  return generic_parse($primaryparser, @_);
+}
+
+1;
index cd0a103426cb8ee8a2058dddde6fd00d8d7dc707..c1836deb0df7874bf4e7df214fc849c3a39439a7 100644 (file)
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 package Build::Susetags;
 
 use strict;
-use warnings;
-use Data::Dumper;
+
+# compatibility to old OBS code
+sub parse_obs_compat {
+  my ($file, undef, undef, @arches) = @_;
+  $file = "$file.gz" if ! -e $file && -e "$file.gz";
+  my $pkgs = {};
+  parse($file, sub {
+    my ($data) = @_;
+    my $medium = delete($data->{'medium'});
+    my $loc = delete($data->{'location'});
+    if (defined($medium) && defined($loc)) {
+      $loc =~ s/^\Q$data->{'arch'}\E\///;
+      $data->{'path'} = "$medium $loc";
+    }
+    return unless !@arches || grep { /$data->{'arch'}/ } @arches;
+    $pkgs->{"$data->{'name'}-$data->{'version'}-$data->{'release'}-$data->{'arch'}"} = $data;
+  }, 'addselfprovides' => 1);
+  return $pkgs;
+}
+
+my %tmap = (
+  'Pkg' => '',
+  'Loc' => 'location',
+  'Src' => 'source',
+  'Prv' => 'provides',
+  'Req' => 'requires',
+  'Con' => 'conflicts',
+  'Obs' => 'obsoletes',
+  'Rec' => 'recommends',
+  'Sug' => 'suggests',
+  'Sup' => 'supplements',
+  'Enh' => 'enhances',
+  'Tim' => 'buildtime',
+);
 
 sub addpkg {
-  my ($pkgs, $cur, $order, $cb, $cbdata, @arches) = @_;
-  if (defined($cur) && (!@arches || grep { /$cur->{'arch'}/ } @arches)) {
-    if(!$cb || &$cb($cur, $cbdata)) {
-      my $k = "$cur->{'name'}-$cur->{'version'}-$cur->{'release'}-$cur->{'arch'}";
-      $pkgs->{$k} = $cur;
-      # keep order (or should we use Tie::IxHash?)
-      push @{$order}, $k if defined $order;
+  my ($res, $data, $options) = @_;
+  # fixup location and source
+  if (exists($data->{'location'})) {
+    my ($medium, $dir, $loc) = split(' ', $data->{'location'}, 3);
+    $data->{'medium'} = $medium;
+    $data->{'location'} = defined($loc) ? "$dir/$loc" : "$data->{'arch'}/$dir";
+  }
+  $data->{'source'} =~ s/\s.*// if exists $data->{'source'};
+  if ($options->{'addselfprovides'} && defined($data->{'name'}) && defined($data->{'version'})) {
+    if (($data->{'arch'} || '') ne 'src' && ($data->{'arch'} || '') ne 'nosrc') {
+      my $evr = $data->{'version'};
+      $evr = "$data->{'epoch'}:$evr" if $data->{'epoch'};
+      $evr = "$evr-$data->{'release'}" if defined $data->{'release'};
+      my $s = "$data->{'name'} = $evr";
+      push @{$data->{'provides'}}, $s unless grep {$_ eq $s} @{$data->{'provides'} || []};
     }
   }
+  if (ref($res) eq 'CODE') {
+    $res->($data);
+  } else {
+    push @$res, $data;
+  }
 }
 
 sub parse {
-  # if @arches is empty take all arches
-  my ($file, $tmap, $order, @arches) = @_;
-  my $cb;
-  my $cbdata;
-  if (ref $order eq 'HASH') {
-    my $d = $order;
-    $order = undef;
-    $cb = $d->{'cb'} if (exists $d->{'cb'});
-    $cbdata = $d->{'data'} if (exists $d->{'data'});
-  }
-
-  # if @arches is empty take all arches
-  my @needed = keys %$tmap;
-  my $r = '(' . join('|', @needed) . '|Pkg):\s*(.*)';
-
-  if (!open(F, '<', $file)) {
-    if (!open(F, '-|', "gzip", "-dc", $file.'.gz')) {
-      die "$file: $!";
+  return parse_obs_compat(@_) if @_ > 2 && !defined $_[2];
+  my ($in, $res, %options) = @_;
+  $res ||= [];
+  my $fd;
+  if (ref($in)) {
+    $fd = $in;
+  } else {
+    if ($in =~ /\.gz$/) {
+      open($fd, '-|', "gzip", "-dc", $in) || die("$in: $!\n");
+    } else {
+      open($fd, '<', $in) || die("$in: $!\n");
     }
   }
-
   my $cur;
-  my $pkgs = {};
-  while (<F>) {
+  my $r = join('|', sort keys %tmap);
+  $r = qr/^([\+=])($r):\s*(.*)/;
+  while (<$fd>) {
     chomp;
-    next unless $_ =~ /([\+=])$r/;
+    next unless /$r/;
     my ($multi, $tag, $data) = ($1, $2, $3);
     if ($multi eq '+') {
-      while (<F>) {
+      while (<$fd>) {
        chomp;
-       last if $_ =~ /-$tag/;
-       push @{$cur->{$tmap->{$tag}}}, $_;
+       last if /^-\Q$tag\E/;
+       next if $tag eq 'Req' && /^rpmlib\(/;
+       push @{$cur->{$tmap{$tag}}}, $_;
       }
     } elsif ($tag eq 'Pkg') {
-      addpkg($pkgs, $cur, $order, $cb, $cbdata, @arches);
+      addpkg($res, $cur, \%options) if $cur;
       $cur = {};
       ($cur->{'name'}, $cur->{'version'}, $cur->{'release'}, $cur->{'arch'}) = split(' ', $data);
+      $cur->{'epoch'} = $1 if $cur->{'version'} =~ s/^(\d+)://;
     } else {
-      $cur->{$tmap->{$tag}} = $data;
+      $cur->{$tmap{$tag}} = $data;
     }
   }
-  addpkg($pkgs, $cur, $order, $cb, $cbdata, @arches);
-  close(F);
-  return $pkgs;
+  addpkg($res, $cur, \%options) if $cur;
+  if (!ref($in)) {
+    close($fd) || die("close $in: $!\n");
+  }
+  return $res;
 }
-
+  
 1;
index 354adca3492d1ce3f8acbf3df8242b1a842ecb9f..8ec554bb96eff86578624ab65f1637f8e033d740 100644 (file)
@@ -1,33 +1,94 @@
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 package Build::Zypp;
 
 use strict;
 
 our $root = '';
 
-sub parsecfg($)
-{
-  my $file = shift;
-  my $repocfg = "$root/etc/zypp/repos.d/$file.repo";
+sub parsecfg {
+  my ($repocfg, $reponame, $allrepos) = @_;
+
   local *REPO;
-  open(REPO, '<', $repocfg) or return undef;
+  open(REPO, '<', "$root/etc/zypp/repos.d/$repocfg") or return undef;
   my $name;
   my $repo = {};
   while (<REPO>) {
     chomp;
+    next if /^\s*#/;
+    s/\s+$//;
     if (/^\[(.+)\]/) {
-      $name = $1;
-    } else {
-      my ($key, $value) = split(/=/,$_,2);
+      if ($allrepos && defined($name)) {
+       $repo->{'description'} = $repo->{'name'} if defined $repo->{'name'};
+       $repo->{'name'} = $name;
+       push @$allrepos, $repo;
+       undef $name;
+       $repo = {};
+      }
+      last if defined $name;
+      $name = $1 if !defined($reponame) || $reponame eq $1;
+    } elsif (defined($name)) {
+      my ($key, $value) = split(/=/, $_, 2);
       $repo->{$key} = $value if defined $key;
     }
   }
   close(REPO);
-  return undef unless $name;
-  $repo->{'description'} = $repo->{'name'} if exists $repo->{'name'};
+  return undef unless defined $name;
+  $repo->{'description'} = $repo->{'name'} if defined $repo->{'name'};
   $repo->{'name'} = $name;
+  push @$allrepos, $repo if $allrepos;
   return $repo;
 }
 
+sub repofiles {
+  local *D;
+  return () unless opendir(D, "/etc/zypp/repos.d");
+  my @r = grep {!/^\./ && /.repo$/} readdir(D);
+  closedir D;
+  return sort(@r);
+}
+
+sub parseallrepos {
+  my @r;
+  for my $r (repofiles()) {
+    parsecfg($r, undef, \@r);
+  }
+  return @r;
+}
+
+sub parserepo($) {
+  my ($reponame) = @_;
+  # first try matching .repo file
+  if (-e "$root/etc/zypp/repos.d/$reponame.repo") {
+    my $repo = parsecfg("$reponame.repo", $reponame);
+    return $repo if $repo;
+  }
+  # then try all repo files
+  for my $r (repofiles()) {
+    my $repo = parsecfg($r, $reponame);
+    return $repo if $repo;
+  }
+  die("could not find repo '$reponame'\n");
+}
+
 1;
 
 # vim: sw=2
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..c6b1bb9
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Steet, Fifth Floor, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
index 5bd4bf9824aea9a8411111ed56ec01805d1904b9..346a9086cc17d0ed70ab0d8babe415620668b4b4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ SCM=$(shell if test -d .svn; then echo svn; elif test -d .git; then echo git; fi
 DATE=$(shell date +%Y%m%d%H%M)
 BUILD=build
 
-INITVM_ARCH=$(shell bash detect_architecture.sh)
+INITVM_ARCH=$(shell bash -c '. common_functions ; build_host_arch; echo $$BUILD_INITVM_ARCH')
 
 ifeq ($(SCM),svn)
 SVNVER=_SVN$(shell LANG=C svnversion .)
@@ -30,29 +30,27 @@ install:
            $(DESTDIR)$(man1dir)
        install -m755 \
            build \
-           build_kiwi.sh \
            vc \
-           createrpmdeps \
+           createdirdeps \
            order \
            expanddeps \
            computeblocklists \
            extractbuild \
            getbinaryid \
            killchroot \
-           getmacros \
-           getoptflags \
-           gettype \
-           getchangetarget \
+           queryconfig \
            common_functions \
            init_buildsystem \
-           initscript_qemu_vm \
            substitutedeps \
            debtransform \
            debtransformbz2 \
            debtransformzip \
            mkbaselibs \
            mkdrpms \
+           listinstalled \
+           createzyppdeps \
            createarchdeps \
+           createdebdeps \
            createrepomddeps \
            createyastdeps \
            changelog2spec \
@@ -62,14 +60,18 @@ install:
            spectool \
            signdummy \
            unrpm \
-           zvm_functions \
            $(DESTDIR)$(pkglibdir)
        install -m755 emulator/emulator.sh $(DESTDIR)$(pkglibdir)/emulator/
        install -m644 Build/*.pm $(DESTDIR)$(pkglibdir)/Build
        install -m644 qemu-reg $(DESTDIR)$(pkglibdir)
+       install -m644 build-vm build-vm-* $(DESTDIR)$(pkglibdir)
+       install -m644 build-recipe build-recipe-* $(DESTDIR)$(pkglibdir)
+       install -m644 build-pkg build-pkg-* $(DESTDIR)$(pkglibdir)
        install -m644 *.pm baselibs_global*.conf lxc.conf $(DESTDIR)$(pkglibdir)
        install -m644 configs/* $(DESTDIR)$(pkglibdir)/configs
        install -m644 build.1 $(DESTDIR)$(man1dir)
+       install -m644 vc.1 $(DESTDIR)$(man1dir)
+       install -m644 unrpm.1 $(DESTDIR)$(man1dir)
        ln -sf $(pkglibdir)/build $(DESTDIR)$(bindir)/build
        ln -sf $(pkglibdir)/vc    $(DESTDIR)$(bindir)/buildvc
        ln -sf $(pkglibdir)/unrpm $(DESTDIR)$(bindir)/unrpm
diff --git a/README b/README
index 3d758aee5795666186fb05b27648d13646f9ef69..b328e72742e912291c1567700f1b9821c4e1ac47 100644 (file)
--- a/README
+++ b/README
@@ -1,21 +1,11 @@
 
-This script is used for building SUSE Linux RPMs in
-a clean and safe chroot'ed build environment.
+This is a tool to build binary packages in a safe and reproducible
+way. The default is to build in a chroot sandbox, but it also
+supports building in a virtual machine for better security.
 
-At first you need to copy your SUSE Linux CDs into a
-path reachable by the build script, for example /home/suse-8.2-i386.
+The build tool can work with multiple package and recipe formats.
+The currently supported package formats are deb, rpm, and arch.
+The supported recipe formats are spec, dsc, kiwi, and PKGBUILD.
 
-If you have a DVD Drive and the SUSE Linux DVD, you can mount it
-and use this as the source for the RPMs.
+See the man page for more information.
 
-To build an RPM, change into the directory with the sources
-and the SPEC file. Then start the build script:
-env BUILD_RPMS=/home/suse-8.2-i386/suse build
-
-If this was successful you can find the binary and source RPMs below
-/var/tmp/build-root/usr/src/packages/
-
-Note: Depending on which package you want to build, you'll need
-a few hundred megabytes for the build in /var/tmp/build-root.
-
-For more information on using build, see 'man build'.
diff --git a/build b/build
index 68acb06bc03417fdbf5bb6faecdbb9fbd929ef91..ea39ae0a9b6cdf0a0723be70174ba85e1920218e 100755 (executable)
--- a/build
+++ b/build
@@ -1,17 +1,36 @@
 #!/bin/bash
 # Script to build a package.  It uses init_buildsystem to setup a chroot
 # building tree.  This script needs a directory as parameter.  This directory
-# has to include sources and a spec file.
+# has to include sources and a recipe file.
 #
 # BUILD_ROOT        here the packages will be built
 #
-# (c) 1997-2008 SuSE GmbH Nuernberg, Germany
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
 
 # some VMs do not allow to specify the init process...
-if test "$0" = "/sbin/init" ; then
-   exec /.build/build "$@"
+if test "$0" = /sbin/init ; then
+    exec /.build/build "$@"
 fi
 
+test -z "$BUILD_DIR" -a -e /.build/build.data -a -z "$BUILD_IGNORE_2ND_STAGE" && BUILD_DIR=/.build
 test -z "$BUILD_DIR" && BUILD_DIR=/usr/lib/build
 test -z "$BUILD_ROOT" && BUILD_ROOT=/var/tmp/build-root
 test -z "$CONFIG_DIR" && CONFIG_DIR="$BUILD_DIR/configs"
@@ -19,55 +38,23 @@ test -z "$CONFIG_DIR" && CONFIG_DIR="$BUILD_DIR/configs"
 export BUILD_ARCH BUILD_HOST_ARCH BUILD_ROOT BUILD_RPMS BUILD_DIR BUILD_DEBUG
 export BUILD_DIST
 
-ccache=0
 icecream=0
-statistics=0
-shell=
 definesnstuff=()
 repos=()
 old_packages=()
 
-# defaults for vm_img_mkfs
-vm_img_mkfs_ext4_options='-O ^has_journal,^huge_file,^resize_inode,sparse_super'
-vm_img_mkfs_ext4_extra='-E lazy_itable_init,discard'
-vm_img_mkfs_ext4="mkfs.ext4 -m 0 -q -F $vm_img_mkfs_ext4_options"
-vm_img_tunefs_ext4='tune2fs -c 0'
-vm_img_mkfs_ext3='mkfs.ext3 -m 0 -q -F'
-vm_img_tunefs_ext3='tune2fs -c 0 -o journal_data_writeback'
-vm_img_mkfs_ext2='mkfs.ext2 -m 0 -q -F'
-vm_img_tunefs_ext2='tune2fs -c 0'
-vm_img_mkfs_reiserfs='mkreiserfs -q -f'
-vm_img_mkfs_btrfs='mkfs.btrfs'
-vm_img_mkfs_xfs='mkfs.xfs -f'
-
-vm_kernel=/boot/vmlinuz
-vm_initrd=/boot/initrd
-qemu_bin=/usr/bin/qemu
-uml_kernel=/boot/vmlinux-um
-uml_initrd=/boot/initrd-um
-
-# z/VM: use default kernel image from local machine
-# lets go with the default parameters. However zvm_initrd will be a required parameter
-#zvm_kernel=/boot/image
-#zvm_initrd=/boot/initrd_worker
-zvm_param="root=/dev/disk/by-path/ccw-0.0.0150-part1 hvc_iucv=8 console=hvc0"
-zvm_mult_pass="THR4ME"
-#zvm_worker_nr="1"
-zvm_init_script="/.build/build"
-
-kvm_bin=/usr/bin/qemu-kvm
-# whether we have virtio support
-kvm_virtio=
-
-# guest visible console device name
-console=ttyS0
+# slurp in vm support
+. "$BUILD_DIR/build-vm"
+
+# slurp in recipe support
+. "$BUILD_DIR/build-recipe"
+
+# slurp in package binary support
+. "$BUILD_DIR/build-pkg"
 
 # need to restore build root owner for non-root builds
 browner=
 
-# additional kiwi parameters, used for appliance builds with obsrepositories:/ directive
-KIWI_PARAMETERS=
-
 # Default uid:gid for the build user
 ABUILD_UID=399
 ABUILD_GID=399
@@ -79,27 +66,15 @@ DO_CHECKS=true
 SHORT_CIRCUIT=false
 NO_TOPDIR_CLEANUP=false
 CLEAN_BUILD=
-USE_SYSTEM_QEMU=
 KEEP_PACKS=
-SPECFILES=()
+RECIPEFILES=()
 SRCDIR=
 BUILD_JOBS=
 ABUILD_TARGET=
 CREATE_BASELIBS=
 USEUSEDFORBUILD=
 LIST_STATE=
-VM_IMAGE=
-VM_SWAP=
-VM_KERNEL=
-VM_INITRD=
-VMDISK_ROOTSIZE=4096
-VMDISK_SWAPSIZE=1024
-VMDISK_FILESYSTEM=ext4
-# settings are for speed and not data safety, we format anyway on next run
-VMDISK_MOUNT_OPTIONS=__default
-VMDISK_CLEAN=
-HUGETLBFSPATH=
-MEMSIZE=
+
 RUNNING_IN_VM=
 RPMLIST=
 RELEASE=
@@ -109,7 +84,6 @@ LOGFILE=
 KILL=
 CHANGELOG=
 BUILD_DEBUG=
-PERSONALITY_SYSCALL=
 INCARNATION=
 DISTURL=
 LINKSOURCES=
@@ -118,10 +92,11 @@ RSYNCSRC=
 RSYNCDEST=
 RSYNCDONE=
 SIGNDUMMY=
-HOST_ARCH=
-EMULATOR_SCRIPT=
-KVM_OPTIONS=
-BUILD_EC2_TYPE="t1.micro"
+DO_STATISTICS=
+RUN_SHELL=
+CCACHE=
+DLNOSIGNATURE=
+CACHE_DIR=/var/cache/build
 
 
 # This is for insserv
@@ -138,7 +113,7 @@ echo_help () {
 Some comments for build
 -----------------------
 
-With build you can create rpm packages.  They will be built in a chroot
+With build you can create binary packages.  They will be built in a chroot
 system.  This chroot system will be setup automatically.  Normally you can
 simply call build with a spec file as parameter - nothing else has to be
 set.
@@ -178,7 +153,7 @@ Known Parameters:
   --no-init   Skip initialization of build root and start with build
               immediately.
 
-  --no-checks Do not run post-build checks
+  --no-checks Do not run checks (postbuild and %check)
 
   --lint      Run rpmlint after build.
 
@@ -186,14 +161,13 @@ Known Parameters:
               Capture build output to logfile. Defaults to
               .build.log in the build root for non-VM builds.
 
-  --repository PATH
-             Use package repository at PATH. Supported formats are
-             rpm-md and yast2.
+  --repo PATH_OR_URL
+             Use package repository at PATH_OR_URL. Supported formats
+              are rpm-md, yast2, debian, and arch linux.
              Alternatively zypp://NAME specifies the zypp
              repository NAME. The repo must be refreshed with zypp
              so package meta data is available locally. With emtpy
              NAME all enabled repositories are used.
-              a url can specify a remote repo.
 
   --rpms path1:path2:...
               Specify path where to find the RPMs for the build system
@@ -211,9 +185,9 @@ Known Parameters:
               Use 'rootdir' to setup chroot environment
 
   --cachedir cachedir
-              Use 'cachedir' to cache remote repo's packages, the
+              Use 'cachedir' to cache remote repo's packages. The
               default cache dir is /var/cache/build, every repo
-              given by --repository corresponds to a subdir named
+              given by --repo corresponds to a subdir named
               as md5sum of its repo url, for example:
                  /var/cache/build/3e8ea9b47808629414a0cebc33ea285e
 
@@ -307,7 +281,6 @@ Known Parameters:
   --emulator 
               Use any generic emulator to isolate the build process. You need to write
               an emulator/emulator.sh script and put it next to the build script sources.
-              You must NOT use any vm swap file for this.
 
   --emulator-script SCRIPT
               specify another emulator instead of emulator.sh
@@ -347,7 +320,7 @@ Known Parameters:
   --vm-memory SIZEINMB
               Set amount of RAM for VMs
 
-  --hugetlbfs HUGETLBFSPATH
+  --vm-hugetlbfs HUGETLBFSPATH
               Use hugetlb for memory management, path to mounted hugetlbfs.
 
   --vm-kernel FILE
@@ -362,8 +335,9 @@ Remember to have fun!
 [*] Maximum RPM: http://www.rpm.org/max-rpm/
 EOT
 }
+
 usage () {
-    echo "Usage: `basename $0` [--no-init|--clean|--rpms path|--verify|--help] [dir-to-build|spec-to-build]"
+    echo "Usage: `basename $0` [--no-init|--clean|--rpms path|--verify|--help] [dir-to-build|recipe-to-build]"
     cleanup_and_exit 1
 }
 
@@ -388,62 +362,25 @@ cleanup_and_exit () {
     if test -n "$RUNNING_IN_VM" ; then
        echo "$1" >  /.build/_exitcode
        test -n "$browner" && chown "$browner" $BUILD_ROOT
-       cd /
-       if test -n "$VM_SWAP" -a -e "$VM_SWAP" ; then
-           swapoff "$VM_SWAP" 2>/dev/null
-           echo -n "BUILDSTATUS$1" >"$VM_SWAP"
-       fi
-       exec >&0 2>&0        # so that the logging tee finishes
-       sleep 1                # wait till tee terminates
-       if test "$VM_TYPE" != lxc; then
-           kill -9 -1        # goodbye cruel world
-           if ! test -x /sbin/halt ; then
-               test -e /proc/sysrq-trigger || mount -n -tproc none /proc
-               sync
-               sleep 2 # like halt does
-               if test -e /proc/sysrq-trigger; then
-                   echo o > /proc/sysrq-trigger
-                   sleep 5 # wait for sysrq to take effect
-               else
-                   echo "Warning: VM doesn't support sysrq and /sbin/halt not installed"
-               fi
-           else
-               halt -f -p
-           fi
-           echo "Warning: clean shut down of the VM didn't work"
-       fi
+       vm_shutdown "$1"
     else
-        # nop if unused
-        cloud_volume_detach "$VM_SERVER" "$VM_VOLUME_NAME"
-        cloud_volume_detach "$VM_SERVER" "$VM_VOLUME_SWAP"
-        cloud_volume_detach "$VM_SERVER" "$EC2_EXTRACT_VOLUME_root"
-        cloud_volume_detach "$VM_SERVER" "$EC2_EXTRACT_VOLUME_swap"
-
-        [ -n "$EC2_SNAP_root" ] && ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
-        [ -n "$EC2_SNAP_swap" ] && ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap"
-        [ -n "$EC2_EXTRACT_VOLUME_root" ] && ec2-delete-volume --region "$BUILD_EC2_REGION" "$EC2_EXTRACT_VOLUME_root"
-        [ -n "$EC2_EXTRACT_VOLUME_swap" ] && ec2-delete-volume --region "$BUILD_EC2_REGION" "$EC2_EXTRACT_VOLUME_swap"
-
        umount -n $BUILD_ROOT/proc/sys/fs/binfmt_misc 2> /dev/null || true
        umount -n $BUILD_ROOT/proc 2>/dev/null || true
        umount -n $BUILD_ROOT/dev/pts 2>/dev/null || true
        umount -n $BUILD_ROOT/dev/shm 2>/dev/null || true
-       test "$VM_IMAGE" = 1 && VM_IMAGE=
-       [ -n "$VM_IMAGE" ] && umount $BUILD_ROOT 2>/dev/null || true
+       umount -n $BUILD_ROOT/sys 2>/dev/null || true
+       test -n "$VM_IMAGE" -a "$VM_IMAGE" != 1 && umount $BUILD_ROOT 2>/dev/null || true
+       test -n "$VM_TYPE" && vm_cleanup
     fi
-
-#    echo "pid $$ exit $1"
     exit $1
 }
 
-fail_exit()
-{
-  cleanup_and_exit 1
+fail_exit() {
+    cleanup_and_exit 1
 }
 
-shellquote()
-{
-    for arg; do
+shellquote() {
+    for arg ; do
        arg=${arg/\\/\\\\}
        arg=${arg/\$/\\\$}
        arg=${arg/\"/\\\"}
@@ -454,17 +391,15 @@ shellquote()
 
 # create a shell script from command line. Used for preserving arguments
 # through /bin/su -c
-toshellscript()
-{
-       echo "#!/bin/sh -x"
-       echo -n exec
-       shellquote "$@"
-       echo
+toshellscript() {
+    echo "#!/bin/sh -x"
+    echo -n exec
+    shellquote "$@"
+    echo
 }
 
-setupccache()
-{
-    if [ "$ccache" = 1 ]; then
+setupccache() {
+    if test -n "$CCACHE" ; then
        if mkdir -p $BUILD_ROOT/var/lib/build/ccache/bin; then
            for i in $(ls $BUILD_ROOT/usr/bin | grep -E '^(cc|gcc|[cg][+][+])([-]?[234][.]?[0-9])*$'); do
 #                ln -sf /usr/bin/ccache $BUILD_ROOT/var/lib/build/ccache/bin/$i
@@ -478,7 +413,7 @@ setupccache()
                echo "Installed ccache wrapper as $BUILD_ROOT/var/lib/build/ccache/bin/$i"
            done
        fi
-       mkdir -p "$BUILD_ROOT"/.ccache
+       mkdir -p "$BUILD_ROOT/.ccache"
        chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/.ccache"
        echo "export CCACHE_DIR=/.ccache" > "$BUILD_ROOT"/etc/profile.d/build_ccache.sh
        echo 'export PATH=/var/lib/build/ccache/bin:$PATH' >> "$BUILD_ROOT"/etc/profile.d/build_ccache.sh
@@ -487,23 +422,21 @@ setupccache()
     fi
 }
 
-setupicecream()
-{
-    if [ "$icecream" -eq 0 ]; then
+setupicecream() {
+    if test "$icecream" -eq 0 ; then
        rm -rf "$BUILD_ROOT/var/run/icecream"
        rm -f "$BUILD_ROOT/etc/profile.d/build_icecream.sh"
-       return
+       return 0
     fi
 
     if ! chroot "$BUILD_ROOT" rpm -q icecream >/dev/null 2>/dev/null; then
        echo "*** icecream package not installed ***"
-       false
-       return
+       return 1
     fi
 
     echo "using icecream with $icecream jobs"
 
-    if [ "$ccache" -ne 1 ]; then
+    if test -z "$CCACHE" ; then
        echo 'export PATH=/usr/lib/icecc/bin:/opt/icecream/bin:$PATH' > "$BUILD_ROOT"/etc/profile.d/build_icecream.sh
     else
        echo 'export CCACHE_PATH=/usr/lib/icecc/bin:/opt/icecream/bin' > "$BUILD_ROOT"/etc/profile.d/build_icecream.sh
@@ -514,25 +447,24 @@ setupicecream()
 
     # XXX use changelog like autobuild does instead?
     # only run create-env if compiler or glibc changed
-    if [ -z "$icecc_vers" \
+    if test -z "$icecc_vers" \
        -o ! -e "$BUILD_ROOT/$icecc_vers" \
        -o "$BUILD_ROOT/usr/bin/gcc" -nt "$BUILD_ROOT/$icecc_vers" \
        -o "$BUILD_ROOT/usr/bin/g++" -nt "$BUILD_ROOT/$icecc_vers" \
        -o "$BUILD_ROOT/usr/bin/as" -nt "$BUILD_ROOT/$icecc_vers" \
-       -o "$BUILD_ROOT/lib/libc.so.6" -nt "$BUILD_ROOT/$icecc_vers" ]
+       -o "$BUILD_ROOT/lib/libc.so.6" -nt "$BUILD_ROOT/$icecc_vers"
     then
        rm -rf "$BUILD_ROOT/var/run/icecream"
        mkdir -p "$BUILD_ROOT/var/run/icecream"
-       if [ -e "$BUILD_ROOT"/usr/bin/create-env ]; then
-         createenv=/usr/bin/create-env
-       elif [ -e "$BUILD_ROOT"/usr/lib/icecc/icecc-create-env ]; then
-         createenv="/usr/lib/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX
-       elif [ -e "$BUILD_ROOT"/usr/lib64/icecc/icecc-create-env ]; then
-         createenv="/usr/lib64/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX
+       if test -e "$BUILD_ROOT"/usr/bin/create-env ; then
+           createenv=/usr/bin/create-env
+       elif test -e "$BUILD_ROOT"/usr/lib/icecc/icecc-create-env ; then
+           createenv="/usr/lib/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX
+       elif test -e "$BUILD_ROOT"/usr/lib64/icecc/icecc-create-env ; then
+           createenv="/usr/lib64/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX
        else
-         echo "create-env not found"
-         false
-         return
+           echo "create-env not found"
+           return 1
        fi
        chroot $BUILD_ROOT bash -c "cd /var/run/icecream; $createenv" || cleanup_and_exit 1
        icecc_vers=(`shopt -s nullglob; echo $BUILD_ROOT/var/run/icecream/*.tar.{bz2,gz}`)
@@ -540,14 +472,13 @@ setupicecream()
     else
        echo "reusing existing icecream environment $icecc_vers"
     fi
-    if [ -n "$icecc_vers" ]; then
-      echo "export ICECC_VERSION=$icecc_vers" >> "$BUILD_ROOT"/etc/profile.d/build_icecream.sh
+    if test -n "$icecc_vers" ; then
+       echo "export ICECC_VERSION=$icecc_vers" >> "$BUILD_ROOT"/etc/profile.d/build_icecream.sh
     fi
 }
 
-setmemorylimit()
-{
-    if [ -n "$VM_IMAGE" -o -n "$RUNNING_IN_VM" ]; then
+setmemorylimit() {
+    if test -n "$VM_IMAGE" -o -n "$RUNNING_IN_VM" ; then
        return
     fi
     local mem
@@ -569,17 +500,16 @@ setmemorylimit()
     echo "Memory limit set to ${limit}KB"
 }
 
-create_baselibs()
-{
+create_baselibs() {
     local pkgs=()
     local line
 
     BASELIBS_CFG=
 
-    if test "$BUILDTYPE" == "arch" ; then
+    if test "$BUILDTYPE" == arch ; then
        return
     fi
-    if test "$BUILDTYPE" == "dsc" ; then
+    if test "$BUILDTYPE" == dsc ; then
        pkgs=($DEBS)
     else # spec and kiwi
        if test -e $BUILD_ROOT$TOPDIR/SOURCES/baselibs.conf ; then
@@ -638,20 +568,19 @@ create_baselibs()
     rm -rf "$BUILD_ROOT/.mkbaselibs"
 }
 
-copy_oldpackages()
-{
+copy_oldpackages() {
     local i=0
     local d
     local dest
-    [ -z "$RUNNING_IN_VM" ] || return 0
-    if [ -z "$old_packages" ]; then
+    test -z "$RUNNING_IN_VM" || return 0
+    if test -z "$old_packages" ; then
        rm -rf "$BUILD_ROOT"/.build.oldpackages*
        return 0
     fi
     for d in "${old_packages[@]}"; do
        dest="$BUILD_ROOT/.build.oldpackages"
        test "$i" = 0 || dest="$dest$i"
-       if [ -d "$d" -a "$d" != "$dest" ] ; then
+       if test -d "$d" -a "$d" != "$dest" ; then
            rm -rf "$dest"
            mkdir -p "$dest"
            cp -L $d/* "$dest"
@@ -660,379 +589,73 @@ copy_oldpackages()
     done
 }
 
-vm_img_create()
-{
-    local img="$1"
-    local size="$2"
-
-    echo "Creating $img (${size}M)"
-    mkdir -p "${img%/*}" || cleanup_and_exit 3
-
-    # prefer fallocate, which avoids fragmentation
-    r=1
-    if type -p fallocate > /dev/null; then
-        fallocate -l "${size}M" "$img"
-        r=$?
-    fi
-    # fall back to dd method if fallocate is not supported
-    if [ "$r" -gt "0" ]; then
-        dd if=/dev/zero of="$img" bs=1M count=0 seek="$size" || cleanup_and_exit 3
-    fi
-}
-
-vm_img_mkfs()
-{
-    local fs="$1"
-    local img="$2"
-    local mkfs tunefs
-    eval "mkfs=\"\$vm_img_mkfs_${fs}\""
-    eval "mkfs_exta_options=\"\$vm_img_mkfs_${fs}_extra\""
-    eval "tunefs=\"\$vm_img_tunefs_${fs}\""
-
-    if test -z "$mkfs"; then
-       echo "filesystem \"$fs\" isn't supported"
-       cleanup_and_exit 3
-    fi
-
-
-    echo "Creating $fs filesystem on $img"
-    if ! $mkfs $mkfs_exta_options "$img"; then
-        if test -z "$mkfs_exta_options"; then
-            cleanup_and_exit 3
-        else
-            echo "Format call failed, trying again without extra options..."
-            $mkfs "$img" || cleanup_and_exit 3
-        fi
-    fi
-    if test -n "$tunefs" ; then
-       $tunefs "$img" || cleanup_and_exit 3
-    fi
-}
-
-background_monitor_process()
-{
-  max_disk=0
-  max_mem=0
-  while sleep 5; do
-
-    # memory usage
-    if [ -e /proc/meminfo ]; then
-      memtotal=0
-      while read key value unit; do
-        case $key in
-          MemTotal:|SwapTotal:)
-            memtotal=$(( $memtotal + $value ))
-            ;;
-          MemFree:|SwapFree:|SwapCached:|Cached:|Buffers:)
-            memtotal=$(( $memtotal - $value ))
-            ;;
-        esac
-      done < /proc/meminfo
-
-      if [ ${memtotal} -gt $max_mem ]; then
-        max_mem="${memtotal}"
-        echo -n $(( $max_mem / 1024 )) > /.build/_statistics.memory.new && mv /.build/_statistics.memory.new /.build/_statistics.memory
-      fi
-    fi
-
-    # disk storage usage
-    if type -p df >& /dev/null; then
-      c=(`df -m / 2>/dev/null | tail -n 1`)
-
-      if [ ${c[2]} -gt $max_disk ]; then
-        max_disk="${c[2]}"
-        echo -n $max_disk > /.build/_statistics.df.new && mv /.build/_statistics.df.new /.build/_statistics.df
-      fi
-    fi
-
-    [ -e /.build/_statistics.exit ] && exit 0
-  done
-}
-
-detect_vm_2nd_stage()
-{
-    if test -e /.build/build.data; then
-        . /.build/build.data
-    fi
-    if test -z "$VM_TYPE" ; then
-       return 1
-    fi
-    if test $$ -eq 1 || test $$ -eq 2; then
-       # ignore special init signals if we're init
-       # we're using ' ' instead of '' so that the signal handlers
-       # are reset in the child processes
-       trap ' ' HUP TERM
-       $0 "$@"
-       cleanup_and_exit $?
-    fi
-    echo "2nd stage started in virtual machine"
-    BUILD_ROOT=/
-    BUILD_DIR=/.build
-    echo "machine type: `uname -m`"
-    if test "$PERSONALITY" != 0 -a -z "$PERSONALITY_SET" ; then
-       export PERSONALITY_SET=true
-       echo "switching personality to $PERSONALITY..."
-       # this is 32bit perl/glibc, thus the 32bit syscall number
-       exec perl -e 'syscall(136, '$PERSONALITY') == -1 && warn("personality: $!\n");exec "/.build/build" || die("/.build/build: $!\n")'
-    fi
-    RUNNING_IN_VM=true
-    test -e /proc/version || mount -orw -n -tproc none /proc
-    if test "$VM_TYPE" != 'lxc'; then
-       mount -n ${VMDISK_MOUNT_OPTIONS},remount,rw /
-    fi
-    umount /run >/dev/null 2>&1
-# qemu inside of xen does not work, check again with kvm later before enabling this
-#    if [ -e /dev/kqemu ]; then
-#        # allow abuild user to run qemu
-#        chmod 0666 /dev/kqemu
-#    fi
-    if test "$VM_TYPE" = 'zvm' ; then
-        VM_SWAP='/dev/dasdb1'
-    fi
-    if test "$VM_TYPE" = 'ec2' ; then
-        VM_SWAP='/dev/sdb1'
-        # Usually the external system is writing the swap signature, but EC2 volume
-        # attach is very slow, so let's do it in the VM for now.
-        mkswap "$VM_SWAP"
-    fi
-    if test -n "$VM_SWAP" ; then
-       for i in 1 2 3 4 5 6 7 8 9 10 ; do
-           test -e "$VM_SWAP" && break
-           test $i = 1 && echo "waiting for $VM_SWAP to appear"
-           echo -n .
-           sleep 1
-       done
-       test $i = 1 || echo
-       # recreate the swap device manually if it didn't exist for some
-       # reason, hardcoded to hda2 atm
-       if ! test -b "$VM_SWAP" ; then
-           rm -f "$VM_SWAP"
-           umask 027
-           mknod "$VM_SWAP" b 3 2
-           umask 022
-       fi
-       swapon -v "$VM_SWAP" || exit 1
-    fi
-    HOST="$MYHOSTNAME"
-
-    # fork a process monitoring max filesystem fillment during build
-    if test "$statistics" = "1"; then
-        background_monitor_process &
-    fi
-
-    if [ ! -e /dev/.udev ]; then
-        echo "WARNING: udev not running, creating extra device nodes"
-        test -e /dev/fd || ln -sf /proc/self/fd /dev/fd
-        test -e /etc/mtab || ln -sf /proc/mounts /etc/mtab
-    fi
-
-    # set date to build start on broken systems (now < build start)
-    if [ $(date '+%s') -lt $(date -r /.build/.date '+%s') ]; then
-        echo -n "WARNING: system has a broken clock, setting it to a newer time: "
-        date -s `cat /.build/.date`
-    fi
-
-    return 0
-}
-
-find_spec_files()
-{
-    local spec files
-    if [ -z "$SPECFILES" ]; then
-       set -- "`pwd`"
-    else
-       set -- "${SPECFILES[@]}"
-    fi
-    SPECFILES=()
-    for spec in "$@"; do
-       if [ "$spec" = "${spec#/}" ]; then
-           spec="`pwd`/$spec"
-       fi
-
-       if [ -d "$spec" ]; then
-           specs=("$spec"/*.spec)
-           if [ -n "$specs" ]; then
-               SPECFILES=("${SPECFILES[@]}" "${specs[@]}")
-           else
-               specs=("$spec"/*.spec)
-               if [ -n "$specs" ]; then
-                   SPECFILES=("${SPECFILES[@]}" "${specs[@]}")
-               fi
-           fi
-       else
-           SPECFILES[${#SPECFILES[@]}]="$spec";
-       fi
-    done
-
-    if test -z "$SPECFILES"; then
-       echo no spec files or src rpms found in $@. exit...
-       cleanup_and_exit 1
-    fi
-}
-
-become_root_or_fail()
-{
-    if [ ! -w /root ]; then
+become_root_or_fail() {
+    if test ! -w /root ; then
        echo "You have to be root to use $0" >&2
        exit 1
     fi
     cleanup_and_exit 1
 }
 
-mkdir_build_root()
-{
-    if [ -d "$BUILD_ROOT" ]; then
+mkdir_build_root() {
+    # strip trailing slash
+    test "$BUILD_ROOT" != / && BUILD_ROOT="${BUILD_ROOT%/}"
+    if test -d "$BUILD_ROOT" ; then
        # check if it is owned by root
-       if [ -z "$RUNNING_IN_VM" -a \! -O "$BUILD_ROOT" -a "`stat -c %u $BUILD_ROOT`" -ne 0 ]; then
+       if test -z "$RUNNING_IN_VM" -a \! -O "$BUILD_ROOT" -a "`stat -c %u $BUILD_ROOT`" -ne 0 ; then
            echo "BUILD_ROOT=$BUILD_ROOT must be owned by root. Exit..."
            cleanup_and_exit 1
        fi
     else
        test "$BUILD_ROOT" != "${BUILD_ROOT%/*}" && mkdir -p "${BUILD_ROOT%/*}"
-       if ! mkdir $BUILD_ROOT; then
+       if ! mkdir $BUILD_ROOT ; then
            echo "can not create BUILD_ROOT=$BUILD_ROOT. Exit..."
            cleanup_and_exit 1
        fi
     fi
 
-    if [ ! -w "$BUILD_ROOT" ]; then
+    if test ! -w "$BUILD_ROOT" ; then
        echo "Error: BUILD_ROOT=$BUILD_ROOT not writeable, try --clean."
        cleanup_and_exit 3
     fi
 
     rm -rf "$BUILD_ROOT/.build.packages"
-    if [ -z "$VM_TYPE" -a -z "$RUNNING_IN_VM" ]; then
-       # don't touch this in VM
-       rm -rf "$BUILD_ROOT/.build"
-       mkdir -p "$BUILD_ROOT/.build"
+    if test -z "$VM_TYPE" -a -z "$RUNNING_IN_VM" ; then
+         # don't touch this in VM
+         rm -rf "$BUILD_ROOT/.build"
+         mkdir -p "$BUILD_ROOT/.build"
     fi
 }
 
-ec2_volume_state()
-{
-    local VM_VOL_NAME="$1"
-    temp_file=`mktemp`
-    ec2-describe-volumes "$VM_VOL_NAME" --region "$BUILD_EC2_REGION" > $temp_file
-
-    if grep -q ^ATTACHMENT "$temp_file"; then
-      grep ^ATTACHMENT "$temp_file" | awk '{ print $5 }'
+copy_overlay() {
+    if test -d "$OVERLAY"; then
+       pushd $OVERLAY
+       echo "Copying overlay to BUILD_ROOT"
+       tar -cpf - . | (cd $BUILD_ROOT ; tar -xvf -)
+       popd
     else
-      grep ^VOLUME "$temp_file" | awk '{ print $5 }'
-    fi
-    rm "$temp_file"
-}
-
-cloud_volume_attach()
-{
-    local VM_SERVER="$1"
-    local VM_VOL_NAME="$2"
-    local VM_VOL_DEV="$3"
-
-    if [ "$VM_TYPE" = 'openstack' ]; then
-      if ! nova volume-attach "$VM_SERVER" "$VM_VOL_NAME" "$VM_VOL_DEV"; then
-          echo "ERROR: nova attach failed. $?" >&2
-          return 3
-      fi
-      while true; do
-          state=`nova volume-show "$VM_VOL_NAME" | sed -n 's,^|[ ]*status[ ]*|[ ]*\([^ ]*\).*,\1,p'`
-          [ "$state" == "in-use" ] && break
-          if [ -z "$state" ]; then
-             echo "ERROR: unable to find state of volume $VM_VOL_NAME" >&2
-             return 3
-          fi
-          if [ "$state" == "available" ]; then
-             echo "WARNING: volume $VM_VOL_NAME got not attached, retrying" >&2
-             if ! nova volume-attach "$VM_SERVER" "$VM_VOL_NAME" "$VM_VOL_DEV"; then
-                 echo "ERROR: nova attach failed. $?" >&2
-                 return 3
-             fi
-          fi
-          sleep 3
-      done
-
-      if [ ! -e "$VM_VOL_DEV" ]; then
-          #GROSS HACK: kernel does not care about the given device name
-#          VM_VOL_DEV="/dev/"`dmesg| sed -n 's,.*\(vd.\): unknown partition tab.*,\1,p' | tail -n 1`
-          VM_VOL_DEV=`ls -1 /dev/vd? | tail -n 1`
-      fi
-      echo "$VM_VOL_DEV"
-    elif [ "$VM_TYPE" = 'ec2' ]; then
-      temp_file=`mktemp`
-      if ! ec2-attach-volume "$VM_VOL_NAME" -d /dev/sdz -i `ec2-instance-id` --region $BUILD_EC2_REGION > "$temp_file"; then
-         rm "$temp_file"
-         cleanup_and_exit 1
-      fi
-      # wait that it becomes available
-      while true; do
-        state=`ec2_volume_state "$VM_VOL_NAME"`
-        [ "$state" = "attached" ] && break
-        sleep 1
-      done
-      # print device node
-      grep ^ATTACHMENT "$temp_file" | awk '{ print $4 }'
-      rm "$temp_file"
-    fi
-}
-
-cloud_volume_detach()
-{
-    local VM_SERVER="$1"
-    local VM_VOL_NAME="$2"
-    if [ "$VM_TYPE" = 'openstack' ]; then
-      # needed at all?
-      nova volume-show "$VM_VOL_NAME" | grep -q in-use || return 0
-
-      # umount seems not to be enough
-      sync
-
-      if ! nova volume-detach "$VM_SERVER" "$VM_VOL_NAME"; then
-          echo "ERROR: nova detach of $VM_VOL_NAME failed." >&2
-          return 3
-      fi
-      while nova volume-show "$VM_VOL_NAME" | grep -q availabe; do
-          sleep 3
-      done
-    elif [ "$VM_TYPE" = 'ec2' ]; then
-       state=`ec2_volume_state "$VM_VOL_NAME"`
-       if [ "$state" != "available" ]; then
-         ec2-detach-volume "$VM_VOL_NAME" --region $BUILD_EC2_REGION || return 3
-       fi
+       echo "OVERLAY ($OVERLAY) is no directory - skipping"
     fi
-    return 0
-}
-
-linux64()
-{
-       perl -e 'syscall('$PERSONALITY_SYSCALL', 0); exec(@ARGV) || die("$ARGV[0]: $!\n")' "$@"
 }
 
-check_for_arm()
-{
-    local uname
-
-    uname=$(uname -m)
-
-    if [ "$uname" != "armv7l" ]; then
-        return
-    fi
-
-    export HOST_ARCH=armv7l
-
-    export kvm_bin="/usr/bin/qemu-system-arm"
-    export console=ttyAMA0
-    export KVM_OPTIONS="-enable-kvm -M vexpress-a15 -dtb /boot/a15-guest.dtb -cpu cortex-a15"
-    VM_KERNEL=/boot/zImage
-    VM_INITRD=/boot/initrd
-    # prefer the guest kernel
-    if [ -e /boot/zImage.guest ]; then
-        VM_KERNEL=/boot/zImage.guest
-    fi
-    # prefer the guest initrd
-    if [ -e /boot/initrd.guest ]; then
-        VM_INITRD=/boot/initrd.guest
+run_rsync() {
+    if test -n "$RSYNCDEST" ; then
+       if test -d "$RSYNCSRC" ; then
+           if ! test -d "$BUILD_ROOT/$RSYNCDEST" ; then
+               echo "ATTENTION! Creating missing target directory ($BUILD_ROOT/$RSYNCDEST)."
+               mkdir -p $BUILD_ROOT/$RSYNCDEST
+           fi
+           echo "Running rsync ..."
+           rsync -av $RSYNCSRC/* $BUILD_ROOT/$RSYNCDEST/
+           chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/$RSYNCDEST"
+           RSYNCDONE=true
+           echo "... done"
+       else
+           echo "RSYNCSRC is not a directory - skipping"
+       fi
+    else
+       echo "RSYNCSRC given, but not RSYNCDEST - skipping"
     fi
-    export VM_KERNEL
-    export VM_INITRD
 }
 
 hide_passwords()
@@ -1053,425 +676,226 @@ hide_passwords()
     echo ${repos[@]}
 }
 
-check_for_ppc()
-{
-    local uname
-
-    uname=$(uname -m)
-
-    case $uname in
-         ppc|ppc64) export VM_KERNEL=/boot/vmlinux
-                    export VM_INITRD=/boot/initrd
-                    ;;
-         ppc64le)   export VM_INITRD=/boot/vmlinuxle
-                    export VM_INITRD=/boot/initrdle
-                    ;;
-         *)         return ;;
-    esac
-
-    grep -q "PowerNV" /proc/cpuinfo && export HOST_ARCH=power7 || export HOST_ARCH=ppc970
-
-    export kvm_bin="/usr/bin/qemu-system-ppc64"
-    export console=hvc0
-    export KVM_OPTIONS="-enable-kvm -M pseries"
-    if [ -z "$RUNNING_IN_VM" -a -n "$HUGETLBFSPATH" ];then
-      if ! grep -q "$HUGETLBFSPATH" /proc/mounts; then
-         echo "hugetlbfs is not mounted"
-         exit 1
-      fi
-         PAGES_FREE=$(cat /sys/kernel/mm/hugepages/hugepages-16384kB/free_hugepages)
-         PAGES_REQ=$(( ${MEMSIZE:-64} / 16 ))
-      if [ "$PAGES_FREE" -lt "$PAGES_REQ" ];then
-         echo "please adjust nr_hugepages"
-         exit 1
-      fi
-      if [ "$HOST_ARCH" = "ppc970" ];then
-          if ! grep -q -E '(kvm_rma_count.*kvm_hpt_count)|(kvm_hpt_count.*kvm_rma_count)' /proc/cmdline; then
-             echo "put kvm_rma_count=<VM number> or kvm_hpt_count=<> to your boot options"
-             exit 1
-          fi
-      fi
-   fi
-}
 
 #### main ####
 
 trap fail_exit EXIT
 
-archname=`perl -V:archname`
-archname="${archname#archname=?}"
-case "$archname" in
-    x86_64*) PERSONALITY_SYSCALL=135 ;;
-    alpha*) PERSONALITY_SYSCALL=324 ;;
-    sparc*) PERSONALITY_SYSCALL=191 ;;
-    ia64*) PERSONALITY_SYSCALL=1140 ;;
-    i?86*|ppc*|aarch64*|arm*|sh4|cris|m68k*|s390*|unicore32|microblaze)   PERSONALITY_SYSCALL=136 ;;
-    *) echo "ARCHITECTURE PERSONALITY IS UNKNOWN"; exit 1;;
-esac
-
 shopt -s nullglob
 
-export PATH=$BUILD_DIR:/sbin:/usr/sbin:$PATH
+export PATH=$BUILD_DIR:/sbin:/usr/sbin:/bin:/usr/bin:$PATH
 
-if detect_vm_2nd_stage ; then
-    set "/.build-srcdir/$SPECFILE"
+if vm_detect_2nd_stage ; then
+    set "/.build-srcdir/$RECIPEFILE"
     export PATH=/.build:$PATH
 fi
 
 . $BUILD_DIR/common_functions || exit 1
-. $BUILD_DIR/zvm_functions || exit 1
 
 export HOST
 
-needarg()
-{
-  if [ -z "$ARG" ]; then
-    echo "$PARAM needs an agrument" >&2
-    cleanup_and_exit 1
-  fi
+needarg() {
+    if test -z "$ARG" ; then
+       echo "$PARAM needs an agrument" >&2
+       cleanup_and_exit 1
+    fi
 }
 
 while test -n "$1"; do
-  PARAM="$1"
-  UNSTRIPPED_ARG="$2"
-  ARG="$2"
-  [ "$ARG" = "${ARG#-}" ] || ARG=""
-  ARG2="$3"
-  [ "$ARG2" = "${ARG2#-}" ] || ARG2=""
-  shift
-  case $PARAM in
-    *-*=*)
-      ARG=${PARAM#*=}
-      PARAM=${PARAM%%=*}
-      set -- "----noarg=$PARAM" "$@"
-  esac
-  case $PARAM in
-      *-help|-h)
+    PARAM="$1"
+    ARG="$2"
+    test "$ARG" = "${ARG#-}" || ARG=
+    shift
+    case $PARAM in
+      *-*=*)
+       ARG=${PARAM#*=}
+       PARAM=${PARAM%%=*}
+       set -- "----noarg=$PARAM" "$@"
+       ;;
+    esac
+    case ${PARAM/#--/-} in
+      -help|-h)
        echo_help
        cleanup_and_exit
       ;;
-      *-no*init)
+      -noinit|-no-init)
        DO_INIT=false
       ;;
-      *-no-build)
-       DO_BUILD=false
+      -no-build)
+       DO_BUILD=false
       ;;
-      *-no*checks)
+      -nochecks|-no-checks)
        DO_CHECKS=false
       ;;
-      -clean|--clean)
+      -clean)
        CLEAN_BUILD='--clean'
       ;;
-      *-kill)
+      -kill)
        KILL=true
       ;;
-      *-rpms)
+      -rpms)
        needarg
        BUILD_RPMS="$ARG"
        shift
       ;;
-      *-arch)
+      -arch)
        needarg
        BUILD_ARCH="$ARG"
        shift
       ;;
-      *-verify)
+      -verify)
        export VERIFY_BUILD_SYSTEM=true
       ;;
-      *-target)
+      -target)
        needarg
        ABUILD_TARGET="$ARG"
        shift
       ;;
-      *-jobs)
+      -jobs)
        needarg
        BUILD_JOBS="$ARG"
        shift
       ;;
-      *-threads)
+      -threads)
        needarg
        BUILD_THREADS="$ARG"
        shift
       ;;
-      *-extra*packs|-X)
+      -extrapacks|-extra-packs|-X)
        needarg
        BUILD_EXTRA_PACKS="$BUILD_EXTRA_PACKS $ARG"
        shift
       ;;
-      *-lint)
+      -lint)
        DO_LINT=true
        ;;
-      *-baselibs)
+      -baselibs)
        CREATE_BASELIBS=true
        ;;
-      --kiwi-parameter)
-       KIWI_PARAMETERS="$KIWI_PARAMETERS $UNSTRIPPED_ARG"
-       shift
-       ;;
-      *-baselibs-internal)
+      -baselibs-internal)
        CREATE_BASELIBS=internal
        ;;
-      *-use-system-qemu)
-       USE_SYSTEM_QEMU="--use-system-qemu"
-      ;;
-      --keep-packs)
-       KEEP_PACKS="--keep-packs"
-      ;;
-      *-root)
+      -keep-packs)
+        KEEP_PACKS="--keep-packs"
+        ;;
+      -root)
        needarg
        BUILD_ROOT="$ARG"
        shift
       ;;
-      *-cachedir)
+      -cachedir)
        needarg
        CACHE_DIR="$ARG"
        shift
       ;;
-      *-oldpackages)
+      -oldpackages)
        needarg
        old_packages=("${old_packages[@]}" "$ARG")
        shift
       ;;
-      *-dist)
+      -dist)
        needarg
        BUILD_DIST="$ARG"
        shift
       ;;
-      *-emulator-script)
-       needarg
-       EMULATOR_SCRIPT="$ARG"
-       shift
-      ;;
-      *-xen|*-kvm|--uml|--qemu|--emulator)
-       VM_TYPE=${PARAM##*-}
-       if [ -n "$ARG" ]; then
-           VM_IMAGE="$ARG"
-           shift
-       else
-           VM_IMAGE=1
-       fi
-      ;;
-      *-zvm)
-        VM_TYPE="zvm"
-       shift
-      ;;
-      --lxc)
-       VM_TYPE=${PARAM##*-}
-      ;;
-      --vm-type)
-       needarg
-       VM_TYPE="$ARG"
-       case "$VM_TYPE" in
-            zvm) ;;
-            ec2)
-               test -z "$VM_IMAGE" && VM_IMAGE=1
-                . /etc/profile.d/ec2.sh
-                EC2_INSTANCE_ID=`ec2-instance-id`
-                BUILD_EC2_ZONE=`ec2-meta-data placement/availability-zone`
-                BUILD_EC2_REGION=${BUILD_EC2_ZONE%?}
-               ;;
-           xen|kvm|uml|qemu|lxc|emulator|openstack)
-               test -z "$VM_IMAGE" && VM_IMAGE=1
-               ;;
-           none|chroot) VM_TYPE='' ;;
-           *)
-               echo "VM $VM_TYPE not supported"
-               cleanup_and_exit
-           ;;
-       esac
-       shift
-      ;;
-      --vm-worker)
-        needarg
-        VM_WORKER="$ARG"
-        shift
-      ;;
-      --vm-worker-nr)
-        needarg
-        zvm_worker_nr="$ARG"
-        shift
-      ;;
-      --vm-server|--vm-region)
-       needarg
-       VM_SERVER="$ARG"
-       shift
-      ;;
-      --vm-volumes)
-       needarg
-       VM_VOLUME_NAME="$ARG"
-       shift
-       needarg
-       VM_VOLUME_SWAP="$ARG2"
-       shift
-      ;;
-      --vm-disk)
-       needarg
-       VM_IMAGE="$ARG"
-       shift
-      ;;
-      *-xenswap|*-swap)
-       needarg
-       VM_SWAP="$ARG"
-       shift
-      ;;
-      *-xenmemory|*-memory)
-       needarg
-       MEMSIZE="$ARG"
-       shift
-      ;;
-      *-vm-kernel)
-       needarg
-       VM_KERNEL="$ARG"
-       shift
-      ;;
-      *-vm-initrd)
-       needarg
-       VM_INITRD="$ARG"
-       shift
-      ;;
-      *-vmdisk-rootsize|--vm-disk-size)
-       needarg
-       VMDISK_ROOTSIZE="$ARG"
-       shift
-      ;;
-      *-vmdisk-swapsize|--vm-swap-size)
-       needarg
-       VMDISK_SWAPSIZE="$ARG"
-       shift
-      ;;
-      *-vmdisk-filesystem|--vm-disk-filesystem)
-       needarg
-       VMDISK_FILESYSTEM="$ARG"
-       shift
-      ;;
-      *-vmdisk-mount-options|--vm-disk-mount-options)
-       needarg
-        # options needs to be quoted to handle argument which might start with "-o ..."
-       VMDISK_MOUNT_OPTIONS=$(echo $ARG | sed 's/^\"\(.*\)\"$/\1/g')
-       shift
-      ;;
-      *-vmdisk-clean)
-       # delete old root/swap to get rid of the old blocks
-        VMDISK_CLEAN=true
-      ;;
-      *-rpmlist)
-       needarg
-       RPMLIST="--rpmlist $ARG"
-       BUILD_RPMS=
-       shift
-      ;;
-      *-hugetlbfs)
-        HUGETLBFSPATH="$ARG"
-       shift
-      ;;
-      *-release)
+      -release)
        needarg
        RELEASE="$ARG"
        shift
       ;;
-      *-logfile)
+      -logfile)
        needarg
        LOGFILE="$ARG"
        shift
       ;;
-      *-reason)
+      -reason)
        needarg
        REASON="$ARG"
        shift
       ;;
-      *-norootforbuild)
+      -norootforbuild)
        NOROOTFORBUILD=true
       ;;
-      *-stage)
-       needarg
-       BUILD_RPM_BUILD_STAGE="$ARG"
-       shift
-      ;;
-      *-short-circuit)
+      -short-circuit)
         SHORT_CIRCUIT=true
       ;;
-      *-no-topdir-cleanup)
+      -no-topdir-cleanup)
         NO_TOPDIR_CLEANUP=true
       ;;
-      *-useusedforbuild)
+      -useusedforbuild)
        USEUSEDFORBUILD="--useusedforbuild"
       ;;
-      *-configdir)
+      -configdir)
         needarg
        CONFIG_DIR="$ARG"
         shift
       ;;
-      *-list*state)
+      -list*state)
        LIST_STATE=true
       ;;
-      --define|--with|--without)
+      -define|-with|-without)
        needarg
-       definesnstuff[${#definesnstuff[@]}]="$PARAM";
-       definesnstuff[${#definesnstuff[@]}]="$ARG";
+        PARAM="-${PARAM/#--/-}"
+       definesnstuff[${#definesnstuff[@]}]="$PARAM"
+       definesnstuff[${#definesnstuff[@]}]="$ARG"
        shift
       ;;
-      --repository|--repo)
+      -repository|-repo)
        needarg
-       repos[${#repos[@]}]="$PARAM";
-       repos[${#repos[@]}]="$ARG";
+       repos[${#repos[@]}]="--repository"
+       repos[${#repos[@]}]="$ARG"
        shift
       ;;
-      --icecream)
+      -icecream)
        needarg
        icecream="$ARG"
-       if [ "$icecream" -gt 0 ]; then
-               BUILD_JOBS="$ARG"
-       fi
+       test "$icecream" -gt 0 && BUILD_JOBS="$ARG"
        shift
       ;;
-      --ccache)
-       ccache=1
+      -ccache)
+       CCACHE=true
       ;;
-      --statistics)
-       statistics=1
+      -statistics)
+       DO_STATISTICS=1
       ;;
-      --debug)
+      -debug)
        BUILD_DEBUG=1
       ;;
-      --incarnation)
+      -incarnation)
        needarg
        INCARNATION=$ARG
        shift
       ;;
-      --disturl)
+      -disturl)
        needarg
        DISTURL=$ARG
        shift
       ;;
-      --linksources)
+      -linksources)
        LINKSOURCES=true
       ;;
-      ----noarg)
-       echo "$ARG does not take an argument"
-       cleanup_and_exit
-      ;;
-      *-changelog)
+      -changelog)
        CHANGELOG=true
       ;;
-      --overlay)
+      -overlay)
        needarg
        OVERLAY=$ARG
        shift
       ;;
-      --rsync-src)
+      -rsync-src)
        needarg
        RSYNCSRC=$ARG
        shift
       ;;
-      --rsync-dest)
+      -rsync-dest)
        needarg
        RSYNCDEST=$ARG
        shift
       ;;
-      --uid)
+      -uid)
        needarg
        ABUILD_ID="$ARG"
-       if test -n "${ABUILD_ID//[0-9:]/}"; then
+       if test -n "${ABUILD_ID//[0-9:]/}" ; then
            echo "--uid argument must be uid:gid"
            cleanup_and_exit
        fi
@@ -1479,353 +903,77 @@ while test -n "$1"; do
        ABUILD_GID=${ABUILD_ID#*:}
        shift
       ;;
-      --shell)
-         shell=1
-         shift
+      -rpmlist)
+       needarg
+       RPMLIST="--rpmlist $ARG"
+       BUILD_RPMS=
+       shift
+      ;;  
+      -shell)
+       RUN_SHELL=1
+       shift
       ;;
-      --signdummy)
+      -signdummy)
        SIGNDUMMY=1
       ;;
+      -nosignature)
+       DLNOSIGNATURE="--nosignature"
+      ;;
+      ---noarg)
+       echo "$ARG does not take an argument"
+       cleanup_and_exit
+      ;;
       -*)
-       echo Unknown Option "$PARAM". Exit.
-       cleanup_and_exit 1
+       if vm_parse_options "$@" ; then
+           set -- "${nextargs[@]}"
+       elif recipe_parse_options "$@" ; then
+           set -- "${nextargs[@]}"
+       else
+           echo "Unknown option '$PARAM'. Exit."
+           cleanup_and_exit 1
+       fi
       ;;
       *)
-       SPECFILES[${#SPECFILES[@]}]="$PARAM";
+       RECIPEFILES[${#RECIPEFILES[@]}]="$PARAM"
       ;;
     esac
 done
 
-check_for_ppc
-check_for_arm
-
 if [ "$SHORT_CIRCUIT" = true -a -z "$BUILD_RPM_BUILD_STAGE" ]; then
     echo "--short-circuit needs a stage (use --stage)"
     cleanup_and_exit 1
 fi
 
-if test "$VM_TYPE" = "lxc"; then
-    VM_IMAGE=''
-    VM_SWAP=''
-fi
-
-if test "$VM_TYPE" = "zvm"; then
-    VM_IMAGE='/dev/dasda1'
-    VM_SWAP='/dev/dasdb1'
-fi
-
-if test "$VM_TYPE" = "ec2"; then
-    # We can not use bash hashes because old bash does not support it
-    # This is always the x86_64 loader, we use also by default the
-    # local x86_64 kernel, which should be able to run a 32bit system
-    if [ "$BUILD_EC2_ZONE" = "us-east-1" ]; then
-        BUILD_EC2_AKI="aki-88aa75e1"
-    elif [ "$BUILD_EC2_ZONE" = "us-west-1" ]; then
-        BUILD_EC2_AKI="aki-f77e26b2"
-    elif [ "$BUILD_EC2_ZONE" = "us-west-2" ]; then
-        BUILD_EC2_AKI="aki-fc37bacc"
-    elif [ "$BUILD_EC2_ZONE" = "eu-west-1" ]; then
-        BUILD_EC2_AKI="aki-71665e05"
-    elif [ "$BUILD_EC2_ZONE" = "ap-southeast-1" ]; then
-        BUILD_EC2_AKI="aki-fe1354ac"
-    elif [ "$BUILD_EC2_ZONE" = "ap-southeast-2" ]; then
-        BUILD_EC2_AKI="aki-3f990e05"
-    elif [ "$BUILD_EC2_ZONE" = "ap-northeast-1" ]; then
-        BUILD_EC2_AKI="aki-44992845"
-    elif [ "$BUILD_EC2_ZONE" = "sa-east-1" ]; then
-        BUILD_EC2_AKI="aki-c48f51d9"
-    elif [ "$BUILD_EC2_ZONE" = "us-gov-west-1" ]; then
-        BUILD_EC2_AKI="aki-79a4c05a"
-    else
-        echo "Unknown Amazon EC2 Zone: $BUILD_EC2_ZONE"
-        exit 1
-    fi
-fi
-
-if test "$VMDISK_MOUNT_OPTIONS" = __default; then
-    if test "$VMDISK_FILESYSTEM" = reiserfs ; then
-       VMDISK_MOUNT_OPTIONS='-o data=writeback,commit=150,noatime'
-    elif test "$VMDISK_FILESYSTEM" = btrfs ; then
-        VMDISK_MOUNT_OPTIONS='-o nobarrier,noatime'
-    elif test "$VMDISK_FILESYSTEM" = "ext4" ; then
-       VMDISK_MOUNT_OPTIONS='-o noatime'
-    elif test "$VMDISK_FILESYSTEM" = "ext3" ; then
-       VMDISK_MOUNT_OPTIONS='-o data=writeback,nobarrier,commit=150,noatime'
-    elif test "$VMDISK_FILESYSTEM" = "ext2" ; then
-       VMDISK_MOUNT_OPTIONS='-o noacl,noatime'
-    elif test "$VMDISK_FILESYSTEM" = "xfs" ; then
-       VMDISK_MOUNT_OPTIONS='-o noatime'
-    else
-       VMDISK_MOUNT_OPTIONS='-o noatime'
-    fi
-fi
-
 if test -n "$KILL" ; then
     test -z "$SRCDIR" || usage
     if test -n "$VM_IMAGE" -a -n "$VM_SWAP" -a -n "$VM_TYPE"; then
        # mark job as failed so that we don't extract packages
-       if test "$VM_TYPE" != "zvm"; then
+       if test "$VM_TYPE" != zvm ; then
            echo -n "BUILDSTATUS1" >"$VM_SWAP"
         fi
     fi
     (set -C; > "$BUILD_ROOT/exit" 2>/dev/null || true)
-    if test "$VM_TYPE" = 'lxc'; then
-       LXCID=${BUILD_ROOT##*/}
-       lxc-stop -n "$LXCID" || true
-       lxc-destroy -n "$LXCID"
-    elif test -z "$VM_IMAGE" ; then
+    if test -n "$VM_TYPE" ; then
+        vm_kill
+    else
        if ! $BUILD_DIR/killchroot -s 9 $BUILD_ROOT ; then
            echo "could not kill build in $BUILD_ROOT"
            cleanup_and_exit 1
        fi
-    elif test "$VM_TYPE" = 'xen'; then
-       XENID="${VM_IMAGE%/root}"
-       XENID="${XENID%/tmpfs}"
-       XENID="${XENID##*/}"
-       XENID="${XENID#root_}"
-       if xm list "build_$XENID" >/dev/null 2>&1 ; then
-           if ! xm destroy "build_$XENID" ; then
-               echo "could not kill xen build $XENID"
-               cleanup_and_exit 1
-           fi
-       fi
-    elif test "$VM_TYPE" = 'zvm'; then
-       if vmcp q "$VM_WORKER" > /dev/null 2>&1 ; then
-            if ! zvm_cp destroy $VM_WORKER ; then
-               echo "could not kill zvm worker $VM_WORKER"
-               cleanup_and_exit 1
-            fi
-        fi
-    elif test "$VM_TYPE" = 'ec2'; then
-       if ec2-describe-instance-status "$VM_BUILD_INSTANCE" --region $BUILD_EC2_REGION >/dev/null 2>&1 ; then
-           if ec2-terminate-instances "$VM_BUILD_INSTANCE" >/dev/null 2>&1 ; then
-               echo "could not kill EC2 instance $VM_BUILD_INSTANCE"
-               cleanup_and_exit 1
-           fi
-       fi
-    elif test "$VM_TYPE" = 'openstack'; then
-       if nova show "$VM_VOLUME_NAME" >/dev/null 2>&1 ; then
-           if ! nova delete "$VM_VOLUME_NAME" ; then
-               echo "could not kill openstack vm build $VM_VOLUME_NAME"
-               cleanup_and_exit 1
-           fi
-       fi
-    elif test -n "$VM_TYPE"; then
-       if ! fuser -k -TERM "$VM_IMAGE"; then
-           echo "could not kill build in $VM_IMAGE"
-           cleanup_and_exit 1
-       fi
-    else
-       echo "don't know how to kill this build job"
-       cleanup_and_exit 1
     fi
     cleanup_and_exit 0
 fi
 
-if [ "$VM_TYPE" = 'xen' -a -z "$RUNNING_IN_VM" ]; then
-    # XXX: merge with kvm path?
-    if [ -n "$VM_KERNEL" ]; then
-       vm_kernel="$VM_KERNEL"
-    elif [ -e "/boot/vmlinuz-xen" ]; then
-       vm_kernel="/boot/vmlinuz-xen"
-    fi
-    if [ -n "$VM_INITRD" ]; then
-       vm_initrd="$VM_INITRD"
-    elif [ -e "/boot/initrd-xen" ]; then
-       vm_initrd="/boot/initrd-xen"
-    fi
-fi
-
-if [ "$VM_TYPE" = 'zvm' -a -z "$RUNNING_IN_VM" ]; then
-    # verify settings
-    # In z/VM, this is a 4 digit hex number instead of a linux device.
-    # This is the root disk defined in user direct
-    # This number can be given with the parameter --root NR.
-    if [ -z "$VM_VOLUME_ROOT" ]; then
-        if [ -n "$BUILD_ROOT" -a ${#BUILD_ROOT} -le 4 ]; then
-            VM_VOLUME_ROOT="$BUILD_ROOT"
-        else
-            VM_VOLUME_ROOT="0150"
-        fi
-    fi
-    # In z/VM, this is a 4 digit hex number instead of a linux device.
-    # This is the swap disk defined in user direct
-    # This number can be given with the parameter --swap NR.
-    if [ -z "$VM_VOLUME_SWAP" ]; then
-        if [ -n "$VM_SWAP" -a ${#VM_SWAP} -le 4 ]; then
-            VM_VOLUME_SWAP="$VM_SWAP"
-        else
-            VM_VOLUME_SWAP="0250"
-        fi
-    fi
-    # z/VM guest name that is already defined in z/VM
-    if [ -z "$VM_WORKER" ]; then
-        echo "ERROR: No z/VM worker id specified"
-       cleanup_and_exit 3
-    fi
-    if [ -z "$zvm_worker_nr" ]; then
-        echo "ERROR: No z/VM worker number specified"
-        cleanup_and_exit 3
-    fi
-    # need the name for a kernel in zvm
-    if [ -n "$VM_KERNEL" ]; then
-        vm_kernel="$VM_KERNEL"
-    elif [ -e "/boot/vmlinux.gz" ]; then
-        vm_kernel="/boot/vmlinux.gz"
-    else
-        echo "ERROR: No z/VM kernel specified"
-       cleanup_and_exit 3
-    fi
-    # need the name for an initrd in zvm
-    # this normally will not be the local initrd
-    if [ -n "$VM_INITRD" ]; then
-        vm_initrd="$VM_INITRD"
-    else
-        echo "ERROR: No z/VM initrd specified"
-       cleanup_and_exit 3
-    fi
-fi
-
-if [ "$VM_TYPE" = 'ec2' -a -z "$RUNNING_IN_VM" ]; then
-    # verify settings
-    if [ -z "$AWS_ACCESS_KEY" -o -z "$AWS_ACCESS_KEY" ]; then
-       echo "ERROR:No amazon EC2 environment set. Set AWS_ACCESS_KEY and AWS_SECRET_KEY."
-       cleanup_and_exit 3
-    fi
-    if [ -z "$BUILD_EC2_AKI"  ]; then
-       echo "ERROR: No image refering to kernel and ramdisk is defined in BUILD_EC2_AKI env."
-       cleanup_and_exit 3
-    fi
-    if [ -z "$VM_VOLUME_NAME" ]; then
-       echo "ERROR: No worker root VM volume name specified."
-       cleanup_and_exit 3
-    fi
-    if [ -z "$VM_VOLUME_SWAP" ]; then
-       echo "ERROR: No worker swap VM volume name specified."
-       cleanup_and_exit 3
-    fi
-
-    # go
-    VM_IMAGE=`cloud_volume_attach "$VM_SERVER" "$VM_VOLUME_NAME" "$VM_IMAGE"`
-    [ "${VM_IMAGE:0:5}" == "/dev/" ] || cleanup_and_exit 3
-fi
-
-if [ "$VM_TYPE" = 'openstack' -a -z "$RUNNING_IN_VM" ]; then
-    # verify settings
-    if [ -z "$OS_AUTH_URL" ]; then
-       echo "ERROR:No openstack environment set. This vm-type works only inside of an openstack VM."
-       cleanup_and_exit 3
-    fi
-    if [ -z "$OBS_OPENSTACK_KERNEL_IMAGE_ID" ]; then
-       echo "ERROR: No image refering to kernel and ramdisk is defined in OBS_OPENSTACK_KERNEL_IMAGE_ID env."
-       cleanup_and_exit 3
-    fi
-    if [ -z "$VM_VOLUME_NAME" ]; then
-       echo "ERROR: No worker root VM volume name specified."
-       cleanup_and_exit 3
-    fi
-    if [ -z "$VM_VOLUME_SWAP" ]; then
-       echo "ERROR: No worker swap VM volume name specified."
-       cleanup_and_exit 3
-    fi
-    if [ -z "$VM_SERVER" ]; then
-       echo "ERROR: No VM server nod name specified (usually this instance)."
-       cleanup_and_exit 3
-    fi
-
-    # go
-    VM_IMAGE=`cloud_volume_attach "$VM_SERVER" "$VM_VOLUME_NAME" "$VM_IMAGE"`
-    [ "${VM_IMAGE:0:5}" == "/dev/" ] || cleanup_and_exit 3
-fi
-
-if [ "$VM_TYPE" = 'kvm' -a -z "$RUNNING_IN_VM" ]; then
-    if [ ! -r /dev/kvm -o ! -x "$kvm_bin" ]; then
-       echo "host doesn't support kvm"
-       echo "either the kvm kernel-module is not loaded or kvm is not installed or hardware virtualization is deactivated in the BIOS."
-       cleanup_and_exit 3
-    fi
-    qemu_bin="$kvm_bin"
-    if [ -n "$VM_KERNEL" ]; then
-       vm_kernel="$VM_KERNEL"
-    fi
-
-    # check if a SUSE system with virtio initrd is running
-    if [ -z "$VM_INITRD" -a -e /etc/sysconfig/kernel ]; then
-       a=$( source /etc/sysconfig/kernel; echo $INITRD_MODULES )
-       have_virtio_pci=""
-       have_virtio_blk=""
-       for i in $a; do
-          [ "$i" == "virtio_pci" ] && have_virtio_pci="1"
-          [ "$i" == "virtio_blk" ] && have_virtio_blk="1"
-       done
-       [ -n "$have_virtio_pci" -a -n "$have_virtio_blk" ] && VM_INITRD="/boot/initrd"
-    fi
-
-    if [ -n "$VM_INITRD" ]; then
-       vm_initrd="$VM_INITRD"
-       kvm_virtio=1
-    elif [ -e "${vm_initrd}-build" ]; then
-       vm_initrd="${vm_initrd}-build"
-       kvm_virtio=1
-    else
-       if [ -L "$vm_initrd" ]; then
-           vm_initrd=`readlink -f "$vm_initrd"` || cleanup_and_exit 3
-       fi
-       vm_initrd_virtio="${vm_initrd}-virtio"
-
-       if [ ! -e ${vm_initrd_virtio} -o $vm_kernel -nt ${vm_initrd_virtio} ]; then
-           mkinitrd_virtio_cmd=(env rootfstype="$VMDISK_FILESYSTEM" \
-                   mkinitrd -d /dev/null \
-                   -m "ext3 ext4 btrfs reiserfs binfmt_misc virtio_pci virtio_blk" \
-                   -k $vm_kernel \
-                   -i ${vm_initrd_virtio})
-           if [ ! -w /root -o -n "$RPMLIST" ]; then
-               echo "No initrd that provides virtio support found. virtio accelleration disabled."
-               echo "Run the following command as root to enable virtio:"
-               shellquote "${mkinitrd_virtio_cmd[@]}"
-               echo
-           elif /sbin/modinfo virtio_pci >/dev/null 2>&1; then
-               echo "creating $vm_initrd_virtio"
-               "${mkinitrd_virtio_cmd[@]}" || cleanup_and_exit 1
-               kvm_virtio=1
-               vm_initrd="${vm_initrd_virtio}"
-           fi
-       else
-           kvm_virtio=1
-           vm_initrd="${vm_initrd_virtio}"
-       fi
-    fi
-
-    case $HOST_ARCH in
-        power7|armv7l) kvm_virtio=1;;
-        ppc970) kvm_virtio=;;
-    esac
-
-    if [ "$kvm_virtio" = 1 ]; then
-       VM_SWAPDEV=/dev/vdb
-       qemu_rootdev=/dev/vda
-    else
-       VM_SWAPDEV=/dev/sdb
-       qemu_rootdev=/dev/sda
-    fi
-fi
-
-if [ "$VM_TYPE" = 'openstack' ]; then
-    VM_SWAPDEV=/dev/vdb
-    qemu_rootdev=/dev/vda
-fi
-
-if [ "$VM_TYPE" = 'qemu' ]; then
-    VM_SWAPDEV=/dev/sdb
-    qemu_rootdev=/dev/sda
+if test -n "$CLEAN_BUILD" ; then
+    DO_INIT=true
 fi
 
-if [ "$VM_TYPE" = 'uml' ]; then
-    VM_SWAPDEV=/dev/ubdb
+if test -n "$VM_TYPE" -a -z "$RUNNING_IN_VM" ; then
+    vm_verify_options
 fi
 
-if [ -z "$RPMLIST" -a -z "$RUNNING_IN_VM" ]; then
-    if [ -z "$repos" -a -z "$BUILD_RPMS" ]; then
+if test -z "$RPMLIST" -a -z "$RUNNING_IN_VM" ; then
+    if test -z "$repos" -a -z "$BUILD_RPMS" ; then
        repos=(--repository 'zypp://')
     fi
 else
@@ -1834,159 +982,57 @@ fi
 
 set_build_arch
 
-if [ -n "$CLEAN_BUILD" ]; then
-    DO_INIT=true
-fi
-
-find_spec_files
+expand_recipe_directories
 
 if test -n "$LIST_STATE" ; then
     BUILD_ROOT=`mktemp -d /var/tmp/build-list-state-XXXXXX`
     test -d "$BUILD_ROOT" || cleanup_and_exit 3
-    SPECFILE=$SPECFILES # only one specified anyways
-    if test "$SPECFILE" != "${SPECFILE%.src.rpm}" ; then
-       rm -rf "$BUILD_ROOT/usr/src/packages"
-       mkdir -p $BUILD_ROOT/usr/src/packages/SOURCES $BUILD_ROOT/usr/src/packages/SPECS
-       rpm -i --nodigest --nosignature --root $BUILD_ROOT $SPECFILE || {
-          echo "could not install $SPECFILE." 2>&1
-          rm -rf "$BUILD_ROOT"
-          cleanup_and_exit 3
-       }
-       for SPECFILE in $BUILD_ROOT/usr/src/packages/SPECS/*.spec ; do : ; done
+    RECIPEFILE=$RECIPEFILES # only one specified anyways
+    if test "$RECIPEFILE" != "${RECIPEFILE%.src.rpm}" ; then
+       MYSRCDIR="$BUILD_ROOT/usr/src/packages/SOURCES"
+       recipe_unpack_srcrpm
+       RECIPEFILE="$MYSRCDIR/$RECIPEFILE"
     fi
-    init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --list-state "${definesnstuff[@]}" "${repos[@]}" $USEUSEDFORBUILD $SPECFILE $BUILD_EXTRA_PACKS
+    init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --list-state "${definesnstuff[@]}" "${repos[@]}" $DLNOSIGNATURE $KEEP_PACKS $USEUSEDFORBUILD $RECIPEFILE $BUILD_EXTRA_PACKS
     ERR=$?
     rm -rf "$BUILD_ROOT"
     cleanup_and_exit $ERR
 fi
 
-# z/VM:
-# 1. make sure that no buildjob exists anymore by doing an ipl of cms
-# 2. detach the root device from the worker
-# 3. link the device to the controlling guest
-#    -> Need a uniq worker id to calculate a uniq device address for linking
-#    -> VM_IMAGE is the resulting block device
-if [ "$VM_TYPE" = 'zvm' ]; then
-    if [ ! "$0" = "/.build/build" ] ; then
-       echo "in controlling guest"
-        zvm_cp worker_init $VM_WORKER $VM_VOLUME_ROOT $VM_VOLUME_SWAP $zvm_worker_nr
-        zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT
-        zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP
-        VM_IMAGE=$(zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_ROOT $zvm_mult_pass $zvm_worker_nr )
-        VM_SWAP=$(zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_SWAP $zvm_mult_pass $zvm_worker_nr )
-        if [ ! "${VM_IMAGE}" = "dasd${VM_IMAGE#dasd}" -o ! "${VM_SWAP}" = "dasd${VM_SWAP#dasd}" ]; then
-            echo "did not get a real device for VM_IMAGES: $VM_IMAGE $VM_SWAP"
-            cleanup_and_exit 3
-        else 
-            VM_IMAGE="/dev/"${VM_IMAGE}
-           VM_SWAP="/dev/"${VM_SWAP}
-        fi
-    fi
-fi
-
-echo "VM_IMAGE: $VM_IMAGE, VM_SWAP: $VM_SWAP"
-
-# doing setup
-if test -z "$RUNNING_IN_VM" ; then
-    if test -n "$VM_IMAGE" ; then
-       if test "$VM_IMAGE" = 1 ; then
-           VM_IMAGE="$BUILD_ROOT.img"
-           echo "using $VM_IMAGE as vm image"
-           if test -z "$VM_SWAP" -a "$VM_TYPE" != "emulator"; then
-               VM_SWAP="$BUILD_ROOT.swap"
-               echo "using $VM_SWAP as vm swap"
-           fi
-       fi
-       if [ "$VM_TYPE" = 'xen' ]; then
-           # this should not be needed, but sometimes a xen instance got lost
-           XENID="${VM_IMAGE%/root}"
-           XENID="${XENID%/tmpfs}"
-           XENID="${XENID##*/}"
-           XENID="${XENID#root_}"
-           xm destroy "build_$XENID" >/dev/null 2>&1
-       fi
-       if test -n "$VMDISK_CLEAN" ; then
-           # delete old root/swap to get rid of the old blocks
-           if test -f "$VM_IMAGE" ; then
-               echo "Deleting old $VM_IMAGE"
-               rm -rf "$VM_IMAGE"
-           fi
-           if test -n "$VM_SWAP" -a -f "$VM_SWAP" ; then
-               echo "Deleting old $VM_SWAP"
-               rm -rf "$VM_SWAP"
-           fi
-       fi
-       if test ! -e "$VM_IMAGE"; then
-           vm_img_create "$VM_IMAGE" "$VMDISK_ROOTSIZE"
-           if test -z "$CLEAN_BUILD" ; then
-               vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE"
-           fi
-       fi
-       if test -n "$VM_SWAP" -a ! -e "$VM_SWAP" -a ! -b "$VM_SWAP"; then
-           vm_img_create "$VM_SWAP" "$VMDISK_SWAPSIZE"
-       fi
-       if test ! -e "$VM_IMAGE" ; then
-           echo "you need to create $VM_IMAGE first"
-           cleanup_and_exit 3
-       fi
-       if test -n "$CLEAN_BUILD" ; then
-           vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE" || cleanup_and_exit 3
-       fi
-       mkdir_build_root
-       if [ -w /root ]; then
-            if [ -b $VM_IMAGE ]; then
-                # mount device directly
-               mount $VMDISK_MOUNT_OPTIONS $VM_IMAGE $BUILD_ROOT || cleanup_and_exit 3
-           else
-               mount ${VMDISK_MOUNT_OPTIONS},loop $VM_IMAGE $BUILD_ROOT || cleanup_and_exit 3
-            fi
-       else
-           if ! mount $BUILD_ROOT; then
-               echo "mounting the build root failed. An fstab entry is probably missing or incorrect."
-               echo "/etc/fstab should contain an entry like this:"
-               echo "$VM_IMAGE $BUILD_ROOT auto noauto,user,loop 0 0"
-               cleanup_and_exit 3
-           fi
-       fi
-    else
-       test -w /root || become_root_or_fail
-    fi
-    if test -n "$VM_SWAP" ; then
-       dd if=/dev/zero of="$VM_SWAP" bs=1024 count=1 conv=notrunc 2>/dev/null
-       echo "mkswap $VM_SWAP"
-       mkswap "$VM_SWAP"
-        [ "$VM_TYPE" = 'openstack' ] && openstack_volume_detach "$VM_SERVER" "$VM_VOLUME_SWAP"
-    fi
+# do vm setup if needed
+if test -z "$RUNNING_IN_VM" -a -n "$VM_TYPE" -a -n "$VM_IMAGE" ; then
+    vm_setup
 fi
 
 mkdir_build_root
 hide_passwords
 
-if [ "$BUILD_ROOT" = / ]; then
+if test "$BUILD_ROOT" = / ; then
     browner="$(stat -c %u /)"
 fi
 
 rm -f $BUILD_ROOT/exit
 
-if [ -w /root ]; then
+if test -w /root ; then
     mkdir -p $BUILD_ROOT/proc
+    mkdir -p $BUILD_ROOT/sys
     mkdir -p $BUILD_ROOT/dev/pts
     mount -n -tproc none $BUILD_ROOT/proc || true
     mount -n -tdevpts -omode=0620,gid=5 none $BUILD_ROOT/dev/pts
 fi
 
-if test -z "$VM_IMAGE" -a -z "$LOGFILE"; then
+if test -z "$VM_IMAGE" -a -z "$LOGFILE" ; then
     LOGFILE="$BUILD_ROOT/.build.log"
 fi
 
-if test -n "$LOGFILE" -a -z "$shell" ; then
-    echo  logging output to $LOGFILE...
+if test -n "$LOGFILE" -a -z "$RUN_SHELL" ; then
+    echo "logging output to $LOGFILE..."
     rm -f $LOGFILE
     touch $LOGFILE
     # set start time, to be substracted for build log timestamps
     STARTTIME=`perl -e 'print time()'`
 
-    if [ -n "$RUNNING_IN_VM" ]; then
+    if test -n "$RUNNING_IN_VM" ; then
         # no additional timestamps in inner vm build system
        exec 1> >(exec -a 'build logging' tee -a $LOGFILE) 2>&1
     elif test -n "$VM_IMAGE" ; then
@@ -2005,7 +1051,7 @@ setmemorylimit
 #
 test -z "$HOST" && HOST=`hostname`
 
-if [ -z "$RUNNING_IN_VM" ]; then
+if test -z "$RUNNING_IN_VM" ; then
     echo Using BUILD_ROOT=$BUILD_ROOT
     test -n "$BUILD_RPMS" && echo Using BUILD_RPMS=$BUILD_RPMS
     echo Using BUILD_ARCH=$BUILD_ARCH
@@ -2016,29 +1062,16 @@ fi
 test "$BUILD_ARCH" = all && BUILD_ARCH=
 BUILD_USER_ABUILD_USED=
 
-for SPECFILE in "${SPECFILES[@]}" ; do
+for RECIPEFILE in "${RECIPEFILES[@]}" ; do
 
-    SRCDIR="${SPECFILE%/*}"
-    SPECFILE="${SPECFILE##*/}"
-
-    BUILDTYPE=
-    case $SPECFILE in
-      *.spec|*.src.rpm) BUILDTYPE=spec ;;
-      *.dsc) BUILDTYPE=dsc ;;
-      *.kiwi) BUILDTYPE=kiwi ;;
-      PKGBUILD) BUILDTYPE=arch ;;
-      _preinstallimage) BUILDTYPE=preinstallimage ;;
-    esac
-    if test -z "$BUILDTYPE" ; then
-       echo "don't know how to build $SPECFILE"
-       cleanup_and_exit 1
-    fi
+    SRCDIR="${RECIPEFILE%/*}"
+    RECIPEFILE="${RECIPEFILE##*/}"
 
-    cd "$SRCDIR"
+    recipe_set_buildtype
 
-    if [ -z "$RUNNING_IN_VM" ]; then
+    if test -z "$RUNNING_IN_VM" ; then
        echo
-       echo "$HOST started \"build $SPECFILE\" at `date --utc`."
+       echo "$HOST started \"build $RECIPEFILE\" at `date --utc`."
        echo
        test -n "$REASON" && echo "$REASON"
        echo
@@ -2048,588 +1081,42 @@ for SPECFILE in "${SPECFILES[@]}" ; do
     #
     # first setup building directory...
     #
-    test -s "$SPECFILE" || {
-       echo "$SPECFILE" is empty.  This should not happen...
-       cleanup_and_exit 1
-    }
-
-    if test "$SPECFILE" != "${SPECFILE%.src.rpm}" ; then
-       echo processing src rpm $SRCDIR/$SPECFILE ...
-       MYSRCDIR=$BUILD_ROOT/.build-srcdir
-       rm -rf "$MYSRCDIR"
-       mkdir -p "$MYSRCDIR"
-       cd $MYSRCDIR || cleanup_and_exit 1
-       $BUILD_DIR/unrpm -q $SRCDIR/$SPECFILE || {
-           echo "could not install $SPECFILE."
-           cleanup_and_exit 1
-       }
-       for SPECFILE in *.spec ; do : ; done
-    else
-       MYSRCDIR="$SRCDIR"
-    fi
-
-    # FIX to work with baselibs_$PROJ etc
-    if test "$BUILDTYPE" == "dsc" -a -e ${SRCDIR}/baselibs-deb.conf ; then
-       # Set CREATE_BASELIBS if not set
-       echo "dsc build and baselibs-deb.conf present: forcing --baselibs to true"
-       CREATE_BASELIBS=true
+    cd "$SRCDIR"
+    if ! test -s "$RECIPEFILE" ; then
+        echo "$RECIPEFILE is empty.  This should not happen..."
+        cleanup_and_exit 1
     fi
+    MYSRCDIR="$SRCDIR"
 
-# Currently local osc build does not allow extra .deb packages to be
-# specified on the command line. Both init_buildsystem and expanddeps
-# need to handle .deb dependencies first
-#    if test -n "$CREATE_BASELIBS" ; then
-#        case $BUILDTYPE in
-#            spec) ;;
-#            dsc) BUILD_EXTRA_PACKS="$BUILD_EXTRA_PACKS libparse-debcontrol-perl" ;;
-#        esac
-#    fi
+    # special hack to build from a .src.rpm
+    test "$RECIPEFILE" != "${RECIPEFILE%.src.rpm}" && recipe_unpack_srcrpm
 
-    echo processing specfile $MYSRCDIR/$SPECFILE ...
+    echo "processing recipe $MYSRCDIR/$RECIPEFILE ..."
 
-    ADDITIONAL_PACKS=""
+    ADDITIONAL_PACKS=
     test -z "$BUILD_EXTRA_PACKS" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS $BUILD_EXTRA_PACKS"
     test -z "$CREATE_BASELIBS" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS build"
-    test "$ccache" = '0' || ADDITIONAL_PACKS="$ADDITIONAL_PACKS ccache"
+    test -z "$CCACHE" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS ccache"
     test "$icecream" = 0 || ADDITIONAL_PACKS="$ADDITIONAL_PACKS icecream gcc-c++"
     test -z "$DO_LINT" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS rpmlint-Factory"
-    test "$VMDISK_FILESYSTEM" = 'xfs' && ADDITIONAL_PACKS="$ADDITIONAL_PACKS libblkid1"
-    test "$VM_TYPE" = 'zvm' && ADDITIONAL_PACKS="$ADDITIONAL_PACKS udev libcap2"
+    test "$VMDISK_FILESYSTEM" = xfs && ADDITIONAL_PACKS="$ADDITIONAL_PACKS libblkid1"
+    test "$VM_TYPE" = zvm && ADDITIONAL_PACKS="$ADDITIONAL_PACKS udev libcap2"
 
+    # we need to do this before the vm is started
     if test -n "$CHANGELOG" -a -z "$RUNNING_IN_VM" ; then
        rm -f $BUILD_ROOT/.build-changelog
-       case $SPECFILE in
-         *.dsc) CFFORMAT=debian ;;
-         *) CFFORMAT=rpm ;;
+       case $RECIPEFILE in
+           *.dsc) CFFORMAT=debian ;;
+           *) CFFORMAT=rpm ;;
        esac
-       echo "running changelog2spec --target $CFFORMAT --file $MYSRCDIR/$SPECFILE"
-       if ! $BUILD_DIR/changelog2spec --target $CFFORMAT --file "$MYSRCDIR/$SPECFILE" > $BUILD_ROOT/.build-changelog ; then
+       echo "running changelog2spec --target $CFFORMAT --file $MYSRCDIR/$RECIPEFILE"
+       if ! $BUILD_DIR/changelog2spec --target $CFFORMAT --file "$MYSRCDIR/$RECIPEFILE" > $BUILD_ROOT/.build-changelog ; then
            rm -f $BUILD_ROOT/.build-changelog
        fi
     fi
 
     if test -n "$VM_TYPE" -a -z "$RUNNING_IN_VM"; then
-       rm -rf "$BUILD_ROOT/.build"
-       mkdir -p "$BUILD_ROOT/.build"
-       if test "$DO_INIT" = true ; then
-           # do first stage of init_buildsystem
-           rm -f $BUILD_ROOT/.build.success
-           set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --prepare "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $USE_SYSTEM_QEMU $KEEP_PACKS $USEUSEDFORBUILD $RPMLIST "$MYSRCDIR/$SPECFILE" $ADDITIONAL_PACKS
-           echo "$* ..."
-            start_time=`date +%s`
-           "$@" || cleanup_and_exit 1
-           check_exit
-            TIME_PREINSTALL=$(( `date +%s` - $start_time ))
-            unset start_time
-           if [ ! -w /root ]; then
-               # remove setuid bit if files belong to user to make e.g. mount work
-               find $BUILD_ROOT/{bin,sbin,usr/bin,usr/sbin} -type f -uid $UID -perm +4000 -print0 | xargs -0 --no-run-if-empty chmod -s
-           fi
-           copy_oldpackages
-       fi
-
-       # start up xen, rerun ourself
-       cp -a $BUILD_DIR/. $BUILD_ROOT/.build
-       if ! test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then
-           rm -rf "$BUILD_ROOT/.build-srcdir"
-           mkdir "$BUILD_ROOT/.build-srcdir"
-           if test "$BUILDTYPE" = kiwi ; then
-               cp -pRL "$MYSRCDIR"/* $BUILD_ROOT/.build-srcdir
-           else
-               cp -p "$MYSRCDIR"/* $BUILD_ROOT/.build-srcdir
-           fi
-           MYSRCDIR=$BUILD_ROOT/.build-srcdir
-       else
-           # cwd is at $BUILD_ROOT/.build-srcdir which we want to
-           # umount later so step aside
-           cd "$SRCDIR"
-       fi
-       Q="'\''"
-       echo "SPECFILE='${SPECFILE//"'"/$Q}'" > $BUILD_ROOT/.build/build.data
-       echo "BUILD_JOBS='${BUILD_JOBS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "BUILD_ARCH='${BUILD_ARCH//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "BUILD_RPMS='${BUILD_RPMS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       case $BUILD_DIST in
-           */*)
-               cp $BUILD_DIST $BUILD_ROOT/.build/build.dist
-               BUILD_DIST=/.build/build.dist
-               ;;
-       esac
-       echo "BUILD_DIST='${BUILD_DIST//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "RELEASE='${RELEASE//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "BUILD_DEBUG='${BUILD_DEBUG//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "SIGNDUMMY='${SIGNDUMMY//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "DO_LINT='${DO_LINT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "DO_CHECKS='${DO_CHECKS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "NOROOTFORBUILD='${NOROOTFORBUILD//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "CREATE_BASELIBS='$CREATE_BASELIBS'" >> $BUILD_ROOT/.build/build.data
-       echo "REASON='${REASON//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "CHANGELOG='${CHANGELOG//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "INCARNATION='${INCARNATION//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "DISTURL='${DISTURL//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "DO_INIT='${DO_INIT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       echo "KIWI_PARAMETERS='${KIWI_PARAMETERS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
-       # FIXME: this depends on the kernel and vm.
-       # could be hda2, sda2 for xen or hdb/sdb for qemu
-       test -n "$VM_SWAP" && echo "VM_SWAP='${VM_SWAPDEV:-/dev/hda2}'" >> $BUILD_ROOT/.build/build.data
-       test -n "$VMDISK_MOUNT_OPTIONS" && echo "VMDISK_MOUNT_OPTIONS='${VMDISK_MOUNT_OPTIONS}'" >> $BUILD_ROOT/.build/build.data
-       PERSONALITY=0
-       if test "$VM_TYPE" != 'lxc'; then
-           test -n "$PERSONALITY_SYSCALL" && PERSONALITY=`perl -e 'print syscall('$PERSONALITY_SYSCALL', 0)."\n"'`
-       fi
-       if test "$(uname -m)" = 'ppc'; then
-            # ppc kernel never tells us if a 32bit personality is active
-            PERSONALITY=8
-        fi
-       echo "PERSONALITY='$PERSONALITY'" >> $BUILD_ROOT/.build/build.data
-       echo "MYHOSTNAME='`hostname`'" >> $BUILD_ROOT/.build/build.data
-       echo -n "definesnstuff=(" >> $BUILD_ROOT/.build/build.data
-       shellquote "${definesnstuff[@]}" >> $BUILD_ROOT/.build/build.data
-       echo ")" >> $BUILD_ROOT/.build/build.data
-       echo -n "repos=(" >> $BUILD_ROOT/.build/build.data
-       shellquote "${repos[@]}" >> $BUILD_ROOT/.build/build.data
-       echo ")" >> $BUILD_ROOT/.build/build.data
-       echo "VM_TYPE='$VM_TYPE'" >> $BUILD_ROOT/.build/build.data
-       echo "shell='$shell'" >> $BUILD_ROOT/.build/build.data
-       echo "statistics='$statistics'" >> $BUILD_ROOT/.build/build.data
-        # use the rpmbuild --stage option
-        if [ ! -z $BUILD_RPM_BUILD_STAGE ]; then
-            echo "BUILD_RPM_BUILD_STAGE='-$BUILD_RPM_BUILD_STAGE'" >> $BUILD_ROOT/.build/build.data
-        fi
-        # fallback time for broken hosts
-        date '+@%s' > $BUILD_ROOT/.build/.date
-       if [ "$VM_TYPE" = 'emulator' ]; then
-            ln -sf /.build/build $BUILD_ROOT/sbin/init
-        fi
-        if [ "$VM_TYPE" = 'zvm' ]; then
-            # initrd is created in obsstoragesetup.
-            # If it is desired to use a project dependent kernel, use make_guestinitrd from zvm_functions.
-            # have to copy kernel/initrd and run zipl to be able to IPL
-            # have to set init_script before unmounting, thus doing it statically for now.
-            zvm_init_script="/.build/build"
-            mkdir -p $BUILD_ROOT/boot
-            cp $vm_kernel $vm_initrd $BUILD_ROOT/boot
-            mkdir -p $BUILD_ROOT/boot/zipl
-             # finally, install bootloader to the worker disk
-             zipl -t $BUILD_ROOT/boot/zipl -i ${BUILD_ROOT}${vm_kernel} -r ${BUILD_ROOT}${vm_initrd} \
-                --parameters "${zvm_param} init=$zvm_init_script rootfsopts=noatime"
-        fi
-       umount -n $BUILD_ROOT/proc/sys/fs/binfmt_misc 2> /dev/null || true
-       umount -n $BUILD_ROOT/proc 2> /dev/null || true
-       umount -n $BUILD_ROOT/dev/pts 2> /dev/null || true
-       umount -n $BUILD_ROOT/dev/shm 2> /dev/null || true
-       umount -n $BUILD_ROOT/mnt 2> /dev/null || true
-
-       if check_use_emulator; then
-           if [ -e $BUILD_DIR/initvm.$BUILD_HOST_ARCH -a -e "$BUILD_DIR/qemu-reg" ]; then
-                chmod 0755 "$BUILD_DIR/initvm.$BUILD_HOST_ARCH"
-                vm_init_script="/.build/initvm.$BUILD_HOST_ARCH"
-           else
-               echo "Warning: can't find initscript to register binfmts"
-           fi
-       else
-           vm_init_script="/.build/build"
-       fi
-
-       if [ "$VM_TYPE" = 'emulator' ]; then
-                # generic emulator hook. an external script is needed to define
-                # the emulator startup
-                sync
-                pushd $BUILD_DIR/emulator
-                if [ -z "$EMULATOR_SCRIPT" ]; then
-                   EMULATOR_SCRIPT="./emulator.sh"
-                elif [ "${EMULATOR_SCRIPT:0:1}" != "/" ]; then
-                   EMULATOR_SCRIPT="./$EMULATOR_SCRIPT"
-                fi
-               set -- "$EMULATOR_SCRIPT" "$VM_IMAGE"
-               echo "$@"
-               if ! "$@"; then
-                     popd
-                     echo "ERROR: The emulator return with an failure"
-                     cleanup_and_exit 3
-                fi
-                popd
-
-       fi
-
-        if [ "$VM_TYPE" = 'openstack' -o "$VM_TYPE" = 'ec2' ]; then
-            # No way to handle this via init= parameter here....
-            echo "#!/bin/sh"               >  "$BUILD_ROOT/sbin/init"
-            echo 'exec /.build/build "$@"' >> "$BUILD_ROOT/sbin/init"
-            chmod 0755 "$BUILD_ROOT/sbin/init"
-        fi
-        if [ "$VM_TYPE" = 'ec2' ]; then
-            # use the instance kernel, if no kernel got installed via preinstall
-            if ! test -e "$BUILD_ROOT/boot/vmlinuz"; then
-                cp /boot/vmlinuz-ec2 "$BUILD_ROOT/boot/vmlinuz"
-                cp /boot/initrd-ec2 "$BUILD_ROOT/boot/initrd"
-            fi
-            # install menu.lst for pv grub
-            if ! test -e "$BUILD_ROOT/boot/grub/menu.lst"; then
-                mkdir -p "$BUILD_ROOT/boot/grub"
-                echo "serial --unit=0 --speed=9600"                                                   >  "$BUILD_ROOT/boot/grub/menu.lst"
-                echo "terminal --dumb serial"                                                         >> "$BUILD_ROOT/boot/grub/menu.lst"
-                echo "default 0"                                                                      >> "$BUILD_ROOT/boot/grub/menu.lst"
-                echo "timeout 0"                                                                      >> "$BUILD_ROOT/boot/grub/menu.lst"
-                echo "hiddenmenu"                                                                     >> "$BUILD_ROOT/boot/grub/menu.lst"
-                echo ""                                                                               >> "$BUILD_ROOT/boot/grub/menu.lst"
-                echo "title default"                                                                  >> "$BUILD_ROOT/boot/grub/menu.lst"
-                echo "   root (hd0)"                                                                  >> "$BUILD_ROOT/boot/grub/menu.lst"
-                echo "   kernel /boot/vmlinuz root=/dev/sda1 xencons=xvc0 console=xvc0 splash=silent" >> "$BUILD_ROOT/boot/grub/menu.lst"
-                echo "   initrd /boot/initrd"                                                         >> "$BUILD_ROOT/boot/grub/menu.lst"
-            fi
-        fi
-       if [ -n "$VM_IMAGE" ]; then
-           check_exit
-           # needs to work otherwise we have a corrupted file system
-           umount $BUILD_ROOT || cleanup_and_exit 3
-       fi
-
-        if [ "$VM_TYPE" = 'openstack' -o "$VM_TYPE" = 'ec2' ]; then
-          cloud_volume_detach "$VM_SERVER" "$VM_VOLUME_NAME" || cleanup_and_exit 3
-        fi
-
-       if [ -n "$VM_IMAGE" -a "$VM_TYPE" = "zvm" ]; then
-          # detach the worker root and swap locally and link it in the worker
-          zvm_cp volume_detach_local $VM_VOLUME_ROOT ${zvm_worker_nr}
-          zvm_cp volume_detach_local $VM_VOLUME_SWAP ${zvm_worker_nr}
-          zvm_cp volume_attach $VM_WORKER $VM_VOLUME_ROOT
-          zvm_cp volume_attach $VM_WORKER $VM_VOLUME_SWAP
-       fi
-
-       if [ "$VM_TYPE" = 'xen' ]; then
-               XMROOT="file:$(readlink -f $VM_IMAGE)"
-               XMROOT=${XMROOT/#file:\/dev/phy:/dev}
-               XMROOT="disk=$XMROOT,hda1,w"
-               XMSWAP=
-               if test -n "$VM_SWAP" ; then
-                   XMSWAP="file:$(readlink -f $VM_SWAP)"
-                   XMSWAP=${XMSWAP/#file:\/dev/phy:/dev}
-                   XMSWAP="disk=$XMSWAP,hda2,w"
-               fi
-               XENID="${VM_IMAGE%/root}"
-               XENID="${XENID%/tmpfs}"
-               XENID="${XENID##*/}"
-               XENID="${XENID#root_}"
-
-               echo "booting XEN kernel ..."
-               if xm list "build_$XENID" >/dev/null 2>&1 ; then
-                  echo "Instance already exist, something really went wrong..."
-                  echo "Please report to your server admin, there might be multiple services running for same domain"
-                  cleanup_and_exit 3
-               fi
-               XEN_CONF_FILE=`mktemp /var/tmp/build.xen.conf-XXXXXXXXX` || cleanup_and_exit 3
-               echo "kernel = \"$vm_kernel\""                                           >  $XEN_CONF_FILE
-               echo "ramdisk = \"$vm_initrd\""                                          >> $XEN_CONF_FILE
-               echo "memory = ${MEMSIZE:-64}"                                           >> $XEN_CONF_FILE
-               echo "vcpus = $BUILD_JOBS"                                               >> $XEN_CONF_FILE
-               echo "root = \"/dev/hda1 ro\""                                           >> $XEN_CONF_FILE
-               echo "extra = \"init=/bin/bash console=ttyS0 panic=1 udev_timeout=360\"" >> $XEN_CONF_FILE
-               echo "on_poweroff = 'destroy'"                                           >> $XEN_CONF_FILE
-               echo "on_reboot = 'destroy'"                                             >> $XEN_CONF_FILE
-               echo "on_crash = 'destroy'"                                              >> $XEN_CONF_FILE
-               set -- xm create -c $XEN_CONF_FILE name="build_$XENID" $XMROOT $XMSWAP extra="quiet init="$vm_init_script" elevator=noop panic=1 console=ttyS0"
-               if test "$PERSONALITY" != 0 ; then
-                   # have to switch back to PER_LINUX to make xm work
-                   set -- linux64 "$@"
-               fi
-               echo "$@"
-               "$@" || cleanup_and_exit 3
-               rm "$XEN_CONF_FILE"
-       elif [ "$VM_TYPE" = 'uml' ]; then
-               echo "booting UML kernel ..."
-               set -- $uml_kernel initrd=$uml_initrd root=ubda init="$vm_init_script" panic=1 elevator=noop quiet ubda=$VM_IMAGE ubdb=$VM_SWAP ${MEMSIZE:+mem=$MEMSIZE}
-               echo "$@"
-               "$@"
-       elif [ "$VM_TYPE" = 'qemu' -o "$VM_TYPE" = 'kvm' ]; then
-               echo "booting $VM_TYPE ..."
-                if [ "$VM_TYPE" = 'kvm' -a -b "$VM_IMAGE" ]; then
-                  # speed optimization when using kvm with raw devices
-                 CACHE=",cache=none"
-                else
-                  # speed optimization when using kvm with raw files
-                 CACHE=",cache=unsafe"
-               fi
-
-               # we do not want to have sound inside the VMs
-               export QEMU_AUDIO_DRV=none
-
-               if [ "$kvm_virtio" = 1 ]; then
-                   qemu_args=(-drive file="$VM_IMAGE",if=virtio$CACHE -drive file="$VM_IMAGE",if=ide,index=0$CACHE)
-                   if [ -n "$VM_SWAP" ]; then
-                       qemu_args=("${qemu_args[@]}" "-drive")
-                       qemu_args=("${qemu_args[@]}" "file=$VM_SWAP,if=virtio$CACHE")
-                   fi
-                   if [ "$HOST_ARCH" = "armv7l" ]; then
-                       qemu_args=(-drive file="$VM_IMAGE",if=none,id=disk$CACHE -device virtio-blk,transport=virtio-mmio.0,drive=disk)
-                       qemu_args=("${qemu_args[@]}" "-drive")
-                       qemu_args=("${qemu_args[@]}" "file=$VM_SWAP,if=none,id=swap$CACHE")
-                       qemu_args=("${qemu_args[@]}" "-device")
-                       qemu_args=("${qemu_args[@]}" "virtio-blk,transport=virtio-mmio.1,drive=swap")
-                   fi
-               else
-                       if [ "$HOST_ARCH" = "ppc970" ];then
-                               qemu_args=( "-drive" )
-                               qemu_args=("${qemu_args[@]}" "file=$VM_IMAGE,if=scsi,cache=unsafe")
-                       else
-                               qemu_args=(-hda "$VM_IMAGE")
-                       fi
-                       if [ -n "$VM_SWAP" ]; then
-                               qemu_args=("${qemu_args[@]}" "-drive")
-                               if [ "$HOST_ARCH" = "ppc970" ];then
-                                       DISK_IF=scsi
-                               else
-                                       DISK_IF=ide
-                               fi
-                               qemu_args=("${qemu_args[@]}" "file=$VM_SWAP,if=$DISK_IF,index=1$CACHE")
-                       fi
-               fi
-               if [ -n "$BUILD_JOBS" -a "$icecream" = 0 -a -z "$BUILD_THREADS" ]; then
-                   qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS")
-               elif [ -n "$BUILD_JOBS" -a -n "$BUILD_THREADS" ]; then
-                   qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS,threads=$BUILD_THREADS")
-               fi
-               if [ "$VM_TYPE" = 'kvm' -a "$HOST_ARCH" != "armv7l" ]; then
-                       KVM_OPTIONS="$KVM_OPTIONS -cpu host"
-                       if [ -n "$HUGETLBFSPATH" ]; then
-                             KVM_OPTIONS="$KVM_OPTIONS -mem-path $HUGETLBFSPATH"
-                       fi
-               fi
-
-               set -- $qemu_bin -no-reboot -nographic -vga none -net none $KVM_OPTIONS \
-                   -kernel $vm_kernel \
-                   -initrd $vm_initrd \
-                   -append "root=$qemu_rootdev panic=1 quiet no-kvmclock nmi_watchdog=0 rw elevator=noop console=$console init=$vm_init_script" \
-                   ${MEMSIZE:+-m $MEMSIZE} \
-                   "${qemu_args[@]}"
-
-               if test "$PERSONALITY" != 0 ; then
-                   # have to switch back to PER_LINUX to make qemu work
-                   set -- linux64 "$@"
-               fi
-               echo "$@"
-               "$@"
-       elif [ "$VM_TYPE" = 'ec2' ]; then
-               echo "booting $VM_TYPE ..."
-                EC2_SNAP_root=`ec2-create-snapshot --region "$BUILD_EC2_REGION" "$VM_VOLUME_NAME" | awk '{ print $2 }'`
-                if [ "$EC2_SNAP_root" == "${EC2_SNAP_root#snap-}" ]; then
-                    echo "ERROR: Failed to create snapshot for root disk $VM_VOLUME_NAME"
-                    cleanup_and_exit 3
-                fi
-                EC2_SNAP_swap=`ec2-create-snapshot --region "$BUILD_EC2_REGION" "$VM_VOLUME_SWAP" | awk '{ print $2 }'`
-                if [ "$EC2_SNAP_swap" == "${EC2_SNAP_swap#snap-}" ]; then
-                    echo "ERROR: Failed to create snapshot for swap disk $VM_VOLUME_SWAP"
-                    ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
-                    cleanup_and_exit 3
-                fi
-                # wait for snapshots being processed
-                while true; do
-                    c=`ec2-describe-snapshots --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" "$EC2_SNAP_swap" | grep completed | wc -l`
-                    [ "$c" == "2" ] && break
-                done
-                EC2_AMI=`ec2-register --region "$BUILD_EC2_REGION" -n build-$VM_VOLUME_NAME  -a x86_64 -b "/dev/sda1=$EC2_SNAP_root::false" -b "/dev/sdb1=$EC2_SNAP_swap::false" --kernel "$BUILD_EC2_AKI" | awk '{ print $2 }'`
-                if [ "$EC2_AMI" == "${EC2_AMI#ami-}" ]; then
-                    echo "ERROR: Failed to register the AMI"
-                    ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
-                    ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap"
-                    cleanup_and_exit 3
-                fi
-                INSTANCE=`ec2-run-instances --region "$BUILD_EC2_REGION" -z "$BUILD_EC2_ZONE" -t $BUILD_EC2_TYPE --kernel "$BUILD_EC2_AKI" --instance-initiated-shutdown-behavior terminate "$EC2_AMI" | grep ^INSTANCE | awk '{ print $2 }'`
-                if [ "$INSTANCE" == "${INSTANCE#i-}" ]; then
-                    echo "ERROR: Failed to run the instance for AMI $EC2_AMI"
-                    ec2-deregister --region "$BUILD_EC2_REGION" "$EC2_AMI"
-                    ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
-                    ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap"
-                    cleanup_and_exit 3
-                fi
-                echo "Waiting for finishing the build. No log file until then on EC2 ...."
-                I=0
-                L=0
-                EC2_EXTRACT_VOLUME_root=""
-                EC2_EXTRACT_VOLUME_swap=""
-                temp_file=`mktemp`
-                while true; do
-                    ec2-describe-instances --region "$BUILD_EC2_REGION" "$INSTANCE" > $temp_file
-                    state=`grep ^INSTANCE "$temp_file"`
-                    if [ -z "$EC2_EXTRACT_VOLUME_root" ]; then
-                        EC2_EXTRACT_VOLUME_root=`grep ^BLOCKDEVICE $temp_file | grep /dev/sda1 | awk '{ print $3 }'`
-                        EC2_EXTRACT_VOLUME_swap=`grep ^BLOCKDEVICE $temp_file | grep /dev/sdb1 | awk '{ print $3 }'`
-                    fi
-                    # the column of the state is at a differen position depending on the state :/
-#                    [ "$state" == "${state/stopped/}" ] || break
-                    [ "$state" == "${state/terminated/}" ] || break
-                    I=$(( $I + 1 ))
-                    if [ $I -gt 10 ]; then
-                       echo -n .
-                       I="0"
-                       L=$(( $L + 1 ))
-                    fi
-                    if [ $L -gt 10 ]; then
-                       # dump entire console log as raw here
-                       ec2-get-console-output --region "$BUILD_EC2_REGION" -r "$INSTANCE"
-                       L="0"
-                    fi
-                    sleep 1
-                done
-                rm "$temp_file"
-                echo
-                ec2-deregister --region "$BUILD_EC2_REGION" "$EC2_AMI"
-                # snapshots get deleted after extract
-       elif [ "$VM_TYPE" = 'openstack' ]; then
-               echo "booting $VM_TYPE ..."
-                nova boot --image $OBS_OPENSTACK_KERNEL_IMAGE_ID --flavor m1.small --block_device_mapping vda=${VM_VOLUME_NAME}::$(( $VMDISK_ROOTSIZE / 1024 )):0 --block_device_mapping vdb=${VM_VOLUME_SWAP}::1:0 --poll "build-$VM_VOLUME_NAME" || cleanup_and_exit 3
-                
-#                while [ `nova show "build-$VM_VOLUME_NAME" | sed -n -e 's,|[ ]*status[ ]*|[ ]*\([^ ]*\).*,\1,p'` == "ACTIVE" ]; do
-#                  sleep 5
-#                done
-                nova console-log "build-$VM_VOLUME_NAME"
-       elif [ "$VM_TYPE" = 'lxc' ]; then
-               echo "booting $VM_TYPE ..."
-               LXCCONF="$BUILD_ROOT/.build.lxc.conf"
-               rm -f "$LXCCONF"
-               cat $BUILD_DIR/lxc.conf > "$LXCCONF"
-               cat >> "$LXCCONF" <<-EOF
-               lxc.rootfs = $BUILD_ROOT
-               EOF
-               # XXX: do this always instead of leaking the hosts' one?
-               echo "rootfs / rootfs rw 0 0" > $BUILD_ROOT/etc/mtab
-               LXCID=${BUILD_ROOT##*/}
-               lxc-destroy -n "$LXCID" >/dev/null 2>&1 || true
-               lxc-create -n "$LXCID" -f "$LXCCONF" || cleanup_and_exit 1
-               lxc-start -n "$LXCID" "$vm_init_script"
-               BUILDSTATUS="$?"
-               test "$BUILDSTATUS" != 255 || BUILDSTATUS=3
-               cleanup_and_exit "$BUILDSTATUS"
-        elif [ "$VM_TYPE" = 'zvm' ]; then
-                echo "booting $VM_TYPE ..."
-                zvm_cp ipl $VM_WORKER $VM_VOLUME_ROOT
-                # start IUCV Console
-                # IPL needs some time until IPL really starts...
-                 sleep 2
-                 # start iucv console. This blocks until build process is finished.
-                iucvconn $VM_WORKER lnxhvc0
-                # Take root and swap devices from worker
-                # This might be critical regarding timing (IUCV_CONSOLE down, but machine still running)
-                sleep 5
-                zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT
-                zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP
-                VM_IMAGE="/dev/$(zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_ROOT $zvm_mult_pass $zvm_worker_nr)"
-                VM_SWAP="/dev/$(zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_SWAP $zvm_mult_pass $zvm_worker_nr)"
-       fi
-
-       if [ "$VM_TYPE" = 'openstack' ]; then
-           VM_IMAGE=`cloud_volume_attach "$VM_SERVER" "$VM_VOLUME_NAME" "$VM_IMAGE"`
-           [ "${VM_IMAGE:0:5}" == "/dev/" ] || cleanup_and_exit 3
-           VM_SWAP=`cloud_volume_attach "$VM_SERVER" "$VM_VOLUME_SWAP" "$VM_SWAP"`
-           [ "${VM_SWAP:0:5}" == "/dev/" ] || cleanup_and_exit 3
-        fi
-       if [ "$VM_TYPE" = 'ec2' ]; then
-           VM_IMAGE=`cloud_volume_attach "$VM_SERVER" "$EC2_EXTRACT_VOLUME_root" "$VM_IMAGE"`
-           [ "${VM_IMAGE:0:5}" == "/dev/" ] || cleanup_and_exit 3
-           VM_SWAP=`cloud_volume_attach "$VM_SERVER" "$EC2_EXTRACT_VOLUME_swap" "$VM_SWAP"`
-           [ "${VM_SWAP:0:5}" == "/dev/" ] || cleanup_and_exit 3
-        fi
-
-        # Exctract build resutls from VM
-       if [ "$VM_TYPE" = 'emulator' ]; then
-            # Emulators may not offer to use a second swap space.
-            # So we just mount the filesystem.
-            # WARNING: This is not safe against attacks.
-
-           mkdir -p $BUILD_ROOT/.build.packages
-           cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1
-            mkdir -p .mount
-            mount $VM_IMAGE -o loop .mount
-            if [ -e .mount/.build.packages ]; then
-              cp -a .mount/.build.packages/* .
-            fi
-            exitcode=`cat .mount/.build/_exitcode`
-            umount .mount
-            rmdir .mount
-
-           cleanup_and_exit "$exitcode"
-
-       elif test -n "$VM_SWAP" ; then
-           BUILDSTATUS=`dd if="$VM_SWAP" bs=12 count=1 2>/dev/null`
-           case $BUILDSTATUS in
-             BUILDSTATUS[02])
-               mkdir -p $BUILD_ROOT/.build.packages
-               cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1
-               echo "build: extracting built packages..."
-               extractbuild --disk "$VM_IMAGE" --input "$VM_SWAP" --skip 512 -v || cleanup_and_exit 3
-               # create same layout as with plain chroot
-               if test "$BUILDTYPE" = spec ; then
-                   mkdir -p SRPMS
-                   for i in *src.rpm *.desktopfiles ; do
-                       test -e "$i" || continue
-                       mv "$i" SRPMS/
-                   done
-                   for i in *.rpm ; do
-                       test -e "$i" || continue
-                       arch=${i%.rpm}
-                       arch=${i%.delta}
-                       arch=${arch##*\.}
-                       mkdir -p RPMS/$arch
-                       mv "$i" RPMS/$arch/
-                   done
-               elif test "$BUILDTYPE" = dsc ; then
-                   mkdir -p DEBS
-                   find . -type f | while read i; do mv "$i" DEBS/; done
-               elif test "$BUILDTYPE" = arch ; then
-                   mkdir -p ARCHPKGS
-                   find . -type f | while read i; do mv "$i" ARCHPKGS/; done
-               elif test "$BUILDTYPE" = kiwi ; then
-                   mkdir -p KIWI
-                   find . -type f | while read i; do mv "$i" KIWI/; done
-               fi
-               for i in * ; do
-                   test -f "$i" || continue
-                   case $i in
-                       _*|.*) ;;
-                       *) mkdir -p OTHER ; mv $i OTHER/ ;;
-                   esac
-               done
-                if test "$statistics" = 1; then
-                    mkdir -p OTHER
-                    [ -e _statistics ] && mv _statistics OTHER/
-                    [ -n "$TIME_PREINSTALL" ] && echo "TIME_preinstall: $TIME_PREINSTALL"  >> OTHER/_statistics
-                    TIME_TOTAL=$(( `date +%s` - $TIME_START_TIME ))
-                    echo "TIME_total: $TIME_TOTAL"  >> OTHER/_statistics
-                fi
-               if [ "$VM_TYPE" = 'zvm' ]; then
-                   # free worker devices
-                   zvm_cp volume_detach_local $VM_VOLUME_ROOT ${zvm_worker_nr}
-                   zvm_cp volume_detach_local $VM_VOLUME_SWAP ${zvm_worker_nr}
-               fi
-               if [ "$VM_TYPE" = 'openstack' ]; then
-                    cloud_volume_detach "$VM_SERVER" "$VM_VOLUME_NAME"
-                    cloud_volume_detach "$VM_SERVER" "$VM_VOLUME_SWAP"
-                fi
-               cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS}
-               ;;
-             BUILDSTATUS*)
-               if [ "$VM_TYPE" = 'zvm' ]; then
-                   # free worker devices
-                   zvm_cp volume_detach_local $VM_VOLUME_ROOT ${zvm_worker_nr}
-                   zvm_cp volume_detach_local $VM_VOLUME_SWAP ${zvm_worker_nr}
-               fi
-               cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS}
-               ;;
-             *)
-               if [ "$VM_TYPE" = 'zvm' ]; then
-                   # free worker devices
-                   zvm_cp volume_detach_local $VM_VOLUME_ROOT ${zvm_worker_nr}
-                   zvm_cp volume_detach_local $VM_VOLUME_SWAP ${zvm_worker_nr}
-               fi
-               echo "No buildstatus set, either the base system is broken (glibc/bash/perl)"
-               echo "or the build host has a kernel or hardware problem..."
-               cleanup_and_exit 3
-               ;;
-           esac
-
-           cleanup_and_exit 1
-       fi
-
+       vm_first_stage
        cleanup_and_exit 0
     fi
 
@@ -2642,8 +1129,11 @@ for SPECFILE in "${SPECFILES[@]}" ; do
        echo "BUILD_INCARNATION=$INCARNATION" > $BUILD_ROOT/.buildenv
        CREATE_BUILD_BINARIES=
        test "$BUILDTYPE" = preinstallimage && mkdir -p $BUILD_ROOT/.preinstall_image
-       egrep '^#[       ]*needsbinariesforbuild[       ]*$' >/dev/null <$MYSRCDIR/$SPECFILE && CREATE_BUILD_BINARIES=--create-build-binaries
-       set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $USE_SYSTEM_QEMU $KEEP_PACKS $USEUSEDFORBUILD $CREATE_BUILD_BINARIES $RPMLIST "$MYSRCDIR/$SPECFILE" $ADDITIONAL_PACKS
+       egrep '^#[       ]*needsbinariesforbuild[       ]*$' >/dev/null <$MYSRCDIR/$RECIPEFILE && CREATE_BUILD_BINARIES=--create-build-binaries
+       test "$BUILDTYPE" = mock && CREATE_BUILD_BINARIES=--create-build-binaries
+       test "$BUILDTYPE" = debootstrap && CREATE_BUILD_BINARIES=--create-build-binaries
+       test "$BUILDTYPE" = livebuild && CREATE_BUILD_BINARIES=--create-build-binaries
+       set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $DLNOSIGNATURE $KEEP_PACKS $USEUSEDFORBUILD $CREATE_BUILD_BINARIES $RPMLIST "$MYSRCDIR/$RECIPEFILE" $ADDITIONAL_PACKS
        echo "$* ..."
         start_time=`date +%s`
        "$@" || cleanup_and_exit 1
@@ -2665,45 +1155,9 @@ for SPECFILE in "${SPECFILES[@]}" ; do
        copy_oldpackages
     fi
 
+    # hack to process preinstallimages early
     if test "$BUILDTYPE" = preinstallimage ; then
-       echo "creating preinstall image..."
-       test -d "$BUILD_ROOT/.preinstall_image" || cleanup_and_exit 1
-       cd $BUILD_ROOT || cleanup_and_exit 1
-       TAR="tar"
-       if test -x /usr/bin/bsdtar; then
-           TAR="/usr/bin/bsdtar --format gnutar --chroot"
-       fi
-       TOPDIRS=
-       for DIR  in .* * ; do
-         case "$DIR" in
-           .|..) continue ;;
-           .build*) continue ;;
-           .preinstallimage*) continue ;;
-           .srcfiles*) continue ;;
-           .pkgs) continue ;;
-           .rpm-cache) continue ;;
-           installed-pkg) continue ;;
-           proc|sys) continue ;;
-         esac
-         TOPDIRS="$TOPDIRS $DIR"
-        done
-       if ! $TAR -czf .preinstallimage.$$.tar.gz --one-file-system $TOPDIRS ; then
-           cleanup_and_exit 1
-       fi
-       echo "image created."
-       TOPDIR=/usr/src/packages
-       mkdir -p $BUILD_ROOT$TOPDIR/OTHER
-       rm -f $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.info
-       for PKG in $BUILD_ROOT/.preinstall_image/* ; do
-           PKG=${PKG##*/}
-           read PKG_HDRMD5 PKGID < $BUILD_ROOT/.preinstall_image/$PKG
-           test -n "$PKG_HDRMD5" || cleanup_and_exit 1
-           echo "$PKG_HDRMD5  $PKG" >> $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.info
-       done
-       mv $BUILD_ROOT/.preinstallimage.$$.tar.gz $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.tar.gz
-       rm -f $BUILD_ROOT/.build.packages
-       ln -s ${TOPDIR#/} $BUILD_ROOT/.build.packages
-       test -d "$SRCDIR" && cd "$SRCDIR"
+       recipe_build
        continue
     fi
 
@@ -2711,18 +1165,6 @@ for SPECFILE in "${SPECFILES[@]}" ; do
        read BUILD_DIST < $BUILD_ROOT/.guessed_dist
     fi
 
-    #
-    # fix rpmrc if we are compiling for i686
-    #
-    test -f $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 && mv $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 $BUILD_ROOT/usr/lib/rpm/rpmrc
-    if test -e $BUILD_ROOT/usr/lib/rpm/rpmrc -a "$BUILD_ARCH" != "${BUILD_ARCH#i686}" ; then
-       mv $BUILD_ROOT/usr/lib/rpm/rpmrc $BUILD_ROOT/usr/lib/rpm/rpmrc_i586
-       sed -e 's/^buildarchtranslate: athlon.*/buildarchtranslate: athlon: i686/' -e 's/^buildarchtranslate: i686.*/buildarchtranslate: i686: i686/' < $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 > $BUILD_ROOT/usr/lib/rpm/rpmrc
-    fi
-    if test "$DO_BUILD" = false ; then
-        cleanup_and_exit 0
-    fi
-
     #
     # install dummy sign program if needed
     #
@@ -2739,23 +1181,22 @@ for SPECFILE in "${SPECFILES[@]}" ; do
     BUILD_USER=abuild
     if test -x $BUILD_ROOT/bin/rpm ; then
        SUSE_VERSION=`chroot $BUILD_ROOT /bin/rpm --eval '%{?suse_version}' 2>/dev/null`
-       if test -n "$SUSE_VERSION" && test "$SUSE_VERSION" -le 1020 ; then
-           BUILD_USER=root
-       fi
+       test -n "$SUSE_VERSION" -a "${SUSE_VERSION:-0}" -le 1020 && BUILD_USER=root
     fi
     if test "$BUILD_USER" = abuild ; then
-       egrep '^#[       ]*needsrootforbuild[       ]*$' >/dev/null <$SPECFILE && BUILD_USER=root
+       egrep '^#[       ]*needsrootforbuild[       ]*$' >/dev/null <$RECIPEFILE && BUILD_USER=root
     else
-       egrep '^#[       ]*norootforbuild[       ]*$' >/dev/null <$SPECFILE && BUILD_USER=abuild
+       egrep '^#[       ]*norootforbuild[       ]*$' >/dev/null <$RECIPEFILE && BUILD_USER=abuild
     fi
     test -n "$NOROOTFORBUILD" && BUILD_USER=abuild
 
     # appliance builds must run as root
-    if test "$BUILDTYPE" = kiwi; then
-      imagetype=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $SPECFILE imagetype)
-      test "$imagetype" = 'product' || BUILD_USER=root
+    if test "$BUILDTYPE" = kiwi ; then
+       imagetype=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $RECIPEFILE imagetype)
+       test "$imagetype" = product || BUILD_USER=root
     fi
 
+    # fixup passwd/group
     if test $BUILD_USER = abuild ; then
        if ! egrep '^abuild:' >/dev/null <$BUILD_ROOT/etc/passwd ; then
            echo "abuild:x:${ABUILD_UID}:${ABUILD_GID}:Autobuild:/home/abuild:/bin/bash" >>$BUILD_ROOT/etc/passwd
@@ -2774,10 +1215,10 @@ for SPECFILE in "${SPECFILES[@]}" ; do
            fi
        fi
        if test -f $BUILD_ROOT/etc/shadow ; then
-           sed -e "s@^root::@root:*:@" < $BUILD_ROOT/etc/shadow > $BUILD_ROOT/etc/shadow.t && mv $BUILD_ROOT/etc/shadow.t $BUILD_ROOT/etc/shadow
+           sed -i -e "s@^root::@root:*:@" $BUILD_ROOT/etc/shadow
        fi
        if test -f $BUILD_ROOT/etc/gshadow ; then
-           sed -e "s@^root::@root:*:@" < $BUILD_ROOT/etc/gshadow > $BUILD_ROOT/etc/gshadow.t && mv $BUILD_ROOT/etc/gshadow.t $BUILD_ROOT/etc/gshadow
+           sed -i -e "s@^root::@root:*:@" $BUILD_ROOT/etc/gshadow
        fi
        BUILD_USER_ABUILD_USED=true
     else
@@ -2786,340 +1227,92 @@ for SPECFILE in "${SPECFILES[@]}" ; do
        ABUILD_GID=0
        if egrep '^abuild:' >/dev/null <$BUILD_ROOT/etc/passwd ; then
            rm -rf "$BUILD_ROOT/home/abuild"
-           egrep -v '^abuild:' <$BUILD_ROOT/etc/passwd >$BUILD_ROOT/etc/passwd.new
-           mv $BUILD_ROOT/etc/passwd.new $BUILD_ROOT/etc/passwd
-           egrep -v '^abuild:' <$BUILD_ROOT/etc/group >$BUILD_ROOT/etc/group.new
-           mv $BUILD_ROOT/etc/group.new $BUILD_ROOT/etc/group
+           sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/passwd
+           sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/group
            if test -f $BUILD_ROOT/etc/shadow ; then
-             egrep -v '^abuild:' <$BUILD_ROOT/etc/shadow >$BUILD_ROOT/etc/shadow.new
-             mv $BUILD_ROOT/etc/shadow.new $BUILD_ROOT/etc/shadow
+               sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/shadow
            fi
            if test -f $BUILD_ROOT/etc/gshadow ; then
-             egrep -v '^abuild:' <$BUILD_ROOT/etc/gshadow >$BUILD_ROOT/etc/gshadow.new
-             mv $BUILD_ROOT/etc/gshadow.new $BUILD_ROOT/etc/gshadow
+               sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/gshadow
            fi
        fi
     fi
 
-    if test "$BUILDTYPE" = spec ; then
-       TOPDIR=`chroot $BUILD_ROOT su -c "rpm --eval '%_topdir'" - $BUILD_USER`
-       if test -z "$TOPDIR"; then
-           echo "Error: TOPDIR empty"
-           cleanup_and_exit 1
-       fi
-    else
-       TOPDIR=/usr/src/packages
-       mkdir -p $BUILD_ROOT$TOPDIR
-    fi
-
-    rm -f $BUILD_ROOT/.build.packages
-    ln -s ${TOPDIR#/} $BUILD_ROOT/.build.packages
-
     mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null
     mount -n -tdevpts -omode=0620,gid=5 none $BUILD_ROOT/dev/pts 2> /dev/null
     # needed for POSIX semaphores
+    test -d $BUILD_ROOT/dev/shm || rm -f $BUILD_ROOT/dev/shm
+    mkdir -p $BUILD_ROOT/dev/shm
     mount -n -ttmpfs none $BUILD_ROOT/dev/shm 2> /dev/null
 
-    setupicecream
+    if test -n "$RUNNING_IN_VM" ; then
+       if test -x /sbin/ip ; then
+           ip addr add 127.0.0.1/8 dev lo
+           ip addr add ::1/128 dev lo
+           ip link set lo up
+       else
+           ifconfig lo 127.0.0.1 up
+           ifconfig lo add ::1/128
+       fi
+       if test -n "$MYHOSTNAME" ; then
+           hostname "$MYHOSTNAME"
+       fi
+    fi
 
+    setupicecream
     setupccache
 
+    # fill build directories with sources. Also sets TOPDIR
+    recipe_setup
+    
+    # strip prefix from autogenerated files of source services.
+    for i in $BUILD_ROOT$TOPDIR/SOURCES/_service\:* ; do
+        mv "$i" "${i%/*}/${i##*:}"
+    done
+    RECIPEFILE="${RECIPEFILE##*:}"
+
+    # create .build.packages link
+    rm -f $BUILD_ROOT/.build.packages
+    ln -s ${TOPDIR#/} $BUILD_ROOT/.build.packages
+
     # nasty hack to prevent rpath on known paths
     # FIXME: do this only for suse
     if test -d "$BUILD_ROOT/etc/profile.d" ; then
        echo "export SUSE_IGNORED_RPATHS=/etc/ld.so.conf" > "$BUILD_ROOT/etc/profile.d/buildsystem.sh"
     fi
 
-    #
-    # now clean up RPM building directories
-    if [ "$NO_TOPDIR_CLEANUP" = false ]; then
-        rm -rf "$BUILD_ROOT$TOPDIR"
-        for i in BUILD RPMS/`uname -m` RPMS/i386 RPMS/noarch SOURCES SPECS SRPMS BUILDROOT OTHER ; do
-            mkdir -p $BUILD_ROOT$TOPDIR/$i
-        done
-    fi
-
-    chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
-    check_exit
-
-    mkdir -p $BUILD_ROOT$TOPDIR/SOURCES
-    if test "$BUILDTYPE" = kiwi ; then
-       mkdir -p $BUILD_ROOT$TOPDIR/KIWI
-       if test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then
-           mv "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
-       else
-           if test -z "$LINKSOURCES" ; then
-               cp -dLR "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
-           else
-               cp -lR "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
-           fi
-           if test "$?" != 0 ; then
-               echo "source copy failed"
-               cleanup_and_exit 1
-           fi
-       fi
-    else
-       cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
-    fi
-    # strip prefix from autogenerated files of source services.
-    for i in $BUILD_ROOT$TOPDIR/SOURCES/_service\:*; do
-      mv "$i" "${i%/*}/${i##*:}"
-    done
-    SPECFILE="${SPECFILE##*:}"
-
+    # get rid of old src dir, it is no longer needed and just wastes space
     test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir && rm -rf "$MYSRCDIR"
-    CHANGELOGARGS=
-    test -n "$CHANGELOG" -a -f "$BUILD_ROOT/.build-changelog" && CHANGELOGARGS="--changelog $BUILD_ROOT/.build-changelog"
-
-    if test "$BUILDTYPE" = spec ; then
-       # do buildrequires/release substitution
-       args=()
-       if test -n "$RELEASE"; then
-               args=(--release "$RELEASE")
-       fi
-       substitutedeps "${args[@]}" --root "$BUILD_ROOT" --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" $CHANGELOGARGS "$BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE" "$BUILD_ROOT/.spec.new" || cleanup_and_exit 1
-       # extract macros from configuration
-       getmacros --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" > $BUILD_ROOT/root/.rpmmacros
-       if test -n "$BUILD_DEBUG" ; then
-           echo '
-%prep %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%prep
-%package %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%package
-%_build_insert_debug_package \
-%global __debug_package 1 \
-%undefine _enable_debug_packages \
-%debug_package
-
-' >> $BUILD_ROOT/root/.rpmmacros
-       fi
 
-       if [ -n "$BUILD_JOBS" ]; then
-               cat >> $BUILD_ROOT/root/.rpmmacros <<-EOF
-               %jobs $BUILD_JOBS
-               %_smp_mflags -j$BUILD_JOBS
-               EOF
-       fi
-       test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmmacros $BUILD_ROOT/home/abuild/.rpmmacros
-       # extract optflags from configuration
-       getoptflags --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" ${BUILD_DEBUG:+--debug} > $BUILD_ROOT/root/.rpmrc
-       test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmrc $BUILD_ROOT/home/abuild/.rpmrc
-       if test -z "$ABUILD_TARGET"; then
-           ABUILD_TARGET=$(getchangetarget --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" )
-           test -z "$ABUILD_TARGET" || echo "build target is $ABUILD_TARGET"
-       fi
-    fi
-    if test -f $BUILD_ROOT/.spec.new ; then
-       if ! cmp -s $BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE $BUILD_ROOT/.spec.new ; then
-           echo -----------------------------------------------------------------
-           echo "I have the following modifications for $SPECFILE:"
-           sed -e "/^%changelog/q" $BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE > $BUILD_ROOT/.spec.t1
-           sed -e "/^%changelog/q" $BUILD_ROOT/.spec.new > $BUILD_ROOT/.spec.t2
-           diff $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2
-           rm -f $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2
-           mv $BUILD_ROOT/.spec.new $BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE
-       else
-           rm -f $BUILD_ROOT/.spec.new
-       fi
-    fi
-
-    if test "$BUILDTYPE" = dsc ; then
-       rm -rf "$BUILD_ROOT$TOPDIR/BUILD"
-       mkdir -p $BUILD_ROOT$TOPDIR/SOURCES.DEB
-       chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
-       DEB_TRANSFORM=
-       DEB_SOURCEDIR=$TOPDIR/SOURCES
-       DEB_DSCFILE=$SPECFILE
-       for f in $BUILD_ROOT$TOPDIR/SOURCES/debian.* ; do
-           test -f $f && DEB_TRANSFORM=true
-       done
-       if test -n "$DEB_TRANSFORM" ; then
-           echo "running debian transformer..."
-           if ! debtransform $CHANGELOGARGS $BUILD_ROOT$TOPDIR/SOURCES $BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE $BUILD_ROOT$TOPDIR/SOURCES.DEB ; then
-               echo "debian transforming failed."
-               cleanup_and_exit 1
-           fi
-           DEB_SOURCEDIR=$TOPDIR/SOURCES.DEB
-           for DEB_DSCFILE in $BUILD_ROOT/$DEB_SOURCEDIR/*.dsc ; do : ; done
-           DEB_DSCFILE="${DEB_DSCFILE##*/}"
-       fi
-       chroot $BUILD_ROOT su -c "dpkg-source -x $DEB_SOURCEDIR/$DEB_DSCFILE $TOPDIR/BUILD" - $BUILD_USER
-    fi
-
-    if test "$BUILDTYPE" = arch ; then
-       echo "Preparing sources..."
-       chroot $BUILD_ROOT su -c "cd $TOPDIR/SOURCES && makepkg -s -o 2>&1 >/dev/null" - $BUILD_USER
-       mv $BUILD_ROOT/$TOPDIR/SOURCES/* -t $BUILD_ROOT/$TOPDIR/BUILD
-    fi
+    # patch recipes
+    recipe_prepare
 
+    # hmmm
     chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
+
     cd $BUILD_ROOT$TOPDIR/SOURCES || cleanup_and_exit 1
 
     echo -----------------------------------------------------------------
     if test "$BUILD_USER" = root ; then
-       echo ----- building $SPECFILE
+       echo ----- building $RECIPEFILE
     else
-       echo ----- building $SPECFILE "(user $BUILD_USER)"
+       echo ----- building $RECIPEFILE "(user $BUILD_USER)"
     fi
     echo -----------------------------------------------------------------
     echo -----------------------------------------------------------------
-    if [ -n "$RUNNING_IN_VM" ]; then
-       if [ -x /sbin/ip ]; then
-           ip addr add 127.0.0.1/8 dev lo
-           ip link set lo up
-       else
-           ifconfig lo 127.0.0.1 up
-       fi
-       if [ -n "$MYHOSTNAME" ]; then
-           hostname "$MYHOSTNAME"
-       fi
-    fi
-
     BUILD_SUCCEEDED=false
 
     if test -n "$OVERLAY" ; then
-       if test -d "$OVERLAY"; then
-           pushd $OVERLAY
-           echo "Copying overlay to BUILD_ROOT"
-           tar -cpf - . | (cd $BUILD_ROOT ; tar -xvf -)
-           popd
-       else
-           echo "OVERLAY ($OVERLAY) is no directory - skipping"
-       fi
+       copy_overlay
     fi
 
     if test -n "$RSYNCSRC" ; then
-       if test -n "$RSYNCDEST"; then
-           if test -d "$RSYNCSRC"; then
-               if ! test -d "$BUILD_ROOT/$RSYNCDEST"; then
-                   echo "ATTENTION! Creating target directory ($BUILD_ROOT/$RSYNCDEST) as its not there."
-                   mkdir -p $BUILD_ROOT/$RSYNCDEST
-               fi
-               echo "Running rsync ..."
-               rsync -av $RSYNCSRC/* $BUILD_ROOT/$RSYNCDEST/
-               chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/$RSYNCDEST"
-               RSYNCDONE=true
-               echo "... done"
-           else
-               echo "RSYNCSRC is no directory - skipping"
-           fi
-       else
-           echo "RSYNCSRC given, but not RSYNCDEST - skipping"
-       fi
+       run_rsync
     fi
 
     start_time=`date +%s`
-    if test "$BUILDTYPE" = spec ; then
-       test -z "$BUILD_RPM_BUILD_STAGE" && BUILD_RPM_BUILD_STAGE=-ba
-
-       rpmbuild=rpmbuild
-       test -x $BUILD_ROOT/usr/bin/rpmbuild || rpmbuild=rpm
-
-       # XXX: move _srcdefattr to macro file?
-       rpmbopts=("--define" "_srcdefattr (-,root,root)")
-       if test "$rpmbuild" == "rpmbuild" ; then
-                # use only --nosignature for rpm v4
-           rpmbopts[${#rpmbopts[@]}]="--nosignature"
-       fi
-       if test -n "$ABUILD_TARGET" ; then
-           rpmbopts[${#rpmbopts[@]}]="--target=$ABUILD_TARGET"
-       fi
-       if test -n "$BUILD_DEBUG" ; then
-           rpmbopts[${#rpmbopts[@]}]='--define'
-           rpmbopts[${#rpmbopts[@]}]="_build_create_debug 1"
-       fi
-       if test -n "$DISTURL" ; then
-           rpmbopts[${#rpmbopts[@]}]='--define'
-           rpmbopts[${#rpmbopts[@]}]="disturl $DISTURL"
-       fi
-       if test -n "$RSYNCDONE" ; then
-           rpmbopts[${#rpmbopts[@]}]='--define'
-           rpmbopts[${#rpmbopts[@]}]="RSYNCDONE 1"
-       fi
-
-       # su involves a shell which would require even more
-       # complicated quoting to bypass than this
-        if test "$SHORT_CIRCUIT" = false ; then
-            rpmbopts[${#rpmbopts[@]}]="$BUILD_RPM_BUILD_STAGE"
-            toshellscript $rpmbuild \
-                    "${definesnstuff[@]}" \
-                    "${rpmbopts[@]}" \
-                    "$TOPDIR/SOURCES/$SPECFILE" \
-                    > $BUILD_ROOT/.build.command
-        else
-            rpmbopts[${#rpmbopts[@]}]='--short-circuit'
-            buildopts="-bc -bi -bb -bs"
-            cmds=""
-            echo "#!/bin/sh -x" >$BUILD_ROOT/.build.command
-            echo "set -e" >>$BUILD_ROOT/.build.command
-            for opt in $buildopts
-            do
-                shellquote $rpmbuild  \
-                        "${definesnstuff[@]}" \
-                        "${rpmbopts[@]}" $opt \
-                        "$TOPDIR/SOURCES/$SPECFILE" \
-                        >> $BUILD_ROOT/.build.command
-                echo >>$BUILD_ROOT/.build.command
-                [ "$opt" == "$BUILD_RPM_BUILD_STAGE" ] && break
-            done
-        fi
-
-       chmod 755 $BUILD_ROOT/.build.command
-       check_exit
-       if test -n "$shell"; then
-           chroot $BUILD_ROOT su -
-       else
-           chroot $BUILD_ROOT su -c /.build.command - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true
-       fi
-    fi
-
-    if test "$BUILDTYPE" = dsc ; then
-       # Checks to see if a build script should be used
-       # this allows the build environment to be manipulated
-       # and alternate build commands can be used
-# Debian policy requires to build with single CPU by default
-#      if [ -n "$BUILD_JOBS" ]; then
-#          DSC_BUILD_JOBS="-j$BUILD_JOBS"
-#      fi
-       DSC_BUILD_CMD="dpkg-buildpackage -us -uc -rfakeroot-tcp $DSC_BUILD_JOBS"
-       if test -e $BUILD_ROOT/$TOPDIR/SOURCES/build.script ; then
-           echo "Sourcing build.script to build - it should normally run 'dpkg-buildpackage -us -uc -rfakeroot-tcp'"
-           DSC_BUILD_CMD="source $TOPDIR/SOURCES/build.script"
-           chmod +x $BUILD_ROOT/$TOPDIR/SOURCES/build.script
-       fi
-
-       if test -n "$shell"; then
-           chroot $BUILD_ROOT su -
-       else
-           chroot $BUILD_ROOT su -c "cd $TOPDIR/BUILD && $DSC_BUILD_CMD" - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true
-           if test "$BUILD_SUCCEEDED" = true -a "$DO_CHECKS" != "false"; then
-               DEB_CHANGESFILE=${SPECFILE%.dsc}_"$(chroot $BUILD_ROOT su -c 'dpkg-architecture -qDEB_BUILD_ARCH')".changes
-               chroot $BUILD_ROOT su -c "which lintian > /dev/null && cd $TOPDIR && echo Running lintian && (set -x && lintian -i $DEB_SOURCEDIR/$DEB_DSCFILE)" - $BUILD_USER < /dev/null
-           fi
-       fi
-
-       mkdir -p $BUILD_ROOT/$TOPDIR/DEBS
-       for DEB in $BUILD_ROOT/$TOPDIR/*.deb ; do
-           test -e "$DEB" && mv "$DEB" "$BUILD_ROOT/$TOPDIR/DEBS"
-       done
-       # link sources over
-       ln $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE $BUILD_ROOT/$TOPDIR/DEBS/
-       while read f ; do
-           ln $BUILD_ROOT/$DEB_SOURCEDIR/$f $BUILD_ROOT/$TOPDIR/DEBS/
-       done < <(sed -ne '/^Files:/,$s/^ ................................ [0-9][0-9]* //p' < $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE)
-    fi
-
-    if test "$BUILDTYPE" = arch ; then
-       chroot $BUILD_ROOT su -c "cd $TOPDIR/BUILD && makepkg -f" - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true
-       mkdir -p $BUILD_ROOT/$TOPDIR/ARCHPKGS
-       for PKG in $BUILD_ROOT/$TOPDIR/BUILD/*.pkg.tar.?z ; do
-           test -e "$PKG" && mv "$PKG" "$BUILD_ROOT/$TOPDIR/ARCHPKGS"
-       done
-    fi
-
-    if test "$BUILDTYPE" = kiwi ; then
-       . $BUILD_DIR/build_kiwi.sh
-       run_kiwi
-    fi
-    if test "$statistics" = 1; then
+    recipe_build
+    if test "$DO_STATISTICS" = 1; then
         mkdir -p $TOPDIR/OTHER
         echo "TIME_main_build: $(( `date +%s` - $start_time ))"  >> $TOPDIR/OTHER/_statistics
     fi
@@ -3129,7 +1322,7 @@ for SPECFILE in "${SPECFILES[@]}" ; do
     test -d "$SRCDIR" && cd "$SRCDIR"
 done
 
-if test -n "$RUNNING_IN_VM" -a -n "$VM_SWAP"; then
+if test -n "$RUNNING_IN_VM" -a -n "$DO_STATISTICS" ; then
     touch /.build/_statistics.exit
 fi
 
@@ -3137,60 +1330,30 @@ RPMS=`find $BUILD_ROOT/$TOPDIR/RPMS -type f -name "*.rpm" 2>/dev/null || true`
 DEBS=`find $BUILD_ROOT/$TOPDIR/DEBS -type f -name "*.deb" 2>/dev/null || true`
 
 if test -n "$RPMS" -a -n "$BUILD_USER_ABUILD_USED" ; then
-    echo "... checking for files with abuild user/group"
-    BADFILE=
-    while read un gn fn ; do
-       if test "$un" = abuild -o "$gn" = abuild -o "$un" = ${ABUILD_UID} -o "$gn" = ${ABUILD_GID} ; then
-           echo "  $un $gn $fn"
-           BADFILE=true
-       fi
-    done < <(rpm -qp --qf '[%{FILEUSERNAME} %{FILEGROUPNAME} %{FILENAMES}\n]' $RPMS)
-    if test -n "$BADFILE" ; then
-       echo "please fix your filelist (e.g. add defattr)"
-       cleanup_and_exit 1
-    fi
+    recipe_check_file_owners
 fi
 
 if test -n "$RPMS" -a -d "$BUILD_ROOT/usr/lib/build/checks" ; then
-    export PNAME=""
     export DO_RPM_REMOVE=true
+    # find package name
+    export PNAME=
     for SRPM in $BUILD_ROOT/$TOPDIR/SRPMS/*src.rpm ; do
        test -f "$SRPM" && PNAME=`rpm --nodigest --nosignature -qp --qf "%{NAME}" $SRPM`
     done
     mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null
     for CHECKSCRIPT in $BUILD_ROOT/usr/lib/build/checks/* ; do
-       echo "... running `basename $CHECKSCRIPT`"
+       echo "... running ${CHECKSCRIPT##*/}"
        $CHECKSCRIPT || cleanup_and_exit 1
     done
     umount -n $BUILD_ROOT/proc 2>/dev/null || true
 fi
 
+# checkscripts may have deleted some binaries
 RPMS=`find $BUILD_ROOT/$TOPDIR/RPMS -type f -name "*.rpm" 2>/dev/null || true`
 DEBS=`find $BUILD_ROOT/$TOPDIR/DEBS -type f -name "*.deb" 2>/dev/null || true`
 
-if test -n "$RPMS" -a "$DO_CHECKS" != "false" -a -x "$BUILD_ROOT/opt/testing/bin/rpmlint" ; then
-    LINT_RPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/RPMS \
-       \( -name "*-debuginfo-*" -o -name "*-debugsource-*" \
-       -o -name "*-32bit-*" -o -name "*-64bit-*" \
-       -o -name "*-x86-*" -o -name "*-ia32-*" \) -prune \
-       -o -type f -name '*.rpm' -print))
-    SRPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/SRPMS -type f -name "*.rpm"))
-    echo
-    echo "RPMLINT report:"
-    echo "==============="
-    rpmlint_logfile=$TOPDIR/OTHER/rpmlint.log
-    rm -f "$BUILD_ROOT$rpmlint_logfile"
-    ret=0
-    mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null
-    chroot $BUILD_ROOT su -s /opt/testing/bin/rpmlint "$BUILD_USER" -- \
-           --info ${LINT_RPM_FILE_LIST[*]#$BUILD_ROOT} \
-           ${SRPM_FILE_LIST[*]#$BUILD_ROOT} > "$BUILD_ROOT$rpmlint_logfile" || ret=1
-           cat "$BUILD_ROOT$rpmlint_logfile"
-           echo
-    umount -n $BUILD_ROOT/proc 2>/dev/null || true
-    if test "$ret" = 1; then
-       cleanup_and_exit 1
-    fi
+if test -n "$RPMS" -a "$DO_CHECKS" != false ; then
+    recipe_run_rpmlint
 fi
 
 if test \( -n "$RPMS" -o -n "$DEBS" \) -a -n "$CREATE_BASELIBS"; then
@@ -3198,102 +1361,23 @@ if test \( -n "$RPMS" -o -n "$DEBS" \) -a -n "$CREATE_BASELIBS"; then
 fi
 
 exitcode=0
-# post build scripts
+
+# post build work
 # TODO: don't hardcode. instead run scripts in a directory as it's done for the checks
-if test -n "$RPMS" \
-       -a -d "$BUILD_ROOT/$TOPDIR/RPMS" \
-       -a -d "$BUILD_ROOT/.build.oldpackages" \
-       ; then
-    if test -x "$BUILD_ROOT/usr/lib/build/same-build-result.sh" ; then
-       echo "... comparing built packages with the former built"
-       mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null
-       if chroot $BUILD_ROOT /usr/lib/build/same-build-result.sh /.build.oldpackages "$TOPDIR/RPMS" "$TOPDIR/SRPMS"; then
-           chroot $BUILD_ROOT touch /.build/.same_result_marker
-           # XXX: dirty build service hack. fix bs_worker. Search for
-           # 'same_result_marker' for traces of a first try to get rid of this
-           if test -n "$REASON" -a -n "$DISTURL"; then
-               exitcode=2
-           fi
-       fi
-        umount -n $BUILD_ROOT/proc 2>/dev/null || true
-    fi
-    if test ! -e $BUILD_ROOT/.build/.same_result_marker \
-       -a -x "$BUILD_ROOT/usr/bin/makedeltarpm" \
-       -a -x $BUILD_ROOT/usr/lib/build/mkdrpms; then
-       echo "... creating delta rpms"
-       ds=("$BUILD_ROOT/$TOPDIR"/RPMS/* "$BUILD_ROOT$TOPDIR/SRPMS")
-       chroot $BUILD_ROOT /usr/lib/build/mkdrpms /.build.oldpackages "${ds[@]#$BUILD_ROOT}"
+if test -n "$RPMS" -a -d "$BUILD_ROOT/.build.oldpackages" ; then
+    recipe_compare_oldpackages
+    # no need to create deltas if the build is the same
+    if test ! -e $BUILD_ROOT/.build/.same_result_marker ; then
+       recipe_create_deltarpms
     fi
 fi
 
-if test -n "$RUNNING_IN_VM"; then
-    if test "$statistics" = 1; then
-         echo "... saving built statistics"
-         [ -n "$TIME_INSTALL" ] && echo "TIME_install: $TIME_INSTALL"  >> $BUILD_ROOT$TOPDIR/OTHER/_statistics
-         if [ -e /.build/_statistics.df ]; then
-           echo -n "MAX_mb_used_on_disk: " >> $TOPDIR/OTHER/_statistics
-           cat /.build/_statistics.df >> $TOPDIR/OTHER/_statistics
-           echo "" >> $TOPDIR/OTHER/_statistics
-           rm /.build/_statistics.df
-         fi
-         if [ -e /.build/_statistics.memory ]; then
-           echo -n "MAX_mb_used_memory: " >> $TOPDIR/OTHER/_statistics
-           cat /.build/_statistics.memory >> $TOPDIR/OTHER/_statistics
-           echo "" >> $TOPDIR/OTHER/_statistics
-           rm /.build/_statistics.memory
-         fi
-         mkdir -p /sys
-         mount -n sys /sys -t sysfs
-         device="hda1"
-         [ -e /dev/sda ] && device="sda"
-         [ -e /dev/vda ] && device="vda"
-         [ -e /dev/dasda ] && device="dasda" # in z/VM
-         [ -e /dev/nfhd0 ] && device="nfhd0" # in aranym
-         if [ -e /sys/block/${device}/stat ]; then
-           disk=(`cat /sys/block/${device}/stat`)
-           [ "0${disk[0]}" -gt 0 ] && echo "IO_requests_read: ${disk[0]}"  >> $TOPDIR/OTHER/_statistics
-           [ "0${disk[2]}" -gt 0 ] && echo "IO_sectors_read: ${disk[2]}"   >> $TOPDIR/OTHER/_statistics
-           [ "0${disk[4]}" -gt 0 ] && echo "IO_requests_write: ${disk[4]}" >> $TOPDIR/OTHER/_statistics
-           [ "0${disk[6]}" -gt 0 ] && echo "IO_sectors_write: ${disk[6]}"  >> $TOPDIR/OTHER/_statistics
-         else
-           echo "ERROR: no root disk device found, yet another new device name?"
-           ls -l /sys/block/
-         fi
-         umount /sys
-    fi
-
-    if test -n "$VM_SWAP"; then
-         echo "... saving built packages"
-         swapoff "$VM_SWAP"
-         args="--padstart 512 --padend 512 -v"
-         case "$BUILDTYPE" in
-             spec)
-                 computeblocklists $args $TOPDIR/RPMS/*/*.{d,}rpm $TOPDIR/SRPMS/* $TOPDIR/OTHER/* > "$VM_SWAP"
-                 ;;
-             dsc)
-                 computeblocklists $args $TOPDIR/DEBS/*.deb $TOPDIR/SOURCES.DEB/* $TOPDIR/OTHER/* > "$VM_SWAP"
-                 ;;
-             kiwi)
-                 computeblocklists $args $TOPDIR/KIWI/* $TOPDIR/OTHER/* > "$VM_SWAP"
-                 ;;
-             arch)
-                 computeblocklists $args $TOPDIR/ARCHPKGS/* $TOPDIR/OTHER/* > "$VM_SWAP"
-                 ;;
-             preinstallimage)
-                 computeblocklists $args $TOPDIR/OTHER/* > "$VM_SWAP"
-                 ;;
-             *)
-                 cleanup_and_exit 1
-                 ;;
-         esac || cleanup_and_exit 1
-    else
-         # quit inside of the emulator
-         cleanup_and_exit "$exitcode"
-    fi
+if test -n "$RUNNING_IN_VM" ; then
+    vm_wrapup_build $(recipe_resultdirs) OTHER
 fi
 
 echo
-echo "$HOST finished \"build $SPECFILE\" at `date --utc`."
+echo "$HOST finished \"build $RECIPEFILE\" at `date --utc`."
 echo
 
 cleanup_and_exit "$exitcode"
diff --git a/build-pkg b/build-pkg
new file mode 100644 (file)
index 0000000..4ffcfb1
--- /dev/null
+++ b/build-pkg
@@ -0,0 +1,93 @@
+#
+# binary package specific functions for the build script
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+for i in rpm deb arch ; do
+    . "$BUILD_DIR/build-pkg-$i"
+done
+
+pkg_initdb() {
+    pkg_initdb_$PSUF "$@"
+}
+
+pkg_prepare() {
+    pkg_prepare_$PSUF "$@"
+}
+
+pkg_install() {
+    pkg_install_$PSUF "$@"
+}
+
+pkg_verify_installed() {
+    pkg_verify_installed_$PSUF "$@"
+}
+
+pkg_erase() {
+    pkg_erase_$PSUF "$@"
+}
+
+pkg_cumulate() {
+    pkg_cumulate_$PSUF "$@"
+}
+
+pkg_finalize() {
+    pkg_finalize_$PSUF "$@"
+}
+
+pkg_preinstall() {
+    pkg_preinstall_$PSUF "$@"
+}
+
+pkg_runscripts() {
+    pkg_runscripts_$PSUF "$@"
+}
+
+pkg_autodetect_type() {
+    if test -n "$PREINSTALL_IMAGE" ; then
+       echo "cannot autodetect build type when using a preinstall image" >&2
+       cleanup_and_exit 1
+    fi
+    PSUF=
+    test -e $BUILD_ROOT/.init_b_cache/rpms/rpm.rpm && PSUF=rpm
+    test -e $BUILD_ROOT/.init_b_cache/rpms/dpkg.deb && PSUF=deb
+    test -e $BUILD_ROOT/.init_b_cache/rpms/pacman.arch && PSUF=arch
+    if test -z "$PSUF" ; then
+       echo "could not autodetect package type" >&2
+       cleanup_and_exit 1
+    fi
+}
+
+pkg_set_type() {
+    PSUF=`queryconfig binarytype --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH"`
+    test "$PSUF" = UNDEFINED && PSUF=
+    case "$PSUF" in
+       rpm|deb|arch)
+           ;;
+       '')
+           pkg_autodetect_type
+           ;;
+       *)
+            echo "unknown package type '$PSUF'" >&2
+            cleanup_and_exit 1
+           ;;
+    esac
+}
diff --git a/build-pkg-arch b/build-pkg-arch
new file mode 100644 (file)
index 0000000..eadab2b
--- /dev/null
@@ -0,0 +1,73 @@
+#
+# Arch specific functions.
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+pkg_initdb_arch() {
+    mkdir -p $BUILD_ROOT/var/lib/pacman/sync
+    touch $BUILD_ROOT/var/lib/pacman/sync/core.db
+    touch $BUILD_ROOT/var/lib/pacman/sync/extra.db
+    touch $BUILD_ROOT/var/lib/pacman/sync/community.db
+}
+
+pkg_prepare_arch() {
+    :
+}
+
+pkg_erase_arch() {
+    ( cd $BUILD_ROOT && chroot $BUILD_ROOT pacman -R -n -d -d --noconfirm $PKG 2>&1 || touch $BUILD_ROOT/exit ) | \
+       perl -ne '$|=1;/^(Total Removed Size: |Packages \(\d+\):|:: Do you want to remove these packages|deleting |removing |    )/||/^$/||print'
+}
+
+pkg_verify_installed_arch() {
+    return 1
+}
+
+pkg_cumulate_arch() {
+    return 1
+}
+
+pkg_install_arch() {
+    # -d -d disables deps checking
+    ( cd $BUILD_ROOT && chroot $BUILD_ROOT pacman -U --force -d -d --noconfirm .init_b_cache/$PKG.$PSUF 2>&1 || touch $BUILD_ROOT/exit ) | \
+       perl -ne '$|=1;/^(warning: could not get filesystem information for |loading packages|looking for inter-conflicts|Targets |Total Installed Size: |Net Upgrade Size: |Proceed with installation|checking package integrity|loading package files|checking for file conflicts|checking keyring|Packages \(\d+\):|:: Proceed with installation|checking available disk space|installing |upgrading |warning:.*is up to date -- reinstalling|Optional dependencies for|    )/||/^$/||print'
+}
+
+pkg_finalize_arch() {
+    :
+}
+
+pkg_preinstall_arch() {
+    $TAR -f "$BUILD_ROOT/.init_b_cache/rpms/$PKG.arch"
+    if test -f .INSTALL ; then
+       cat .INSTALL > ".init_b_cache/scripts/$PKG.post"
+       echo 'type post_install >/dev/null 2>&1 && post_install' >> ".init_b_cache/scripts/$PKG.post"
+    fi
+    rm -f .PKGINFO .INSTALL
+}
+
+pkg_runscripts_arch() {
+    if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post" ; then
+       echo "running $PKG postinstall script"
+       ( cd $BUILD_ROOT && chroot $BUILD_ROOT ".init_b_cache/scripts/$PKG.post" < /dev/null )
+       rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post"
+    fi
+}
diff --git a/build-pkg-deb b/build-pkg-deb
new file mode 100644 (file)
index 0000000..83a4afe
--- /dev/null
@@ -0,0 +1,124 @@
+#
+# Debian dpkg specific functions.
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+deb_setup() {
+    mkdir -p $BUILD_ROOT/var/lib/dpkg
+    mkdir -p $BUILD_ROOT/var/log
+    mkdir -p $BUILD_ROOT/etc/default
+    :>> $BUILD_ROOT/var/lib/dpkg/status
+    :>> $BUILD_ROOT/var/lib/dpkg/available
+    :>> $BUILD_ROOT/var/log/dpkg.log
+    :>> $BUILD_ROOT/etc/ld.so.conf
+    :>> $BUILD_ROOT/etc/default/rcS
+}
+
+pkg_initdb_deb() {
+    deb_setup
+    # force dpkg into database to make epoch test work
+    if ! test "$BUILD_ROOT/.init_b_cache/rpms/dpkg.deb" -ef "$BUILD_ROOT/.init_b_cache/dpkg.deb" ; then
+       rm -f $BUILD_ROOT/.init_b_cache/dpkg.deb
+       cp $BUILD_ROOT/.init_b_cache/rpms/dpkg.deb $BUILD_ROOT/.init_b_cache/dpkg.deb || cleanup_and_exit 1
+    fi
+    chroot $BUILD_ROOT dpkg -i --force all .init_b_cache/dpkg.deb >/dev/null 2>&1
+}
+
+pkg_prepare_deb() {
+    :
+}
+
+pkg_install_deb() {
+    export DEBIAN_FRONTEND=noninteractive
+    export DEBIAN_PRIORITY=critical
+    ( cd $BUILD_ROOT && chroot $BUILD_ROOT dpkg --install --force all .init_b_cache/$PKG.deb 2>&1 || touch $BUILD_ROOT/exit ) | \
+       perl -ne '$|=1;/^(Configuration file|Installing new config file|Selecting previously deselected|Selecting previously unselected|\(Reading database|Unpacking |Setting up|Creating config file|Preparing to replace dpkg|Preparing to unpack )/||/^$/||print'
+    # ugly workaround for upstart system. some packages (procps) try
+    # to start a service in their configure phase. As we don't have
+    # a running upstart, we just link the start binary to /bin/true
+    if test -e "$BUILD_ROOT/sbin/start"; then
+       if test "$BUILD_ROOT/sbin/start" -ef "$BUILD_ROOT/sbin/initctl" ; then
+           echo "linking /sbin/start to /bin/true"
+           mv "$BUILD_ROOT/sbin/start" "$BUILD_ROOT/sbin/start.disabled"
+           ln -s "/bin/true" "$BUILD_ROOT/sbin/start"
+       fi
+    fi
+    # another workaround, see bug bnc#733699
+    rm -f "$BUILD_ROOT/var/run/init.upgraded"
+}
+
+pkg_erase_deb() {
+    export DEBIAN_FRONTEND=noninteractive
+    export DEBIAN_PRIORITY=critical
+    ( cd $BUILD_ROOT && chroot $BUILD_ROOT dpkg --purge --force all $PKG 2>&1 || touch $BUILD_ROOT/exit ) | \
+       perl -ne '$|=1;/^(\(Reading database|Removing |Purging configuration files for )/||/^$/||print'
+}
+
+pkg_cumulate_deb() {
+    return 1
+}
+
+pkg_verify_installed_deb() {
+    return 1
+}
+
+pkg_finalize_deb() {
+    echo "configuring all installed packages..."
+    # configure all packages after complete installation, not for each package like rpm does
+    # We need to run this twice, because of cyclic dependencies as it does not succeed on most
+    # debian based distros in the first attempt.
+    if ! chroot $BUILD_ROOT dpkg --configure --pending  2>&1; then
+         echo "first configure attempt failed, trying again..."
+         chroot $BUILD_ROOT dpkg --configure --pending  2>&1 || cleanup_and_exit 1
+    fi
+}
+
+pkg_preinstall_deb() {
+    ar x "$BUILD_ROOT/.init_b_cache/rpms/$PKG.deb"
+    mkdir -p .init_b_cache/scripts/control
+    $TAR -C .init_b_cache/scripts/control -z -f control.tar.gz
+    if test -f "data.tar.gz" ; then
+       $TAR -z -f data.tar.gz
+    elif test -f "data.tar.xz" ; then
+       $TAR -J -f data.tar.xz
+    fi
+    if test -e ".init_b_cache/scripts/$PKG.run" ; then
+       test -e .init_b_cache/scripts/control/preinst && mv .init_b_cache/scripts/control/preinst ".init_b_cache/scripts/$PKG.pre"
+       test -e .init_b_cache/scripts/control/postinst && mv .init_b_cache/scripts/control/postinst ".init_b_cache/scripts/$PKG.post"
+    fi
+    rm -rf .init_b_cache/scripts/control control.tar.gz data.tar.{g,x}z
+}
+
+pkg_runscripts_deb() {
+    if ! test -e $BUILD_ROOT/var/lib/dpkg/status ; then
+       deb_setup
+    fi
+    if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.pre" ; then
+       echo "running $PKG preinstall script"
+       (cd $BUILD_ROOT && chroot $BUILD_ROOT ".init_b_cache/scripts/$PKG.pre" install < /dev/null )
+       rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.pre"
+    fi
+    if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post" ; then
+       echo "running $PKG postinstall script"
+       (cd $BUILD_ROOT && chroot $BUILD_ROOT ".init_b_cache/scripts/$PKG.post" configure '' < /dev/null )
+       rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post"
+    fi
+}
diff --git a/build-pkg-rpm b/build-pkg-rpm
new file mode 100644 (file)
index 0000000..c0f9653
--- /dev/null
@@ -0,0 +1,193 @@
+#
+# RPM specific functions.
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+
+pkg_initdb_rpm() {
+    echo "initializing rpm db..."
+    mkdir -p $BUILD_ROOT/var/lib/rpm
+    # rpm v5 does not have initdb
+    if ! test -e $BUILD_ROOT/usr/lib/rpm/cpuinfo.yaml ; then
+       if test -x $BUILD_ROOT/usr/bin/rpmdb ; then
+           chroot $BUILD_ROOT /usr/bin/rpmdb --initdb || cleanup_and_exit 1
+       else
+           chroot $BUILD_ROOT rpm --initdb || cleanup_and_exit 1
+       fi
+    fi
+    # hack: add nofsync to db config to speed up install
+    mkdir -p $BUILD_ROOT/root
+    DBI_OTHER=`chroot $BUILD_ROOT rpm --eval '%{?__dbi_other}'`
+    echo "%__dbi_other $DBI_OTHER nofsync" > $BUILD_ROOT/.rpmmacros
+    echo "%__dbi_other $DBI_OTHER nofsync" > $BUILD_ROOT/root/.rpmmacros
+}
+
+pkg_prepare_rpm() {
+    rpm_set_checkopts
+    rpm_init_cumulate
+}
+
+pkg_erase_rpm() {
+    chroot $BUILD_ROOT rpm --nodeps -e $PKG 2>&1 | {
+       local retry
+       while read line; do
+           case "$line" in
+               r*failed:\ No\ such\ file\ or\ directory) ;;
+               error:\ failed\ to\ stat\ *:\ No\ such\ file\ or\ directory) ;;
+               error:\ *scriptlet\ failed*)
+                   echo "$line"
+                   retry=1
+               ;;
+               *) echo "$line" ;;
+           esac
+       done
+       if test -n "$retry" ; then
+           echo "re-try deleting $PKG using --noscripts"
+           chroot $BUILD_ROOT rpm --nodeps --noscripts -e $PKG || true
+       fi
+    }
+}
+
+rpm_set_checkopts() {
+    RPMCHECKOPTS=
+    # on Fedora 10 rpmbuild is in a separate package so we need something else to
+    # detect rpm4
+    test -x $BUILD_ROOT/usr/bin/rpmquery && RPMCHECKOPTS="--nodigest --nosignature"
+}
+
+rpm_init_cumulate() {
+    cumulate=-1
+    CUMULATED_LIST=()
+    CUMULATED_PIDS=()
+    CUMULATED_HMD5=()
+    DO_CUMULATE=
+    typeset -ri suse_version=$(chroot $BUILD_ROOT rpm --eval '%{?suse_version}' 2>/dev/null)
+    if ((suse_version > 1220)) ; then 
+       DO_CUMULATE=true
+    fi
+}
+
+pkg_verify_installed_rpm() {
+    chroot $BUILD_ROOT rpm --verify $PKG 2>&1 | tee $TMPFILE
+    if grep ^missing $TMPFILE > /dev/null ; then
+       return 1
+    fi
+    return 0
+}
+
+pkg_cumulate_rpm() {
+    test "$DO_CUMULATE" = true || return 1
+    # work around for cross-build installs, we must not overwrite the running rpm
+    if test "$PKG" = rpm ; then
+       for i in $BUILD_ROOT/.init_b_cache/preinstalls/rpm-x86-* ; do
+           test -e "$i" && return 1
+       done
+    fi
+    let cumulate++
+    CUMULATED_LIST[$cumulate]=".init_b_cache/$PKG.rpm"
+    CUMULATED_PIDS[$cumulate]="$PKGID"
+    CUMULATED_HMD5[$cumulate]="$PKG_HDRMD5"
+    return 0
+}
+
+pkg_install_rpm() {
+    ( chroot $BUILD_ROOT rpm --ignorearch --nodeps -U --oldpackage --ignoresize $RPMCHECKOPTS \
+               $ADDITIONAL_PARAMS .init_b_cache/$PKG.rpm 2>&1 || \
+         touch $BUILD_ROOT/exit ) | \
+             grep -v "^warning:.*saved as.*rpmorig$"
+}
+
+pkg_finalize_rpm() {
+    if test -n "${CUMULATED_LIST[*]}" ; then
+       echo "now installing cumulated packages"
+       for ((num=0; num<=cumulate; num++)) ; do
+           echo ${CUMULATED_LIST[$num]}
+           PKG=${CUMULATED_LIST[$num]##*/}
+           test "$BUILD_ROOT/.init_b_cache/rpms/$PKG" -ef "$BUILD_ROOT/${CUMULATED_LIST[$num]}" && continue
+           rm -f $BUILD_ROOT/${CUMULATED_LIST[$num]}
+           cp $BUILD_ROOT/.init_b_cache/rpms/$PKG $BUILD_ROOT/${CUMULATED_LIST[$num]} || cleanup_and_exit 1
+       done > $BUILD_ROOT/.init_b_cache/manifest
+       chroot $BUILD_ROOT rpm --ignorearch --nodeps -Uh --oldpackage --ignoresize --verbose $RPMCHECKOPTS \
+               $ADDITIONAL_PARAMS .init_b_cache/manifest 2>&1 || touch $BUILD_ROOT/exit
+       for ((num=0; num<=cumulate; num++)) ; do
+           rm -f $BUILD_ROOT/${CUMULATED_LIST[$num]}
+       done
+       rm -f $BUILD_ROOT/.init_b_cache/manifest
+       check_exit
+       for ((num=0; num<=cumulate; num++)) ; do
+           PKG=${CUMULATED_LIST[$num]##*/}
+           echo "${CUMULATED_PIDS[$num]}" > $BUILD_ROOT/installed-pkg/${PKG%.rpm}
+           test -n "${CUMULATED_HMD5[$num]}" || continue
+           echo "${CUMULATED_HMD5[$num]} ${CUMULATED_PIDS[$num]}" > $BUILD_ROOT/.preinstall_image/${PKG%.rpm}
+       done
+    fi
+}
+
+pkg_preinstall_rpm() {
+    PAYLOADDECOMPRESS=cat
+    case `rpm -qp --nodigest --nosignature --qf "%{PAYLOADCOMPRESSOR}\n" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm"` in
+       lzma) rpm --showrc | egrep 'PayloadIsLzma|_lzma' > /dev/null || PAYLOADDECOMPRESS="lzma -d" ;;
+       xz) rpm --showrc | egrep 'PayloadIsXz|_xz' > /dev/null || PAYLOADDECOMPRESS="xz -d" ;;
+    esac
+    if test "$PAYLOADDECOMPRESS" = "lzma -d" ; then
+       if ! lzma </dev/null >/dev/null 2>&1 ; then
+           test -f "$BUILD_DIR/lzmadec.sh" && PAYLOADDECOMPRESS="bash $BUILD_DIR/lzmadec.sh"
+       fi
+    fi
+    if test "$PAYLOADDECOMPRESS" = "xz -d" ; then
+       if ! xz </dev/null >/dev/null 2>&1 ; then
+           test -f "$BUILD_DIR/xzdec.sh" && PAYLOADDECOMPRESS="bash $BUILD_DIR/xzdec.sh"
+       fi
+    fi
+    if test "$PAYLOADDECOMPRESS" = cat ; then
+       rpm2cpio "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" | $CPIO
+    else
+       rpm2cpio "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" | $PAYLOADDECOMPRESS | $CPIO
+    fi
+    if test -e ".init_b_cache/scripts/$PKG.run" ; then
+       rpm -qp --nodigest --nosignature --qf "%{PREIN}" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" > ".init_b_cache/scripts/$PKG.pre"
+       rpm -qp --nodigest --nosignature --qf "%{POSTIN}" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" > ".init_b_cache/scripts/$PKG.post"
+       echo -n '(none)' > .init_b_cache/scripts/.none
+       cmp -s ".init_b_cache/scripts/$PKG.pre" .init_b_cache/scripts/.none && rm -f ".init_b_cache/scripts/$PKG.pre"
+       cmp -s ".init_b_cache/scripts/$PKG.post" .init_b_cache/scripts/.none && rm -f ".init_b_cache/scripts/$PKG.post"
+       rm -f .init_b_cache/scripts/.none
+    fi
+    # hack for rpm erasures
+    if test -d "$BUILD_ROOT/installed-pkg" ; then
+       # call for rpm-4.x and not rpm-devel
+        test -z "${PKG##rpm-[0-9]*}" && chroot $BUILD_ROOT rpm --rebuilddb
+        # also exec for exchanged rpm !  naming is rpm-x86-<target>-<ver>
+        test -z "${PKG##rpm-x86-*[0-9]*}" && chroot $BUILD_ROOT rpm --rebuilddb
+    fi
+}
+
+pkg_runscripts_rpm() {
+    if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.pre" ; then
+       echo "running $PKG preinstall script"
+       chroot $BUILD_ROOT sh ".init_b_cache/scripts/$PKG.pre" 0
+       rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.pre"
+    fi
+    if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post" ; then
+       echo "running $PKG postinstall script"
+       chroot $BUILD_ROOT sh ".init_b_cache/scripts/$PKG.post" 1
+       rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post"
+    fi
+}
diff --git a/build-recipe b/build-recipe
new file mode 100644 (file)
index 0000000..4d9674a
--- /dev/null
@@ -0,0 +1,140 @@
+#
+# recipe specific functions for the build script
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+
+KIWI_PARAMETERS=
+
+for i in spec dsc kiwi arch preinstallimage mock livebuild debootstrap; do
+    . "$BUILD_DIR/build-recipe-$i"
+done
+
+recipe_setup() {
+    recipe_setup_$BUILDTYPE "$@"
+}
+
+recipe_prepare() {
+    recipe_prepare_$BUILDTYPE "$@"
+}
+
+recipe_build() {
+    recipe_build_$BUILDTYPE "$@"
+}
+
+recipe_resultdirs () {
+    recipe_resultdirs_$BUILDTYPE "$@"
+}
+
+recipe_parse_options() {
+    case ${PARAM/#--/-} in
+      -stage)
+       needarg
+       BUILD_RPM_BUILD_STAGE="$ARG"
+       shift
+       ;;
+      -kiwi-parameter)
+       test -z "$ARG" && ARG="$1"
+       needarg
+       KIWI_PARAMETERS="$KIWI_PARAMETERS $ARG"
+       shift
+       ;;
+      -*)
+       return 1
+       ;;
+    esac
+    nextargs=("$@")
+    return 0
+}
+
+recipe_set_buildtype() {
+    BUILDTYPE=
+    case ${RECIPEFILE##_service:*:} in
+        *.spec|*.src.rpm) BUILDTYPE=spec ;;
+        *.dsc) BUILDTYPE=dsc ;;
+        *.kiwi) BUILDTYPE=kiwi ;;
+        PKGBUILD) BUILDTYPE=arch ;;
+        _preinstallimage) BUILDTYPE=preinstallimage ;;
+        *.livebuild) BUILDTYPE=livebuild ;;
+    esac
+    if test -z "$BUILDTYPE" ; then
+       echo "I don't know how to build $RECIPEFILE"
+       cleanup_and_exit 1
+    fi
+    # we can't query right after vm startup, so we put the BUILDENGINE in the build.data
+    if test -z "$RUNNING_IN_VM" ; then
+       BUILDENGINE=
+       if test -n "$BUILD_DIST" ; then
+           BUILDENGINE=`queryconfig buildengine --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH"`
+           test "$BUILDENGINE" = UNDEFINED && BUILDENGINE=
+       fi
+    fi
+    if test "$BUILDENGINE" = mock -a "$BUILDTYPE" = spec ; then
+       BUILDTYPE=mock
+    fi
+    if test "$BUILDENGINE" = debootstrap -a "$BUILDTYPE" = dsc ; then
+       BUILDTYPE=debootstrap
+    fi
+}
+
+# expands all directories into files
+expand_recipe_directories() {
+    local f t ff found types
+    if test -z "$RECIPEFILES" ; then
+       set -- "`pwd`"
+    else
+       set -- "${RECIPEFILES[@]}"
+    fi
+    RECIPEFILES=()
+    for f in "$@" ; do
+       if test "$f" = "${f#/}" ; then
+           f="`pwd`/$f"
+       fi
+       if test -d "$f" ; then
+           if test -z "$types" ; then
+               if test -n "$BUILD_DIST" ; then
+                   case $(queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" type) in
+                       dsc) types=".dsc" ;;
+                       kiwi) types=".kiwi" ;;
+                       arch) types="PKGBUILD" ;;
+                       livebuild) types=".livebuild" ;;
+                   esac
+               fi
+               types="$types .spec .dsc PKGBUILD .kiwi .src.rpm .nosrc.rpm"
+           fi
+           for t in $types ; do
+               found=
+               for ff in "$f"/*$t ; do
+                   test -f "$ff" || continue
+                   RECIPEFILES=("${RECIPEFILES[@]}" "$ff")
+                   found=true
+               done
+               test -n "$found" && break
+           done
+       else
+           RECIPEFILES[${#RECIPEFILES[@]}]="$f"
+       fi
+    done
+    if test -z "$RECIPEFILES" ; then
+       echo "no recipe files found in $@. exit..."
+       cleanup_and_exit 1
+    fi
+}
diff --git a/build-recipe-arch b/build-recipe-arch
new file mode 100644 (file)
index 0000000..2fe6159
--- /dev/null
@@ -0,0 +1,57 @@
+#
+# Arch specific functions.
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+recipe_setup_arch() {
+    TOPDIR=/usr/src/packages
+    rm -rf "$BUILD_ROOT$TOPDIR"
+    mkdir -p "$BUILD_ROOT$TOPDIR"
+    mkdir -p "$BUILD_ROOT$TOPDIR/OTHER"
+    mkdir -p "$BUILD_ROOT$TOPDIR/SOURCES"
+    mkdir -p "$BUILD_ROOT/$TOPDIR/ARCHPKGS"
+    mkdir -p "$BUILD_ROOT/$TOPDIR/BUILD"
+    chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
+    cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
+    {
+       echo 'source /etc/makepkg.conf'
+       printf '%s=%s\n' \
+           BUILDDIR $TOPDIR/BUILD \
+           PKGDEST $TOPDIR/ARCHPKGS
+    } > $BUILD_ROOT$TOPDIR/makepkg.conf
+}
+
+recipe_prepare_arch() {
+    echo "Preparing sources..."
+    _arch_recipe_makepkg -so "2>&1" ">/dev/null"
+}
+
+recipe_build_arch() {
+    _arch_recipe_makepkg -ef < /dev/null && BUILD_SUCCEEDED=true
+}
+
+recipe_resultdirs_arch() {
+    echo ARCHPKGS
+}
+
+_arch_recipe_makepkg() {
+    chroot $BUILD_ROOT su -lc "source /etc/profile; cd $TOPDIR/SOURCES && makepkg --config ../makepkg.conf $*" $BUILD_USER
+}
diff --git a/build-recipe-debootstrap b/build-recipe-debootstrap
new file mode 100644 (file)
index 0000000..265b6e2
--- /dev/null
@@ -0,0 +1,92 @@
+#
+# debootstrap specific functions.
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+recipe_setup_debootstrap() {
+    recipe_setup_dsc "$@"
+}
+
+recipe_prepare_debootstrap() {
+    recipe_prepare_dsc "$@"
+}
+
+recipe_build_debootstrap() {
+    local arch=$(chroot $BUILD_ROOT su -c "dpkg-architecture -qDEB_BUILD_ARCH")
+    local dist=$(chroot $BUILD_ROOT su -c "lsb_release --codename --short")
+    local myroot=debootstraproot
+    test -d $BUILD_ROOT/.build.binaries || cleanup_and_exit 1
+    if test "$DO_INIT" = true -o ! -d "$BUILD_ROOT/.build.binaries/dists" ; then
+       echo "creating repository for debootstrap..."
+       createrepo_debian $BUILD_ROOT/.build.binaries ${arch} ${dist}
+    fi
+    FULL_PKG_LIST=
+    for PKG in $BUILD_ROOT/.build.binaries/*.deb ; do
+       PKG="${PKG##*/}"
+       FULL_PKG_LIST="$FULL_PKG_LIST,${PKG%.deb}"
+    done
+    FULL_PKG_LIST="${FULL_PKG_LIST#,}"
+    rm -rf "$BUILD_ROOT/$myroot"
+    set -- chroot $BUILD_ROOT debootstrap --no-check-gpg --variant=buildd --arch="${arch}" --include="$FULL_PKG_LIST" "$dist" "$myroot" file:///.build.binaries
+    echo "running debootstrap..."
+    "$@"
+    # adapt passwd
+    if test $BUILD_USER = abuild ; then
+       echo "abuild:x:${ABUILD_UID}:${ABUILD_GID}:Autobuild:/home/abuild:/bin/bash" >>$BUILD_ROOT/$myroot/etc/passwd
+       echo 'abuild:*::' >>$BUILD_ROOT/$myroot/etc/gshadow
+       echo "abuild:x:${ABUILD_GID}:" >>$BUILD_ROOT/$myroot/etc/group
+       mkdir -p $BUILD_ROOT/$myroot/home/abuild
+       chown "$ABUILD_UID:$ABUILD_GID" $BUILD_ROOT/$myroot/home/abuild
+    fi
+    # move topdir over
+    mv "$BUILD_ROOT/$TOPDIR" "$BUILD_ROOT/$myroot/${TOPDIR%/*}"
+    # do the build
+    DSC_BUILD_OPTIONS=
+    test -n "$BUILD_JOBS" && DSC_BUILD_OPTIONS="parallel=${BUILD_JOBS}"
+    DSC_BUILD_CMD="$(queryconfig --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" substitute dsc:build_cmd)"
+    test -z "$DSC_BUILD_CMD" && DSC_BUILD_CMD="dpkg-buildpackage -us -uc"
+    if test -e $BUILD_ROOT/$myroot/$TOPDIR/SOURCES/build.script ; then
+        echo "Sourcing build.script to build - it should normally run 'dpkg-buildpackage -us -uc'"
+        DSC_BUILD_CMD="source $TOPDIR/SOURCES/build.script"
+        chmod +x $BUILD_ROOT/$myroot/$TOPDIR/SOURCES/build.script
+    fi
+    chroot "$BUILD_ROOT/$myroot" su -c "export DEB_BUILD_OPTIONS=${DSC_BUILD_OPTIONS} ; cd $TOPDIR/BUILD && $DSC_BUILD_CMD" - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true
+    # run lintian
+    if test "$BUILD_SUCCEEDED" = true -a "$DO_CHECKS" != "false"; then
+       DEB_CHANGESFILE=${RECIPEFILE%.dsc}_"$(chroot "$BUILD_ROOT/$myroot" su -c 'dpkg-architecture -qDEB_BUILD_ARCH')".changes
+       chroot $BUILD_ROOT/$myroot su -c "which lintian > /dev/null && cd $TOPDIR && echo Running lintian && (set -x && lintian -i $DEB_SOURCEDIR/$DEB_DSCFILE)" - $BUILD_USER < /dev/null
+    fi
+    # move topdir back
+    mv "$BUILD_ROOT/$myroot/$TOPDIR" "$BUILD_ROOT/${TOPDIR%/*}"
+    for DEB in $BUILD_ROOT/$TOPDIR/*.deb ; do
+        test -e "$DEB" && mv "$DEB" "$BUILD_ROOT/$TOPDIR/DEBS"
+    done
+    # link used sources over to DEB directory
+    ln $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE $BUILD_ROOT/$TOPDIR/DEBS/
+    while read f ; do
+        ln $BUILD_ROOT/$DEB_SOURCEDIR/$f $BUILD_ROOT/$TOPDIR/DEBS/
+    done < <(sed -ne '/^Files:/,$s/^ ................................ [0-9][0-9]* //p' < $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE)
+}
+
+recipe_resultdirs_debootstrap() {
+    echo DEBS
+}
+
diff --git a/build-recipe-dsc b/build-recipe-dsc
new file mode 100644 (file)
index 0000000..9b3ca33
--- /dev/null
@@ -0,0 +1,111 @@
+#
+# dsc specific functions.
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+recipe_setup_dsc() {
+    TOPDIR=/usr/src/packages
+    rm -rf "$BUILD_ROOT$TOPDIR"
+    mkdir -p "$BUILD_ROOT$TOPDIR"
+    mkdir -p "$BUILD_ROOT$TOPDIR/OTHER"
+    mkdir -p "$BUILD_ROOT$TOPDIR/SOURCES"
+    mkdir -p "$BUILD_ROOT/$TOPDIR/DEBS"
+    chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
+    cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
+    # FIX to work with baselibs_$PROJ etc
+    if test -e "$MYSRCDIR/baselibs-deb.conf" ; then
+       echo "dsc build and baselibs-deb.conf present: forcing --baselibs to true"
+       CREATE_BASELIBS=true
+    fi
+}
+
+recipe_prepare_dsc() {
+    rm -rf "$BUILD_ROOT$TOPDIR/BUILD"
+    mkdir -p "$BUILD_ROOT$TOPDIR/SOURCES.DEB"
+    chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
+    DEB_TRANSFORM=
+    DEB_SOURCEDIR="$TOPDIR/SOURCES"
+    DEB_DSCFILE="$RECIPEFILE"
+    for f in $BUILD_ROOT$TOPDIR/SOURCES/debian.* ; do 
+       test -f $f && DEB_TRANSFORM=true
+    done
+    if test -n "$DEB_TRANSFORM" ; then 
+       CHANGELOGARGS=
+       test -n "$CHANGELOG" -a -f "$BUILD_ROOT/.build-changelog" && CHANGELOGARGS="--changelog $BUILD_ROOT/.build-changelog"
+       echo "running debian transformer..."
+        if [ "$RELEASE" ]; then
+          # remove rpm macros (everything after "%")
+          # they are not evaluated by the Debian build process
+          DEB_RELEASE=`sed 's/%.*$//' <<< $RELEASE`
+          echo "release: ($RELEASE), release (DEB) ($DEB_RELEASE)"
+                 RELEASEARGS="--release $DEB_RELEASE"
+        fi
+        if ! debtransform $CHANGELOGARGS $RELEASEARGS $BUILD_ROOT$TOPDIR/SOURCES $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE $BUILD_ROOT$TOPDIR/SOURCES.DEB ; then
+           echo "debian transforming failed."
+           cleanup_and_exit 1
+       fi
+       DEB_SOURCEDIR=$TOPDIR/SOURCES.DEB
+       for DEB_DSCFILE in $BUILD_ROOT/$DEB_SOURCEDIR/*.dsc ; do : ; done 
+       DEB_DSCFILE="${DEB_DSCFILE##*/}"
+    fi
+    chroot $BUILD_ROOT su -c "dpkg-source -x $DEB_SOURCEDIR/$DEB_DSCFILE $TOPDIR/BUILD" - $BUILD_USER
+}
+
+recipe_build_dsc() {
+    DSC_BUILD_OPTIONS=
+    if test -n "$BUILD_JOBS" ; then
+       DSC_BUILD_OPTIONS="parallel=${BUILD_JOBS}"
+    fi
+    # Checks to see if a build script should be used
+    # this allows the build environment to be manipulated
+    # and alternate build commands can be used
+    DSC_BUILD_CMD="$(queryconfig --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" substitute dsc:build_cmd)"
+    test -z "$DSC_BUILD_CMD" && DSC_BUILD_CMD="dpkg-buildpackage -us -uc"
+    if test -e $BUILD_ROOT/$TOPDIR/SOURCES/build.script ; then
+       echo "Sourcing build.script to build - it should normally run 'dpkg-buildpackage -us -uc'"
+       DSC_BUILD_CMD="source $TOPDIR/SOURCES/build.script"
+       chmod +x $BUILD_ROOT/$TOPDIR/SOURCES/build.script
+    fi
+
+    if test -n "$RUN_SHELL"; then
+       chroot $BUILD_ROOT su -
+    else
+       chroot $BUILD_ROOT su -c "export DEB_BUILD_OPTIONS=${DSC_BUILD_OPTIONS} ; cd $TOPDIR/BUILD && $DSC_BUILD_CMD" - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true
+       if test "$BUILD_SUCCEEDED" = true -a "$DO_CHECKS" != "false"; then
+          DEB_CHANGESFILE=${RECIPEFILE%.dsc}_"$(chroot $BUILD_ROOT su -c 'dpkg-architecture -qDEB_BUILD_ARCH')".changes
+          chroot $BUILD_ROOT su -c "which lintian > /dev/null && cd $TOPDIR && echo Running lintian && (set -x && lintian -i $DEB_SOURCEDIR/$DEB_DSCFILE)" - $BUILD_USER < /dev/null
+       fi
+    fi
+
+    for DEB in $BUILD_ROOT/$TOPDIR/*.deb ; do
+       test -e "$DEB" && mv "$DEB" "$BUILD_ROOT/$TOPDIR/DEBS"
+    done
+
+    # link used sources over to DEB directory
+    ln $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE $BUILD_ROOT/$TOPDIR/DEBS/
+    while read f ; do
+       ln $BUILD_ROOT/$DEB_SOURCEDIR/$f $BUILD_ROOT/$TOPDIR/DEBS/
+    done < <(sed -ne '/^Files:/,$s/^ ................................ [0-9][0-9]* //p' < $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE)
+}
+
+recipe_resultdirs_dsc() {
+    echo DEBS
+}
diff --git a/build-recipe-kiwi b/build-recipe-kiwi
new file mode 100644 (file)
index 0000000..6f8e6a1
--- /dev/null
@@ -0,0 +1,494 @@
+#
+# KIWI specific functions. Handle with care.
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+
+############################################################
+
+# post scriptlet generation functions
+
+kiwi_post_oem() {
+    cat <<-EOF
+       echo "compressing oem images... "
+       cd /$TOPDIR/KIWI-oem
+       # do not store compressed file _and_ uncompressed one
+       [ -e "$imageout.gz" ] && rm -f "$imageout"
+       if [ -e "$imageout.iso" ]; then
+           echo "take iso file and create sha256..."
+           mv "$imageout.iso" "/$TOPDIR/KIWI/$imageout$buildnum.iso"
+           pushd /$TOPDIR/KIWI
+           if [ -x /usr/bin/sha256sum ]; then
+               /usr/bin/sha256sum "$imageout$buildnum.iso" > "$imageout$buildnum.iso.sha256"
+           fi
+           popd
+       fi
+       if [ -e "$imageout.install.iso" ]; then
+           echo "take install.iso file and create sha256..."
+           mv "$imageout.install.iso" "/$TOPDIR/KIWI/$imageout$buildnum.install.iso"
+           pushd /$TOPDIR/KIWI
+           if [ -x /usr/bin/sha256sum ]; then
+               /usr/bin/sha256sum "$imageout$buildnum.install.iso" > "$imageout$buildnum.install.iso.sha256"
+           fi
+           popd
+       fi
+       if [ -e "$imageout.qcow2" ]; then
+           mv "$imageout.qcow2" "/$TOPDIR/KIWI/$imageout$buildnum.qcow2"
+           pushd /$TOPDIR/KIWI
+           if [ -x /usr/bin/sha256sum ]; then
+               echo "Create sha256 file..."
+               /usr/bin/sha256sum "$imageout$buildnum.qcow2" > "$imageout$buildnum.qcow2.sha256"
+           fi
+           popd
+       fi
+       if [ -e "$imageout.raw.install.raw" ]; then
+           compress_tool="bzip2"
+           compress_suffix="bz2"
+           if [ -x /usr/bin/xz ]; then
+               # take xz to get support for sparse files
+               compress_tool="xz -2"
+               compress_suffix="xz"
+           fi
+           mv "$imageout.raw.install.raw" "/$TOPDIR/KIWI/$imageout$buildnum.raw.install.raw"
+           pushd /$TOPDIR/KIWI
+           echo "\$compress_tool raw.install.raw file..."
+           \$compress_tool "$imageout$buildnum.raw.install.raw"
+           if [ -x /usr/bin/sha256sum ]; then
+               echo "Create sha256 file..."
+               /usr/bin/sha256sum "$imageout$buildnum.raw.install.raw.\${compress_suffix}" > "$imageout$buildnum.raw.install.raw.\${compress_suffix}.sha256"
+           fi
+           popd
+       fi
+       if [ -e "$imageout.raw" ]; then
+           compress_tool="bzip2"
+           compress_suffix="bz2"
+           if [ -x /usr/bin/xz ]; then
+               # take xz to get support for sparse files
+               compress_tool="xz -2"
+               compress_suffix="xz"
+           fi
+           mv "$imageout.raw" "/$TOPDIR/KIWI/$imageout$buildnum.raw"
+           pushd /$TOPDIR/KIWI
+           echo "\$compress_tool raw file..."
+           \$compress_tool "$imageout$buildnum.raw"
+           if [ -x /usr/bin/sha256sum ]; then
+               echo "Create sha256 file..."
+               /usr/bin/sha256sum "$imageout$buildnum.raw.\${compress_suffix}" > "$imageout$buildnum.raw.\${compress_suffix}.sha256"
+           fi
+           popd
+       fi
+       EOF
+}
+
+kiwi_post_vmx() {
+    cat <<-EOF
+       echo "compressing vmx images... "
+       cd /$TOPDIR/KIWI-vmx
+       compress_tool="bzip2"
+       compress_suffix="bz2"
+       if [ -x /usr/bin/xz ]; then
+           # take xz to get support for sparse files
+           compress_tool="xz -2"
+           compress_suffix="xz"
+       fi
+       VMXFILES=""
+       SHAFILES=""
+       for suffix in "ovf" "qcow2" "ova" "tar" "vhdfixed" "vhd"; do
+           if [ -e "$imageout.\$suffix" ]; then
+               if [ "\$suffix" == "vhd" -o "\$suffix" == "vhdfixed" ]; then 
+                   mv "$imageout.\$suffix" "/$TOPDIR/KIWI/$imageout$buildnum.\$suffix"
+                   pushd /$TOPDIR/KIWI
+                   echo "\$compress_tool \$suffix file..."
+                   \$compress_tool "$imageout$buildnum.\$suffix"
+                   SHAFILES="\$SHAFILES $imageout$buildnum.\$suffix.\${compress_suffix}"
+                   popd
+               elif [ "\$suffix" == "ovf" ]; then 
+                   mv "$imageout.\${suffix}/$imageout.\$suffix" "/$TOPDIR/KIWI/$imageout$buildnum.\$suffix"
+                   SHAFILES="\$SHAFILES $imageout$buildnum.\$suffix"
+               else 
+                   mv "$imageout.\$suffix" "/$TOPDIR/KIWI/$imageout$buildnum.\$suffix"
+                   SHAFILES="\$SHAFILES $imageout$buildnum.\$suffix"
+               fi
+           fi
+       done
+       # This option has a number of format parameters
+       for i in "$imageout.vmx" "$imageout.vmdk" "$imageout-disk*.vmdk"; do
+           test -e \$i && VMXFILES="\$VMXFILES \$i"
+       done
+       # take raw files as fallback
+       if [ -n "\$VMXFILES" ]; then
+           tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-vmx.tar.bz2" \$VMXFILES
+           SHAFILES="\$SHAFILES $imageout$buildnum-vmx.tar.bz2"
+       elif [ -z "\$SHAFILES" -a -e  "$imageout.raw" ]; then
+           mv "$imageout.raw" "/$TOPDIR/KIWI/$imageout$buildnum-vmx.raw"
+           pushd /$TOPDIR/KIWI
+           echo "\$compress_tool raw file..."
+           \$compress_tool "$imageout$buildnum-vmx.raw"
+           SHAFILES="\$SHAFILES $imageout$buildnum-vmx.raw.\${compress_suffix}"
+           popd
+       fi
+       if [ -e "$imageout.box" ]; then
+           tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-vmx-box.tar.bz2" $imageout.box $imageout.json
+           SHAFILES="\$SHAFILES $imageout$buildnum-vmx-box.tar.bz2"
+       fi
+       if [ -e "$imageout.xenconfig" ]; then
+           tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-vmx.tar.bz2" $imageout.xenconfig $imageout.raw initrd-*
+           SHAFILES="\$SHAFILES $imageout$buildnum-vmx.tar.bz2"
+       fi
+       # FIXME: do we need a single .raw file in any case ?
+
+       cd /$TOPDIR/KIWI
+       if [ -n "\$SHAFILES" -a -x /usr/bin/sha256sum ]; then
+           for i in \$SHAFILES; do
+               echo "Create sha256 file..."
+               /usr/bin/sha256sum "\$i" > "\$i.sha256"
+           done
+       fi
+       tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-raw.tar.bz2" \
+           --exclude="$imageout.iso" --exclude="$imageout.raw" --exclude="$imageout.qcow2" *
+       cd /$TOPDIR/KIWI
+       if [ -x /usr/bin/sha256sum ]; then
+           /usr/bin/sha256sum "$imageout$buildnum-raw.tar.bz2" > "$imageout$buildnum-raw.tar.bz2.sha256"
+       fi
+       EOF
+}
+
+kiwi_post_xen() {
+    cat <<-EOF
+       echo "compressing xen images... "
+       cd /$TOPDIR/KIWI-xen
+       # do not store compressed file _and_ uncompressed one
+       [ -e "$imageout.gz" ] && rm -f "$imageout"
+       tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-xen.tar.bz2" \
+               `grep ^kernel $imageout.xenconfig | cut -d'"'  -f2` \
+               `grep ^ramdisk $imageout.xenconfig | cut -d'"'  -f2` \
+               initrd-* \
+               "$imageout.xenconfig" \
+               "$imageout"
+       if [ -x /usr/bin/sha256sum ]; then
+           echo "Create sha256 file..."
+           cd $TOPDIR/KIWI
+           /usr/bin/sha256sum "$imageout$buildnum-xen.tar.bz2" > "$imageout$buildnum-xen.tar.bz2.sha256"
+       fi
+       EOF
+}
+
+kiwi_post_pxe() {
+    cat <<-EOF
+       echo "compressing pxe images... "
+       cd /$TOPDIR/KIWI-pxe
+       # do not store compressed file _and_ uncompressed one
+       [ -e "$imageout.gz" ] && rm -f "$imageout"
+       tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-pxe.tar.bz2" ${imageout}* initrd-*
+       if [ -x /usr/bin/sha256sum ]; then
+           echo "Create sha256 file..."
+           cd $TOPDIR/KIWI
+           /usr/bin/sha256sum "$imageout$buildnum-pxe.tar.bz2" > "$imageout$buildnum-pxe.tar.bz2.sha256"
+       fi
+       EOF
+}
+
+kiwi_post_iso() {
+    cat <<-EOF
+       cd /$TOPDIR/KIWI-iso
+       for i in *.iso; do
+           mv "\$i" "/$TOPDIR/KIWI/\${i%.iso}$buildnum.iso"
+       done
+       if [ -x /usr/bin/sha256sum ]; then
+           echo "creating sha256 sum for iso images... "
+           cd $TOPDIR/KIWI
+           for i in *.iso; do
+               /usr/bin/sha256sum "\$i" > "\$i.sha256"
+           done
+       fi
+       EOF
+}
+
+kiwi_post_tbz() {
+    cat <<-EOF
+       cd /$TOPDIR/KIWI-tbz
+       for i in *.tbz; do
+           file=\$(readlink -f "\$i")
+           [ -z "\$file" ] && echo readlink failed for $i
+           mv "\$file" "/$TOPDIR/KIWI/\${i%.tbz}$buildnum.tbz"
+       done
+       if [ -x /usr/bin/sha256sum ]; then
+           echo "creating sha256 sum for tar balls... "
+           cd $TOPDIR/KIWI
+           for i in *.tbz; do
+               /usr/bin/sha256sum "\$i" > "\$i.sha256"
+           done
+       fi
+       EOF
+}
+
+kiwi_post_unknown() {
+    cat <<-EOF
+       echo "compressing unkown images... "
+       cd /$TOPDIR/KIWI-$imgtype
+       # do not store compressed file _and_ uncompressed one
+       [ -e "$imageout.gz" ] && rm -f "$imageout"
+       tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-$imgtype.tar.bz2" *
+       if [ -x /usr/bin/sha256sum ]; then
+           echo "Create sha256 file..."
+           cd /$TOPDIR/KIWI
+           /usr/bin/sha256sum "$imageout$buildnum-$imgtype.tar.bz2" > "$imageout$buildnum-$imgtype.tar.bz2.sha256"
+       fi
+       EOF
+}
+
+############################################################
+
+recipe_setup_kiwi() {
+    TOPDIR=/usr/src/packages
+    mkdir -p "$BUILD_ROOT$TOPDIR"
+    mkdir -p "$BUILD_ROOT$TOPDIR/OTHER"
+    mkdir -p "$BUILD_ROOT$TOPDIR/SOURCES"
+    mkdir -p "$BUILD_ROOT$TOPDIR/KIWI"
+    chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
+    if test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then 
+       mv "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
+    else
+       if test -z "$LINKSOURCES" ; then 
+           cp -dLR "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
+       else
+           cp -lR "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
+       fi
+       if test "$?" != 0 ; then 
+           echo "source copy failed"
+           cleanup_and_exit 1
+       fi
+    fi
+
+    # extract macros from configuration
+    # some post scripts might call rpm-build and rely on the macros
+    queryconfig rawmacros --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" > $BUILD_ROOT/root/.rpmmacros
+}
+
+recipe_prepare_kiwi() {
+    :
+}
+
+## obsolete with current kiwi versions, only needed for kiwi 3.01 version
+run_suse_isolinux() {
+    for i in $BUILD_ROOT/$TOPDIR/KIWIROOT/main/* ; do
+       test -d "$i" || continue
+       i="${i##*/}"
+       test "$i" = scripts && continue
+       test "$i" != "${i%0}" && continue
+       chroot $BUILD_ROOT su -c "suse-isolinux $TOPDIR/KIWIROOT/main/$i $TOPDIR/KIWI/$i.iso" - $BUILD_USER
+    done
+}
+
+build_kiwi_product() {
+    echo "running kiwi --create-instsource..."
+    # runs always as abuild user
+    mkdir -p "$BUILD_ROOT/$TOPDIR/KIWIROOT"
+    # XXX: again?
+    chroot "$BUILD_ROOT" chown -R abuild.abuild "$TOPDIR"
+    chroot "$BUILD_ROOT" rm -rf "$TOPDIR/KIWIROOT"
+    ver=`chroot "$BUILD_ROOT" su -c "/usr/sbin/kiwi --version | sed -n 's,.*kiwi version v\(.*\),\1,p'"`
+    test -n "$ver" || ver=`chroot "$BUILD_ROOT" su -c "/usr/sbin/kiwi --version | sed -n 's,.* vnr: \(.*\),\1,p'"`
+    if test "${ver:0:1}" == "3" ; then
+        # old style kiwi 3 builds
+       chroot "$BUILD_ROOT" su -c "APPID=- LANG=POSIX /usr/sbin/kiwi --root $TOPDIR/KIWIROOT -v --logfile terminal -p $TOPDIR/SOURCES --instsource-local --create-instsource $TOPDIR/SOURCES" - abuild < /dev/null && BUILD_SUCCEEDED=true
+       test ${ver:2:2} == "01" && run_suse_isolinux
+    else
+       VERBOSE_OPTION="-v 2"
+       # broken kiwi version, not accepting verbose level
+        test "${ver:0:1}" == "4" -a "${ver:2:2}" -lt 90 && VERBOSE_OPTION="-v -v"
+       chroot "$BUILD_ROOT" su -c "APPID=- LANG=POSIX /usr/sbin/kiwi --root $TOPDIR/KIWIROOT $VERBOSE_OPTION --logfile terminal -p $TOPDIR/SOURCES --create-instsource $TOPDIR/SOURCES" - abuild < /dev/null && BUILD_SUCCEEDED=true
+    fi
+
+    # move created product to correct destination
+    for i in $BUILD_ROOT/$TOPDIR/KIWIROOT/main/* ; do
+       test -e "$i" || continue
+       f=${i##*/}
+       case $f in
+           *.iso) if [ -x /usr/bin/sha256sum ]; then
+                       /usr/bin/sha256sum "$i" > "$i.sha256"
+                       mv "$i.sha256" $BUILD_ROOT/$TOPDIR/KIWI/.
+                   fi
+                   mv "$i" $BUILD_ROOT/$TOPDIR/KIWI/. ;;
+           *.packages) mv $i $BUILD_ROOT/$TOPDIR/OTHER/. ;;
+           *.report) mv $i $BUILD_ROOT/$TOPDIR/OTHER/. ;;
+           scripts) ;;
+           *0) ;;
+           *) test -d $i -a "$drop_repo" != true  && mv $i $BUILD_ROOT/$TOPDIR/KIWI/. ;;
+       esac
+    done
+}
+
+build_kiwi_appliance() {
+    if test -z "$RUNNING_IN_VM" ; then
+       # NOTE: this must be done with the outer system, because it loads the dm-mod kernel modules, which needs to fit to the kernel.
+       echo "starting device mapper for kiwi..."
+       test -x /etc/init.d/boot.device-mapper && /etc/init.d/boot.device-mapper start
+    fi
+    RUN_BUNDLE="true"
+    for imgtype in $imagetype ; do
+       echo "running kiwi --prepare for $imgtype..."
+       # Do not use $BUILD_USER here, since we always need root permissions
+       chroot $BUILD_ROOT su -c "cd $TOPDIR/SOURCES && rm -rf $TOPDIR/KIWIROOT-$imgtype && kiwi --prepare $TOPDIR/SOURCES --logfile terminal --root $TOPDIR/KIWIROOT-$imgtype $KIWI_PARAMETERS" - root < /dev/null || cleanup_and_exit 1
+       echo "running kiwi --create for $imgtype..."
+       mkdir -p $BUILD_ROOT/$TOPDIR/KIWI-$imgtype
+       chroot $BUILD_ROOT su -c "cd $TOPDIR/SOURCES && kiwi --create $TOPDIR/KIWIROOT-$imgtype --logfile terminal --type $imgtype -d $TOPDIR/KIWI-$imgtype $KIWI_PARAMETERS" - root < /dev/null || cleanup_and_exit 1
+        rm -rf "/$TOPDIR/KIWI.bundle"
+        if chroot $BUILD_ROOT su -c "kiwi --bundle-build $TOPDIR/KIWI-$imgtype -d /$TOPDIR/KIWI.bundle/ --bundle-id Build$RELEASE" - root < /dev/null; then
+            mv "$BUILD_ROOT/$TOPDIR/KIWI.bundle/"* "$BUILD_ROOT/$TOPDIR/KIWI/" || cleanup_and_exit 1
+            rmdir "$BUILD_ROOT/$TOPDIR/KIWI.bundle"
+            unset RUN_BUNDLE
+        fi
+    done
+    BUILD_SUCCEEDED=true
+
+    if test -z "$RUN_BUNDLE"; then
+       # new kiwi has bundled our result already :)
+       return
+    fi
+
+    #
+    # Legacy bundling code for kiwi version below 5.06.106
+    #
+
+    # create tar.gz of images, in case it makes sense
+    buildnum=
+    if test -n "$RELEASE"; then
+       buildnum="-Build$RELEASE"
+    fi
+    imagearch=`uname -m`
+    imageout="$imagename.$imagearch-$imageversion"
+    for imgtype in $imagetype ; do
+       case "$imgtype" in
+           oem) kiwi_post_oem   > $BUILD_ROOT/kiwi_post.sh ;;
+           vmx) kiwi_post_vmx   > $BUILD_ROOT/kiwi_post.sh ;;
+           xen) kiwi_post_xen   > $BUILD_ROOT/kiwi_post.sh ;;
+           pxe) kiwi_post_pxe   > $BUILD_ROOT/kiwi_post.sh ;;
+           iso) kiwi_post_iso   > $BUILD_ROOT/kiwi_post.sh ;;
+           tbz) kiwi_post_tbz   > $BUILD_ROOT/kiwi_post.sh ;;
+           *) kiwi_post_unknown > $BUILD_ROOT/kiwi_post.sh ;;
+       esac
+       cat >> $BUILD_ROOT/kiwi_post.sh <<-EOF
+               cd /$TOPDIR/KIWI-$imgtype
+               if [ -e "$imageout.channel" ]; then
+                   echo "Found kiwi channel list file, exporting as well..."
+                   cp "$imageout.channel" "/$TOPDIR/OTHER/$imageout$buildnum-$imgtype.channel"
+               fi
+               if [ -e "$imageout.packages" ]; then
+                   echo "Found kiwi package list file, exporting as well..."
+                   cp "$imageout.packages" "/$TOPDIR/OTHER/$imageout$buildnum-$imgtype.packages"
+               fi
+               if [ -e "$imageout.verified" ]; then
+                   echo "Found rpm verification report, exporting as well..."
+                   cp "$imageout.verified" "/$TOPDIR/OTHER/$imageout$buildnum-$imgtype.verified"
+               fi
+               EOF
+       chroot $BUILD_ROOT su -c "sh -e /kiwi_post.sh" || cleanup_and_exit 1
+       rm -f $BUILD_ROOT/kiwi_post.sh
+    done
+}
+
+recipe_build_kiwi() {
+    imagetype=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $BUILD_ROOT/$TOPDIR/SOURCES/$RECIPEFILE imagetype)
+    imagename=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $BUILD_ROOT/$TOPDIR/SOURCES/$RECIPEFILE filename)
+    imageversion=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $BUILD_ROOT/$TOPDIR/SOURCES/$RECIPEFILE version)
+    drop_repo=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $BUILD_ROOT/$TOPDIR/SOURCES/$RECIPEFILE drop_repository)
+
+    # prepare rpms as source and createrepo on the repositories
+    ln -sf $TOPDIR/SOURCES/repos $BUILD_ROOT/repos
+    cd $BUILD_ROOT/$TOPDIR/SOURCES/repos
+    for r in */* ; do
+        test -L $r && continue
+        test -d $r || continue
+        repo="$TOPDIR/SOURCES/repos/$r/"
+        # create compatibility link for old kiwi versions
+        rc="${r//:/:/}"
+        if test "$rc" != "$r" ; then
+       rl="${rc//[^\/]}"
+       rl="${rl//?/../}"
+       mkdir -p "${rc%/*}"
+       ln -s $rl$r "${rc%/*}/${rc##*/}"
+       repo="$TOPDIR/SOURCES/repos/${rc%/*}/${rc##*/}/"
+        fi
+        if test "$imagetype" != product -a "$DO_INIT" != "false" ; then
+           echo "creating repodata for $repo"
+           if chroot $BUILD_ROOT createrepo --no-database --simple-md-filenames --help >/dev/null 2>&1 ; then
+               chroot $BUILD_ROOT createrepo --no-database --simple-md-filenames "$repo"
+           else
+               chroot $BUILD_ROOT createrepo "$repo"
+           fi
+        fi
+    done
+
+    # unpack root tar
+    for t in $BUILD_ROOT/$TOPDIR/SOURCES/root.tar* ; do
+       test -f $t || continue
+       mkdir -p $BUILD_ROOT/$TOPDIR/SOURCES/root
+       chroot $BUILD_ROOT tar -C $TOPDIR/SOURCES/root -xf "$TOPDIR/SOURCES/${t##*/}"
+    done
+
+    # fix script permissions
+    chmod a+x $BUILD_ROOT/$TOPDIR/SOURCES/*.sh 2>/dev/null
+
+    # unpack tar files in image directories
+    if test -d $BUILD_ROOT/$TOPDIR/SOURCES/images ; then
+       (
+       cd $BUILD_ROOT/$TOPDIR/SOURCES/images
+       for r in */* ; do
+           test -L $r && continue
+           test -d $r || continue
+           for t in $r/root.tar* ; do
+               test -f $t || continue
+               mkdir -p $r/root
+               chroot $BUILD_ROOT tar -C $TOPDIR/SOURCES/images/$r/root -xf "$TOPDIR/SOURCES/images/$r/${t##*/}"
+           done
+           # fix script permissions
+           chmod a+x $BUILD_ROOT/$TOPDIR/SOURCES/images/$r/*.sh 2>/dev/null
+           # create compatibility link for old kiwi versions
+           rc="${r//:/:/}"
+           if test "$rc" != "$r" ; then
+               rl="${rc//[^\/]}"
+               rl="${rl//?/../}"
+               mkdir -p "${rc%/*}"
+               ln -s $rl$r "${rc%/*}/${rc##*/}"
+           fi
+       done
+       )
+    fi
+
+    rm -f $BUILD_ROOT/$TOPDIR/SOURCES/config.xml
+    ln -s $RECIPEFILE $BUILD_ROOT/$TOPDIR/SOURCES/config.xml
+
+    if test "$imagetype" = product ; then
+       build_kiwi_product
+    else
+       build_kiwi_appliance
+    fi
+
+    # Hook for running post kiwi build scripts like QA scripts if installed
+    if test -x $BUILD_ROOT/usr/lib/build/kiwi_post_run ; then
+       chroot $BUILD_ROOT su -c /usr/lib/build/kiwi_post_run || cleanup_and_exit 1
+    fi
+}
+
+recipe_resultdirs_kiwi() {
+    echo KIWI
+}
diff --git a/build-recipe-livebuild b/build-recipe-livebuild
new file mode 100644 (file)
index 0000000..c9d3566
--- /dev/null
@@ -0,0 +1,225 @@
+#################################################################
+#
+# Debian live-build specific functions.
+#
+# Author: Jan Blunck <jblunck@infradead.org>
+#
+# This file is part of build.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+#################################################################
+
+recipe_setup_livebuild() {
+
+    TOPDIR=/usr/src/packages
+    rm -rf "$BUILD_ROOT$TOPDIR"
+    for i in OTHER SOURCES LIVEBUILD_ROOT ; do
+       mkdir -p "$BUILD_ROOT$TOPDIR/$i"
+    done
+    chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
+    if test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then
+       mv "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
+    else
+       cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
+    fi
+}
+
+recipe_prepare_livebuild() {
+    :
+}
+
+createrepo_debian() {
+    local DIR=${1}
+    local ARCH=${2}
+    local DIST=${3}
+
+    if [ -z "${DIR}" -o ! -d ${DIR} -o ${DIR} = ${DIR##${BUILD_ROOT}} ] ; then
+        return
+    fi
+
+    pushd ${DIR} >/dev/null
+
+    # cleanup existing repository files
+    rm -f Packages Packages.gz Release
+    rm -fr dists
+
+    mkdir -p dists/${DIST}
+    # Suite is symlinked to Codename
+    ln -s ${DIST} dists/stable
+
+    # create Packages and Sources files
+    mkdir -p dists/${DIST}/main/binary-${ARCH}
+    mkdir -p dists/${DIST}/main/source
+    cat > ${BUILD_ROOT}/.createrepo_debian.tmp.sh <<-EOF
+       cd /.build.binaries || exit 1
+       dpkg-scanpackages -m . > dists/${DIST}/main/binary-${ARCH}/Packages
+       gzip -c9 < dists/${DIST}/main/binary-${ARCH}/Packages \
+           > dists/${DIST}/main/binary-${ARCH}/Packages.gz
+       dpkg-scansources . > dists/${DIST}/main/source/Sources
+       gzip -c9 dists/${DIST}/main/source/Sources \
+           > dists/${DIST}/main/source/Sources.gz
+       EOF
+    chroot $BUILD_ROOT su -c "sh /.createrepo_debian.tmp.sh" - root
+    local RESULT=$?
+    rm -f $BUILD_ROOT/.createrepo_debian.tmp.sh
+    [ "${RESULT}" != 0 ] && return
+
+    # create Release file
+    pushd dists/${DIST} >/dev/null
+    cat > Release <<-EOF
+       Origin: Debian
+       Label: Debian
+       Suite: stable
+       Version: 7.1
+       Codename: ${DIST}
+       Date: Sat, 15 Jun 2013 10:55:26 UTC
+       Description: Debian repository created by build-recipe-livebuild
+       Components: main
+       EOF
+    echo "SHA256:" >> Release
+    for file in main/binary-${ARCH}/Packages* ; do
+        local SUM=( $(sha256sum ${file}) )
+        local SIZE=$(stat -c '%s' ${file})
+        echo " ${SUM} ${SIZE} ${file}" >> Release
+    done
+    for file in main/source/Sources* ; do
+        local SUM=( $(sha256sum ${file}) )
+        local SIZE=$(stat -c '%s' ${file})
+        echo " ${SUM} ${SIZE} ${file}" >> Release
+    done
+    popd >/dev/null
+
+    # TODO: this is missing the signature with the private key
+
+    popd >/dev/null
+}
+
+# This script expects that the $BUILD_ROOT is a Debian installation with
+# live-build already installed!
+#
+# Variables:
+# $BUILD_ROOT the Debian chroot
+# $TOPDIR/SOURCES includes the live-build config tarball
+# $TOPDIR/$LIVEBUILD_ROOT where live-build will be called
+# $RECIPEFILE the name of the live-build config tarball
+
+recipe_build_livebuild() {
+    local ARCH=$(chroot $BUILD_ROOT su -c "dpkg-architecture -qDEB_BUILD_ARCH")
+    local DIST=$(chroot $BUILD_ROOT su -c "lsb_release --codename" | awk '{ print $2 }')
+    local LIVEBUILD_ROOT="LIVEBUILD_ROOT"
+
+    [ -z "${ARCH}" -o -z "${DIST}" ] && cleanup_and_exit 1
+
+    test -d $BUILD_ROOT/.build.binaries || cleanup_and_exit 1
+    if test "$DO_INIT" = true -o ! -d "$BUILD_ROOT/.build.binaries/dists" ; then
+       echo "creating repository metadata..."
+        createrepo_debian $BUILD_ROOT/.build.binaries ${ARCH} ${DIST}
+    fi
+
+    # Write our default configuration variables
+    mkdir -p $BUILD_ROOT/etc/live
+    cat > $BUILD_ROOT/etc/live/build.conf <<-EOF
+       LB_DEBIAN_INSTALLER_DISTRIBUTION="${DIST}"
+       LB_DISTRIBUTION="${DIST}"
+       LB_PARENT_DISTRIBUTION="${DIST}"
+       LB_PARENT_DEBIAN_INSTALLER_DISTRIBUTION="${DIST}"
+       LB_PARENT_MIRROR_BOOTSTRAP="file:/.build.binaries/"
+       LB_PARENT_MIRROR_CHROOT="file:/.build.binaries/"
+       LB_PARENT_MIRROR_CHROOT_SECURITY="file:/.build.binaries/"
+       LB_PARENT_MIRROR_BINARY="file:/.build.binaries/"
+       LB_PARENT_MIRROR_BINARY_SECURITY="file:/.build.binaries/"
+       LB_PARENT_MIRROR_DEBIAN_INSTALLER="file:/.build.binaries/"
+       LB_MIRROR_BOOTSTRAP="file:/.build.binaries/"
+       LB_MIRROR_CHROOT="file:/.build.binaries/"
+       LB_MIRROR_CHROOT_SECURITY="file:/.build.binaries/"
+       LB_MIRROR_BINARY="file:/.build.binaries/"
+       LB_MIRROR_BINARY_SECURITY="file:/.build.binaries/"
+       LB_MIRROR_DEBIAN_INSTALLER="file:/.build.binaries/"
+       LB_APT_SECURE="false"
+       EOF
+
+    # Expand live-build configuration to $TOPDIR/$LIVEBUILD_ROOT
+    echo "Expanding live-build configuration"
+    tar -xvf $BUILD_ROOT/$TOPDIR/SOURCES/$RECIPEFILE \
+       -C $BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT || cleanup_and_exit 1
+
+    # Skip top-level directory if it matches recipe name, ...
+    local files=($BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT/*)
+    # ... but ignore some well known names
+    files=(${files[@]%%*/auto})
+    files=(${files[@]%%*/config})
+    files=(${files[@]%%*/local})
+    if [ ${#files[@]} -eq 1 ] && \
+       [ -d $BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT/${RECIPEFILE%.livebuild} ]
+    then
+       LIVEBUILD_ROOT="LIVEBUILD_ROOT/${RECIPEFILE%.livebuild}"
+    fi
+
+    # Sanity check to not configure archives inside configuration
+    files=($BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT/config/archives/*)
+    [ ${#files[@]} -gt 0 ] && cleanup_and_exit 1
+
+    # TODO: Add the repository public key
+    # cp ... $BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT/config/archives/debian.key
+
+    if [ -x $BUILD_ROOT/usr/lib/build/livebuild_pre_run ] ; then
+       echo "Running OBS build livebuild_pre_run hook"
+       chroot $BUILD_ROOT su -c "/usr/lib/build/livebuild_pre_run" - root \
+           < /dev/null || cleanup_and_exit 1
+    fi
+
+    # TODO: this might move to lb auto/config file
+    if [ -f $BUILD_ROOT/$TOPDIR/SOURCES/livebuild_pre_run ] ; then
+       cp $BUILD_ROOT/$TOPDIR/SOURCES/livebuild_pre_run \
+           $BUILD_ROOT/.build.livebuild_pre_run
+       chmod +x $BUILD_ROOT/.build.livebuild_pre_run
+       echo "Running package livebuild_pre_run hook"
+       chroot $BUILD_ROOT su -c "/.build.livebuild_pre_run" - root \
+           < /dev/null || cleanup_and_exit 1
+    fi
+
+    chroot $BUILD_ROOT su -c "cd $TOPDIR/$LIVEBUILD_ROOT && lb build" - root \
+       < /dev/null || cleanup_and_exit 1
+
+    # Move created product to destination
+    for i in $BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT/* ; do
+       test -f "$i" || continue
+       case "${i##*/}" in
+           *.iso)
+               # all created files share the same name without suffix
+               mv ${i%%.iso}.* $BUILD_ROOT/$TOPDIR/OTHER/.
+               BUILD_SUCCEEDED=true
+               ;;
+           *)
+               ;;
+       esac
+    done
+
+    # Fail the build if no ISO was created
+    if [ -z "$(ls $BUILD_ROOT/$TOPDIR/OTHER/*.iso)" ] ; then
+       echo "No ISO image found"
+       cleanup_and_exit 1
+    fi
+}
+
+recipe_resultdirs_livebuild() {
+    # our results are already in OTHER
+    :
+}
+
+# Local Variables:
+# mode: Shell-script
+# End:
diff --git a/build-recipe-mock b/build-recipe-mock
new file mode 100644 (file)
index 0000000..3298fce
--- /dev/null
@@ -0,0 +1,100 @@
+#
+# mock specific functions.
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+recipe_setup_mock() {
+    recipe_setup_spec "$@"
+}
+
+recipe_prepare_mock() {
+    recipe_prepare_spec "$@"
+}
+
+recipe_build_mock() {
+    test -d $BUILD_ROOT/.build.binaries || cleanup_and_exit 1
+    if test "$DO_INIT" = true -o ! -d "$BUILD_ROOT/.build.binaries/repodata" ; then
+       echo "creating repository for mock..."
+       chroot $BUILD_ROOT createrepo --no-database --basedir /.build.binaries -o /.build.binaries /.build.binaries
+    fi
+    MOCK_CHROOT_SETUP_CMD="$(queryconfig --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" substitute mock:chroot_setup_cmd)"
+    test -z "$MOCK_CHROOT_SETUP_CMD" && MOCK_CHROOT_SETUP_CMD="groupinstall buildsys-build"
+    echo "config_opts['root'] = 'build'" > $BUILD_ROOT/etc/mock/build.cfg
+    echo "config_opts['target_arch'] = '${BUILD_ARCH%%:*}'" >> $BUILD_ROOT/etc/mock/build.cfg
+    echo "config_opts['plugin_conf']['ccache_enable'] = False" >> $BUILD_ROOT/etc/mock/build.cfg
+    echo "config_opts['chroot_setup_cmd'] = '$MOCK_CHROOT_SETUP_CMD'" >> $BUILD_ROOT/etc/mock/build.cfg
+    cat >> $BUILD_ROOT/etc/mock/build.cfg <<-'EOF'
+       config_opts['yum.conf'] = """
+       [main]
+       cachedir=/var/cache/yum
+       debuglevel=1
+       reposdir=/dev/null
+       logfile=/var/log/yum.log
+       obsoletes=1
+       gpgcheck=0
+       assumeyes=1
+       syslog_ident=mock
+       syslog_device=
+
+       [build]
+       name=build
+       baseurl=file:///.build.binaries
+       """
+       EOF
+    touch $BUILD_ROOT/etc/resolv.conf
+    BUILD_SUCCEEDED=false
+    echo "building src rpm..."
+    MOCK_INIT_ARG=
+    test "$DO_INIT" = true || MOCK_INIT_ARG=--no-clean
+    if chroot $BUILD_ROOT /usr/bin/mock -r build $MOCK_INIT_ARG --buildsrpm --spec "$TOPDIR/SOURCES/$RECIPEFILE" --sources "$TOPDIR/SOURCES" ; then
+       BUILT_SRPM=
+       for i in "$BUILD_ROOT/var/lib/mock/build/result/"*src.rpm ; do
+           test -s "$i" && BUILT_SRPM="${i##*/}"
+       done
+       if test -n "$BUILT_SRPM" ; then
+           mkdir -p "$BUILD_ROOT/$TOPDIR/SRPMS"
+           mv "$BUILD_ROOT/var/lib/mock/build/result/$BUILT_SRPM" "$BUILD_ROOT/$TOPDIR/SRPMS/$BUILT_SRPM"
+           echo "building binary rpms..."
+           if chroot $BUILD_ROOT /usr/bin/mock -v -r build --rebuild --no-clean "$TOPDIR/SRPMS/$BUILT_SRPM" ; then
+               BUILD_SUCCEEDED=true
+               # move result over to TOPDIR
+               rm -f "$TOPDIR/SRPMS/$BUILT_SRPM"
+               for i in "$BUILD_ROOT/var/lib/mock/build/result/"*.rpm ; do
+                   a="${i%.rpm}"
+                   a="${a##*/}"
+                   a="${a##*.}"
+                   if test "$a" = src -o "$a" = nosrc ; then
+                       mkdir -p "$BUILD_ROOT/$TOPDIR/SRPMS"
+                       mv $i "$BUILD_ROOT/$TOPDIR/SRPMS/."
+                   else
+                       mkdir -p "$BUILD_ROOT/$TOPDIR/RPMS/$a"
+                       mv $i "$BUILD_ROOT/$TOPDIR/RPMS/$a/."
+                   fi
+               done
+           fi
+       fi
+    fi
+}
+
+recipe_resultdirs_mock() {
+    echo RPMS SRPMS
+}
+
diff --git a/build-recipe-preinstallimage b/build-recipe-preinstallimage
new file mode 100644 (file)
index 0000000..446236f
--- /dev/null
@@ -0,0 +1,79 @@
+#
+# preinstall specific functions.
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+recipe_setup_preinstallimage() {
+    # should never be called
+    cleanup_and_exit 1
+}
+
+recipe_prepare_preinstallimage() {
+    :
+}
+
+recipe_build_preinstallimage() {
+    echo "creating preinstall image..."
+    test -d "$BUILD_ROOT/.preinstall_image" || cleanup_and_exit 1
+    cd $BUILD_ROOT || cleanup_and_exit 1
+    TAR="tar"
+    if test -x /usr/bin/bsdtar; then
+       TAR="/usr/bin/bsdtar --format gnutar --chroot"
+    fi
+    TOPDIRS=
+    for DIR  in .* * ; do
+      case "$DIR" in
+       .|..) continue ;;
+       .build.kernel*) ;; # to be packaged
+       .build.initrd*) ;; # to be packaged
+       .build*) continue ;;
+       .preinstallimage*) continue ;;
+       .srcfiles*) continue ;;
+       .pkgs) continue ;;
+       .rpm-cache) continue ;;
+       installed-pkg) continue ;;
+       proc|sys) continue ;;
+      esac
+      TOPDIRS="$TOPDIRS $DIR"
+    done
+    if ! $TAR -czf .preinstallimage.$$.tar.gz --one-file-system $TOPDIRS ; then
+       cleanup_and_exit 1
+    fi
+    echo "image created."
+    TOPDIR=/usr/src/packages
+    mkdir -p $BUILD_ROOT$TOPDIR/OTHER
+    rm -f $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.info
+    for PKG in $BUILD_ROOT/.preinstall_image/* ; do
+       PKG=${PKG##*/}
+       read PKG_HDRMD5 PKGID < $BUILD_ROOT/.preinstall_image/$PKG
+       test -n "$PKG_HDRMD5" || cleanup_and_exit 1
+       echo "$PKG_HDRMD5  $PKG" >> $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.info
+    done
+    mv $BUILD_ROOT/.preinstallimage.$$.tar.gz $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.tar.gz
+    rm -f $BUILD_ROOT/.build.packages
+    ln -s ${TOPDIR#/} $BUILD_ROOT/.build.packages
+    test -d "$SRCDIR" && cd "$SRCDIR"
+}
+
+recipe_resultdirs_preinstallimage() {
+    :
+}
+
diff --git a/build-recipe-spec b/build-recipe-spec
new file mode 100644 (file)
index 0000000..c9a948c
--- /dev/null
@@ -0,0 +1,261 @@
+#
+# spec specific functions.
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+recipe_setup_spec() {
+    TOPDIR=`chroot $BUILD_ROOT su -c "rpm --eval '%_topdir'" - $BUILD_USER`
+    if test -z "$TOPDIR"; then
+       echo "Error: TOPDIR empty"
+       cleanup_and_exit 1
+    fi
+    if [ "$NO_TOPDIR_CLEANUP" = false ]; then
+        rm -rf "$BUILD_ROOT$TOPDIR"
+        for i in BUILD RPMS/`uname -m` RPMS/i386 RPMS/noarch SOURCES SPECS SRPMS BUILDROOT OTHER ; do
+            mkdir -p $BUILD_ROOT$TOPDIR/$i
+        done
+    fi
+
+    chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
+    mkdir -p $BUILD_ROOT$TOPDIR/SOURCES
+    cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
+}
+
+recipe_prepare_spec() {
+    args=()
+    if test -n "$RELEASE"; then
+       args=(--release "$RELEASE")
+    fi
+
+    # fixup specfile
+    CHANGELOGARGS=
+    test -n "$CHANGELOG" -a -f "$BUILD_ROOT/.build-changelog" && CHANGELOGARGS="--changelog $BUILD_ROOT/.build-changelog"
+    substitutedeps "${args[@]}" --root "$BUILD_ROOT" --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" $CHANGELOGARGS "$BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE" "$BUILD_ROOT/.spec.new" || cleanup_and_exit 1
+
+    # fix rpmrc if we are compiling for i686
+    test -f $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 && mv $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 $BUILD_ROOT/usr/lib/rpm/rpmrc
+    if test -e $BUILD_ROOT/usr/lib/rpm/rpmrc -a "$BUILD_ARCH" != "${BUILD_ARCH#i686}" ; then
+       mv $BUILD_ROOT/usr/lib/rpm/rpmrc $BUILD_ROOT/usr/lib/rpm/rpmrc_i586
+       sed -e 's/^buildarchtranslate: athlon.*/buildarchtranslate: athlon: i686/' -e 's/^buildarchtranslate: i686.*/buildarchtranslate: i686: i686/' < $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 > $BUILD_ROOT/usr/lib/rpm/rpmrc
+    fi
+    if test "$DO_BUILD" = false ; then
+        cleanup_and_exit 0
+    fi
+
+    # extract macros from configuration
+    queryconfig rawmacros --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" > $BUILD_ROOT/root/.rpmmacros
+    if test -n "$BUILD_DEBUG" ; then
+       echo '
+%prep %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%prep
+%package %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%package
+%_build_insert_debug_package \
+%global __debug_package 1 \
+%undefine _enable_debug_packages \
+%debug_package
+
+' >> $BUILD_ROOT/root/.rpmmacros
+    fi
+
+    if test -n "$BUILD_JOBS" ; then
+       cat >> $BUILD_ROOT/root/.rpmmacros <<-EOF
+               %jobs $BUILD_JOBS
+               %_smp_mflags -j$BUILD_JOBS
+               EOF
+    fi
+    test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmmacros $BUILD_ROOT/home/abuild/.rpmmacros
+
+    # extract optflags from configuration
+    queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" optflags ${BUILD_DEBUG:+debug} > $BUILD_ROOT/root/.rpmrc
+    test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmrc $BUILD_ROOT/home/abuild/.rpmrc
+
+    if test -z "$ABUILD_TARGET"; then
+       ABUILD_TARGET=$(queryconfig target --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" )
+       test -z "$ABUILD_TARGET" || echo "build target is $ABUILD_TARGET"
+    fi
+
+    # report specfile changes
+    if test -f $BUILD_ROOT/.spec.new ; then
+       if ! cmp -s $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE $BUILD_ROOT/.spec.new ; then
+           echo -----------------------------------------------------------------
+           echo "I have the following modifications for $RECIPEFILE:"
+           sed -e "/^%changelog/q" $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE > $BUILD_ROOT/.spec.t1
+           sed -e "/^%changelog/q" $BUILD_ROOT/.spec.new > $BUILD_ROOT/.spec.t2
+           diff $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2
+           rm -f $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2
+           mv $BUILD_ROOT/.spec.new $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE
+       else
+           rm -f $BUILD_ROOT/.spec.new
+       fi
+    fi
+}
+
+recipe_build_spec() {
+    test -z "$BUILD_RPM_BUILD_STAGE" && BUILD_RPM_BUILD_STAGE=-ba
+
+    rpmbuild=rpmbuild
+    test -x $BUILD_ROOT/usr/bin/rpmbuild || rpmbuild=rpm
+
+    # XXX: move _srcdefattr to macro file?
+    rpmbopts=("--define" "_srcdefattr (-,root,root)")
+    if test "$DO_CHECKS" != true ; then
+       rpmbopts[${#rpmbopts[@]}]="--nocheck"
+    fi
+    if test "$rpmbuild" == "rpmbuild" ; then
+           # use only --nosignature for rpm v4
+       rpmbopts[${#rpmbopts[@]}]="--nosignature"
+    fi
+    if test -n "$ABUILD_TARGET" ; then
+       rpmbopts[${#rpmbopts[@]}]="--target=$ABUILD_TARGET"
+    fi
+    if test -n "$BUILD_DEBUG" ; then
+       rpmbopts[${#rpmbopts[@]}]='--define'
+       rpmbopts[${#rpmbopts[@]}]="_build_create_debug 1"
+    fi
+    if test -n "$DISTURL" ; then
+       rpmbopts[${#rpmbopts[@]}]='--define'
+       rpmbopts[${#rpmbopts[@]}]="disturl $DISTURL"
+    fi
+    if test -n "$RSYNCDONE" ; then
+       rpmbopts[${#rpmbopts[@]}]='--define'
+       rpmbopts[${#rpmbopts[@]}]="RSYNCDONE 1"
+    fi
+
+    # su involves a shell which would require even more
+    # complicated quoting to bypass than this
+    if test "$SHORT_CIRCUIT" = false ; then
+        rpmbopts[${#rpmbopts[@]}]="$BUILD_RPM_BUILD_STAGE"
+        toshellscript $rpmbuild \
+                "${definesnstuff[@]}" \
+                "${rpmbopts[@]}" \
+                "$TOPDIR/SOURCES/$RECIPEFILE" \
+                > $BUILD_ROOT/.build.command
+    else
+        rpmbopts[${#rpmbopts[@]}]='--short-circuit'
+        buildopts="-bc -bi -bb -bs"
+        cmds=""
+        echo "#!/bin/sh -x" >$BUILD_ROOT/.build.command
+        echo "set -e" >>$BUILD_ROOT/.build.command
+        for opt in $buildopts
+        do
+            shellquote $rpmbuild  \
+                    "${definesnstuff[@]}" \
+                    "${rpmbopts[@]}" $opt \
+                    "$TOPDIR/SOURCES/$RECIPEFILE" \
+                    >> $BUILD_ROOT/.build.command
+            echo >>$BUILD_ROOT/.build.command
+            [ "$opt" == "$BUILD_RPM_BUILD_STAGE" ] && break
+        done
+    fi
+
+    chmod 755 $BUILD_ROOT/.build.command
+    check_exit
+    if test -n "$RUN_SHELL"; then
+       chroot $BUILD_ROOT su -
+    else
+       chroot $BUILD_ROOT su -c /.build.command - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true
+    fi
+}
+
+recipe_resultdirs_spec() {
+    echo RPMS SRPMS
+}
+
+recipe_unpack_srcrpm() {
+    test -n "$LIST_STATE" || echo "processing src rpm $SRCDIR/$RECIPEFILE ..."
+    MYSRCDIR="$BUILD_ROOT/.build-srcdir"
+    rm -rf "$MYSRCDIR"
+    mkdir -p "$MYSRCDIR"
+    cd $MYSRCDIR || cleanup_and_exit 1
+    $BUILD_DIR/unrpm -q $SRCDIR/$RECIPEFILE || {
+       echo "could not unpack $RECIPEFILE."
+       cleanup_and_exit 1
+    }
+    for RECIPEFILE in *.spec ; do : ; done
+}
+
+# post build functions... move somewhere else?
+
+recipe_check_file_owners() {
+    echo "... checking for files with abuild user/group"
+    BADFILE=
+    while read un gn fn ; do
+        if test "$un" = abuild -o "$gn" = abuild -o "$un" = ${ABUILD_UID} -o "$gn" = ${ABUILD_GID} ; then
+            echo "  $un $gn $fn"
+            BADFILE=true
+        fi
+    done < <(rpm -qp --qf '[%{FILEUSERNAME} %{FILEGROUPNAME} %{FILENAMES}\n]' $RPMS)
+    if test -n "$BADFILE" ; then
+        echo "please fix your filelist (e.g. add defattr)"
+        cleanup_and_exit 1
+    fi
+}
+
+recipe_run_rpmlint() {
+    if ! test -x "$BUILD_ROOT/opt/testing/bin/rpmlint" ; then 
+       return
+    fi
+    LINT_RPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/RPMS \
+       \( -name "*-debuginfo-*" -o -name "*-debugsource-*" \
+       -o -name "*-32bit-*" -o -name "*-64bit-*" \
+       -o -name "*-x86-*" -o -name "*-ia32-*" \) -prune \
+       -o -type f -name '*.rpm' -print))
+    SRPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/SRPMS -type f -name "*.rpm"))
+    echo 
+    echo "RPMLINT report:"
+    echo "==============="
+    rpmlint_logfile=$TOPDIR/OTHER/rpmlint.log
+    rm -f "$BUILD_ROOT$rpmlint_logfile"
+    ret=0
+    mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null
+    chroot $BUILD_ROOT su -s /opt/testing/bin/rpmlint "$BUILD_USER" -- \
+           --info ${LINT_RPM_FILE_LIST[*]#$BUILD_ROOT} \
+           ${SRPM_FILE_LIST[*]#$BUILD_ROOT} > "$BUILD_ROOT$rpmlint_logfile" || ret=1
+    cat "$BUILD_ROOT$rpmlint_logfile"
+    echo
+    umount -n $BUILD_ROOT/proc 2>/dev/null || true 
+    if test "$ret" = 1 ; then 
+       cleanup_and_exit 1
+    fi   
+}
+
+recipe_compare_oldpackages() {
+    if test -x "$BUILD_ROOT/usr/lib/build/same-build-result.sh" ; then 
+       echo "... comparing built packages with the former built"
+       mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null
+       if chroot $BUILD_ROOT /usr/lib/build/same-build-result.sh /.build.oldpackages "$TOPDIR/RPMS" "$TOPDIR/SRPMS"; then 
+           chroot $BUILD_ROOT touch /.build/.same_result_marker
+           # XXX: dirty build service hack. fix bs_worker. Search for
+           # 'same_result_marker' for traces of a first try to get rid of this
+           if test -n "$REASON" -a -n "$DISTURL" ; then 
+               exitcode=2
+           fi
+       fi
+       umount -n $BUILD_ROOT/proc 2>/dev/null || true 
+    fi   
+}
+
+recipe_create_deltarpms() {
+    if test -x "$BUILD_ROOT/usr/bin/makedeltarpm" -a -x $BUILD_ROOT/usr/lib/build/mkdrpms ; then
+       echo "... creating delta rpms"
+       ds=("$BUILD_ROOT/$TOPDIR"/RPMS/* "$BUILD_ROOT$TOPDIR/SRPMS")
+       chroot $BUILD_ROOT /usr/lib/build/mkdrpms /.build.oldpackages "${ds[@]#$BUILD_ROOT}"
+    fi
+}
diff --git a/build-vm b/build-vm
new file mode 100644 (file)
index 0000000..01070d9
--- /dev/null
+++ b/build-vm
@@ -0,0 +1,828 @@
+#
+# VM specific functions for the build script
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+# defaults for vm_img_mkfs
+vm_img_mkfs_ext4_options='-O ^has_journal,^huge_file,^resize_inode,sparse_super'
+vm_img_mkfs_ext4_extra='-E lazy_itable_init,discard'
+vm_img_mkfs_ext4="mkfs.ext4 -m 0 -q -F $vm_img_mkfs_ext4_options"
+vm_img_tunefs_ext4='tune2fs -c 0'
+vm_img_mkfs_ext3='mkfs.ext3 -m 0 -q -F'
+vm_img_tunefs_ext3='tune2fs -c 0 -o journal_data_writeback'
+vm_img_mkfs_ext2='mkfs.ext2 -m 0 -q -F'
+vm_img_tunefs_ext2='tune2fs -c 0'
+vm_img_mkfs_reiserfs='mkreiserfs -q -f'
+vm_img_mkfs_btrfs='mkfs.btrfs'
+vm_img_mkfs_xfs='mkfs.xfs -f'
+
+# guest visible swap device
+VM_SWAPDEV=/dev/hda2
+
+VM_TYPE=
+VM_IMAGE=
+VM_SWAP=
+VM_KERNEL=
+VM_INITRD=
+VM_WORKER=
+VM_SERVER=
+VM_MEMSIZE=
+VMDISK_ROOTSIZE=4096
+VMDISK_SWAPSIZE=1024
+VMDISK_FILESYSTEM=
+VMDISK_MOUNT_OPTIONS=__default
+VMDISK_CLEAN=
+
+# zvm specific?
+VM_WORKER_NR=
+
+# kvm specific?
+HUGETLBFSPATH=
+
+# emulator specific?
+EMULATOR_SCRIPT=
+
+for i in ec2 emulator kvm lxc openstack qemu uml xen zvm ; do
+    . "$BUILD_DIR/build-vm-$i"
+done
+
+VM_WATCHDOG=
+VM_WATCHDOG_PID=
+
+# the following functions just call the corresponding vm versions
+vm_kill() {
+    vm_kill_$VM_TYPE "$@"
+}
+
+vm_verify_options() {
+    vm_verify_options_$VM_TYPE "$@"
+}
+
+vm_attach_root() {
+    vm_attach_root_$VM_TYPE "$@"
+}
+
+vm_attach_swap() {
+    vm_attach_swap_$VM_TYPE "$@"
+}
+
+vm_detach_root() {
+    vm_detach_root_$VM_TYPE "$@"
+}
+
+vm_detach_swap() {
+    vm_detach_swap_$VM_TYPE "$@"
+}
+
+vm_fixup() {
+    vm_fixup_$VM_TYPE "$@"
+}
+
+vm_startup() {
+    vm_startup_$VM_TYPE "$@"
+}
+
+vm_kill() {
+    vm_kill_$VM_TYPE "$@"
+}
+
+vm_cleanup() {
+    kill_watchdog
+    vm_cleanup_$VM_TYPE "$@"
+}
+
+vm_parse_options() {
+    case ${PARAM/#--/-} in
+      -vm-emulator-script|-emulator-script)
+       needarg
+       EMULATOR_SCRIPT="$ARG"
+       shift
+      ;;
+      -xen|-kvm|-uml|-qemu|-emulator)
+       VM_TYPE=${PARAM##*-}
+       test -z "$VM_IMAGE" && VM_IMAGE=1
+       if test -n "$ARG" ; then
+           VM_IMAGE="$ARG"
+           shift
+       fi
+      ;;
+      -zvm|-lxc)
+        VM_TYPE=${PARAM##*-}
+       shift
+      ;;
+      -vm-type)
+       needarg
+       VM_TYPE="$ARG"
+       case "$VM_TYPE" in
+           lxc) ;;
+           ec2|xen|kvm|uml|qemu|emulator|openstack|zvm)
+               test -z "$VM_IMAGE" && VM_IMAGE=1
+           ;;
+           none|chroot) VM_TYPE= ;;
+           *)
+               echo "VM '$VM_TYPE' is not supported"
+               cleanup_and_exit
+           ;;
+       esac
+       shift
+      ;;
+      -vm-worker)
+        needarg
+        VM_WORKER="$ARG"
+        shift
+      ;;
+      -vm-worker-nr|-vm-worker-no)
+        needarg
+        VM_WORKER_NR="$ARG"
+        shift
+      ;;
+      -vm-server|-vm-region)
+       needarg
+       VM_SERVER="$ARG"
+       shift
+      ;;
+      -vm-volumes)
+       needarg
+       VM_VOLUME_NAME="$ARG"
+       shift
+        ARG="$1"
+        test "$ARG" = "${ARG#-}" || ARG=
+       needarg
+       VM_VOLUME_SWAP="$ARG"
+       shift
+      ;;
+      -vm-disk)
+       needarg
+       VM_IMAGE="$ARG"
+       shift
+      ;;
+      -vm-swap|-xenswap|-swap)
+       needarg
+       VM_SWAP="$ARG"
+       shift
+      ;;
+      -vm-memory|-xenmemory|-memory)
+       needarg
+       VM_MEMSIZE="$ARG"
+       shift
+      ;;
+      -vm-kernel)
+       needarg
+       VM_KERNEL="$ARG"
+       shift
+      ;;
+      -vm-initrd)
+       needarg
+       VM_INITRD="$ARG"
+       shift
+      ;;
+      -vm-disk-size|-vmdisk-rootsize)
+       needarg
+       VMDISK_ROOTSIZE="$ARG"
+       shift
+      ;;
+      -vm-swap-size|-vmdisk-swapsize)
+       needarg
+       VMDISK_SWAPSIZE="$ARG"
+       shift
+      ;;
+      -vm-disk-filesystem|-vmdisk-filesystem)
+       needarg
+       VMDISK_FILESYSTEM="$ARG"
+       shift
+      ;;
+      -vm-disk-mount-options|-vmdisk-mount-options)
+       needarg
+       # options needs to be quoted to handle argument which might start with "-o ..."
+       VMDISK_MOUNT_OPTIONS=$(echo $ARG | sed 's/^\"\(.*\)\"$/\1/g')
+       shift
+      ;;
+      -vm-disk-clean|-vmdisk-clean)
+       # delete old root/swap to get rid of the old blocks
+        VMDISK_CLEAN=true
+      ;;
+      -vm-hugetlbfs|-hugetlbfs)
+       needarg
+       HUGETLBFSPATH="$ARG"
+       shift
+      ;;
+      -vm-watchdog)
+       VM_WATCHDOG=true
+      ;;
+      -*)
+       return 1
+      ;;
+    esac
+    nextargs=("$@")
+    return 0
+}
+
+
+#
+# shutdown the system from inside the VM
+#
+vm_shutdown() {
+    test -n "$VM_WATCHDOG" && echo "### WATCHDOG MARKER START ###"
+    cd /
+    test -n "$1" || set 1
+    if test -n "$VM_SWAP" -a -e "$VM_SWAP" ; then
+       swapoff "$VM_SWAP" 2>/dev/null
+       echo -n "BUILDSTATUS$1" >"$VM_SWAP"
+    fi
+    exec >&0 2>&0      # so that the logging tee finishes
+    sleep 1            # wait till tee terminates
+    test "$VM_TYPE" = lxc && exit $1
+    kill -9 -1        # goodbye cruel world
+    if ! test -x /sbin/halt ; then
+       test -e /proc/sysrq-trigger || mount -n -tproc none /proc
+       sync
+       sleep 2 # like halt does
+       if test -e /proc/sysrq-trigger; then
+           echo o > /proc/sysrq-trigger
+           sleep 5 # wait for sysrq to take effect
+       else
+           echo "Warning: VM doesn't support sysrq and /sbin/halt not installed"
+       fi
+    else
+       sync    # halt from systemd is not syncing anymore.
+       halt -f -p
+    fi
+    echo "Warning: clean shut down of the VM didn't work"
+    exit $1    # init died...
+}
+
+vm_img_create() {
+    local img="$1"
+    local size="$2"
+
+    echo "Creating $img (${size}M)"
+    mkdir -p "${img%/*}" || cleanup_and_exit 3
+
+    # prefer fallocate, which avoids fragmentation
+    r=1
+    if type -p fallocate > /dev/null ; then
+        fallocate -l "${size}M" "$img"
+        r=$?
+    fi
+    # fall back to dd method if fallocate is not supported
+    if test "$r" -gt 0 ; then
+        dd if=/dev/zero of="$img" bs=1M count=0 seek="$size" || cleanup_and_exit 3
+    fi
+}
+
+vm_img_mkfs() {
+    local fs="$1"
+    local img="$2"
+    local mkfs tunefs
+    eval "mkfs=\"\$vm_img_mkfs_${fs}\""
+    eval "mkfs_exta_options=\"\$vm_img_mkfs_${fs}_extra\""
+    eval "tunefs=\"\$vm_img_tunefs_${fs}\""
+
+    if test -z "$mkfs"; then
+       echo "filesystem \"$fs\" is not supported"
+       cleanup_and_exit 3
+    fi
+
+    echo "Creating $fs filesystem on $img"
+    export MKE2FS_SYNC=0
+    if ! $mkfs $mkfs_exta_options "$img"; then
+        if test -z "$mkfs_exta_options"; then
+            cleanup_and_exit 3
+        else
+            echo "Format call failed, trying again without extra options..."
+            $mkfs "$img" || cleanup_and_exit 3
+        fi
+    fi
+    if test -n "$tunefs" ; then
+       $tunefs "$img" || cleanup_and_exit 3
+    fi
+}
+
+background_monitor_process() {
+    max_disk=0
+    max_mem=0
+    while sleep 5; do
+       test -e /.build/_statistics.exit  && exit 0
+
+       # memory usage
+       if test -e /proc/meminfo ; then
+           memtotal=0
+           while read key value unit; do
+               case $key in
+                   MemTotal:|SwapTotal:) memtotal=$(( $memtotal + $value )) ;;
+                   MemFree:|SwapFree:|SwapCached:|Cached:|Buffers:) memtotal=$(( $memtotal - $value )) ;;
+               esac
+           done < /proc/meminfo
+           if test ${memtotal} -gt $max_mem ; then
+               max_mem="${memtotal}"
+               echo -n $(( $max_mem / 1024 )) > /.build/_statistics.memory.new && mv /.build/_statistics.memory.new /.build/_statistics.memory
+           fi
+       fi
+
+       # disk storage usage
+       if type -p df >& /dev/null; then
+           c=(`df -m / 2>/dev/null | tail -n 1`)
+
+           if test ${c[2]} -gt $max_disk ; then
+               max_disk="${c[2]}"
+               echo -n $max_disk > /.build/_statistics.df.new && mv /.build/_statistics.df.new /.build/_statistics.df
+           fi
+       fi
+    done
+}
+
+background_watchdog() {
+    WATCHDOG_START=
+    WATCHDOG_TIMEOUT=300
+    while sleep 5 ; do
+       WATCH=`grep -a "### WATCHDOG MARKER" "$LOGFILE" | tail -n 1`
+       case $WATCH in
+           *WATCHDOG\ MARKER\ START*) test -n "$WATCHDOG_START" || WATCHDOG_START=`date +%s` ;;
+           *WATCHDOG\ MARKER\ END*) WATCHDOG_START= ;;
+       esac
+       if test -n "$WATCHDOG_START" ; then
+           NOW=`date +%s`
+           ELAPSED=$((NOW-WATCHDOG_START))
+           if test $ELAPSED -gt $WATCHDOG_TIMEOUT ; then
+               # kill the VM
+                echo "### WATCHDOG TRIGGERED, KILLING VM ###"
+           fuser -k -TERM "$VM_IMAGE"
+           exit 0
+       fi
+    fi
+    done
+}
+
+start_watchdog() {
+    local wf=$(mktemp)
+    ( background_watchdog & echo $! > "$wf" )
+    read VM_WATCHDOG_PID < "$wf"
+    rm -f "$wf"
+}
+
+kill_watchdog() {
+    test -n "$VM_WATCHDOG_PID" && kill "$VM_WATCHDOG_PID"
+    VM_WATCHDOG_PID=
+}
+
+vm_set_personality_syscall() {
+    local archname
+    archname=`perl -V:archname 2>/dev/null`
+    archname="${archname#archname=?}"
+    case "$archname" in
+       x86_64*) PERSONALITY_SYSCALL=135 ;;
+       alpha*) PERSONALITY_SYSCALL=324 ;;
+       sparc*) PERSONALITY_SYSCALL=191 ;;
+       ia64*) PERSONALITY_SYSCALL=1140 ;;
+       i?86*|ppc*|aarch64*|arm*|sh4|cris|m68k*|s390*|unicore32|microblaze)   PERSONALITY_SYSCALL=136 ;;
+       *) echo "Unknown architecture personality: '$archname'"; cleanup_and_exit 1 ;;
+    esac
+}
+
+# used before calling kvm or xen
+linux64() {
+    perl -e 'syscall('$PERSONALITY_SYSCALL', 0); exec(@ARGV) || die("$ARGV[0]: $!\n")' "$@"
+}
+
+vm_detect_2nd_stage() {
+    if test ! -e /.build/build.data -o -n "$BUILD_IGNORE_2ND_STAGE" ; then
+       return 1
+    fi
+    . /.build/build.data
+    if test -z "$VM_TYPE" ; then
+       return 1
+    fi
+    if test $$ -eq 1 || test $$ -eq 2 ; then
+       # ignore special init signals if we're init
+       # we're using ' ' instead of '' so that the signal handlers
+       # are reset in the child processes
+       trap ' ' HUP TERM
+       $0 "$@"
+       cleanup_and_exit $?
+    fi
+
+    test -n "$VM_WATCHDOG" -a -z "$PERSONALITY_SET" && echo "### WATCHDOG MARKER END ###"
+    echo "2nd stage started in virtual machine"
+    BUILD_ROOT=/
+    BUILD_DIR=/.build
+    echo "machine type: `uname -m`"
+    if test "$PERSONALITY" != 0 -a -z "$PERSONALITY_SET" ; then
+       export PERSONALITY_SET=true
+       echo "switching personality to $PERSONALITY..."
+       # this is 32bit perl/glibc, thus the 32bit syscall number
+       exec perl -e 'syscall(136, '$PERSONALITY') == -1 && warn("personality: $!\n");exec "/.build/build" || die("/.build/build: $!\n")'
+    fi
+    RUNNING_IN_VM=true
+    test -e /proc/version || mount -orw -n -tproc none /proc
+    if test "$VM_TYPE" != lxc ; then
+       mount -n ${VMDISK_MOUNT_OPTIONS},remount,rw /
+    fi
+    umount /run >/dev/null 2>&1
+    # mount /sys
+    if ! test -e /sys/block; then
+       mkdir -p /sys
+       mount -orw -n -tsysfs sysfs /sys
+    fi
+# qemu inside of xen does not work, check again with kvm later before enabling this
+#    if test -e /dev/kqemu ; then
+#        # allow abuild user to run qemu
+#        chmod 0666 /dev/kqemu
+#    fi
+
+    if test -n "$VM_SWAP" ; then
+       for i in 1 2 3 4 5 6 7 8 9 10 ; do
+           test -e "$VM_SWAP" && break
+           test $i = 1 && echo "waiting for $VM_SWAP to appear"
+           echo -n .
+           sleep 1
+       done
+       test $i = 1 || echo
+       # recreate the swap device manually if it didn't exist for some
+       # reason, hardcoded to hda2 atm
+       if ! test -b "$VM_SWAP" ; then
+           rm -f "$VM_SWAP"
+           umask 027
+           mknod "$VM_SWAP" b 3 2
+           umask 022
+       fi
+       # Do not rely on external system writing the signature, it might differ...
+       mkswap "$VM_SWAP"
+       swapon -v "$VM_SWAP" || exit 1
+    fi
+    HOST="$MYHOSTNAME"
+
+    # fork a process monitoring max filesystem usage during build
+    if test "$DO_STATISTICS" = 1 ; then
+       rm -f /.build/_statistics.exit
+        ( background_monitor_process & )
+    fi
+
+    if test ! -e /dev/.udev ; then
+        echo "WARNING: udev not running, creating extra device nodes"
+        test -e /dev/fd || ln -sf /proc/self/fd /dev/fd
+        test -e /etc/mtab || ln -sf /proc/mounts /etc/mtab
+    fi
+
+    # set date to build start on broken systems (now < build start)
+    if test $(date '+%s') -lt $(date -r /.build/.date '+%s') ; then
+        echo -n "WARNING: system has a broken clock, setting it to a newer time: "
+        date -s `cat /.build/.date`
+    fi
+
+    return 0
+}
+
+vm_set_filesystem_type() {
+    if test -z "$VMDISK_FILESYSTEM" -a -n "$BUILD_DIST" ; then 
+       VMDISK_FILESYSTEM=`queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" buildflags vmfstype`
+    fi   
+    test -n "$VMDISK_FILESYSTEM" || VMDISK_FILESYSTEM=ext3
+}
+
+vm_set_mount_options() {
+    if test "$VMDISK_MOUNT_OPTIONS" = __default; then
+       if test "$VMDISK_FILESYSTEM" = reiserfs ; then
+           VMDISK_MOUNT_OPTIONS='-o data=writeback,commit=150,noatime'
+       elif test "$VMDISK_FILESYSTEM" = btrfs ; then
+           VMDISK_MOUNT_OPTIONS='-o nobarrier,noatime'
+       elif test "$VMDISK_FILESYSTEM" = "ext4" ; then
+           VMDISK_MOUNT_OPTIONS='-o noatime'
+       elif test "$VMDISK_FILESYSTEM" = "ext3" ; then
+           VMDISK_MOUNT_OPTIONS='-o data=writeback,nobarrier,commit=150,noatime'
+       elif test "$VMDISK_FILESYSTEM" = "ext2" ; then
+           VMDISK_MOUNT_OPTIONS='-o noacl,noatime'
+       elif test "$VMDISK_FILESYSTEM" = "xfs" ; then
+           VMDISK_MOUNT_OPTIONS='-o noatime'
+       else
+           VMDISK_MOUNT_OPTIONS='-o noatime'
+       fi
+    fi
+}
+
+#
+# create file system and swap space, mount file system to $BUILD_ROOT
+#
+vm_setup() {
+    vm_set_filesystem_type
+    vm_set_mount_options
+    if test "$VM_IMAGE" = 1 ; then
+       VM_IMAGE="$BUILD_ROOT.img"
+       if test -z "$VM_SWAP" -a "$VM_TYPE" != emulator; then
+           VM_SWAP="$BUILD_ROOT.swap"
+       fi
+       echo "VM_IMAGE: $VM_IMAGE, VM_SWAP: $VM_SWAP"
+    else
+       echo "VM_IMAGE: $VM_IMAGE, VM_SWAP: $VM_SWAP"
+        vm_attach_root
+    fi
+    # this should not be needed, but sometimes a xen instance got lost
+    test "$VM_TYPE" = xen && vm_purge_xen
+    if test -n "$VMDISK_CLEAN" ; then
+       # delete old root/swap to get rid of the old blocks
+       if test -n "$VM_IMAGE" -a -f "$VM_IMAGE" ; then
+           echo "Deleting old $VM_IMAGE"
+           rm -rf "$VM_IMAGE"
+       fi
+       if test -n "$VM_SWAP" -a -f "$VM_SWAP" ; then
+           echo "Deleting old $VM_SWAP"
+           rm -rf "$VM_SWAP"
+       fi
+    fi
+    if test ! -e "$VM_IMAGE" ; then
+       vm_img_create "$VM_IMAGE" "$VMDISK_ROOTSIZE"
+       if test -z "$CLEAN_BUILD" ; then
+           vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE"
+       fi
+    fi
+    if test -n "$VM_SWAP" -a ! -e "$VM_SWAP" -a ! -b "$VM_SWAP" ; then
+       vm_img_create "$VM_SWAP" "$VMDISK_SWAPSIZE"
+    fi
+    if test ! -e "$VM_IMAGE" ; then
+       echo "you need to create $VM_IMAGE first"
+       cleanup_and_exit 3
+    fi
+    if test -n "$CLEAN_BUILD" ; then
+       vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE" || cleanup_and_exit 3
+    fi
+    # now mount root/swap
+    mkdir_build_root
+    if test -w /root ; then
+       if test -b $VM_IMAGE ; then
+           # mount device directly
+           mount $VMDISK_MOUNT_OPTIONS $VM_IMAGE $BUILD_ROOT || cleanup_and_exit 3
+       else
+           mount ${VMDISK_MOUNT_OPTIONS},loop $VM_IMAGE $BUILD_ROOT || cleanup_and_exit 3
+       fi
+    else
+       if ! mount $BUILD_ROOT; then
+           echo "mounting the build root failed. An fstab entry is probably missing or incorrect."
+           echo "/etc/fstab should contain an entry like this:"
+           echo "$VM_IMAGE $BUILD_ROOT auto noauto,user,loop 0 0"
+           cleanup_and_exit 3
+       fi
+    fi
+    if test -n "$VM_SWAP" ; then
+       vm_attach_swap
+       dd if=/dev/zero of="$VM_SWAP" bs=1024 count=1 conv=notrunc 2>/dev/null
+       vm_detach_swap
+        # mkswap happens inside of the vm
+    fi
+}
+
+#
+# prepare for vm startup
+#
+vm_first_stage() {
+    vm_set_personality_syscall
+    rm -rf "$BUILD_ROOT/.build"
+    mkdir -p "$BUILD_ROOT/.build"
+    TIME_PREINSTALL=
+    if test "$DO_INIT" = true ; then
+       # do first stage of init_buildsystem
+       rm -f $BUILD_ROOT/.build.success
+       set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --prepare "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $USEUSEDFORBUILD $RPMLIST "$MYSRCDIR/$RECIPEFILE" $ADDITIONAL_PACKS
+       echo "$* ..."
+       start_time=`date +%s`
+       "$@" || cleanup_and_exit 1
+       check_exit
+       TIME_PREINSTALL=$(( `date +%s` - $start_time ))
+       unset start_time
+       if test ! -w /root ; then
+           # remove setuid bit if files belong to user to make e.g. mount work
+           find $BUILD_ROOT/{bin,sbin,usr/bin,usr/sbin} -type f -uid $UID -perm +4000 -print0 | xargs -0 --no-run-if-empty chmod -s
+       fi
+       copy_oldpackages
+    fi
+
+    # start up VM, rerun ourself
+    cp -a $BUILD_DIR/. $BUILD_ROOT/.build
+    if ! test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then
+       rm -rf "$BUILD_ROOT/.build-srcdir"
+       mkdir "$BUILD_ROOT/.build-srcdir"
+       if test "$BUILDTYPE" = kiwi ; then
+           cp -pRL "$MYSRCDIR"/* $BUILD_ROOT/.build-srcdir
+       else
+           cp -p "$MYSRCDIR"/* $BUILD_ROOT/.build-srcdir
+       fi
+       MYSRCDIR=$BUILD_ROOT/.build-srcdir
+    else
+       # cwd is at $BUILD_ROOT/.build-srcdir which we want to
+       # umount later so step aside
+       cd "$SRCDIR"
+    fi
+
+    # do vm specific fixups
+    vm_fixup
+
+    # the watchdog needs a log file
+    test -n "$LOGFILE" || VM_WATCHDOG=
+    # put our config into .build/build.data
+    Q="'\''"
+    echo "RECIPEFILE='${RECIPEFILE//"'"/$Q}'" > $BUILD_ROOT/.build/build.data
+    echo "BUILD_JOBS='${BUILD_JOBS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "BUILD_ARCH='${BUILD_ARCH//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "BUILD_RPMS='${BUILD_RPMS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    case $BUILD_DIST in
+       */*)
+           cp $BUILD_DIST $BUILD_ROOT/.build/build.dist
+           BUILD_DIST=/.build/build.dist
+           ;;
+    esac
+    echo "BUILD_DIST='${BUILD_DIST//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "RELEASE='${RELEASE//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "BUILD_DEBUG='${BUILD_DEBUG//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "SIGNDUMMY='${SIGNDUMMY//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "DO_LINT='${DO_LINT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "DO_CHECKS='${DO_CHECKS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "NOROOTFORBUILD='${NOROOTFORBUILD//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "CREATE_BASELIBS='$CREATE_BASELIBS'" >> $BUILD_ROOT/.build/build.data
+    echo "REASON='${REASON//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "CHANGELOG='${CHANGELOG//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "INCARNATION='${INCARNATION//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "DISTURL='${DISTURL//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "DO_INIT='${DO_INIT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    echo "KIWI_PARAMETERS='${KIWI_PARAMETERS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    test -n "$VM_SWAP" && echo "VM_SWAP='${VM_SWAPDEV//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    test -n "$VMDISK_MOUNT_OPTIONS" && echo "VMDISK_MOUNT_OPTIONS='${VMDISK_MOUNT_OPTIONS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+    PERSONALITY=0
+    test -n "$PERSONALITY_SYSCALL" && PERSONALITY=`perl -e 'print syscall('$PERSONALITY_SYSCALL', 0)."\n"'`
+    test "$PERSONALITY" = -1 && PERSONALITY=0  # syscall failed?
+    case $(uname -m) in
+       ppc|ppcle|s390) PERSONALITY=8 ;;        # ppc/s390 kernel never tells us if a 32bit personality is active, assume we run on 64bit
+       aarch64) test "$BUILD_ARCH" != "${BUILD_ARCH#armv}" && PERSONALITY=8 ;; # workaround, to be removed
+    esac
+    test "$VM_TYPE" = lxc && PERSONALITY=0
+    echo "PERSONALITY='$PERSONALITY'" >> $BUILD_ROOT/.build/build.data
+    echo "MYHOSTNAME='`hostname`'" >> $BUILD_ROOT/.build/build.data
+    echo -n "definesnstuff=(" >> $BUILD_ROOT/.build/build.data
+    shellquote "${definesnstuff[@]}" >> $BUILD_ROOT/.build/build.data
+    echo ")" >> $BUILD_ROOT/.build/build.data
+    echo -n "repos=(" >> $BUILD_ROOT/.build/build.data
+    shellquote "${repos[@]}" >> $BUILD_ROOT/.build/build.data
+    echo ")" >> $BUILD_ROOT/.build/build.data
+    echo "VM_TYPE='$VM_TYPE'" >> $BUILD_ROOT/.build/build.data
+    echo "RUN_SHELL='$RUN_SHELL'" >> $BUILD_ROOT/.build/build.data
+    echo "DO_STATISTICS='$DO_STATISTICS'" >> $BUILD_ROOT/.build/build.data
+    echo "TIME_PREINSTALL='$TIME_PREINSTALL'" >> $BUILD_ROOT/.build/build.data
+    echo "VM_WATCHDOG='$VM_WATCHDOG'" >> $BUILD_ROOT/.build/build.data
+    echo "BUILDENGINE='$BUILDENGINE'" >> $BUILD_ROOT/.build/build.data
+    echo "CCACHE='$CCACHE'" >> $BUILD_ROOT/.build/build.data
+    echo "ABUILD_TARGET='$ABUILD_TARGET'" >> $BUILD_ROOT/.build/build.data
+    # fallback time for broken hosts
+    date '+@%s' > $BUILD_ROOT/.build/.date
+    # we're done with the root file system, unmount
+    umount -n $BUILD_ROOT/proc/sys/fs/binfmt_misc 2> /dev/null || true
+    umount -n $BUILD_ROOT/proc 2> /dev/null || true
+    umount -n $BUILD_ROOT/dev/pts 2> /dev/null || true
+    umount -n $BUILD_ROOT/dev/shm 2> /dev/null || true
+    umount -n $BUILD_ROOT/mnt 2> /dev/null || true
+
+    vm_init_script="/.build/build"
+    if check_use_emulator ; then
+       vm_init_script="/.build/$INITVM_NAME"
+    fi
+    if test -n "$VM_IMAGE" ; then
+       # copy out kernel & initrd (if they exist) during unmounting VM image
+       KERNEL_TEMP_DIR=
+       if test -z "$VM_KERNEL" -a -e "$BUILD_ROOT/.build.kernel.$VM_TYPE" ; then
+           KERNEL_TEMP_DIR=`mktemp -d`
+           cp "$BUILD_ROOT/.build.kernel.$VM_TYPE" "$KERNEL_TEMP_DIR/kernel"
+           if test -e  "$BUILD_ROOT/.build.initrd.$VM_TYPE" ; then
+               cp "$BUILD_ROOT/.build.initrd.$VM_TYPE" "$KERNEL_TEMP_DIR/initrd"
+           fi
+       fi
+       check_exit
+       # needs to work otherwise we have a corrupted file system
+       if ! umount $BUILD_ROOT; then
+           rm -rf "$KERNEL_TEMP_DIR"
+           cleanup_and_exit 3
+       fi
+       # copy back the kernel and set it for VM
+       if test -n "$KERNEL_TEMP_DIR" ; then
+           mkdir -p "$BUILD_ROOT/boot"
+           mv "$KERNEL_TEMP_DIR/kernel" "$BUILD_ROOT/boot/kernel"
+           vm_kernel="$BUILD_ROOT/boot/kernel"
+           if test -e "$KERNEL_TEMP_DIR/initrd" ; then
+               mv "$KERNEL_TEMP_DIR/initrd" "$BUILD_ROOT/boot/initrd"
+               test -z "$VM_INITRD" && vm_initrd="$BUILD_ROOT/boot/initrd"
+           fi
+           rmdir "$KERNEL_TEMP_DIR"
+       fi
+    fi
+    vm_detach_root
+
+    # start watchdog if requested
+    if test -n "$VM_WATCHDOG" ; then
+       start_watchdog
+       echo "### WATCHDOG MARKER START ###"
+    fi
+
+    echo "booting $VM_TYPE..."
+    vm_startup
+
+    # kill watchdog again
+    if test -n "$VM_WATCHDOG" ; then
+       echo "### WATCHDOG MARKER END ###"
+       kill_watchdog
+    fi
+
+    vm_attach_root
+    if test -n "$VM_SWAP" ; then
+       vm_attach_swap
+       BUILDSTATUS=`dd if="$VM_SWAP" bs=12 count=1 2>/dev/null`
+       case $BUILDSTATUS in
+         BUILDSTATUS[02])
+           mkdir -p $BUILD_ROOT/.build.packages
+           cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1
+           echo "build: extracting built packages..."
+           extractbuild --disk "$VM_IMAGE" --input "$VM_SWAP" --skip 512 -v || cleanup_and_exit 3
+           if test "$DO_STATISTICS" = 1 ; then
+               mkdir -p OTHER
+               TIME_TOTAL=$(( `date +%s` - $TIME_START_TIME ))
+               echo "TIME_total: $TIME_TOTAL"  >> OTHER/_statistics
+           fi
+           cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS}
+           ;;
+         BUILDSTATUS*)
+           cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS}
+           ;;
+         *)
+           echo "No buildstatus set, either the base system is broken (kernel/initrd/udev/glibc/bash/perl)"
+           echo "or the build host has a kernel or hardware problem..."
+           cleanup_and_exit 3
+           ;;
+       esac
+       cleanup_and_exit 1
+    fi
+}
+
+vm_save_statistics() {
+    echo "... saving statistics"
+    local sys_mounted otherdir
+    otherdir="$BUILD_ROOT$TOPDIR/OTHER"
+    test -n "$TIME_PREINSTALL" && echo "TIME_preinstall: $TIME_PREINSTALL"  >> $otherdir/_statistics
+    test -n "$TIME_INSTALL" && echo "TIME_install: $TIME_INSTALL"  >> $otherdir/_statistics
+    if test -e /.build/_statistics.df ; then
+       echo -n "MAX_mb_used_on_disk: " >> $otherdir/_statistics
+       cat /.build/_statistics.df >> $otherdir/_statistics
+       echo "" >> $otherdir/_statistics
+       rm /.build/_statistics.df
+    fi
+    if test -e /.build/_statistics.memory ; then
+       echo -n "MAX_mb_used_memory: " >> $otherdir/_statistics
+       cat /.build/_statistics.memory >> $otherdir/_statistics
+       echo "" >> $otherdir/_statistics
+       rm /.build/_statistics.memory
+    fi
+    if ! test -e /sys/block; then
+       mkdir -p /sys
+       mount -n sys /sys -t sysfs
+       sys_mounted=1
+    fi
+    device="hda1"
+    test -e /dev/sda && device="sda"
+    test -e /dev/vda && device="vda"
+    test -e /dev/dasda && device="dasda" # in z/VM
+    test -e /dev/nfhd0 && device="nfhd0" # in aranym
+    if test -e /sys/block/${device}/stat ; then
+       disk=(`cat /sys/block/${device}/stat`)
+       test "0${disk[0]}" -gt 0 && echo "IO_requests_read: ${disk[0]}"  >> $otherdir/_statistics
+       test "0${disk[2]}" -gt 0 && echo "IO_sectors_read: ${disk[2]}"   >> $otherdir/_statistics
+       test "0${disk[4]}" -gt 0 && echo "IO_requests_write: ${disk[4]}" >> $otherdir/_statistics
+       test "0${disk[6]}" -gt 0 && echo "IO_sectors_write: ${disk[6]}"  >> $otherdir/_statistics
+    else
+       echo "ERROR: no root disk device found, yet another new device name?"
+       ls -l /sys/block/
+    fi
+    test -n "$sys_mounted" && umount /sys
+}
+
+# args: resultdirs
+vm_wrapup_build() {
+    test "$DO_STATISTICS" = 1 && vm_save_statistics
+    if test -n "$VM_SWAP"; then
+        echo "... saving built packages"
+        swapoff "$VM_SWAP"
+       pushd "$BUILD_ROOT$TOPDIR" >/dev/null
+       find "$@" -print0 | computeblocklists --padstart 512 --padend 512 -v --manifest - -0 > "$VM_SWAP"
+       popd >/dev/null
+    fi
+}
diff --git a/build-vm-ec2 b/build-vm-ec2
new file mode 100644 (file)
index 0000000..3fefc61
--- /dev/null
@@ -0,0 +1,228 @@
+#
+# EC2 specific functions
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+BUILD_EC2_TYPE="t1.micro"
+
+cloud_volume_attach_ec2() {
+    local VM_SERVER="$1"
+    local VM_VOL_NAME="$2"
+    local VM_VOL_DEV="$3"
+
+    temp_file=`mktemp`
+    if ! ec2-attach-volume "$VM_VOL_NAME" -d /dev/sdz -i `ec2-instance-id` --region "$BUILD_EC2_REGION" > "$temp_file"; then
+        rm -f "$temp_file"
+        cleanup_and_exit 1
+    fi
+    # wait that it becomes available
+    while true; do
+        state=`ec2_volume_state "$VM_VOL_NAME"`
+        test "$state" = attached && break
+        sleep 1
+    done
+    # print device node
+    grep ^ATTACHMENT "$temp_file" | awk '{ print $4 }'
+    rm -f "$temp_file"
+}
+
+cloud_volume_detach_ec2() {
+    local VM_SERVER="$1"
+    local VM_VOL_NAME="$2"
+    state=`ec2_volume_state "$VM_VOL_NAME"`
+    if test "$state" != available ; then
+        ec2-detach-volume "$VM_VOL_NAME" --region "$BUILD_EC2_REGION" || return 3
+    fi
+    return 0
+}
+
+vm_verify_options_ec2() {
+    # verify settings
+    if test -z "$AWS_ACCESS_KEY" -o -z "$AWS_ACCESS_KEY" ; then
+        echo "ERROR: No amazon EC2 environment set. Set AWS_ACCESS_KEY and AWS_SECRET_KEY."
+        cleanup_and_exit 3
+    fi
+    . /etc/profile.d/ec2.sh
+    EC2_INSTANCE_ID=`ec2-instance-id`
+    BUILD_EC2_AKI=
+    BUILD_EC2_ZONE=`ec2-meta-data placement/availability-zone`
+    BUILD_EC2_REGION=${BUILD_EC2_ZONE%?}
+    case "$BUILD_EC2_ZONE" in
+        us-east-1)      BUILD_EC2_AKI=aki-88aa75e1 ;;
+        us-west-1)      BUILD_EC2_AKI=aki-f77e26b2 ;;
+        us-west-2)      BUILD_EC2_AKI=aki-fc37bacc ;;
+        eu-west-1)      BUILD_EC2_AKI=aki-71665e05 ;;
+        ap-southeast-1) BUILD_EC2_AKI=aki-fe1354ac ;;
+        ap-southeast-2) BUILD_EC2_AKI=aki-3f990e05 ;;
+        ap-northeast-1) BUILD_EC2_AKI=aki-44992845 ;;
+        sa-east-1)      BUILD_EC2_AKI=aki-c48f51d9 ;;
+        us-gov-west-1)  BUILD_EC2_AKI=aki-79a4c05a ;;
+    esac
+    if test -z "$BUILD_EC2_AKI" ; then
+        echo "Unknown Amazon EC2 Zone: $BUILD_EC2_ZONE"
+       cleanup_and_exit 1
+    fi
+    if test -z "$BUILD_EC2_AKI" ; then
+        echo "ERROR: No image refering to kernel and ramdisk is defined in BUILD_EC2_AKI env."
+        cleanup_and_exit 3
+    fi
+    if test -z "$VM_VOLUME_NAME" ; then
+        echo "ERROR: No worker root VM volume name specified."
+        cleanup_and_exit 3
+    fi
+    if test -z "$VM_VOLUME_SWAP" ; then
+        echo "ERROR: No worker swap VM volume name specified."
+        cleanup_and_exit 3
+    fi
+
+    VM_SWAPDEV=/dev/sdb1       # in the vm
+}
+
+vm_attach_root_ec2() {
+    VM_IMAGE=`cloud_volume_attach_ec2 "$VM_SERVER" "$VM_VOLUME_NAME" "$VM_IMAGE"`
+    test "${VM_IMAGE:0:5}" = /dev/ || cleanup_and_exit 3
+}
+
+vm_attach_swap_ec2() {
+    VM_SWAP=`cloud_volume_attach_ec2 "$VM_SERVER" "$EC2_EXTRACT_VOLUME_swap" "$VM_SWAP"`
+    test "${VM_SWAP:0:5}" = /dev/ || cleanup_and_exit 3
+}
+
+vm_detach_root_ec2() {
+    cloud_volume_detach_ec2 "$VM_SERVER" "$VM_VOLUME_NAME"
+}
+
+vm_detach_swap_ec2() {
+    cloud_volume_detach_ec2 "$VM_SERVER" "$VM_VOLUME_SWAP"
+}
+
+vm_fixup_ec2() {
+    # No way to handle this via init= parameter here....
+    echo "#!/bin/sh"               >  "$BUILD_ROOT/sbin/init"
+    echo 'exec /.build/build "$@"' >> "$BUILD_ROOT/sbin/init"
+    chmod 0755 "$BUILD_ROOT/sbin/init"
+    # use the instance kernel, if no kernel got installed via preinstall
+    if ! test -e "$BUILD_ROOT/boot/vmlinuz"; then
+       cp /boot/vmlinuz-ec2 "$BUILD_ROOT/boot/vmlinuz"
+       cp /boot/initrd-ec2 "$BUILD_ROOT/boot/initrd"
+    fi
+    # install menu.lst for pv grub
+    if ! test -e "$BUILD_ROOT/boot/grub/menu.lst"; then
+       mkdir -p "$BUILD_ROOT/boot/grub"
+       echo "serial --unit=0 --speed=9600"                                                   >  "$BUILD_ROOT/boot/grub/menu.lst"
+       echo "terminal --dumb serial"                                                         >> "$BUILD_ROOT/boot/grub/menu.lst"
+       echo "default 0"                                                                      >> "$BUILD_ROOT/boot/grub/menu.lst"
+       echo "timeout 0"                                                                      >> "$BUILD_ROOT/boot/grub/menu.lst"
+       echo "hiddenmenu"                                                                     >> "$BUILD_ROOT/boot/grub/menu.lst"
+       echo ""                                                                               >> "$BUILD_ROOT/boot/grub/menu.lst"
+       echo "title default"                                                                  >> "$BUILD_ROOT/boot/grub/menu.lst"
+       echo "   root (hd0)"                                                                  >> "$BUILD_ROOT/boot/grub/menu.lst"
+       echo "   kernel /boot/vmlinuz root=/dev/sda1 xencons=xvc0 console=xvc0 splash=silent" >> "$BUILD_ROOT/boot/grub/menu.lst"
+       echo "   initrd /boot/initrd"                                                         >> "$BUILD_ROOT/boot/grub/menu.lst"
+    fi
+}
+
+vm_cleanup_ec2() {
+    cloud_volume_detach_ec2 "$VM_SERVER" "$VM_VOLUME_NAME"
+    cloud_volume_detach_ec2 "$VM_SERVER" "$VM_VOLUME_SWAP"
+    test -n "$EC2_EXTRACT_VOLUME_root" && cloud_volume_detach_ec2 "$VM_SERVER" "$EC2_EXTRACT_VOLUME_root"
+    test -n "$EC2_EXTRACT_VOLUME_swap" && cloud_volume_detach_ec2 "$VM_SERVER" "$EC2_EXTRACT_VOLUME_swap"
+    test -n "$EC2_SNAP_root" && ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
+    test -n "$EC2_SNAP_swap" && ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap"
+    test -n "$EC2_EXTRACT_VOLUME_root" && ec2-delete-volume --region "$BUILD_EC2_REGION" "$EC2_EXTRACT_VOLUME_root"
+    test -n "$EC2_EXTRACT_VOLUME_swap" && ec2-delete-volume --region "$BUILD_EC2_REGION" "$EC2_EXTRACT_VOLUME_swap"
+}
+
+vm_kill_ec2() {
+    if ec2-describe-instance-status "$VM_BUILD_INSTANCE" --region "$BUILD_EC2_REGION" >/dev/null 2>&1 ; then
+       if ec2-terminate-instances "$VM_BUILD_INSTANCE" >/dev/null 2>&1 ; then
+           echo "could not kill EC2 instance $VM_BUILD_INSTANCE"
+           cleanup_and_exit 1
+       fi
+    fi
+}
+
+vm_startup_ec2() {
+    EC2_SNAP_root=`ec2-create-snapshot --region "$BUILD_EC2_REGION" "$VM_VOLUME_NAME" | awk '{ print $2 }'`
+    if test "$EC2_SNAP_root" = "${EC2_SNAP_root#snap-}" ; then
+       echo "ERROR: Failed to create snapshot for root disk $VM_VOLUME_NAME"
+       cleanup_and_exit 3
+    fi
+    EC2_SNAP_swap=`ec2-create-snapshot --region "$BUILD_EC2_REGION" "$VM_VOLUME_SWAP" | awk '{ print $2 }'`
+    if test "$EC2_SNAP_swap" = "${EC2_SNAP_swap#snap-}" ; then
+       echo "ERROR: Failed to create snapshot for swap disk $VM_VOLUME_SWAP"
+       ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
+       cleanup_and_exit 3
+    fi
+    # wait for snapshots being processed
+    while true; do
+       c=`ec2-describe-snapshots --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" "$EC2_SNAP_swap" | grep completed | wc -l`
+       test "$c" = 2 && break
+    done
+    EC2_AMI=`ec2-register --region "$BUILD_EC2_REGION" -n build-$VM_VOLUME_NAME  -a x86_64 -b "/dev/sda1=$EC2_SNAP_root::false" -b "/dev/sdb1=$EC2_SNAP_swap::false" --kernel "$BUILD_EC2_AKI" | awk '{ print $2 }'`
+    if test "$EC2_AMI" == "${EC2_AMI#ami-}" ; then
+       echo "ERROR: Failed to register the AMI"
+       ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
+       ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap"
+       cleanup_and_exit 3
+    fi
+    INSTANCE=`ec2-run-instances --region "$BUILD_EC2_REGION" -z "$BUILD_EC2_ZONE" -t $BUILD_EC2_TYPE --kernel "$BUILD_EC2_AKI" --instance-initiated-shutdown-behavior terminate "$EC2_AMI" | grep ^INSTANCE | awk '{ print $2 }'`
+    if test "$INSTANCE" == "${INSTANCE#i-}" ; then
+       echo "ERROR: Failed to run the instance for AMI $EC2_AMI"
+       ec2-deregister --region "$BUILD_EC2_REGION" "$EC2_AMI"
+       ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
+       ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap"
+       cleanup_and_exit 3
+    fi
+    echo "Waiting for finishing the build. No log file until then on EC2 ...."
+    I=0
+    L=0
+    EC2_EXTRACT_VOLUME_root=
+    EC2_EXTRACT_VOLUME_swap=
+    temp_file=`mktemp`
+    while true; do
+       ec2-describe-instances --region "$BUILD_EC2_REGION" "$INSTANCE" > $temp_file
+       state=`grep ^INSTANCE "$temp_file"`
+       if test -z "$EC2_EXTRACT_VOLUME_root" ; then
+           EC2_EXTRACT_VOLUME_root=`grep ^BLOCKDEVICE $temp_file | grep /dev/sda1 | awk '{ print $3 }'`
+           EC2_EXTRACT_VOLUME_swap=`grep ^BLOCKDEVICE $temp_file | grep /dev/sdb1 | awk '{ print $3 }'`
+       fi
+       # the column of the state is at a differen position depending on the state :/
+#       test "$state" = "${state/stopped/}" || break
+       test "$state" = "${state/terminated/}" || break
+       I=$(( $I + 1 ))
+       if test $I -gt 10 ; then
+          echo -n .
+          I=0
+          L=$(( $L + 1 ))
+       fi
+       if test $L -gt 10 ; then
+          # dump entire console log as raw here
+          ec2-get-console-output --region "$BUILD_EC2_REGION" -r "$INSTANCE"
+          L=0
+       fi
+       sleep 1
+    done
+    rm -f "$temp_file"
+    echo
+    ec2-deregister --region "$BUILD_EC2_REGION" "$EC2_AMI"
+    # snapshots get deleted after extract
+}
diff --git a/build-vm-emulator b/build-vm-emulator
new file mode 100644 (file)
index 0000000..045d244
--- /dev/null
@@ -0,0 +1,93 @@
+#
+# generic emulator specific functions
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+vm_verify_options_emulator() {
+    if test -f "$BUILD_DIR/emulator/verify-options.sh"; then
+      . "$BUILD_DIR/emulator/verify-options.sh"
+    else
+      VM_SWAP=
+    fi
+}
+
+vm_startup_emulator() {
+    pushd "$BUILD_DIR/emulator"
+    if test -z "$EMULATOR_SCRIPT" ; then
+       EMULATOR_SCRIPT=./emulator.sh
+    elif test "${EMULATOR_SCRIPT:0:1}" != / ; then
+       EMULATOR_SCRIPT="./$EMULATOR_SCRIPT"
+    fi
+    set -- "$EMULATOR_SCRIPT" "$VM_IMAGE" "$VM_SWAP"
+    echo "$@"
+    if ! "$@"; then
+        popd
+        echo "ERROR: The emulator returned with a failure"
+        cleanup_and_exit 3
+    fi
+    popd
+
+    test -n "$VM_SWAP" && return
+
+    # Emulators may not offer to use a second swap space.
+    # So we just mount the filesystem.
+    # WARNING: This is not safe against attacks.
+    mkdir -p $BUILD_ROOT/.build.packages
+    cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1
+    mkdir -p .mount
+    mount $VM_IMAGE -o loop .mount
+    if test -e .mount/.build.packages ; then
+        cp -a .mount/.build.packages/* .
+    fi
+    exitcode=`cat .mount/.build/_exitcode`
+    umount .mount
+    rmdir .mount
+    cleanup_and_exit "$exitcode"
+}
+
+vm_kill_emulator() {
+    if ! fuser -k -TERM "$VM_IMAGE" ; then
+        echo "could not kill build in $VM_IMAGE"
+        cleanup_and_exit 1
+    fi
+}
+
+vm_fixup_emulator() {
+    # emulator may not be able to hand over kernel parameters
+    ln -sf /.build/build $BUILD_ROOT/sbin/init
+}
+
+vm_attach_root_emulator() {
+    :
+}
+vm_attach_swap_emulator() {
+    :
+} 
+vm_detach_root_emulator() {
+    :
+}
+vm_detach_swap_emulator() {
+    :
+}
+vm_cleanup_emulator() {
+    :
+}
+
diff --git a/build-vm-kvm b/build-vm-kvm
new file mode 100644 (file)
index 0000000..455ecc1
--- /dev/null
@@ -0,0 +1,228 @@
+#
+# kvm/qemu specific functions
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+kvm_bin=/usr/bin/qemu-kvm
+kvm_console=ttyS0
+
+# assume virtio support by default
+kvm_device=virtio-blk-pci
+kvm_options=
+
+kvm_check_ppc970() {
+    if ! grep -q -E '(kvm_rma_count.*kvm_hpt_count)|(kvm_hpt_count.*kvm_rma_count)' /proc/cmdline ; then 
+       echo "put kvm_rma_count=<VM number> or kvm_hpt_count=<> to your boot options"
+       cleanup_and_exit 3
+    fi
+}
+
+kvm_check_hugetlb() {
+    if ! grep -q "$HUGETLBFSPATH" /proc/mounts ; then
+       echo "hugetlbfs is not mounted to $HUGETLBFSPATH"
+       cleanup_and_exit 3
+    fi
+    local HUGETLBBLKSIZE=$(stat -f -c "%S" "$HUGETLBFSPATH")
+    HUGETLBBLKSIZE=$(( ${HUGETLBBLKSIZE:-0} / 1024 ))
+    if test "$HUGETLBBLKSIZE" -lt 1 -o ! -e  "/sys/kernel/mm/hugepages/hugepages-${HUGETLBBLKSIZE}kB" ; then
+       echo "could not determine hugetlbfs block size"
+       cleanup_and_exit 3
+    fi
+    local PAGES_FREE=$(cat /sys/kernel/mm/hugepages/hugepages-${HUGETLBBLKSIZE}kB/free_hugepages)
+    local PAGES_REQ=$(( ${VM_MEMSIZE:-64} * 1024 / $HUGETLBBLKSIZE ))
+    if test "$PAGES_FREE" -lt "$PAGES_REQ" ; then
+       echo "expected $PAGES_REQ to be available (have $PAGES_FREE)"
+       echo "please adjust nr_hugepages"
+       cleanup_and_exit 3
+    fi
+}
+
+vm_verify_options_kvm() {
+    vm_kernel=
+    vm_initrd=
+    
+    # overwrite some options for specific host architectures
+    case `uname -m` in
+       armv7l)
+           kvm_bin="/usr/bin/qemu-system-arm"
+           kvm_console=ttyAMA0
+           kvm_options="-enable-kvm -M vexpress-a15 -dtb /boot/a15-guest.dtb -cpu cortex-a15"
+           vm_kernel=/boot/zImage
+           vm_initrd=/boot/initrd
+           # prefer the guest kernel/initrd
+           test -e /boot/zImage.guest && vm_kernel=/boot/zImage.guest
+           test -e /boot/initrd.guest && vm_initrd=/boot/initrd.guest
+           kvm_device=virtio-blk-device
+           ;;
+       aarch64)
+           kvm_bin="/usr/bin/qemu-system-aarch64"
+           kvm_console=ttyAMA0
+           kvm_options="-enable-kvm -M virt -cpu host"
+           vm_kernel=/boot/Image
+           vm_initrd=/boot/initrd
+           # prefer the guest kernel/initrd
+           test -e /boot/Image.guest && vm_kernel=/boot/Image.guest
+           test -e /boot/initrd.guest && vm_initrd=/boot/initrd.guest
+           kvm_device=virtio-blk-device
+           ;;
+       ppc|ppcle|ppc64|ppc64le)
+           kvm_bin="/usr/bin/qemu-system-ppc64"
+           kvm_console=hvc0
+           kvm_options="-enable-kvm -M pseries"
+           grep -q PPC970MP /proc/cpuinfo && kvm_check_ppc970
+           vm_kernel=/boot/vmlinux
+           vm_initrd=/boot/initrd
+           if test "$BUILD_ARCH" = ppc64le -a -e /boot/vmlinuxle ; then
+               vm_kernel=/boot/vmlinuxle
+               vm_initrd=/boot/initrdle
+           fi
+           grep -q "pSeries" /proc/cpuinfo && kvm_device=scsi-hd       # no virtio on pSeries
+           grep -q "PowerNV" /proc/cpuinfo || kvm_device=scsi-hd       # no virtio on ppc != power7 yet
+           ;;
+       s390|s390x)
+           kvm_bin="/usr/bin/qemu-system-s390x"
+           kvm_options="-enable-kvm"
+           kvm_console=hvc0
+           vm_kernel=/boot/image
+           vm_initrd=/boot/initrd
+           kvm_device=virtio-blk-ccw
+           ;;
+    esac
+
+    # check if we can run kvm
+    if ! test -r /dev/kvm -a -x "$kvm_bin" ; then
+       echo "host does not support kvm"
+       echo "either the kvm kernel-module is not loaded or kvm is not installed or hardware virtualization is deactivated in the BIOS."
+       cleanup_and_exit 3
+    fi
+
+    # check hugepages
+    test -n "$HUGETLBFSPATH" -a "$VM_TYPE" = kvm && kvm_check_hugetlb
+
+    # set kernel
+    test -n "$VM_KERNEL" && vm_kernel="$VM_KERNEL"
+    test -z "$vm_kernel" && vm_kernel=/boot/vmlinuz
+
+    # set initrd
+    test -n "$VM_INITRD" && vm_initrd="$VM_INITRD"
+    if test -z "$vm_initrd" ; then
+       # find a nice default
+       if test -e "/boot/initrd-build" ; then
+           vm_initrd="/boot/initrd-build"
+       elif test -e "/boot/initrd-virtio" ; then
+           vm_initrd="/boot/initrd-virtio"
+       else
+           vm_initrd="/boot/initrd"
+           kvm_device=ide-hd
+           # use /etc/sysconfig/kernel as indication if we have virtio
+           if test -e /etc/sysconfig/kernel ; then
+               local im=$(INITRD_MODULES=; . /etc/sysconfig/kernel; echo "$INITRD_MODULES")
+               if test "$im" != "${im/virtio/}" ; then
+                   kvm_device=virtio-blk-pci
+               fi
+           fi
+       fi
+    fi
+
+    case $kvm_device in
+       virtio*)
+           qemu_rootdev=/dev/disk/by-id/virtio-0
+           VM_SWAPDEV=/dev/disk/by-id/virtio-1
+           ;;
+       *)
+           qemu_rootdev=/dev/sda
+           VM_SWAPDEV=/dev/sdb
+           ;;
+    esac
+}
+
+vm_startup_kvm() {
+    qemu_bin="$kvm_bin"
+    qemu_args=(-drive file="$VM_IMAGE",if=none,id=disk,serial=0,cache=unsafe -device "$kvm_device",drive=disk)
+    if test -n "$VM_SWAP" ; then
+       qemu_args=("${qemu_args[@]}" -drive file="$VM_SWAP",if=none,id=swap,serial=1,cache=unsafe -device "$kvm_device",drive=swap)
+    fi
+
+    if test -n "$BUILD_JOBS" -a "$icecream" = 0 -a -z "$BUILD_THREADS" ; then
+       qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS")
+    elif test -n "$BUILD_JOBS" -a -n "$BUILD_THREADS" ; then
+       qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS,threads=$BUILD_THREADS")
+    fi
+    if test "$VM_TYPE" = kvm ; then
+       test "$kvm_console" != ttyAMA0 && kvm_options="$kvm_options -cpu host"
+       test -n "$HUGETLBFSPATH" && kvm_options="$kvm_options -mem-prealloc -mem-path $HUGETLBFSPATH"
+    fi
+    set -- $qemu_bin -no-reboot -nographic -vga none -net none $kvm_options \
+       -kernel $vm_kernel \
+       -initrd $vm_initrd \
+       -append "root=$qemu_rootdev panic=1 quiet no-kvmclock nmi_watchdog=0 rw rd.driver.pre=binfmt_misc elevator=noop console=$kvm_console init=$vm_init_script" \
+       ${VM_MEMSIZE:+-m $VM_MEMSIZE} \
+       "${qemu_args[@]}"
+
+    if test "$PERSONALITY" != 0 ; then
+       # have to switch back to PER_LINUX to make qemu work
+       set -- linux64 "$@"
+    fi
+    export QEMU_AUDIO_DRV=none         # we do not want to have sound inside the VMs
+    echo "$@"
+    "$@"
+}
+
+vm_kill_kvm() {
+    if ! fuser -k -TERM "$VM_IMAGE" ; then
+       echo "could not kill build in $VM_IMAGE"
+       cleanup_and_exit 1
+    fi
+}
+
+vm_fixup_kvm() {
+    # check if we will use a kernel from the build root, in this case
+    # we assume the kernel does virtio
+    if test -z "$VM_KERNEL" -a -e "$BUILD_ROOT/.build.kernel.$VM_TYPE" ; then
+       # ide-hd is the non-virtio default
+       if test "$kvm_device" = ide-hd ; then
+           kvm_device=virtio-blk-pci
+           qemu_rootdev=/dev/disk/by-id/virtio-0
+           VM_SWAPDEV=/dev/disk/by-id/virtio-1
+       fi
+    fi
+}
+
+vm_attach_root_kvm() {
+    :
+}
+
+vm_attach_swap_kvm() {
+    :
+}
+
+vm_detach_root_kvm() {
+    :
+}
+
+vm_detach_swap_kvm() {
+    :
+}
+
+vm_cleanup_kvm() {
+    :
+}
+
diff --git a/build-vm-lxc b/build-vm-lxc
new file mode 100644 (file)
index 0000000..6d9ef20
--- /dev/null
@@ -0,0 +1,76 @@
+#
+# LXC specific functions
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+vm_verify_options_lxc() {
+    VM_IMAGE=
+    VM_SWAP=
+}
+
+vm_startup_lxc() {
+    LXCCONF="$BUILD_ROOT/.build.lxc.conf"
+    rm -f "$LXCCONF"
+    cat $BUILD_DIR/lxc.conf > "$LXCCONF"
+    cat >> "$LXCCONF" <<-EOF
+       lxc.rootfs = $BUILD_ROOT
+       EOF
+    # XXX: do this always instead of leaking the hosts' one?
+    echo "rootfs / rootfs rw 0 0" > $BUILD_ROOT/etc/mtab
+    LXCID=${BUILD_ROOT##*/}
+    lxc-destroy -n "$LXCID" >/dev/null 2>&1 || true
+    lxc-create -n "$LXCID" -f "$LXCCONF" || cleanup_and_exit 1
+    lxc-start -n "$LXCID" "$vm_init_script"
+    BUILDSTATUS="$?"
+    test "$BUILDSTATUS" != 255 || BUILDSTATUS=3
+    cleanup_and_exit "$BUILDSTATUS"
+}
+
+vm_kill_lxc() {
+    LXCID=${BUILD_ROOT##*/}
+    lxc-stop -n "$LXCID" || true
+    lxc-destroy -n "$LXCID"
+}
+
+vm_fixup_lxc() {
+    :
+}
+
+vm_attach_root_lxc() {
+    :
+}
+
+vm_attach_swap_lxc() {
+    :
+}
+
+vm_detach_root_lxc() {
+    :
+}
+
+vm_detach_swap_lxc() {
+    :
+}
+
+vm_cleanup_lxc() {
+    :
+}
+
diff --git a/build-vm-openstack b/build-vm-openstack
new file mode 100644 (file)
index 0000000..73688ec
--- /dev/null
@@ -0,0 +1,145 @@
+#
+# Openstack specific functions
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+cloud_volume_attach_openstack() {
+    local VM_SERVER="$1"
+    local VM_VOL_NAME="$2"
+    local VM_VOL_DEV="$3"
+
+    if ! nova volume-attach "$VM_SERVER" "$VM_VOL_NAME" "$VM_VOL_DEV"; then
+       echo "ERROR: nova attach failed. $?" >&2
+       return 3
+    fi
+    while true; do
+       state=`nova volume-show "$VM_VOL_NAME" | sed -n 's,^|[ ]*status[ ]*|[ ]*\([^ ]*\).*,\1,p'`
+       test "$state" = "in-use" && break
+        if test -z "$state" ; then
+           echo "ERROR: unable to find state of volume $VM_VOL_NAME" >&2
+            return 3
+        fi
+        if test "$state" = available ; then
+           echo "WARNING: volume $VM_VOL_NAME got not attached, retrying" >&2
+            if ! nova volume-attach "$VM_SERVER" "$VM_VOL_NAME" "$VM_VOL_DEV"; then
+               echo "ERROR: nova attach failed. $?" >&2
+                return 3
+            fi
+        fi
+        sleep 3
+    done
+    if test ! -e "$VM_VOL_DEV" ; then
+       #GROSS HACK: kernel does not care about the given device name
+#       VM_VOL_DEV="/dev/"`dmesg| sed -n 's,.*\(vd.\): unknown partition tab.*,\1,p' | tail -n 1`
+        VM_VOL_DEV=`ls -1 /dev/vd? | tail -n 1`
+    fi
+    echo "$VM_VOL_DEV"
+}
+
+cloud_volume_detach_openstack() {
+    local VM_SERVER="$1"
+    local VM_VOL_NAME="$2"
+
+    # needed at all?
+    nova volume-show "$VM_VOL_NAME" | grep -q in-use || return 0
+    # umount seems not to be enough
+    sync
+    if ! nova volume-detach "$VM_SERVER" "$VM_VOL_NAME"; then
+       echo "ERROR: nova detach of $VM_VOL_NAME failed." >&2
+        return 3
+    fi
+    while nova volume-show "$VM_VOL_NAME" | grep -q availabe; do
+       sleep 3
+    done
+    return 0
+}
+
+vm_verify_options_openstack() {
+    # verify settings
+    if test -z "$OS_AUTH_URL" ; then
+       echo "ERROR: No openstack environment set. This vm-type works only inside of an openstack VM."
+       cleanup_and_exit 3
+    fi
+    if test -z "$OBS_OPENSTACK_KERNEL_IMAGE_ID" ; then
+       echo "ERROR: No image refering to kernel and ramdisk is defined in OBS_OPENSTACK_KERNEL_IMAGE_ID env."
+       cleanup_and_exit 3
+    fi
+    if test -z "$VM_VOLUME_NAME" ; then
+       echo "ERROR: No worker root VM volume name specified."
+       cleanup_and_exit 3
+    fi
+    if test -z "$VM_VOLUME_SWAP" ; then
+       echo "ERROR: No worker swap VM volume name specified."
+       cleanup_and_exit 3
+    fi
+    if test -z "$VM_SERVER" ; then
+       echo "ERROR: No VM server nod name specified (usually this instance)."
+       cleanup_and_exit 3
+    fi
+
+    # XXX why here?
+    VM_SWAPDEV=/dev/vdb
+    qemu_rootdev=/dev/vda
+}
+
+vm_attach_root_openstack() {
+    VM_IMAGE=`cloud_volume_attach_openstack "$VM_SERVER" "$VM_VOLUME_NAME" "$VM_IMAGE"`
+    test "${VM_IMAGE:0:5}" = "/dev/" || cleanup_and_exit 3
+}
+
+vm_attach_swap_openstack() {
+    VM_SWAP=`cloud_volume_attach_openstack "$VM_SERVER" "$VM_VOLUME_SWAP" "$VM_SWAP"`
+    test "${VM_SWAP:0:5}" = /dev/ || cleanup_and_exit 3
+}
+
+vm_detach_root_openstack() {
+    cloud_volume_detach_openstack "$VM_SERVER" "$VM_VOLUME_NAME"
+}
+
+vm_detach_swap_openstack() {
+    cloud_volume_detach_openstack "$VM_SERVER" "$VM_VOLUME_SWAP"
+}
+
+vm_cleanup_openstack() {
+    cloud_volume_detach_openstack "$VM_SERVER" "$VM_VOLUME_NAME"
+    cloud_volume_detach_openstack "$VM_SERVER" "$VM_VOLUME_SWAP"
+}
+
+vm_fixup_openstack() {
+    # No way to handle this via init= parameter here....
+    echo "#!/bin/sh"               >  "$BUILD_ROOT/sbin/init"
+    echo 'exec /.build/build "$@"' >> "$BUILD_ROOT/sbin/init"
+    chmod 0755 "$BUILD_ROOT/sbin/init"
+}
+
+vm_kill_openstack() {
+    if nova show "$VM_VOLUME_NAME" >/dev/null 2>&1 ; then
+       if ! nova delete "$VM_VOLUME_NAME" ; then
+           echo "could not kill openstack vm build $VM_VOLUME_NAME"
+            cleanup_and_exit 1
+       fi
+    fi
+}
+
+vm_startup_openstack() {
+    nova boot --image $OBS_OPENSTACK_KERNEL_IMAGE_ID --flavor m1.small --block_device_mapping vda=${VM_VOLUME_NAME}::$(( $VMDISK_ROOTSIZE / 1024 )):0 --block_device_mapping vdb=${VM_VOLUME_SWAP}::1:0 --poll "build-$VM_VOLUME_NAME" || cleanup_and_exit 3
+    nova console-log "build-$VM_VOLUME_NAME"
+}
diff --git a/build-vm-qemu b/build-vm-qemu
new file mode 100644 (file)
index 0000000..09e4250
--- /dev/null
@@ -0,0 +1,61 @@
+#
+# qemu specific functions
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+# just forward everything to kvm...
+
+vm_verify_options_qemu() {
+    vm_verify_options_kvm
+}
+
+vm_startup_qemu() {
+    vm_startup_kvm
+}
+
+vm_kill_qemu() {
+    vm_kill_kvm
+}
+
+vm_fixup_qemu() {
+    vm_setup_kvm
+}
+
+vm_attach_root_qemu() {
+    vm_attach_root_kvm
+}
+
+vm_attach_swap_qemu() {
+    vm_attach_swap_kvm
+}
+
+vm_detach_root_qemu() {
+    vm_detach_root_kvm
+}
+
+vm_detach_swap_qemu() {
+    vm_detach_swap_kvm
+}
+
+vm_cleanup_qemu() {
+    vm_cleanup_kvm
+}
+
diff --git a/build-vm-uml b/build-vm-uml
new file mode 100644 (file)
index 0000000..4ca82e6
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# UML specific functions
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+uml_kernel=/boot/vmlinux-um
+uml_initrd=/boot/initrd-um
+
+vm_verify_options_uml() {
+    VM_SWAPDEV=/dev/sdb
+}
+
+vm_startup_uml() {
+    set -- $uml_kernel initrd=$uml_initrd root=ubda init="$vm_init_script" panic=1 elevator=noop quiet ubda=$VM_IMAGE ubdb=$VM_SWAP ${VM_MEMSIZE:+mem=$VM_MEMSIZE}
+    echo "$@"
+    "$@"
+}
+
+vm_kill_uml() {
+    if ! fuser -k -TERM "$VM_IMAGE"; then
+        echo "could not kill build in $VM_IMAGE"
+        cleanup_and_exit 1
+    fi
+}
+
+vm_fixup_uml() {
+    :
+}
+
+vm_attach_root_uml() {
+    :
+}
+
+vm_attach_swap_uml() {
+    :
+}
+
+vm_detach_root_uml() {
+    :
+}
+
+vm_detach_swap_uml() {
+    :
+}
+
+vm_cleanup_uml() {
+    :
+}
+
diff --git a/build-vm-xen b/build-vm-xen
new file mode 100644 (file)
index 0000000..7366009
--- /dev/null
@@ -0,0 +1,133 @@
+#
+# XEN specific functions
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+vm_verify_options_xen() {
+    vm_kernel=/boot/vmlinuz
+    vm_initrd=/boot/initrd
+    test -e /boot/vmlinuz-xen && vm_kernel=/boot/vmlinuz-xen
+    test -e /boot/initrd-xen && vm_initrd=/boot/initrd-xen
+    test -n "$VM_KERNEL" && vm_kernel="$VM_KERNEL"
+    test -n "$VM_INITRD" && vm_initrd="$VM_INITRD"
+}
+
+vm_startup_xen() {
+    XMCMD=xm
+    test ! -x /usr/sbin/xm -a -x /usr/sbin/xl && XMCMD=xl
+    XMROOT="file:$(readlink -f $VM_IMAGE)"
+    XMROOT=${XMROOT/#file:\/dev/phy:/dev}
+    XMROOT="disk=$XMROOT,hda1,w"
+    XMSWAP=
+    if test -n "$VM_SWAP" ; then
+       XMSWAP="file:$(readlink -f $VM_SWAP)"
+       XMSWAP=${XMSWAP/#file:\/dev/phy:/dev}
+       XMSWAP="disk=$XMSWAP,hda2,w"
+    fi
+    XENID="${VM_IMAGE%/root}"
+    XENID="${XENID%/tmpfs}"
+    XENID="${XENID##*/}"
+    XENID="${XENID#root_}"
+
+    if $XMCMD list "build_$XENID" >/dev/null 2>&1 ; then
+       echo "Instance already exists, something really went wrong..."
+       echo "Please report to your server admin, there might be multiple services running for same domain"
+       cleanup_and_exit 3
+    fi
+    XEN_CONF_FILE=`mktemp /var/tmp/build.xen.conf-XXXXXXXXX` || cleanup_and_exit 3
+    
+    echo "kernel = \"$vm_kernel\""                                           >  $XEN_CONF_FILE
+    echo "ramdisk = \"$vm_initrd\""                                          >> $XEN_CONF_FILE
+    echo "memory = ${VM_MEMSIZE:-64}"                                        >> $XEN_CONF_FILE
+    test -n "$BUILD_JOBS" && echo "vcpus = $BUILD_JOBS"                      >> $XEN_CONF_FILE
+    echo "root = \"/dev/hda1 ro\""                                           >> $XEN_CONF_FILE
+    echo "extra = \"init=/bin/bash console=ttyS0 panic=1 udev_timeout=360\"" >> $XEN_CONF_FILE
+    echo "on_poweroff = \"destroy\""                                         >> $XEN_CONF_FILE
+    echo "on_reboot = \"destroy\""                                           >> $XEN_CONF_FILE
+    echo "on_crash = \"destroy\""                                            >> $XEN_CONF_FILE
+    if test "$XMCMD" = xm ; then
+       set -- xm create -c $XEN_CONF_FILE name="build_$XENID" $XMROOT $XMSWAP extra="panic=1 quiet init="$vm_init_script" rd.driver.pre=binfmt_misc elevator=noop console=ttyS0"
+    else
+       XLDISK=
+       XLDISK="\"${XMROOT#disk=}\""
+       test -n "$XMSWAP" && XLDISK="$XLDISK, \"${XMSWAP#disk=}\""
+       set -- xl create -c $XEN_CONF_FILE name="\"build_$XENID\"" "disk=[ $XLDISK ]" extra=\""panic=1 quiet init="$vm_init_script" rd.driver.pre=binfmt_misc elevator=noop console=ttyS0"\"
+    fi
+    if test "$PERSONALITY" != 0 ; then
+       # have to switch back to PER_LINUX to make xm work
+       set -- linux64 "$@"
+    fi
+    echo "$@"
+    "$@" || cleanup_and_exit 3
+    rm -f "$XEN_CONF_FILE"
+}
+
+vm_kill_xen() {
+    XMCMD=xm
+    test ! -x /usr/sbin/xm -a -x /usr/sbin/xl && XMCMD=xl
+    XENID="${VM_IMAGE%/root}"
+    XENID="${XENID%/tmpfs}"
+    XENID="${XENID##*/}"
+    XENID="${XENID#root_}"
+    if $XMCMD list "build_$XENID" >/dev/null 2>&1 ; then 
+       if ! $XMCMD destroy "build_$XENID" ; then 
+           echo "could not kill xen build $XENID"
+           cleanup_and_exit 1
+       fi
+    fi
+}
+
+# XEN only
+vm_purge_xen() {
+    # this should not be needed, but sometimes a xen instance gets lost
+    XMCMD=xm
+    test ! -x /usr/sbin/xm -a -x /usr/sbin/xl && XMCMD=xl
+    XENID="${VM_IMAGE%/root}"
+    XENID="${XENID%/tmpfs}"
+    XENID="${XENID##*/}"
+    XENID="${XENID#root_}"
+    $XMCMD destroy "build_$XENID" >/dev/null 2>&1
+}
+
+vm_fixup_xen() {
+    :
+}
+
+vm_attach_root_xen() {
+    :
+}
+
+vm_attach_swap_xen() {
+    :
+}
+
+vm_detach_root_xen() {
+    :
+}
+
+vm_detach_swap_xen() {
+    :
+}
+
+vm_cleanup_xen() {
+    :
+}
+
diff --git a/build-vm-zvm b/build-vm-zvm
new file mode 100644 (file)
index 0000000..c28442c
--- /dev/null
@@ -0,0 +1,369 @@
+#
+# z/VM specific functions
+#
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+# z/VM: use default kernel image from local machine
+# lets go with the default parameters. However zvm_initrd will be a required parameter
+#zvm_kernel=/boot/image
+#zvm_initrd=/boot/initrd_worker
+zvm_param="root=/dev/disk/by-path/ccw-0.0.0150-part1 hvc_iucv=8 console=hvc0"
+zvm_mult_pass="THR4ME"
+zvm_init_script="/.build/build"
+
+#######################################################################################
+
+# this once was in zvm_functions
+
+zvm_fatal() {
+    echo "$1"
+    test -n "$ZVM_CLEANUP" && exit 1
+    cleanup_and_exit 1
+}
+
+prevent_detach() {
+    if test "$1" = "150" -o "$1" = "0150"; then
+        zvm_fatal "don't detach local root"
+    fi
+}
+
+zvm_memset() {
+    # defining the worker also resets the operating system. Be careful
+    # $1: user name
+    # $2: amount in MB
+    # Note, that this is also limited by the worker definition in the user directory
+    if test -n "$2"; then
+        if ! vmcp send $1 define storage ${2}M ; then
+            zvm_fatal "Could not redefine storage of $1 to ${2}M"
+        fi
+    fi
+}
+
+zvm_logon() {
+    # kill machine if it already runs
+    # autolog machine
+    # Needs machine name as $1
+    if test -n "$1" ; then
+        if $(vmcp q "$1" >& /dev/null) ; then
+            vmcp force $1
+            sleep 1
+        fi
+        if ! $(vmcp q "$1" >& /dev/null) ; then
+            if ! $(vmcp xautolog $1 >& /dev/null) ; then
+                zvm_fatal "Could not start machine $1. Is $1 defined in the user directory?"
+            else
+                # give the worker a moment to initialize
+                sleep 2
+                zvm_memset $1 $VM_MEMSIZE
+               sleep 2
+            fi
+        fi
+    fi
+}
+
+zvm_ipl() {
+    # IPL worker. Needs user as $1 and ipl device as $2.
+    if test -n "$1" -a -n "$2" ; then
+        if ! $(vmcp q "$1" >& /dev/null); then
+            zvm_fatal "User $1 not logged on."
+        else
+            if ! $(vmcp send $1 ipl $2); then
+                 zvm_fatal "Could not send command to $1"
+            fi
+        fi
+    else
+        zvm_fatal "Not enough arguments for ipl. Need user and device number."
+    fi
+}
+
+
+zvm_destroy() {
+    # Destroy build. Done by killing the worker machine.
+    # needs user as $1
+    if test -n "$1"; then
+        if ! $(vmcp force $1 ) ; then
+            zvm_fatal "Could not force $1"
+        fi
+    fi
+}
+
+zvm_get_local_devnr() {
+    # $1 is base address, either 150 or 250
+    # $2 is worker number
+    # there is room for up to 100 workers for this controlling guest, however in our setup I expect only up to 10 workers.
+    #echo "Debug: zvm_get_local_devnr: arg1: $1 arg2: $2"
+    if test "$2" -ge 100 ; then
+        zvm_fatal "Not more than 100 workers supported by one controlling guest."
+    fi
+    if test "$1" = "0150" -o "$1" = "150" ; then 
+        DEVNR=$((300+$2))
+    else
+        if test "$1" = "0250" -o "$1" = "250" ; then 
+            DEVNR=$((400+$2))
+        else
+            zvm_fatal "The disk devices for root and swap must be 150 and 250 respectively."
+        fi
+    fi
+    echo $DEVNR
+}
+
+zvm_volume_link_local() {
+    # attach worker disk to local system as preparation for 
+    # a) prepare worker for build
+    # b) get rpms of the swap disk after build finished
+    # disk must be detached from worker first
+    # The following arguments are needed:
+    # 1. Worker user name
+    # 2. Worker disk device number
+    # 3. Mult password for the disk
+    # 4. Worker number to generate a uniq local device number
+    if test -n "$4"; then
+        DEVNR=$(zvm_get_local_devnr $2 $4)
+        if ! vmcp link $1 $2 $DEVNR MW pass=THR4ME >& /dev/null ; then
+            zvm_fatal "Could not link disk $2 from user $1 to local device $DEVNR."
+        fi
+        dasd_configure 0.0.0$DEVNR 1 0 >& /dev/null
+       udevadm settle
+        DEVICE=$(ls /sys/bus/ccw/devices/0.0.0$DEVNR/block/)
+        if ! test -b /dev/${DEVICE}1 ; then
+            zvm_fatal "The device /sys/bus/ccw/devices/0.0.0$DEVNR has not been setup correctly."
+        fi
+        echo "${DEVICE}1"
+    else
+        zvm_fatal "Not enough arguments given to volume_link_local."
+    fi 
+}
+
+zvm_volume_detach_local() {
+    # we need
+    # 1. worker device number
+    # 2. worker number
+    DEVNR=$(zvm_get_local_devnr $1 $2)
+    prevent_detach $DEVNR
+    dasd_configure 0.0.0$DEVNR 0 0
+    if ! vmcp detach $DEVNR >& /dev/null ; then
+        zvm_fatal "Could not locally detach disk number $1 from worker $2"
+    fi
+}
+
+zvm_volume_attach() {
+    # link the local disk of the worker 
+    # $1: user name
+    # $2: disk device number
+    # send link * nr nr
+    if ! vmcp send $1 link \* $2 $2 ; then
+        zvm_fatal "Could not link remote worker disk number $2 from user $1"
+    fi 
+}
+
+zvm_volume_detach() {
+    # send machine detach nr
+    # $1: user name
+    # $2: disk
+    if ! vmcp send $1 detach $2 ; then
+        zvm_fatal "Could not detach disk $2 on worker $1"
+    fi
+}
+
+zvm_worker_init() {
+    # 1. Worker user name
+    # 2. Worker root device number
+    # 3. Worker swap device number
+    # 4. Worker number to generate a uniq local device number
+    # Check for: 
+    # - still mounted dasd
+    # - configured dasd
+    # - linked dasd
+    # - reset worker with force and autolog 
+    DEVNR_ROOT=$(zvm_get_local_devnr $2 $4) 
+    DEVNR_SWAP=$(zvm_get_local_devnr $3 $4)
+    # First, check for mounts:
+    for DEVNR in $DEVNR_ROOT $DEVNR_SWAP ; do
+        if test -d /sys/bus/ccw/devices/0.0.0$DEVNR/block ; then
+            DEV=$(ls /sys/bus/ccw/devices/0.0.0$DEVNR/block/)
+            echo "Found device of worker $1 available at $DEVNR, device is /dev/$DEV."
+            grep "/dev/$DEV" /proc/mounts >& /dev/null && umount /dev/${DEV}1
+        fi
+    done
+    # Second, check if devices are online
+    for DEVNR in $DEVNR_ROOT $DEVNR_SWAP ; do
+        lsdasd $DEVNR | grep $DEVNR && dasd_configure 0.0.0$DEVNR 0 0
+    done
+    # Third, remove stale links
+    for DEVNR in $DEVNR_ROOT $DEVNR_SWAP ; do
+        prevent_detach $DEVNR
+        if vmcp q v $DEVNR 2> /dev/null ; then
+            vmcp detach $DEVNR
+        fi
+    done
+    # Fourth, reset worker
+    zvm_logon $1
+}
+
+zvm_cp() {
+    modprobe vmcp || zvm_fatal "Cannod load vmcp module"
+    if test -n "$1" ; then
+        case "$1" in 
+            start)                shift ; zvm_logon "$@"         ;;
+            ipl)                  shift ; zvm_ipl "$@"           ;;
+            destroy)              shift ; zvm_destroy "$@"       ;;
+            volume_attach)        shift ; zvm_volume_attach "$@" ;;
+            volume_detach)        shift ; zvm_volume_detach "$@" ;;
+            volume_link_local)    shift ; zvm_volume_link_local "$@" ;;
+            volume_detach_local)  shift ; zvm_volume_detach_local "$@" ;;
+            memset)               shift ; zvm_memset "$@"        ;;
+            worker_init)          shift ; zvm_worker_init "$@"   ;;
+        esac
+    fi
+}
+
+#######################################################################################
+
+vm_verify_options_zvm() {
+    VM_IMAGE=/dev/dasda1
+    VM_SWAP=/dev/dasdb1
+
+    VM_SWAPDEV=/dev/dasdb1     # in the vm
+
+    if test -z "$VM_VOLUME_ROOT" ; then
+       if test -n "$BUILD_ROOT" -a ${#BUILD_ROOT} -le 4 ; then
+           VM_VOLUME_ROOT="$BUILD_ROOT"
+       else
+           VM_VOLUME_ROOT="0150"
+       fi
+    fi
+    # In z/VM, this is a 4 digit hex number instead of a linux device.
+    # This is the swap disk defined in user direct
+    # This number can be given with the parameter --swap NR.
+    if test -z "$VM_VOLUME_SWAP" ; then
+       if test -n "$VM_SWAP" -a ${#VM_SWAP} -le 4 ; then
+           VM_VOLUME_SWAP="$VM_SWAP"
+       else
+           VM_VOLUME_SWAP="0250"
+       fi
+    fi
+    # z/VM guest name that is already defined in z/VM
+    if test -z "$VM_WORKER" ; then
+       echo "ERROR: No z/VM worker id specified"
+       cleanup_and_exit 3
+    fi
+    if test -z "$VM_WORKER_NR" ; then
+       echo "ERROR: No z/VM worker number specified"
+       cleanup_and_exit 3
+    fi
+    # need the name for a kernel in zvm
+    if test -n "$VM_KERNEL" ; then
+       vm_kernel="$VM_KERNEL"
+    elif test -e "/boot/vmlinux.gz" ; then
+       vm_kernel="/boot/vmlinux.gz"
+    else
+       echo "ERROR: No z/VM kernel specified"
+       cleanup_and_exit 3
+    fi
+    # need the name for an initrd in zvm
+    # this normally will not be the local initrd
+    if test -n "$VM_INITRD" ; then
+       vm_initrd="$VM_INITRD"
+    else
+       echo "ERROR: No z/VM initrd specified"
+       cleanup_and_exit 3
+    fi
+    zvm_cp worker_init $VM_WORKER $VM_VOLUME_ROOT $VM_VOLUME_SWAP $VM_WORKER_NR
+    zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT
+    zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP
+}
+
+vm_startup_zvm() {
+    # link root/swap to the worker
+    zvm_cp volume_attach $VM_WORKER $VM_VOLUME_ROOT
+    zvm_cp volume_attach $VM_WORKER $VM_VOLUME_SWAP
+    zvm_cp ipl $VM_WORKER $VM_VOLUME_ROOT
+    # start IUCV Console
+    # IPL needs some time until IPL really starts...
+    sleep 2
+    # start iucv console. This blocks until build process is finished.
+    iucvconn $VM_WORKER lnxhvc0
+    # sleep some time before taking root and swap devices from worker
+    # This might be critical regarding timing (IUCV_CONSOLE down, but machine still running)
+    sleep 5
+    zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT
+    zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP
+}
+
+vm_kill_zvm() {
+    if vmcp q "$VM_WORKER" > /dev/null 2>&1 ; then
+       if ! zvm_cp destroy $VM_WORKER ; then
+           echo "could not kill zvm worker $VM_WORKER"
+           cleanup_and_exit 1
+       fi
+    fi
+}
+
+vm_fixup_zvm() {
+    # initrd is created in obsstoragesetup.
+    # If it is desired to use a project dependent kernel, use make_guestinitrd from zvm_functions.
+    # have to copy kernel/initrd and run zipl to be able to IPL
+    # have to set init_script before unmounting, thus doing it statically for now.
+    zvm_init_script="/.build/build"
+    mkdir -p $BUILD_ROOT/boot
+    cp $vm_kernel $vm_initrd $BUILD_ROOT/boot
+    mkdir -p $BUILD_ROOT/boot/zipl
+    # finally, install bootloader to the worker disk
+    zipl -t $BUILD_ROOT/boot/zipl -i ${BUILD_ROOT}${vm_kernel} -r ${BUILD_ROOT}${vm_initrd} \
+       --parameters "${zvm_param} init=$zvm_init_script rootfsopts=noatime"
+}
+
+vm_attach_root_zvm() {
+    VM_IMAGE=$(ZVM_CLEANUP=1 zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_ROOT $zvm_mult_pass $VM_WORKER_NR )
+    if test "${VM_IMAGE}" = "${VM_IMAGE#dasd}" ; then
+       echo "did not get a real device for VM_IMAGE: $VM_IMAGE"
+       cleanup_and_exit 3
+    fi
+    VM_IMAGE="/dev/$VM_IMAGE"
+}
+
+vm_attach_swap_zvm() {
+    VM_SWAP=$(ZVM_CLEANUP=1 zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_SWAP $zvm_mult_pass $VM_WORKER_NR )
+    if test "${VM_SWAP}" = "${VM_SWAP#dasd}" ; then
+       echo "did not get a real device for VM_SWAP: $VM_SWAP"
+       cleanup_and_exit 3
+    fi
+    VM_SWAP="/dev/$VM_SWAP"
+}
+
+vm_detach_root_zvm () {
+    zvm_cp volume_detach_local $VM_VOLUME_ROOT $VM_WORKER_NR
+}
+
+vm_detach_swap_zvm() {
+    zvm_cp volume_detach_local $VM_VOLUME_SWAP $VM_WORKER_NR
+}
+
+vm_cleanup_zvm() {
+    if test -n "$VM_WORKER" -a -n "$VM_WORKER_NR" -a -n "$VM_VOLUME_ROOT" -a -n "$VM_VOLUME_SWAP" ; then
+       ZVM_CLEANUP=1
+       (zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT >/dev/null 2>&1)
+       (zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP >/dev/null 2>&1)
+       (zvm_cp volume_detach_local $VM_VOLUME_ROOT $VM_WORKER_NR >/dev/null 2>&1)
+       (zvm_cp volume_detach_local $VM_VOLUME_SWAP $VM_WORKER_NR >/dev/null 2>&1)
+    fi
+}
+
diff --git a/build.1 b/build.1
index 53cfcea879d8ad95cf5b718bff633c20b1fbfab0..8989c59b94fde164c4b75461527133bd06ebd699 100644 (file)
--- a/build.1
+++ b/build.1
@@ -10,13 +10,12 @@ build \- build SuSE Linux RPMs in a chroot environment
 .SH SYNOPSIS
 .B build
 .RB [ --clean | --no-init]
-.RB [ --rpms
-.IR path1 : path2 : ... ]
-.RB [ --arch
-.IR arch1 : arch2 : ... ]
+.RB [ --repo
+.IR dir_or_url ]
+.RB [ --repo ...]
 .RB [ --root
 .IR buildroot ]
-.RB [ specfile | srcrpm ]
+.RB [ recipefile ]
 .br
 .B build
 .B --help
@@ -24,67 +23,91 @@ build \- build SuSE Linux RPMs in a chroot environment
 .B build
 .B --verify
 .SH DESCRIPTION
-\fBbuild\fR is a tool to build SuSE Linux RPMs in a safe and clean way.
-.B build
-will install a minimal SuSE Linux as build system into some directory
-and will chroot to this system to compile the package.
-This way you don't risk to corrupt your working system (due to a broken spec
-file for example), even if the package does not use BuildRoot.
-
-.B build
-searches the spec file for a
-.I BuildRequires:
-line; if such a line is found, all the specified rpms are installed.
-Otherwise a selection of default packages are used. Note that
-.B build
-doesn't automatically resolve missing dependencies, so the specified
-rpms have to be sufficient for the build.
+\fBbuild\fR is a tool to build binary packages in a safe and reproducible
+way.
+The default is to build in a chroot sandbox, but \fBbuild\fP also supports
+building in a virtual machine for better security.
 .P
-If a spec file is specified on the command line,
+If a recipe file is specified on the command line,
 .B build
 will use this file and all other files in the directory for building
-the package. If a srcrpm is specified,
-.B build
-automatically unpacks it for the build.
-If neither is given,
+the package. If no recipe argument is provided, build will search the
+current directory for a file.
+.P
+The
 .B build
-will use all the specfiles in the current directory.
+tool understands the following recipe file types:
+.TP
+.B spec
+A specfile used to generate rpms.
+.TP
+.B src.rpm
+A source rpm, which will be unpacked for the build.
+.TP
+.B kiwi
+A kiwi config file used to generate a kiwi image.
+.TP
+.B dsc
+A dsc file used to generate Debian binary packages.
+.TP
+.B PKGBUILD
+A file used to generate Arch Linux binary packages.
 .P
 .SH OPTIONS
 .TP
 .B --clean
-remove the build system and reinitialize it from scratch.
+Remove the build system and reinitialize it from scratch.
 .TP
 .B --no-init
-skip the build system initialization and start with build immediately.
+Skip the build system initialization and start with build immediately.
+.TP
+.BI "\-\-repo " dir_or_url
+Either a directory containing binary packages (optionally with repository
+metadata), or a url pointing to some remote repository. Multiple
+\fB--repo\fP options can be used so create a specific repository
+layering. Note that packages are searched in the specified repository
+order, i.e. the first repository containing a package with a specific
+name wins regardless of the version.
+As a special form, 'zypp://reponame' can be used to specify
+a system repository. 'zypp://' selects all enabled system
+repositories. This is also the default if BUILD_RPMS is not
+set and no \fB--rpms\fP or \fB--repo\fP option is used.
+.TP
+.BI "\-\-dist " distribution
+Set the distribution. If this option is not given, build tries to
+guess the distribution by looking at the available packages.
+The specified distribution can either be a string
+like "11.2" or "sles9", "debian7", or the pathname of the build
+configuration to use.
+.TP
+.BI "\-\-root " buildroot
+Specifies where the build system is set up. Overrides the
+BUILD_ROOT enviroment variable.
+.TP
+.B --help
+Print a short help text.
+.TP
+.B --norootforbuild
+Force building with user \fRabuild\fP. Otherwise, \fBbuild\fP searches
+the recipe file for a "needsrootforbuild" hint to decide what user
+to use.
 .TP
 .B --list-state
-list rpms that would be used to create a fresh build root.
+list packages that would be used to create a fresh build root.
 Does not create the build root or perform a build.
 .TP
 .BI "\-\-rpms " path1 : path2 : path3\fR...\fP
-Where build can find the SuSE Linux RPMs needed to create the
+Where build can find the packages needed to create the
 build system. This option overrides the BUILD_RPMS environment
-variable.
+variable. This option is deprecated, use \fB--repo\fP instead.
 .TP
 .BI "\-\-arch " arch1 : arch2 : arch3\fR...\fP
 What architectures to select from the RPMs.
 .B build
 automatically sets this to a sensible value for your host if you
-don't specify this option.
-.TP
-.BI "\-\-repo " url_or_dir
-Also use the specified repository to create the build system.
-The repositories may be either of type rpmmd, yast2 (susetags),
-or a simple directory. Multiple --repo options may be given.
-As a special form, 'zypp://reponame' can be used to specify
-a system repository. 'zypp://' selects all enabled system
-repositories. This is also the default if BUILD_RPMS is not
-set and no --rpms or --repo option is used.
-.TP
-.BI "\-\-root " buildroot
-Specifies where the build system is set up. Overrides the
-BUILD_ROOT enviroment variable.
+do not specify this option so you should almost never need it.
+
+.SH RPM BUILD SPECIFIC OPTIONS
 .TP
 .B --useusedforbuild
 Tell build not to do dependency expansion, but to extract the
@@ -93,27 +116,57 @@ are found, from all "BuildRequires" lines.  This option is useful
 if you want to re-build a package from a srcrpm with exactly the
 same packages used for the srcrpm build.
 .TP
-.B --norootforbuild
-
+.B --stage
+Pass a stage option to rpmbuild. The default is \fB-ba\fP.
 .TP
-.B --help
-Print a short help text.
+.B --target
+Call rpmbuild with a target option. This can be used for cross building.
 .TP
 .B --verify
-verify the files in an existing build system.
+Verify the files in an existing build system.
+
+.SH VIRTUAL MACHINE SPECIFIC OPTIONS
 .TP
-.BI "\-\--dist " distribution
-Set the distribution. If this option is not given, build tries to
-calculate the distribution by looking at the rpm package used in the
-build.
-The specified distribution can either be a string
-like "11.2" or "sles9", or the pathname of the build configuration to
-use.
+.B "--xen --kvm --uml --qemu --emulator --zvm --lxc"
+Sets a specific vm type.
+.TP
+.BI "--vm-type " type
+As above.
+.TP
+.BI "--vm-disk " file
+Specifies the location of the disk image to use. If this option is not
+given, \fIbuildroot\fP\fB.img\fP is used (e.g. /var/tmp/build-root.img).
+.TP
+.BI "--vm-disk-size " size_in_mb
+Specify the size of the disk image to create.
+.TP
+.BI "--vm-disk-filesystem " type
+Sets the filesystem type to use when creating the disk image. The default
+is to use the ext3 filesystem.
+.TP
+.BI "--vm-swap " file
+Specifies the location of the swap file to use. If this option is not
+given, \fIbuildroot\fP\fB.swap\fP is used (e.g. /var/tmp/build-root.swap).
+.TP
+.BI "--vm-swap-size " size_in_mb
+Specify the size of the swap file to create.
+.TP
+.BI "--vm-memory " size_in_mb
+Sets the desired memory size of the virtual machine.
+.TP
+.BI "--vm-kernel " kernel_file
+Set a specific kernel to boot in the virtual machine.
+.TP
+.BI "--vm-initrd " initrd_file
+Set a specific kernel to boot in the virtual machine.
+.TP
+.B --vm-disk-clean
+Force the recreation of the disk image.
 
-.SH .spec FILE OPTIONS
+.SH RECIPE FILE OPTIONS
 The
 .B build
-command interprets some special control comments in the specfile:
+command interprets some special control comments in the recipe file:
 .TP
 .B # norootforbuild
 .TQ
@@ -144,20 +197,19 @@ within the build root.
 .TP
 .B BUILD_ROOT
 The directory where build should install the chrooted build system.
-"/var/tmp/build-root" is used by default.
+"/var/tmp/build-root" is used by default. See the \fB--root\fP option.
 .TP
 .B BUILD_RPMS
-Where build can find the SuSE Linux RPMs.  build needs them to create the
-build system.
+This can be used instead of the \fB--rpms\fP option. Deprecated.
 .TP
 .B BUILD_RPM_BUILD_STAGE
 The rpm build stage (-ba, -bb, ...).  This is just passed through to
 rpm, check the rpm manpage for a complete list and descriptions.
-"-ba" is the default.
-You can use this to add more options to RPM.
+"-ba" is the default. You should probably use the \fB--stage\fP
+option instead.
 
 .SH SEE ALSO
-.BR rpm (8),
+.BR rpm (8), dpkg (8), pacman (8), kiwi (8)
 .TP
 .BR "Maximum RPM":
 .I http://www.rpm.org/max-rpm/
index dceb7e50231ca711ceffeec5feb17714bcfa65b2..d95ab85d6d152f927c8895dda8a39bf971eba51e 100755 (executable)
@@ -4,6 +4,26 @@
 # Convert a SUSE or Debian changelog file to rpm format
 #
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 BEGIN {
   unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
 }
@@ -49,6 +69,10 @@ if (@ARGV == 2 && $ARGV[0] eq '--file') {
   opendir(D, $dir) || die("$dir: $!\n");
   my @changes = grep {/\.changes$/} readdir(D);
   closedir(D);
+  # support _service: prefixes, they need to be stripped
+  $file =~ s/^_service:.*://;
+  my %changes = map {/^((?:_service:.*:)?(.*?))$/ ? ($2, $1) : ($_, $_)} @changes;
+  @changes = keys %changes;
   @changes = sort {length($a) <=> length($b) || $a cmp $b} @changes;
   exit(1) unless @changes;     # nothing to do
   if (@changes > 1) {
@@ -61,7 +85,7 @@ if (@ARGV == 2 && $ARGV[0] eq '--file') {
       last unless $file =~ s/[-.][^-.]*$//;
     }
   }
-  @ARGV = ("$dir/$changes[0]");
+  @ARGV = ("$dir/$changes{$changes[0]}");
 }
 
 sub parse_suse {
index a0e528f933d17e68a19990d69b4ae41acce318d6..2bfc988afa522220fcf61b9817e8920421cce867 100755 (executable)
@@ -1,22 +1,33 @@
 #!/bin/bash
 
-: ${CACHE_DIR:=/var/cache/build}
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
 
-build_host_arch()
-{
+build_host_arch() {
     : ${BUILD_HOST_ARCH:=`uname -m`}
+    BUILD_INITVM_ARCH="$BUILD_HOST_ARCH"
     # avoid multiple initvm.* helpers for i586 and i686
-    test i686 != "$BUILD_HOST_ARCH" || BUILD_HOST_ARCH=i586
+    test i686 != "$BUILD_INITVM_ARCH" || BUILD_INITVM_ARCH=i586
 }
 
-set_build_arch()
-{
-    build_host_arch
-
-    if [ -z "$BUILD_ARCH" ]; then
-       BUILD_ARCH="$BUILD_HOST_ARCH"
-    fi
-
+extend_build_arch() {
     case $BUILD_ARCH in
       armv7hl) BUILD_ARCH="armv7hl:armv7l:armv6hl:armv6l:armv5tel" ;;
       armv7l) BUILD_ARCH="armv7l:armv6l:armv5tel" ;;
@@ -37,6 +48,14 @@ set_build_arch()
       sparc) BUILD_ARCH="sparc" ;;
       x86_64) BUILD_ARCH="x86_64:i686:i586:i486:i386" ;;
     esac
+}
+
+set_build_arch() {
+    build_host_arch
+    if test -z "$BUILD_ARCH" ; then
+       BUILD_ARCH="$BUILD_HOST_ARCH"
+    fi
+    extend_build_arch
     if test "$BUILD_ARCH" != "${BUILD_ARCH#i686}" ; then
        cpuflags=`grep ^flags /proc/cpuinfo`
        cpuflags="$cpuflags "
@@ -47,36 +66,39 @@ set_build_arch()
     fi
 }
 
-check_exit()
-{
+check_exit() {
     if test -e $BUILD_ROOT/exit; then
        echo "exit ..."
        cleanup_and_exit 1
     fi
 }
 
-check_use_emulator()
-{
-    arch=":$BUILD_ARCH:"
-    if test "$arch" != "${arch/:$BUILD_HOST_ARCH:/}"; then
-        # native supported arch, no emulator
-        return 1
+check_use_emulator() {
+    INITVM_NAME=
+    # check if the extended host arch contains the build arch
+    local old_build_arch="$BUILD_ARCH"
+    local arch="${BUILD_ARCH%%:*}"
+    BUILD_ARCH="$BUILD_HOST_ARCH"
+    extend_build_arch
+    BUILD_ARCH=":$BUILD_ARCH:"
+    if test "$BUILD_ARCH" != "${BUILD_ARCH/:$arch:/}" ; then
+       # native supported arch, no emulator
+       BUILD_ARCH="$old_build_arch"
+       return 1
     fi
+    BUILD_ARCH="$old_build_arch"
 
-    # to run the qemu initialization in the XEN chroot, we need to
+    # to run the qemu initialization in the vm, we need to
     # register it with a static program or shell script
-    if test -e $BUILD_DIR/initvm.$BUILD_HOST_ARCH && \
-        test -e $BUILD_DIR/qemu-reg; then
-       chmod 0755 "$BUILD_DIR/initvm.$BUILD_HOST_ARCH"
-        if [ -z "$PREPARE_VM" ]; then
-             return 0  # chroot build, we need to run
-        fi
-        # emulator in vm already registered during startup
-    else
-        # XXX: error?
-        echo "Warning: cross compile not possible due to missing static binaries. please install build-initvm package for that purpose."
-        echo "         check that the right architecture is available for your build host, you need initvm.$BUILD_HOST_ARCH for this one."
+    INITVM_NAME="initvm.$BUILD_INITVM_ARCH"
+    if test -e "$BUILD_DIR/$INITVM_NAME" -a -e "$BUILD_DIR/qemu-reg" ; then
+       chmod 0755 "$BUILD_DIR/$INITVM_NAME"
+       return 0        # chroot build, we need to run
     fi
+    # XXX: error?
+    echo "Warning: cross compile not possible due to missing static binaries. please install build-initvm package for that purpose."
+    echo "         check that the right architecture is available for your build host, you need $INITVM_NAME for this one."
+    INITVM_NAME=
     return 1
 }
 
index f9300d6076e64a1d79ee6173b1bbac46082f36a7..1370f506a62ab3de46a12d5e58c3a2892814f061 100755 (executable)
 #
 # a block is either a number or a range (start-end)
 #
-# TODO: instead of printing zeroes for each block in a hole use
-# something like 0*num
+
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
 
 use strict;
 
-my ($opt_padstart, $opt_padend, $opt_verbose);
+my ($opt_padstart, $opt_padend, $opt_verbose, $opt_manifest, $opt_mani0);
+$opt_verbose = 0;
 
 while (@ARGV)  {
   if ($ARGV[0] eq '--padstart') {
@@ -30,71 +49,139 @@ while (@ARGV)  {
   }
   if ($ARGV[0] eq '--verbose' || $ARGV[0] eq '-v') {
     shift @ARGV;
-    $opt_verbose = 1;
+    $opt_verbose++;
+    next;
+  }
+  if ($ARGV[0] eq '-0') {
+    shift @ARGV;
+    $opt_mani0 = 1;
+    next;
+  }
+  if ($ARGV[0] eq '--manifest') {
+    shift @ARGV;
+    $opt_manifest = shift @ARGV;
     next;
   }
   last;
 }
 
-if($opt_padstart) {
-  print "\n"x$opt_padstart;
+print "\n"x$opt_padstart if $opt_padstart;
+
+if ($opt_manifest) {
+  if ($opt_manifest eq '-') {
+    open(MANIFEST, '<&STDIN') || die("STDIN dup: $!\n");
+  } else {
+    open(MANIFEST, '<', $opt_manifest) || die("$opt_manifest: $!\n");
+  }
 }
 
-for my $file (@ARGV) {
-  next unless -f $file;
-  print STDERR "$file\n" if $opt_verbose;
+while (1) {
+  my $file;
+  if (@ARGV) {
+    $file = shift @ARGV;
+  } elsif ($opt_manifest) {
+    if ($opt_mani0) {
+      local $/ = "\0";
+      $file = <MANIFEST>;
+      last unless defined $file;
+      $file =~ s/\0$//s;
+    } else {
+      $file = <MANIFEST>;
+      last unless defined $file;
+      chomp $file;
+    }
+  } else {
+    last;
+  }
   my $n = $file;
-  $n =~ s/.*\///;
+  $n =~ s/([\000-\037 %])/sprintf("%%%02X", ord($1))/ges;
+  if (-l $file) {
+    print STDERR "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//);
+    my $c = readlink($file);
+    die("$file: readlink: $!\n") unless defined $c;
+    if ("/$c/" =~ /\/\.?\//s) {
+      print STDERR "$file: bad symlink ($c) ignored\n";
+      next;
+    }
+    if ("/$c/" =~ /^(\/\.\.)+\/(.*?)$/s) {
+      my ($head, $tail) = ($1, $2);
+      if (("/$tail/" =~ /\/\.\.\//s) || (($head =~ y!/!!) > ($file =~ y!/!!))) {
+        print STDERR "$file: bad symlink ($c) ignored\n";
+        next;
+      }
+    } else {
+      if ("/$c/" =~ /\/\.\.\//s) {
+        print STDERR "$file: bad symlink ($c) ignored\n";
+        next;
+      }
+    }
+    $c =~ s/([\000-\037 %])/sprintf("%%%02X", ord($1))/ges;
+    print "l $n $c\n";
+    next;
+  } elsif (-d _) {
+    print STDERR "$file\n" if $opt_verbose && $opt_verbose > 1;
+    my @stat = stat(_);
+    print "d $n\n";
+    next;
+  } elsif (!-f _) {
+    next;
+  }
+  print STDERR "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//);
 
-  if(!open(F, '<', $file)) {
+  if (!open(F, '<', $file)) {
     print STDERR "$file: $!";
     next;
   }
 
+  my @stat = stat(F);
+  die unless @stat;
+  my $st_size = $stat[7];
+  if ($st_size == 0) {
+    print "f $n 0\n";
+    close F;
+    next;
+  }
+
   my $bsize = 'xxxx';
   ioctl(F, 2, $bsize) || ioctl(F, 536870914, $bsize) || die("FIGETBSZ: $!\n");
   $bsize = unpack("L", $bsize);
+  die("$file: empty blocksize\n") unless $bsize != 0;
 
-  my @stat = stat(F);
-  my ($st_size, $st_blocks) = ($stat[7], $stat[11], $stat[12]);
-
+  print "f $n $st_size $bsize";
   my $blocks = int(($st_size+$bsize-1)/$bsize);
-
-  print "$n $st_size $bsize ";
-
   my ($firstblock, $lastblock);
   for ($b = 0; $b < $blocks; ++$b) {
     my $block = pack('I', $b);
-    if(not defined ioctl(F, 1, $block)) {
-       if(not defined ioctl(F, 536870913, $block)) {
-           die "$file: $!";
-       }
+    if (not defined ioctl(F, 1, $block)) {
+      if (not defined ioctl(F, 536870913, $block)) {
+       die "$file: $!\n";
+      }
     }
     $block = unpack('I', $block);
-    if($b == 0) {
-      print "$block";
-      $firstblock = $block;
-    } else {
-      # blocks are non-contiguous
-      if($lastblock+1 != $block) {
-       # check if we skipped some that form a range
-       if($firstblock != $lastblock) {
-         printf "-$lastblock";
-       }
+    if (!$firstblock && defined($firstblock)) {
+      # last block was hole
+      if (!$block) {
+       $lastblock++;   # count holes, 0-2 means three hole blocks
+      } else {
+       # switch back from 'hole mode' into normal mode
+       printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock;
        print " $block";
-       $firstblock = $block;
-      }
-      # last block, check if contiguous
-      if($b+1==$blocks && $lastblock+1 == $block) {
-       print "-$block";
+       $firstblock = $lastblock = $block;
       }
+      next;
+    }
+    if (!$firstblock || $lastblock + 1 != $block) {
+      # start of a new run
+      printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock;
+      print " $block";
+      $firstblock = $block;
     }
     $lastblock = $block;
   }
+  # finish last run
+  printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock;
   close F;
   print "\n";
 }
 
-if($opt_padend) {
-  print "\n"x$opt_padend;
-}
+print "\n"x$opt_padend if $opt_padend;
index 466475e7f4bfdeec5b1415adb442f6896aa34e95..05944fb2d4dd4eac5aff236d7511eb2d12fd7d4d 100644 (file)
@@ -1,16 +1,25 @@
 Repotype: arch
 
 Preinstall: glibc bash perl sed grep coreutils pacman pacman-mirrorlist
-Preinstall: gawk gzip filesystem curl acl gpgme libarchive
+Preinstall: gawk gzip filesystem curl libidn acl gpgme libarchive
 Preinstall: openssl libssh2 zlib libassuan libgpg-error attr
-Preinstall: expat xz bzip2
+Preinstall: expat xz bzip2 readline lzo krb5 e2fsprogs keyutils
+Preinstall: ncurses
 
-VMinstall: util-linux binutils readline ncurses pcre libcap
+VMinstall: util-linux libutil-linux binutils pcre libcap
 
 Required: binutils gcc glibc libtool
 
 Support: acl autoconf automake zlib bzip2 filesystem curl
 Support: libtool ncurses perl gpgme libarchive openssl libssh2
 Support: libassuan libgpg-error attr expat xz pacman pacman-mirrorlist
-Support: fakeroot file sudo patch make net-tools pkg-config
+Support: fakeroot file sudo patch make net-tools pkg-config inetutils
+Support: bison flex gettext which
+
+Prefer: zlib ttf-dejavu
+Prefer: libgl jdk7-openjdk libdrm
+
+Prefer: -nvidia-libgl -nvidia-304xx-utils
+Prefer: mesa-libgl
+Prefer: curl:ca-certificates
 
index 77cd7aeb68dbab929895d03f9af8f466d5d1fc1a..37981f734081fe23288b5a913719c1ca699c94eb 100644 (file)
@@ -22,6 +22,7 @@ Conflict: kiwi:systemd-mini
 Conflict: libudev1:udev-mini
 
 FileProvides: /usr/sbin/groupadd pwdutils
+FileProvides: /usr/sbin/useradd shadow
 FileProvides: /sbin/netconfig sysconfig-netconfig
 
 Preinstall: aaa_base attr bash coreutils diffutils
@@ -37,14 +38,14 @@ Runscripts: aaa_base
 Order: libopenssl0_9_8:openssl-certs
 
 Prefer: libdb-4_8-devel
-VMinstall: util-linux libmount1 perl-base libdb-4_8 libsepol1 libblkid1 libuuid1 net-tools
+VMinstall: util-linux libmount1 perl-base libdb-4_8 libsepol1 libblkid1 libuuid1 net-tools 
+# kernel-obs-build - bnc#865554 
 
 ExportFilter: \.x86_64\.rpm$ x86_64
 ExportFilter: \.ia64\.rpm$ ia64
 ExportFilter: \.s390x\.rpm$ s390x
 ExportFilter: \.ppc64\.rpm$ ppc64
 ExportFilter: \.ppc\.rpm$ ppc
-ExportFilter: \.ppc64le\.rpm$ ppc64le
 ExportFilter: -ia32-.*\.rpm$
 ExportFilter: -32bit-.*\.sparc64\.rpm$
 ExportFilter: -64bit-.*\.sparcv9\.rpm$
@@ -55,7 +56,7 @@ ExportFilter: ^glibc(?:-devel)?-64bit-.*\.sparcv9\.rpm$ sparcv9
 # it would be a great idea to have, but sometimes installation-images wants to build debuginfos in
 #ExportFilter: -debuginfo-.*\.rpm$
 #ExportFilter: -debugsource-.*\.rpm$
-ExportFilter: ^master-boot-code.*\.i586.rpm$ . x86_64
+#ExportFilter: ^master-boot-code.*\.i586.rpm$ . x86_64
 ExportFilter: ^acroread.*\.i586.rpm$ . x86_64
 ExportFilter: ^avmailgate.*\.i586.rpm$ . x86_64
 ExportFilter: ^avmailgate.*\.ppc.rpm$ . ppc64
@@ -134,7 +135,7 @@ Prefer: pkg-config gtk-doc wlan-kmp-default lua-libs lua-devel
 Prefer: gnu-jaf classpathx-mail avahi-compat-mDNSResponder yast2-control-center-qt
 Prefer: vim-normal myspell-american wine
 Prefer: eclipse-platform eclipse-scripts
-Prefer: yast2-theme-openSUSE
+Prefer: yast2-theme-openSUSE enlightenment-theme-upstream
 Prefer: amarok:amarok-xine
 Prefer: kdenetwork3-vnc:tightvnc
 Prefer: libgweather0 jessie ndesk-dbus ndesk-dbus-glib tomcat6-jsp-2_1-api tomcat6-servlet-2_5-api
@@ -237,13 +238,14 @@ Prefer: typelib-1_0-Gst-0_10 gstreamer-0_10-utils-unversioned gstreamer-0_10-uti
 Prefer: libudev-mini-devel libudev-mini1 udev-debuginfo libudev1-debuginfo
 Prefer: systemd-mini systemd-mini-devel
 Prefer: systemd-mini-devel:systemd-mini
-Prefer: udev-mini
+Prefer: udev-mini libcom_err2-mini libext2fs2-mini
 Prefer: libudev1:udev
 Prefer: xmlgraphics-commons:apache-commons-io
 # the -32bit stuff provides things it shouldn't (hopefully temporary)
 Prefer: -typelib-1_0-GdkPixbuf-2_0-32bit -typelib-1_0-Pango-1_0-32bit
 Prefer: postgresql postgresql-server
-Prefer: -unzip-rcc
+Prefer: -unzip-rcc -linuxconsoletools
+
 
 # kernel bug (coolo)
 Prefer: kernel-default-devel
@@ -255,6 +257,7 @@ Prefer: -xerces-j2-xml-resolver -xerces-j2-xml-apis
 Prefer: -vmware-player
 Prefer: libgcc_s1 libgcc_s1-32bit libgcc_s1-64bit
 Prefer: libffi%{gcc_version} libffi%{gcc_version}-devel
+Prefer: -libatomic1-gcc49 -libitm1-gcc49 -libgcj_bc1-gcc49 -libtsan0-gcc49 -libatomic1-gcc49-32bit -libitm1-gcc49-32bit
 Prefer: libgcc_s1-x86 libffi4 libgcj_bc1
 Prefer: libffi4-32bit libffi4-64bit
 Prefer: libgomp1 libgomp1-32bit libgomp1-64bit
@@ -304,8 +307,12 @@ Prefer: -kmod-compat
 Prefer: gettext-tools-mini gettext-runtime-mini
 # choice p11-kit-nss-trust
 Prefer: mozilla-nss-certs
-# amarok dependency
+# amarok dependency resolution
 Prefer: phonon-backend-gstreamer-0_10
+# replacing mkinitrd
+Prefer: dracut
+# Not sure if wicked is ready yet
+Prefer: sysconfig-network
 
 Ignore: java-1_7_0-openjdk:mozilla-nss
 Ignore: java-1_7_0-openjdk:java-ca-certificates
@@ -389,6 +396,7 @@ Ignore: mkinitrd:pciutils
 Ignore: pciutils:pciutils-ids
 Ignore: postfix:iproute2
 Ignore: aaa_base:systemd
+Ignore: gpm:systemd
 Ignore: ConsoleKit:systemd
 Ignore: openssh:systemd
 Ignore: cronie:systemd
@@ -398,6 +406,8 @@ Ignore: systemd:dbus-1
 Ignore: systemd:pam-config
 Ignore: systemd:udev
 Ignore: systemd-mini:this-is-only-for-build-envs
+Ignore: udev-mini:this-is-only-for-build-envs
+Ignore: libudev-mini1:this-is-only-for-build-envs
 Ignore: polkit:ConsoleKit
 Ignore: logrotate:cron
 Ignore: texlive-filesystem:cron
@@ -428,6 +438,7 @@ Ignore: man:groff-full
 Ignore: git-core:rsync
 Ignore: apache2:systemd
 Ignore: icewm-lite:icewm
+Ignore: cluster-glue:sudo
 
 Ignore: libgcc:glibc-32bit
 Ignore: libgcc41:glibc-32bit
@@ -465,6 +476,7 @@ Ignore: libreoffice:libreoffice-i18n
 Ignore: libreoffice:libreoffice-icon-themes
 Ignore: mediawiki:php-session,php-gettext,php-zlib,php-mysql,mod_php_any
 Ignore: squirrelmail:mod_php_any,php-session,php-gettext,php-iconv,php-mbstring,php-openssl
+Ignore: perl-Log-Log4perl:rrdtool
 
 Ignore: simias:mono(log4net)
 Ignore: zmd:mono(log4net)
@@ -541,6 +553,7 @@ Ignore: NetworkManager:dhcp
 Ignore: sysconfig:dbus-1
 Ignore: sysconfig:procps
 Ignore: sysconfig:iproute2
+Ignore: sysconfig-network:iproute2
 Ignore: sysconfig:tunctl
 # no build dependencies
 Ignore: libksuseinstall1:yast2-packager
@@ -553,17 +566,14 @@ Ignore: NetworkManager:dhcp-client
 Ignore: autoyast2:yast2-schema
 Ignore: libgio-2_0-0:dbus-1-x11
 Ignore: weather-wallpaper:inkscape
+Ignore: libgamin-1-0:gamin-server
+Ignore: libfam0-gamin:gamin-server
 
 %ifarch %arm
 Prefer: java-1_7_0-icedtea java-1_7_0-icedtea-devel
 %else
-%ifnarch s390 s390x
 Prefer: java-1_7_0-openjdk java-1_7_0-openjdk-devel
 %endif
-%ifarch s390 s390x
-Prefer: java-1_6_0-ibm java-1_6_0-ibm-devel
-%endif
-%endif
 
 Prefer: -java-1_5_0-gcj-compat-devel
 %ifarch %ix86 x86_64
@@ -612,62 +622,30 @@ Substitute: kernel-binary-packages kernel-default
 Substitute: yast2-theme-SLED
 Substitute: yast2-theme-SLE
 
-Optflags: i586 -fomit-frame-pointer -fmessage-length=0 -grecord-gcc-switches -fstack-protector
-Optflags: i686 -march=i686 -mtune=generic -fomit-frame-pointer -fmessage-length=0 -grecord-gcc-switches -fstack-protector
-Optflags: x86_64 -fmessage-length=0 -grecord-gcc-switches -fstack-protector
-Optflags: ppc -fmessage-length=0 -grecord-gcc-switches -fstack-protector
-Optflags: ppc64 -fmessage-length=0 -grecord-gcc-switches -fstack-protector
-Optflags: ia64 -fmessage-length=0 -grecord-gcc-switches -fstack-protector
-Optflags: s390 -fmessage-length=0 -grecord-gcc-switches -fstack-protector
-Optflags: s390x -fmessage-length=0 -grecord-gcc-switches -fstack-protector
-Optflags: armv6l -fmessage-length=0 -grecord-gcc-switches -fstack-protector
-Optflags: armv6hl -fmessage-length=0 -grecord-gcc-switches -fstack-protector
-Optflags: armv7l -fmessage-length=0 -grecord-gcc-switches -fstack-protector
-Optflags: armv7hl -fmessage-length=0 -grecord-gcc-switches -fstack-protector
+Optflags: i586 -fomit-frame-pointer -fmessage-length=0 -grecord-gcc-switches
+Optflags: i686 -march=i686 -mtune=generic -fomit-frame-pointer -fmessage-length=0 -grecord-gcc-switches
+Optflags: x86_64 -fmessage-length=0 -grecord-gcc-switches
+Optflags: ppc -fmessage-length=0 -grecord-gcc-switches
+Optflags: ppc64 -fmessage-length=0 -grecord-gcc-switches
+Optflags: ia64 -fmessage-length=0 -grecord-gcc-switches
+Optflags: s390 -fmessage-length=0 -grecord-gcc-switches
+Optflags: s390x -fmessage-length=0 -grecord-gcc-switches
+Optflags: armv5el -fmessage-length=0 -grecord-gcc-switches
+Optflags: armv5tel -fmessage-length=0 -grecord-gcc-switches
+Optflags: armv7l -fmessage-length=0 -grecord-gcc-switches
+Optflags: armv7hl -fmessage-length=0 -grecord-gcc-switches
 Optflags: aarch64 -fmessage-length=0 -grecord-gcc-switches
 # need mcpu=ultrasparc to complete sparcv8plus to sparcv9 (adds, for example, atomic ops)
-Optflags: sparcv9 -fmessage-length=0 -grecord-gcc-switches -mcpu=ultrasparc -fstack-protector
-Optflags: sparc64 -fmessage-length=0 -grecord-gcc-switches -mcpu=ultrasparc -fstack-protector
+Optflags: sparcv9 -fmessage-length=0 -grecord-gcc-switches -mcpu=ultrasparc
+Optflags: sparc64 -fmessage-length=0 -grecord-gcc-switches -mcpu=ultrasparc
 %ifarch sparcv9
 Target: sparcv9
 %endif
-# Workaround buildservice bug (scheduler arch not matching target arch)
-%ifarch armv7l armv7hl
-Target: armv7hl-suse-linux
-%endif
-%ifarch armv6l armv6hl
-Target: armv6hl-suse-linux
-%endif
 
-Optflags: * -O2 -Wall -D_FORTIFY_SOURCE=2 -funwind-tables -fasynchronous-unwind-tables
+Optflags: * -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables
 
 %define suse_version 1320
 
-%ifarch aarch64 armv6l armv6hl
-%define qemu_user_space_build 1
-%endif
-
-%if "%qemu_user_space_build" == "1"
-Hostarch: x86_64
-Constraint: hostlabel QEMU_ARM
-
-Macros:
-%qemu_user_space_build 1
-%_without_mono 1
-:Macros
-
-%ifarch armv6l armv6hl
-Preinstall: qemu-linux-user
-%endif
-
-%ifarch armv7l armv7hl
-Preinstall: qemu-linux-user
-%endif
-
-ExportFilter: ^qemu-linux-user.*\.x86_64\.rpm$ . armv7l armv6l
-%endif
-
-
 Macros:
 %insserv_prereq insserv sed
 %fillup_prereq fillup coreutils grep diffutils
diff --git a/configs/sles12.conf b/configs/sles12.conf
new file mode 100644 (file)
index 0000000..931eaf1
--- /dev/null
@@ -0,0 +1,668 @@
+%define gcc_version 48
+
+Patterntype: rpm-md ymp
+
+Substitute: kiwi-packagemanager:instsource kiwi-instsource cdrkit-cdrtools-compat syslinux dosfstools kiwi-instsource-plugins-SLE-12
+
+Conflict: kiwi:libudev-mini1
+Conflict: kiwi:systemd-mini
+Conflict: libudev1:udev-mini
+Conflict: udev:udev-mini
+Conflict: sles-release:dummy-release
+
+FileProvides: /usr/sbin/groupadd pwdutils
+FileProvides: /usr/sbin/useradd shadow
+FileProvides: /sbin/netconfig sysconfig-netconfig
+FileProvides: /usr/bin/docbook2man docbook-utils
+FileProvides: /usr/bin/mkisofs cdrkit-cdrtools-compat
+FileProvides: /usr/sbin/lockdev lockdev
+FileProvides: /bin/logger util-linux-systemd
+
+Preinstall: aaa_base attr bash coreutils diffutils
+Preinstall: filesystem fillup glibc grep
+Preinstall: libbz2-1 libgcc_s1 m4 libncurses5 pam
+Preinstall: permissions libreadline6 rpm sed tar libz1 libselinux1
+Preinstall: liblzma5 libcap2 libacl1 libattr1
+Preinstall: libpopt0 libelf1 liblua5_1
+Preinstall: libpcre1 libsmartcols1
+
+Runscripts: aaa_base
+
+Order: libopenssl0_9_8:openssl-certs
+
+VMinstall: util-linux libmount1 perl-base libdb-4_8 libsepol1 libblkid1 libuuid1 net-tools
+VMInstall: kernel-obs-build
+
+%ifarch aarch64
+Preinstall: qemu-linux-user
+Runscripts: qemu-linux-user
+Hostarch: x86_64
+Macros:
+%qemu_user_space_build 1
+:Macros
+%endif
+
+Required: rpm-build
+
+Support: pam-modules
+
+# the basic stuff
+Support: perl build-mkbaselibs
+Support: brp-check-suse post-build-checks rpmlint-Factory
+
+Prefer: libblkid1-mini libuuid1-mini libmount1-mini libsmartcols1-mini libdb-4_8-devel
+Prefer: krb5-mini krb5-mini-devel
+Conflict: krb5-devel:krb5-mini
+Conflict: krb5:krb5-mini-devel
+Prefer: libreadline5
+Prefer: libdb_java-4_8 libicu
+Prefer: cracklib-dict-small postfix
+Prefer: jta fam mozilla mozilla-nss
+Prefer: unixODBC libsoup glitz
+Prefer: gnome-panel desktop-data-SLE gnome2-SuSE
+Prefer: mono-nunit gecko-sharp2
+Prefer: apache2-prefork Mesa openmotif-libs ghostscript-mini ghostscript
+Prefer: gtk-sharp2 glib-sharp2 glade-sharp2
+Prefer: libzypp-zmd-backend novell-NLDAPsdk zaptel-kmp-default
+Prefer: hbedv-dazuko-kmp-default dazuko-kmp-default vmware-wkstnmods-kmp-default
+Prefer: virtualbox-kmp-default virtualbox-host-kmp-default
+Prefer: libstdc++6 libgcc_s1 libquadmath0
+Prefer: libstdc++6-32bit libstdc++6-64bit
+Prefer: libstdc++6-x86
+Prefer: libstdc++6-gcc%{gcc_version} libgcc_s1-gcc%{gcc_version} libgomp1-gcc%{gcc_version}
+%ifarch s390x
+Prefer: -libstdc++41
+%endif
+Prefer: libstroke
+Prefer: syslog-service syslogd
+Prefer: gnome-sharp2:art-sharp2 gnome-sharp:art-sharp
+Prefer: ifolder3:gnome-sharp2 ifolder3:gconf-sharp2
+Prefer: nautilus-ifolder3:gnome-sharp2 inkscape:gtkmm24
+Prefer: gconf-sharp2:glade-sharp2 gconf-sharp:glade-sharp
+Prefer: gjdoc:antlr-bootstrap
+Prefer: tomboy:gconf-sharp2 tomboy:gnome-sharp2
+Prefer: zmd:libzypp-zmd-backend
+Prefer: yast2-packagemanager-devel:yast2-packagemanager
+Prefer: glitz-32bit:Mesa-32bit
+Prefer: poppler-tools
+Prefer: libjpeg8-devel libjpeg-turbo
+Prefer: banshee:banshee-engine-gst helix-banshee:helix-banshee-engine-gst
+Prefer: banshee-1:banshee-1-client-classic
+Prefer: libfam0
+Prefer: java-1_5_0-ibm:java-1_5_0-ibm-alsa
+Prefer: java-1_5_0-ibm:java-1_5_0-ibm-fonts
+Prefer: java-1_6_0-ibm:java-1_6_0-ibm-fonts
+Prefer: microcode_ctl:kernel-default
+Prefer: notification-daemon
+Prefer: pkg-config gtk-doc wlan-kmp-default lua-libs lua-devel
+Prefer: gnu-jaf classpathx-mail avahi-compat-mDNSResponder yast2-control-center-qt
+Prefer: vim-normal myspell-american wine
+Prefer: eclipse-platform eclipse-scripts
+Prefer: yast2-theme-SLE
+Prefer: amarok:amarok-xine
+Prefer: kdenetwork3-vnc:tightvnc
+Prefer: libgweather0 jessie ndesk-dbus ndesk-dbus-glib tomcat6-jsp-2_1-api tomcat6-servlet-2_5-api
+Prefer: icewm-lite
+Prefer: patterns-openSUSE-GNOME-cd:banshee
+Prefer: yast2-ncurses-pkg
+Prefer: monodevelop: mono-addins
+Prefer: ant-trax:saxon
+Prefer: gnome-session:gnome-session-branding-openSUSE
+Prefer: gnome-session:gconf2-branding-openSUSE
+Prefer: yast2-qt:yast2-qt-branding-openSUSE
+Prefer: bundle-lang-gnome:gnome-session-branding-openSUSE
+Prefer: fcitx:fcitx-branding-openSUSE
+Prefer: xfce4-notifyd:xfce4-notifyd-branding-upstream
+Prefer: exo-data:exo-branding-upstream
+Prefer: xfce4-settings:xfce4-settings-branding-upstream
+Prefer: xfdesktop:xfdesktop-branding-upstream
+Prefer: texlive-xmltex texlive-tools texlive-jadetex
+Prefer: mono-web:mono-data-sqlite
+Prefer: gnome-games:gnuchess
+Prefer: glchess:gnuchess
+Prefer: libreoffice:libreoffice-branding-upstream
+Prefer: yast2-branding-openSUSE
+Prefer: gimp:gimp-branding-upstream
+Prefer: libesd-devel:esound
+Prefer: libesd0:esound-daemon
+Prefer: package-lists-openSUSE-KDE-cd: esound-daemon
+Prefer: glib2:glib2-branding-upstream
+Prefer: libgio-2_0-0:gio-branding-upstream
+Prefer: libglib-2_0-0:glib2-branding-upstream
+Prefer: kdelibs4:kdelibs4-branding-upstream
+Prefer: kdebase4-workspace:kdebase4-workspace-branding-upstream
+Prefer: kdelibs4-branding:kdelibs4-branding-upstream
+Prefer: PackageKit:PackageKit-branding-upstream
+Prefer: lightdm-gtk-greeter:lightdm-gtk-greeter-branding-upstream
+Prefer: mysql-connector-java:java-1_5_0-gcj-compat
+Prefer: -geronimo-jta-1_0_1B-api -geronimo-jms-1_1-api -geronimo-el-1_0-api
+Prefer: rhino:xmlbeans-mini
+Prefer: ghostscript-devel:ghostscript-library
+Prefer: gdm:gdm-branding-upstream
+Prefer: rpcbind log4j-mini eclipse-source
+Prefer: mx4j:log4j-mini
+Prefer: podsleuth:sg3_utils
+Prefer: libcdio_cdda0 libcdio_paranoia0
+Prefer: mozilla-xulrunner191
+Prefer: mozilla-xulrunner191-32bit
+Prefer: boo tog-pegasus
+Prefer: kde4-kupdateapplet:kde4-kupdateapplet-zypp
+Prefer: kdebase4-workspace:kdebase4-workspace-ksysguardd
+Prefer: ant:xerces-j2
+Prefer: dhcp-client:dhcp
+Prefer: dummy-release
+# provides typelib(St)
+Prefer: -cinnamon
+Prefer: -bundle-lang-kde-de -bundle-lang-kde-en -bundle-lang-kde-es
+Prefer: -bundle-lang-kde-fr -bundle-lang-kde-pt -bundle-lang-kde-el
+Prefer: -bundle-lang-kde-zh -bundle-lang-kde-ja -bundle-lang-kde-ru -bundle-lang-kde-pl
+Prefer: -bundle-lang-kde-sv -bundle-lang-kde-ko -bundle-lang-kde-fi -bundle-lang-kde-da
+Prefer: -bundle-lang-kde-cs -bundle-lang-kde-nl -bundle-lang-kde-hu -bundle-lang-kde-nb
+Prefer: -bundle-lang-kde-it -bundle-lang-kde-ca -bundle-lang-kde-ar
+Prefer: -bundle-lang-gnome-es -bundle-lang-gnome-de -bundle-lang-gnome-fr
+Prefer: -bundle-lang-gnome-pt -bundle-lang-gnome-en -bundle-lang-gnome-el
+Prefer: -bundle-lang-gnome-zh -bundle-lang-gnome-ja -bundle-lang-gnome-ru -bundle-lang-gnome-cs
+Prefer: -bundle-lang-gnome-ko -bundle-lang-gnome-da -bundle-lang-gnome-nl -bundle-lang-gnome-hu
+Prefer: -bundle-lang-gnome-pl -bundle-lang-gnome-fi -bundle-lang-gnome-nb -bundle-lang-gnome-sv
+Prefer: -bundle-lang-gnome-it -bundle-lang-gnome-ca -bundle-lang-gnome-ar
+Prefer: -bundle-lang-gnome-extras-es -bundle-lang-gnome-extras-de -bundle-lang-gnome-extras-fr
+Prefer: -bundle-lang-gnome-extras-pt -bundle-lang-gnome-extras-en -bundle-lang-gnome-extras-el
+Prefer: -bundle-lang-gnome-extras-zh -bundle-lang-gnome-extras-ja -bundle-lang-gnome-extras-ru -bundle-lang-gnome-extras-cs
+Prefer: -bundle-lang-gnome-extras-ko -bundle-lang-gnome-extras-da -bundle-lang-gnome-extras-nl -bundle-lang-gnome-extras-hu
+Prefer: -bundle-lang-gnome-extras-pl -bundle-lang-gnome-extras-fi -bundle-lang-gnome-extras-nb -bundle-lang-gnome-extras-sv
+Prefer: -bundle-lang-gnome-extras-it -bundle-lang-gnome-extras-ca -bundle-lang-gnome-extras-ar
+Prefer: -bundle-lang-common-es -bundle-lang-common-de -bundle-lang-common-fr
+Prefer: -bundle-lang-common-pt -bundle-lang-common-en -bundle-lang-common-el
+Prefer: -bundle-lang-common-ja -bundle-lang-common-zh -bundle-lang-common-cs -bundle-lang-common-ru
+Prefer: -bundle-lang-common-nl -bundle-lang-common-hu -bundle-lang-common-pl -bundle-lang-common-da
+Prefer: -bundle-lang-common-ko -bundle-lang-common-nb -bundle-lang-common-fi -bundle-lang-common-sv
+Prefer: -bundle-lang-common-it -bundle-lang-common-ca -bundle-lang-common-ar
+Prefer: -libgcc-mainline -libstdc++-mainline -gcc-mainline-c++
+Prefer: -libgcj-mainline -viewperf -compat -compat-openssl097g
+Prefer: -zmd -libreoffice -pam-laus -libgcc-tree-ssa -busybox-links
+Prefer: -python-setuptools
+Prefer: -kdenetwork3-InstantMessenger
+Prefer: -icc-profiles
+Prefer: libsocialweb:libsocialweb-branding-upstream
+Prefer: gnome-panel:gnome-panel-branding-upstream
+Prefer: vala
+Prefer: wallpaper-branding-SLE
+Prefer: -crimson
+Prefer: -rubygem-rack-1_1 -rubygem-rack-1_2 -rubygem-rack-1_3 -rubygem-tilt-1_1 -rubygem-rack-1_4
+Prefer: -rubygem-method_source-0_7 -rubygem-rails-2_3 -rubygem-activerecord-2_3
+Prefer: -rubygem-json_pure-1_5
+Prefer: geronimo-servlet-2_4-api
+Prefer: -libhdf5-0-openmpi -libhdf5_hl0-openmpi -libhdf5_hl8-openmpi -libhdf5-8-openmpi
+Prefer: typelib-1_0-Gst-0_10 gstreamer-0_10-utils-unversioned gstreamer-0_10-utils typelib-1_0-GstInterfaces-0_10
+# prefer the small systemd for building
+Prefer: libudev-mini-devel libudev-mini1 udev-debuginfo libudev1-debuginfo
+Prefer: systemd-mini systemd-mini-devel
+Prefer: systemd-mini-devel:systemd-mini
+Prefer: udev-mini libcom_err2-mini libext2fs2-mini
+Prefer: libudev1:udev
+Prefer: xmlgraphics-commons:apache-commons-io
+# the -32bit stuff provides things it shouldn't (hopefully temporary)
+Prefer: -typelib-1_0-GdkPixbuf-2_0-32bit -typelib-1_0-Pango-1_0-32bit
+Prefer: postgresql postgresql-server
+Prefer: -unzip-rcc
+
+Prefer: kernel-default-devel
+Prefer: wxWidgets-2_9-devel
+
+Prefer: -NX -xaw3dd -db43
+Prefer: -xerces-j2-xml-resolver -xerces-j2-xml-apis
+Prefer: -vmware-player
+Prefer: libgcc_s1 libgcc_s1-32bit libgcc_s1-64bit
+Prefer: libffi%{gcc_version} libffi%{gcc_version}-devel
+Prefer: libgcc_s1-x86 libffi4 libgcj_bc1
+Prefer: libffi4-32bit libffi4-64bit
+Prefer: libgomp1 libgomp1-32bit libgomp1-64bit
+Prefer: libmudflap4 libmudflap4-32bit libmudflap4-64bit
+Prefer: libobjc4 libgfortran3 libquadmath0
+Prefer: -libnetpbm -libcdio7-mini -libiso9660-5-mini -libiso9660-7-mini -libcdio10-mini -libcdio12-mini
+Prefer: -libcdio-mini -faac-mini -libcdio-mini-devel
+Prefer: -seamonkey
+Prefer: -libdb-4_4-devel -libdb-4_5-devel -libevoldap-2_4-2
+Prefer: libopenal0-soft openal-soft -lsb-buildenv
+Prefer: -libevent
+Prefer: gnu-crypto libusb-compat-devel
+Prefer: libusb-0_1-4
+Prefer: CASA_auth_token_svc:xerces-j2
+Prefer: libreoffice:xerces-j2
+Prefer: k3b:libdvdread4
+Prefer: glibc-devel
+Prefer: -libpcap -libiniparser -loudmouth -libkonq4 -libnetcdf-4 -java-1_7_0-openjdk-javadoc -java-1_7_0-icedtea-javadoc
+Prefer: -java-1_7_0-icedtea-devel
+Prefer: NetworkManager:dhcp-client
+Prefer: kdebase3-SuSE:kdebase3
+Prefer: kde4-kdm:kde4-kdm-branding-upstream
+Prefer: kdm:kdm-branding-upstream
+Prefer: pcre-tools
+Prefer: libpopt0
+Prefer: -apache2-mod_perl -otrs -qa_apache_testsuite -ctcs2
+Prefer: libgnome-keyring-devel
+Prefer: linux-glibc-devel
+Prefer: squid sysvinit
+Prefer: libpng16-compat-devel
+Prefer: -python3 -python3-gobject-devel -python3-gobject2-devel -x11-video-fglrxG02 -libpng12-0
+Prefer: perl-Mail-SPF:perl-Error libldb0 -audit-libs mysql-community-server mysql-community-server-client
+Prefer: xml-commons-resolver12 xml-commons-jaxp-1.3-apis
+Prefer: xmlgraphics-fop:xerces-j2
+Prefer: libxfce4ui:libxfce4ui-branding-upstream
+Prefer: libgarcon-1-0:libgarcon-branding-upstream
+Prefer: libgarcon-data:libgarcon-branding-upstream
+Prefer: libexo-1-0:libexo-1-0-branding-upstream
+Prefer: gnome-shell:mozilla-js20
+Prefer: cogl-devel
+Prefer: -perl-XML-SAX
+Prefer: gettext-tools-mini gettext-runtime-mini
+Prefer: mozilla-nss-certs
+Prefer: phonon-backend-gstreamer-0_10
+Prefer: dracut
+Prefer: kmod-compat
+
+Prefer: typelib-1_0-Wnck-3_0
+Prefer: -cups154-libs -cups154-client -cups154
+
+Ignore: java-1_7_0-openjdk:mozilla-nss
+Ignore: java-1_7_0-openjdk:java-ca-certificates
+Ignore: openSUSE-release:openSUSE-release-ftp,openSUSE-release-dvd5,openSUSE-release-biarch,openSUSE-release-livecdkde,openSUSE-release-livecdgnome
+Ignore: cracklib:cracklib-dict
+Ignore: aaa_base:aaa_skel,suse-release,logrotate,ash,distribution-release,udev
+Ignore: sysvinit:mingetty
+Ignore: gettext-tools:libgcj,libstdc++-devel,libgcj41,libstdc++41-devel,libgcj42,libstdc++42-devel
+Ignore: libgcj43,libstdc++43-devel
+Ignore: libgcj44,libstdc++44-devel
+Ignore: libgcj45,libstdc++45-devel
+Ignore: libgcj46,libstdc++46-devel
+Ignore: libgcj47,libstdc++47-devel
+Ignore: pwdutils:openslp
+Ignore: pam-modules:resmgr
+Ignore: rpm:suse-build-key,build-key
+Ignore: bind-utils:bind-libs
+Ignore: alsa:dialog,pciutils
+Ignore: portmap:syslogd
+Ignore: xorg-x11:x11-tools,resmgr,xkeyboard-config,xorg-x11-Mesa,libusb,freetype2,libjpeg,libpng
+Ignore: xorg-x11-server:xorg-x11-driver-input,xorg-x11-driver-video
+Ignore: apache2:logrotate
+Ignore: arts:alsa,audiofile,resmgr,libogg,libvorbis
+Ignore: kdelibs3:alsa,arts,OpenEXR,aspell,cups-libs,mDNSResponder-lib,krb5,libjasper
+Ignore: kdelibs3-devel:libvorbis-devel
+Ignore: kdebase3:kdebase3-ksysguardd,OpenEXR,dbus-1,dbus-1-qt,hal,powersave,openslp,libusb
+Ignore: kdebase3-SuSE:release-notes
+Ignore: jack:alsa,libsndfile
+Ignore: libxml2-devel:readline-devel
+Ignore: gnome-vfs2:gnome-mime-data,desktop-file-utils,cdparanoia,dbus-1,dbus-1-glib,hal,libsmbclient,fam,file_alteration
+Ignore: libgda:file_alteration
+Ignore: gnutls:lzo,libopencdk
+Ignore: gnutls-devel:lzo-devel,libopencdk-devel
+Ignore: pango:cairo,glitz,libpixman,libpng
+Ignore: pango-devel:cairo-devel
+Ignore: cairo-devel:libpixman-devel
+Ignore: libgnomeprint:libgnomecups
+Ignore: libgnomeprintui:libgnomecups
+Ignore: orbit2-devel:indent
+Ignore: qt3:libmng
+Ignore: qt-sql:qt_database_plugin
+Ignore: gtk2:libpng,libtiff
+Ignore: libgnomecanvas-devel:glib-devel
+Ignore: libgnomeui:gnome-icon-theme,shared-mime-info
+Ignore: scrollkeeper:docbook_4
+Ignore: gnome-desktop:libgnomesu,startup-notification
+Ignore: python-devel:python-tk
+Ignore: gnome-pilot:gnome-panel
+Ignore: gnome-panel:control-center2
+Ignore: gnome-menus:kdebase3
+Ignore: gnome-main-menu:rug
+Ignore: libbonoboui:gnome-desktop
+Ignore: libxfce4ui-1-0:exo-tools
+Ignore: docbook_4:iso_ent,xmlcharent
+Ignore: control-center2:nautilus,evolution-data-server,gnome-menus,gstreamer-plugins,gstreamer,metacity,mozilla-nspr,mozilla,libxklavier,gnome-desktop,startup-notification
+Ignore: docbook-xsl-stylesheets:xmlcharent
+Ignore: liby2util-devel:libstdc++-devel,openssl-devel
+Ignore: yast2:yast2-ncurses,yast2_theme,perl-Config-Crontab,yast2-xml,SuSEfirewall2
+Ignore: yast2-core:netcat,hwinfo,wireless-tools,sysfsutils
+Ignore: yast2-core-devel:libxcrypt-devel,hwinfo-devel,blocxx-devel,sysfsutils,libstdc++-devel
+Ignore: yast2-packagemanager-devel:rpm-devel,curl-devel,openssl-devel
+Ignore: yast2-devtools:libxslt
+Ignore: yast2-iscsi-lio-server:lio-utils
+Ignore: yast2-installation:yast2-update,yast2-mouse,yast2-country,yast2-bootloader,yast2-packager,yast2-network,yast2-online-update,yast2-users,release-notes,autoyast2-installation
+Ignore: yast2-bootloader:bootloader-theme
+Ignore: yast2-packager:yast2-x11,libyui_pkg
+Ignore: yui_backend
+Ignore: yast2-x11:sax2-libsax-perl
+Ignore: yast2-network:yast2-inetd
+Ignore: openslp-devel:openssl-devel
+Ignore: java-1_4_2-sun:xorg-x11-libs
+Ignore: java-1_4_2-sun-devel:xorg-x11-libs
+Ignore: tetex:xorg-x11-libs,expat,fontconfig,freetype2,libjpeg,ghostscript-x11,xaw3d,gd,dialog,ed
+Ignore: texlive-bin:ghostscript-x11
+Ignore: texlive-bin-omega:ghostscript-x11
+Ignore: yast2-country:yast2-trans-stats
+Ignore: tpb:tpctl-kmp
+Ignore: tpctl:tpctl-kmp
+Ignore: zaptel:zaptel-kmp
+Ignore: mkinitrd:pciutils
+Ignore: pciutils:pciutils-ids
+Ignore: postfix:iproute2
+Ignore: aaa_base:systemd
+Ignore: gpm:systemd
+Ignore: ConsoleKit:systemd
+Ignore: openssh:systemd
+Ignore: cronie:systemd
+Ignore: systemd:kbd
+Ignore: systemd:kmod
+Ignore: systemd:systemd-presets-branding
+Ignore: systemd:dbus-1
+Ignore: systemd:pam-config
+Ignore: systemd:udev
+Ignore: pesign:systemd
+Ignore: systemd-mini:this-is-only-for-build-envs
+Ignore: udev-mini:this-is-only-for-build-envs
+Ignore: libudev-mini1:this-is-only-for-build-envs
+Ignore: polkit:ConsoleKit
+Ignore: logrotate:cron
+Ignore: texlive-filesystem:cron
+Ignore: xinit:xterm
+Ignore: xdm:xterm
+Ignore: gnome-control-center:gnome-themes-accessibility
+Ignore: coreutils:info
+Ignore: cpio:info
+Ignore: diffutils:info
+Ignore: findutils:info
+Ignore: gawk:info
+Ignore: grep:info
+Ignore: groff:info
+Ignore: m4:info
+Ignore: sed:info
+Ignore: tar:info
+Ignore: util-linux:info
+Ignore: util-linux-mini:info
+Ignore: gettext-tools:info
+Ignore: gettext-runtime:info
+Ignore: libgcrypt-devel:info
+Ignore: binutils:info
+Ignore: gzip:info
+Ignore: make:info
+Ignore: bison:info
+Ignore: flex:info
+Ignore: help2man:info
+Ignore: man:groff-full
+Ignore: git-core:rsync
+Ignore: apache2:systemd
+Ignore: icewm-lite:icewm
+Ignore: cluster-glue:sudo
+
+Ignore: libgcc:glibc-32bit
+Ignore: libgcc41:glibc-32bit
+Ignore: libgcc42:glibc-32bit
+Ignore: libgcc43:glibc-32bit
+Ignore: libgcc44:glibc-32bit
+Ignore: libgcc45:glibc-32bit
+Ignore: libgcc46:glibc-32bit
+Ignore: libgcc47:glibc-32bit
+Ignore: libstdc++:glibc-32bit
+Ignore: libstdc41++:glibc-32bit
+Ignore: libstdc42++:glibc-32bit
+Ignore: libstdc43++:glibc-32bit
+Ignore: libstdc44++:glibc-32bit
+Ignore: libstdc45++:glibc-32bit
+Ignore: libstdc46++:glibc-32bit
+Ignore: libstdc47++:glibc-32bit
+Ignore: ncurses-32bit
+
+Ignore: susehelp:susehelp_lang,suse_help_viewer
+Ignore: mailx:smtp_daemon
+Ignore: cron:smtp_daemon
+Ignore: hotplug:syslog
+Ignore: pcmcia:syslog
+Ignore: openct:syslog
+Ignore: postfix:sysvinit(syslog)
+Ignore: cups:sysvinit(syslog)
+Ignore: avalon-logkit:servlet
+Ignore: jython:servlet
+Ignore: ispell:ispell_dictionary,ispell_english_dictionary
+Ignore: aspell:aspel_dictionary,aspell_dictionary
+Ignore: smartlink-softmodem:kernel,kernel-nongpl
+Ignore: libreoffice-de:myspell-german-dictionary
+Ignore: libreoffice:libreoffice-i18n
+Ignore: libreoffice:libreoffice-icon-themes
+Ignore: mediawiki:php-session,php-gettext,php-zlib,php-mysql,mod_php_any
+Ignore: squirrelmail:mod_php_any,php-session,php-gettext,php-iconv,php-mbstring,php-openssl
+Ignore: perl-Log-Log4perl:rrdtool
+
+Ignore: simias:mono(log4net)
+Ignore: zmd:mono(log4net)
+Ignore: horde:mod_php_any,php-gettext,php-mcrypt,php-imap,php-pear-log,php-pear,php-session,php
+
+Ignore: xerces-j2:xml-commons-apis,xml-commons-resolver
+Ignore: xdg-menu:desktop-data
+Ignore: nessus-libraries:nessus-core
+Ignore: evolution:yelp
+Ignore: e17:e17-branding e17:e17-theme
+
+Ignore: mono-tools:mono(gconf-sharp),mono(glade-sharp),mono(gnome-sharp),mono(gtkhtml-sharp),mono(atk-sharp),mono(gdk-sharp),mono(glib-sharp),mono(gtk-sharp),mono(pango-sharp)
+Ignore: gecko-sharp2:mono(glib-sharp),mono(gtk-sharp)
+
+Ignore: vcdimager:libcdio.so.6,libcdio.so.6(CDIO_6),libiso9660.so.4,libiso9660.so.4(ISO9660_4)
+Ignore: libcdio:libcddb.so.2
+
+Ignore: gnome-libs:libgnomeui
+Ignore: nautilus:gnome-themes
+Ignore: gnome-panel:gnome-themes
+Ignore: gnome-panel:tomboy
+Ignore: NetworkManager:NetworkManager-client
+Ignore: libbeagle:beagle
+Ignore: coreutils:coreutils-lang
+Ignore: cpio:cpio-lang
+Ignore: glib2:glib2-lang
+Ignore: gtk2:gtk2-lang
+Ignore: gtk:gtk-lang
+Ignore: atk:atk-lang
+Ignore: hal:pm-utils
+Ignore: MozillaThunderbird:pinentry-dialog
+Ignore: seamonkey:pinentry-dialog
+Ignore: pinentry:pinentry-dialog
+Ignore: gpg2:gpg2-lang
+Ignore: util-linux:util-linux-lang
+Ignore: util-linux-mini:util-linux-mini-lang
+Ignore: suseRegister:distribution-release
+Ignore: compiz:compiz-decorator
+Ignore: icecream:gcc-c++
+Ignore: no
+Ignore: package
+Ignore: provides
+Ignore: j9vm/libjvm.so()(64bit)
+Ignore: kdepim3:suse_help_viewer
+Ignore: kdebase3-SuSE:kdebase3-SuSE-branding
+Ignore: kio_sysinfo:kdebase3-SuSE-branding
+Ignore: gnome-menus:gnome-menus-branding
+Ignore: epiphany:epiphany-branding
+Ignore: gnome-control-center:gnome-control-center-branding
+Ignore: phonon:phonon-backend
+Ignore: openwbem-devel
+Ignore: MozillaFirefox:MozillaFirefox-branding
+Ignore: yast2:yast2-branding
+Ignore: plymouth:plymouth-branding 
+Ignore: plymouth:suspend
+Ignore: yast2-qt:yast2-branding
+Ignore: yast2-theme-SLE:yast2-branding
+Ignore: yast2-registration:yast2-registration-branding
+Ignore: compiz:compiz-branding
+Ignore: texlive:perl-Tk texlive-bin:perl-Tk
+Ignore: xfce4-desktop:xfce4-desktop-branding
+Ignore: xfce4-panel:xfce4-panel-branding
+Ignore: xfce4-session:xfce4-session-branding
+Ignore: kdebase4-runtime:kdebase4-runtime-branding
+Ignore: kwin:kdebase4-workspace-branding
+Ignore: pulseaudio:kernel
+Ignore: transmission-common:transmission-ui
+Ignore: mutter-moblin:moblin-branding
+Ignore: sysvinit-tools:mkinitrd cifs-utils:mkinitrd
+Ignore: mkinitrd:sbin_init
+Ignore: opensc:pinentry
+Ignore: gpg2:pinentry
+Ignore: NetworkManager:dhcp
+Ignore: NetworkManager:iproute2
+Ignore: sysconfig:dbus-1
+Ignore: sysconfig:procps
+Ignore: sysconfig:iproute2
+Ignore: sysconfig-network:iproute2
+Ignore: sysconfig:tunctl
+# no build dependencies
+Ignore: libksuseinstall1:yast2-packager
+Ignore: libksuseinstall1:zypper
+Ignore: syslog-service:logrotate
+Ignore: libglue-devel:cluster-glue
+Ignore: libqca2:gpg2
+Ignore: NetworkManager:wpa_supplicant
+Ignore: NetworkManager:dhcp-client
+Ignore: openSUSE-release:product_flavor(openSUSE)
+Ignore: sles-release:product_flavor(SLES)
+Ignore: autoyast2:yast2-schema
+Ignore: libgio-2_0-0:dbus-1-x11
+Ignore: weather-wallpaper:inkscape
+Ignore: libgamin-1-0:gamin-server
+Ignore: libfam0-gamin:gamin-server
+Ignore: avahi:sysvinit(network)
+Ignore: sysconfig:sysvinit(network)
+
+Prefer: java-1_7_0-openjdk java-1_7_0-openjdk-devel
+
+Prefer: -java-1_5_0-gcj-compat-devel
+Prefer: -java-1_6_0-ibm-devel
+%ifarch %ix86 x86_64
+Prefer: -java-1_5_0-ibm-devel
+%endif
+
+Substitute: java2-devel-packages java-1_7_0-openjdk-devel
+
+%ifarch x86_64 ppc64 s390x sparc64
+Substitute: glibc-devel-32bit glibc-devel-32bit glibc-32bit
+%else
+ %ifarch ppc sparc sparcv9
+Substitute: glibc-devel-32bit glibc-devel-64bit
+ %else
+Substitute: glibc-devel-32bit
+ %endif
+%endif
+
+%ifarch %ix86
+Substitute: kernel-binary-packages kernel-default kernel-smp kernel-bigsmp kernel-debug kernel-xen
+%endif
+%ifarch ia64
+Substitute: kernel-binary-packages kernel-default kernel-debug
+%endif
+%ifarch x86_64
+Substitute: kernel-binary-packages kernel-default kernel-smp kernel-xen
+%endif
+%ifarch ppc
+Substitute: kernel-binary-packages kernel-default kernel-ppc64 kernel-ps3
+%endif
+%ifarch ppc64
+Substitute: kernel-binary-packages kernel-default kernel-ppc64
+%endif
+%ifarch s390
+Substitute: kernel-binary-packages kernel-s390
+%endif
+%ifarch s390x
+Substitute: kernel-binary-packages kernel-default
+%endif
+
+Optflags: i586 -fomit-frame-pointer -fmessage-length=0 -grecord-gcc-switches -fstack-protector
+Optflags: i686 -march=i686 -mtune=generic -fomit-frame-pointer -fmessage-length=0 -grecord-gcc-switches -fstack-protector
+Optflags: x86_64 -fmessage-length=0 -grecord-gcc-switches -fstack-protector
+Optflags: ppc64le -fmessage-length=0 -grecord-gcc-switches -fstack-protector
+Optflags: s390 -fmessage-length=0 -grecord-gcc-switches -fstack-protector
+Optflags: s390x -fmessage-length=0 -grecord-gcc-switches -fstack-protector
+Optflags: aarch64 -fmessage-length=0 -grecord-gcc-switches -fstack-protector
+
+Optflags: * -O2 -Wall -D_FORTIFY_SOURCE=2 -funwind-tables -fasynchronous-unwind-tables
+
+%define suse_version 1315
+%define _without_mono 1
+%define _without_vlc 1
+%define _without_compat_libs 1
+
+%define rb_default_ruby        ruby21
+%define rb_default_ruby_suffix ruby2.1
+%define rb_default_ruby_abi    ruby:2.1.0
+
+%define rb_build_ruby_abis     ruby:2.1.0
+%define rb_build_versions      ruby21
+
+#Prefer: rubygem(%{rb_default_ruby_abi}:gem2rpm)
+Prefer: %{rb_default_ruby_suffix}-rubygem-gem2rpm
+
+Macros:
+%insserv_prereq insserv sed
+%fillup_prereq fillup coreutils grep diffutils
+%suseconfig_fonts_prereq perl aaa_base
+%install_info_prereq info
+%kernel_module_package_buildreq kmod-compat kernel-syms
+%kernel_module_package_buildreqs kmod-compat kernel-syms
+%maintenance_vendor SUSE LLC <https://www.suse.com/>
+%maintenance_distribution SUSE Linux Enterprise 12
+
+%suse_version 1315
+%sles_version 0
+%ul_version 0
+%do_profiling 1
+%opensuse_bs 1
+%_without_mono 1
+%_without_vlc 1
+%_without_compat_libs 1
+%rb_default_ruby        ruby21
+%rb_default_ruby_suffix ruby2.1
+%rb_default_ruby_abi    ruby:2.1.0
+
+%rb_build_ruby_abis     ruby:2.1.0
+%rb_build_versions      ruby21
+
+%rubygemsruby21() rubygem(ruby:2.1.0:%{expand:%%rubygemsx%*} %{expand:%%{rubygems%*}}
+%rubygemsxruby21() %{expand:%%{rubygemsx%*}}
+#
+%rubygemsruby22() rubygem(ruby:2.2.0:%{expand:%%rubygemsx%*} %{expand:%%{rubygems%*}}
+%rubygemsxruby22() %{expand:%%{rubygemsx%*}}
+#
+%rubygem() %{expand:%%{rubygems%rb_build_versions STOP %*}}
+%rubygemsSTOP() %nil
+%rubygemsxSTOP() %{expand:%%rubygemsxxSTOP -a %*}
+%rubygemsxxSTOP(a:) %{-a*}) %*
+#
+%rubyruby21() ruby2.1 %{expand:%%rubyx%*} %{expand:%%{ruby%*}}
+%rubyxruby21() %{expand:%%{rubyx%*}}
+#
+%rubyruby22() ruby2.2 %{expand:%%rubyx%*} %{expand:%%{ruby%*}}
+%rubyxruby22() %{expand:%%{rubyx%*}}
+#
+%rubySTOP() %nil
+%rubyxSTOP() %*
+#
+%ruby() %{expand:%%{ruby%rb_build_versions STOP %*}}
+#
+%rubydevelruby21() ruby2.1-devel %{expand:%%rubydevelx%*} %{expand:%%{rubydevel%*}}
+%rubydevelxruby21() %{expand:%%{rubydevelx%*}}
+#
+%rubydevelruby22() ruby2.2-devel %{expand:%%rubydevelx%*} %{expand:%%{rubydevel%*}}
+%rubydevelxruby22() %{expand:%%{rubydevelx%*}}
+#
+%rubydevel() %{expand:%%{rubydevel%rb_build_versions STOP %*}}
+#
+%rubydevelSTOP() %nil
+%rubydevelxSTOP() %*
+
+%_vendor suse
+
+# define which gcc package builds the system libraries
+%product_libs_gcc_ver 48
+
+%ext_info .gz
+%ext_man .gz
+
+%info_add(:-:) test -x /sbin/install-info -a -f %{?2}%{?!2:%{_infodir}}/%{1}%ext_info && /sbin/install-info --info-dir=%{?2}%{?!2:%{_infodir}} %{?2}%{?!2:%{_infodir}}/%{1}%ext_info \
+%{nil}
+
+%info_del(:-:) test -x /sbin/install-info -a ! -f %{?2}%{?!2:%{_infodir}}/%{1}%ext_info && /sbin/install-info --quiet --delete --info-dir=%{?2}%{?!2:%{_infodir}} %{?2}%{?!2:%{_infodir}}/%{1}%ext_info \
+%{nil}
+
index a97f762997fbc5a064757f5c244d0e3e9370a111..aab83465604271b664ddd6352603220dad68cd4c 100755 (executable)
@@ -2,14 +2,34 @@
 
 # Archlinux support, based on the GSoC work of Nikolay Rysev <mad.f3ka@gmail.com>
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 BEGIN {
   unshift @INC, ($::ENV{"BUILD_DIR"} || "/usr/lib/build");
 }
 
 use strict;
-use Archive::Tar;
-use Build::Arch;
-use Digest::MD5;
+use Build ':arch';
+use Build::Archrepo;
+use Digest::MD5 ();
 use File::Path;
 use Getopt::Long;
 
@@ -17,56 +37,22 @@ Getopt::Long::Configure("no_ignore_case");
 
 my $cachedir = "/var/cache/build";
 
-sub getrepodb {
-  my ($url, $reponame, $dir) = @_;
-  File::Path::mkpath($dir);
-  system($INC[0]."/download", $dir, "$url$reponame.db");
-}
-
 sub getreponame {
   my ($url) = @_;
   return $1 if "/$url/" =~ /.*\/([^\/]+)\/os\//;
   return undef;
 }
 
-sub printpkginfo {
-  my ($d, $repourl)  = @_;
-  my $id = $d->{'name'} . "." . $d->{'arch'} . "-" . $d->{'buildtime'} . "/0/0";
-  my $pkgurl = $repourl . $d->{'filename'};
-  my $selfprovides = $d->{'name'};
-  $selfprovides .= "=$d->{'version'}" if defined $d->{'version'};
-  push @{$d->{'provides'}}, $selfprovides unless @{$d->{'provides'} || []} && $d->{'provides'}->[-1] eq $selfprovides;
-  print "F:$id: $pkgurl\n";
-  print "P:$id: " . join(' ', @{$d->{'provides'}}) . "\n" if $d->{'provides'};
-  print "R:$id: " . join(' ', @{$d->{'requires'}}) . "\n" if $d->{'requires'};
-  print "I:$id: $d->{name}-$d->{'version'} $d->{'buildtime'}\n";
-}
-
 GetOptions("cachedir=s"  => \$cachedir) or exit(1);
 
-
 for my $url (@ARGV) {
-  die("Not an Archlinux repo") unless $url =~ /^(ht|f)tp:\/\/([^\/]*)\/?/;
+  die("$url: not an remote Archlinux repo") unless $url =~ /^(:?ftps?|https?):\/\/([^\/]*)\/?/;
   my $reponame = getreponame($url);
-  my $repoid = Digest::MD5::md5_hex("arch\@$url");
+  die("could not determine reponame from url $url\n") unless defined $reponame;
+  my $repoid = Digest::MD5::md5_hex($url);
   my $dir = "$cachedir/$repoid";
   $url .= '/' unless $url =~ /\/$/;
-  getrepodb($url, $reponame, $dir);
-
-  my $repodb = Archive::Tar->iter("$dir/$reponame.db", 1);
-  my $e;
-  my $lastfn = '';
-  my $d;
-  while ($e = $repodb->()) {
-    next unless $e->type() == Archive::Tar::Constant::FILE;
-    my $fn = $e->name();
-    next unless $fn =~ s/\/(?:depends|desc|files)$//s;
-    if ($lastfn ne $fn) {
-      printpkginfo($d, $url) if $d->{'name'};
-      $d = {};
-      $lastfn = $fn;
-    }
-    Build::Arch::parserepodata($d, $e->get_content());
-  }
-  printpkginfo($d, $url) if $d->{'name'};
+  File::Path::mkpath($dir);
+  system("$INC[0]/download", $dir, "$url$reponame.db");
+  Build::Archrepo::parse("$dir/$reponame.db", sub { Build::writedeps(\*STDOUT, $_[0], $url) }, 'addselfprovides' => 1);
 }
diff --git a/createdebdeps b/createdebdeps
new file mode 100755 (executable)
index 0000000..90207d8
--- /dev/null
@@ -0,0 +1,79 @@
+#!/usr/bin/perl -w
+
+BEGIN {
+  unshift @INC, ($::ENV{"BUILD_DIR"} || "/usr/lib/build");
+}
+
+use strict;
+use Digest::MD5;
+use File::Path;
+use Getopt::Long;
+use Build ':deb';
+use Build::Deb;
+use Build::Debrepo;
+
+Getopt::Long::Configure("no_ignore_case");
+
+#
+# supported urls
+#
+# distribution:   <baseurl>/<dist>/[components]
+# flat repo:      <baseurl>/.
+
+my $cachedir = "/var/cache/build";
+my $archpath;
+
+GetOptions('cachedir=s'  => \$cachedir, 'archpath=s' => \$archpath) or exit(1);
+
+if (!$archpath) {
+  $archpath = `uname -p` || 'unknown';
+  chomp $archpath;
+}
+my $basearch = $archpath;
+$basearch =~ s/:.*//;
+$basearch = Build::Deb::basearch($basearch);
+my $pkgnum = 0;
+
+for my $url (@ARGV) {
+  die("$url: not an remote debian repo\n") unless $url =~ /^(:?ftps?|https?):\/\/([^\/]*)\/?/;
+  my $repoid = Digest::MD5::md5_hex($url);
+  my $dir = "$cachedir/$repoid";
+
+  my @components;
+  my $baseurl = $url;
+
+  if ($url =~ /^(.*\/)\.(\/.*)?$/) {
+    # flat repo
+    $baseurl = $1;
+    @components = ('.');
+    $url = defined($2) ? "$1$2" : $1;
+    $url .= '/' unless $url =~ /\/$/;
+  } else {
+    if ($url =~ /([^\/]+)$/) {
+      @components = split(/[,+]/, $1);
+      $url =~ s/([^\/]+)$//;
+    }
+    push @components, 'main' unless @components;
+    $url .= '/' unless $url =~ /\/$/;
+    $baseurl = $url;
+    $url =~ s/([^\/]+\/)$/dists\/$1/;
+    $baseurl =~ s/([^\/]+\/)$//;
+  }
+
+  File::Path::mkpath($dir);
+  for my $component (@components) {
+    unlink("$dir/Packages.gz");
+    if ($component eq '.') {
+      system($INC[0]."/download", $dir, "${url}Packages.gz");
+      die("Packages.gz missing\n") unless -s "$dir/Packages.gz";
+    } else {
+      system($INC[0]."/download", $dir, "$url$component/binary-$basearch/Packages.gz");
+      die("Packages.gz missing for basearch $basearch, component $component\n") unless -s "$dir/Packages.gz";
+    }
+    Build::Debrepo::parse("$dir/Packages.gz", sub {
+      $pkgnum++;
+      $_[0]->{'id'} = "$pkgnum/0/0";
+      Build::writedeps(\*STDOUT, $_[0], $baseurl);
+    }, 'addselfprovides' => 1);
+  }
+}
diff --git a/createdirdeps b/createdirdeps
new file mode 100755 (executable)
index 0000000..e507004
--- /dev/null
@@ -0,0 +1,99 @@
+#!/usr/bin/perl -w
+
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+BEGIN {
+  unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
+}
+
+use Build;
+use Getopt::Long;
+
+use strict;
+
+Getopt::Long::Configure("no_ignore_case");
+
+my $oldfile;
+
+GetOptions ("oldfile=s" => \$oldfile) or exit(1);
+
+sub queryfromfilename {
+  my ($fn) = @_;
+  $fn =~ s/.*\///;
+  return {'name' => $1, 'arch' => $2} if $fn =~ /^(.*)-[^-]+-[^-]+\.([^\. ]+)\.rpm$/;
+  return {'name' => $1, 'arch' => $2} if $fn =~ /^([^_]*)_(?:[^_]*)_([^_]*)\.deb$/;
+  return {'name' => $1, 'arch' => $2} if $fn =~ /^(.*)-[^-]+-[^-]+-([^-]+)\.pkg\.tar\.[gx]z$/;
+  return undef;
+}
+
+
+######################################################################
+
+my %old;
+if (defined($oldfile) && open(F, '<', $oldfile)) {
+  while (<F>) {
+    chomp;
+    $old{$1} = $_ if /^([PRCOI]:[^ ]+): /;
+  }
+  close F;
+}
+
+my %seen;
+
+for my $dir (@ARGV) {
+  my $cmd = "find $dir -follow -type f \\( -name \"*.rpm\" -o -name \"*.deb\" -o -name \"*.pkg.tar.gz\" -o -name \"*.pkg.tar.xz\" \\) -a ! -name \"*src.rpm\" -printf '\%T@/\%s/\%i \%p\\n'";
+  open(F, '-|', $cmd) or next;
+  while (<F>) {
+    chomp;
+    next unless /^([\d\.]+\/\d+\/\d+) (.*)$/;
+    my $id = $1;
+    my $path = $2;
+    # newer find version add a fraction part to %T@, strip it
+    $id =~ s/^(\d+)\.\d+/$1/;
+    next if $path =~ /\.(?:patch|delta)\.rpm$/;        # not good for building...
+    if (%old) {
+      my $q = queryfromfilename($path);
+      if ($q && defined($q->{'name'}) && defined($q->{'arch'})) {
+        my $idx = "$q->{'name'}.$q->{'arch'}-$id";
+       if ($old{"I:$idx"} && $old{"P:$idx"}) {
+         # reuse old data
+         next if $seen{$idx};
+         $seen{$idx} = 1;
+         print "F:$idx: $path\n";
+         for (qw{P R C O I}) {
+           print $old{"$_:$idx"}."\n" if $old{"$_:$idx"};
+         }
+         next;
+       }
+      }
+    }
+    my $q = Build::query($path, 'addselfprovides' => 1, 'conflicts' => 1, 'evra' => 1, 'buildtime' => 1);
+    next unless $q && defined($q->{'name'}) && defined($q->{'arch'}) && defined($q->{'version'});
+    my $idx = "$q->{'name'}.$q->{'arch'}-$id";
+    next if $seen{$idx};
+    $seen{$idx} = 1;
+    $q->{'id'} = $id;
+    $q->{'location'} = $path;
+    Build::writedeps(\*STDOUT, $q);
+  }
+  close F;
+}
+
index 48a6b465b87146e01977581746894fe170fc1087..6f96434d3c53c1583dd518361e6502ea8fda3470 100755 (executable)
 #!/usr/bin/perl -w
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 BEGIN {
   unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
 }
 
 use strict;
-use XML::Parser;
 use Data::Dumper;
 use Getopt::Long;
+use Build ':rpm';
 use Build::Rpm;
-use Digest::MD5 qw(md5 md5_hex md5_base64);
+use Build::Rpmmd;
+use Digest::MD5 ();
 use File::Path qw(mkpath rmtree);
 use File::Basename;
-use LWP::UserAgent;
-use URI;
-Getopt::Long::Configure("no_ignore_case");
 
-my @parent = [];
-my @primaryfiles = ();
-my @packages = ();
-
-my $baseurl; # current url
+Getopt::Long::Configure("no_ignore_case");
 
 my $opt_dump;
 my $opt_old;
 my $opt_nosrc;
 my $opt_bc;
+my $opt_zypp;
 my $cachedir = "/var/cache/build";
 
-my $old_seen = ();
-
-my $repomdparser = {
-  repomd => {
-    data => {
-      _start => \&repomd_handle_data_start,
-      _end => \&repomd_handle_data_end,
-      location => {
-       _start => \&repomd_handle_location,
-      },
-      size => {
-       _text => \&repomd_handle_size,
-      },
-    },
-  },
-};
-
-my $primaryparser = {
-  metadata => {
-    'package' => {
-      _start => \&primary_handle_package_start,
-      _end => \&primary_handle_package_end,
-      name => { _text => \&primary_collect_text, _end => \&primary_store_text },
-      arch => { _text => \&primary_collect_text, _end => \&primary_store_text },
-      version => { _start => \&primary_handle_version },
-      'time' => { _start => \&primary_handle_time },
-      format => {
-       'rpm:provides' => { 'rpm:entry' => { _start => \&primary_handle_package_provides }, },
-       'rpm:requires' => { 'rpm:entry' => { _start => \&primary_handle_package_requires }, },
-       'rpm:conflicts' => { 'rpm:entry' => { _start => \&primary_handle_package_conflicts }, },
-       'rpm:obsoletes' => { 'rpm:entry' => { _start => \&primary_handle_package_obsoletes }, },
-       'rpm:buildhost' => { _text => \&primary_collect_text, _end => \&primary_store_text },
-       'rpm:sourcerpm' => { _text => \&primary_collect_text, _end => \&primary_store_text },
-### currently commented out, as we ignore file provides in createrpmdeps
-#      file => {
-#        _start => \&primary_handle_file_start,
-#        _text => \&primary_collect_text,
-#        _end => \&primary_handle_file_end
-#      },
-      },
-      location => { _start => \&primary_handle_package_location },
-    },
-  },
-};
-
-# [ [tag, \%], ... ]
-my @cursor = ();
-
-my %datafile;
-sub repomd_handle_data_start
-{
-  my $p = shift;
-  my $el = shift;
-
-  my $attr = map_attrs(@_);
-  %datafile = ();
-  if($attr->{'type'} ne 'primary') {
-    pop @cursor;
-  }
-}
-
-sub repomd_handle_data_end
-{
-  my $p = shift;
-  my $el = shift;
-  push @primaryfiles, { %datafile } if exists $datafile{'location'};
-}
-
-
-sub repomd_handle_location
-{
-  my $p = shift;
-  my $el = shift;
-
-  my $attr = map_attrs(@_);
-  $datafile{'location'} = $attr->{'href'} if defined $attr->{'href'};
-}
-
-sub repomd_handle_size
-{
-  my $p = shift;
-  my $el = shift;
-  $datafile{'size'} = $el;
-}
-
-
-sub generic_handle_start
-{
-  my $p = shift;
-  my $el = shift;
-
-  if(exists $cursor[-1]->[1]->{$el})
-  {
-    my $h = $cursor[-1]->[1]->{$el};
-    push @cursor, [$el, $h];
-    if(exists $h->{'_start'}) {
-      &{$h->{'_start'}}($p, $el, @_);
-    }
-  }
-}
-
-sub generic_handle_char
-{
-  my $p = shift;
-  my $text = shift;
-
-  my $h = $cursor[-1]->[1];
-
-  if(exists $h->{'_text'}) {
-    &{$h->{'_text'}}($p, $text);
-  }
-}
-
-sub generic_handle_end
-{
-  my $p = shift;
-  my $el = shift;
-
-  if(!defined $cursor[-1]->[0] || $cursor[-1]->[0] eq $el)
-  {
-    my $h = $cursor[-1]->[1];
-
-    if(exists $h->{'_end'}) {
-      &{$h->{'_end'}}($p, $el);
-    }
-
-    pop @cursor;
-  }
-}
-
-sub map_attrs
-{
-  my %h;
-  while(@_) {
-    my $k = shift;
-    $h{$k} = shift;
-  }
-
-  return \%h;
-}
-
-# expat does not guarantee that character data doesn't get split up
-# between multiple calls
-my $textbuf = '';
-sub primary_collect_text
-{
-  my $p = shift;
-  my $text = shift;
-
-  $textbuf .= $text;
-}
-
-sub primary_store_text
-{
-    my $p = shift;
-    my $el = shift;
-
-    $packages[-1]->{$cursor[-1]->[0]} = $textbuf;
-    $textbuf = '';
-}
-
-sub primary_handle_package_start
-{
-  my $p = shift;
-  my $el = shift;
-
-  my $attr = map_attrs(@_);
-
-  push @packages, { type => $attr->{'type'}, baseurl => $baseurl };
-}
-
-sub primary_handle_package_end
-{
-  my $p = shift;
-  my $el = shift;
-
-  if($opt_bc) {
-      printasbuildcachefile(@packages);
-      shift @packages;
-  } elsif ($opt_old) {
-      foreach my $pkg (@packages) {
-    my $arch = $pkg->{'arch'};
-    $arch = 'src' if $pkg->{'arch'} eq 'nosrc';
-    next if ($arch eq 'src' && $opt_nosrc);
-    if(exists($old_seen->{$pkg->{'name'}}->{$arch})) {
-       my $pv = $old_seen->{$pkg->{'name'}}->{$arch}->{'ver'};
-       my $rv = $pkg->{'ver'}.'-'.$pkg->{'rel'};
-       my $vv = Build::Rpm::verscmp($pv, $rv, 0);
-       if($vv < 0)
-       {
-      print $old_seen->{$pkg->{'name'}}->{$arch}->{'loc'}."\n";
-      $old_seen->{$pkg->{'name'}}->{$arch}->{'ver'} = $pkg->{'ver'}.'-'.$pkg->{'rel'};
-      $old_seen->{$pkg->{'name'}}->{$arch}->{'loc'} = $pkg->{'baseurl'} . $pkg->{'location'};
-       } else {
-      print $pkg->{'baseurl'} . $pkg->{'location'}."\n";
-       }
-    } else {
-       $old_seen->{$pkg->{'name'}}->{$arch}->{'ver'} = $pkg->{'ver'}.'-'.$pkg->{'rel'};
-       $old_seen->{$pkg->{'name'}}->{$arch}->{'loc'} = $pkg->{'baseurl'} . $pkg->{'location'};
-    }
-      }
-      shift @packages;
-  }
-}
-
-sub primary_handle_version
-{
-  my $p = shift;
-  my $el = shift;
-
-  my $attr = map_attrs(@_);
-  $packages[-1]->{'ver'} = $attr->{'ver'};
-  $packages[-1]->{'rel'} = $attr->{'rel'};
-}
-
-sub primary_handle_time
-{
-  my $p = shift;
-  my $el = shift;
-
-  my $attr = map_attrs(@_);
-  $packages[-1]->{'filetime'} = $attr->{'file'};
-  $packages[-1]->{'buildtime'} = $attr->{'build'};
-}
-
-sub primary_handle_package_location
-{
-  my $p = shift;
-  my $el = shift;
-
-  my $attr = map_attrs(@_);
-  $packages[-1]->{'location'} = $attr->{'href'};
-}
-
-sub primary_handle_file_start
-{
-  my $p = shift;
-  my $el = shift;
-
-  my $attr = map_attrs(@_);
-  if(exists $attr->{'type'}) {
-    pop @cursor;
-  }
-}
-
-sub primary_handle_file_end
-{
-  my $p = shift;
-  my $text = shift;
-
-  primary_handle_package_deps('provides', 'name', $textbuf);
-  $textbuf = '';
-}
-
-my %flagmap = (
-  EQ => '=',
-  LE => '<=',
-  GE => '>=',
-  GT => '>',
-  LT => '<',
-  NE => '!=',
-);
-
-sub primary_handle_package_deps
-{
-  my $dep = shift;
-  my $attr = map_attrs(@_);
-
-  if(exists $attr->{'flags'}) {
-    if(!exists($flagmap{$attr->{'flags'}})) {
-      print STDERR "bogus relation: ", $attr->{'flags'}, "\n";
+sub printold {
+  my ($pkg, $baseurl, $old_seen) = @_;
+
+  my $arch = $pkg->{'arch'};
+  $arch = 'src' if $pkg->{'arch'} eq 'nosrc';
+  return if $arch eq 'src' && $opt_nosrc;
+  my $evr = $pkg->{'version'}.'-'.$pkg->{'release'};
+  $evr = "$pkg->{'epoch'}:$evr" if $pkg->{'epoch'};
+  my $loc = $baseurl . $pkg->{'location'};
+  if ($old_seen->{$pkg->{'name'}}->{$arch}) {
+    my $vv = Build::Rpm::verscmp($old_seen->{$pkg->{'name'}}->{$arch}->{'evr'}, $evr, 0);
+    if ($vv >= 0) {
+      print "$loc\n";
       return;
     }
-    $attr->{'flags'} = $flagmap{$attr->{'flags'}};
-  }
-  return if($attr->{'name'} =~ /^rpmlib\(/);
-  push @{$packages[-1]->{$dep}}, $attr;
-
-}
-
-sub primary_handle_package_conflicts
-{
-  shift;shift; primary_handle_package_deps('conflicts', @_);
-}
-
-sub primary_handle_package_obsoletes
-{
-  shift;shift; primary_handle_package_deps('obsoletes', @_);
-}
-
-sub primary_handle_package_requires
-{
-  shift;shift; primary_handle_package_deps('requires', @_);
-}
-sub primary_handle_package_provides
-{
-  shift;shift; primary_handle_package_deps('provides', @_);
-}
-
-sub deps2string
-{
-  return join(' ', map {
-       my $s = $_->{'name'};
-       if(exists $_->{'flags'}) {
-         $s .= ' '.$_->{'flags'}.' ';
-         $s .= $_->{'epoch'}.':' if(exists $_->{'epoch'} && $_->{'epoch'} != 0);
-         $s .= $_->{'ver'};
-         $s .= '-'.$_->{'rel'} if exists $_->{'rel'};
-       }
-       $s
-      } @_);
-}
-
-sub printasbuildcachefile(@)
-{
-  foreach my $pkg (@_) {
-    next if $pkg->{'arch'} eq 'src' || $pkg->{'arch'} eq 'nosrc';
-    my $id = sprintf("%s.%s-%d/%d/%d: ",
-      $pkg->{'name'},
-      $pkg->{'arch'},
-      $pkg->{'buildtime'},
-      $pkg->{'filetime'},
-      0);
-    print "F:".$id. $pkg->{'baseurl'} . $pkg->{'location'} . "\n";
-
-    my $deps = deps2string(@{$pkg->{'provides'}});
-    print "P:$id$deps\n";
-
-    $deps = deps2string(@{$pkg->{'requires'}});
-    print "R:$id$deps\n";
-
-    my $tag = sprintf("%s-%s-%s %s",
-      $pkg->{'name'},
-      $pkg->{'ver'},
-      $pkg->{'rel'},
-#      $pkg->{'rpm:buildhost'},
-      $pkg->{'buildtime'});
-    print "I:$id$tag\n";
+    print $old_seen->{$pkg->{'name'}}->{$arch}->{'loc'}."\n";
   }
+  $old_seen->{$pkg->{'name'}}->{$arch}->{'evr'} = $evr;
+  $old_seen->{$pkg->{'name'}}->{$arch}->{'loc'} = $loc;
 }
 
-sub getmetadata
-{
-  my $url = $_[0];
-  my $dir = $_[1];
-
-  my $dest = $dir . "repodata";
-  mkpath($dest);
-  system($INC[0].'/download', $dest, $url . "repodata/repomd.xml");
-}
-
-### main
-
 GetOptions (
-    "nosrc"   => \$opt_nosrc,
-    "dump"   => \$opt_dump,
-    "old"   => \$opt_old,
-    "cachedir=s"  => \$cachedir,
-    ) or exit(1);
+  "nosrc"   => \$opt_nosrc,
+  "dump"   => \$opt_dump,
+  "old"   => \$opt_old,
+  "zypp=s"   => \$opt_zypp,
+  "cachedir=s"  => \$cachedir,
+  ) or exit(1);
 
-$opt_bc = 1 unless ($opt_dump || $opt_old);
+$opt_bc = 1 unless $opt_dump || $opt_old;
 
-my $p = new XML::Parser(
-  Handlers => {
-    Start => \&generic_handle_start,
-    End => \&generic_handle_end,
-    Char => \&generic_handle_char
-  });
+my $old_seen = {};     # for opt_old
+my @packages;          # for opt_dump
 
-#my $url = '/mounts/mirror/SuSE/ftp.suse.com/pub/suse/update/10.1/';
 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";
-    }
-  } elsif ($url =~ /^http[s]?:\/\/([^\/]*)\/?/) {
-    my $repoid = md5_hex($url);
+  my $baseurl = $url;
+  if ($opt_zypp) {
+    $dir = $opt_zypp;
+  } elsif ($url =~ /^(?:ftps?|https?):\/\/([^\/]*)\/?/) {
+    my $repoid = Digest::MD5::md5_hex($url);
     $dir = "$cachedir/$repoid/";
-    $baseurl = $url;
     $baseurl .= '/' unless $baseurl =~ /\/$/;
-    getmetadata($baseurl, $dir);
-  } elsif ($url =~ /^arch\@/) {
-    exec ("$INC[0]/createarchdeps", "--cachedir=$cachedir", substr($url, 5));
+    mkpath("${dir}repodata");
+    system($INC[0].'/download', "${dir}repodata", "${baseurl}repodata/repomd.xml");
   } else {
     $dir = $url;
-    $dir .= '/' unless $dir =~ /\/$/;
-    $baseurl = $dir;
   }
+  $dir .= '/' unless $dir =~ /\/$/;
+  $baseurl .= '/' unless $baseurl =~ /\/$/;
 
-  @primaryfiles = ();
-  @cursor = ([undef, $repomdparser]);
-
-  $p->parsefile($dir . 'repodata/repomd.xml');
+  if (! -s "${dir}repodata/repomd.xml") {
+    die("zypp repo $url is not up to date, please refresh first\n") if $opt_zypp;
+    die("repo $url does not contain a repomd.xml file\n");
+  }
 
+  my @primaryfiles;
+  Build::Rpmmd::parse_repomd("${dir}repodata/repomd.xml", \@primaryfiles);
+  @primaryfiles = grep {$_->{'type'} eq 'primary' && defined($_->{'location'})} @primaryfiles;
 #  print Dumper(\@primaryfiles);
 
-  foreach my $f (@primaryfiles) {
-    @cursor = ([undef, $primaryparser]);
-
-    my $u = $dir . $f->{'location'};
+  for my $f (@primaryfiles) {
+    my $u = "$dir$f->{'location'}";
     if ($] > 5.007) {
-       require Encode;
-       utf8::downgrade($u);
+      require Encode;
+      utf8::downgrade($u);
     }
     my $cached;
     if (-e $u) {
@@ -451,45 +116,38 @@ for my $url (@ARGV) {
       $cached = 0 if exists($f->{'size'}) && $f->{'size'} != (-s _);
       $cached = 0 if !exists($f->{'size'}) && $u !~ /[0-9a-f]{32}-primary/;
     }
-    if ($url =~ /^http[s]?:\/\/([^\/]*)\/?/ and !$cached) {
-        if (system($INC[0].'/download', $dir . "repodata/", $baseurl . "repodata/" . basename($u))) {
+    if (!$cached) {
+      die("zypp repo $url is not up to date, please refresh first\n") if $opt_zypp;
+      if ($url =~ /^(?:ftps?|https?):\/\/([^\/]*)\/?/) {
+       if (system("$INC[0]/download", "${dir}repodata/", "${baseurl}repodata/" . basename($u))) {
          die("download failed\n");
        }
+      } else {
+       die("inconsistent repodata in $url\n");
+      }
     }
     my $fh;
     open($fh, '<', $u) or die "Error opening $u: $!\n";
     if ($u =~ /\.gz$/) {
-       use IO::Uncompress::Gunzip qw($GunzipError);
-       $fh = new IO::Uncompress::Gunzip $fh or die "Error opening $u: $GunzipError\n";
+      use IO::Uncompress::Gunzip qw($GunzipError);
+      $fh = new IO::Uncompress::Gunzip $fh or die "Error opening $u: $GunzipError\n";
     }
-    $p->parse($fh);
+    Build::Rpmmd::parse($fh, sub {
+      if ($opt_dump) {
+        $_[0]->{'baseurl'} = $baseurl;
+        push @packages, $_[0] if $opt_dump;
+      }
+      if ($opt_bc) {
+       Build::writedeps(\*STDOUT, $_[0], $baseurl);
+      } elsif ($opt_old) {
+       printold($_[0], $baseurl, $old_seen);
+      }
+    }, 'addselfprovides' => 1);
     close($fh);
   }
 }
 
 if ($opt_dump) {
-    print Data::Dumper->Dump([\@packages], ['packages']); # caution: excessive memory consumption!
+  print Data::Dumper->Dump([\@packages], ['packages']); # caution: excessive memory consumption!
 }
 
-#if($rpmdepdump) {
-#    my %amap = map { $_ => 1 } @archs;
-#    my $packages = do $rpmdepdump or die $!;
-#
-#    foreach my $pkg (@$packages) {
-#        next if exists $packs{$pkg->{'name'}};
-#        next unless exists $amap{$pkg->{'arch'}};
-#        next if $pkg->{'arch'} eq 'src' || $pkg->{'arch'} eq 'nosrc';
-#        next if $pkg->{'location'} =~ /\.(?:patch|delta)\.rpm$/;
-#
-#        my $pa = $pkg->{'name'}.'.'.$pkg->{'arch'};
-#        $packs{$pkg->{'name'}} = $pa;
-#        $fn{$pa} = $pkg->{'baseurl'}.$pkg->{'location'};
-#        my $r = {};
-#        # flags and version ignored
-#        my @pr = map { $_->{'name'} } @{$pkg->{'provides'}};
-#        my @re = map { $_->{'name'} } @{$pkg->{'requires'}};
-#        $r->{'provides'} = \@pr;
-#        $r->{'requires'} = \@re;
-#        $repo{$pkg->{'name'}} = $r;
-#    }
-#}
index a17bd747861a0ee3be180e661b0ae072ad34c67c..b5fb603ab14312acca58a461f022349919d3a9c3 100755 (executable)
 #!/usr/bin/perl -w
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 BEGIN {
   unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
 }
 
-use Build;
+use Build ':rpm';
 use Build::Susetags;
-use strict;
+use Getopt::Long;
+use File::Path qw(mkpath);
 
-sub print_pkg($)
-{
-  my $pkg = shift;
+use strict;
 
-  return if $pkg->{'arch'} eq 'src' || $pkg->{'arch'} eq 'nosrc';
-  my $id = sprintf("%s.%s-%d/%d/%d: ",
-    $pkg->{'name'},
-    $pkg->{'arch'},
-    $pkg->{'buildtime'},
-    0,
-    0);
-  print sprintf('F:%s%ssuse/%s/%s',$id,$pkg->{'baseurl'},
-    $pkg->{'arch'}, $pkg->{'location'}), "\n";
+Getopt::Long::Configure("no_ignore_case");
 
-  print "P:$id".$pkg->{'provides'}."\n";
-  print "R:$id".$pkg->{'requires'}."\n";
+my $opt_zypp;
+my $cachedir = "/var/cache/build";
 
-  my $tag = sprintf("%s-%s-%s %s",
-    $pkg->{'name'},
-    $pkg->{'version'},
-    $pkg->{'release'},
-#    $pkg->{'rpm:buildhost'},
-    $pkg->{'buildtime'});
-  print "I:$id$tag\n";
-}
-
-sub callback
-{
-  my ($pkg, $url) = @_;
-  $pkg->{'provides'} = [] unless exists $pkg->{'provides'};
-  # add self provides (rpm3 misses that)
-  my $n = $pkg->{'name'};
-  if(substr($pkg->{'arch'}, -3) ne 'src' && !scalar grep(/^\Q$n\E( =.*)?$/,@{$pkg->{'provides'}}))
-  {
-    push @{$pkg->{'provides'}}, sprintf("%s = %s-%s", $pkg->{'name'}, $pkg->{'version'}, $pkg->{'release'});
-  }
-  $pkg->{'provides'} = join(' ', @{$pkg->{'provides'}});
-  $pkg->{'requires'} = join(' ', @{$pkg->{'requires'}}) if $pkg->{'requires'};
-  $pkg->{'baseurl'} = $url;
-  my @data = split(' ', $pkg->{'location'});
-  # multi cd support hack
-  my $num = $data[0];
-  if($pkg->{'baseurl'} =~ /1\/$/ && $num ne 0) {
-    $pkg->{'baseurl'} =~ s/1\/$/$num\//;
-  }
-  $pkg->{'location'} = $data[1];
-
-  print_pkg($pkg);
-
-  return 0;
-}
+GetOptions ("zypp=s" => \$opt_zypp, "cachedir=s" => \$cachedir) or exit(1);
 
 for my $url (@ARGV) {
+  # XXX: use descrdir/datadir from content file
+  my $descrdir = 'suse/setup/descr';
+  my $datadir = 'suse';
+
   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/";
+  my $baseurl = $url;
+  if ($opt_zypp) {
+    $dir =  $opt_zypp;
+  } elsif ($url =~ /^(?:ftps?|https?):\/\/([^\/]*)\/?/) {
+    my $repoid = Digest::MD5::md5_hex($url);
+    $dir = "$cachedir/$repoid/";
+    $baseurl .= '/' unless $baseurl =~ /\/$/;
+    mkpath($dir);
+    system("$INC[0]/download", "$dir/", "${baseurl}$descrdir/packages.gz");
+    $descrdir = '.';
   } else {
     $dir = $url;
   }
+  $dir .= '/' unless $dir =~ /\/$/;
+  $baseurl .= '/' unless $baseurl =~ /\/$/;
 
-# a really fucked up system
-#  if (-e $url."/yast/order") {
-#    if(open(F, '<', $url."/yast/order")) {
-#      my $found_products;
-#      while(<F>) {
-#        chomp;
-#        my ($a, $b) = split(/ /);
-#        $a =~ s/^\///;
-#        if(-e $url.$a)
-#        {
-#          push @ARGV, $url.$a;
-#          $found_products = 1;
-#          print STDERR "$url -> $url$a\n";
-#        }
-#      }
-#      close(F);
-#      next if $found_products;
-#    }
-#  }
-  # XXX: location is actually defined in content file
-  my $packages = $dir.'/suse/setup/descr/packages';
-  
-  $url .= '/' unless $url =~ /\/$/;
-
-  my @order = ();
-  my $pkgs = Build::Susetags::parse($packages,
-    { 'Loc' => 'location', 'Prv' => 'provides', 'Req' => 'requires', 'Tim' => 'buildtime' },
-    { cb => \&callback, data => $url });
+  my $packages = "$dir$descrdir/packages";
+  $packages = "$packages.gz" if ! -e $packages && -e "$packages.gz";
+  Build::Susetags::parse($packages, sub {
+    my $xurl = $baseurl;
+    # multi cd support hack
+    $xurl =~ s/1\/$/$_[0]->{'medium'}/ if $_[0]->{'medium'};
+    $xurl .= "$datadir/" if $datadir;
+    Build::writedeps(\*STDOUT, $_[0], $xurl);
+  }, 'addselfprovides' => 1);
 }
+
diff --git a/createzyppdeps b/createzyppdeps
new file mode 100755 (executable)
index 0000000..8d85e49
--- /dev/null
@@ -0,0 +1,64 @@
+#!/usr/bin/perl -w
+
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+BEGIN {
+  unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
+}
+
+use strict;
+
+use Build::Zypp;
+use Getopt::Long;
+
+Getopt::Long::Configure("no_ignore_case");
+
+my $cachedir = "/var/cache/build";
+my $opt_listrepos;
+
+GetOptions(
+    "cachedir=s"  => \$cachedir,
+    "listrepos" => \$opt_listrepos,
+    ) or exit(1);
+
+if ($opt_listrepos) {
+  die("createzyppdeps --listrepos does not take an argument\n") if @ARGV;
+  for my $r (Build::Zypp::parseallrepos()) {
+    print "$r->{'name'}\n" if $r->{'enabled'};
+  }
+  exit 0;
+}
+die("createzyppdeps needs exactly one argument\n") if @ARGV != 1;
+my $url = $ARGV[0];
+
+die("createzyppdeps argument must start with 'zypp://'\n") unless $url =~ /^zypp:\/\/([^\/]*)/;
+my $repo = Build::Zypp::parserepo($1);
+
+my $type = $repo->{'type'};
+my $zyppcachedir = "/var/cache/zypp/raw/$repo->{'name'}";
+
+if($type eq 'rpm-md') {
+  exec ("$INC[0]/createrepomddeps", '--cachedir', $cachedir, '--zypp', $zyppcachedir, $url);
+} elsif ($type eq 'yast2') {
+  exec ("$INC[0]/createyastdeps", '--cachedir', $cachedir, '--zypp', $zyppcachedir, $url);
+} else {
+  die "unsupported repo type: $type\n";
+}
index c44d629513affb03ec6b86457a8692eb48320cd2..f16624feb0e5f56b5368c112a5c0fecabf9b5222 100644 (file)
@@ -1,8 +1,8 @@
-build (2015.01.15-tizen20160315) unstable; urgency=high
+build (20150115-tizen20160302) unstable; urgency=high
 
-  * just update version to 2015.01.15 
+  * update to version 20150115
 
- -- Jiankang Fan <jiankang.fan@samsung.com>  Tue, 15 Mar 2016 19:30:22 +0200
+ -- Fan Jiankang <jiankang.fan@samsung.com>  Wed, 2 Mar 2016 19:30:22 +0200
 
 
 build (2013.11.12-tizen20140815) unstable; urgency=high
index 272ff7150ea6308e58ae70cb0eb9c75ae9f32660..3d18326bebcd90cf0b26ae83c0f0c516db9c9ed2 100755 (executable)
@@ -1,8 +1,33 @@
 #!/usr/bin/perl -w
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 use strict;
 use Digest::MD5;
 
+sub usage
+{
+  die("usage: debtransform [--debug] [--changelog <changelog>] [--release <release number>] <srcdir> <dscfile> <outdir>\n");
+}
+
 sub parsedsc {
   my ($fn) = @_;
   my @control;
@@ -211,13 +236,30 @@ sub addfile {
   return "$md5 $size $base";
 }
 
+print "debtransform: ", join( " ", @ARGV ), "\n";
+
+my $debug = 0;
 my $changelog;
+my $release;
+
+while (@ARGV > 3) {
+  if ($ARGV[0] eq '--debug') {
+    shift @ARGV;
+    $debug = 1;
+  } elsif ($ARGV[0] eq '--changelog') {
+    shift @ARGV;
+    $changelog = shift @ARGV;
+  } elsif ($ARGV[0] eq '--release') {
+    shift @ARGV;
+    $release = shift @ARGV;
+  } else {
+    usage();
+  }
+}
 
-if (@ARGV > 1 && $ARGV[0] eq '--changelog') {
-  shift @ARGV;
-  $changelog = shift @ARGV;
+if( @ARGV != 3 ) {
+  usage();
 }
-die("usage: debtransform [--changelog <changelog>] <srcdir> <dscfile> <outdir>\n") unless @ARGV == 3;
 
 my $dir = $ARGV[0];
 my $dsc = $ARGV[1];
@@ -263,6 +305,7 @@ my $version = $tags->{'VERSION'};
 die("dsc file contains no version\n") unless defined($version);
 $version =~ s/^\d+://; # no epoch in version, please
 
+
 # transform 
 my $tmptar;
 if ($tarfile =~ /\.tar\.bz2/) {
@@ -300,6 +343,18 @@ if( $tmptar ) {
 }
 push @files, addfile("$out/$ntarfile");
 
+if ( $tags->{'DEBTRANSFORM-RELEASE'} && $release ) {
+    # if dsc file contains the tag DEBTRANSFORM-RELEASE
+    # and "release" is given as a commad line parameter,
+    # replace "version" from dsc file by "version-release".
+    # From "version" the current release is stripped before
+    # (last "-" and the part after the last "-").
+    # On OBS, release is incremented automatically
+    # (same as for RPMs)
+    $version = $v . "-" . $release;
+    $tags->{'VERSION'} = $version;
+}
+
 my $tarpath = "$out/$ntarfile";
 my $tardir = $tarfile;
 $tardir =~ s/\.orig\.tar/\.tar/;
@@ -368,5 +423,13 @@ delete $tags->{'DEBTRANSFORM-SERIES'};
 delete $tags->{'DEBTRANSFORM-TAR'};
 delete $tags->{'DEBTRANSFORM-FILES-TAR'};
 delete $tags->{'DEBTRANSFORM-FILES'};
+delete $tags->{'DEBTRANSFORM-RELEASE'};
 writedsc("$out/${name}_$version.dsc", $tags);
+
+if( $debug ) {
+  print `ls -la $out`;
+  print `cat $out/${name}_$version.dsc`;
+  print `zcat $out/${name}_$version.diff.gz`;
+}
+
 exit(0);
index 01c1e9dafa1e1b7e3dba9278041f0efa289f560a..b49ed4cfba67c6815176d0d44a2a237aabaa7ac4 100755 (executable)
@@ -1,5 +1,25 @@
 #! /bin/bash
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 if test $# -ne 2; then
     exit 1
 fi
index 2054c1288c80a93a02e0fa0d4acab5666e7b33ad..233574587f671a22a9e5a17298231c8ec0e391fb 100755 (executable)
@@ -1,5 +1,25 @@
 #! /bin/bash
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 if test $# -ne 2; then
     exit 1
 fi
index 4314617e37d450d6605b46f5b24df8847997f1a5..ac6e9f4121d9e00802c8df8fd0f86d8b0a5e2532 100755 (executable)
--- a/download
+++ b/download
@@ -1,5 +1,25 @@
 #!/usr/bin/perl -w
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 use Net::SSL ();
 BEGIN {
   $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0,
@@ -31,11 +51,11 @@ for my $url (@ARGV) {
   my $original = $url;
   if ($url =~ /^zypp:\/\/([^\/]*)\/?/) {
     use Build::Zypp;
-    my $repo = Build::Zypp::parsecfg($1);
+    my $repo = Build::Zypp::parserepo($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 '/';
+    $u .= '/' unless $u =~ /\/$/;
     $url =~ s/^zypp:\/\/[^\/]*\/*//;
     $url = URI->new($u.$url);
     if ($url->scheme eq 'dir') {
index 0051172ae69e4477b28df98ed32c8bc2894dd988..3320f9f817906bdcd585e56a210c458fe366acfe 100755 (executable)
@@ -1,6 +1,26 @@
 #!/bin/bash
 
-echo "ERROR: the emulator.sh script got not changed to support your emulator!"
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+echo "ERROR: the emulator.sh script needs to be changed to support your emulator!"
 exit 1
 
 
index fe54d2bb717c4cc95c32e095d9d8a8c51a15dc52..c7520bd1eaf6d69aea7b9b730a7b590e8f619ffc 100755 (executable)
@@ -1,5 +1,25 @@
 #!/usr/bin/perl -w
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 BEGIN {
   unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
 }
@@ -9,7 +29,9 @@ use strict;
 use Build;
 use File::Basename;
 
-my ($dist, $rpmdeps, $archs, $configdir, $useusedforbuild);
+my ($dist, $rpmdeps, $archs, $configdir, $useusedforbuild, $installonly, $noinstall);
+
+$configdir = ($::ENV{'BUILD_DIR'} || '/usr/lib/build') . '/configs';
 
 while (@ARGV)  {
   if ($ARGV[0] eq '--dist') {
@@ -57,23 +79,44 @@ while (@ARGV)  {
   }
   last;
 }
-$configdir = '.' unless defined $configdir;
+
 $archs = '' unless defined $archs;
 die("you must specfiy a depfile!\n") unless defined $rpmdeps;
 
-my @extradeps = grep {!/(^|\/)(?:PKGBUILD|_preinstallimage)$/ && !/\.(?:spec|dsc|kiwi)$/} @ARGV;
-my @specs = grep {/(^|\/)(?:PKGBUILD|_preinstallimage)$/ || /\.(?:spec|dsc|kiwi)$/} @ARGV;
-die("can only work with at most one spec\n") if @specs > 1;
-my $spec = $specs[0];
+# split args in recipe and pkgnames
+my $recipe;
+my @extradeps;
+for my $arg (@ARGV) {
+  my $buildtype = Build::recipe2buildtype($arg);
+  if ($buildtype) {
+    die("can only work with at most one recipe file\n") if defined $recipe;
+    $recipe = $arg;
+  } else {
+    push @extradeps, $arg;
+  }
+}
 
+my $binarytype;
 my @archs = split(':', $archs);
-if ($spec =~ /(^|\/)PKGBUILD$/) {
+if ($recipe =~ /(^|\/)PKGBUILD$/) {
   push @archs, 'any' unless grep {$_ eq 'any'} @archs;
+  $binarytype = 'arch';
+} elsif ($recipe =~ /\.dsc$/) {
+  push @archs, 'all' unless grep {$_ eq 'noarch'} @archs;
+  $binarytype = 'deb';
 } else {
   push @archs, 'noarch' unless grep {$_ eq 'noarch'} @archs;
+  $binarytype = 'rpm';
 }
 
-my (%fn, %prov, %req);
+# read dist if we can
+my $cf;
+if (defined($dist) && $dist ne '') {
+  $cf = Build::read_config_dist($dist, $archs[0], $configdir);
+  $binarytype = $cf->{'binarytype'} if $cf->{'binarytype'} && $cf->{'binarytype'} ne 'UNDEFINED';
+}
+
+my (%fn, %prov, %req, %con, %obs);
 
 my %packs;
 my %repo;
@@ -81,7 +124,6 @@ my %ids;
 
 my %packs_arch;
 my %packs_done;
-
 # XXX: move to separate tool
 if (!defined($dist) || $dist eq '') {
   my $rpmarch = (grep {$fn{"rpm.$_"}} @archs)[0];
@@ -109,15 +151,26 @@ if (!defined($dist) || $dist eq '') {
   print STDERR "Warning: distribution not specified, assuming '$dist' (see $configdir).\n";
 }
 
-my $cf = Build::read_config_dist($dist, $archs[0], $configdir);
+$cf ||= Build::read_config_dist($dist, $archs[0], $configdir);
 $cf->{'warnings'} = 1;
 
 my $dofileprovides = %{$cf->{'fileprovides'}};
-
+$dofileprovides = 1 if ($binarytype || 'rpm') ne 'rpm';
 my %exportfilters = %{$cf->{'exportfilter'}};
+
 open(F, '<', $rpmdeps) || die("$rpmdeps: $!\n");
 # WARNING: the following code assumes that the 'I' tag comes last
-my ($pkgF, $pkgP, $pkgR);
+my ($pkgF, $pkgP, $pkgR, $pkgC, $pkgO);
+
+my $verscmp = \&Build::Rpm::verscmp;
+
+if ($binarytype && $binarytype eq 'deb') {
+  $verscmp = \&Build::Deb::verscmp;
+  for my $arch (@archs) {
+    $arch = Build::Deb::basearch($arch) unless $arch =~ /^i[456]86$/;
+  }
+}
+
 while(<F>) {
   chomp;
   if (/^F:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
@@ -141,30 +194,35 @@ while(<F>) {
     }
   } elsif (/^P:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
     $pkgP = $2;
-    next if $prov{$1};
-    $prov{$1} = $2;
   } elsif (/^R:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
     $pkgR = $2;
-    next if $req{$1};
-    $req{$1} = $2;
+  } elsif (/^C:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
+    $pkgC = $2;
+  } elsif (/^O:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
+    $pkgO = $2;
   } elsif (/^I:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
-    if ($ids{$1} && !$packs_done{$1} && defined($pkgF) && defined($pkgP) && defined($pkgR)) {
-      my $i = $1;
-      my $oldid = $ids{$1};
-      my $newid = $2;
-      if (Build::Rpm::verscmp($oldid, $newid) < 0) {
-        $ids{$i}  = $newid;
-        $fn{$i}   = $pkgF;
-        $prov{$i} = $pkgP;
-        $req{$i}  = $pkgR;
-      }
-    } else {
-      next if $ids{$1};
-      $ids{$1} = $2;
+    next if $packs_done{$1};
+    my ($i, $newid) = ($1, $2);
+    undef $i unless !$ids{$i} || $verscmp->($ids{$i}, $newid) < 0;
+    undef $i unless defined($pkgF) && defined($pkgP);
+    if (defined $i) {
+      $i =~ /^(.*)\.([^\.]+)$/ or die;
+      push @{$packs_arch{$2}}, $1;
+      $ids{$i}  = $newid;
+      $fn{$i}   = $pkgF;
+      $prov{$i} = $pkgP;
+      delete $req{$i};
+      delete $con{$i};
+      delete $obs{$i};
+      $req{$i}  = $pkgR;
+      $con{$i}  = $pkgC if defined $pkgC;
+      $obs{$i}  = $pkgO if defined $pkgO;
     }
     undef $pkgF;
     undef $pkgP;
     undef $pkgR;
+    undef $pkgC;
+    undef $pkgO;
   } elsif ($_ eq 'D:') {
     %packs_done = %ids;
   }
@@ -174,9 +232,10 @@ close F;
 for my $arch (@archs) {
   $packs{$_} ||= "$_.$arch" for @{$packs_arch{$arch} || []};
 }
+
 for my $pack (keys %packs) {
   my $r = {};
-  my (@s, $s, @pr, @re);
+  my (@s, $s, @pr, @re, @co, @ob);
   @s = split(' ', $prov{$packs{$pack}} || '');
   while (@s) {
     $s = shift @s;
@@ -186,7 +245,12 @@ for my $pack (keys %packs) {
       next;
     }
     push @pr, $s;
-    splice(@s, 0, 2) if @s && $s[0] =~ /^[<=>]/;
+    while (@s && $s[0] =~ /^[\(<=>|]/) {
+      $pr[-1] .= " $s[0] $s[1]";
+      $pr[-1] =~ s/ \((.*)\)/ $1/;
+      $pr[-1] =~ s/(<|>){2}/$1/;
+      splice(@s, 0, 2);
+    }
   }
   @s = split(' ', $req{$packs{$pack}} || '');
   while (@s) {
@@ -197,18 +261,48 @@ for my $pack (keys %packs) {
       next;
     }
     push @re, $s;
-    splice(@s, 0, 2) if @s && $s[0] =~ /^[<=>]/;
+    while (@s && $s[0] =~ /^[\(<=>|]/) {
+      $re[-1] .= " $s[0] $s[1]";
+      $re[-1] =~ s/ \((.*)\)/ $1/;
+      $re[-1] =~ s/(<|>){2}/$1/;
+      splice(@s, 0, 2);
+    }
+  }
+  @s = split(' ', $con{$packs{$pack}} || '');
+  while (@s) {
+    $s = shift @s;
+    next if !$dofileprovides && $s =~ /^\//;
+    push @co, $s;
+    while (@s && $s[0] =~ /^[\(<=>|]/) {
+      $co[-1] .= " $s[0] $s[1]";
+      $co[-1] =~ s/ \((.*)\)/ $1/;
+      $co[-1] =~ s/(<|>){2}/$1/;
+      splice(@s, 0, 2);
+    }
+  }
+  @s = split(' ', $obs{$packs{$pack}} || '');
+  while (@s) {
+    $s = shift @s;
+    next if !$dofileprovides && $s =~ /^\//;
+    push @ob, $s;
+    while (@s && $s[0] =~ /^[\(<=>|]/) {
+      $ob[-1] .= " $s[0] $s[1]";
+      $ob[-1] =~ s/ \((.*)\)/ $1/;
+      $ob[-1] =~ s/(<|>){2}/$1/;
+      splice(@s, 0, 2);
+    }
   }
   $r->{'provides'} = \@pr;
   $r->{'requires'} = \@re;
+  $r->{'conflicts'} = \@co;
+  $r->{'obsoletes'} = \@ob;
   $repo{$pack} = $r;
 }
 
 
 #######################################################################
 
-sub print_rpmlist
-{
+sub print_rpmlist {
   for (@_) {
     print "$_ $fn{$packs{$_}}\n";
     print "rpmid: $_:$ids{$packs{$_}}\n" if exists $ids{$packs{$_}};
@@ -217,12 +311,14 @@ sub print_rpmlist
   print "vminstall: @{$cf->{'vminstall'} || []}\n";
   print "runscripts: @{$cf->{'runscripts'} || []}\n";
   print "dist: $dist\n" if defined $dist;
+  print "installonly: $installonly\n" if defined $installonly;
+  print "noinstall: $noinstall\n" if defined $noinstall;
 }
 
 if ($useusedforbuild) {
-  die("Need a specfile/dscfile for --usedforbuild\n") unless defined $spec;
+  die("Need a recipe file for --usedforbuild\n") unless defined $recipe;
   local *F;
-  open(F, '<', $spec) || die("$spec: $!\n");
+  open(F, '<', $recipe) || die("$recipe: $!\n");
   my @usedforbuild;
   my @buildrequires;
   while(<F>) {
@@ -255,11 +351,12 @@ if ($useusedforbuild) {
 my ($packname, $packvers, $subpacks, @packdeps);
 $subpacks = [];
 
-if ($spec) {
-  my $d;
-  if ($spec =~ /\.kiwi$/) {
+if ($recipe) {
+  my $d = Build::parse($cf, $recipe) || {};
+  my $buildtype = Build::recipe2buildtype($recipe) || '';
+  $cf->{'type'} = $buildtype if $buildtype;
+  if ($buildtype eq 'kiwi') {
     # lets see if this is a product or image build
-    $d = Build::parse($cf, $spec) || {};
     my $type = $d->{'imagetype'} && $d->{'imagetype'}->[0] eq 'product' ? 'product' : 'image';
     my @kdeps;
     if ($type eq 'image') {
@@ -271,8 +368,6 @@ if ($spec) {
     }
     push @kdeps, grep {/^kiwi-.*:/} @{$d->{'deps'} || []};
     $d = { 'deps' => \@kdeps, 'subpacks' => [] };
-  } else {
-    $d = Build::parse($cf, $spec);
   }
   $packname = $d->{'name'};
   $packvers = $d->{'version'};
@@ -280,7 +375,7 @@ if ($spec) {
   @packdeps = @{$d->{'deps'} || []};
   if ($d->{'prereqs'}) {
     my %deps = map {$_ => 1} (@packdeps, @{$d->{'subpacks'} || []});
-    push @packdeps, grep {!$deps{$_} && !/^%/} @{$d->{'prereqs'}};
+    push @packdeps, '--directdepsend--', grep {!$deps{$_} && !/^%/} @{$d->{'prereqs'}};
   }
 }
 
@@ -296,6 +391,20 @@ if (!shift @bdeps) {
   exit(1);
 }
 
+my @sysdeps = Build::get_sysbuild($cf);
+if (@sysdeps) {
+  if (!shift @sysdeps) {
+    print STDERR "expansion error\n";
+    print STDERR "  $_\n" for @sysdeps;
+    exit(1);
+  }
+  my %sysdeps = map {$_ => 1} @sysdeps;
+  my %bdeps = map {$_ => 1} @bdeps;
+  $installonly = join(' ', grep {!$bdeps{$_}} @sysdeps);
+  $noinstall = join(' ', grep {!$sysdeps{$_}} @bdeps);
+  @bdeps = Build::unify(@sysdeps, @bdeps);
+}
+
 # make sure all preinstalls are in bdeps;
 # XXX: also add vmdeps?
 @bdeps = Build::unify(@bdeps, Build::get_preinstalls($cf));
index f46ffc14ab614899b4ab5b399416e90f506887e6..d2d56aded885fc03e6ab3d628c3d6444e6d0af36 100755 (executable)
@@ -1,11 +1,32 @@
 #!/usr/bin/perl -w
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 use strict;
 
 # buffer size for reading
 my $bufsize = 4*1024*1024;
 
 my ($opt_skip, $opt_disk, $opt_input, $opt_verbose);
+$opt_verbose = 0;
 
 while (@ARGV)  {
   if ($ARGV[0] eq '--skip') {
@@ -25,7 +46,7 @@ while (@ARGV)  {
   }
   if ($ARGV[0] eq '--verbose' || $ARGV[0] eq '-v') {
     shift @ARGV;
-    $opt_verbose = 1;
+    $opt_verbose++;
     next;
   }
   last;
@@ -35,51 +56,86 @@ die "need to specify disk image\n" unless $opt_disk;
 
 open(F, '<', $opt_disk) || die "$opt_disk: $!\n";
 
-if($opt_input) {
+if ($opt_input) {
   open(S, '<', $opt_input) || die "$opt_input: $!\n";
 } else {
   open(S, '<&STDIN') || die "can't dup stdin: $!\n";
 }
 
 # skip build status
-if($opt_skip) {
-  seek(S, $opt_skip, 0) || die "$!\n";
+if ($opt_skip) {
+  seek(S, $opt_skip, 0) || die "seek: $!\n";
 }
 
-while(<S>) {
+my %done;
+while (<S>) {
   chomp;
   last unless length $_;
-  my ($file, $filesize, $blksize, @blocks) = split(/ /);
-  if($#blocks == -1 && $filesize) {
-    die "invalid input '$_'\n";
+  my ($filetype, $file, $filesize, $blksize, @blocks) = split(/ /);
+  die("invalid input '$_'\n") unless defined($file);
+  $file =~ s/%([a-fA-F0-9]{2})/chr(hex($1))/ge;
+  die("bad file '$file'\n") if "/$file/" =~ /\/\.{0,2}\//s;
+  if ($file =~ /^(.*)\//s) {
+    die("file without directory: $file\n") unless $done{$1} && $done{$1} eq 'd';
+  }
+  if ($filetype eq 'd') {      # dir
+    print "$file\n" if $opt_verbose && $opt_verbose > 1;
+    mkdir($file) || die("mkdir $file: $!\n");
+    $done{$file} = 'd';
+    next;
+  }
+  if ($filetype eq 'l') {      # symlink
+    my $target = $filesize;
+    die("symlink without target\n") unless defined $target;
+    $target =~ s/%([a-fA-F0-9]{2})/chr(hex($1))/ge;
+    die("bad symlink: $target\n") if "/$target/" =~ /\/\.?\//s;
+    if ("/$target/" =~ /^(\/\.\.)+\/(.*?)$/s) {
+      my ($head, $tail) = ($1, $2);
+      die("bad upref in symlink: $target\n") if "/$tail/" =~ /\/\.\.\//s;
+      die("bad upref in symlink: $target\n") if ($head =~ y!/!!) > ($file =~ y!/!!);
+    } else {
+      die("bad upref in symlink: $target\n") if "/$target/" =~ /\/\.\.\//s;
+    }
+    print "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//);
+    symlink($target, $file) || die("symlink $target $file: $!\n");
+    $done{$file} = 'l';
+    next;
   }
+  die("illegal file type: $filetype\n") unless $filetype eq 'f';
+  die "invalid input '$_'\n" if !@blocks && $filesize;
+  $done{$file} = 'f';
   $filesize = int($filesize);
+  if ($filesize == 0) {
+    print "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//);
+    open (O, '>', $file) or die "$file: $!\n";
+    close O;
+    next;
+  }
   $blksize = int($blksize);
-  die "invalid block size" unless ($blksize > 0 && $blksize <= $bufsize);
+  die "$file: invalid block size $blksize\n" unless $blksize > 0 && $blksize <= $bufsize;
   my $maxblocks = int($bufsize/$blksize);
-  $file =~ s/.*\///; # ensure basename, also stops directory traversal
-  $file =~ s/[^[:print:]]/_/g; # no binary junk in file names
-  print "$file\n" if $opt_verbose;
-  open (O, '>', $file) or die "$file: $!";
+  print "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//);
+  open (O, '>', $file) or die "$file: $!\n";
   for my $block (@blocks) {
-    my ($block, $end) = split(/-/, $block);
+    my $end;
+    ($block, $end) = split(/-/, $block);
     $block = int($block);
-
-    if($block == 0) { # a hole!
-      seek(O, $blksize, 1);
-      $filesize -= $blksize;
+    if ($block == 0) { # a hole!
+      $end = (($end || 0) + 1) * $blksize;
+      $end = $filesize if $end > $filesize;
+      seek(O, $end, 1);
+      $filesize -= $end;
       next;
     }
-
     $end = $block unless $end;
     $end = int($end);
     seek(F, $block*$blksize, 0) || die "$file: seek: $!\n";
-    while($block <= $end && $filesize) {
+    while ($block <= $end && $filesize) {
       my $size;
-      if($end == $block) {
+      if ($end == $block) {
        $size = $blksize;
        ++$block;
-      } elsif($maxblocks >= $end-$block) {
+      } elsif ($maxblocks >= $end-$block) {
        $size = ($end-$block)*$blksize;
        $block += $end-$block;
       } else {
@@ -88,14 +144,12 @@ while(<S>) {
       }
       $size = $filesize if $size > $filesize;
       my $buf;
-      if((sysread(F, $buf, $size) || 0) != $size) {
-       die "$file: read: $!\n";
-      }
+      (sysread(F, $buf, $size) || 0) == $size || die("$file: read: $!\n");
       $filesize -= $size;
-      print O $buf;
+      (syswrite(O, $buf) || 0) == length($buf) || die("$file: write error\n");
     }
   }
-  close O;
+  close(O) || die("$file: close error: $!\n");
   # sanity check
   die "$file: invalid file size ($filesize byes left)\n" if $filesize != 0;
 }
index 55c57f64cbadf937db2ae780fdf671937437aee7..a85df827573a8ceb7aa51d287397361bcb2e8a46 100755 (executable)
@@ -1,5 +1,25 @@
 #!/usr/bin/perl
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 BEGIN {
   unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
 }
index 6e832663aca358c25def26727abc54e19d29a653..169158dc69bbc6a18170f35c9432d71918a44d71 100755 (executable)
@@ -7,16 +7,37 @@
 # BUILD_RPMS  here we get our packages to install
 # BUILD_ARCH  path of the architectures we try
 #
-# (c) 1997-2005 SuSE GmbH Nuernberg, Germany
+################################################################
+#
+# Copyright (c) 1997-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
 
 #
 # needed globals variables
 #
 export SRC
-export YAST_IS_RUNNING="instsys"
-export DEBIAN_FRONTEND=noninteractive
-export DEBIAN_PRIORITY=critical
 export BUILD_DIR=${BUILD_DIR:-/usr/lib/build}
+
+export YAST_IS_RUNNING=instsys
+
+# slurp in package binary support
+. "$BUILD_DIR/build-pkg"
+
 # need to restore build root owner for non-root builds
 browner=0
 definesnstuff=()
@@ -24,23 +45,20 @@ repos=()
 
 . $BUILD_DIR/common_functions || exit 1
 
-# should RPMs be installed with --force ?
-USE_FORCE=false
-
 BUILD_IS_RUNNING=$BUILD_ROOT/not-ready
 TMPFILE=$BUILD_ROOT/tmpfile
-#buildhost removed so that id can be generated from repo files
-#RPMIDFMT="%{NAME}-%{VERSION}-%{RELEASE} %{BUILDHOST}-%{BUILDTIME}\n"
-RPMIDFMT="%{NAME}-%{VERSION}-%{RELEASE} %{BUILDTIME}\n"
 
+# should RPMs be installed with --force ?
+USE_FORCE=false
 PREPARE_VM=
-USE_SYSTEM_QEMU=
 KEEP_PACKS=
 USEUSEDFORBUILD=
 LIST_STATE=
 RPMLIST=
 CLEAN_BUILD=
 CREATE_BUILD_BINARIES=
+DLNOSIGNATURE=
+CACHE_DIR=/var/cache/build
 
 while test -n "$1" ; do
     case "$1" in
@@ -48,14 +66,10 @@ while test -n "$1" ; do
            shift
            PREPARE_VM=true
            ;;
-       --use-system-qemu)
-           shift
-           USE_SYSTEM_QEMU=true
-           ;;
-       --keep-packs)
-           shift
-           KEEP_PACKS=true
-           ;;
+       --keep-packs)
+           shift
+           KEEP_PACKS=true
+           ;;
        --create-build-binaries)
            shift
            CREATE_BUILD_BINARIES=true
@@ -80,12 +94,12 @@ while test -n "$1" ; do
            ;;
        --repository|--repo)
            repos[${#repos[@]}]="$2";
-           shift 2;
+           shift 2
            ;;
        --clean)
            CLEAN_BUILD="$1"
            shift
-       ;;
+           ;;
        --cachedir)
            CACHE_DIR="$2"
            shift 2
@@ -94,6 +108,10 @@ while test -n "$1" ; do
            CONFIG_DIR=$2
            shift 2
            ;;
+       --nosignature)
+           shift
+           DLNOSIGNATURE="--nosignature"
+           ;;
        *)
            break
            ;;
@@ -105,8 +123,7 @@ PKGS=("$@")
 # needed functions
 #
 
-cleanup_and_exit()
-{
+cleanup_and_exit() {
     trap EXIT
     test "$BUILD_ROOT" = / -a -n "$browner" && chown "$browner" "$BUILD_ROOT"
     # umount so init_buildsystem can be used standalone
@@ -118,31 +135,33 @@ cleanup_and_exit()
     exit ${1:-0}
 }
 
-clean_build_root()
-{
-       test -n "$BUILD_ROOT" && {
-           umount -n "$BUILD_ROOT/proc/sys/fs/binfmt_misc" 2> /dev/null || true
-           umount -n "$BUILD_ROOT/proc" 2> /dev/null || true
-           umount -n "$BUILD_ROOT/dev/pts" 2> /dev/null || true
-           umount -n "$BUILD_ROOT/mnt" 2> /dev/null || true
-           rm -rf -- "$BUILD_ROOT"/*
-           rm -rf -- "$BUILD_ROOT/.build"
-           rm -rf -- "$BUILD_ROOT/.root"
-           rm -rf -- "$BUILD_ROOT/.init_b_cache"
-           rm -rf -- "$BUILD_ROOT/.preinstall_image/*"
-           rm -rf -- "$BUILD_ROOT/.preinstallimage"*
-           mkdir -p "$BUILD_ROOT/proc"
-           mkdir -p "$BUILD_ROOT/dev/pts"
-           if [ "$UID" = '0' ]; then
-                   mount -n -tproc none "$BUILD_ROOT/proc"
-                   mount -n -tdevpts -omode=0620,gid=5 none "$BUILD_ROOT/dev/pts"
-           fi
-       }
+clean_build_root() {
+    if test -n "$BUILD_ROOT" ; then
+       umount -n "$BUILD_ROOT/proc/sys/fs/binfmt_misc" 2> /dev/null || true
+       umount -n "$BUILD_ROOT/proc" 2> /dev/null || true
+       umount -n "$BUILD_ROOT/dev/pts" 2> /dev/null || true
+       umount -n "$BUILD_ROOT/dev/shm" 2> /dev/null || true
+       umount -n "$BUILD_ROOT/mnt" 2> /dev/null || true
+       rm -rf -- "$BUILD_ROOT"/* 2> /dev/null || true
+       chattr -a -A -i -R -- "$BUILD_ROOT" 2> /dev/null || true
+       rm -rf -- "$BUILD_ROOT"/*
+       rm -rf -- "$BUILD_ROOT/.build"
+       rm -rf -- "$BUILD_ROOT"/.build.kernel.*
+       rm -rf -- "$BUILD_ROOT"/.build.initrd.*
+       rm -rf -- "$BUILD_ROOT/.root"
+       rm -rf -- "$BUILD_ROOT/.init_b_cache"
+       rm -rf -- "$BUILD_ROOT"/.preinstall_image/*
+       rm -rf -- "$BUILD_ROOT"/.preinstallimage*
+       mkdir -p "$BUILD_ROOT/proc"
+       mkdir -p "$BUILD_ROOT/dev/pts"
+       if test "$UID" = 0 ; then
+           mount -n -tproc none "$BUILD_ROOT/proc"
+           mount -n -tdevpts -omode=0620,gid=5 none "$BUILD_ROOT/dev/pts"
+       fi
+    fi
 }
 
-
-unsafe_preinstall_check()
-{
+unsafe_preinstall_check() {
     # cpio isn't safe so we require bsdtar for VMs. chroot is
     # unsafe anyways so it's ok for that.
     if test -n "$PREPARE_VM" ; then
@@ -152,22 +171,16 @@ unsafe_preinstall_check()
     fi
 }
 
-preinstall_image_filter()
-{
+preinstall_image_filter() {
     for PKG in "$@" ; do
        test -e "$BUILD_ROOT/.preinstall_image/$PKG" && continue
        echo $PKG
     done
 }
 
-preinstall_image()
-{
+preinstall_image() {
     check_exit
-    if test -n "$2" ; then
-       echo "unpacking preinstall image $2"
-    else
-       echo "unpacking preinstall image"
-    fi
+    echo "unpacking preinstall image${2:+ $2}"
     cd $BUILD_ROOT || cleanup_and_exit 1
     if test -x /usr/bin/bsdtar ; then
        TAR="/usr/bin/bsdtar -P --chroot --numeric-owner -x"
@@ -184,10 +197,10 @@ preinstall_image()
     rm -f "$BUILD_ROOT/.preinstallimage.unpack"
 }
 
-preinstall()
-{
+preinstall() {
+    local PKG="$1"
     check_exit
-    echo "preinstalling $1..."
+    echo "preinstalling $PKG..."
     cd $BUILD_ROOT || cleanup_and_exit 1
     if test -x /usr/bin/bsdtar ; then
        CPIO="/usr/bin/bsdtar -P --chroot -o --numeric-owner -x -f-"
@@ -195,128 +208,20 @@ preinstall()
     else
        unsafe_preinstall_check
        CPIO="cpio --extract --unconditional --preserve-modification-time --make-directories --no-absolute-filenames --quiet"
-    cpio --help 2>/dev/null | grep -q -e --extract-over-symlinks && CPIO="$CPIO --extract-over-symlinks"
        TAR="tar -x"
     fi
-    if test -e "$BUILD_ROOT/.init_b_cache/rpms/$1.rpm" ; then
-       PAYLOADDECOMPRESS=cat
-       case `rpm -qp --nodigest --nosignature --qf "%{PAYLOADCOMPRESSOR}\n" "$BUILD_ROOT/.init_b_cache/rpms/$1.rpm"` in
-           lzma) rpm --showrc | egrep 'PayloadIsLzma|_lzma' > /dev/null || PAYLOADDECOMPRESS="lzma -d" ;;
-           xz) rpm --showrc | egrep 'PayloadIsXz|_xz' > /dev/null || PAYLOADDECOMPRESS="xz -d" ;;
-       esac
-       if test "$PAYLOADDECOMPRESS" = "lzma -d" ; then
-           if ! lzma </dev/null >/dev/null 2>&1 ; then
-               test -f "$BUILD_DIR/lzmadec.sh" && PAYLOADDECOMPRESS="bash $BUILD_DIR/lzmadec.sh"
-           fi
-       fi
-       if test "$PAYLOADDECOMPRESS" = "xz -d" ; then
-           if ! xz </dev/null >/dev/null 2>&1 ; then
-               test -f "$BUILD_DIR/xzdec.sh" && PAYLOADDECOMPRESS="bash $BUILD_DIR/xzdec.sh"
-           fi
-       fi
-       if test "$PAYLOADDECOMPRESS" = cat ; then
-           rpm2cpio "$BUILD_ROOT/.init_b_cache/rpms/$1.rpm" | $CPIO
-       else
-           rpm2cpio "$BUILD_ROOT/.init_b_cache/rpms/$1.rpm" | $PAYLOADDECOMPRESS | $CPIO
-       fi
-       if test -e ".init_b_cache/scripts/$1.run" ; then
-           rpm -qp --nodigest --nosignature --qf "%{PREIN}" "$BUILD_ROOT/.init_b_cache/rpms/$1.rpm" > ".init_b_cache/scripts/$1.pre"
-           rpm -qp --nodigest --nosignature --qf "%{POSTIN}" "$BUILD_ROOT/.init_b_cache/rpms/$1.rpm" > ".init_b_cache/scripts/$1.post"
-           echo -n '(none)' > .init_b_cache/scripts/.none
-           cmp -s ".init_b_cache/scripts/$1.pre" .init_b_cache/scripts/.none && rm -f ".init_b_cache/scripts/$1.pre"
-           cmp -s ".init_b_cache/scripts/$1.post" .init_b_cache/scripts/.none && rm -f ".init_b_cache/scripts/$1.post"
-           rm -f .init_b_cache/scripts/.none
-       fi
-    elif test -e "$BUILD_ROOT/.init_b_cache/rpms/$1.deb" ; then
-        # fix issue for ubuntu15.04 "data.tar.xz"
-       ar x "$BUILD_ROOT/.init_b_cache/rpms/$1.deb"
-       mkdir -p .init_b_cache/scripts/control
-       $TAR -C .init_b_cache/scripts/control -z -f control.tar.gz
-       if test -f "data.tar.gz"; then
-           $TAR -z -f data.tar.gz
-       elif test -f "data.tar.xz"; then
-           $TAR -J -f data.tar.xz
-       fi
-       if test -e ".init_b_cache/scripts/$1.run" ; then
-           test -e .init_b_cache/scripts/control/preinst && mv .init_b_cache/scripts/control/preinst ".init_b_cache/scripts/$1.pre"
-           test -e .init_b_cache/scripts/control/postinst && mv .init_b_cache/scripts/control/postinst ".init_b_cache/scripts/$1.post"
-       fi
-       rm -rf .init_b_cache/scripts/control control.tar.gz data.tar.{g,x}z
-    elif test -e "$BUILD_ROOT/.init_b_cache/rpms/$1.arch" ; then
-       $TAR -f "$BUILD_ROOT/.init_b_cache/rpms/$1.arch"
-       if test -f .INSTALL ; then
-           cat .INSTALL > ".init_b_cache/scripts/$1.post"
-           echo 'type post_install >/dev/null 2>&1 && post_install' >> ".init_b_cache/scripts/$1.post"
-       fi
-       rm -f .PKGINFO .INSTALL
-    else
-       echo "warning: package $1 does not exist"
-    fi
+    pkg_preinstall
 }
 
-run_pkg_scripts()
-{
-    # need to change to $BUILD_ROOT
-    cd $BUILD_ROOT
+run_pkg_scripts() {
     chroot $BUILD_ROOT /sbin/ldconfig 2>/dev/null
     for PKG in $PACKAGES_TO_RUNSCRIPTS ; do
-       if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.pre" ; then
-           echo "running $PKG preinstall script"
-           if test -e "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" ; then
-               chroot $BUILD_ROOT sh ".init_b_cache/scripts/$PKG.pre" 0
-           else
-               chroot $BUILD_ROOT ".init_b_cache/scripts/$PKG.pre" install < /dev/null
-           fi
-           rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.pre"
-       fi
-       if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post" ; then
-           echo "running $PKG postinstall script"
-           if test -e "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" ; then
-               chroot $BUILD_ROOT sh ".init_b_cache/scripts/$PKG.post" 1
-           else
-               chroot $BUILD_ROOT ".init_b_cache/scripts/$PKG.post" configure '' < /dev/null
-           fi
-           rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post"
-       fi
+       pkg_runscripts
        check_exit
     done
 }
 
-init_db()
-{
-    if test $PSUF = rpm ; then
-       echo initializing rpm db...
-        if ! test -e $BUILD_ROOT/usr/lib/rpm/cpuinfo.yaml; then
-            # rpm v5 does not have initdb
-            # rpmdb --initdb is recommended and exists since SL9
-            if [ -x $BUILD_ROOT/usr/bin/rpmdb ]; then
-             chroot $BUILD_ROOT /usr/bin/rpmdb --initdb || cleanup_and_exit 1
-            else
-             chroot $BUILD_ROOT rpm --initdb || cleanup_and_exit 1
-            fi
-        fi
-       # hack: add nofsync to db config to speed up install
-       mkdir -p $BUILD_ROOT/root
-       DBI_OTHER=`chroot $BUILD_ROOT rpm --eval '%{?__dbi_other}'`
-       echo "%__dbi_other $DBI_OTHER nofsync" > $BUILD_ROOT/.rpmmacros
-       echo "%__dbi_other $DBI_OTHER nofsync" > $BUILD_ROOT/root/.rpmmacros
-    elif test $PSUF = deb ; then
-       # force dpkg into database to make epoch test work
-       if ! test "$BUILD_ROOT/.init_b_cache/rpms/dpkg.deb" -ef "$BUILD_ROOT/.init_b_cache/dpkg.deb" ; then
-           rm -f $BUILD_ROOT/.init_b_cache/dpkg.deb
-           cp $BUILD_ROOT/.init_b_cache/rpms/dpkg.deb $BUILD_ROOT/.init_b_cache/dpkg.deb || cleanup_and_exit 1
-       fi
-       chroot $BUILD_ROOT dpkg -i --force all .init_b_cache/dpkg.deb >/dev/null 2>&1
-    elif test $PSUF = arch ; then
-       mkdir -p $BUILD_ROOT/var/lib/pacman/sync
-       touch $BUILD_ROOT/var/lib/pacman/sync/core.db
-       touch $BUILD_ROOT/var/lib/pacman/sync/extra.db
-       touch $BUILD_ROOT/var/lib/pacman/sync/community.db
-    fi
-}
-
-reorder()
-{
+reorder() {
     test -z "$*" && return
     rm -f $BUILD_ROOT/.init_b_cache/order.manifest
     for PKG in "$@" ; do
@@ -326,12 +231,11 @@ reorder()
     rm -f $BUILD_ROOT/.init_b_cache/order.manifest
 }
 
-create_devs()
-{
+create_devs() {
     local com file mode arg
 
     mkdir -m 755 -p $BUILD_ROOT/dev/pts
-    test -f $BUILD_ROOT/dev/shm && rm -f $BUILD_ROOT/dev/shm
+    test -d $BUILD_ROOT/dev/shm || rm -f $BUILD_ROOT/dev/shm
     mkdir -m 755 -p $BUILD_ROOT/dev/shm
     while read com file mode arg ; do
        rm -f $BUILD_ROOT/dev/$file
@@ -361,16 +265,14 @@ DEVLIST
 
 # check whether the repo list contains a plain "zypp://". Add all
 # enabled zypp repos in this case
-maybe_add_all_zypp_repos()
-{
+expand_plain_zypp_repo() {
     local i j
     r=()
     for i in "${repos[@]}"; do
-       if [ "$i" = "zypp://" ]; then
-           while read j; do
-               j="${j#/etc/zypp/repos.d/}"
-               r=("${r[@]}" "zypp://${j%.repo}")
-           done < <(grep -l enabled=1 /etc/zypp/repos.d/*.repo)
+       if test "$i" = "zypp://" ; then
+           for j in $($BUILD_DIR/createzyppdeps --listrepos) ; do
+               r=("${r[@]}" "zypp://$j")
+           done
        else
            r=("${r[@]}" "$i")
        fi
@@ -378,25 +280,24 @@ maybe_add_all_zypp_repos()
     repos=("${r[@]}")
 }
 
-validate_cache_file()
-{
-    local findonly=''
-    maybe_add_all_zypp_repos
+create_cache_file() {
+    local findonly=
+    expand_plain_zypp_repo
     if ! test -f $CACHE_FILE || ! test -f $CACHE_FILE.id || \
        test "${repos[*]} ${BUILD_RPMS//:/ /}" != "$(cat $CACHE_FILE.id 2>/dev/null)"; then
        rm -f $CACHE_FILE.id
     else
        for SRC in "${repos[@]}" ${BUILD_RPMS//:/ /}; do
            test -n "$SRC" || SRC=.
-           if [ "${SRC#zypp://}" != "$SRC" ]; then
-               SRC="/var/cache/zypp/raw" # XXX can't use name here as we'd need to parse the file
+           if test "${SRC#zypp://}" != "$SRC" ; then
+               SRC="/var/cache/zypp/raw/${SRC#zypp://}"
            fi
            if test "$SRC" -nt $CACHE_FILE; then
                rm -f $CACHE_FILE.id
                break
            fi
            # always rebuild if we have remote repositories and --clean is given
-           if test -n "$CLEAN_BUILD" -a "$SRC" != "${SRC#*://}" ; then
+           if test -n "$CLEAN_BUILD" -a "$SRC" != "${SRC#*://}" -a "${SRC#zypp://}" = "$SRC" ; then
                rm -f $CACHE_FILE.id
                break
            fi
@@ -404,29 +305,50 @@ validate_cache_file()
     fi
     if ! test -f $CACHE_FILE.id ; then
        test -z "$LIST_STATE" && echo initializing $CACHE_FILE ...
+       BINTYPE=
+       if test -n "$BUILD_DIST" ; then
+           BINTYPE=`queryconfig binarytype --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH"`
+           test "$BINTYPE" = UNDEFINED && BINTYPE=
+       fi
+       if test -z "$BINTYPE" ; then
+           # check the first init_buildsystem arg, maybe it is a recipe
+           case ${PKGS[0]} in
+               *.spec)
+                   BINTYPE=rpm ;;
+               *.dsc)
+                   BINTYPE=deb ;;
+               */PKGBUILD|PKGBUILD)
+                   BINTYPE=arch ;;
+           esac
+       fi
        for SRC in "${repos[@]}" -- ${BUILD_RPMS//:/ /}; do
            if test "$SRC" = '--' ; then
                findonly=1
                continue
            fi
            test -z "$SRC" && SRC=`pwd`
-           if [ "${SRC#zypp://}" != "$SRC" ]; then
-               set -- $BUILD_DIR/createrepomddeps "$SRC"
-           elif [ "${SRC#http://}" != "$SRC" -o "${SRC#https://}" != "$SRC" -o "${SRC#ftp://}" != "$SRC" -o "${SRC#ftps://}" != "$SRC" ]; then
-               mkdir -p "$(getcachedir "$SRC")"
-               set -- $BUILD_DIR/createrepomddeps --cachedir="$CACHE_DIR" "$SRC"
-           elif [ "${SRC#arch@http://}" != "$SRC" -o "${SRC#arch@https://}" != "$SRC" -o "${SRC#arch@ftp://}" != "$SRC" -o "${SRC#arch@ftps://}" != "$SRC" ]; then
+           if test "${SRC#http://}" != "$SRC" -o "${SRC#https://}" != "$SRC" -o "${SRC#ftp://}" != "$SRC" -o "${SRC#ftps://}" != "$SRC" ; then
+               # remote repo, cache binary packages
                mkdir -p "$(getcachedir "$SRC")"
-               set -- $BUILD_DIR/createrepomddeps --cachedir="$CACHE_DIR" "$SRC"
-           elif [ ! -e "$SRC" ]; then
+               if test "$BINTYPE" = arch ; then
+                   set -- $BUILD_DIR/createarchdeps --cachedir="$CACHE_DIR" "$SRC"
+               elif test "$BINTYPE" = deb ; then
+                   set -- $BUILD_DIR/createdebdeps --cachedir="$CACHE_DIR" --archpath "$BUILD_ARCH" "$SRC"
+               else
+                   set -- $BUILD_DIR/createrepomddeps --cachedir="$CACHE_DIR" "$SRC"
+               fi
+           elif test "${SRC#zypp://}" != "$SRC" ; then
+               # special zypp repo
+               set -- $BUILD_DIR/createzyppdeps --cachedir="$CACHE_DIR" "$SRC"
+           elif test ! -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
+           elif test -z "$findonly" -a \( -e "$SRC"/suse/setup/descr/packages -o -e "$SRC"/suse/setup/descr/packages.gz \) ; then
                set -- $BUILD_DIR/createyastdeps "$SRC"
-           elif [ -z "$findonly" -a -e "$SRC"/repodata/repomd.xml ]; then
+           elif test -z "$findonly" -a -e "$SRC"/repodata/repomd.xml ; then
                set -- $BUILD_DIR/createrepomddeps "$SRC"
            else
-               set -- $BUILD_DIR/createrpmdeps "$SRC"
+               set -- $BUILD_DIR/createdirdeps --oldfile "$CACHE_FILE" "$SRC"
            fi
            echo "$@" >&2
            "$@" || cleanup_and_exit 1
@@ -438,6 +360,71 @@ validate_cache_file()
     fi
 }
 
+fail_exit() {
+    cleanup_and_exit 1
+}
+
+# modifies $SRC
+downloadpkg() {
+    local url="$1"
+    local cachedir
+
+    if test "${url:0:7}" == "zypp://" -o "${url:0:7}" == "http://" -o "${url:0:8}" == "https://" -o "${url:0:6}" == "ftp://" -o "${url:0:7}" == "ftps://" ; then
+       cachedir="$(getcachedir "$url")"
+       local name="$(basename "$url")"
+       name=${name/%.pkg.tar.?z/.arch}
+       SRC="$cachedir/$name"
+    else
+       echo "Invalid url: $url"
+       cleanup_and_exit 1
+    fi
+
+    local destdir="$cachedir/tmp_$$"
+    mkdir -p "$destdir"
+    echo "downloading $url ... ";
+    $BUILD_DIR/download "$destdir" "$url" || cleanup_and_exit 1
+    local destfile="$destdir/${url##*/}"
+    if test ! -e "$destfile" ; then
+       echo "expected $destfile after download but it's missing" >&2
+       cleanup_and_exit 1
+    fi
+    # for rpm check integrity and the signature
+    case $destfile in
+      *.rpm)
+       rpm -K $DLNOSIGNATURE "$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"
+       ;;
+    esac
+    mv "$destfile" "$SRC" || cleanup_and_exit 1
+    rm -rf $destdir
+}
+
+getcachedir() {
+    local url=$1
+    for repo in "${repos[@]}" ; do
+       if test "${url:0:${#repo}}" == "$repo" ; then
+           read repoid dummy < <(echo -n "$repo" | md5sum)
+           echo "$CACHE_DIR/$repoid"
+           break
+       fi
+    done
+}
+
+can_reuse_cached_package() {
+    local cachepkgid pkgid
+    test -s "$1" || return 1
+    if test -s "$BUILD_ROOT/.init_b_cache/rpms/$PKG.id" ; then
+        pkgid=$(perl -I$BUILD_DIR -MBuild -e Build::showquery "$1" buildid)
+       read cachepkgid < $BUILD_ROOT/.init_b_cache/rpms/$PKG.id
+       test "$cachepkgid" = "$pkgid" || return 1
+    fi
+    return 0
+}
+
 check_copy_qemu()
 {
     local arch
@@ -506,112 +493,24 @@ copy_qemu()
     fi
 }
 
-check_binfmt_registered()
-{
-    local arch
-    for arch in $EMULATOR_DEVS; do
-       if test -e /proc/sys/fs/binfmt_misc/$arch; then
-           return 0
-       fi
-    done
-    return 1
-}
-
-fail_exit()
-{
-  cleanup_and_exit 1
-}
-
-# modifies $SRC
-downloadpkg()
-{
-    local url="$1"
-    local cachedir
-
-    if [ "${url:0:7}" == "zypp://" ] ; then
-       cachedir="/var/cache/zypp/packages/"
-       SRC="$cachedir${url#zypp://}"
-       mkdir -p "${SRC%/*}" || cleanup_and_exit 1
-    elif [ "${url:0:7}" == "http://" -o "${url:0:8}" == "https://" -o "${url:0:6}" == "ftp://" -o "${url:0:7}" == "ftps://" ] ; then
-       cachedir="$(getcachedir "$url")"
-       local name="$(basename "$url")"
-       name=${name/%.pkg.tar.?z/.arch}
-       SRC="$cachedir/$name"
-    else
-       echo "Invalid url: $url"
-       cleanup_and_exit 1
-    fi
-
-    local destdir="$cachedir/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
-    case $destfile in
-      *.rpm)
-       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"
-       ;;
-    esac
-    mv "$destfile" "$SRC" || cleanup_and_exit 1
-    rm -rf $destdir
-}
-
-getcachedir()
-{
-    local url=$1
-    case $url in
-      zypp://*)
-       url=${url#zypp:/}
-       echo "/var/cache/zypp/packages/${url%/*}"
-       return 0;
-       ;;
-      *.pkg.tar.?z) url="arch@$url" ;;
-    esac
-    for repo in "${repos[@]}" ; do
-       if [ "${url:0:${#repo}}" == "$repo" -o "${url:0:${#repo}}" == "$repo" ] ; then
-           read repoid dummy < <(echo -n "$repo" | md5sum)
-           echo "$CACHE_DIR/$repoid"
-           break
-       fi
-    done
-}
-
-get_pkg_filename()
-{
-    local url="$1"
-    local name=$(basename $url)
-    local cachedir=$(getcachedir $url)
-    local destfile="$cachedir/$name"
-    echo $destfile
-}
-
 set_build_arch
 
 trap fail_exit EXIT
 
-if [ "$BUILD_ROOT" = / ]; then
+if test "$BUILD_ROOT" = / ; then
     browner="$(stat -c %u /)"
 fi
 
-if [ -n "$CLEAN_BUILD" ]; then
+if test -n "$CLEAN_BUILD" ; then
     clean_build_root
 fi
 
 #
 # now test if there was an incomplete run
 #
-if test -e $BUILD_IS_RUNNING ; then
-    echo It seems that there was an incomplete setup of $BUILD_ROOT.
-    echo To be sure, we will build it again completely...
+if test -e "$BUILD_IS_RUNNING" ; then
+    echo "It seems that there was an incomplete setup of $BUILD_ROOT."
+    echo "To be sure, we will build it again completely..."
     umount -n $BUILD_ROOT/proc/sys/fs/binfmt_misc 2> /dev/null || true
     umount -n $BUILD_ROOT/proc 2> /dev/null
     umount -n $BUILD_ROOT/dev/pts 2> /dev/null
@@ -626,9 +525,12 @@ if test -e $BUILD_IS_RUNNING ; then
     echo -n "[y/N/c] "
     read ANSWER
     case "$ANSWER" in
-       c|C) rm -f $BUILD_IS_RUNNING ;;
-       y|Y) clean_build_root ;;
-       *) cleanup_and_exit 1 ;;
+       c|C)
+           rm -f $BUILD_IS_RUNNING ;;
+       y|Y)
+           clean_build_root ;;
+       *)
+           cleanup_and_exit 1 ;;
     esac
 fi
 
@@ -642,13 +544,14 @@ touch $BUILD_IS_RUNNING
 if test -n "$PREPARE_VM" ; then
     rm -f $BUILD_ROOT/.build/init_buildsystem.data
 fi
+
 if test -e $BUILD_ROOT/.build/init_buildsystem.data ; then
     # vm continuation
     . $BUILD_ROOT/.build/init_buildsystem.data
     if ! test -e $BUILD_ROOT/.init_b_cache/preinstall_finished ; then
        # finish preinstall
        run_pkg_scripts
-       init_db
+       pkg_initdb
        touch $BUILD_ROOT/.init_b_cache/preinstall_finished
     fi
 else
@@ -663,7 +566,7 @@ else
        # create rpmdeps file
        #
        CACHE_FILE=$BUILD_ROOT/.srcfiles.cache
-       validate_cache_file
+       create_cache_file
 
        #
        # select and expand packages
@@ -692,29 +595,31 @@ else
     fi
 
     #
-    # register the QEMU emulator
+    # register the QEMU emulator if needed
+    # (we do not need this for the prepare step, as we do not run scripts in this case)
     #
-    if check_use_emulator; then
-           [ -n "$USE_SYSTEM_QEMU" ] && copy_qemu
-           echo "registering binfmt handlers for VM"
-
-           if [ -x "$BUILD_DIR/initvm.$BUILD_HOST_ARCH" -a -e "$BUILD_DIR/qemu-reg" ]; then
-               $BUILD_DIR/initvm.$BUILD_HOST_ARCH
-           else
-               echo "Warning: could not register binfmt handlers. Neither build-initvm nor /usr/sbin/qemu-binfmt-conf.sh exist"
-           fi
-
+    if test -z "$PREPARE_VM" ; then
+       if check_use_emulator ; then
+           copy_qemu
+           echo "registering binfmt handlers for cross build"
+           "$BUILD_DIR/$INITVM_NAME"
            echo 0 > /proc/sys/vm/mmap_min_addr
            read mmap_min_addr < /proc/sys/vm/mmap_min_addr
-           if [ "$mmap_min_addr" != 0 ]; then
-               echo "Warning: mmap_min_addr is != 0. If programs fail at mmap this could be the reason"
+           if test "$mmap_min_addr" != 0 ; then
+               echo "Warning: mmap_min_addr is != 0. If programs fail at mmap this could be the reason."
            fi
+       fi
     fi
 
+    #
+    # extract the data from the (generated) rpm list
+    #
     PACKAGES_TO_INSTALL=
     PACKAGES_TO_PREINSTALL=
     PACKAGES_TO_RUNSCRIPTS=
     PACKAGES_TO_VMINSTALL=
+    PACKAGES_TO_INSTALLONLY=
+    PACKAGES_TO_NOINSTALL=
     PREINSTALL_IMAGE=
     PREINSTALL_IMAGE_SOURCE=
     RUNSCRIPTS_SEEN=
@@ -731,6 +636,14 @@ else
            PACKAGES_TO_VMINSTALL=$SRC
            continue
        fi
+       if test "$PKG" = "installonly:" ; then
+           PACKAGES_TO_INSTALLONLY=$SRC
+           continue
+       fi
+       if test "$PKG" = "noinstall:" ; then
+           PACKAGES_TO_NOINSTALL=$SRC
+           continue
+       fi
        if test "$PKG" = "preinstallimage:" ; then
            PREINSTALL_IMAGE=${SRC##*/}
            ln -s "$SRC" "$BUILD_ROOT/.init_b_cache/rpms/${SRC##*/}"
@@ -763,7 +676,7 @@ else
            continue
        fi
        PACKAGES_TO_INSTALL="$PACKAGES_TO_INSTALL $PKG"
-       if [ "${SRC#/}" = "$SRC" ]; then
+       if test "${SRC#/}" = "$SRC" ; then
            case "$SRC" in
                zypp://* | http://* | https://* | ftp://* | ftps://*)
                    echo "$PKG $SRC" >>$BUILD_ROOT/.init_b_cache/rpmlist.download
@@ -779,32 +692,51 @@ else
        ln -s "$SRC" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.${SRCSUF##*.}"
     done < $RPMLIST
 
+    PACKAGES_TO_ALL="$PACKAGES_TO_INSTALL"
+    PACKAGES_TO_AVAILABLE="$PACKAGES_TO_INSTALL"
+
+    # subtract noinstall packages from PACKAGES_TO_INSTALL
+    if test -n "$PACKAGES_TO_NOINSTALL" ; then
+        settest=" $PACKAGES_TO_NOINSTALL "
+       PACKAGES_TO_INSTALL=
+       for PKG in $PACKAGES_TO_ALL ; do
+           test "$settest" = "${settest/ $PKG /}" && PACKAGES_TO_INSTALL="$PACKAGES_TO_INSTALL $PKG"
+       done
+    fi
+    # subtract installonly packages from PACKAGES_TO_AVAILABLE
+    if test -n "$PACKAGES_TO_INSTALLONLY" ; then
+        settest=" $PACKAGES_TO_INSTALLONLY "
+       PACKAGES_TO_AVAILABLE=
+       for PKG in $PACKAGES_TO_ALL ; do
+           test "$settest" = "${settest/ $PKG /}" && PACKAGES_TO_AVAILABLE="$PACKAGES_TO_AVAILABLE $PKG"
+       done
+    fi
+
     # check if we really can use cached versions for packages on the download list
     if test -s $BUILD_ROOT/.init_b_cache/rpmlist.download ; then
        rm -f $BUILD_ROOT/.init_b_cache/rpmlist.download2
         while read PKG SRC ; do
            cachepkg="${SRC##*/}"
            cachepkg="${cachepkg/%.pkg.tar.?z/.arch}"
-           cachedir="$(getcachedir "$SRC")"
-           if test -s "$cachedir/$cachepkg" ; then
-               if test -s "$BUILD_ROOT/.init_b_cache/rpms/$PKG.id" -a "${SRC%.rpm}" != "$SRC" ; then
-                   PKGID=`rpm -qp --qf "$RPMIDFMT" $RPMCHECKOPTS_HOST "$cachedir/$cachepkg"`
-                   read cachepkgid < $BUILD_ROOT/.init_b_cache/rpms/$PKG.id
-                   if test "$cachepkgid" = "$PKGID" ; then
-                       SRC="$cachedir/$cachepkg"
-                   else
-                       rm -f "$cachedir/$cachepkg"
-                   fi
-               else
-                   $SRC="$cachedir/$cachepkg"
+           if test "$SRC" != "${SRC#zypp://}" ; then
+               # for zypp packages also look in the zypp cache
+               cachedir="/var/cache/zypp/packages/${SRC#zypp://}"
+               cachedir="${cachedir%/*}"
+               if can_reuse_cached_package "$cachedir/$cachepkg" ; then
+                   SRCSUF=${SRC/%.pkg.tar.?z/.arch}
+                   ln -s "$cachedir/$cachepkg" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.${SRCSUF##*.}"
+                   continue
                fi
            fi
-           if test "${SRC#/}" = "$SRC" ; then
-               echo "$PKG $SRC" >>$BUILD_ROOT/.init_b_cache/rpmlist.download2
-           else
+           cachedir="$(getcachedir "$SRC")"
+           if can_reuse_cached_package "$cachedir/$cachepkg" ; then
                SRCSUF=${SRC/%.pkg.tar.?z/.arch}
-               ln -s "$SRC" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.${SRCSUF##*.}"
+               ln -s "$cachedir/$cachepkg" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.${SRCSUF##*.}"
+               continue
            fi
+           # not found in cache or cache has different package
+           rm -f "$cachedir/$cachepkg"
+           echo "$PKG $SRC" >>$BUILD_ROOT/.init_b_cache/rpmlist.download2
        done < $BUILD_ROOT/.init_b_cache/rpmlist.download
        rm -f $BUILD_ROOT/.init_b_cache/rpmlist.download
        test -s $BUILD_ROOT/.init_b_cache/rpmlist.download2 && mv $BUILD_ROOT/.init_b_cache/rpmlist.download2 $BUILD_ROOT/.init_b_cache/rpmlist.download
@@ -822,7 +754,7 @@ else
            ln -s "$SRC" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.${SRCSUF##*.}"
         done < $BUILD_ROOT/.init_b_cache/rpmlist.download
         rm -f $BUILD_ROOT/.init_b_cache/rpmlist.download
-        printf "\n"
+        echo
     fi
 
     # compatibility...
@@ -830,19 +762,8 @@ else
 
     echo "$GUESSED_DIST" > $BUILD_ROOT/.guessed_dist
     test -n "$BUILD_DIST" || BUILD_DIST="$GUESSED_DIST"
-    PSUF=`gettype --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH"`
-    case "$PSUF" in
-       UNKNOWN|'')
-           # auto detect from packages
-           if test -n "$PREINSTALL_IMAGE" ; then
-               echo "cannot autodetect build type when using a preinstall image" >&2
-               cleanup_and_exit 1
-           fi
-           PSUF=rpm
-           test -e $BUILD_ROOT/.init_b_cache/rpms/dpkg.deb && PSUF=deb
-           test -e $BUILD_ROOT/.init_b_cache/rpms/pacman.arch && PSUF=arch
-           ;;
-    esac
+
+    pkg_set_type
 
     if test -n "$PREINSTALL_IMAGE" ; then
        for PKG in $PACKAGES_FROM_PREINSTALLIMAGE ; do
@@ -854,24 +775,12 @@ else
 fi
 
 #
-# now test if there is already a build dir.
+# test if we need to preinstall
 #
-if test ! -f $BUILD_ROOT/var/lib/rpm/packages.rpm -a ! -f $BUILD_ROOT/var/lib/rpm/Packages -a ! -e $BUILD_ROOT/.build/init_buildsystem.data ; then
-    mkdir -p $BUILD_ROOT/var/lib/rpm || cleanup_and_exit 1
-    mkdir -p $BUILD_ROOT/usr/src/packages/SOURCES || cleanup_and_exit 1
+if test ! -e $BUILD_ROOT/installed-pkg -a ! -e $BUILD_ROOT/.build/init_buildsystem.data ; then
     mkdir -p $BUILD_ROOT/etc || cleanup_and_exit 1
     mkdir -p $BUILD_ROOT/proc || cleanup_and_exit 1
     test -f $BUILD_ROOT/etc/HOSTNAME || hostname -f > $BUILD_ROOT/etc/HOSTNAME
-    if test $PSUF = deb ; then
-       mkdir -p $BUILD_ROOT/var/lib/dpkg
-       mkdir -p $BUILD_ROOT/var/log
-       mkdir -p $BUILD_ROOT/etc/default
-       :> $BUILD_ROOT/var/lib/dpkg/status
-       :> $BUILD_ROOT/var/lib/dpkg/available
-       :> $BUILD_ROOT/var/log/dpkg.log
-       :> $BUILD_ROOT/etc/ld.so.conf
-       :> $BUILD_ROOT/etc/default/rcS
-    fi
     for PKG in $PACKAGES_TO_RUNSCRIPTS ; do
        : > $BUILD_ROOT/.init_b_cache/scripts/$PKG.run
     done
@@ -889,7 +798,7 @@ if test ! -f $BUILD_ROOT/var/lib/rpm/packages.rpm -a ! -f $BUILD_ROOT/var/lib/rp
        progress_step PACKAGES_TO_PREINSTALL_FILTERED
        preinstall ${PKG##*/}
     done
-    printf "\n"
+    echo
     if test -n "$PREPARE_VM" ; then
         PACKAGES_TO_VMINSTALL_FILTERED=`reorder $PACKAGES_TO_VMINSTALL_FILTERED`
        progress_setup PACKAGES_TO_VMINSTALL_FILTERED
@@ -900,21 +809,24 @@ if test ! -f $BUILD_ROOT/var/lib/rpm/packages.rpm -a ! -f $BUILD_ROOT/var/lib/rp
     fi
     # for reorder
     check_exit
-    if [ -w /root ]; then
-           test -c $BUILD_ROOT/dev/null || create_devs
+    if test -w /root ; then
+       test -c $BUILD_ROOT/dev/null || create_devs
     fi
     test -e $BUILD_ROOT/etc/fstab || touch $BUILD_ROOT/etc/fstab
     test ! -e $BUILD_ROOT/etc/ld.so.conf -a -e $BUILD_ROOT/etc/ld.so.conf.in && cp $BUILD_ROOT/etc/ld.so.conf.in $BUILD_ROOT/etc/ld.so.conf
     if test -z "$PREPARE_VM" ; then
        run_pkg_scripts
-       init_db
+       pkg_initdb
        touch $BUILD_ROOT/.init_b_cache/preinstall_finished
     fi
+    # mark as preinstalled no longer needed
+    rm -rf "$BUILD_ROOT/installed-pkg"
+    mkdir -p "$BUILD_ROOT/installed-pkg"
 fi
 
 if test -n "$PREPARE_VM" ; then
     echo "copying packages..."
-    for PKG in $PACKAGES_TO_INSTALL ; do
+    for PKG in $PACKAGES_TO_ALL ; do
        rm -f $BUILD_ROOT/.init_b_cache/$PKG.$PSUF
        cp $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF $BUILD_ROOT/.init_b_cache/$PKG.$PSUF || cleanup_and_exit 1
        ln -s -f ../$PKG.$PSUF $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF
@@ -930,11 +842,13 @@ if test -n "$PREPARE_VM" ; then
     echo "PACKAGES_TO_RUNSCRIPTS='${PACKAGES_TO_RUNSCRIPTS//"'"/$Q}'" >> $BUILD_ROOT/.build/init_buildsystem.data
     # needed for continuation in xen/kvm with rpm-x86
     echo "PACKAGES_TO_PREINSTALL='${PACKAGES_TO_PREINSTALL//"'"/$Q}'" >> $BUILD_ROOT/.build/init_buildsystem.data
+    echo "PACKAGES_TO_AVAILABLE='${PACKAGES_TO_AVAILABLE//"'"/$Q}'" >> $BUILD_ROOT/.build/init_buildsystem.data
     echo "PSUF='$PSUF'" >> $BUILD_ROOT/.build/init_buildsystem.data
     rm -f $BUILD_IS_RUNNING
     cleanup_and_exit 0
 fi
 
+
 mkdir -p $BUILD_ROOT/proc
 mkdir -p $BUILD_ROOT/dev/pts
 mount -n -tproc none $BUILD_ROOT/proc 2>/dev/null || true
@@ -947,7 +861,7 @@ rm -rf "$BUILD_ROOT/.build.binaries"
 if test -n "$CREATE_BUILD_BINARIES" ; then
     echo "creating .build.binaries directory..."
     mkdir -p "$BUILD_ROOT/.build.binaries"
-    for PKG in $PACKAGES_TO_INSTALL ; do
+    for PKG in $PACKAGES_TO_AVAILABLE ; do
        test -L "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" || continue
        LPKG=`readlink -f "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF"`
        ln "$LPKG" "$BUILD_ROOT/.build.binaries/$PKG.$PSUF" 2>/dev/null
@@ -957,18 +871,6 @@ if test -n "$CREATE_BUILD_BINARIES" ; then
     done
 fi
 
-#
-# get list and ids of already installed rpms
-#
-mkdir -p $BUILD_ROOT/.init_b_cache/alreadyinstalled
-if test -f $BUILD_ROOT/var/lib/rpm/packages.rpm -o -f $BUILD_ROOT/var/lib/rpm/Packages ; then
-    chroot $BUILD_ROOT rpm -qa --qf "%{NAME} $RPMIDFMT" | (
-       while read pp ii; do
-           echo "$ii" > "$BUILD_ROOT/.init_b_cache/alreadyinstalled/$pp"
-       done
-    )
-fi
-
 #
 # reorder packages (already done in vm continuation)
 #
@@ -979,23 +881,18 @@ if ! test -e $BUILD_ROOT/.build/init_buildsystem.data ; then
     echo 'done'
 fi
 
-rpm_e()
-{
-    chroot $BUILD_ROOT rpm --nodeps -e $PKG 2>&1 | \
-    while read line; do
-       case "$line" in
-
-           r*failed:\ No\ such\ file\ or\ directory) ;;
-           error:\ failed\ to\ stat\ *:\ No\ such\ file\ or\ directory) ;;
-           error:\ *scriptlet\ failed*)
-               echo "$line"
-               echo "re-try deleting $PKG using --noscripts"
-               chroot $BUILD_ROOT rpm --nodeps --noscripts -e $PKG || true
-           ;;
-           *) echo "$line" ;;
-       esac
+#
+# get list and ids of already installed packages
+#
+mkdir -p $BUILD_ROOT/.init_b_cache/alreadyinstalled
+listinstalled --root "$BUILD_ROOT" --type "$PSUF" --extraname | (
+    while read id name buildid; do
+       echo "$buildid" > "$BUILD_ROOT/.init_b_cache/alreadyinstalled/$name"
     done
-}
+)
+
+# do pre-installation work
+pkg_prepare
 
 #
 # delete all packages we don't want
@@ -1014,7 +911,7 @@ if [ -z "$KEEP_PACKS" ]; then
         PKG=${PKG##*/}
         test "$PKG" = "*" && continue
         echo "deleting $PKG"
-        rpm_e "$PKG"
+        pkg_erase
         check_exit
     done
     rm -rf "$BUILD_ROOT/.init_b_cache/todelete"
@@ -1029,70 +926,14 @@ done
 rm -rf "$BUILD_ROOT/installed-pkg"
 mkdir -p "$BUILD_ROOT/installed-pkg"
 
-RPMCHECKOPTS=
-RPMCHECKOPTS_HOST=
-# on Fedora 10 rpmbuild is in a separate package so we need something else to
-# detect rpm4
-test -x $BUILD_ROOT/usr/bin/rpmquery && RPMCHECKOPTS="--nodigest --nosignature"
-test -x /usr/bin/rpmquery && RPMCHECKOPTS_HOST="--nodigest --nosignature"
-
 test -x $BUILD_ROOT/sbin/ldconfig && chroot $BUILD_ROOT /sbin/ldconfig 2>&1
 
-typeset -ri suse_version=$(chroot $BUILD_ROOT rpm --eval '%{?suse_version}' 2>/dev/null)
-typeset -i num cumulate=-1
-typeset -a CUMULATED_LIST=()
-typeset -a CUMULATED_PIDS=()
-typeset -a CUMULATED_HMD5=()
-
-DO_CUMULATE=
-if ((suse_version > 1220)) ; then
-    DO_CUMULATE=true
-fi
-
 MAIN_LIST="$PACKAGES_TO_INSTALL"
-test -n "$DO_CUMULATE" && MAIN_LIST="$MAIN_LIST CUMULATED"
 progress_setup MAIN_LIST
-for PKG in $MAIN_LIST; do
+for PKG in $MAIN_LIST ; do
     test -f $BUILD_ROOT/installed-pkg/$PKG && continue
     progress_step MAIN_LIST
 
-    case $PKG in
-    CUMULATED)
-       #
-       # Use the features of rpm which are reordering the list of packages to
-       # satisfy dependencies and the final execution of the %posttrans scriplets
-       #
-       echo "now installing cumulated packages"
-       ((cumulate < 0)) && continue
-       exec 4>$BUILD_ROOT/.init_b_cache/manifest
-       for ((num=0; num<=cumulate; num++)) ; do
-           echo ${CUMULATED_LIST[$num]} 1>&4
-           PKG=${CUMULATED_LIST[$num]##*/}
-           test "$BUILD_ROOT/.init_b_cache/rpms/$PKG" -ef "$BUILD_ROOT/${CUMULATED_LIST[$num]}" && continue
-           rm -f $BUILD_ROOT/${CUMULATED_LIST[$num]}
-           cp $BUILD_ROOT/.init_b_cache/rpms/$PKG $BUILD_ROOT/${CUMULATED_LIST[$num]} || cleanup_and_exit 1
-       done
-       exec 4>&-
-       chroot $BUILD_ROOT rpm --ignorearch --nodeps -Uh --oldpackage --ignoresize --verbose $RPMCHECKOPTS \
-               $ADDITIONAL_PARAMS .init_b_cache/manifest 2>&1 || touch $BUILD_ROOT/exit 
-       for ((num=0; num<=cumulate; num++)) ; do
-           rm -f $BUILD_ROOT/${CUMULATED_LIST[$num]}
-       done
-       rm -f .init_b_cache/manifest
-       check_exit
-       for ((num=0; num<=cumulate; num++)) ; do
-           PKG=${CUMULATED_LIST[$num]##*/}
-           echo "${CUMULATED_PIDS[$num]}" > $BUILD_ROOT/installed-pkg/${PKG%.rpm}
-           test -n "${CUMULATED_HMD5[$num]}" || continue
-           echo "${CUMULATED_HMD5[$num]} ${CUMULATED_PIDS[$num]}" > $BUILD_ROOT/.preinstall_image/${PKG%.rpm}
-       done
-       CUMULATED_LIST=()
-       CUMULATED_PIDS=()
-       CUMULATED_HMD5=()
-       let cumulate=-1
-       continue
-       ;;
-    esac
     if test -e "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" -a ! -s "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" ; then
        # preinstallimage package, make sure it's in the image
        if ! test -e $BUILD_ROOT/.preinstall_image/$PKG ; then
@@ -1104,152 +945,84 @@ for PKG in $MAIN_LIST; do
        echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG
        continue
     fi
-    PKG_HDRMD5=
-    if test -d $BUILD_ROOT/.preinstall_image ; then
-       if ! test -e $BUILD_ROOT/.preinstall_image/$PKG ; then
-           PKG_HDRMD5=`perl -I$BUILD_DIR -MBuild -e 'print Build::queryhdrmd5($ARGV[0])' $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF`
-           test -n "$PKG_HDRMD5" || cleanup_and_exit 1
-       fi
-    fi
-    test -L $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF || continue
 
-    if test $PSUF = deb ; then
-       # debian world, install deb files
-       if ! test "$BUILD_ROOT/.init_b_cache/rpms/$PKG.deb" -ef "$BUILD_ROOT/.init_b_cache/$PKG.deb" ; then
-           rm -f $BUILD_ROOT/.init_b_cache/$PKG.deb
-           cp $BUILD_ROOT/.init_b_cache/rpms/$PKG.deb $BUILD_ROOT/.init_b_cache/$PKG.deb || cleanup_and_exit 1
-       fi
-       PKGID=`readlink $BUILD_ROOT/.init_b_cache/rpms/$PKG.deb`
-       PKGID="${PKGID##*/}"
-       PKGID="${PKGID%.deb} debian"
-       echo "installing ${PKGID%% *}"
-       ( chroot $BUILD_ROOT dpkg --install --force all .init_b_cache/$PKG.deb 2>&1 || touch $BUILD_ROOT/exit ) | \
-           perl -ne '$|=1;/^(Configuration file|Installing new config file|Selecting previously deselected|\(Reading database|Unpacking |Setting up|Creating config file|Preparing to replace dpkg)/||/^$/||print'
-       check_exit
-       echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG
-       test -n "$PKG_HDRMD5" && echo "$PKG_HDRMD5 $PKGID" > $BUILD_ROOT/.preinstall_image/$PKG
-        # ugly workaround for upstart system. some packages (procps) try
-        # to start a service in their configure phase. As we don't have
-        # a running upstart, we just link the start binary to /bin/true
-       if test -e "$BUILD_ROOT/sbin/start"; then
-           if test "$BUILD_ROOT/sbin/start" -ef "$BUILD_ROOT/sbin/initctl" ; then
-               echo "linking /sbin/start to /bin/true"
-               mv "$BUILD_ROOT/sbin/start" "$BUILD_ROOT/sbin/start.disabled"
-               ln -s "/bin/true" "$BUILD_ROOT/sbin/start"
-           fi
-       fi
-       # another workaround, see bug bnc#733699
-       rm -f "$BUILD_ROOT/var/run/init.upgraded"
-       continue
+    # get the hdrmd5 if we want to create a preinstall image
+    PKG_HDRMD5=
+    if test -d $BUILD_ROOT/.preinstall_image -a ! -e $BUILD_ROOT/.preinstall_image/$PKG ; then
+       PKG_HDRMD5=`perl -I$BUILD_DIR -MBuild -e 'print Build::queryhdrmd5($ARGV[0])' $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF`
+       test -n "$PKG_HDRMD5" || cleanup_and_exit 1
     fi
 
-    if test $PSUF = arch ; then
-       if ! test "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" -ef "$BUILD_ROOT/.init_b_cache/$PKG.$PSUF" ; then 
-           rm -f $BUILD_ROOT/.init_b_cache/$PKG.$PSUF
-           cp $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF $BUILD_ROOT/.init_b_cache/$PKG.$PSUF || cleanup_and_exit 1
-       fi
-       PKGID=`readlink $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF`
-       PKGID="${PKGID##*/}"
-       PKGID="${PKGID/%.pkg.tar.?z/.arch}"
-       PKGID="${PKGID%.arch} arch"
-       echo "installing ${PKGID%% *}"
-       # -d -d disables deps checking
-       ( chroot $BUILD_ROOT pacman -U --force -d -d --noconfirm .init_b_cache/$PKG.$PSUF 2>&1 || touch $BUILD_ROOT/exit ) | \
-           perl -ne '$|=1;/^(warning: could not get filesystem information for |loading packages|looking for inter-conflicts|Targets |Total Installed Size: |Net Upgrade Size: |Proceed with installation|checking package integrity|loading package files|checking available disk space|installing |upgrading |warning:.*is up to date -- reinstalling|Optional dependencies for|    )/||/^$/||print'
-       check_exit
-       echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG
-       test -n "$PKG_HDRMD5" && echo "$PKG_HDRMD5 $PKGID" > $BUILD_ROOT/.preinstall_image/$PKG
-       continue
-    fi
+    test -L $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF || continue
 
-    if test -f $BUILD_ROOT/.init_b_cache/rpms/$PKG.id -a -f $BUILD_ROOT/.init_b_cache/alreadyinstalled/$PKG ; then
+    # check if we can keep an already installed package
+    if test "$VERIFY_BUILD_SYSTEM" != true -a -f $BUILD_ROOT/.init_b_cache/rpms/$PKG.id -a -f $BUILD_ROOT/.init_b_cache/alreadyinstalled/$PKG ; then
        read PKGID < $BUILD_ROOT/.init_b_cache/rpms/$PKG.id
        read OLDPKGID < $BUILD_ROOT/.init_b_cache/alreadyinstalled/$PKG
        if test "$PKGID" = "$OLDPKGID" ; then
            #echo "keeping ${PKGID%% *}"
+           rm -f $BUILD_ROOT/.init_b_cache/$PKG.$PSUF
            echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG
            test -n "$PKG_HDRMD5" && echo "$PKG_HDRMD5 $PKGID" > $BUILD_ROOT/.preinstall_image/$PKG
            continue
        fi
     fi
 
-    PKGID=`rpm -qp --qf "$RPMIDFMT" $RPMCHECKOPTS_HOST $BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm`
+    PKGID=$(perl -I$BUILD_DIR -MBuild -e Build::showquery "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" buildid)
 
     if test -f $BUILD_ROOT/.init_b_cache/alreadyinstalled/$PKG ; then
        read OLDPKGID < $BUILD_ROOT/.init_b_cache/alreadyinstalled/$PKG
        if test "$PKGID" != "$OLDPKGID" ; then
-           echo deleting unwanted ${OLDPKGID%% *}
-           rpm_e "$PKG"
-       elif test "$VERIFY_BUILD_SYSTEM" = true ; then
-           chroot $BUILD_ROOT rpm --verify $PKG 2>&1 | tee $TMPFILE
-           if grep ^missing $TMPFILE > /dev/null ; then
-               echo deleting incomplete ${PKGID%% *}
-               rpm_e "$PKG"
-           else
+           echo "deleting unwanted ${OLDPKGID%% *}"
+           pkg_erase
+       else
+           if test "$VERIFY_BUILD_SYSTEM" != true || pkg_verify_installed ; then
                #echo "keeping ${PKGID%% *}"
                echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG
                test -n "$PKG_HDRMD5" && echo "$PKG_HDRMD5 $PKGID" > $BUILD_ROOT/.preinstall_image/$PKG
                continue
            fi
-       else
-           #echo "keeping ${PKGID%% *}"
-           echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG
-           test -n "$PKG_HDRMD5" && echo "$PKG_HDRMD5 $PKGID" > $BUILD_ROOT/.preinstall_image/$PKG
-           continue
+           echo "deleting incomplete ${OLDPKGID%% *}"
+           pkg_erase
        fi
        if test -e "$BUILD_ROOT/.init_b_cache/preinstalls/$PKG" ; then
            preinstall "$PKG"
-           # call for rpm-4.x and not rpm-devel
-           test -z "${PKG##rpm-[0-9]*}" && chroot $BUILD_ROOT rpm --rebuilddb
-           # also exec for exchanged rpm !  naming is rpm-x86-<target>-<ver>
-           test -z "${PKG##rpm-x86-*[0-9]*}" && chroot $BUILD_ROOT rpm --rebuilddb
        fi
+       check_exit
     fi
+    
     export ADDITIONAL_PARAMS=
     if test "$USE_FORCE" = true ; then
        export ADDITIONAL_PARAMS="$ADDITIONAL_PARAMS --force"
     fi
-    # FIXME: work around for cross-build installs, we must not overwrite the running rpm
+    # work around for cross-build installs, we must not overwrite the running rpm
     if test "$PKG" = rpm ; then
        for i in $BUILD_ROOT/.init_b_cache/preinstalls/rpm-x86-* ; do
            test -e "$i" && ADDITIONAL_PARAMS="$ADDITIONAL_PARAMS --justdb"
        done
     fi
-    if test -n "$DO_CUMULATE" -a "$ADDITIONAL_PARAMS" = "${ADDITIONAL_PARAMS%--justdb}"; then
+    
+    if pkg_cumulate ; then
        echo "cumulate ${PKGID%% *}"
-       let cumulate++
-       CUMULATED_LIST[$cumulate]=".init_b_cache/$PKG.rpm"
-       CUMULATED_PIDS[$cumulate]="$PKGID"
-       CUMULATED_HMD5[$cumulate]="$PKG_HDRMD5"
        continue
     fi
+    
+    # install the package
     echo "installing ${PKGID%% *}"
-    if ! test "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" -ef "$BUILD_ROOT/.init_b_cache/$PKG.rpm" ; then
-       rm -f $BUILD_ROOT/.init_b_cache/$PKG.rpm
-       cp $BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm $BUILD_ROOT/.init_b_cache/$PKG.rpm || cleanup_and_exit 1
+    if ! test "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" -ef "$BUILD_ROOT/.init_b_cache/$PKG.$PSUF" ; then
+       rm -f $BUILD_ROOT/.init_b_cache/$PKG.$PSUF
+       cp $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF $BUILD_ROOT/.init_b_cache/$PKG.$PSUF || cleanup_and_exit 1
     fi
-    ( chroot $BUILD_ROOT rpm --ignorearch --nodeps -U --oldpackage --ignoresize $RPMCHECKOPTS \
-               $ADDITIONAL_PARAMS .init_b_cache/$PKG.rpm 2>&1 || \
-         touch $BUILD_ROOT/exit ) | \
-             grep -v "^warning:.*saved as.*rpmorig$"
-    # delete link so package is only installed once
-    rm -f $BUILD_ROOT/.init_b_cache/$PKG.rpm
+    pkg_install
     check_exit
+    rm -f $BUILD_ROOT/.init_b_cache/$PKG.$PSUF
     echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG
     test -n "$PKG_HDRMD5" && echo "$PKG_HDRMD5 $PKGID" > $BUILD_ROOT/.preinstall_image/$PKG
 
 done
 
-if test $PSUF = deb ; then
-    echo "configuring all installed packages..."
-    # configure all packages after complete installation, not for each package like rpm does
-    # We need to run this twice, because of cyclic dependencies as it does not succeed on most
-    # debian based distros in the first attempt.
-    if ! chroot $BUILD_ROOT dpkg --configure --pending  2>&1; then
-       echo "first configure attempt failed, trying again..."
-       chroot $BUILD_ROOT dpkg --configure --pending  2>&1 || touch $BUILD_ROOT/exit
-    fi
-fi
+# do post-installation work
+pkg_finalize
 
 # devices can vanish if devs got uninstalled
 test -c $BUILD_ROOT/dev/null || create_devs
@@ -1263,74 +1036,23 @@ rm -f $BUILD_ROOT/etc/mtab
 cp /proc/mounts $BUILD_ROOT/etc/mtab
 chmod 644 $BUILD_ROOT/etc/mtab
 
-#
-# to be sure, path is set correctly, we have to source /etc/profile before
-# starting rpm.
-#
-# XXX
-#rm -f $BUILD_ROOT/bin/rpm.sh
-#cp $BUILD_LIBDIR/lib/rpm.sh $BUILD_ROOT/bin/rpm.sh
-#chmod 755 $BUILD_ROOT/bin/rpm.sh
-#test -f $BUILD_ROOT/bin/rpm -a ! -L $BUILD_ROOT/bin/rpm && \
-#    mv $BUILD_ROOT/bin/rpm $BUILD_ROOT/bin/rpm.bin
-#rm -f $BUILD_ROOT/bin/rpm
-#ln -s rpm.sh $BUILD_ROOT/bin/rpm
-
-#
-# some packages use uname -r to decide which kernel is used to build for.
-# this does not work in autobuild always.  Here is a wrapper script, that
-# gets Version from kernel sources.
-#
-# XXX
-#rm -f $BUILD_ROOT/bin/uname.sh
-#cp -v $BUILD_LIBDIR/lib/uname.sh $BUILD_ROOT/bin/uname.sh
-#chmod 755 $BUILD_ROOT/bin/uname.sh
-#test -f $BUILD_ROOT/bin/uname -a ! -L $BUILD_ROOT/bin/uname && \
-#    mv $BUILD_ROOT/bin/uname $BUILD_ROOT/bin/uname.bin
-#rm -f $BUILD_ROOT/bin/uname
-#ln -s uname.sh $BUILD_ROOT/bin/uname
-
-#
-# some distributions have a /etc/rpmrc or /etc/rpm/macros and some not.
-# make sure, that it is setup correctly.
-#
-# XXX
-#rm -f $BUILD_ROOT/etc/rpmrc
-#if test -e $BUILD_LIBDIR/lib/rpmrc.$BUILD_BASENAME ; then
-#    cp -v $BUILD_LIBDIR/lib/rpmrc.$BUILD_BASENAME $BUILD_ROOT/etc/rpmrc
-#elif test -e $BUILD_LIBDIR/lib/rpmrc ; then
-#    cp -v $BUILD_LIBDIR/lib/rpmrc $BUILD_ROOT/etc/rpmrc
-#fi
-
-# XXX
-#rm -f $BUILD_ROOT/etc/rpm/macros $BUILD_ROOT/etc/rpm/suse_macros
-#mkdir -p $BUILD_ROOT/etc/rpm
-#if test -e $BUILD_LIBDIR/lib/macros.$BUILD_BASENAME ; then
-#    cp -v $BUILD_LIBDIR/lib/macros.$BUILD_BASENAME $BUILD_ROOT/etc/rpm/macros
-#    cp -v $BUILD_LIBDIR/lib/macros.$BUILD_BASENAME $BUILD_ROOT/etc/rpm/suse_macros
-#elif test -e $BUILD_LIBDIR/lib/macros ; then
-#    cp -v $BUILD_LIBDIR/lib/macros $BUILD_ROOT/etc/rpm/macros
-#    cp -v $BUILD_LIBDIR/lib/macros $BUILD_ROOT/etc/rpm/suse_macros
-#fi
-
 #
 # make sure, that our nis is not present in the chroot system
 #
 test -e $BUILD_ROOT/etc/nsswitch.conf && {
-    echo removing nis flags from $BUILD_ROOT/etc/nsswitch.conf...
-    cat $BUILD_ROOT/etc/nsswitch.conf | sed -e"s:nis::g" > \
-       $BUILD_ROOT/etc/nsswitch.conf.tmp
+    echo "removing nis flags from $BUILD_ROOT/etc/nsswitch.conf..."
+    cat $BUILD_ROOT/etc/nsswitch.conf | sed -e"s:nis::g" > $BUILD_ROOT/etc/nsswitch.conf.tmp
     mv $BUILD_ROOT/etc/nsswitch.conf.tmp $BUILD_ROOT/etc/nsswitch.conf
 }
 
 #
-# creating some default directories
+# create some default directories and files
+#
 for DIR in /usr/share/doc/packages \
           /usr/X11R6/include/X11/pixmaps \
           /usr/X11R6/include/X11/bitmaps ; do
     mkdir -p $BUILD_ROOT/$DIR
 done
-
 for FILE in /var/run/utmp /var/log/wtmp /etc/fstab ; do
     mkdir -p $BUILD_ROOT/${FILE%/*}
     touch $BUILD_ROOT/$FILE
@@ -1341,24 +1063,26 @@ if test -x $BUILD_ROOT/sbin/ldconfig ; then
        CHROOT_RETURN="`chroot $BUILD_ROOT /sbin/ldconfig 2>&1`"
        case "$CHROOT_RETURN" in
            *warning:*)
-             chroot $BUILD_ROOT /sbin/ldconfig
-             echo
-             echo chroot $BUILD_ROOT /sbin/ldconfig
-             echo
-             echo "$CHROOT_RETURN"
-             echo
-             echo "Problem with ldconfig.  It's better to reinit the build system..."
-             echo
-             cleanup_and_exit 1
-           ;;
+               chroot $BUILD_ROOT /sbin/ldconfig
+               echo
+               echo chroot $BUILD_ROOT /sbin/ldconfig
+               echo
+               echo "$CHROOT_RETURN"
+               echo
+               echo "Problem with ldconfig.  It's better to reinit the build system..."
+               echo
+               cleanup_and_exit 1
+               ;;
        esac
 fi
-if test -x $BUILD_ROOT/usr/sbin/Check && ! grep -q "/usr/sbin/Check is obsolete" $BUILD_ROOT/usr/sbin/Check; then
-  chroot $BUILD_ROOT /usr/sbin/Check
+
+if test -x $BUILD_ROOT/usr/sbin/Check && ! grep -q "/usr/sbin/Check is obsolete" $BUILD_ROOT/usr/sbin/Check ; then
+    chroot $BUILD_ROOT /usr/sbin/Check
 fi
 
 mkdir -p $BUILD_ROOT/var/adm/packages
 touch $BUILD_ROOT/var/adm/packages
+
 if test -x $BUILD_ROOT/sbin/SuSEconfig ; then
     if grep norestarts $BUILD_ROOT/sbin/SuSEconfig > /dev/null ; then
        chroot $BUILD_ROOT /sbin/SuSEconfig --norestarts --force
@@ -1378,7 +1102,7 @@ done
 
 if test -e $BUILD_ROOT/usr/share/zoneinfo/UTC ; then
     for PROG in /usr/sbin/zic /usr/bin/zic /bin/zic /sbin/zic ; do
-        test -x $BUILD_ROOT/$PROG  && chroot $BUILD_ROOT $PROG -l UTC
+        test -x $BUILD_ROOT/$PROG  && chroot $BUILD_ROOT bash -c "$PROG -l $(readlink -f /usr/share/zoneinfo/UTC)"
     done
 fi
 
@@ -1392,26 +1116,17 @@ if ! grep -F "127.0.0.1 $HOST" $BUILD_ROOT/etc/hosts > /dev/null ; then
     mv $BUILD_ROOT/etc/hosts.new $BUILD_ROOT/etc/hosts
 fi
 
+# XXX: still needed?
 if test -x $BUILD_ROOT/bin/rpm -a ! -f $BUILD_ROOT/var/lib/rpm/packages.rpm -a ! -f $BUILD_ROOT/var/lib/rpm/Packages ; then
-    echo "initializing rpm db..."
-    if [ -x $BUILD_ROOT/usr/bin/rpmdb ]; then
-      chroot $BUILD_ROOT /usr/bin/rpmdb --initdb || cleanup_and_exit 1
-    else
-      chroot $BUILD_ROOT rpm --initdb || cleanup_and_exit 1
-    fi
-    # create provides index
-    chroot $BUILD_ROOT rpm -q --whatprovides rpm >/dev/null 2>&1
+    pkg_initdb_rpm
+    chroot $BUILD_ROOT rpm -q --whatprovides rpm >/dev/null 2>&1       # create provides index
 fi
 
-# create modules.dep in kvm/xen
-# This can not work, until we use the native repository kernel
-#if [ $BUILD_ROOT = "/" -a -x /sbin/depmod ]; then
-#  /sbin/depmod -a
-#fi
-
 rm -f $BUILD_ROOT/.rpmmacros $BUILD_ROOT/root/.rpmmacros
 rm -rf "$BUILD_ROOT/.init_b_cache"
 rm -f $BUILD_IS_RUNNING
 rm -f $TMPFILE
 
 cleanup_and_exit 0
+
+# vim: set tabstop=8 softtabstop=4 shiftwidth=4 noexpandtab:
index d7fb40569fea3d2740d6362970a298adfbb7ec4f..241cf41468b948722d12f8060239828b7dc60ea9 100644 (file)
--- a/initvm.c
+++ b/initvm.c
  *             build script to execute once binfmts are set up
  *
  * AUTHOR
- *     James Perkins <james.perkins@linuxfoundation.org>
+ *      Copyright (c) 2012 James Perkins <james.perkins@linuxfoundation.org>
+ *     i                  Adrian Schroeter <adrian@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
 #include <sys/mount.h>
@@ -177,7 +192,7 @@ enum okfail binfmt_register(char *datafile, char *regfile)
 
                if (buf[0] != ':')      /* non-data input line */
                {
-                       goto skip;
+                       continue;
                }
 
                /* copy buf and tokenize :-seperated fields into f[] */
@@ -200,21 +215,41 @@ enum okfail binfmt_register(char *datafile, char *regfile)
                {
                        fprintf(stderr, "%s: line %d: extra fields, ignoring."
                                " Content: %s", datafile, line, buf);
-                       goto skip;
+                       continue;
                }
 
                if (n < n_fields)
                {
                        fprintf(stderr, "%s: line %d: missing fields, ignoring."
                                " Content: %s", datafile, line, buf);
-                       goto skip;
+                       continue;
                }
 
+               int ret;
+                /* Is an interpreter for this arch already registered? */
+               snprintf(path, sizeof(path), SYSFS_BINFMT_MISC "/%s", f[name]);
+               ret=access(path, X_OK);
+                       fprintf(stderr, 
+                               "interpreter for '%s' is %d\n",
+                               f[name], ret);
+               if (ret == 0) {
+#ifdef DEBUG
+                       fprintf(stderr, 
+                               "interpreter for '%s' already registered, ignoring\n",
+                               f[name]);
+#endif /* DEBUG */
+                       continue;
+               }
 
-               if (access(f[interpreter], X_OK) != 0) {
-                       fprintf(stderr,
-                               "warning: %s: line %d: interpreter '%s' not "
-                               "found\n", datafile, line, f[interpreter]);
+                /* Does the interpreter exists? */
+               ret=access(f[interpreter], X_OK);
+               if (ret != 0) {
+#ifdef DEBUG
+                       fprintf(stderr, 
+                               "%s: line %d: interpreter '%s' not found,"
+                               " ignoring, return %d\n", datafile, line, f[interpreter], ret);
+#endif /* DEBUG */
+                       continue;
                }
 
                if (!write_file_string(regfile, buf)) {
@@ -237,9 +272,6 @@ enum okfail binfmt_register(char *datafile, char *regfile)
 
                DBG(fprintf(stderr, "dumping: %s\n", path));
                DBG(dump_file(path));
-
-skip:
-               ;
        }
 
 
@@ -326,7 +358,7 @@ int main(int argc, char* argv[], char* env[])
                        exit(1);
                }
                execve(BUILD, args, env);
-               perror("execve");
+               perror("execve of "BUILD);
                exit(1);
        }
 
index 2b71f6c614884b56a3c6e0058e5211a4c679c949..330b7c76d5d0c3945893697de3e6f4045f6bc5ab 100755 (executable)
@@ -1,5 +1,25 @@
 #!/usr/bin/perl
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 my $sig = 15;
 my $verbose = 0;
 my $msg = '';
diff --git a/listinstalled b/listinstalled
new file mode 100755 (executable)
index 0000000..aa09eac
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/perl -w
+
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+BEGIN {
+  unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
+}
+
+use Getopt::Long;
+use Build;
+
+use strict;
+
+Getopt::Long::Configure("no_ignore_case");
+
+my $opt_root;
+my $opt_type;
+my $opt_extraname;
+
+GetOptions ("root=s" => \$opt_root, "type=s" => \$opt_type, "extraname" => \$opt_extraname) or exit(1);
+
+$opt_type ||= 'rpm';
+
+my $ql = Build::queryinstalled($opt_type, $opt_root);
+die("cannot get list of installed packages for type $opt_type\n") unless $ql;
+
+for my $q (@$ql) {
+  next unless defined($q->{'name'}) && defined($q->{'arch'});
+  next if $q->{'arch'} eq 'src' || $q->{'arch'} eq 'nosrc';
+  my $id = "$q->{'name'}.$q->{'arch'}-0/0/0: ";
+  my $evr = $q->{'version'};
+  $evr = "$q->{'epoch'}:$evr" if $q->{'epoch'};
+  $evr .= "-$q->{'release'}" if defined $q->{'release'};
+  my $buildtime = $q->{'buildtime'} || 0;
+  if ($opt_extraname) {
+    print "I:$id$q->{'name'} $q->{'name'}-$evr $buildtime-$q->{'arch'}\n";
+  } else {
+    print "I:$id$q->{'name'}-$evr $buildtime-$q->{'arch'}\n";
+  }
+}
+
diff --git a/livebuild_pre_run.template b/livebuild_pre_run.template
new file mode 100755 (executable)
index 0000000..679220c
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/bash
+#
+# This is a template for a livebuild_pre_run script. These scripts are
+# executed by build_livebuild.sh in the chroot environment.
+#
+
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+fix_debootstrap()
+{
+    # debootstrap in Debian 7.0 does not like dash
+
+    if [ -x /usr/sbin/debootstrap ] ; then
+       sed -i 's|^#!/bin/sh|#!/bin/bash|' /usr/sbin/debootstrap
+    fi
+}
+
+fix_lb_bootstrap_archive-keys()
+{
+    if [ -e /usr/lib/live/build/bootstrap_archive-keys ] ; then
+       sed -i '/apt-get update/{ s/^/#/ }' \
+           /usr/lib/live/build/bootstrap_archive-keys
+    fi
+}
+
+#
+# main
+#
+
+: ${TOPDIR:=/usr/src/packages}
+
+# Distribution and live-build specific hooks
+fix_debootstrap
+fix_lb_bootstrap_archive-keys
+
+# Expand configuration based on defaults
+cd $TOPDIR/LIVEBUILD_ROOT && lb config || exit 1
+
+# Replace all occurances of LB_MIRROR with local repository
+sed -i "s|^\(LB_MIRROR_[^=]\+=\).*|\1\"file:$TOPDIR/SOURCES/repos/\"|" \
+    $TOPDIR/LIVEBUILD_ROOT/config/bootstrap
+sed -i "s|^\(LB_PARENT_MIRROR_[^=]\+=\).*|\1\"file:$TOPDIR/SOURCES/repos/\"|" \
+    $TOPDIR/LIVEBUILD_ROOT/config/bootstrap
+
+# Prevent debootstrap from cleaning our cache
+sed -i 's|^\(LB_CACHE_PACKAGES=\).*|\1"false"|' \
+    $TOPDIR/LIVEBUILD_ROOT/config/common
+
+# Disable GPG checking
+sed -i 's|^\(LB_APT_SECURE=\).*|\1"false"|' \
+    $TOPDIR/LIVEBUILD_ROOT/config/common
index 1446ff0f16da5ad5626220dd5f6c3affaf7789bb..33bcee38a4d138b218f2a54702f1bd3ca802b352 100755 (executable)
@@ -1,5 +1,25 @@
 #!/usr/bin/perl -w
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 use POSIX;
 use strict;
 use File::Temp qw/tempfile tempdir/;
@@ -529,8 +549,8 @@ sub handle_rpms {
   $arch = $res{'ARCH'}->[0];
   my @targets = get_targets($arch, $config);
   if (!@targets) {
-    print "no targets for arch $arch, nothing to do\n";
-    exit(0);
+    print "no targets for arch $arch, skipping $rname\n";
+    next;
   }
   for my $target (@targets) {
 
@@ -637,6 +657,7 @@ sub handle_rpms {
        delete $alldirs{"$prefix$fn"};
       }
     }
+    delete $alldirs{$_} for keys %symlinks;
     $ad = $prefix;
     delete $alldirs{$ad};
     delete $alldirs{$ad} while $ad =~ s/\/[^\/]+$//;
@@ -965,8 +986,8 @@ sub handle_debs {
     # line and get a list of target_arch-es
     my @targets = get_targets($arch, $config);
     if (!@targets) {
-      print "no targets for arch $arch, nothing to do\n";
-      return; # there may be more debs to handle
+      print "no targets for arch $arch, skipping $d_name\n";
+      next; # there may be more debs to handle
     }
 
     for my $target (@targets) {
diff --git a/mkdrpms b/mkdrpms
index b3c13b3f41eed87c9b2e5d05fc0716fdc13ffb1d..a6ba7309b113908a9abb8aa571eeca34c0c4722b 100755 (executable)
--- a/mkdrpms
+++ b/mkdrpms
@@ -1,5 +1,25 @@
 #!/usr/bin/perl -w
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 BEGIN {
   unshift @INC, '/usr/lib/build';
   unshift @INC, $::ENV{'BUILD_DIR'} if $::ENV{'BUILD_DIR'};
diff --git a/order b/order
index 6682fd6d74b21a92357bf981807c6dbaa9f6c601..a3c9d8e71994cec4facf4e0c2e675995d46b8d41 100755 (executable)
--- a/order
+++ b/order
@@ -1,5 +1,25 @@
 #!/usr/bin/perl -w
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 BEGIN {
   unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
 }
@@ -9,6 +29,7 @@ use strict;
 
 my ($dist, $archs, $configdir, $manifest);
 
+$configdir = ($::ENV{'BUILD_DIR'} || '/usr/lib/build') . '/configs';
 
 while (@ARGV)  {
   if ($ARGV[0] eq '--dist') {
@@ -65,7 +86,7 @@ for my $p (@p) {
       $q = {'provides' => [], 'requires' => []}; # package from preinstallimage, no need to order
       last;
     }
-    $q = Build::query("$cachedir/$p.$suf", 'filelist' => 1, 'alldeps' => 1);
+    $q = Build::query("$cachedir/$p.$suf", 'filelist' => 1, 'alldeps' => 1, 'addselfprovides' => 1, 'normalizedeps' => 1);
     die("bad binary: $p.$suf\n") unless $q;
     push @{$q->{'provides'}}, @{$q->{'filelist'}} if $suf eq 'rpm' && $q->{'filelist'};
     delete $q->{'filelist'};
index 0aa9f488a00730e574c6c2ddb6eff9f04c5e7450..5824f7b46906664f6483364cf37d1adcf4ddeada 100644 (file)
 Name:           build
 Summary:        A Script to Build SUSE Linux RPMs
 License:        GPL-2.0+ and GPL-2.0
+Epoch:          1
 Group:          Development/Tools/Building
 Epoch:          1
 %if 0%{?suse_version} >= 1230
-Version:        20150115
+Version:        20150115 
 %else
-Version:        2015.01.15
+Version:        20150115
 %else
 %endif
 Release:        3.1
@@ -72,7 +73,7 @@ Requires:       build-mkbaselibs
 %if 0%{?suse_version} > 1120 || 0%{?mdkversion}
 Recommends:     build-mkdrpms
 %endif
-Provides:   tizen-build = 20160315
+Provides:   tizen-build = 20160311
 %description
 This package provides a script for building RPMs for SUSE Linux in a
 chroot environment.
@@ -116,7 +117,7 @@ Group:          Development/Tools/Building
 Requires:       build
 BuildRequires:  gcc
 BuildRequires:  glibc-devel
-Provides:       tizen-build-initvm-%{initvm_arch} = 20160315
+Provides:       tizen-build-initvm-%{initvm_arch} = 20160311
 Obsoletes:      build-initvm
 %if 0%{?suse_version}
 BuildRequires:  glibc-devel-static
@@ -134,6 +135,7 @@ chroot or a secure virtualized
 %build
 # initvm
 make CFLAGS="$RPM_BUILD_FLAGS" initvm-all
+
 %if 0%{?fedora} == 23
 cp -f find-debuginfo.sh /usr/lib/rpm/find-debuginfo.sh
 %endif
@@ -167,6 +169,8 @@ test -e default.conf
 /usr/lib/build
 %config(noreplace) /usr/lib/build/emulator/emulator.sh
 %{_mandir}/man1/build.1*
+%{_mandir}/man1/unrpm.1*
+%{_mandir}/man1/vc.1*
 %exclude /usr/lib/build/initvm.*
 
 %if 0%{?suse_version} > 1120 || ! 0%{?suse_version}
@@ -191,6 +195,8 @@ test -e default.conf
 /usr/lib/build/initvm.*
 
 %changelog
+* Mon Feb 29 2016 jiankang.fan@samsung.com
+- update to version 2015.11.12
 * Tue Sep 11 2012 qiang.z.zhang@intel.com
 - update to version 2012.09.11
 * Sat Aug 11 2012 qiang.z.zhang@intel.com
index ddcd6e98e259107615faf920e34273a31c19c833..da3aeaa0e8de6db518f6c670e362517ad00dc320 100644 (file)
--- a/qemu-reg
+++ b/qemu-reg
@@ -4,10 +4,13 @@
 
 # NOTE: this requires a qemu with the binfmt misc handler binary
 
+:aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-aarch64-binfmt:P
 :aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-arm64-binfmt:P
 :arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfa\xff\xff\xff:/usr/bin/qemu-arm-static:
 :armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb-binfmt:P
 :ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc-binfmt:P
+:ppc64:M::i\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff::/usr/bin/qemu-ppc64-binfmt:P
+:ppc64le:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff::/usr/bin/qemu-ppc64le-binfmt:P
 :mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips-binfmt:P
 :mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel-binfmt:P
 #:mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32-binfmt:P
@@ -15,6 +18,6 @@
 #:mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64-binfmt:P
 #:mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el-binfmt:P
 
-:sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4-binfmt:P
-:sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb-binfmt:P
+:sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4-binfmt:P
+:sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb-binfmt:P
 
diff --git a/queryconfig b/queryconfig
new file mode 100755 (executable)
index 0000000..ea319a1
--- /dev/null
@@ -0,0 +1,84 @@
+#!/usr/bin/perl -w
+
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+BEGIN {
+  unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
+}
+
+use strict;
+
+use Build;
+
+my ($dist, $archs, $configdir, $type, $argument);
+
+$configdir = ($::ENV{'BUILD_DIR'} || '/usr/lib/build') . '/configs';
+
+while (@ARGV)  {
+  if ($ARGV[0] eq '--dist') {
+    shift @ARGV;
+    $dist = shift @ARGV;
+    next;
+  } elsif ($ARGV[0] eq '--archpath') {
+    shift @ARGV;
+    $archs = shift @ARGV;
+    next;
+  } elsif ($ARGV[0] eq '--configdir') {
+    shift @ARGV;
+    $configdir = shift @ARGV;
+    next;
+  } elsif (defined($type)) {
+    $argument = shift @ARGV; 
+  } else {
+    $type = shift @ARGV;
+  }
+}
+
+die("Please specify what to query\n") unless defined $type;
+
+my $cf = Build::read_config_dist($dist, $archs, $configdir);
+die("Unable to read config\n") unless $cf;
+
+if ($type eq 'buildflags') {
+  die("Specify which buildflag to query\n") unless $argument;
+  my $result = $cf->{"buildflags:$argument"};
+  print "$result\n" if defined $result;
+} elsif ($type eq 'target' || $type eq 'type' || $type eq 'binarytype' || $type eq 'buildengine' || $type eq 'rawmacros') {
+  print "$cf->{$type}\n" if $cf->{$type};
+} elsif ($type eq 'optflags') {
+  exit(0) unless $cf->{'optflags'};
+  my $all = $cf->{'optflags'}->{'*'};
+  $all = defined($all) && $all ne '' ? " $all" : '';
+  $all .= " -g" if $argument && $argument eq 'debug';
+  for (sort keys %{$cf->{'optflags'}}) {
+    next if $_ eq '*';
+    print "optflags: $_ $cf->{'optflags'}->{$_}$all\n";
+  }
+} elsif ($type eq 'substitute') {
+  die("Specify which substitute to query\n") unless $argument;
+  my @res =  @{$cf->{'substitute'}->{$argument} || []};
+  print join(' ', @res)."\n" if @res;
+} else {
+  die("unsupported query type: $type\n");
+}
+
+exit(0);
+
index 8fc2e4c4c5b79048778d2776fc086a6ba38d3764..df15f847ea5801c8403041017d8baa145ffd81fd 100755 (executable)
--- a/signdummy
+++ b/signdummy
@@ -1,5 +1,25 @@
 #!/usr/bin/perl
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 # simple "sign" replacement that does nothing but
 # write a 2048 byte file with a fixed signature.
 # sign is used in kiwi builds to sign repositories
index 4ac2b0ae9d81b47845a56aedd018391dbfebfa2d..a7bcf1e5e6b08f9c61504ac35bc0b87bf092ce80 100755 (executable)
@@ -6,10 +6,25 @@
 #
 # Usage: cat foo.spec | spec2changes.pl > foo.changes
 #
+################################################################
+#
 # Copyright 2009 by Pascal Bleser <pascal.bleser@opensuse.org>
-# This script is licensed under the GNU General Public License version 2
-# http://www.gnu.org/licenses/gpl-2.0.html
 #
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
 
 use warnings;
 use strict;
index fd62753c54afc1c47b3c91c7c106d82fbbd0deee..7b7cf36f37a920351011b923b4e6b22c375ef164 100755 (executable)
@@ -2,6 +2,26 @@
 # vim:sw=4:et
 # Author: Dirk Mueller
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 use strict;
 
 sub helpexit {
index ef058594c565a85f858323e89836f67a18103dd9..bdb897ca2f41baacfb20a06ef711e4ff81ce937f 100755 (executable)
--- a/spectool
+++ b/spectool
@@ -1,5 +1,25 @@
 #!/usr/bin/perl -w
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 =head1 spectool
 
 spectool - tool to work with rpm spec files
index efea76ac96cc45ded91886bebca34724bd7bf4be..92f5dbc039243b89c50128bec0302e0d23624b35 100755 (executable)
@@ -1,5 +1,25 @@
 #!/usr/bin/perl -w
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 BEGIN {
   unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
 }
@@ -19,6 +39,8 @@ sub expand {
 
 my ($dist, $buildroot, $rpmdeps, $archs, $configdir, $release, $changelog);
 
+$configdir = ($::ENV{'BUILD_DIR'} || '/usr/lib/build') . '/configs';
+
 while (@ARGV)  {
   if ($ARGV[0] eq '--root') {
     shift @ARGV;
@@ -142,6 +164,37 @@ for my $line (@$xspec) {
       $line =~ s/<CI_CNT>/0/;
       $line =~ s/<B_CNT>/0/;
     }
+
+    if ($cf->{'releasesuffix'}) {
+      my $suffix = $cf->{'releasesuffix'};
+      if ($suffix =~ /^file:(.+)$/) {
+       my $file = $1;
+       if ($file =~ /\//s || $file =~ /^\./) {
+         $suffix = "error:illegal release suffix";
+       } else {
+         if (open(RP, '<', "$specdir$file")) {
+           $suffix = "error:no suffix in $file";
+           for (<RP>) {
+             chomp;
+             s/^\s+//;
+             s/\s+$//;
+             $suffix = $_ if $_ && !/^#/;
+           }
+           close RP;
+         } else {
+           $suffix = "error:$file file does not exist";
+         }
+       }
+      }
+      if ($suffix =~ /^error:(.*)$/) {
+       $suffix = $1;
+       $suffix =~ s/^\s+//;
+       $suffix =~ s/\s+$//;
+       $suffix = "Error: $suffix";
+      }
+      $line =~ s/^(Release\s*:\s*.*?)\s*$/$1$suffix/i if $suffix;
+    }
+
     # this is to be compatible to legacy autobuild.
     # you can specify a releaseprg in the project configuration,
     # if your package contains this file it is executed and its
diff --git a/t/bad.livebuild b/t/bad.livebuild
new file mode 100644 (file)
index 0000000..ae2cae0
Binary files /dev/null and b/t/bad.livebuild differ
diff --git a/t/directory.livebuild b/t/directory.livebuild
new file mode 100644 (file)
index 0000000..318d128
Binary files /dev/null and b/t/directory.livebuild differ
diff --git a/t/dist b/t/dist
index 889d1827956a8276ed3cbb58475afddb9840ca41..f1fab4f729f3b2be1eecc4a72ef0a463294c202b 100755 (executable)
--- a/t/dist
+++ b/t/dist
@@ -1,5 +1,25 @@
 #!/usr/bin/perl -w
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 use strict;
 use Test::More tests => 9;
 use Build;
diff --git a/t/live-build b/t/live-build
new file mode 100755 (executable)
index 0000000..1b20be0
--- /dev/null
@@ -0,0 +1,72 @@
+#!/usr/bin/perl -w -I ..
+
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
+use strict;
+use Test::More tests => 5;
+use Build::LiveBuild;
+
+use Data::Dumper;
+use Digest::MD5 qw(md5_hex);
+
+my $VAR = '
+
+
+a
+
+b
+#comment
+
+! whatever
+';
+
+is(Build::LiveBuild::filter($VAR), 'a
+b
+');
+
+
+my $DEB_ARCHIVE = '
+# comment
+deb obs://openSUSE.org:Debian:7.0/standard wheezy main contrib
+deb-src obs://openSUSE.org:Debian:7.0/standard wheezy main contrib
+
+';
+my $DEB_ARCHIVE_RESULT = "\$VAR1 = 'openSUSE.org:Debian:7.0/standard';
+";
+
+is(Dumper(Build::LiveBuild::parse_archive($DEB_ARCHIVE)), $DEB_ARCHIVE_RESULT);
+
+my $config = {};
+$Data::Dumper::Sortkeys = 1;
+is(md5_hex(Dumper(Build::LiveBuild::parse( $config, 'standard.livebuild'))),
+   '9cfb69e8f0581293f207342edacd19e7');
+
+#print Dumper(Build::LiveBuild::parse( $config, 'standard.livebuild'));
+
+is(md5_hex(Dumper(Build::LiveBuild::parse( $config, 'directory.livebuild'))),
+   'bc803d2b4a375d9a02b3242117f6c93a');
+
+#print Dumper(Build::LiveBuild::parse( $config, 'directory.livebuild'));
+
+is(md5_hex(Dumper(Build::LiveBuild::parse( $config, 'bad.livebuild'))),
+   '1e596160978007d1014e9c5e38574700');
+
+#print Dumper(Build::LiveBuild::parse( $config, 'bad.livebuild'));
diff --git a/t/standard.livebuild b/t/standard.livebuild
new file mode 100644 (file)
index 0000000..bd96fda
Binary files /dev/null and b/t/standard.livebuild differ
index 6c42210e66de1bbc8a347e86445d58a38d493561..45c0da23308db77a5dfb1fcce486f1670193e76f 100644 (file)
@@ -22,6 +22,8 @@ if [ -e ${0%/*}/config.local ]; then
        . ${0%/*}/config.local
 fi
 
+: ${BUILD_DIR:=/usr/lib/build}
+
 #if [ ! -e "$build_vm_img" ]; then
 #      sudo dd if=/dev/zero of="$build_vm_img" bs=512 count=0 seek=$((build_vm_image_size*2*1024))
 #fi
@@ -89,8 +91,10 @@ run_build()
                        build_args+=("$i")
                fi
        done
-       set -- $linux32 sudo env \
-               /usr/bin/build \
+        SU_WRAPPER=""
+        [ -x /usr/bin/sudo ] && SU_WRAPPER="sudo env"
+       set -- $linux32 $SU_WRAPPER \
+               $BUILD_DIR/build \
                --root "${build_root}" \
                "${repos[@]}" \
                "${build_args[@]}"
diff --git a/test/testbuild.sh b/test/testbuild.sh
new file mode 100755 (executable)
index 0000000..b81c929
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/bash
+#
+# This is the generic test case for the current distribution, it
+# is to be called from the spec file while building a build.rpm
+
+. ${0%/*}/common
+REPO="$1"
+shift
+
+if [ -z "$REPO" ]; then
+  echo "No local path to binary packages is given as argument"
+  exit 1
+fi
+
+[ "$ARCH" == "i386" ] && arch32bit
+
+repo "$REPO"
+
+run_build "$@"
diff --git a/unrpm b/unrpm
index e69dafbc747b326355509ce000e44fe4ed76aa6e..e1c347c43f787697e65848e96ce5dec7480e3c61 100755 (executable)
--- a/unrpm
+++ b/unrpm
@@ -1,5 +1,25 @@
 #!/bin/bash
 
+################################################################
+#
+# Copyright (c) 1995-2014 SUSE Linux Products GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program (see the file COPYING); if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#
+################################################################
+
 function Usage () {
     echo "Usage: $(basename $0) [-vq] rpm-files...";
     echo "Unpack rpm files in current directory.";
diff --git a/unrpm.1 b/unrpm.1
new file mode 100644 (file)
index 0000000..6ed4dcd
--- /dev/null
+++ b/unrpm.1
@@ -0,0 +1,17 @@
+.TH unrpm 1 "(c) 1997-2014 SuSE Linux AG Nuernberg, Germany"
+.SH NAME
+unrpm \- unpack the contents of one or more rpm files
+.SH SYNOPSIS
+.B unrpm
+.RB [ -v ]
+.RB [ -q ]
+.I rpm
+.RB ...
+
+.SH DESCRIPTION
+The \fBunrpm\fP tool unpacks one or more rpm files into the
+current directory. The \fB-v\fP option makes it print the filenames
+while unpacking, whereas the \fB-q\fP option suppresses any output.
+
+.SH SEE ALSO
+.BR rpm2cpio (8),
diff --git a/vc b/vc
index e9d8f55087805f9d79249aa1f9ba316837c0dc39..66f3da0258b978a9ea6946a8c50a86d48050f3c5 100755 (executable)
--- a/vc
+++ b/vc
@@ -8,7 +8,7 @@
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation; either version 2 or 3 of the License, or
 # (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful,
@@ -125,7 +125,7 @@ set +e
                echo
        fi
        if [ -n "$message" ]; then
-               echo "- $message"
+               echo -e "- $message"
                echo
        elif [ -n "$content" ]; then
                cat "$content"
@@ -133,24 +133,6 @@ set +e
        elif [ ! $just_edit ]; then
                echo "- "
                echo
-               if [ -d .osc -a -n "$(which osc 2>/dev/null)" ]; then
-                       OSC_STATUS="$(cd "$pkgpath" &> /dev/null; osc st)"
-                       ADDED="$(sed -n 's/^A[[:blank:]]\+\([^[:blank:]].*\.\(patch\|diff\)\)$/  * \1/p' <<< "$OSC_STATUS")"
-                       DELETED="$(sed -n 's/^D[[:blank:]]\+\([^[:blank:]].*\.\(patch\|diff\)\)$/  * \1/p' <<< "$OSC_STATUS")"
-                       MODIFIED="$(sed -n 's/^M[[:blank:]]\+\([^[:blank:]].*\.\(patch\|diff\)\)$/  * \1/p' <<< "$OSC_STATUS")"
-                       if [ -n "$ADDED" ]; then
-                           echo "- added patches:"
-                           echo "$ADDED"
-                       fi
-                       if [ -n "$DELETED" ]; then
-                           echo "- removed patches:"
-                           echo "$DELETED"
-                       fi
-                       if [ -n "$MODIFIED" ]; then
-                           echo "- modified patches:"
-                           echo "$MODIFIED"
-                       fi
-               fi
        fi
        cat $changelog
 } >> "$tmpfile"
@@ -166,5 +148,7 @@ if [ -z "$message" ]; then
        fi
 fi
 mode=`stat -c "%a" "$changelog"`
+user=`stat -c "%u:%g" "$changelog"`
 mv "$tmpfile" "$changelog"
 chmod $mode "$changelog"
+chown $user "$changelog"
diff --git a/vc.1 b/vc.1
new file mode 100644 (file)
index 0000000..e2b50e2
--- /dev/null
+++ b/vc.1
@@ -0,0 +1,25 @@
+.TH vc 1 "(c) 1997-2014 SuSE Linux AG Nuernberg, Germany"
+.SH NAME
+vs \- create a SUSE stype changes entry
+.SH SYNOPSIS
+.B vc
+.RB [ -m
+.IR message ]
+.RB [ -e ]
+.RI [ changesfile_or_dir
+.RI [ commentfile ]]
+
+.SH DESCRIPTION
+The \fBvc\fP tool adds a new changes entry to a SUSE \fB.changes\fP file.
+The \fB-m\fP option can be used to directly specify the entry, if it is
+not given an editor is started to interactively enter the new changes
+entry. If a \fIcommentfile\fP is given, its content is used as template
+for the new entry instead of an empty entry, whereas the \fB-e\fP option
+suppresses the creation of an empty entry.
+
+If no \fIchangesfile\fP is specified, \fBvc\fP will search the current
+directory for a file ending with \fB.changes\fP. If a directory is
+specified instead of a changes will, it will be searched instead.
+
+.SH SEE ALSO
+.BR build (1),