summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Lee (李健秋) <ajqlee@debian.org>2017-02-20 10:32:56 (GMT)
committerAndrew Lee (李健秋) <ajqlee@debian.org>2017-02-20 10:32:56 (GMT)
commit2c522ce4d7ca2d981c9b87f5cf2a6679f78d6ea9 (patch)
treeef92b9bec9a01cc1d606be8e227ab71b679f751e
downloadobs-build-upstream.tar.gz
obs-build-upstream.tar.xz
Adding upstream version 20170201.upstream/20170201upstream
Signed-off-by: Andrew Lee (李健秋) <ajqlee@debian.org>
-rw-r--r--Build.pm1421
-rw-r--r--Build/Arch.pm329
-rw-r--r--Build/Archrepo.pm98
-rw-r--r--Build/Collax.pm64
-rw-r--r--Build/Deb.pm469
-rw-r--r--Build/Debrepo.pm130
-rw-r--r--Build/Kiwi.pm329
-rw-r--r--Build/LiveBuild.pm102
-rw-r--r--Build/Mdkrepo.pm121
-rw-r--r--Build/Repo.pm67
-rw-r--r--Build/Rpm.pm1161
-rw-r--r--Build/Rpmmd.pm218
-rw-r--r--Build/SimpleXML.pm103
-rw-r--r--Build/Snapcraft.pm83
-rw-r--r--Build/Susetags.pm136
-rw-r--r--Build/Zypp.pm94
-rw-r--r--COPYING340
-rw-r--r--HOWTO.add_another_format99
-rw-r--r--Makefile110
-rw-r--r--README11
-rw-r--r--baselibs_global-deb.conf39
-rw-r--r--baselibs_global.conf45
-rwxr-xr-xbuild1467
-rw-r--r--build-pkg90
-rw-r--r--build-pkg-arch76
-rw-r--r--build-pkg-deb159
-rw-r--r--build-pkg-rpm203
-rw-r--r--build-recipe146
-rw-r--r--build-recipe-arch59
-rw-r--r--build-recipe-collax64
-rw-r--r--build-recipe-debbuild52
-rw-r--r--build-recipe-debootstrap80
-rw-r--r--build-recipe-dsc136
-rw-r--r--build-recipe-kiwi621
-rw-r--r--build-recipe-livebuild249
-rw-r--r--build-recipe-mock100
-rw-r--r--build-recipe-preinstallimage79
-rw-r--r--build-recipe-simpleimage108
-rw-r--r--build-recipe-snapcraft192
-rw-r--r--build-recipe-spec235
-rw-r--r--build-validate-params103
-rw-r--r--build-vm994
-rw-r--r--build-vm-docker80
-rw-r--r--build-vm-ec2226
-rw-r--r--build-vm-emulator94
-rw-r--r--build-vm-kvm320
-rw-r--r--build-vm-lxc197
-rw-r--r--build-vm-openstack143
-rw-r--r--build-vm-pvm193
-rw-r--r--build-vm-qemu65
-rw-r--r--build-vm-uml70
-rw-r--r--build-vm-xen147
-rw-r--r--build-vm-zvm367
-rw-r--r--build.1233
-rw-r--r--build.conf.example27
-rwxr-xr-xchangelog2spec247
-rwxr-xr-xcommon_functions140
-rwxr-xr-xcomputeblocklists187
-rw-r--r--configs/arch.conf25
-rw-r--r--configs/collax.conf7
-rw-r--r--configs/debian.conf182
-rw-r--r--configs/sl10.0.conf202
-rw-r--r--configs/sl10.1.conf196
-rw-r--r--configs/sl10.2.conf208
-rw-r--r--configs/sl10.3.conf316
-rw-r--r--configs/sl11.0.conf377
-rw-r--r--configs/sl11.1.conf407
-rw-r--r--configs/sl11.2.conf452
-rw-r--r--configs/sl11.3.conf489
-rw-r--r--configs/sl11.4.conf600
-rw-r--r--configs/sl12.1.conf638
-rw-r--r--configs/sl12.2.conf610
-rw-r--r--configs/sl12.3.conf640
-rw-r--r--configs/sl13.1.conf696
-rw-r--r--configs/sl13.2.conf675
-rw-r--r--configs/sl13.3.conf788
-rw-r--r--configs/sl42.1.conf797
-rw-r--r--configs/sl42.2.conf856
-rw-r--r--configs/sl42.3.conf856
-rw-r--r--configs/sl8.1.conf196
-rw-r--r--configs/sl8.2.conf199
-rw-r--r--configs/sl9.0.conf200
-rw-r--r--configs/sl9.1.conf203
-rw-r--r--configs/sl9.2.conf198
-rw-r--r--configs/sl9.3.conf198
-rw-r--r--configs/sles10.conf200
l---------configs/sles11.conf1
-rw-r--r--configs/sles11sp2.conf486
-rw-r--r--configs/sles12.conf668
-rw-r--r--configs/sles8.conf196
-rw-r--r--configs/sles9.conf203
-rw-r--r--configs/spectool.conf4
-rw-r--r--configs/ubuntu.conf233
-rw-r--r--configs/ul1.conf196
-rwxr-xr-xcreatearchdeps58
-rwxr-xr-xcreatedebdeps99
-rwxr-xr-xcreatedirdeps99
-rwxr-xr-xcreatemdkdeps50
-rwxr-xr-xcreaterepomddeps154
-rwxr-xr-xcreateyastdeps73
-rwxr-xr-xcreatezyppdeps64
-rwxr-xr-xdebtransform469
-rwxr-xr-xdebtransformbz231
-rwxr-xr-xdebtransformxz6
-rwxr-xr-xdebtransformzip34
-rwxr-xr-xdownload76
-rwxr-xr-xemulator/emulator.sh46
-rwxr-xr-xexpanddeps445
-rwxr-xr-xextractbuild155
-rwxr-xr-xgetbinaryid77
-rwxr-xr-xgetbuildids79
-rwxr-xr-xinit_buildsystem1099
-rw-r--r--initvm.c399
-rwxr-xr-xkillchroot108
-rwxr-xr-xlistinstalled59
-rwxr-xr-xlivebuild_pre_run.template69
-rw-r--r--lxc.conf20
-rwxr-xr-xmkbaselibs1170
-rwxr-xr-xmkdrpms159
-rwxr-xr-xorder101
-rw-r--r--qemu-reg32
-rwxr-xr-xqueryconfig89
-rwxr-xr-xrunservices112
-rwxr-xr-xsigndummy65
-rwxr-xr-xspec2changelog94
-rwxr-xr-xspec_add_patch177
-rwxr-xr-xspectool426
-rwxr-xr-xsubstitutedeps330
-rw-r--r--t/bad.livebuildbin0 -> 40960 bytes
-rw-r--r--t/directory.livebuildbin0 -> 30720 bytes
-rwxr-xr-xt/dist39
-rwxr-xr-xt/live-build72
-rw-r--r--t/standard.livebuildbin0 -> 30720 bytes
-rwxr-xr-xtelnet_login_wrapper8
-rw-r--r--test-debtransform/1-out/grandorgue_0.3.0.6.1026.diff.gzbin0 -> 756 bytes
-rw-r--r--test-debtransform/1-out/grandorgue_0.3.0.6.1026.dsc12
-rw-r--r--test-debtransform/1-out/grandorgue_0.3.0.6.1026.orig.tar.gzbin0 -> 655 bytes
-rw-r--r--test-debtransform/1/debian.changelog24
-rw-r--r--test-debtransform/1/debian.empty0
-rw-r--r--test-debtransform/1/debian.obs-version1
-rw-r--r--test-debtransform/1/debian.tar.gzbin0 -> 522 bytes
-rw-r--r--test-debtransform/1/debian1.tar.gzbin0 -> 598 bytes
-rw-r--r--test-debtransform/1/go.tar.gzbin0 -> 655 bytes
-rw-r--r--test-debtransform/1/grandorgue.dsc11
-rw-r--r--test-debtransform/2-out/grandorgue_0.3.0.6.1026.diff.gzbin0 -> 756 bytes
-rw-r--r--test-debtransform/2-out/grandorgue_0.3.0.6.1026.dsc12
-rw-r--r--test-debtransform/2-out/grandorgue_0.3.0.6.1026.orig.tar.gzbin0 -> 655 bytes
-rw-r--r--test-debtransform/2/debian.changelog24
-rw-r--r--test-debtransform/2/debian.empty0
-rw-r--r--test-debtransform/2/debian.obs-version1
-rw-r--r--test-debtransform/2/debian.tar.gzbin0 -> 522 bytes
-rw-r--r--test-debtransform/2/debian1.tar.gzbin0 -> 598 bytes
-rw-r--r--test-debtransform/2/go.tar.bz2bin0 -> 707 bytes
-rw-r--r--test-debtransform/2/grandorgue.dsc11
-rwxr-xr-xtest-debtransform/run.sh32
-rw-r--r--test/Fedora_11.conf305
-rw-r--r--test/Fedora_12.conf311
-rw-r--r--test/baselibs.conf1
-rw-r--r--test/common109
-rw-r--r--test/config8
-rw-r--r--test/libdummy1.spec28
-rwxr-xr-xtest/testbuild.11.0-i3869
-rwxr-xr-xtest/testbuild.11.0-x86_647
-rwxr-xr-xtest/testbuild.11.1-i3869
-rwxr-xr-xtest/testbuild.11.2-i3869
-rwxr-xr-xtest/testbuild.8.1-i3869
-rwxr-xr-xtest/testbuild.Fedora11-i3869
-rwxr-xr-xtest/testbuild.Fedora11-x86_647
-rwxr-xr-xtest/testbuild.Fedora12-i3869
-rwxr-xr-xtest/testbuild.Fedora12-x86_647
-rwxr-xr-xtest/testbuild.sh19
-rwxr-xr-xtest/testbuild.sles10-i38610
-rwxr-xr-xtest/testbuild.sles10-x86_648
-rwxr-xr-xtest/testbuild.sles9-i38610
-rwxr-xr-xunrpm59
-rw-r--r--unrpm.117
-rwxr-xr-xvc160
-rw-r--r--vc.125
178 files changed, 34832 insertions, 0 deletions
diff --git a/Build.pm b/Build.pm
new file mode 100644
index 0000000..ccf8735
--- /dev/null
+++ b/Build.pm
@@ -0,0 +1,1421 @@
+################################################################
+#
+# 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;
+use Digest::MD5;
+use Build::Rpm;
+use Data::Dumper;
+use POSIX qw(strftime);
+
+our $expand_dbg;
+
+our $do_rpm;
+our $do_deb;
+our $do_kiwi;
+our $do_arch;
+our $do_collax;
+our $do_livebuild;
+our $do_snapcraft;
+
+sub import {
+ for (@_) {
+ $do_rpm = 1 if $_ eq ':rpm';
+ $do_deb = 1 if $_ eq ':deb';
+ $do_kiwi = 1 if $_ eq ':kiwi';
+ $do_arch = 1 if $_ eq ':arch';
+ $do_collax = 1 if $_ eq ':collax';
+ $do_livebuild = 1 if $_ eq ':livebuild';
+ $do_snapcraft = 1 if $_ eq ':snapcraft';
+ }
+ $do_rpm = $do_deb = $do_kiwi = $do_arch = $do_collax = $do_livebuild = $do_snapcraft = 1 if !$do_rpm && !$do_deb && !$do_kiwi && !$do_arch && !$do_collax && !$do_livebuild && !$do_snapcraft;
+ if ($do_deb) {
+ require Build::Deb;
+ }
+ if ($do_kiwi) {
+ require Build::Kiwi;
+ }
+ if ($do_arch) {
+ require Build::Arch;
+ }
+ if ($do_collax) {
+ require Build::Collax;
+ }
+ if ($do_livebuild) {
+ require Build::LiveBuild;
+ }
+ if ($do_snapcraft) {
+ require Build::Snapcraft;
+ }
+}
+
+package Build::Features;
+our $preinstallimage = 1; # on sale now
+package Build;
+
+my $std_macros = q{
+%define nil
+%define ix86 i386 i486 i586 i686 athlon
+%define arm armv4l armv5l armv6l armv7l armv4b armv5l armv5b armv5el armv5eb armv5tel armv5teb armv6hl armv6el armv6eb armv7el armv7eb armv7hl armv7nhl armv8el
+%define arml armv4l armv5l armv6l armv7l armv5tel armv5el armv6el armv6hl armv7el armv7hl armv7nhl armv8el
+%define armb armv4b armv5b armv5teb armv5eb armv6eb armv7eb
+%define sparc sparc sparcv8 sparcv9 sparcv9v sparc64 sparc64v
+};
+my $extra_macros = '';
+
+sub unify {
+ my %h = map {$_ => 1} @_;
+ return grep(delete($h{$_}), @_);
+}
+
+sub define($)
+{
+ my $def = shift;
+ $extra_macros .= '%define '.$def."\n";
+}
+
+sub init_helper_hashes {
+ my ($config) = @_;
+
+ $config->{'preferh'} = { map {$_ => 1} @{$config->{'prefer'}} };
+
+ my %ignore;
+ for (@{$config->{'ignore'}}) {
+ if (!/:/) {
+ $ignore{$_} = 1;
+ next;
+ }
+ my @s = split(/[,:]/, $_);
+ my $s = shift @s;
+ $ignore{"$s:$_"} = 1 for @s;
+ }
+ $config->{'ignoreh'} = \%ignore;
+
+ my %conflicts;
+ for (@{$config->{'conflict'}}) {
+ my @s = split(/[,:]/, $_);
+ my $s = shift @s;
+ push @{$conflicts{$s}}, @s;
+ push @{$conflicts{$_}}, $s for @s;
+ }
+ for (keys %conflicts) {
+ $conflicts{$_} = [ unify(@{$conflicts{$_}}) ]
+ }
+ $config->{'conflicth'} = \%conflicts;
+}
+
+# 'canonicalize' dist string as found in rpm dist tags
+sub dist_canon($$) {
+ my ($rpmdist, $arch) = @_;
+ $rpmdist = lc($rpmdist);
+ $rpmdist =~ s/-/_/g;
+ $rpmdist =~ s/opensuse/suse linux/;
+ my $rpmdista;
+ if ($rpmdist =~ /\(/) {
+ $rpmdista = $rpmdist;
+ $rpmdista =~ s/.*\(//;
+ $rpmdista =~ s/\).*//;
+ } else {
+ $rpmdista = $arch;
+ }
+ $rpmdista =~ s/i[456]86/i386/;
+ $rpmdist = '' unless $rpmdista =~ /^(i386|x86_64|ia64|ppc|ppc64|ppc64le|s390|s390x)$/;
+ my $dist = 'default';
+ if ($rpmdist =~ /unitedlinux 1\.0.*/) {
+ $dist = "ul1-$rpmdista";
+ } elsif ($rpmdist =~ /suse sles_(\d+)/) {
+ $dist = "sles$1-$rpmdista";
+ } elsif ($rpmdist =~ /suse linux enterprise (\d+)/) {
+ $dist = "sles$1-$rpmdista";
+ } elsif ($rpmdist =~ /suse linux (\d+)\.(\d+)\.[4-9]\d/) {
+ # alpha version
+ $dist = "$1.".($2 + 1)."-$rpmdista";
+ } elsif ($rpmdist =~ /suse linux (?:leap )?(\d+\.\d+)/) {
+ $dist = "$1-$rpmdista";
+ }
+ return $dist;
+}
+
+sub read_config_dist {
+ my ($dist, $archpath, $configdir) = @_;
+
+ my $arch = $archpath;
+ $arch = 'noarch' unless defined $arch;
+ $arch =~ s/:.*//;
+ $arch = 'noarch' if $arch eq '';
+ die("Please specify a distribution!\n") unless defined $dist;
+ if ($dist !~ /\//) {
+ my $saved = $dist;
+ $configdir = '.' unless defined $configdir;
+ $dist =~ s/-.*//;
+ $dist = "sl$dist" if $dist =~ /^\d/;
+ $dist = "$configdir/$dist.conf";
+ if (! -e $dist) {
+ $dist =~ s/-.*//;
+ $dist = "sl$dist" if $dist =~ /^\d/;
+ $dist = "$configdir/$dist.conf";
+ }
+ if (! -e $dist) {
+ warn "$saved.conf not found, using default.conf\n" unless $saved eq 'default';
+ $dist = "$configdir/default.conf";
+ }
+ }
+ die("$dist: $!\n") unless -e $dist;
+ my $cf = read_config($arch, $dist);
+ die("$dist: parse error\n") unless $cf;
+ return $cf;
+}
+
+sub read_config {
+ my ($arch, $cfile) = @_;
+ my @macros = split("\n", $std_macros.$extra_macros);
+ push @macros, "%define _target_cpu $arch";
+ push @macros, "%define _target_os linux";
+ my $config = {'macros' => \@macros, 'arch' => $arch};
+ my @config;
+ if (ref($cfile)) {
+ @config = @$cfile;
+ } elsif (defined($cfile)) {
+ local *CONF;
+ return undef unless open(CONF, '<', $cfile);
+ @config = <CONF>;
+ close CONF;
+ chomp @config;
+ }
+ # create verbatim macro blobs
+ my @newconfig;
+ while (@config) {
+ push @newconfig, shift @config;
+ next unless $newconfig[-1] =~ /^\s*macros:\s*$/si;
+ $newconfig[-1] = "macros:\n";
+ while (@config) {
+ my $l = shift @config;
+ last if $l =~ /^\s*:macros\s*$/si;
+ $newconfig[-1] .= "$l\n";
+ }
+ }
+ my @spec;
+ $config->{'save_expanded'} = 1;
+ Build::Rpm::parse($config, \@newconfig, \@spec);
+ delete $config->{'save_expanded'};
+ $config->{'preinstall'} = [];
+ $config->{'vminstall'} = [];
+ $config->{'cbpreinstall'} = [];
+ $config->{'cbinstall'} = [];
+ $config->{'runscripts'} = [];
+ $config->{'required'} = [];
+ $config->{'support'} = [];
+ $config->{'keep'} = [];
+ $config->{'prefer'} = [];
+ $config->{'ignore'} = [];
+ $config->{'conflict'} = [];
+ $config->{'substitute'} = {};
+ $config->{'substitute_vers'} = {};
+ $config->{'optflags'} = {};
+ $config->{'order'} = {};
+ $config->{'exportfilter'} = {};
+ $config->{'publishfilter'} = [];
+ $config->{'rawmacros'} = '';
+ $config->{'release'} = '<CI_CNT>.<B_CNT>';
+ $config->{'repotype'} = [];
+ $config->{'patterntype'} = [];
+ $config->{'fileprovides'} = {};
+ $config->{'constraint'} = [];
+ $config->{'expandflags'} = [];
+ $config->{'buildflags'} = [];
+ $config->{'singleexport'} = '';
+ for my $l (@spec) {
+ $l = $l->[1] if ref $l;
+ next unless defined $l;
+ my @l = split(' ', $l);
+ next unless @l;
+ my $ll = shift @l;
+ my $l0 = lc($ll);
+ if ($l0 eq 'macros:') {
+ $l =~ s/.*?\n//s;
+ if ($l =~ /^!\n/s) {
+ $config->{'rawmacros'} = substr($l, 2);
+ } else {
+ $config->{'rawmacros'} .= $l;
+ }
+ 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:' || $l0 eq 'buildflags:') {
+ my $t = substr($l0, 0, -1);
+ for my $l (@l) {
+ if ($l eq '!*') {
+ $config->{$t} = [];
+ } elsif ($l =~ /^!/) {
+ $config->{$t} = [ grep {"!$_" ne $l} @{$config->{$t}} ];
+ } else {
+ push @{$config->{$t}}, $l;
+ }
+ }
+ } elsif ($l0 eq 'substitute:') {
+ next unless @l;
+ $ll = shift @l;
+ if ($ll eq '!*') {
+ $config->{'substitute'} = {};
+ } elsif ($ll =~ /^!(.*)$/) {
+ delete $config->{'substitute'}->{$1};
+ } else {
+ $config->{'substitute'}->{$ll} = [ @l ];
+ }
+ } elsif ($l0 eq 'fileprovides:') {
+ next unless @l;
+ $ll = shift @l;
+ if ($ll eq '!*') {
+ $config->{'fileprovides'} = {};
+ } elsif ($ll =~ /^!(.*)$/) {
+ delete $config->{'fileprovides'}->{$1};
+ } else {
+ $config->{'fileprovides'}->{$ll} = [ @l ];
+ }
+ } elsif ($l0 eq 'exportfilter:') {
+ next unless @l;
+ $ll = shift @l;
+ $config->{'exportfilter'}->{$ll} = [ @l ];
+ } elsif ($l0 eq 'publishfilter:') {
+ $config->{'publishfilter'} = [ @l ];
+ } elsif ($l0 eq 'optflags:') {
+ next unless @l;
+ $ll = shift @l;
+ $config->{'optflags'}->{$ll} = join(' ', @l);
+ } elsif ($l0 eq 'order:') {
+ for my $l (@l) {
+ if ($l eq '!*') {
+ $config->{'order'} = {};
+ } elsif ($l =~ /^!(.*)$/) {
+ delete $config->{'order'}->{$1};
+ } else {
+ $config->{'order'}->{$l} = 1;
+ }
+ }
+ } elsif ($l0 eq 'repotype:') { # type of generated repository data
+ $config->{'repotype'} = [ @l ];
+ } elsif ($l0 eq 'type:') { # kind of recipe system (spec,dsc,arch,kiwi,...)
+ $config->{'type'} = $l[0];
+ } 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
+ $config->{'patterntype'} = [ @l ];
+ } elsif ($l0 eq 'release:') {
+ $config->{'release'} = $l[0];
+ } elsif ($l0 eq 'cicntstart:') {
+ $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'};
+ } elsif ($l0 eq 'hostarch:') {
+ $config->{'hostarch'} = join(' ', @l);
+ } elsif ($l0 eq 'constraint:') {
+ my $l = join(' ', @l);
+ if ($l eq '!*') {
+ $config->{'constraint'} = [];
+ } else {
+ push @{$config->{'constraint'}}, $l;
+ }
+ } elsif ($l0 eq 'singleexport:') {
+ $config->{'singleexport'} = $l[0]; # avoid to export multiple package container in maintenance_release projects
+ } elsif ($l0 !~ /^[#%]/) {
+ warn("unknown keyword in config: $l0\n");
+ }
+ }
+ for my $l (qw{preinstall vminstall required support keep runscripts repotype patterntype}) {
+ $config->{$l} = [ unify(@{$config->{$l}}) ];
+ }
+ for my $l (keys %{$config->{'substitute'}}) {
+ $config->{'substitute_vers'}->{$l} = [ map {/^(.*?)(=)?$/g} unify(@{$config->{'substitute'}->{$l}}) ];
+ $config->{'substitute'}->{$l} = [ unify(@{$config->{'substitute'}->{$l}}) ];
+ s/=$// for @{$config->{'substitute'}->{$l}};
+ }
+ init_helper_hashes($config);
+ if (!$config->{'type'}) {
+ # Fallback to old guessing method if no type (spec, dsc or kiwi) is defined
+ if (grep {$_ eq 'rpm'} @{$config->{'preinstall'} || []}) {
+ $config->{'type'} = 'spec';
+ } elsif (grep {$_ eq 'debianutils'} @{$config->{'preinstall'} || []}) {
+ $config->{'type'} = 'dsc';
+ } elsif (grep {$_ eq 'pacman'} @{$config->{'preinstall'} || []}) {
+ $config->{'type'} = 'arch';
+ } else {
+ $config->{'type'} = 'UNDEFINED';
+ }
+ }
+ if (!$config->{'binarytype'}) {
+ $config->{'binarytype'} = 'rpm' if $config->{'type'} eq 'spec' || $config->{'type'} eq 'kiwi';
+ $config->{'binarytype'} = 'deb' if $config->{'type'} eq 'dsc' || $config->{'type'} eq 'collax' || $config->{'type'} eq 'livebuild';
+ $config->{'binarytype'} = 'arch' if $config->{'type'} eq 'arch';
+ if ($config->{'type'} eq 'snapcraft') {
+ if (grep {$_ eq 'rpm'} @{$config->{'preinstall'} || []}) {
+ $config->{'binarytype'} = 'rpm';
+ } elsif (grep {$_ eq 'debianutils'} @{$config->{'preinstall'} || []}) {
+ $config->{'binarytype'} = 'deb';
+ } elsif (grep {$_ eq 'pacman'} @{$config->{'preinstall'} || []}) {
+ $config->{'binarytype'} = 'arch';
+ }
+ }
+ $config->{'binarytype'} ||= 'UNDEFINED';
+ }
+ # add rawmacros to our macro list
+ if ($config->{'rawmacros'} ne '') {
+ for my $rm (split("\n", $config->{'rawmacros'})) {
+ if (@macros && $macros[-1] =~ /\\$/) {
+ if ($rm =~ /\\$/) {
+ push @macros, '...\\';
+ } else {
+ push @macros, '...';
+ }
+ } elsif ($rm !~ /^%/) {
+ push @macros, $rm;
+ } else {
+ push @macros, "%define ".substr($rm, 1);
+ }
+ }
+ }
+ for (@{$config->{'expandflags'} || []}) {
+ if (/^([^:]+):(.*)$/s) {
+ $config->{"expandflags:$1"} = $2;
+ } else {
+ $config->{"expandflags:$_"} = 1;
+ }
+ }
+ for (@{$config->{'buildflags'} || []}) {
+ if (/^([^:]+):(.*)$/s) {
+ $config->{"buildflags:$1"} = $2;
+ } else {
+ $config->{"buildflags:$_"} = 1;
+ }
+ }
+ return $config;
+}
+
+sub do_subst {
+ my ($config, @deps) = @_;
+ my @res;
+ my %done;
+ my $subst = $config->{'substitute'};
+ while (@deps) {
+ my $d = shift @deps;
+ next if $done{$d};
+ my $ds = $d;
+ $ds =~ s/\s*[<=>].*$//s;
+ if ($subst->{$ds}) {
+ unshift @deps, @{$subst->{$ds}};
+ push @res, $d if grep {$_ eq $ds} @{$subst->{$ds}};
+ } else {
+ push @res, $d;
+ }
+ $done{$d} = 1;
+ }
+ return @res;
+}
+
+sub do_subst_vers {
+ my ($config, @deps) = @_;
+ my @res;
+ my %done;
+ my $subst = $config->{'substitute_vers'};
+ while (@deps) {
+ my ($d, $dv) = splice(@deps, 0, 2);
+ next if $done{$d};
+ if ($subst->{$d}) {
+ unshift @deps, map {defined($_) && $_ eq '=' ? $dv : $_} @{$subst->{$d}};
+ push @res, $d, $dv if grep {defined($_) && $_ eq $d} @{$subst->{$d}};
+ } else {
+ push @res, $d, $dv;
+ }
+ $done{$d} = 1;
+ }
+ return @res;
+}
+
+my %subst_defaults = (
+ # defaults live-build package dependencies base on 4.0~a26 gathered with:
+ # grep Check_package -r /usr/lib/live/build
+ 'build-packages:livebuild' => [
+ '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',
+ ],
+ 'system-packages:livebuild' => [
+ 'apt-utils', 'cpio', 'dpkg-dev', 'live-build', 'lsb-release', 'tar',
+ ],
+ 'system-packages:mock' => [
+ 'mock', 'createrepo',
+ ],
+ 'system-packages:debootstrap' => [
+ 'debootstrap', 'lsb-release',
+ ],
+ 'system-packages:kiwi-image' => [
+ 'kiwi', 'createrepo', 'tar',
+ ],
+ 'system-packages:kiwi-product' => [
+ 'kiwi',
+ ],
+ 'system-packages:deltarpm' => [
+ 'deltarpm',
+ ],
+);
+
+# expand the preinstalls/vminstalls
+sub expandpreinstalls {
+ my ($config) = @_;
+ return if !$config->{'expandflags:preinstallexpand'} || $config->{'preinstallisexpanded'};
+ my (@pre, @vm);
+ if (@{$config->{'preinstall'} || []}) {
+ @pre = expand($config, @{$config->{'preinstall'} || []});
+ return "preinstalls: $pre[0]" unless shift @pre;
+ @pre = sort(@pre);
+ }
+ if (@{$config->{'vminstall'} || []}) {
+ my %pre = map {$_ => 1} @pre;
+ my %vmx = map {+"-$_" => 1} @{$config->{'vminstall'} || []};
+ my @pren = grep {/^-/ && !$vmx{$_}} @{$config->{'preinstall'} || []};
+ @vm = expand($config, @pre, @pren, @{$config->{'vminstall'} || []});
+ return "vminstalls: $vm[0]" unless shift @vm;
+ @vm = sort(grep {!$pre{$_}} @vm);
+ }
+ $config->{'preinstall'} = \@pre;
+ $config->{'vminstall'} = \@vm;
+ #print STDERR "pre: @pre\n";
+ #print STDERR "vm: @vm\n";
+ $config->{'preinstallisexpanded'} = 1;
+ return '';
+}
+
+# Delivers all packages which get used for building
+sub get_build {
+ my ($config, $subpacks, @deps) = @_;
+
+ if ($config->{'expandflags:preinstallexpand'} && !$config->{'preinstallisexpanded'}) {
+ my $err = expandpreinstalls($config);
+ return (undef, $err) if $err;
+ }
+ if ($config->{'type'} eq 'livebuild') {
+ push @deps, @{$config->{'substitute'}->{'build-packages:livebuild'}
+ || $subst_defaults{'build-packages: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 || []}) {
+ 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;
+ }
+ @deps = grep {!$ndeps{$_}} @deps;
+ push @deps, @{$config->{'preinstall'}};
+ push @deps, @extra;
+ @deps = grep {!$ndeps{"-$_"}} @deps;
+ @deps = do_subst($config, @deps);
+ @deps = grep {!$ndeps{"-$_"}} @deps;
+ 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, $extradeps) = @_;
+ my $engine = $config->{'buildengine'} || '';
+ $buildtype ||= $config->{'type'} || '';
+ my @sysdeps;
+ if ($engine eq 'mock' && $buildtype eq 'spec') {
+ @sysdeps = @{$config->{'substitute'}->{'system-packages:mock'} || []};
+ @sysdeps = @{$subst_defaults{'system-packages:mock'} || []} unless @sysdeps;
+ } elsif ($engine eq 'debootstrap' && $buildtype eq 'dsc') {
+ @sysdeps = @{$config->{'substitute'}->{'system-packages:debootstrap'} || []};
+ @sysdeps = @{$subst_defaults{'system-packages:debootstrap'} || []} unless @sysdeps;
+ } elsif ($buildtype eq 'livebuild') {
+ # packages used for build environment setup (build-recipe-livebuild deps)
+ @sysdeps = @{$config->{'substitute'}->{'system-packages:livebuild'} || []};
+ @sysdeps = @{$subst_defaults{'system-packages:livebuild'} || []} unless @sysdeps;
+ } elsif ($buildtype eq 'kiwi-image') {
+ @sysdeps = @{$config->{'substitute'}->{'system-packages:kiwi-image'} || []};
+ @sysdeps = @{$config->{'substitute'}->{'kiwi-setup:image'} || []} unless @sysdeps;
+ @sysdeps = @{$subst_defaults{'system-packages:kiwi-image'} || []} unless @sysdeps;
+ push @sysdeps, @$extradeps if $extradeps;
+ } elsif ($buildtype eq 'kiwi-product') {
+ @sysdeps = @{$config->{'substitute'}->{'system-packages:kiwi-product'} || []};
+ @sysdeps = @{$config->{'substitute'}->{'kiwi-setup:product'} || []} unless @sysdeps;
+ @sysdeps = @{$subst_defaults{'system-packages:kiwi-product'} || []} unless @sysdeps;
+ push @sysdeps, @$extradeps if $extradeps;
+ } elsif ($buildtype eq 'deltarpm') {
+ @sysdeps = @{$config->{'substitute'}->{'system-packages:deltarpm'} || []};
+ @sysdeps = @{$subst_defaults{'system-packages:deltarpm'} || []} unless @sysdeps;
+ }
+ return () unless @sysdeps;
+ if ($config->{'expandflags:preinstallexpand'} && !$config->{'preinstallisexpanded'}) {
+ my $err = expandpreinstalls($config);
+ return (undef, $err) if $err;
+ }
+ my @ndeps = grep {/^-/} @sysdeps;
+ my %ndeps = map {$_ => 1} @ndeps;
+ @sysdeps = grep {!$ndeps{$_}} @sysdeps;
+ push @sysdeps, @{$config->{'preinstall'}}, @{$config->{'required'}};
+ push @sysdeps, @{$config->{'support'}} if $buildtype eq 'kiwi-image' || $buildtype eq 'kiwi-product'; # compat to old versions
+ @sysdeps = do_subst($config, @sysdeps);
+ @sysdeps = grep {!$ndeps{$_}} @sysdeps;
+ my $configtmp = $config;
+ @sysdeps = expand($configtmp, @sysdeps, @ndeps);
+ 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) = @_;
+ if ($config->{'expandflags:preinstallexpand'} && !$config->{'preinstallisexpanded'}) {
+ my $err = expandpreinstalls($config);
+ return (undef, $err) if $err;
+ }
+ my @ndeps = grep {/^-/} @deps;
+ my @extra = @{$config->{'required'}};
+ if (@{$config->{'keep'} || []}) {
+ my %keep = map {$_ => 1} (@deps, @{$config->{'keep'} || []}, @{$config->{'preinstall'}});
+ for (@{$subpacks || []}) {
+ push @ndeps, "-$_" unless $keep{$_};
+ }
+ } else {
+ # new "empty keep" mode, filter subpacks from required
+ my %subpacks = map {$_ => 1} @{$subpacks || []};
+ @extra = grep {!$subpacks{$_}} @extra;
+ }
+ my %ndeps = map {$_ => 1} @ndeps;
+ @deps = grep {!$ndeps{$_}} @deps;
+ push @deps, @extra;
+ @deps = grep {!$ndeps{"-$_"}} @deps;
+ @deps = do_subst($config, @deps);
+ @deps = grep {!$ndeps{"-$_"}} @deps;
+ my %bdeps = map {$_ => 1} (@{$config->{'preinstall'}}, @{$config->{'support'}});
+ delete $bdeps{$_} for @deps;
+ @deps = expand($config, @deps, @ndeps);
+ if (@deps && $deps[0]) {
+ my $r = shift @deps;
+ @deps = grep {!$bdeps{$_}} @deps;
+ unshift @deps, $r;
+ }
+ return @deps;
+}
+
+sub get_preinstalls {
+ my ($config) = @_;
+ if ($config->{'expandflags:preinstallexpand'} && !$config->{'preinstallisexpanded'}) {
+ my $err = expandpreinstalls($config);
+ return ('expandpreinstalls_error') if $err;
+ }
+ return @{$config->{'preinstall'}};
+}
+
+sub get_vminstalls {
+ my ($config) = @_;
+ if ($config->{'expandflags:preinstallexpand'} && !$config->{'preinstallisexpanded'}) {
+ my $err = expandpreinstalls($config);
+ return ('expandpreinstalls_error') if $err;
+ }
+ return @{$config->{'vminstall'}};
+}
+
+sub get_runscripts {
+ my ($config) = @_;
+ return @{$config->{'runscripts'}};
+}
+
+### just for API compability
+sub get_cbpreinstalls { return (); }
+sub get_cbinstalls { return (); }
+
+###########################################################################
+
+sub readdeps {
+ my ($config, $pkginfo, @depfiles) = @_;
+
+ local *F;
+ my %requires;
+ my %provides;
+ my %pkgconflicts;
+ my %pkgobsoletes;
+ my %recommends;
+ my %supplements;
+ 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'};
+ $recommends{$rr} = $depfile->{$rr}->{'recommends'};
+ $supplements{$rr} = $depfile->{$rr}->{'supplements'};
+ }
+ next;
+ }
+ # XXX: we don't support different architectures per file
+ 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] =~ /^\//) {
+ shift @s;
+ next;
+ }
+ if ($s[0] =~ /^rpmlib\(/) {
+ splice(@s, 0, 3);
+ next;
+ }
+ push @ss, shift @s;
+ 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|C|O|r|s):(.*)\.(.*)-\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;
+ }
+ 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;
+ }
+ if ($1 eq "r") {
+ $recommends{$pkgid} = \@ss;
+ $pkginfo->{$pkgid}->{'recommends'} = \@ss if $pkginfo;
+ next;
+ }
+ if ($1 eq "s") {
+ $supplements{$pkgid} = \@ss;
+ $pkginfo->{$pkgid}->{'supplements'} = \@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;
+ $config->{'recommendsh'} = \%recommends;
+ $config->{'supplementsh'} = \%supplements;
+ 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 "r:$id".join(' ', @{$pkg->{'recommends'}})."\n" if $pkg->{'recommends'};
+ print $fh "s:$id".join(' ', @{$pkg->{'supplements'}})."\n" if $pkg->{'supplements'};
+ print $fh "I:$id".getbuildid($pkg)."\n";
+}
+
+sub makewhatprovidesh {
+ my ($config) = @_;
+
+ my %whatprovides;
+ my $provides = $config->{'providesh'};
+
+ for my $p (keys %$provides) {
+ my @pp = @{$provides->{$p}};
+ s/[ <=>].*// for @pp;
+ push @{$whatprovides{$_}}, $p for unify(@pp);
+ }
+ for my $p (keys %{$config->{'fileprovides'}}) {
+ my @pp = map {@{$whatprovides{$_} || []}} @{$config->{'fileprovides'}->{$p}};
+ @{$whatprovides{$p}} = unify(@{$whatprovides{$p} || []}, @pp) if @pp;
+ }
+ $config->{'whatprovidesh'} = \%whatprovides;
+}
+
+sub setdeps {
+ my ($config, $provides, $whatprovides, $requires) = @_;
+ $config->{'providesh'} = $provides;
+ $config->{'whatprovidesh'} = $whatprovides;
+ $config->{'requiresh'} = $requires;
+}
+
+sub forgetdeps {
+ my ($config) = @_;
+ delete $config->{'providesh'};
+ delete $config->{'whatprovidesh'};
+ delete $config->{'requiresh'};
+ delete $config->{'pkgconflictsh'};
+ delete $config->{'pkgobsoletesh'};
+ delete $config->{'recommendsh'};
+ delete $config->{'supplementsh'};
+}
+
+my %addproviders_fm = (
+ '>' => 1,
+ '=' => 2,
+ '>=' => 3,
+ '<' => 4,
+ '<=' => 6,
+);
+
+sub addproviders {
+ my ($config, $r) = @_;
+
+ my @p;
+ my $whatprovides = $config->{'whatprovidesh'};
+ $whatprovides->{$r} = \@p;
+ my $binarytype = $config->{'binarytype'};
+ if ($r =~ /\|/) {
+ for my $or (split(/\s*\|\s*/, $r)) {
+ push @p, @{$whatprovides->{$or} || addproviders($config, $or)};
+ }
+ @p = unify(@p) if @p > 1;
+ return \@p;
+ }
+ if ($r !~ /^(.*?)\s*([<=>]{1,2})\s*(.*?)$/) {
+ @p = @{$whatprovides->{$r} || addproviders($config, $r)} if $binarytype eq 'deb' && $r =~ s/:any$//;
+ return \@p;
+ }
+ my $rn = $1;
+ my $rv = $3;
+ my $rf = $addproviders_fm{$2};
+ return \@p unless $rf;
+ $rn =~ s/:any$// if $binarytype eq 'deb';
+ my $provides = $config->{'providesh'};
+ my @rp = @{$whatprovides->{$rn} || []};
+ for my $rp (@rp) {
+ for my $pp (@{$provides->{$rp} || []}) {
+ if ($pp eq $rn) {
+ # debian: unversioned provides do not match
+ next if $binarytype eq 'deb';
+ push @p, $rp;
+ last;
+ }
+ next unless $pp =~ /^\Q$rn\E\s*([<=>]{1,2})\s*(.*?)$/;
+ my $pv = $2;
+ my $pf = $addproviders_fm{$1};
+ next unless $pf;
+ if ($pf & $rf & 5) {
+ push @p, $rp;
+ last;
+ }
+ if ($pv eq $rv) {
+ next unless $pf & $rf & 2;
+ push @p, $rp;
+ last;
+ }
+ my $rr = $rf == 2 ? $pf : ($rf ^ 5);
+ $rr &= 5 unless $pf & 2;
+ # verscmp for spec and kiwi types
+ my $vv;
+ if ($binarytype eq 'deb') {
+ $vv = Build::Deb::verscmp($pv, $rv, 1);
+ } else {
+ $vv = Build::Rpm::verscmp($pv, $rv, 1);
+ }
+ if ($rr & (1 << ($vv + 1))) {
+ push @p, $rp;
+ last;
+ }
+ }
+ }
+ @p = unify(@p) if @p > 1;
+ 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 todo2recommended {
+ my ($config, $recommended, $todo) = @_;
+ my $whatprovides = $config->{'whatprovidesh'};
+ my $pkgrecommends = $config->{'recommendsh'} || {};
+ for my $p (splice @$todo) {
+ for my $r (@{$pkgrecommends->{$p} || []}) {
+ $recommended->{$_} = 1 for @{$whatprovides->{$r} || addproviders($config, $r)}
+ }
+ }
+}
+
+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 $ignoreignore;
+ my $userecommendsforchoices = 1;
+
+ my $whatprovides = $config->{'whatprovidesh'};
+ my $requires = $config->{'requiresh'};
+
+ my %xignore = map {substr($_, 1) => 1} grep {/^-/} @p;
+ $ignore = {} if $xignore{'-ignoreignore--'};
+ 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);
+ }
+
+ my %aconflicts; # packages we are conflicting with
+ for (grep {/^!/} @p) {
+ my $r = /^!!/ ? substr($_, 2) : substr($_, 1);
+ my @q = @{$whatprovides->{$r} || addproviders($config, $r)};
+ @q = nevrmatch($config, $r, @q) if /^!!/;
+ $aconflicts{$_} = "is in BuildConflicts" for @q;
+ }
+ my %recommended; # recommended by installed packages
+ my @rec_todo; # installed todo
+
+ @p = grep {!/^[-!]/} @p;
+ my %p; # expanded packages
+
+ # add direct dependency packages. this is different from below,
+ # 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)};
+ if (@q > 1) {
+ my $pn = $p;
+ $pn =~ s/ .*//;
+ @q = grep {$_ eq $pn} @q;
+ }
+ if (@q != 1) {
+ push @p, $p;
+ next;
+ }
+ next if $p{$q[0]};
+ 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{$_} = "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 @rec_todo, $q[0] if $userecommendsforchoices;
+ }
+ push @p, @directdepsend;
+
+ my @pamb = ();
+ my $doamb = 0;
+ while (@p) {
+ my @error = ();
+ my @rerror = ();
+ for my $p (splice @p) {
+ for my $r (@{$requires->{$p} || [$p]}) {
+ my $ri = (split(/[ <=>]/, $r, 2))[0];
+ if (!$ignoreignore) {
+ next if $ignore->{"$p:$ri"} || $xignore{"$p:$ri"};
+ next if $ignore->{$ri} || $xignore{$ri};
+ }
+ my @q = @{$whatprovides->{$r} || addproviders($config, $r)};
+ next if grep {$p{$_}} @q;
+ if (!$ignoreignore) {
+ 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, "$msg $r$eq";
+ } else {
+ next if $r =~ /^\// && !@eq;
+ push @rerror, "$msg $r needed by $p$eq";
+ }
+ next;
+ }
+ if (@q > 1 && !$doamb) {
+ push @pamb, $p unless @pamb && $pamb[-1] eq $p;
+ print "undecided about $p:$r: @q\n" if $expand_dbg;
+ next;
+ }
+ if (@q > 1) {
+ my @pq = grep {!$prefer->{"-$_"} && !$prefer->{"-$p:$_"}} @q;
+ @q = @pq if @pq;
+ @pq = grep {$prefer->{$_} || $prefer->{"$p:$_"}} @q;
+ if (@pq > 1) {
+ my %pq = map {$_ => 1} @pq;
+ @q = (grep {$pq{$_}} @{$config->{'prefer'}})[0];
+ } elsif (@pq == 1) {
+ @q = @pq;
+ }
+ }
+ if (@q > 1 && $r =~ /\|/) {
+ # choice op, implicit prefer of first match...
+ my %pq = map {$_ => 1} @q;
+ for my $rr (split(/\s*\|\s*/, $r)) {
+ next unless $whatprovides->{$rr};
+ my @pq = grep {$pq{$_}} @{$whatprovides->{$rr}};
+ next unless @pq;
+ @q = @pq;
+ last;
+ }
+ }
+ if ($doamb == 2) {
+ todo2recommended($config, \%recommended, \@rec_todo) if @rec_todo;
+ my @pq = grep {$recommended{$_}} @q;
+ print "recommended [@pq] among [@q]\n" if $expand_dbg;
+ @q = @pq if @pq;
+ }
+ if (@q > 1) {
+ if ($r ne $p) {
+ push @error, "have choice for $r needed by $p: @q";
+ } else {
+ push @error, "have choice for $r: @q";
+ }
+ push @pamb, $p unless @pamb && $pamb[-1] eq $p;
+ next;
+ }
+ push @p, $q[0];
+ print "added $q[0] because of $p:$r\n" if $expand_dbg;
+ $p{$q[0]} = 1;
+ $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 @rec_todo, $q[0] if $userecommendsforchoices;
+ @error = ();
+ $doamb = 0;
+ }
+ }
+ return undef, @rerror if @rerror;
+ next if @p; # still work to do
+
+ # only ambig stuff left
+ if (@pamb && ($doamb == 0 || $doamb == 1)) {
+ @p = @pamb;
+ @pamb = ();
+ todo2recommended($config, \%recommended, \@rec_todo) if @rec_todo;
+ $doamb = %recommended ? 2 : 3;
+ print "now doing undecided dependencies, $doamb = $doamb\n" if $expand_dbg;
+ next;
+ }
+ return undef, @error if @error;
+ }
+ return 1, (sort keys %p);
+}
+
+sub order {
+ my ($config, @p) = @_;
+
+ my $requires = $config->{'requiresh'};
+ my $recommends = $config->{'recommendsh'};
+ my $whatprovides = $config->{'whatprovidesh'};
+ my %deps;
+ my %rdeps;
+ my %needed;
+ my %p = map {$_ => 1} @p;
+ for my $p (@p) {
+ my @r;
+ for my $r (@{$requires->{$p} || []}) {
+ my @q = @{$whatprovides->{$r} || addproviders($config, $r)};
+ push @r, grep {$_ ne $p && $p{$_}} @q;
+ }
+ if (%{$config->{'order'} || {}}) {
+ push @r, grep {$_ ne $p && $config->{'order'}->{"$_:$p"}} @p;
+ }
+ @r = unify(@r);
+ $deps{$p} = \@r;
+ $needed{$p} = @r;
+ push @{$rdeps{$_}}, $p for @r;
+ }
+ @p = sort {$needed{$a} <=> $needed{$b} || $a cmp $b} @p;
+ my @good;
+ my @res;
+ # the big sort loop
+ while (@p) {
+ @good = grep {$needed{$_} == 0} @p;
+ if (@good) {
+ @p = grep {$needed{$_}} @p;
+ push @res, @good;
+ for my $p (@good) {
+ $needed{$_}-- for @{$rdeps{$p}};
+ }
+ next;
+ }
+ # uh oh, cycle alert. find and remove all cycles.
+ my %notdone = map {$_ => 1} @p;
+ $notdone{$_} = 0 for @res; # already did those
+ my @todo = @p;
+ while (@todo) {
+ my $v = shift @todo;
+ if (ref($v)) {
+ $notdone{$$v} = 0; # finished this one
+ next;
+ }
+ my $s = $notdone{$v};
+ next unless $s;
+ my @e = grep {$notdone{$_}} @{$deps{$v}};
+ if (!@e) {
+ $notdone{$v} = 0; # all deps done, mark as finished
+ next;
+ }
+ if ($s == 1) {
+ $notdone{$v} = 2; # now under investigation
+ unshift @todo, @e, \$v;
+ next;
+ }
+ # reached visited package, found a cycle!
+ my @cyc = ();
+ my $cycv = $v;
+ # go back till $v is reached again
+ while(1) {
+ die unless @todo;
+ $v = shift @todo;
+ next unless ref($v);
+ $v = $$v;
+ $notdone{$v} = 1 if $notdone{$v} == 2;
+ unshift @cyc, $v;
+ last if $v eq $cycv;
+ }
+ unshift @todo, $cycv;
+ print STDERR "cycle: ".join(' -> ', @cyc)."\n";
+ my $breakv;
+ my @breakv = (@cyc, $cyc[0]);
+ while (@breakv > 1) {
+ last if $config->{'order'}->{"$breakv[0]:$breakv[1]"};
+ shift @breakv;
+ }
+ if (@breakv > 1) {
+ $breakv = $breakv[0];
+ } else {
+ $breakv = (sort {$needed{$a} <=> $needed{$b} || $a cmp $b} @cyc)[-1];
+ }
+ push @cyc, $cyc[0]; # make it loop
+ shift @cyc while $cyc[0] ne $breakv;
+ $v = $cyc[1];
+ print STDERR " breaking dependency $breakv -> $v\n";
+ $deps{$breakv} = [ grep {$_ ne $v} @{$deps{$breakv}} ];
+ $rdeps{$v} = [ grep {$_ ne $breakv} @{$rdeps{$v}} ];
+ $needed{$breakv}--;
+ }
+ }
+ return @res;
+}
+
+sub add_all_providers {
+ my ($config, @p) = @_;
+ my $whatprovides = $config->{'whatprovidesh'};
+ my $requires = $config->{'requiresh'};
+ my $recommends = $config->{'recommendsh'};
+ my %a;
+ for my $p (@p) {
+ for my $r (@{$requires->{$p} || [$p]}) {
+ my $rn = (split(' ', $r, 2))[0];
+ $a{$_} = 1 for @{$whatprovides->{$rn} || []};
+ }
+ }
+ push @p, keys %a;
+ return unify(@p);
+}
+
+###########################################################################
+
+sub recipe2buildtype {
+ my ($recipe) = @_;
+ return undef unless defined $recipe;
+ return $1 if $recipe =~ /\.(spec|dsc|kiwi|livebuild)$/;
+ $recipe =~ s/.*\///;
+ $recipe =~ s/^_service:.*://;
+ return 'arch' if $recipe eq 'PKGBUILD';
+ return 'collax' if $recipe eq 'build.collax';
+ return 'snapcraft' if $recipe eq 'snapcraft.yaml';
+ return 'preinstallimage' if $recipe eq '_preinstallimage';
+ return 'simpleimage' if $recipe eq 'simpleimage';
+ return undef;
+}
+
+sub show {
+ my ($conffile, $fn, $field, $arch) = @ARGV;
+ my $cf = read_config($arch, $conffile);
+ die unless $cf;
+ my $d = Build::parse($cf, $fn);
+ die("$d->{'error'}\n") if $d->{'error'};
+ $d->{'sources'} = [ map {ref($d->{$_}) ? @{$d->{$_}} : $d->{$_}} grep {/^source/} sort keys %$d ];
+ $d->{'patches'} = [ map {ref($d->{$_}) ? @{$d->{$_}} : $d->{$_}} grep {/^patch/} sort keys %$d ];
+ my $x = $d->{$field};
+ $x = [ $x ] unless ref $x;
+ print "$_\n" for @$x;
+}
+
+sub parse_preinstallimage {
+ return undef unless $do_rpm;
+ my $d = Build::Rpm::parse(@_);
+ $d->{'name'} ||= 'preinstallimage';
+ return $d;
+}
+
+sub parse_simpleimage {
+ return undef unless $do_rpm;
+ my $d = Build::Rpm::parse(@_);
+ $d->{'name'} ||= 'simpleimage';
+ if (!defined($d->{'version'})) {
+ my @s = stat($_[1]);
+ $d->{'version'} = strftime "%Y.%m.%d-%H.%M.%S", gmtime($s[9] || time);
+ }
+ return $d;
+}
+
+sub parse {
+ my ($cf, $fn, @args) = @_;
+ return Build::Rpm::parse($cf, $fn, @args) if $do_rpm && $fn =~ /\.spec$/;
+ 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::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 parse_simpleimage($cf, $fn, @args) if $fnx eq 'simpleimage';
+ return Build::Snapcraft::parse($cf, $fn, @args) if $do_snapcraft && $fnx eq 'snapcraft.yaml';
+ return Build::Arch::parse($cf, $fn, @args) if $do_arch && $fnx eq 'PKGBUILD';
+ return Build::Collax::parse($cf, $fn, @args) if $do_collax && $fnx eq 'build.collax';
+ 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::Snapcraft::parse($cf, $fn, @args) if $do_snapcraft && $buildtype eq 'snapcraft';
+ return parse_simpleimage($cf, $fn, @args) if $buildtype eq 'simpleimage';
+ return Build::Arch::parse($cf, $fn, @args) if $do_arch && $buildtype eq 'arch';
+ return Build::Collax::parse($cf, $fn, @args) if $do_collax && $buildtype eq 'collax';
+ return parse_preinstallimage($cf, $fn, @args) if $buildtype eq 'preinstallimage';
+ return undef;
+}
+
+sub query {
+ my ($binname, %opts) = @_;
+ my $handle = $binname;
+ if (ref($binname) eq 'ARRAY') {
+ $handle = $binname->[1];
+ $binname = $binname->[0];
+ }
+ return Build::Rpm::query($handle, %opts) if $do_rpm && $binname =~ /\.d?rpm$/;
+ return Build::Deb::query($handle, %opts) if $do_deb && $binname =~ /\.deb$/;
+ return Build::Kiwi::queryiso($handle, %opts) if $do_kiwi && $binname =~ /\.iso$/;
+ return Build::Arch::query($handle, %opts) if $do_arch && $binname =~ /\.pkg\.tar(?:\.gz|\.xz)?$/;
+ return Build::Arch::query($handle, %opts) if $do_arch && $binname =~ /\.arch$/;
+ 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 =~ /\.d?rpm$/;
+ return Build::Deb::queryhdrmd5(@_) if $do_deb && $binname =~ /\.deb$/;
+ return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.iso$/;
+ return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.raw$/;
+ return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.raw.install$/;
+ return Build::Arch::queryhdrmd5(@_) if $do_arch && $binname =~ /\.pkg\.tar(?:\.gz|\.xz)?$/;
+ return Build::Arch::queryhdrmd5(@_) if $do_arch && $binname =~ /\.arch$/;
+ 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;
diff --git a/Build/Arch.pm b/Build/Arch.pm
new file mode 100644
index 0000000..8da6be0
--- /dev/null
+++ b/Build/Arch.pm
@@ -0,0 +1,329 @@
+################################################################
+#
+# 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;
+use Digest::MD5;
+
+eval { require Archive::Tar; };
+*Archive::Tar::new = sub {die("Archive::Tar is not available\n")} unless defined &Archive::Tar::new;
+
+
+# Archlinux support, based on the GSoC work of Nikolay Rysev <mad.f3ka@gmail.com>
+
+# parse a PKGBUILD file
+
+sub quote {
+ my ($str, $q, $vars) = @_;
+ if ($q ne "'" && $str =~ /\$/) {
+ $str =~ s/\$([a-zA-Z0-9_]+|\{([^\}]+)\})/join(' ', @{$vars->{$2 || $1} || []})/ge;
+ }
+ $str =~ s/([ \t\"\'\$])/sprintf("%%%02X", ord($1))/ge;
+ return $str;
+}
+
+sub unquotesplit {
+ my ($str, $vars) = @_;
+ $str =~ s/%/%25/g;
+ $str =~ s/^[ \t]+//;
+ while ($str =~ /([\"\'])/) {
+ my $q = $1;
+ last unless $str =~ s/$q(.*?)$q/quote($1, $q, $vars)/e;
+ }
+ if ($str =~ /\$/) {
+ $str =~ s/\$([a-zA-Z0-9_]+|\{([^\}]+)\})/join(' ', @{$vars->{$2 || $1} || []})/ge;
+ }
+ my @args = split(/[ \t]+/, $str);
+ for (@args) {
+ s/%([a-fA-F0-9]{2})/chr(hex($1))/ge
+ }
+ return @args;
+}
+
+sub parse {
+ my ($config, $pkgbuild) = @_;
+ my $ret;
+ local *PKG;
+ if (!open(PKG, '<', $pkgbuild)) {
+ $ret->{'error'} = "$pkgbuild: $!";
+ return $ret;
+ }
+ my %vars;
+ my @ifs;
+ while (<PKG>) {
+ chomp;
+ next if /^\s*$/;
+ next if /^\s*#/;
+ s/^\s+//;
+ if (/^(el)?if\s+(?:(?:test|\[)\s+(-n|-z)\s+)?(.*?)\s*\]?\s*;\s*then\s*$/) {
+ if ($1) {
+ $ifs[-1] += 1;
+ next if $ifs[-1] != 1;
+ pop @ifs;
+ }
+ my $flag = $2 || '-n';
+ my $t = join('', unquotesplit($3, \%vars));
+ $t = $t eq '' ? 'true' : '' if $flag eq '-z';
+ push @ifs, $t ne '' ? 1 : 0;
+ next;
+ }
+ if (@ifs) {
+ if (/^fi\s*$/) {
+ pop @ifs;
+ next;
+ } elsif (/^else\s*$/) {
+ $ifs[-1] += 1;
+ next;
+ }
+ next if grep {$_ != 1} @ifs;
+ }
+ last unless /^([a-zA-Z0-9_]*)(\+?)=(\(?)(.*?)$/;
+ my $var = $1;
+ my $app = $2;
+ my $val = $4;
+ if ($3) {
+ while ($val !~ s/\)\s*(?:#.*)?$//s) {
+ my $nextline = <PKG>;
+ last unless defined $nextline;
+ chomp $nextline;
+ $val .= ' ' . $nextline;
+ }
+ }
+ if ($app) {
+ push @{$vars{$var}}, unquotesplit($val, \%vars);
+ } else {
+ $vars{$var} = [ unquotesplit($val, \%vars) ];
+ }
+ }
+ close PKG;
+ $ret->{'name'} = $vars{'pkgname'}->[0] if $vars{'pkgname'};
+ $ret->{'version'} = $vars{'pkgver'}->[0] if $vars{'pkgver'};
+ $ret->{'deps'} = [];
+ push @{$ret->{'deps'}}, @{$vars{$_} || []} for qw{makedepends checkdepends depends};
+ # get arch from macros
+ my $arch;
+ for (@{$config->{'macros'} || []}) {
+ $arch = $1 if /^%define _target_cpu (\S+)/;
+ }
+ # map to arch linux name and add arch dependent
+ $arch = 'i686' if $arch =~ /^i[345]86$/;
+ push @{$ret->{'deps'}}, @{$vars{"${_}_$arch"} || []} for qw{makedepends checkdepends depends};
+ # Maintain architecture-specific sources for officially supported architectures
+ for my $asuf ('', '_i686', '_x86_64') {
+ $ret->{"source$asuf"} = $vars{"source$asuf"} if $vars{"source$asuf"};
+ }
+ return $ret;
+}
+
+sub islzma {
+ my ($fn) = @_;
+ local *F;
+ return 0 unless open(F, '<', $fn);
+ my $h;
+ return 0 unless read(F, $h, 5) == 5;
+ close F;
+ return $h eq "\3757zXZ";
+}
+
+sub lzmadec {
+ my ($fn) = @_;
+ my $nh;
+ my $pid = open($nh, '-|');
+ return undef unless defined $pid;
+ if (!$pid) {
+ $SIG{'PIPE'} = 'DEFAULT';
+ exec('xzdec', '-dc', $fn);
+ die("xzdec: $!\n");
+ }
+ return $nh;
+}
+
+sub queryvars {
+ my ($handle) = @_;
+
+ if (ref($handle)) {
+ die("arch pkg query not implemented for file handles\n");
+ }
+ if ($handle =~ /\.xz$/ || islzma($handle)) {
+ $handle = lzmadec($handle);
+ }
+ my $tar = Archive::Tar->new;
+ my @read = $tar->read($handle, 1, {'filter' => '^\.PKGINFO$', 'limit' => 1});
+ die("$handle: not an arch package file\n") unless @read == 1;
+ my $pkginfo = $read[0]->get_content;
+ die("$handle: not an arch package file\n") unless $pkginfo;
+ my %vars;
+ $vars{'_pkginfo'} = $pkginfo;
+ for my $l (split('\n', $pkginfo)) {
+ next unless $l =~ /^(.*?) = (.*)$/;
+ push @{$vars{$1}}, $2;
+ }
+ return \%vars;
+}
+
+sub queryfiles {
+ my ($handle) = @_;
+ if (ref($handle)) {
+ die("arch pkg query not implemented for file handles\n");
+ }
+ if ($handle =~ /\.xz$/ || islzma($handle)) {
+ $handle = lzmadec($handle);
+ }
+ my @files;
+ my $tar = Archive::Tar->new;
+ # we use filter_cb here so that Archive::Tar skips the file contents
+ $tar->read($handle, 1, {'filter_cb' => sub {
+ my ($entry) = @_;
+ push @files, $entry->name unless $entry->is_longlink || (@files && $files[-1] eq $entry->name);
+ return 0;
+ }});
+ shift @files if @files && $files[0] eq '.PKGINFO';
+ return \@files;
+}
+
+sub query {
+ my ($handle, %opts) = @_;
+ my $vars = queryvars($handle);
+ my $ret = {};
+ $ret->{'name'} = $vars->{'pkgname'}->[0] if $vars->{'pkgname'};
+ $ret->{'hdrmd5'} = Digest::MD5::md5_hex($vars->{'_pkginfo'});
+ $ret->{'provides'} = $vars->{'provides'} || [];
+ $ret->{'requires'} = $vars->{'depend'} || [];
+ 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;
+ }
+ if ($opts{'evra'}) {
+ if ($vars->{'pkgver'}) {
+ my $evr = $vars->{'pkgver'}->[0];
+ if ($evr =~ /^([0-9]+):(.*)$/) {
+ $ret->{'epoch'} = $1;
+ $evr = $2;
+ }
+ $ret->{'version'} = $evr;
+ if ($evr =~ /^(.*)-(.*?)$/) {
+ $ret->{'version'} = $1;
+ $ret->{'release'} = $2;
+ }
+ }
+ $ret->{'arch'} = $vars->{'arch'}->[0] if $vars->{'arch'};
+ }
+ 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;
+}
+
+sub queryhdrmd5 {
+ my ($handle) = @_;
+ if (ref($handle)) {
+ die("arch pkg query not implemented for file handles\n");
+ }
+ if ($handle =~ /\.xz$/ || islzma($handle)) {
+ $handle = lzmadec($handle);
+ }
+ my $tar = Archive::Tar->new;
+ my @read = $tar->read($handle, 1, {'filter' => '^\.PKGINFO$', 'limit' => 1});
+ die("$handle: not an arch package file\n") unless @read == 1;
+ my $pkginfo = $read[0]->get_content;
+ die("$handle: not an arch package file\n") unless $pkginfo;
+ return Digest::MD5::md5_hex($pkginfo);
+}
+
+sub parserepodata {
+ my ($d, $data) = @_;
+ $d ||= {};
+ $data =~ s/^\n+//s;
+ my @parts = split(/\n\n+/s, $data);
+ for my $part (@parts) {
+ my @p = split("\n", $part);
+ my $p = shift @p;
+ if ($p eq '%NAME%') {
+ $d->{'name'} = $p[0];
+ } elsif ($p eq '%VERSION%') {
+ $d->{'version'} = $p[0];
+ } elsif ($p eq '%ARCH%') {
+ $d->{'arch'} = $p[0];
+ } elsif ($p eq '%BUILDDATE%') {
+ $d->{'buildtime'} = $p[0];
+ } elsif ($p eq '%FILENAME%') {
+ $d->{'filename'} = $p[0];
+ } elsif ($p eq '%PROVIDES%') {
+ 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;
+ } elsif ($p eq '%MD5SUM%') {
+ $d->{'checksum_md5'} = $p[0];
+ } elsif ($p eq '%SHA256SUM%') {
+ $d->{'checksum_sha256'} = $p[0];
+ }
+ }
+ 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
index 0000000..1952251
--- /dev/null
+++ b/Build/Archrepo.pm
@@ -0,0 +1,98 @@
+################################################################
+#
+# 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; };
+if (!defined &Archive::Tar::iter) {
+ *Archive::Tar::iter = sub {
+ my ($class, $filename) = @_;
+ die("Archive::Tar is not available\n") unless defined &Archive::Tar::new;
+ Archive::Tar->new();
+ my $handle = $class->_get_handle($filename, 1, 'rb') or return undef;
+ my @data;
+ return sub {
+ return shift(@data) if !$handle || @data;
+ my $files = $class->_read_tar($handle, { limit => 1 });
+ @data = @$files if (ref($files) || '') eq 'ARRAY';
+ undef $handle unless @data;
+ return shift @data;
+ };
+ };
+}
+
+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 ($options->{'withchecksum'}) {
+ for (qw {md5 sha1 sha256}) {
+ my $c = delete($data->{"checksum_$_"});
+ $data->{'checksum'} = "$_:$c" if $c;
+ }
+ } else {
+ delete $data->{"checksum_$_"} for qw {md5 sha1 sha256};
+ }
+ 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;
diff --git a/Build/Collax.pm b/Build/Collax.pm
new file mode 100644
index 0000000..2fc332c
--- /dev/null
+++ b/Build/Collax.pm
@@ -0,0 +1,64 @@
+#
+# Copyright 2015 Zarafa B.V. and its licensors
+#
+# 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 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.
+#
+package Build::Collax;
+
+use strict;
+
+sub parse {
+ my($buildconf, $fn) = @_;
+ my @bscript;
+
+ if (ref($fn) eq "ARRAY") {
+ @bscript = @$fn;
+ $fn = undef;
+ } elsif (ref($fn) ne "") {
+ die "Unhandled ref type in collax";
+ } else {
+ local *FH;
+ if (!open(FH, "<", $fn)) {
+ return {"error" => "$fn: $!"};
+ }
+ @bscript = <FH>;
+ chomp(@bscript);
+ close(FH);
+ }
+
+ my $ret = {"deps" => []};
+ for (my $i = 0; $i <= $#bscript; ++$i) {
+ next unless $bscript[$i] =~ m{^\w+=};
+ my $key = lc(substr($&, 0, -1));
+ my $value = $';
+ if ($value =~ m{^([\'\"])}) {
+ $value = substr($value, 1);
+ while ($value !~ m{[\'\"]}) {
+ my @cut = splice(@bscript, $i + 1, 1);
+ $value .= $cut[0];
+ }
+ $value =~ s{[\'\"]}{}s;
+ $value =~ s{\n}{ }gs;
+ }
+ if ($key eq "package") {
+ $ret->{"name"} = $value;
+ } elsif ($key eq "version") {
+ $ret->{$key} = $value;
+ } elsif ($key eq "builddepends" || $key eq "extradepends") {
+ $value =~ s{^\s+}{}gs;
+ $value =~ s{\s+$}{}gs;
+ $value =~ s{,}{ }gs;
+ push(@{$ret->{"deps"}}, split(/\s+/, $value));
+ }
+ }
+ return $ret;
+}
+
+1;
diff --git a/Build/Deb.pm b/Build/Deb.pm
new file mode 100644
index 0000000..e723b58
--- /dev/null
+++ b/Build/Deb.pm
@@ -0,0 +1,469 @@
+################################################################
+#
+# 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;
+use Digest::MD5;
+
+my $have_zlib;
+eval {
+ require Compress::Zlib;
+ $have_zlib = 1;
+};
+
+my %obs2debian = (
+ "i486" => "i386",
+ "i586" => "i386",
+ "i686" => "i386",
+ "ppc" => "powerpc",
+ "ppc64le" => "ppc64el",
+ "x86_64" => "amd64",
+ "armv4l" => "armel",
+ "armv5l" => "armel",
+ "armv6l" => "armel",
+ "armv7el" => "armel",
+ "armv7l" => "armhf",
+ "armv7hl" => "armhf",
+ "aarch64" => "arm64",
+);
+
+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;
+ my @control;
+
+ # get arch and os from macros
+ my ($arch, $os);
+ for (@{$bconf->{'macros'} || []}) {
+ $arch = $1 if /^%define _target_cpu (\S+)/;
+ $os = $1 if /^%define _target_os (\S+)/;
+ }
+ # map to debian names
+ $os = 'linux' if !defined($os);
+ $arch = basearch($arch);
+
+ if (ref($fn) eq 'ARRAY') {
+ @control = @$fn;
+ } else {
+ local *F;
+ if (!open(F, '<', $fn)) {
+ $ret->{'error'} = "$fn: $!";
+ return $ret;
+ }
+ @control = <F>;
+ close F;
+ chomp @control;
+ }
+ splice(@control, 0, 3) if @control > 3 && $control[0] =~ /^-----BEGIN/;
+ my $name;
+ my $version;
+ my @deps;
+ my @exclarch;
+ 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;
+ if ($tag eq 'VERSION') {
+ $version = $data;
+ $version =~ s/-[^-]+$//;
+ } elsif ($tag eq 'ARCHITECTURE') {
+ my @archs = split('\s+', $data);
+ map { s/\Q$os\E-//; 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*,\s*/, $data);
+ for my $d (@d) {
+ my @alts = split('\s*\|\s*', $d);
+ my @needed;
+ for my $c (@alts) {
+ if ($c =~ /\s+<[^>]+>$/) {
+ my @build_profiles; # Empty for now
+ my $bad = 1;
+ while ($c =~ s/\s+<([^>]+)>$//) {
+ next if (!$bad);
+ my $list_valid = 1;
+ for my $term (split(/\s+/, $1)) {
+ my $isneg = ($term =~ s/^\!//);
+ my $profile_match = grep(/^$term$/, @build_profiles);
+ if (( $profile_match && $isneg) ||
+ (!$profile_match && !$isneg)) {
+ $list_valid = 0;
+ last;
+ }
+ }
+ $bad = 0 if ($list_valid);
+ }
+ next if ($bad);
+ }
+ if ($c =~ /^(.*?)\s*\[(.*)\]$/) {
+ $c = $1;
+ my $isneg = 0;
+ my $bad;
+ for my $q (split('[\s,]', $2)) {
+ $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" || $q eq "any-$arch") {
+ $bad = 1;
+ last;
+ }
+ } elsif ($q eq $arch || $q eq 'any' || $q eq "$os-$arch" || $q eq "$os-any" || $q eq "any-$arch") {
+ $bad = 0;
+ }
+ }
+ next if ($bad);
+ }
+ $c =~ s/^([^:\s]*):(any|native)(.*)$/$1$3/;
+ push @needed, $c;
+ }
+ next unless @needed;
+ $d = join(' | ', @needed);
+ $d =~ s/ \(([^\)]*)\)/ $1/g;
+ $d =~ s/>>/>/g;
+ $d =~ s/<</</g;
+ if ($tag eq 'BUILD-DEPENDS' || $tag eq 'BUILD-DEPENDS-INDEP') {
+ push @deps, $d;
+ } else {
+ push @deps, "-$d";
+ }
+ }
+ }
+ }
+ $ret->{'name'} = $name;
+ $ret->{'version'} = $version;
+ $ret->{'deps'} = \@deps;
+ $ret->{'exclarch'} = \@exclarch if @exclarch;
+ return $ret;
+}
+
+sub ungzip {
+ my $data = shift;
+ local (*TMP, *TMP2);
+ open(TMP, "+>", undef) or die("could not open tmpfile\n");
+ syswrite TMP, $data;
+ sysseek(TMP, 0, 0);
+ my $pid = open(TMP2, "-|");
+ die("fork: $!\n") unless defined $pid;
+ if (!$pid) {
+ open(STDIN, "<&TMP");
+ exec 'gunzip';
+ die("gunzip: $!\n");
+ }
+ close(TMP);
+ $data = '';
+ 1 while sysread(TMP2, $data, 1024, length($data)) > 0;
+ close(TMP2) || die("gunzip error");
+ 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) = @_;
+
+ local *DEBF;
+ if (ref($fn) eq 'GLOB') {
+ *DEBF = *$fn;
+ } elsif (!open(DEBF, '<', $fn)) {
+ warn("$fn: $!\n");
+ return ();
+ }
+ my $data = '';
+ sysread(DEBF, $data, 4096);
+ if (length($data) < 8+60) {
+ warn("$fn: not a debian package - header too short\n");
+ close DEBF unless ref $fn;
+ return ();
+ }
+ if (substr($data, 0, 8+16) ne "!<arch>\ndebian-binary " &&
+ substr($data, 0, 8+16) ne "!<arch>\ndebian-binary/ ") {
+ close DEBF unless ref $fn;
+ return ();
+ }
+ my $len = substr($data, 8+48, 10);
+ $len += $len & 1;
+ if (length($data) < 8+60+$len+60) {
+ my $r = 8+60+$len+60 - length($data);
+ $r -= length($data);
+ if ((sysread(DEBF, $data, $r < 4096 ? 4096 : $r, length($data)) || 0) < $r) {
+ warn("$fn: unexpected EOF\n");
+ close DEBF unless ref $fn;
+ return ();
+ }
+ }
+ $data = substr($data, 8 + 60 + $len);
+ if (substr($data, 0, 16) ne 'control.tar.gz ' &&
+ substr($data, 0, 16) ne 'control.tar.gz/ ') {
+ warn("$fn: control.tar.gz is not second ar entry\n");
+ close DEBF unless ref $fn;
+ return ();
+ }
+ $len = substr($data, 48, 10);
+ if (length($data) < 60+$len) {
+ my $r = 60+$len - length($data);
+ if ((sysread(DEBF, $data, $r, length($data)) || 0) < $r) {
+ warn("$fn: unexpected EOF\n");
+ close DEBF unless ref $fn;
+ return ();
+ }
+ }
+ close DEBF unless ref($fn);
+ $data = substr($data, 60, $len);
+ my $controlmd5 = Digest::MD5::md5_hex($data); # our header signature
+ if ($have_zlib) {
+ $data = Compress::Zlib::memGunzip($data);
+ } else {
+ $data = ungzip($data);
+ }
+ if (!$data) {
+ warn("$fn: corrupt control.tar.gz file\n");
+ return ();
+ }
+ my $control;
+ while (length($data) >= 512) {
+ my $n = substr($data, 0, 100);
+ $n =~ s/\0.*//s;
+ my $len = oct('00'.substr($data, 124,12));
+ my $blen = ($len + 1023) & ~511;
+ if (length($data) < $blen) {
+ warn("$fn: corrupt control.tar.gz file\n");
+ return ();
+ }
+ if ($n eq './control' || $n eq "control") {
+ $control = substr($data, 512, $len);
+ last;
+ }
+ $data = substr($data, $blen);
+ }
+ my %res = control2res($control);
+ $res{'CONTROL_MD5'} = $controlmd5;
+ return %res;
+}
+
+sub query {
+ my ($handle, %opts) = @_;
+
+ my %res = debq($handle);
+ return undef unless %res;
+ my $name = $res{'PACKAGE'};
+ my $src = $name;
+ if ($res{'SOURCE'}) {
+ $src = $res{'SOURCE'};
+ $src =~ s/\s.*$//;
+ }
+ my @provides = split(',\s*', $res{'PROVIDES'} || '');
+ if ($opts{'addselfprovides'}) {
+ push @provides, "$name (= $res{'VERSION'})";
+ }
+ my @depends = split(',\s*', $res{'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;
+ $data->{'epoch'} = $1 if defined $1;
+ $data->{'version'} = $2;
+ $data->{'release'} = $3 if defined $3;
+ $data->{'arch'} = $res{'ARCHITECTURE'};
+ }
+ 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;
+}
+
+sub queryhdrmd5 {
+ my ($bin) = @_;
+
+ local *F;
+ open(F, '<', $bin) || die("$bin: $!\n");
+ my $data = '';
+ sysread(F, $data, 4096);
+ if (length($data) < 8+60) {
+ warn("$bin: not a debian package - header too short\n");
+ close F;
+ return undef;
+ }
+ if (substr($data, 0, 8+16) ne "!<arch>\ndebian-binary " &&
+ substr($data, 0, 8+16) ne "!<arch>\ndebian-binary/ ") {
+ warn("$bin: not a debian package - no \"debian-binary\" entry\n");
+ close F;
+ return undef;
+ }
+ my $len = substr($data, 8+48, 10);
+ $len += $len & 1;
+ if (length($data) < 8+60+$len+60) {
+ my $r = 8+60+$len+60 - length($data);
+ $r -= length($data);
+ if ((sysread(F, $data, $r < 4096 ? 4096 : $r, length($data)) || 0) < $r) {
+ warn("$bin: unexpected EOF\n");
+ close F;
+ return undef;
+ }
+ }
+ $data = substr($data, 8 + 60 + $len);
+ if (substr($data, 0, 16) ne 'control.tar.gz ' &&
+ substr($data, 0, 16) ne 'control.tar.gz/ ') {
+ warn("$bin: control.tar.gz is not second ar entry\n");
+ close F;
+ return undef;
+ }
+ $len = substr($data, 48, 10);
+ if (length($data) < 60+$len) {
+ my $r = 60+$len - length($data);
+ if ((sysread(F, $data, $r, length($data)) || 0) < $r) {
+ warn("$bin: unexpected EOF\n");
+ close F;
+ return undef;
+ }
+ }
+ close F;
+ $data = substr($data, 60, $len);
+ return Digest::MD5::md5_hex($data);
+}
+
+sub verscmp_part {
+ my ($s1, $s2) = @_;
+ return 0 if $s1 eq $s2;
+ $s1 =~ s/([0-9]+)/substr("00000000000000000000000000000000$1", -32, 32)/ge;
+ $s2 =~ s/([0-9]+)/substr("00000000000000000000000000000000$1", -32, 32)/ge;
+ $s1 .= "\0";
+ $s2 .= "\0";
+ $s1 =~ tr[\176\000-\037\060-\071\101-\132\141-\172\040-\057\072-\100\133-\140\173-\175][\000-\176];
+ $s2 =~ tr[\176\000-\037\060-\071\101-\132\141-\172\040-\057\072-\100\133-\140\173-\175][\000-\176];
+ return $s1 cmp $s2;
+}
+
+sub verscmp {
+ my ($s1, $s2) = @_;
+ my ($e1, $v1, $r1) = $s1 =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
+ $e1 = 0 unless defined $e1;
+ my ($e2, $v2, $r2) = $s2 =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
+ $e2 = 0 unless defined $e2;
+ if ($e1 ne $e2) {
+ my $r = verscmp_part($e1, $e2);
+ return $r if $r;
+ }
+ my $r = verscmp_part($v1, $v2);
+ return $r if $r;
+ $r1 = '' unless defined $r1;
+ $r2 = '' unless defined $r2;
+ 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
index 0000000..328fd79
--- /dev/null
+++ b/Build/Debrepo.pm
@@ -0,0 +1,130 @@
+################################################################
+#
+# 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 ($options->{'withchecksum'}) {
+ for (qw {md5 sha1 sha256}) {
+ my $c = delete($data->{"checksum_$_"});
+ $data->{'checksum'} = "$_:$c" if $c;
+ }
+ }
+ 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',
+);
+
+my %tmap_checksums = (
+ 'md5sum' => 'checksum_md5',
+ 'sha1' => 'checksum_sha1',
+ 'sha256' => 'checksum_sha256',
+);
+
+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;
+ my %ltmap = %tmap;
+ %ltmap = (%ltmap, %tmap_checksums) if $options{'withchecksum'};
+ 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;
diff --git a/Build/Kiwi.pm b/Build/Kiwi.pm
new file mode 100644
index 0000000..7d94e2f
--- /dev/null
+++ b/Build/Kiwi.pm
@@ -0,0 +1,329 @@
+################################################################
+#
+# 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;
+use Build::SimpleXML;
+
+our $bootcallback;
+our $urlmapper;
+
+sub unify {
+ my %h = map {$_ => 1} @_;
+ return grep(delete($h{$_}), @_);
+}
+
+sub findFallBackArchs {
+ my ($fallbackArchXML, $arch) = @_;
+ my @fa;
+
+ for my $a (@{$fallbackArchXML->{'arch'}||[]}) {
+ if ( $a->{'id'} eq $arch && $a->{'fallback'} ) {
+ @fa = unify( $a->{'fallback'}, findFallBackArchs($fallbackArchXML, $a->{'fallback'}));
+ }
+ }
+
+ return @fa
+}
+
+# sles10 perl does not have the version.pm
+# implement own hack
+sub versionstring {
+ my ($str) = @_;
+ my @xstr = split (/\./,$str);
+ my $result = 0;
+ while (my $digit = shift(@xstr)) {
+ $result = $result * 100;
+ $result += $digit;
+ }
+ return $result;
+}
+
+sub kiwiparse {
+ my ($xml, $arch, $count) = @_;
+ $count ||= 0;
+ die("kiwi config inclusion depth limit reached\n") if $count++ > 10;
+
+ my $ret = {};
+ my @types;
+ my @repos;
+ my @bootrepos;
+ my @packages;
+ my @extrasources;
+ my @requiredarch;
+ my @badarch;
+ my $schemaversion = 0;
+ my $schemaversion56 = versionstring("5.6");
+ my $obsexclusivearch;
+ my $obsexcludearch;
+ $obsexclusivearch = $1 if $xml =~ /^\s*<!--\s+OBS-ExclusiveArch:\s+(.*)\s+-->\s*$/im;
+ $obsexcludearch = $1 if $xml =~ /^\s*<!--\s+OBS-ExcludeArch:\s+(.*)\s+-->\s*$/im;
+ my $kiwi = Build::SimpleXML::parse($xml);
+ die("not a kiwi config\n") unless $kiwi && $kiwi->{'image'};
+ $kiwi = $kiwi->{'image'}->[0];
+ $schemaversion = versionstring($kiwi->{'schemaversion'}) if $kiwi->{'schemaversion'};
+ $ret->{'filename'} = $kiwi->{'name'} if $kiwi->{'name'};
+ my $description = (($kiwi->{'description'} || [])->[0]) || {};
+ if ($description->{'specification'}) {
+ $ret->{'name'} = $description->{'specification'}->[0]->{'_content'};
+ }
+ # take default version setting
+ my $preferences = ($kiwi->{'preferences'} || []);
+ if ($preferences->[0]->{'version'}) {
+ $ret->{'version'} = $preferences->[0]->{'version'}->[0]->{'_content'};
+ }
+ for my $pref (@{$preferences || []}) {
+ for my $type (@{$pref->{'type'} || []}) {
+ next unless @{$pref->{'type'}} == 1 || !$type->{'optional'};
+ if (defined $type->{'image'}) {
+ # for kiwi 4.1 and 5.x
+ push @types, $type->{'image'};
+ push @packages, "kiwi-image:$type->{'image'}" if $schemaversion >= $schemaversion56;
+ } else {
+ # for kiwi 3.8 and before
+ push @types, $type->{'_content'};
+ }
+ push @packages, "kiwi-filesystem:$type->{'filesystem'}" if $type->{'filesystem'};
+ if (defined $type->{'boot'}) {
+ if ($type->{'boot'} =~ /^obs:\/\/\/?([^\/]+)\/([^\/]+)\/?$/) {
+ next unless $bootcallback;
+ my ($bootxml, $xsrc) = $bootcallback->($1, $2);
+ next unless $bootxml;
+ push @extrasources, $xsrc if $xsrc;
+ my $bret = kiwiparse($bootxml, $arch, $count);
+ push @bootrepos, map {"$_->{'project'}/$_->{'repository'}"} @{$bret->{'path'} || []};
+ push @packages, @{$bret->{'deps'} || []};
+ push @extrasources, @{$bret->{'extrasource'} || []};
+ } else {
+ die("bad boot reference: $type->{'boot'}\n") unless $type->{'boot'} =~ /^([^\/]+)\/([^\/]+)$/;
+ push @packages, "kiwi-boot:$1";
+ }
+ }
+ }
+ }
+
+ my $instsource = ($kiwi->{'instsource'} || [])->[0];
+ if ($instsource) {
+ for my $repository(sort {$a->{priority} <=> $b->{priority}} @{$instsource->{'instrepo'} || []}) {
+ my $kiwisource = ($repository->{'source'} || [])->[0];
+ if ($kiwisource->{'path'} eq 'obsrepositories:/') {
+ # special case, OBS will expand it.
+ push @repos, '_obsrepositories';
+ next;
+ }
+ if ($kiwisource->{'path'} =~ /^obs:\/\/\/?([^\/]+)\/([^\/]+)\/?$/) {
+ push @repos, "$1/$2";
+ } else {
+ my $prp;
+ $prp = $urlmapper->($kiwisource->{'path'}) if $urlmapper;
+ die("instsource repo url not using obs:/ scheme: $kiwisource->{'path'}\n") unless $prp;
+ push @repos, $prp;
+ }
+ }
+ $ret->{'sourcemedium'} = -1;
+ $ret->{'debugmedium'} = -1;
+ 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'} || []}) {
+ $ret->{'sourcemedium'} = $po->{'_content'} if $po->{'name'} eq 'SOURCEMEDIUM';
+ $ret->{'debugmedium'} = $po->{'_content'} if $po->{'name'} eq 'DEBUGMEDIUM';
+ }
+ }
+ if ($instsource->{'architectures'}) {
+ my $a = $instsource->{'architectures'}->[0] || {};
+ for my $ra (@{$a->{'requiredarch'} || []}) {
+ push @requiredarch, $ra->{'ref'} if defined $ra->{'ref'};
+ }
+ }
+ }
+
+ # set default values for priority
+ for (@{$kiwi->{'repository'} || []}) {
+ next if defined $_->{'priority'};
+ if ($preferences->[0]->{'packagemanager'}->[0]->{'_content'} eq 'smart') {
+ $_->{'priority'} = 0;
+ } else {
+ $_->{'priority'} = 99;
+ }
+ }
+ my @repositories = sort {$a->{'priority'} <=> $b->{'priority'}} @{$kiwi->{'repository'} || []};
+ if ($preferences->[0]->{'packagemanager'}->[0]->{'_content'} eq 'smart') {
+ @repositories = reverse @repositories;
+ }
+ for my $repository (@repositories) {
+ my $kiwisource = ($repository->{'source'} || [])->[0];
+ next if $kiwisource->{'path'} eq '/var/lib/empty'; # grr
+ if ($kiwisource->{'path'} eq 'obsrepositories:/') {
+ push @repos, '_obsrepositories/';
+ next;
+ }
+ if ($kiwisource->{'path'} =~ /^obs:\/\/\/?([^\/]+)\/([^\/]+)\/?$/) {
+ push @repos, "$1/$2";
+ } else {
+ my $prp;
+ $prp = $urlmapper->($kiwisource->{'path'}) if $urlmapper;
+ die("repo url not using obs:/ scheme: $kiwisource->{'path'}\n") unless $prp;
+ push @repos, $prp;
+ }
+ }
+
+ # Find packages and possible additional required architectures
+ my @additionalarchs;
+ my @pkgs;
+ for my $pattern (@{$kiwi->{'opensusePatterns'}}) {
+ push @pkgs, @{"pattern:$pattern->{'package'}"} if $pattern->{'package'};
+ }
+ for my $packages (@{$kiwi->{'packages'}}) {
+ next if $packages->{'type'} and $packages->{'type'} ne 'image' and $packages->{'type'} ne 'bootstrap';
+ push @pkgs, @{$packages->{'package'}} if $packages->{'package'};
+ }
+ if ($instsource) {
+ push @pkgs, @{$instsource->{'metadata'}->[0]->{'repopackage'} || []} if $instsource->{'metadata'};
+ push @pkgs, @{$instsource->{'repopackages'}->[0]->{'repopackage'} || []} if $instsource->{'repopackages'};
+ }
+ @pkgs = unify(@pkgs);
+ for my $package (@pkgs) {
+ # filter packages, which are not targeted for the wanted plattform
+ if ($package->{'arch'}) {
+ my $valid=undef;
+ if (@requiredarch) {
+ # this is a product
+ foreach my $ma(@requiredarch) {
+ foreach my $pa(split(",", $package->{'arch'})) {
+ $valid = 1 if $ma eq $pa;
+ }
+ }
+ } else {
+ # live appliance
+ my $ma = $arch;
+ $ma =~ s/i[456]86/i386/;
+ foreach my $pa(split(",", $package->{'arch'})) {
+ $pa =~ s/i[456]86/i386/;
+ $valid = 1 if $ma eq $pa;
+ }
+ }
+ next unless $valid;
+ }
+
+ # not nice, but optimizes our build dependencies
+ # FIXME: design a real blacklist option in kiwi
+ if ($package->{'onlyarch'} && $package->{'onlyarch'} eq "skipit") {
+ push @packages, "-".$package->{'name'};
+ next;
+ }
+ # handle replaces as buildignore
+ if ($package->{'replaces'}) {
+ push @packages, "-".$package->{'replaces'};
+ }
+
+ # we need this package
+ push @packages, $package->{'name'};
+
+ # find the maximal superset of possible required architectures
+ push @additionalarchs, split(',', $package->{'addarch'}) if $package->{'addarch'};
+ push @additionalarchs, split(',', $package->{'onlyarch'}) if $package->{'onlyarch'};
+ }
+ @requiredarch = unify(@requiredarch, @additionalarchs);
+
+ #### FIXME: kiwi files have no informations where to get -32bit packages from
+ push @requiredarch, "i586" if grep {/^ia64/} @requiredarch;
+ push @requiredarch, "i586" if grep {/^x86_64/} @requiredarch;
+ push @requiredarch, "ppc" if grep {/^ppc64/} @requiredarch;
+ push @requiredarch, "s390" if grep {/^s390x/} @requiredarch;
+
+ my @fallbackarchs;
+ for my $arch (@requiredarch) {
+ push @fallbackarchs, findFallBackArchs($instsource->{'architectures'}[0], $arch) if $instsource->{'architectures'}[0];
+ }
+ @requiredarch = unify(@requiredarch, @fallbackarchs);
+
+ if (!$instsource) {
+ my $packman = $preferences->[0]->{'packagemanager'}->[0]->{'_content'};
+ push @packages, "kiwi-packagemanager:$packman";
+ } else {
+ push @packages, "kiwi-packagemanager:instsource";
+ }
+
+ push @requiredarch, split(' ', $obsexclusivearch) if $obsexclusivearch;
+ push @badarch , split(' ', $obsexcludearch) if $obsexcludearch;
+
+ $ret->{'exclarch'} = [ unify(@requiredarch) ] if @requiredarch;
+ $ret->{'badarch'} = [ unify(@badarch) ] if @badarch;
+ $ret->{'deps'} = [ unify(@packages) ];
+ $ret->{'path'} = [ unify(@repos, @bootrepos) ];
+ $ret->{'imagetype'} = [ unify(@types) ];
+ $ret->{'extrasource'} = \@extrasources if @extrasources;
+ for (@{$ret->{'path'}}) {
+ my @s = split('/', $_, 2);
+ $_ = {'project' => $s[0], 'repository' => $s[1]};
+ }
+ return $ret;
+}
+
+sub parse {
+ my ($cf, $fn) = @_;
+
+ local *F;
+ open(F, '<', $fn) || die("$fn: $!\n");
+ my $xml = '';
+ 1 while sysread(F, $xml, 4096, length($xml)) > 0;
+ close F;
+ $cf ||= {};
+ my $d;
+ eval {
+ $d = kiwiparse($xml, ($cf->{'arch'} || ''));
+ };
+ if ($@) {
+ my $err = $@;
+ $err =~ s/^\n$//s;
+ return {'error' => $err};
+ }
+ return $d;
+}
+
+sub show {
+ my ($fn, $field, $arch) = @ARGV;
+ local $urlmapper = sub { return $_[0] };
+ my $cf = {'arch' => $arch};
+ my $d = parse($cf, $fn);
+ die("$d->{'error'}\n") if $d->{'error'};
+ my $x = $d->{$field};
+ $x = [ $x ] unless ref $x;
+ print "@$x\n";
+}
+
+# not implemented yet.
+sub queryiso {
+ my ($handle, %opts) = @_;
+ return {};
+}
+
+
+sub queryhdrmd5 {
+ my ($bin) = @_;
+ die("Build::Kiwi::queryhdrmd5 unimplemented.\n");
+}
+
+1;
diff --git a/Build/LiveBuild.pm b/Build/LiveBuild.pm
new file mode 100644
index 0000000..fbc66d9
--- /dev/null
+++ b/Build/LiveBuild.pm
@@ -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/Mdkrepo.pm b/Build/Mdkrepo.pm
new file mode 100644
index 0000000..2ea669a
--- /dev/null
+++ b/Build/Mdkrepo.pm
@@ -0,0 +1,121 @@
+################################################################
+#
+# Copyright (c) 2015 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::Mdkrepo;
+
+use strict;
+use Data::Dumper;
+
+sub addpkg {
+ my ($res, $data, $options) = @_;
+ 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 parsedeps {
+ my ($d) = @_;
+ my @d = split('@', $d);
+ for (@d) {
+ s/\[\*\]//s;
+ s/\[(.*)\]$/ $1/s;
+ s/ == / = /;
+ }
+ return \@d;
+}
+
+sub parse {
+ my ($in, $res, %options) = @_;
+ $res ||= [];
+ my $fd;
+ if (ref($in)) {
+ $fd = $in;
+ } else {
+ if ($in =~ /\.[gc]z$/) {
+ # we need to probe, as mageia uses xz for compression
+ open($fd, '<', $in) || die("$in: $!\n");
+ my $probe;
+ sysread($fd, $probe, 5);
+ close($fd);
+ if ($probe && $probe eq "\xFD7zXZ") {
+ open($fd, '-|', "xzdec", "-dc", $in) || die("$in: $!\n");
+ } else {
+ open($fd, '-|', "gzip", "-dc", $in) || die("$in: $!\n");
+ }
+ } else {
+ open($fd, '<', $in) || die("$in: $!\n");
+ }
+ }
+ my $s = {};
+ while (<$fd>) {
+ chomp;
+ if (/^\@summary\@/) {
+ $s->{'summary'} = substr($_, 9);
+ } elsif (/^\@provides\@/) {
+ $s->{'provides'} = parsedeps(substr($_, 10));
+ } elsif (/^\@requires\@/) {
+ $s->{'requires'} = parsedeps(substr($_, 10));
+ } elsif (/^\@suggests\@/) {
+ $s->{'suggests'} = parsedeps(substr($_, 10));
+ } elsif (/^\@recommends\@/) {
+ $s->{'recommends'} = parsedeps(substr($_, 12));
+ } elsif (/^\@obsoletes\@/) {
+ $s->{'obsoletes'} = parsedeps(substr($_, 11));
+ } elsif (/^\@conflicts\@/) {
+ $s->{'conflicts'} = parsedeps(substr($_, 11));
+ } elsif (/^\@info\@/) {
+ $s ||= {};
+ my @s = split('@', substr($_, 6));
+ $s->{'location'} = "$s[0].rpm";
+ my $arch;
+ if ($s[0] =~ /\.([^\.]+)$/) {
+ $arch = $1;
+ $s[0] =~ s/\.[^\.]+$//;
+ }
+ $s->{'epoch'} = $s[1] if $s[1];
+ $s[0] =~ s/-\Q$s[4]\E[^-]*$//s if defined($s[4]) && $s[4] ne ''; # strip disttag
+ $s[0] .= ":$s[5]" if defined($s[5]) && $s[5] ne ''; # add distepoch
+ $s->{'arch'} = $arch || 'noarch';
+ if ($s[0] =~ /^(.*)-([^-]+)-([^-]+)$/s) {
+ ($s->{'name'}, $s->{'version'}, $s->{'release'}) = ($1, $2, $3);
+ # fake source entry for now...
+ $s->{'source'} = $s->{'name'} if $s->{'arch'} ne 'src' && $s->{'arch'} ne 'nosrc';
+ addpkg($res, $s, \%options);
+ }
+ $s = {};
+ }
+ }
+ return $res;
+}
+
+1;
+
diff --git a/Build/Repo.pm b/Build/Repo.pm
new file mode 100644
index 0000000..002f4ab
--- /dev/null
+++ b/Build/Repo.pm
@@ -0,0 +1,67 @@
+################################################################
+#
+# 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;
+our $do_mdk;
+
+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_mdk = 1 if $_ eq ':mdk';
+ }
+ $do_rpmmd = $do_deb = $do_arch = $do_susetags = $do_mdk = 1 unless $do_rpmmd || $do_deb || $do_arch || $do_susetags || $do_mdk;
+ if ($do_rpmmd) {
+ require Build::Rpmmd;
+ }
+ if ($do_susetags) {
+ require Build::Susetags;
+ }
+ if ($do_deb) {
+ require Build::Debrepo;
+ }
+ if ($do_arch) {
+ require Build::Archrepo;
+ }
+ if ($do_mdk) {
+ require Build::Mdkrepo;
+ }
+}
+
+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';
+ return Build::Mdkrepo::parse(@args) if $do_arch && $type eq 'mdk';
+ die("parse repo: unknown type '$type'\n");
+}
+
+1;
diff --git a/Build/Rpm.pm b/Build/Rpm.pm
new file mode 100644
index 0000000..4af895b
--- /dev/null
+++ b/Build/Rpm.pm
@@ -0,0 +1,1161 @@
+################################################################
+#
+# 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;
+our $conflictdeps = 0;
+
+use strict;
+
+use Digest::MD5;
+
+sub expr {
+ my $expr = shift;
+ my $lev = shift;
+
+ $lev ||= 0;
+ my ($v, $v2);
+ $expr =~ s/^\s+//;
+ my $t = substr($expr, 0, 1);
+ if ($t eq '(') {
+ ($v, $expr) = expr(substr($expr, 1), 0);
+ return undef unless defined $v;
+ return undef unless $expr =~ s/^\)//;
+ } elsif ($t eq '!') {
+ ($v, $expr) = expr(substr($expr, 1), 5);
+ return undef unless defined $v;
+ $v = 0 if $v && $v eq '\"\"';
+ $v =~ s/^0+/0/ if $v;
+ $v = !$v;
+ } elsif ($t eq '-') {
+ ($v, $expr) = expr(substr($expr, 1), 5);
+ return undef unless defined $v;
+ $v = -$v;
+ } elsif ($expr =~ /^([0-9]+)(.*?)$/) {
+ $v = $1;
+ $expr = $2;
+ } elsif ($expr =~ /^([a-zA-Z_0-9]+)(.*)$/) {
+ $v = "\"$1\"";
+ $expr = $2;
+ } elsif ($expr =~ /^(\".*?\")(.*)$/) {
+ $v = $1;
+ $expr = $2;
+ } else {
+ return;
+ }
+ return ($v, $expr) if $lev >= 5;
+ while (1) {
+ $expr =~ s/^\s+//;
+ if ($expr =~ /^&&/) {
+ return ($v, $expr) if $lev > 1;
+ ($v2, $expr) = expr(substr($expr, 2), 1);
+ return undef unless defined $v2;
+ $v = 0 if $v && $v eq '\"\"';
+ $v =~ s/^0+/0/;
+ $v2 = 0 if $v2 && $v2 eq '\"\"';
+ $v2 =~ s/^0+/0/;
+ $v &&= $v2;
+ } elsif ($expr =~ /^\|\|/) {
+ return ($v, $expr) if $lev > 1;
+ ($v2, $expr) = expr(substr($expr, 2), 1);
+ return undef unless defined $v2;
+ $v = 0 if $v && $v eq '\"\"';
+ $v =~ s/^0+/0/;
+ $v2 = 0 if $v2 && $v2 eq '\"\"';
+ $v2 =~ s/^0+/0/;
+ $v ||= $v2;
+ } elsif ($expr =~ /^>=/) {
+ return ($v, $expr) if $lev > 2;
+ ($v2, $expr) = expr(substr($expr, 2), 2);
+ return undef unless defined $v2;
+ $v = (($v =~ /^\"/) ? $v ge $v2 : $v >= $v2) ? 1 : 0;
+ } elsif ($expr =~ /^>/) {
+ return ($v, $expr) if $lev > 2;
+ ($v2, $expr) = expr(substr($expr, 1), 2);
+ return undef unless defined $v2;
+ $v = (($v =~ /^\"/) ? $v gt $v2 : $v > $v2) ? 1 : 0;
+ } elsif ($expr =~ /^<=/) {
+ return ($v, $expr) if $lev > 2;
+ ($v2, $expr) = expr(substr($expr, 2), 2);
+ return undef unless defined $v2;
+ $v = (($v =~ /^\"/) ? $v le $v2 : $v <= $v2) ? 1 : 0;
+ } elsif ($expr =~ /^</) {
+ return ($v, $expr) if $lev > 2;
+ ($v2, $expr) = expr(substr($expr, 1), 2);
+ return undef unless defined $v2;
+ $v = (($v =~ /^\"/) ? $v lt $v2 : $v < $v2) ? 1 : 0;
+ } elsif ($expr =~ /^==/) {
+ return ($v, $expr) if $lev > 2;
+ ($v2, $expr) = expr(substr($expr, 2), 2);
+ return undef unless defined $v2;
+ $v = (($v =~ /^\"/) ? $v eq $v2 : $v == $v2) ? 1 : 0;
+ } elsif ($expr =~ /^!=/) {
+ return ($v, $expr) if $lev > 2;
+ ($v2, $expr) = expr(substr($expr, 2), 2);
+ return undef unless defined $v2;
+ $v = (($v =~ /^\"/) ? $v ne $v2 : $v != $v2) ? 1 : 0;
+ } elsif ($expr =~ /^\+/) {
+ return ($v, $expr) if $lev > 3;
+ ($v2, $expr) = expr(substr($expr, 1), 3);
+ return undef unless defined $v2;
+ $v += $v2;
+ } elsif ($expr =~ /^-/) {
+ return ($v, $expr) if $lev > 3;
+ ($v2, $expr) = expr(substr($expr, 1), 3);
+ return undef unless defined $v2;
+ $v -= $v2;
+ } elsif ($expr =~ /^\*/) {
+ ($v2, $expr) = expr(substr($expr, 1), 4);
+ return undef unless defined $v2;
+ $v *= $v2;
+ } elsif ($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);
+ }
+ }
+}
+
+sub adaptmacros {
+ my ($macros, $optold, $optnew) = @_;
+ for (keys %$optold) {
+ delete $macros->{$_};
+ }
+ for (keys %$optnew) {
+ $macros->{$_} = $optnew->{$_};
+ }
+ return $optnew;
+}
+
+sub grabargs {
+ my ($macname, $getopt, @args) = @_;
+ my %m;
+ $m{'0'} = $macname;
+ $m{'**'} = join(' ', @args);
+ my %go;
+ %go = ($getopt =~ /(.)(:*)/sg) if defined $getopt;
+ while (@args && $args[0] =~ s/^-//) {
+ my $o = shift @args;
+ last if $o eq '-';
+ while ($o =~ /^(.)(.*)$/) {
+ if ($go{$1}) {
+ my $arg = $2;
+ $arg = shift(@args) if @args && $arg eq '';
+ $m{"-$1"} = "-$1 $arg";
+ $m{"-$1*"} = $arg;
+ last;
+ }
+ $m{"-$1"} = "-$1";
+ $o = $2;
+ }
+ }
+ $m{'#'} = scalar(@args);
+ my $i = 1;
+ for (@args) {
+ $m{$i} = $_;
+ $i++;
+ }
+ $m{'*'} = join(' ', @args);
+ return \%m;
+}
+
+# xspec may be passed as array ref to return the parsed spec files
+# an entry in the returned array can be
+# - a string: verbatim line from the original file
+# - a two element array ref:
+# - [0] original line
+# - [1] undef: line unused due to %if
+# - [1] scalar: line after macro expansion. Only set if it's a build deps
+# line and build deps got modified or 'save_expanded' is set in
+# config
+sub parse {
+ my ($config, $specfile, $xspec) = @_;
+
+ my $packname;
+ my $exclarch;
+ my $badarch;
+ my @subpacks;
+ my @packdeps;
+ my @prereqs;
+ my $hasnfb;
+ my $nfbline;
+ my %macros;
+ my %macros_args;
+ my $ret = {};
+ my $ifdeps;
+
+ my $specdata;
+ local *SPEC;
+ if (ref($specfile) eq 'GLOB') {
+ *SPEC = *$specfile;
+ } elsif (ref($specfile) eq 'ARRAY') {
+ $specdata = [ @$specfile ];
+ } elsif (!open(SPEC, '<', $specfile)) {
+ warn("$specfile: $!\n");
+ $ret->{'error'} = "open $specfile: $!";
+ return $ret;
+ }
+ my @macros = @{$config->{'macros'}};
+ my $skip = 0;
+ my $main_preamble = 1;
+ my $preamble = 1;
+ my $inspec = 0;
+ my $hasif = 0;
+ my $lineno = 0;
+ while (1) {
+ my $line;
+ if (@macros) {
+ $line = shift @macros;
+ $hasif = 0 unless @macros;
+ } elsif ($specdata) {
+ $inspec = 1;
+ last unless @$specdata;
+ $line = shift @$specdata;
+ ++$lineno;
+ if (ref $line) {
+ $line = $line->[0]; # verbatim line
+ push @$xspec, $line if $xspec;
+ $xspec->[-1] = [ $line, undef ] if $xspec && $skip;
+ next;
+ }
+ } else {
+ $inspec = 1;
+ $line = <SPEC>;
+ last unless defined $line;
+ chomp $line;
+ ++$lineno;
+ }
+ push @$xspec, $line if $inspec && $xspec;
+ if ($line =~ /^#\s*neededforbuild\s*(\S.*)$/) {
+ if (defined $hasnfb) {
+ $xspec->[-1] = [ $xspec->[-1], undef ] if $inspec && $xspec;
+ next;
+ }
+ $hasnfb = $1;
+ $nfbline = \$xspec->[-1] if $inspec && $xspec;
+ next;
+ }
+ if ($line =~ /^\s*#/) {
+ next unless $line =~ /^#!Build(?:Ignore|Conflicts)\s*:/i;
+ }
+ my $expandedline = '';
+ if (!$skip && ($line =~ /%/)) {
+ my $tries = 0;
+ my @expandstack;
+ my $optmacros = {};
+ # newer perls: \{((?:(?>[^{}]+)|(?2))*)\}
+reexpand:
+ while ($line =~ /^(.*?)%(\{([^\}]+)\}|[\?\!]*[0-9a-zA-Z_]+|%|\*\*?|#|\()(.*?)$/) {
+ if ($tries++ > 1000) {
+ print STDERR "Warning: spec file parser ",($lineno?" line $lineno":''),": macro too deeply nested\n" if $config->{'warnings'};
+ $line = 'MACRO';
+ last;
+ }
+ $expandedline .= $1;
+ $line = $4;
+ my $macname = defined($3) ? $3 : $2;
+ my $macorig = $2;
+ my $macdata;
+ my $macalt;
+ if (defined($3)) {
+ if ($macname =~ /{/) { # {
+ while (($macname =~ y/{/{/) > ($macname =~ y/}/}/)) {
+ last unless $line =~ /^([^}]*)}(.*)$/;
+ $macname .= "}$1";
+ $macorig .= "$1}";
+ $line = $2;
+ }
+ }
+ $macdata = '';
+ if ($macname =~ /^([^\s:]+)([\s:])(.*)$/) {
+ $macname = $1;
+ if ($2 eq ':') {
+ $macalt = $3;
+ } else {
+ $macdata = $3;
+ }
+ }
+ }
+ my $mactest = 0;
+ if ($macname =~ /^\!\?/ || $macname =~ /^\?\!/) {
+ $mactest = -1;
+ } elsif ($macname =~ /^\?/) {
+ $mactest = 1;
+ }
+ $macname =~ s/^[\!\?]+//;
+ if ($macname eq '%') {
+ $expandedline .= '%';
+ next;
+ } elsif ($macname eq '(') {
+ print STDERR "Warning: spec file parser",($lineno?" line $lineno":''),": can't expand %(...)\n" if $config->{'warnings'};
+ $line = 'MACRO';
+ last;
+ } elsif ($macname eq 'define' || $macname eq 'global') {
+ if ($line =~ /^\s*([0-9a-zA-Z_]+)(?:\(([^\)]*)\))?\s*(.*?)$/) {
+ my $macname = $1;
+ my $macargs = $2;
+ my $macbody = $3;
+ if (defined $macargs) {
+ $macros_args{$macname} = $macargs;
+ } else {
+ delete $macros_args{$macname};
+ }
+ $macros{$macname} = $macbody;
+ }
+ $line = '';
+ last;
+ } elsif ($macname eq 'defined' || $macname eq 'with' || $macname eq 'undefined' || $macname eq 'without' || $macname eq 'bcond_with' || $macname eq 'bcond_without') {
+ my @args;
+ if ($macorig =~ /^\{(.*)\}$/) {
+ @args = split(' ', $1);
+ shift @args;
+ } else {
+ @args = split(' ', $line);
+ $line = '';
+ }
+ next unless @args;
+ if ($macname eq 'bcond_with') {
+ $macros{"with_$args[0]"} = 1 if exists $macros{"_with_$args[0]"};
+ next;
+ }
+ if ($macname eq 'bcond_without') {
+ $macros{"with_$args[0]"} = 1 unless exists $macros{"_without_$args[0]"};
+ next;
+ }
+ $args[0] = "with_$args[0]" if $macname eq 'with' || $macname eq 'without';
+ $line = ((exists($macros{$args[0]}) ? 1 : 0) ^ ($macname eq 'undefined' || $macname eq 'without' ? 1 : 0)).$line;
+ } elsif ($macname eq 'expand') {
+ $macalt = $macros{$macname} unless defined $macalt;
+ $macalt = '' if $mactest == -1;
+ push @expandstack, ($expandedline, $line, undef);
+ $line = $macalt;
+ $expandedline = '';
+ } elsif (exists($macros{$macname})) {
+ if (!defined($macros{$macname})) {
+ print STDERR "Warning: spec file parser",($lineno?" line $lineno":''),": can't expand '$macname'\n" if $config->{'warnings'};
+ $line = 'MACRO';
+ last;
+ }
+ if (defined($macros_args{$macname})) {
+ # macro with args!
+ if (!defined($macdata)) {
+ $line =~ /^\s*([^\n]*).*$/;
+ $macdata = $1;
+ $line = '';
+ }
+ push @expandstack, ($expandedline, $line, $optmacros);
+ $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;
+ if ($macalt =~ /%/) {
+ push @expandstack, ('', $line, 1) if $line ne '';
+ $line = $macalt;
+ } else {
+ $expandedline .= $macalt;
+ }
+ } elsif ($mactest) {
+ $macalt = '' if !defined($macalt) || $mactest == 1;
+ if ($macalt =~ /%/) {
+ push @expandstack, ('', $line, 1) if $line ne '';
+ $line = $macalt;
+ } else {
+ $expandedline .= $macalt;
+ }
+ } else {
+ $expandedline .= "%$macorig" unless $macname =~ /^-/;
+ }
+ }
+ $line = $expandedline . $line;
+ if (@expandstack) {
+ my $m = pop(@expandstack);
+ if ($m) {
+ $optmacros = adaptmacros(\%macros, $optmacros, $m) if ref $m;
+ $expandstack[-2] .= $line;
+ $line = pop(@expandstack);
+ $expandedline = pop(@expandstack);
+ } else {
+ my $todo = pop(@expandstack);
+ $expandedline = pop(@expandstack);
+ push @expandstack, ('', $todo, 1) if $todo ne '';
+ }
+ goto reexpand;
+ }
+ }
+ if ($line =~ /^\s*%else\b/) {
+ $skip = 1 - $skip if $skip < 2;
+ next;
+ }
+ if ($line =~ /^\s*%endif\b/) {
+ $skip-- if $skip;
+ next;
+ }
+ $skip++ if $skip && $line =~ /^\s*%if/;
+
+ if ($skip) {
+ $xspec->[-1] = [ $xspec->[-1], undef ] if $xspec;
+ $ifdeps = 1 if $line =~ /^(BuildRequires|BuildPrereq|BuildConflicts|\#\!BuildIgnore|\#\!BuildConflicts)\s*:\s*(\S.*)$/i;
+ next;
+ }
+
+ if ($line =~ /^\s*%ifarch(.*)$/) {
+ my $arch = $macros{'_target_cpu'} || 'unknown';
+ my @archs = grep {$_ eq $arch} split(/\s+/, $1);
+ $skip = 1 if !@archs;
+ $hasif = 1;
+ next;
+ }
+ if ($line =~ /^\s*%ifnarch(.*)$/) {
+ my $arch = $macros{'_target_cpu'} || 'unknown';
+ my @archs = grep {$_ eq $arch} split(/\s+/, $1);
+ $skip = 1 if @archs;
+ $hasif = 1;
+ next;
+ }
+ if ($line =~ /^\s*%ifos(.*)$/) {
+ my $os = $macros{'_target_os'} || 'unknown';
+ my @oss = grep {$_ eq $os} split(/\s+/, $1);
+ $skip = 1 if !@oss;
+ $hasif = 1;
+ next;
+ }
+ if ($line =~ /^\s*%ifnos(.*)$/) {
+ my $os = $macros{'_target_os'} || 'unknown';
+ my @oss = grep {$_ eq $os} split(/\s+/, $1);
+ $skip = 1 if @oss;
+ $hasif = 1;
+ next;
+ }
+ if ($line =~ /^\s*%if(.*)$/) {
+ my ($v, $r) = expr($1);
+ $v = 0 if $v && $v eq '\"\"';
+ $v =~ s/^0+/0/ if $v;
+ $skip = 1 unless $v;
+ $hasif = 1;
+ next;
+ }
+ if ($main_preamble) {
+ if ($line =~ /^(Name|Version|Disttag|Release)\s*:\s*(\S+)/i) {
+ $ret->{lc $1} = $2;
+ $macros{lc $1} = $2;
+ } elsif ($line =~ /^ExclusiveArch\s*:\s*(.*)/i) {
+ $exclarch ||= [];
+ push @$exclarch, split(' ', $1);
+ } elsif ($line =~ /^ExcludeArch\s*:\s*(.*)/i) {
+ $badarch ||= [];
+ push @$badarch, split(' ', $1);
+ }
+ }
+ if (@subpacks && $preamble && exists($ret->{'version'}) && $line =~ /^Version\s*:\s*(\S+)/i) {
+ $ret->{'multiversion'} = 1 if $ret->{'version'} ne $1;
+ }
+ if ($line =~ /^(?:Requires\(pre\)|Requires\(post\)|PreReq)\s*:\s*(\S.*)$/i) {
+ my $deps = $1;
+ my @deps = $deps =~ /([^\s\[,]+)(\s+[<=>]+\s+[^\s\[,]+)?(\s+\[[^\]]+\])?[\s,]*/g;
+ while (@deps) {
+ my ($pack, $vers, $qual) = splice(@deps, 0, 3);
+ if (!$unfilteredprereqs && $pack =~ /^\//) {
+ $ifdeps = 1;
+ next unless $config->{'fileprovides'}->{$pack};
+ }
+ push @prereqs, $pack unless grep {$_ eq $pack} @prereqs;
+ }
+ next;
+ }
+ if ($preamble && ($line =~ /^(BuildRequires|BuildPrereq|BuildConflicts|\#\!BuildIgnore|\#\!BuildConflicts)\s*:\s*(\S.*)$/i)) {
+ my $what = $1;
+ my $deps = $2;
+ $ifdeps = 1 if $hasif;
+ # XXX: weird syntax addition. can append arch or project to dependency
+ # BuildRequire: foo > 17 [i586,x86_64]
+ # BuildRequire: foo [home:bar]
+ # BuildRequire: foo [!home:bar]
+ my @deps = $deps =~ /([^\s\[,]+)(\s+[<=>]+\s+[^\s\[,]+)?(\s+\[[^\]]+\])?[\s,]*/g;
+ my $replace = 0;
+ my @ndeps = ();
+ while (@deps) {
+ my ($pack, $vers, $qual) = splice(@deps, 0, 3);
+ if (defined($qual)) {
+ $replace = 1;
+ my $arch = $macros{'_target_cpu'} || '';
+ my $proj = $macros{'_target_project'} || '';
+ $qual =~ s/^\s*\[//;
+ $qual =~ s/\]$//;
+ my $isneg = 0;
+ my $bad;
+ for my $q (split('[\s,]', $qual)) {
+ $isneg = 1 if $q =~ s/^\!//;
+ $bad = 1 if !defined($bad) && !$isneg;
+ if ($isneg) {
+ if ($q eq $arch || $q eq $proj) {
+ $bad = 1;
+ last;
+ }
+ } elsif ($q eq $arch || $q eq $proj) {
+ $bad = 0;
+ }
+ }
+ next if $bad;
+ }
+ $vers = '' unless defined $vers;
+ $vers =~ s/=(>|<)/$1=/;
+ push @ndeps, "$pack$vers";
+ }
+
+ $replace = 1 if grep {/^-/} @ndeps;
+ if (lc($what) ne 'buildrequires' && lc($what) ne 'buildprereq') {
+ if ($conflictdeps && $what =~ /conflict/i) {
+ push @packdeps, map {"!$_"} @ndeps;
+ next;
+ }
+ push @packdeps, map {"-$_"} @ndeps;
+ next;
+ }
+ if (defined($hasnfb)) {
+ if ((grep {$_ eq 'glibc' || $_ eq 'rpm' || $_ eq 'gcc' || $_ eq 'bash'} @ndeps) > 2) {
+ # ignore old generated BuildRequire lines.
+ $xspec->[-1] = [ $xspec->[-1], undef ] if $xspec;
+ next;
+ }
+ }
+ push @packdeps, @ndeps;
+ next unless $xspec && $inspec;
+ if ($replace) {
+ my @cndeps = grep {!/^-/} @ndeps;
+ if (@cndeps) {
+ $xspec->[-1] = [ $xspec->[-1], "$what: ".join(' ', @cndeps) ];
+ } else {
+ $xspec->[-1] = [ $xspec->[-1], ''];
+ }
+ }
+ next;
+ } elsif ($preamble && $line =~ /^(Source\d*|Patch\d*|Url|Icon)\s*:\s*(\S+)/i) {
+ my ($tag, $val) = (lc($1), $2);
+ # associate url and icon tags with the corresponding subpackage
+ $tag .= scalar @subpacks if ($tag eq 'url' || $tag eq 'icon') && @subpacks;
+ if ($tag =~ /icon/) {
+ # there can be a gif and xpm icon
+ push @{$ret->{$tag}}, $val;
+ } else {
+ $ret->{$tag} = $val;
+ }
+ }
+
+ if ($line =~ /^\s*%package\s+(-n\s+)?(\S+)/) {
+ if ($1) {
+ push @subpacks, $2;
+ } else {
+ push @subpacks, $ret->{'name'}.'-'.$2 if defined $ret->{'name'};
+ }
+ $preamble = 1;
+ $main_preamble = 0;
+ }
+
+ if ($line =~ /^\s*%(prep|build|install|check|clean|preun|postun|pretrans|posttrans|pre|post|files|changelog|description|triggerpostun|triggerun|triggerin|trigger|verifyscript)/) {
+ $main_preamble = 0;
+ $preamble = 0;
+ }
+
+ # do this always?
+ if ($xspec && @$xspec && $config->{'save_expanded'}) {
+ $xspec->[-1] = [ $xspec->[-1], $line ];
+ }
+ }
+ close SPEC unless ref $specfile;
+ if (defined($hasnfb)) {
+ if (!@packdeps) {
+ @packdeps = split(' ', $hasnfb);
+ } elsif ($nfbline) {
+ $$nfbline = [$$nfbline, undef ];
+ }
+ }
+ unshift @subpacks, $ret->{'name'} if defined $ret->{'name'};
+ $ret->{'subpacks'} = \@subpacks;
+ $ret->{'exclarch'} = $exclarch if defined $exclarch;
+ $ret->{'badarch'} = $badarch if defined $badarch;
+ $ret->{'deps'} = \@packdeps;
+ $ret->{'prereqs'} = \@prereqs if @prereqs;
+ $ret->{'configdependent'} = 1 if $ifdeps;
+ return $ret;
+}
+
+###########################################################################
+
+my %rpmstag = (
+ "SIGTAG_SIZE" => 1000, # Header+Payload size in bytes. */
+ "SIGTAG_PGP" => 1002, # RSA signature over Header+Payload
+ "SIGTAG_MD5" => 1004, # MD5 hash over Header+Payload
+ "SIGTAG_GPG" => 1005, # DSA signature over Header+Payload
+ "NAME" => 1000,
+ "VERSION" => 1001,
+ "RELEASE" => 1002,
+ "EPOCH" => 1003,
+ "SUMMARY" => 1004,
+ "DESCRIPTION" => 1005,
+ "BUILDTIME" => 1006,
+ "ARCH" => 1022,
+ "OLDFILENAMES" => 1027,
+ "SOURCERPM" => 1044,
+ "PROVIDENAME" => 1047,
+ "REQUIREFLAGS" => 1048,
+ "REQUIRENAME" => 1049,
+ "REQUIREVERSION" => 1050,
+ "NOSOURCE" => 1051,
+ "NOPATCH" => 1052,
+ "SOURCEPACKAGE" => 1106,
+ "PROVIDEFLAGS" => 1112,
+ "PROVIDEVERSION" => 1113,
+ "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 {
+ my ($rpm, @stags) = @_;
+
+ my @sigtags = grep {/^SIGTAG_/} @stags;
+ @stags = grep {!/^SIGTAG_/} @stags;
+ my $dosigs = @sigtags && !@stags;
+ @stags = @sigtags if $dosigs;
+
+ my $need_filenames = grep { $_ eq 'FILENAMES' } @stags;
+ push @stags, 'BASENAMES', 'DIRNAMES', 'DIRINDEXES', 'OLDFILENAMES' if $need_filenames;
+ @stags = grep { $_ ne 'FILENAMES' } @stags if $need_filenames;
+
+ my %stags = map {0 + ($rpmstag{$_} || $_) => $_} @stags;
+
+ my ($magic, $sigtype, $headmagic, $cnt, $cntdata, $lead, $head, $index, $data, $tag, $type, $offset, $count);
+
+ local *RPM;
+ my $forcebinary;
+ if (ref($rpm) eq 'ARRAY') {
+ ($headmagic, $cnt, $cntdata) = unpack('N@8NN', $rpm->[0]);
+ if ($headmagic != 0x8eade801) {
+ warn("Bad rpm\n");
+ return ();
+ }
+ if (length($rpm->[0]) < 16 + $cnt * 16 + $cntdata) {
+ warn("Bad rpm\n");
+ return ();
+ }
+ $index = substr($rpm->[0], 16, $cnt * 16);
+ $data = substr($rpm->[0], 16 + $cnt * 16, $cntdata);
+ } else {
+ if (ref($rpm) eq 'GLOB') {
+ *RPM = *$rpm;
+ } elsif (!open(RPM, '<', $rpm)) {
+ warn("$rpm: $!\n");
+ return ();
+ }
+ if (read(RPM, $lead, 96) != 96) {
+ warn("Bad rpm $rpm\n");
+ close RPM unless ref($rpm);
+ return ();
+ }
+ ($magic, $sigtype) = unpack('N@78n', $lead);
+ if ($magic != 0xedabeedb || $sigtype != 5) {
+ warn("Bad rpm $rpm\n");
+ close RPM unless ref($rpm);
+ return ();
+ }
+ $forcebinary = 1 if unpack('@6n', $lead) != 1;
+ if (read(RPM, $head, 16) != 16) {
+ warn("Bad rpm $rpm\n");
+ close RPM unless ref($rpm);
+ return ();
+ }
+ ($headmagic, $cnt, $cntdata) = unpack('N@8NN', $head);
+ if ($headmagic != 0x8eade801) {
+ warn("Bad rpm $rpm\n");
+ close RPM unless ref($rpm);
+ return ();
+ }
+ if (read(RPM, $index, $cnt * 16) != $cnt * 16) {
+ warn("Bad rpm $rpm\n");
+ close RPM unless ref($rpm);
+ return ();
+ }
+ $cntdata = ($cntdata + 7) & ~7;
+ if (read(RPM, $data, $cntdata) != $cntdata) {
+ warn("Bad rpm $rpm\n");
+ close RPM unless ref($rpm);
+ return ();
+ }
+ }
+
+ my %res = ();
+ if (@sigtags && !$dosigs) {
+ %res = &rpmq(["$head$index$data"], @sigtags);
+ }
+ if (ref($rpm) eq 'ARRAY' && !$dosigs && @$rpm > 1) {
+ my %res2 = &rpmq([ $rpm->[1] ], @stags);
+ %res = (%res, %res2);
+ return %res;
+ }
+ if (ref($rpm) ne 'ARRAY' && !$dosigs) {
+ if (read(RPM, $head, 16) != 16) {
+ warn("Bad rpm $rpm\n");
+ close RPM unless ref($rpm);
+ return ();
+ }
+ ($headmagic, $cnt, $cntdata) = unpack('N@8NN', $head);
+ if ($headmagic != 0x8eade801) {
+ warn("Bad rpm $rpm\n");
+ close RPM unless ref($rpm);
+ return ();
+ }
+ if (read(RPM, $index, $cnt * 16) != $cnt * 16) {
+ warn("Bad rpm $rpm\n");
+ close RPM unless ref($rpm);
+ return ();
+ }
+ if (read(RPM, $data, $cntdata) != $cntdata) {
+ warn("Bad rpm $rpm\n");
+ close RPM unless ref($rpm);
+ return ();
+ }
+ }
+ close RPM unless ref($rpm);
+
+# return %res unless @stags;
+
+ while($cnt-- > 0) {
+ ($tag, $type, $offset, $count, $index) = unpack('N4a*', $index);
+ $tag = 0+$tag;
+ if ($stags{$tag} || !@stags) {
+ eval {
+ my $otag = $stags{$tag} || $tag;
+ if ($type == 0) {
+ $res{$otag} = [ '' ];
+ } elsif ($type == 1) {
+ $res{$otag} = [ unpack("\@${offset}c$count", $data) ];
+ } elsif ($type == 2) {
+ $res{$otag} = [ unpack("\@${offset}c$count", $data) ];
+ } elsif ($type == 3) {
+ $res{$otag} = [ unpack("\@${offset}n$count", $data) ];
+ } elsif ($type == 4) {
+ $res{$otag} = [ unpack("\@${offset}N$count", $data) ];
+ } elsif ($type == 5) {
+ $res{$otag} = [ undef ];
+ } elsif ($type == 6) {
+ $res{$otag} = [ unpack("\@${offset}Z*", $data) ];
+ } elsif ($type == 7) {
+ $res{$otag} = [ unpack("\@${offset}a$count", $data) ];
+ } elsif ($type == 8 || $type == 9) {
+ my $d = unpack("\@${offset}a*", $data);
+ my @res = split("\0", $d, $count + 1);
+ $res{$otag} = [ splice @res, 0, $count ];
+ } else {
+ $res{$otag} = [ undef ];
+ }
+ };
+ if ($@) {
+ warn("Bad rpm $rpm: $@\n");
+ return ();
+ }
+ }
+ }
+ if ($forcebinary && $stags{1044} && !$res{$stags{1044}} && !($stags{1106} && $res{$stags{1106}})) {
+ $res{$stags{1044}} = [ '(none)' ]; # like rpm does...
+ }
+
+ if ($need_filenames) {
+ if ($res{'OLDFILENAMES'}) {
+ $res{'FILENAMES'} = [ @{$res{'OLDFILENAMES'}} ];
+ } else {
+ my $i = 0;
+ $res{'FILENAMES'} = [ map {"$res{'DIRNAMES'}->[$res{'DIRINDEXES'}->[$i++]]$_"} @{$res{'BASENAMES'}} ];
+ }
+ }
+
+ return %res;
+}
+
+sub add_flagsvers {
+ my ($res, $name, $flags, $vers) = @_;
+
+ return unless $res && $res->{$name};
+ my @flags = @{$res->{$flags} || []};
+ my @vers = @{$res->{$vers} || []};
+ for (@{$res->{$name}}) {
+ if (@flags && ($flags[0] & 0xe) && @vers) {
+ $_ .= ' ';
+ $_ .= '<' if $flags[0] & 2;
+ $_ .= '>' if $flags[0] & 4;
+ $_ .= '=' if $flags[0] & 8;
+ $_ .= " $vers[0]";
+ }
+ shift @flags;
+ shift @vers;
+ }
+}
+
+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)) {
+ return defined($s2) ? -1 : 0;
+ }
+ return 1 if !defined $s2;
+ return 0 if $s1 eq $s2;
+ while (1) {
+ $s1 =~ s/^[^a-zA-Z0-9~]+//;
+ $s2 =~ s/^[^a-zA-Z0-9~]+//;
+ if ($s1 =~ s/^~//) {
+ next if $s2 =~ s/^~//;
+ return -1;
+ }
+ return 1 if $s2 =~ /^~/;
+ if ($s1 eq '') {
+ return $s2 eq '' ? 0 : -1;
+ }
+ return 1 if $s2 eq '';
+ my ($x1, $x2, $r);
+ if ($s1 =~ /^([0-9]+)(.*?)$/) {
+ $x1 = $1;
+ $s1 = $2;
+ $s2 =~ /^([0-9]*)(.*?)$/;
+ $x2 = $1;
+ $s2 = $2;
+ return 1 if $x2 eq '';
+ $x1 =~ s/^0+//;
+ $x2 =~ s/^0+//;
+ $r = length($x1) - length($x2) || $x1 cmp $x2;
+ } elsif ($s1 ne '' && $s2 ne '') {
+ $s1 =~ /^([a-zA-Z]*)(.*?)$/;
+ $x1 = $1;
+ $s1 = $2;
+ $s2 =~ /^([a-zA-Z]*)(.*?)$/;
+ $x2 = $1;
+ $s2 = $2;
+ return -1 if $x1 eq '' || $x2 eq '';
+ $r = $x1 cmp $x2;
+ }
+ return $r > 0 ? 1 : -1 if $r;
+ }
+}
+
+sub verscmp {
+ my ($s1, $s2, $dtest) = @_;
+
+ return 0 if $s1 eq $s2;
+ my ($e1, $v1, $r1) = $s1 =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
+ $e1 = 0 unless defined $e1;
+ my ($e2, $v2, $r2) = $s2 =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
+ $e2 = 0 unless defined $e2;
+ if ($e1 ne $e2) {
+ my $r = verscmp_part($e1, $e2);
+ return $r if $r;
+ }
+ return 0 if $dtest && ($v1 eq '' || $v2 eq '');
+ if ($v1 ne $v2) {
+ my $r = verscmp_part($v1, $v2);
+ return $r if $r;
+ }
+ $r1 = '' unless defined $r1;
+ $r2 = '' unless defined $r2;
+ return 0 if $dtest && ($r1 eq '' || $r2 eq '');
+ if ($r1 ne $r2) {
+ return verscmp_part($r1, $r2);
+ }
+ return 0;
+}
+
+sub query {
+ my ($handle, %opts) = @_;
+
+ my @tags = qw{NAME SOURCERPM NOSOURCE NOPATCH SIGTAG_MD5 PROVIDENAME PROVIDEFLAGS PROVIDEVERSION REQUIRENAME REQUIREFLAGS REQUIREVERSION SOURCEPACKAGE};
+ 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];
+ $src = '' unless defined $src;
+ $src =~ s/-[^-]*-[^-]*\.[^\.]*\.rpm//;
+ add_flagsvers(\%res, 'PROVIDENAME', 'PROVIDEFLAGS', 'PROVIDEVERSION');
+ add_flagsvers(\%res, 'REQUIRENAME', 'REQUIREFLAGS', 'REQUIREVERSION');
+ my $data = {
+ name => $res{'NAME'}->[0],
+ hdrmd5 => unpack('H32', $res{'SIGTAG_MD5'}->[0]),
+ };
+ if ($opts{'alldeps'}) {
+ $data->{'provides'} = [ @{$res{'PROVIDENAME'} || []} ];
+ $data->{'requires'} = [ @{$res{'REQUIRENAME'} || []} ];
+ } else {
+ $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 '') {
+ my $haveselfprovides;
+ if (@{$data->{'provides'}}) {
+ if ($data->{'provides'}->[-1] =~ /^\Q$res{'NAME'}->[0]\E =/) {
+ $haveselfprovides = 1;
+ } elsif (@{$data->{'provides'}} > 1 && $data->{'provides'}->[-2] =~ /^\Q$res{'NAME'}->[0]\E =/) {
+ $haveselfprovides = 1;
+ }
+ }
+ if (!$haveselfprovides) {
+ my $evr = "$res{'VERSION'}->[0]-$res{'RELEASE'}->[0]";
+ $evr = "$res{'EPOCH'}->[0]:$evr" if $res{'EPOCH'} && $res{'EPOCH'}->[0];
+ push @{$data->{'provides'}}, "$res{'NAME'}->[0] = $evr";
+ }
+ }
+
+ $data->{'source'} = $src eq '(none)' ? $data->{'name'} : $src if $src ne '';
+ if ($opts{'evra'}) {
+ my $arch = $res{'ARCH'}->[0];
+ $arch = $res{'NOSOURCE'} || $res{'NOPATCH'} ? 'nosrc' : 'src' unless $src ne '';
+ $data->{'version'} = $res{'VERSION'}->[0];
+ $data->{'release'} = $res{'RELEASE'}->[0];
+ $data->{'arch'} = $arch;
+ $data->{'epoch'} = $res{'EPOCH'}->[0] if exists $res{'EPOCH'};
+ }
+ if ($opts{'filelist'}) {
+ $data->{'filelist'} = $res{'FILENAMES'};
+ }
+ if ($opts{'description'}) {
+ $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;
+}
+
+sub queryhdrmd5 {
+ my ($bin, $leadsigp) = @_;
+
+ local *F;
+ open(F, '<', $bin) || die("$bin: $!\n");
+ my $buf = '';
+ my $l;
+ while (length($buf) < 96 + 16) {
+ $l = sysread(F, $buf, 4096, length($buf));
+ if (!$l) {
+ warn("$bin: read error\n");
+ close(F);
+ return undef;
+ }
+ }
+ my ($magic, $sigtype) = unpack('N@78n', $buf);
+ if ($magic != 0xedabeedb || $sigtype != 5) {
+ warn("$bin: not a rpm (bad magic of header type)\n");
+ close(F);
+ return undef;
+ }
+ my ($headmagic, $cnt, $cntdata) = unpack('@96N@104NN', $buf);
+ if ($headmagic != 0x8eade801) {
+ warn("$bin: not a rpm (bad sig header magic)\n");
+ close(F);
+ return undef;
+ }
+ my $hlen = 96 + 16 + $cnt * 16 + $cntdata;
+ $hlen = ($hlen + 7) & ~7;
+ while (length($buf) < $hlen) {
+ $l = sysread(F, $buf, 4096, length($buf));
+ if (!$l) {
+ warn("$bin: read error\n");
+ close(F);
+ return undef;
+ }
+ }
+ close F;
+ $$leadsigp = Digest::MD5::md5_hex(substr($buf, 0, $hlen)) if $leadsigp;
+ my $idxarea = substr($buf, 96 + 16, $cnt * 16);
+ if ($idxarea !~ /\A(?:.{16})*\000\000\003\354\000\000\000\007(....)\000\000\000\020/s) {
+ warn("$bin: no md5 signature header\n");
+ return undef;
+ }
+ my $md5off = unpack('N', $1);
+ if ($md5off >= $cntdata) {
+ warn("$bin: bad md5 offset\n");
+ return undef;
+ }
+ $md5off += 96 + 16 + $cnt * 16;
+ return unpack("\@${md5off}H32", $buf);
+}
+
+sub queryinstalled {
+ my ($root, %opts) = @_;
+
+ $root = '' if !defined($root) || $root eq '/';
+ local *F;
+ my $dochroot = $root ne '' && !$opts{'nochroot'} && !$< && (-x "$root/usr/bin/rpm" || -x "$root/bin/rpm") ? 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;
+}
+
+# return (lead, sighdr, hdr [, hdrmd5]) of a rpm
+sub getrpmheaders {
+ my ($path, $withhdrmd5) = @_;
+
+ my $hdrmd5;
+ local *F;
+ open(F, '<', $path) || die("$path: $!\n");
+ my $buf = '';
+ my $l;
+ while (length($buf) < 96 + 16) {
+ $l = sysread(F, $buf, 4096, length($buf));
+ die("$path: read error\n") unless $l;
+ }
+ die("$path: not a rpm\n") unless unpack('N', $buf) == 0xedabeedb && unpack('@78n', $buf) == 5;
+ my ($headmagic, $cnt, $cntdata) = unpack('@96N@104NN', $buf);
+ die("$path: not a rpm (bad sig header)\n") unless $headmagic == 0x8eade801 && $cnt < 16384 && $cntdata < 1048576;
+ my $hlen = 96 + 16 + $cnt * 16 + $cntdata;
+ $hlen = ($hlen + 7) & ~7;
+ while (length($buf) < $hlen + 16) {
+ $l = sysread(F, $buf, 4096, length($buf));
+ die("$path: read error\n") unless $l;
+ }
+ if ($withhdrmd5) {
+ my $idxarea = substr($buf, 96 + 16, $cnt * 16);
+ die("$path: no md5 signature header\n") unless $idxarea =~ /\A(?:.{16})*\000\000\003\354\000\000\000\007(....)\000\000\000\020/s;
+ my $md5off = unpack('N', $1);
+ die("$path: bad md5 offset\n") unless $md5off;
+ $md5off += 96 + 16 + $cnt * 16;
+ $hdrmd5 = unpack("\@${md5off}H32", $buf);
+ }
+ ($headmagic, $cnt, $cntdata) = unpack('N@8NN', substr($buf, $hlen));
+ die("$path: not a rpm (bad header)\n") unless $headmagic == 0x8eade801 && $cnt < 1048576 && $cntdata < 33554432;
+ my $hlen2 = $hlen + 16 + $cnt * 16 + $cntdata;
+ while (length($buf) < $hlen2) {
+ $l = sysread(F, $buf, 4096, length($buf));
+ die("$path: read error\n") unless $l;
+ }
+ close F;
+ return (substr($buf, 0, 96), substr($buf, 96, $hlen - 96), substr($buf, $hlen, $hlen2 - $hlen), $hdrmd5);
+}
+
+1;
diff --git a/Build/Rpmmd.pm b/Build/Rpmmd.pm
new file mode 100644
index 0000000..0d148b7
--- /dev/null
+++ b/Build/Rpmmd.pm
@@ -0,0 +1,218 @@
+################################################################
+#
+# 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'},
+ checksum => { _start => \&generic_store_attr, _attr => 'type', _tag => 'checksum', _text => 1, _end => \&primary_handle_checksum },
+ 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 },
+ checksum => { _start => \&generic_store_attr, _attr => 'type', _tag => 'checksum', _text => 1, _end => \&primary_handle_checksum },
+ '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_checksum {
+ my ($h, $c, $p, $el) = @_;
+ my $data = $c->[0]->[4];
+ my $type = lc(delete($data->{$h->{'_tag'}}) || '');
+ $type = 'sha1' if $type eq 'sha';
+ if ($type eq 'md5' || $type eq 'sha1' || $type eq 'sha256' || $type eq 'sha512') {
+ $data->{$h->{'_tag'}} = "$type:$c->[-1]->[2]" if defined $c->[-1]->[2];
+ }
+}
+
+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'} || []};
+ }
+ }
+ delete $data->{'checksum'} unless $options->{'withchecksum'};
+ return generic_add_result(@_);
+}
+
+sub parse_repomd {
+ return generic_parse($repomdparser, @_);
+}
+
+sub parse {
+ return generic_parse($primaryparser, @_);
+}
+
+1;
diff --git a/Build/SimpleXML.pm b/Build/SimpleXML.pm
new file mode 100644
index 0000000..d133638
--- /dev/null
+++ b/Build/SimpleXML.pm
@@ -0,0 +1,103 @@
+################################################################
+#
+# Copyright (c) 1995-2016 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::SimpleXML;
+
+use strict;
+
+# very simple xml parser, just good enough to parse kiwi and _service files...
+# can't use standard XML parsers, unfortunatelly, as the build script
+# must not rely on external libraries
+#
+sub parse {
+ my ($xml) = @_;
+
+ my @nodestack;
+ my $node = {};
+ my $c = '';
+ $xml =~ s/^\s*\<\?.*?\?\>//s;
+ while ($xml =~ /^(.*?)\</s) {
+ if ($1 ne '') {
+ $c .= $1;
+ $xml = substr($xml, length($1));
+ }
+ if (substr($xml, 0, 4) eq '<!--') {
+ $xml =~ s/.*?-->//s;
+ next;
+ }
+ die("bad xml\n") unless $xml =~ /(.*?\>)/s;
+ my $tag = $1;
+ $xml = substr($xml, length($tag));
+ my $mode = 0;
+ if ($tag =~ s/^\<\///s) {
+ chop $tag;
+ $mode = 1; # end
+ } elsif ($tag =~ s/\/\>$//s) {
+ $mode = 2; # start & end
+ $tag = substr($tag, 1);
+ } else {
+ $tag = substr($tag, 1);
+ chop $tag;
+ }
+ my @tag = split(/(=(?:\"[^\"]*\"|\'[^\']*\'|[^\"\s]*))?\s+/, "$tag ");
+ $tag = shift @tag;
+ shift @tag;
+ push @tag, undef if @tag & 1;
+ my %atts = @tag;
+ for (values %atts) {
+ next unless defined $_;
+ s/^=\"([^\"]*)\"$/=$1/s or s/^=\'([^\']*)\'$/=$1/s;
+ s/^=//s;
+ s/&lt;/</g;
+ s/&gt;/>/g;
+ s/&amp;/&/g;
+ s/&apos;/\'/g;
+ s/&quot;/\"/g;
+ }
+ if ($mode == 0 || $mode == 2) {
+ my $n = {};
+ push @{$node->{$tag}}, $n;
+ for (sort keys %atts) {
+ $n->{$_} = $atts{$_};
+ }
+ if ($mode == 0) {
+ push @nodestack, [ $tag, $node, $c ];
+ $c = '';
+ $node = $n;
+ }
+ } else {
+ die("element '$tag' closes without open\n") unless @nodestack;
+ die("element '$tag' closes, but I expected '$nodestack[-1]->[0]'\n") unless $nodestack[-1]->[0] eq $tag;
+ $c =~ s/^\s*//s;
+ $c =~ s/\s*$//s;
+ $node->{'_content'} = $c if $c ne '';
+ $node = $nodestack[-1]->[1];
+ $c = $nodestack[-1]->[2];
+ pop @nodestack;
+ }
+ }
+ $c .= $xml;
+ $c =~ s/^\s*//s;
+ $c =~ s/\s*$//s;
+ $node->{'_content'} = $c if $c ne '';
+ return $node;
+}
+
+1;
diff --git a/Build/Snapcraft.pm b/Build/Snapcraft.pm
new file mode 100644
index 0000000..1d611b7
--- /dev/null
+++ b/Build/Snapcraft.pm
@@ -0,0 +1,83 @@
+################################################################
+#
+# 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::Snapcraft;
+
+use strict;
+use Build::Deb;
+
+eval { require YAML::XS; };
+*YAML::XS::LoadFile = sub {die("YAML::XS is not available\n")} unless defined &YAML::XS::LoadFile;
+
+sub parse {
+ my ($cf, $fn) = @_;
+
+ my ($yaml) = YAML::XS::LoadFile($fn);
+ return {'error' => "Failed to parse yaml file"} unless $yaml;
+
+ my $ret = {};
+ $ret->{'name'} = $yaml->{'name'};
+ $ret->{'version'} = $yaml->{'version'};
+ $ret->{'epoch'} = $yaml->{'epoch'} if $yaml->{'epoch'};
+
+ # how should we report the built apps?
+ my @packdeps;
+ for my $p (@{$yaml->{'stage-packages'} || []}) {
+ push @packdeps, $p;
+ }
+ for my $p (@{$yaml->{'build-packages'} || []}) {
+ push @packdeps, $p;
+ }
+ for my $p (@{$yaml->{'after'} || []}) {
+ push @packdeps, "snapcraft-part:$p";
+ }
+
+ for my $key (sort keys(%{$yaml->{'parts'} || {}})) {
+ my $part = $yaml->{'parts'}->{$key};
+ push @packdeps, "snapcraft-plugin:$part->{plugin}" if defined $part->{plugin};
+ for my $p (@{$part->{'stage-packages'} || []}) {
+ push @packdeps, $p;
+ }
+ for my $p (@{$part->{'build-packages'} || []}) {
+ push @packdeps, $p;
+ }
+ for my $p (@{$part->{'after'} || []}) {
+ next if $yaml->{'parts'}->{$p};
+ push @packdeps, "build-snapcraft-part-$p";
+ }
+ }
+
+ my %exclarchs;
+ for my $arch (@{$yaml->{architectures} || []}) {
+ my @obsarchs = Build::Deb::obsarch($arch);
+ push @obsarchs, $arch unless @obsarchs;
+ $exclarchs{$_} = 1 for @obsarchs;
+ }
+
+ $ret->{'exclarch'} = [ sort keys %exclarchs ] if %exclarchs;
+# $ret->{'badarch'} = $badarch if defined $badarch;
+ $ret->{'deps'} = \@packdeps;
+# $ret->{'prereqs'} = \@prereqs if @prereqs;
+# $ret->{'configdependent'} = 1 if $ifdeps;
+
+ return $ret;
+}
+
+1;
diff --git a/Build/Susetags.pm b/Build/Susetags.pm
new file mode 100644
index 0000000..034f6d8
--- /dev/null
+++ b/Build/Susetags.pm
@@ -0,0 +1,136 @@
+################################################################
+#
+# 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;
+
+# 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',
+ 'Cks' => 'checksum',
+);
+
+sub addpkg {
+ 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 ($options->{'withchecksum'} && $data->{'checksum'}) {
+ my ($ctype, $csum) = split(' ', delete($data->{'checksum'}));
+ $ctype = lc($ctype || '');
+ $data->{'checksum'} = "$ctype:$csum" if $csum && ($ctype eq 'md5' || $ctype eq 'sha1' || $ctype eq 'sha256' || $ctype eq 'sha512');
+ }
+ if (ref($res) eq 'CODE') {
+ $res->($data);
+ } else {
+ push @$res, $data;
+ }
+}
+
+sub parse {
+ 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 @tmap = sort keys %tmap;
+ @tmap = grep {$_ ne 'Cks'} @tmap unless $options{'withchecksum'};
+ my $r = join('|', @tmap);
+ $r = qr/^([\+=])($r):\s*(.*)/;
+ while (<$fd>) {
+ chomp;
+ next unless /$r/;
+ my ($multi, $tag, $data) = ($1, $2, $3);
+ if ($multi eq '+') {
+ while (<$fd>) {
+ chomp;
+ last if /^-\Q$tag\E/;
+ next if $tag eq 'Req' && /^rpmlib\(/;
+ push @{$cur->{$tmap{$tag}}}, $_;
+ }
+ } elsif ($tag eq 'Pkg') {
+ 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;
+ }
+ }
+ addpkg($res, $cur, \%options) if $cur;
+ if (!ref($in)) {
+ close($fd) || die("close $in: $!\n");
+ }
+ return $res;
+}
+
+1;
diff --git a/Build/Zypp.pm b/Build/Zypp.pm
new file mode 100644
index 0000000..8ec554b
--- /dev/null
+++ b/Build/Zypp.pm
@@ -0,0 +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 ($repocfg, $reponame, $allrepos) = @_;
+
+ local *REPO;
+ open(REPO, '<', "$root/etc/zypp/repos.d/$repocfg") or return undef;
+ my $name;
+ my $repo = {};
+ while (<REPO>) {
+ chomp;
+ next if /^\s*#/;
+ s/\s+$//;
+ if (/^\[(.+)\]/) {
+ 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 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
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.
+
+ 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.)
+
+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.
+
+ 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.
+
+ 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
+
+ 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.
diff --git a/HOWTO.add_another_format b/HOWTO.add_another_format
new file mode 100644
index 0000000..a4dbccc
--- /dev/null
+++ b/HOWTO.add_another_format
@@ -0,0 +1,99 @@
+
+How to add another build format
+===============================
+
+To support yet another package format to be used with standalone build
+script and Open Build Service you need to follow these steps:
+
+Let's call the new format "XYZ" here.
+
+General notes about the implementations. There are two areas:
+
+SAFE implementations:
+ Some code runs outside of protected environments like KVM. Therefore
+this code must be implemented with security in mind. Special crafted
+build descriptions or binary files must not be able to exploit this code.
+What makes it even more interessting is that this code can also run
+on all kind of old or obscure systems. So any external dependency should
+be avoided as well.
+This means in short:
+ - code must be as simple as possible.
+ - code must not allow to execute random commands or to access random files.
+ - avoid external dependencies. When you look for a simple XML parser
+ check the kiwi support for this.
+ - code must stay compatible for all versions
+
+Build code running inside of environment.
+ - using any tool is fine here. However, the tool must be installed
+ somehow into the build system. In best case via some dependency.
+ - Incompatible changes can be implemented inside of these packages
+ pulled into the build environment.
+ - network is not possible here.
+
+
+1) Implement the parse() function into Build/XYZ.pm
+
+ parse() extracts the build dependecies from the build specification.
+ For RPM this would be the <package>.spec file for example.
+
+ Must be a SAFE implementation.
+
+2) Add a query() function to Build/XYZ.pm
+
+ query() extracts information from built packages. In the rpm world
+ these are the .rpm files.
+ query returns a hash containing:
+ name, epoch, version, release, arch, description,
+ provides, requires, hdrmd5
+
+ hdrmd5 is some unique identifier of the package built, it might be
+ just a md5 over the entire file.
+
+ Must be a SAFE implementation.
+
+3) Add a queryhdrmd5() function
+
+ this functions is a specialized version of query(), it just returns
+ the hdrmd5
+
+ Must be a SAFE implementation.
+
+4) Add a verscmp() function
+
+ verscmp() compares two package version strings. For rpms, a version has
+ the form [epoch:]version-release
+
+ Must be a SAFE implementation.
+
+5) Implement build-pkg-xyz functions
+
+ Those functions are used to setup the build environment. I.e. they
+ need to install/unpack the packages
+
+ Must be a SAFE implementation for the pre-installation part. Afterwards
+ it is fine to use any tool to install the packages (like rpm itself).
+
+6) Implement build-recipe-xyz functions
+
+ This functions are called to create the build result
+
+7) For standalone build support (actually not needed for OBS integration, but
+ it makes development easier) we need a "createxyzdeps" helper script.
+ For xyz://<...> repos it needs to download the repository metadata
+ and convert it to build's representation. See createyastdeps and createrepomddeps.
+
+
+Special notes for non-OSS systems
+=================================
+
+Systems like MS-Windows, MacOSX or SunOS could be support as well. However, these
+systems can not be installed by packages from scratch. So using preinstallimages
+would be mandatory here. Support for that exists in general already inside of
+the code.
+
+Special notes for image formats
+===============================
+
+Image formats can usually skip 2) 3) and 4) from the items above. At least as long
+as they do not want to build new images based on former created ones.
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..fa51581
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,110 @@
+VERSION=0.1
+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 -c '. common_functions ; build_host_arch; echo $$BUILD_INITVM_ARCH')
+
+ifeq ($(SCM),svn)
+SVNVER=_SVN$(shell LANG=C svnversion .)
+endif
+
+prefix=/usr
+bindir=$(prefix)/bin
+datadir=$(prefix)/share
+libdir=$(prefix)/lib
+pkglibdir=$(libdir)/$(BUILD)
+mandir=$(datadir)/man
+man1dir=$(mandir)/man1
+sysconfdir=/etc
+DESTDIR=
+
+all:
+
+install:
+ install -m755 -d \
+ $(DESTDIR)$(pkglibdir)/configs \
+ $(DESTDIR)$(pkglibdir)/Build \
+ $(DESTDIR)$(pkglibdir)/emulator \
+ $(DESTDIR)$(bindir) \
+ $(DESTDIR)$(man1dir)
+ install -m755 \
+ build \
+ vc \
+ createdirdeps \
+ order \
+ expanddeps \
+ computeblocklists \
+ extractbuild \
+ getbinaryid \
+ getbuildids \
+ killchroot \
+ queryconfig \
+ common_functions \
+ init_buildsystem \
+ substitutedeps \
+ debtransform \
+ debtransformbz2 \
+ debtransformxz \
+ debtransformzip \
+ mkbaselibs \
+ mkdrpms \
+ listinstalled \
+ createzyppdeps \
+ createarchdeps \
+ createdebdeps \
+ createrepomddeps \
+ createyastdeps \
+ changelog2spec \
+ spec2changelog \
+ download \
+ runservices \
+ spec_add_patch \
+ spectool \
+ signdummy \
+ unrpm \
+ telnet_login_wrapper \
+ build-validate-params \
+ $(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
+
+# Allow initvm to be packaged seperately from the rest of build. This
+# is useful because it is distributed as a static binary package (e.g.
+# build-initvm-static) whereas the build scripts package is noarch.
+
+initvm: initvm.c
+ $(CC) -o $@.$(INITVM_ARCH) -static $(CFLAGS) initvm.c
+
+initvm-all: initvm
+
+initvm-build: initvm
+
+initvm-install: initvm
+ install -m755 -d $(DESTDIR)$(pkglibdir)
+ install -m755 initvm.$(INITVM_ARCH) $(DESTDIR)$(pkglibdir)/initvm.$(INITVM_ARCH)
+
+
+dist:
+ifeq ($(SCM),svn)
+ rm -rf $(BUILD)-$(VERSION)$(SVNVER)
+ svn export . $(BUILD)-$(VERSION)$(SVNVER)
+ tar --force-local -cjf $(BUILD)-$(VERSION)$(SVNVER).tar.bz2 $(BUILD)-$(VERSION)$(SVNVER)
+ rm -rf $(BUILD)-$(VERSION)$(SVNVER)
+else
+ifeq ($(SCM),git)
+ git archive --prefix=$(BUILD)-$(VERSION)_git$(DATE)/ HEAD| bzip2 > $(BUILD)-$(VERSION)_git$(DATE).tar.bz2
+endif
+endif
diff --git a/README b/README
new file mode 100644
index 0000000..b328e72
--- /dev/null
+++ b/README
@@ -0,0 +1,11 @@
+
+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.
+
+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.
+
+See the man page for more information.
+
diff --git a/baselibs_global-deb.conf b/baselibs_global-deb.conf
new file mode 100644
index 0000000..bbed7d0
--- /dev/null
+++ b/baselibs_global-deb.conf
@@ -0,0 +1,39 @@
+arch i586 targets x86_64:32bit ia64:x86
+arch i686 targets x86_64:32bit ia64:x86
+arch s390 targets s390x:32bit
+arch ppc targets ppc64:32bit
+arch ppc64 targets ppc:64bit
+
+configdir /usr/lib/baselibs-<targettype>/bin
+
+targettype x86 prefix /emul/ia32-linux
+
+targettype x86 extension -x86
+targettype 32bit extension 32
+targettype 64bit extension 64
+
+targetname <name>-<targettype>
+
++.*/lib(64)?/.*\.(so\..*|so|o|a|la)$
+
+targettype 64bit -^(/usr)?/lib/lib
+targettype 32bit -/lib64/
+targettype x86 -/lib64/
+
+config +.*bin.*-config$
+config -/kde-config$
+
+targettype x86 requires "ia32el"
+targettype x86 prereq "glibc-x86"
+
+package /.(?<!-devel)$/
+post #!/bin/sh
+#post "/sbin/ldconfig"
+
+package /(.*)-devel$/
+targettype x86 block!
+requires "<name> = <version>"
+#requires "<match1>-<targettype> = <version>"
+
+package /(.*)-debuginfo$/
++/usr/lib(64)?/debug/.*/lib(64)?/.*\.(so\..*|so|o|a|la)\.debug$
diff --git a/baselibs_global.conf b/baselibs_global.conf
new file mode 100644
index 0000000..3bc500a
--- /dev/null
+++ b/baselibs_global.conf
@@ -0,0 +1,45 @@
+arch i586 targets x86_64:32bit
+arch i686 targets x86_64:32bit
+arch s390 targets s390x:32bit
+arch ppc targets ppc64:32bit
+arch ppc64 targets ppc:64bit
+arch sparc targets sparc64:32bit
+arch sparcv8 targets sparc64:32bit
+arch sparcv9 targets sparc64:32bit
+arch sparcv9v targets sparc64v:32bit
+arch sparc64 targets sparcv9:64bit
+arch sparc64v targets sparcv9v:64bit
+arch aarch64 targets aarch64_ilp32:64bit
+arch aarch64_ilp32 targets aarch64:32bit
+
+configdir /usr/lib/baselibs-<targettype>/bin
+
+targettype x86 prefix /emul/ia32-linux
+
+targettype x86 extension -x86
+targettype 32bit extension 32
+targettype 64bit extension 64
+
+targetname <name>-<targettype>
+
++.*/lib(64|ilp32)?/.*\.(so\..*|so|o|a|la)$
+
+targettype 64bit -^(/usr)?/lib(ilp32)?/lib
+targettype 32bit -/lib64/
+targettype x86 -/lib64/
+
+config +.*bin.*-config$
+config -/kde-config$
+
+targettype x86 requires "ia32el"
+targettype x86 prereq "glibc-x86"
+
+package /(.*-devel)$/
+requires "<match1> = <version>"
+
+package /.(?<!-devel)$/
+post "/sbin/ldconfig"
+
+package /(.*)-debuginfo$/
++/usr/lib(64|ilp32)?/debug/.*/lib(64|ilp32)?/.*\.(so\..*|so|o|a|la)\.debug$
++/usr/lib(64|ilp32)?/debug/.build-id/.*
diff --git a/build b/build
new file mode 100755
index 0000000..cb64985
--- /dev/null
+++ b/build
@@ -0,0 +1,1467 @@
+#!/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 recipe file.
+#
+# BUILD_ROOT here the packages will be built
+#
+################################################################
+#
+# 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 "$@"
+fi
+
+BUILD_CONF=/etc/build.conf
+
+# ignore BUILD_DIR if we have a config
+test -e "$BUILD_CONF" && BUILD_DIR=/usr/lib/build
+
+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"
+
+export BUILD_ARCH BUILD_HOST_ARCH BUILD_ROOT BUILD_RPMS BUILD_DIR BUILD_DEBUG
+export BUILD_DIST
+
+icecream=0
+definesnstuff=()
+repos=()
+old_packages=()
+
+# 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"
+
+# slurp in validation support
+. "$BUILD_DIR/build-validate-params"
+
+# need to restore build root owner for non-root builds
+browner=
+
+# Default uid:gid for the build user
+ABUILD_UID=399
+ABUILD_GID=399
+
+BUILD_OPTIONS_PARSED=
+DO_INIT=true
+DO_INIT_TOPDIR=true
+DO_LINT=
+DO_CHECKS=true
+CLEAN_BUILD=
+RECIPEFILES=()
+SRCDIR=
+BUILD_JOBS=
+BUILD_THREADS=
+ABUILD_TARGET=
+CREATE_BASELIBS=
+USEUSEDFORBUILD=
+LIST_STATE=
+
+RUNNING_IN_VM=
+RPMLIST=
+RELEASE=
+REASON=
+NOROOTFORBUILD=
+LOGFILE=
+KILL=
+DO_WIPE=
+CHANGELOG=
+BUILD_DEBUG=
+INCARNATION=
+DISTURL=
+LINKSOURCES=
+OVERLAY=
+RSYNCSRC=
+RSYNCDEST=
+RSYNCDONE=
+SIGNDUMMY=
+DO_STATISTICS=
+RUN_SHELL=
+CCACHE=
+DLNOSIGNATURE=
+CACHE_DIR=/var/cache/build
+
+
+# This is for insserv
+export YAST_IS_RUNNING=instsys
+
+unset LANGUAGE
+unset LANG
+export LC_ALL=POSIX
+umask 022
+
+echo_help () {
+ cat << EOT
+
+Some comments for build
+-----------------------
+
+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.
+
+If you want to set the directory were the chroot system will be setup
+(at the moment it uses $BUILD_ROOT),
+simply set the the environment variable BUILD_ROOT.
+
+Example:
+
+ export BUILD_ROOT=/var/tmp/mybuildroot
+
+
+Normally build builds the complete package including src.rpm (rpmbuild -ba).
+If you want let build only make the binary package, simply set
+
+ export BUILD_RPM_BUILD_STAGE=-bb
+
+(or -bc, -bp, -bi, ... see "Maximum RPM" for more details [*]).
+
+When the build command succeeds, the rpm files can be found under
+$BUILD_ROOT/usr/src/packages/RPMS/
+
+
+Known Parameters:
+
+ --help You already got it :)
+
+ --kill Instead of starting a build kill the one currently
+ running.
+
+ --shell Instead of starting a build start a root shell in
+ the build root.
+
+ --clean Delete old build root before initializing it
+
+ --wipe Completely removes build environment and exits.
+
+ --no-init Skip initialization of build root and start with build
+ immediately.
+
+ --no-checks Do not run checks (postbuild and %check)
+
+ --lint Run rpmlint after build.
+
+ --logfile logfile
+ Capture build output to logfile. Defaults to
+ .build.log in the build root for non-VM builds.
+
+ --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.
+
+ --rpms path1:path2:...
+ Specify path where to find the RPMs for the build system
+
+ --arch arch1:arch2:...
+ Specify what architectures to select from the RPMs
+
+ --verify Run verify when initializing the build root
+
+ --extra-packs pack
+ -X pack
+ Also install package 'pack'
+
+ --root rootdir
+ Use 'rootdir' to setup chroot environment
+
+ --cachedir cachedir
+ Use 'cachedir' to cache remote repo's packages. The
+ default cache dir is /var/cache/build, every repo
+ given by --repo corresponds to a subdir named
+ as md5sum of its repo url, for example:
+ /var/cache/build/3e8ea9b47808629414a0cebc33ea285e
+
+ --oldpackages oldpackagesdir
+ Define a directory with a former build
+
+ --baselibs Create -32bit/-64bit/-x86 rpms for other architectures
+
+ --list-state
+ List rpms that would be used to create a fresh build root.
+ Does not create the build root or perform a build.
+
+ --dist dist
+ Distribution to use
+
+ --with X
+ Enable feature X for build
+
+ --without X
+ Disable feature X for build
+
+ --define 'X Y'
+ Define macro X with value Y
+
+ --release release
+ Override Release in spec file
+
+ --stage -bSTAGE
+ Set stage for rpmbuild. Defaults to -ba.
+
+ --target platform
+ Set target platform for rpmbuild
+
+ --jobs N Use N parallel processes during build.
+ Sets %jobs and %_smp_mflags macros and
+ defines the number of CPUs to use for
+ VMs.
+
+ --threads N sets number of threads for VM
+
+ --ccache
+ Use ccache to speed up rebuilds
+
+ --icecream N
+ Use N parallel build jobs with icecream
+
+ --overlay OVERLAY
+ Copy overlay filesystem to buildroot after installing
+ all RPMs. This must be a valid directory.
+
+ --rsync-src RSYNCSRC
+ Copy overlay folder (RSYNCSRC) to a folder (RSYNCDEST)
+ inside the buildroot using rsync.
+ It will "%define RSYNCDONE 1" for handling %setup in your
+ specfile. E.g.:
+ %prep
+ %if 0%{?RSYNCDONE}
+ %setup -n aaa_base -T -D -b 5 -b 7
+ %else
+ %setup -n aaa_base -b 5 -b 7
+ %endif
+
+ --rsync-dest RSYNCDEST
+ Copy overlay folder (RSYNCSRC) to a folder (RSYNCDEST)
+ inside the buildroot using rsync.
+
+ --uid uid:gid
+ Specify the uid and gid to use for the abuild user.
+ This is useful if you are hacking in the buildroot.
+ This must be set to the same value if the buildroot is re-used.
+
+ --statistics
+ monitor used resources during build inside VM
+
+ --kvm
+ Use KVM to secure build process. Your hardware needs to support
+ virtualization
+
+ --xen
+ Use XEN to secure build process, you to run in a XEN Dom0 environment.
+
+ --lxc
+ Use Linux Containers to isolate the process. This may not be 100% safe.
+
+ --openstack
+ Cloud build
+
+ --ec2
+ Cloud build
+
+ --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.
+
+ --emulator-script SCRIPT
+ specify another emulator instead of emulator.sh
+
+ --vm-type TYPE
+ Use virtual machine instead of chroot
+ TYPE is one of xen|kvm|uml|qemu|lxc|zvm|openstack|ec2|docker|pvm
+
+ --vm-worker GUEST
+ GUEST is a z/VM build worker controlled by the controlling
+ z/VM build machine.
+
+ --vm-worker-nr N
+ Each worker in z/VM needs a uniq number. This is needed to
+ calculate uniq device addresses for root and swap device.
+
+ --vm-region NAME
+ EC2 only: defines amazon control server
+
+ --vm-server NAME
+ openstack only: defines control server name
+
+ --vm-disk FILE
+ Use FILE as disk for virtual machine.
+ Defaults to \$BUILD_ROOT.img if unset
+
+ --vm-swap FILE
+ Use FILE as swap space for virtual machine. The swap space is
+ also used for retrieving packages from the VM so its size must
+ be sufficiently large
+
+ --vm-disk-size SIZEINMB
+ --vm-swap-size SIZEINMB
+ --vm-disk-filesystem TYPE
+ Defaults for automatic setup of VM root/swap files
+
+ --vm-memory SIZEINMB
+ Set amount of RAM for VMs
+
+ --vm-hugetlbfs HUGETLBFSPATH
+ Use hugetlb for memory management, path to mounted hugetlbfs.
+
+ --vm-kernel FILE
+ --vm-initrd FILE
+ Kernel and initrd to use for VM (kvm and qemu only)
+
+ --vm-user USERNAME
+ User name to run qemu/kvm process
+
+ --vm-telnet PORT
+ Is forwarding PORT to a telnet session inside of the VM.
+ Specify also needed extra packages via -x parameter, usually:
+ --vm-telnet 1234 -x telnet-server -x net-tools
+ And connect from the host via
+ telnet 1234
+ NOTE: The telnet server gets started after all packages got installed.
+
+ --vm-net OPTION
+ --vm-netdev OPTION
+ --vm-device OPTION
+ KVM only: Attach kvm option
+ Available options are -net, -netdev, -device
+ (This options in kvm can not guarantee reproducible builds)
+ --debug
+ Enable creation of a debuginfo package
+
+Remember to have fun!
+
+[*] Maximum RPM: http://www.rpm.org/max-rpm/
+EOT
+}
+
+usage () {
+ cleanup_and_exit 1 "Usage: `basename $0` [--no-init|--clean|--rpms path|--verify|--help] [dir-to-build|recipe-to-build]"
+}
+
+#
+# cleanup_and_exit
+# return values: 0 -> success, new packages built
+# 1 -> error, build failed
+# 2 -> successfull build, but no changes to former built packages
+# 3 -> something wrong with build host
+#
+cleanup_and_exit () {
+ trap EXIT
+ test -z "$1" && set 0
+ if test -n "$2" ; then
+ if test "$1" -ne 0 ; then
+ echo "$2" >&2
+ else
+ echo "$2"
+ fi
+ fi
+ if test -z "$BUILD_OPTIONS_PARSED" ; then
+ # if we haven't parsed the options yet we do
+ # not know the correct build root. just exit.
+ exit $1
+ fi
+ rm -f $BUILD_ROOT/exit
+ if test "$1" -eq 1 -a -x /bin/df ; then
+ echo
+ echo "$HOST failed \"build $RECIPEFILE\" at `date --utc`."
+ echo
+ # okay, it failed, but maybe because disk space?
+ if df $BUILD_ROOT 2>/dev/null | grep -q "100%"; then
+ df $BUILD_ROOT 2>/dev/null
+ echo
+ echo "$HOST ran out of disk space. Please try again."
+ echo
+ set 3
+ fi
+ fi
+ if test -n "$RUNNING_IN_VM" ; then
+ echo "$1" > /.build/_exitcode
+ test -n "$browner" && chown "$browner" $BUILD_ROOT
+ vm_shutdown "$1"
+ else
+ 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/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
+ exit $1
+}
+
+fail_exit() {
+ cleanup_and_exit 1
+}
+
+shellquote() {
+ for arg ; do
+ arg=${arg/\\/\\\\}
+ arg=${arg/\$/\\\$}
+ arg=${arg/\"/\\\"}
+ arg=${arg/\`/\\\`}
+ echo -n " \"$arg\""
+ done
+}
+
+# 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
+}
+
+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][+][+]|clang|clang[+][+])([-]?[234][.]?[0-9])*$'); do
+ rm -f $BUILD_ROOT/var/lib/build/ccache/bin/$i
+ test -e $BUILD_ROOT/usr/bin/$i || continue
+ echo '#! /bin/sh' > $BUILD_ROOT/var/lib/build/ccache/bin/$i
+ echo "test -e /usr/bin/$i || exit 1" >> $BUILD_ROOT/var/lib/build/ccache/bin/$i
+ echo 'export PATH=/usr/lib/icecc/bin:/opt/icecream/bin:/usr/bin:$PATH' >> $BUILD_ROOT/var/lib/build/ccache/bin/$i
+ echo "ccache $i \"\$@\"" >> $BUILD_ROOT/var/lib/build/ccache/bin/$i
+ chmod 755 $BUILD_ROOT/var/lib/build/ccache/bin/$i
+ echo "Installed ccache wrapper as $BUILD_ROOT/var/lib/build/ccache/bin/$i"
+ done
+ fi
+ 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
+ else
+ rm -f "$BUILD_ROOT"/var/lib/build/ccache/bin/{gcc,g++,cc,c++,clang,clang++}
+ fi
+}
+
+setupicecream() {
+ local icecreamdir=/var/run/icecream
+ if test "$(readlink "$BUILD_ROOT/var/run")" = /run ; then
+ icecreamdir=/run/icecream
+ fi
+ if test "$icecream" -eq 0 ; then
+ rm -rf "$BUILD_ROOT$icecreamdir"
+ rm -f "$BUILD_ROOT/etc/profile.d/build_icecream.sh"
+ return 0
+ fi
+
+ if ! chroot "$BUILD_ROOT" rpm -q icecream >/dev/null 2>/dev/null; then
+ echo "*** icecream package not installed ***"
+ return 1
+ fi
+
+ echo "using icecream with $icecream jobs"
+
+ 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
+ fi
+
+ local icecc_vers=(`shopt -s nullglob; echo $BUILD_ROOT$icecreamdir/*.tar.{bz2,gz}`)
+ icecc_vers=${icecc_vers//$BUILD_ROOT/}
+
+ # XXX use changelog like autobuild does instead?
+ # only run create-env if compiler or glibc changed
+ 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"
+ then
+ rm -rf "$BUILD_ROOT$icecreamdir"
+ mkdir -p "$BUILD_ROOT$icecreamdir"
+ 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"
+ return 1
+ fi
+ echo "creating new env in '$icecreamdir'"
+ chroot $BUILD_ROOT bash -c "cd $icecreamdir; $createenv" || cleanup_and_exit 1
+ icecc_vers=(`shopt -s nullglob; echo $BUILD_ROOT/$icecreamdir/*.tar.{bz2,gz}`)
+ icecc_vers=${icecc_vers//$BUILD_ROOT/}
+ echo "created icecream environment $icecc_vers"
+ else
+ echo "reusing existing icecream environment $icecc_vers"
+ fi
+ if test -n "$icecc_vers" ; then
+ echo "export ICECC_VERSION=$icecc_vers" >> "$BUILD_ROOT"/etc/profile.d/build_icecream.sh
+ fi
+}
+
+setmemorylimit() {
+ if test -n "$VM_IMAGE" -o -n "$RUNNING_IN_VM" ; then
+ return
+ fi
+ local mem
+ local limit
+ while read mem; do
+ case "$mem" in
+ MemTotal:*)
+ set -- $mem
+ eval "limit=\$(($2/3*2))"
+ ;;
+ SwapTotal:*)
+ set -- $mem
+ eval "limit=\$(($2/3*2+$limit))"
+ ;;
+ esac
+ done < <(cat /proc/meminfo) # cat for proc stuff
+
+ ulimit -v $limit
+ echo "Memory limit set to ${limit}KB"
+}
+
+create_baselibs() {
+ local pkgs=()
+ local line
+
+ BASELIBS_CFG=
+
+ if test "$BUILDTYPE" == arch || test "$BUILDTYPE" = collax ; then
+ return
+ fi
+ if test "$BUILDTYPE" == dsc ; then
+ pkgs=($DEBS)
+ else # spec and kiwi
+ if test -e $BUILD_ROOT$TOPDIR/SOURCES/baselibs.conf ; then
+ BASELIBS_CFG="-c $TOPDIR/SOURCES/baselibs.conf"
+ fi
+ if test -e $BUILD_ROOT/usr/lib/build/baselibs_global.conf; then
+ BASELIBS_GLOBAL="-c /usr/lib/build/baselibs_global.conf"
+ fi
+ pkgs=($RPMS)
+ fi
+
+ # don't use -R as extracted sources, build root etc might be below $TOPDIR
+ chown "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"/* "$BUILD_ROOT$TOPDIR"/RPMS/* || true
+
+ local mkbaselibs="/usr/lib/build/mkbaselibs"
+ local whichone=''
+ # $BUILD_DIR is set to /.build when using a vm. So we need to
+ # hardcode /usr/lib/build instead of $BUILD_DIR to prefer
+ # mkbaselibs from the distro.
+ if test -f $BUILD_ROOT$mkbaselibs; then
+ if test -z "$BASELIBS_CFG" -a -e $BUILD_ROOT/usr/lib/build/baselibs.conf ; then
+ BASELIBS_CFG="-c /usr/lib/build/baselibs.conf"
+ fi
+ else
+ if test "$CREATE_BASELIBS" = 'internal'; then
+ echo "Warning: mkbaselibs missing in build root, skipping baselibs"
+ return
+ fi
+ # use external version
+ whichone=" (external)"
+ mkbaselibs="/.mkbaselibs/mkbaselibs"
+ rm -rf "$BUILD_ROOT/.mkbaselibs"
+ mkdir -p "$BUILD_ROOT/.mkbaselibs"
+ cp -f $BUILD_DIR/mkbaselibs $BUILD_ROOT/.mkbaselibs/
+ if test "$BUILDTYPE" == "dsc" ; then
+ cp -f $BUILD_DIR/baselibs_global-deb.conf $BUILD_ROOT/.mkbaselibs/baselibs_g.conf
+ cp -f $BUILD_ROOT$TOPDIR/SOURCES/baselibs-deb.conf $BUILD_ROOT/.mkbaselibs/baselibs-deb.conf
+ BASELIBS_CFG="-c /.mkbaselibs/baselibs-deb.conf"
+ else
+ cp -f $BUILD_DIR/baselibs_global.conf $BUILD_ROOT/.mkbaselibs/baselibs_g.conf
+ if test -z "$BASELIBS_CFG" -a -e $BUILD_DIR/baselibs.conf; then
+ cp -f $BUILD_DIR/baselibs.conf $BUILD_ROOT/.mkbaselibs/baselibs.conf
+ BASELIBS_CFG="-c /.mkbaselibs/baselibs.conf"
+ fi
+ fi
+ if test -e $BUILD_ROOT/.mkbaselibs/baselibs_g.conf; then
+ BASELIBS_GLOBAL="-c /.mkbaselibs/baselibs_g.conf"
+ fi
+ fi
+ echo "... creating baselibs$whichone"
+ while read line
+ do
+ chroot $BUILD_ROOT su -c "$mkbaselibs $BASELIBS_GLOBAL $BASELIBS_CFG $line" - $BUILD_USER || cleanup_and_exit 1
+ done < <(IFS=$'\n'; echo "${pkgs[*]#$BUILD_ROOT}" | xargs -n 1024)
+ rm -rf "$BUILD_ROOT/.mkbaselibs"
+}
+
+copy_oldpackages() {
+ local i=0
+ local d
+ local dest
+ 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 test -d "$d" -a "$d" != "$dest" ; then
+ rm -rf "$dest"
+ mkdir -p "$dest"
+ cp -L $d/* "$dest"
+ : $((++i))
+ fi
+ done
+}
+
+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 test -z "$RUNNING_IN_VM" -a \! -O "$BUILD_ROOT" -a "`stat -c %u $BUILD_ROOT`" -ne 0 ; then
+ cleanup_and_exit 1 "BUILD_ROOT=$BUILD_ROOT must be owned by root. Exit..."
+ fi
+ else
+ test "$BUILD_ROOT" != "${BUILD_ROOT%/*}" && mkdir -p "${BUILD_ROOT%/*}"
+ if ! mkdir $BUILD_ROOT ; then
+ cleanup_and_exit 1 "can not create BUILD_ROOT=$BUILD_ROOT. Exit..."
+ fi
+ fi
+
+ if test ! -w "$BUILD_ROOT" ; then
+ cleanup_and_exit 3 "Error: BUILD_ROOT=$BUILD_ROOT not writeable, try --clean."
+ fi
+
+ rm -rf "$BUILD_ROOT/.build.packages"
+ 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
+}
+
+copy_overlay() {
+ 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
+}
+
+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
+}
+
+wipe_build_environment() {
+ if test -n "$VM_TYPE"; then
+ vm_img_wipe
+ else
+ echo "Wiping build root: '$BUILD_ROOT'"
+
+ # unmount all mounts still in the build root path
+ for m in $(cat /proc/mounts | grep "$BUILD_ROOT" | awk '{ print $2 }'); do
+ if ! umount -n "$m" 2>/dev/null ; then
+ echo "Failed to umount "$m", cannot wipe buildroot"
+ exit 1
+ fi
+ done
+ rm -rf "$BUILD_ROOT"
+ fi
+}
+
+#### main ####
+
+trap fail_exit EXIT
+
+shopt -s nullglob
+
+export PATH=$BUILD_DIR:/sbin:/usr/sbin:/bin:/usr/bin:$PATH
+
+if vm_detect_2nd_stage ; then
+ set "/.build-srcdir/$RECIPEFILE"
+ export PATH=/.build:$PATH
+fi
+
+. $BUILD_DIR/common_functions || exit 1
+
+export HOST
+
+needarg() {
+ if test -z "$ARG" ; then
+ cleanup_and_exit 1 "$PARAM needs an agrument"
+ fi
+}
+
+validate_init "$BUILD_CONF"
+
+while test -n "$1"; do
+ 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
+ ;;
+ -noinit|-no-init)
+ test "$DO_INIT" = false && DO_INIT_TOPDIR=false
+ DO_INIT=false
+ ;;
+ -nochecks|-no-checks)
+ DO_CHECKS=false
+ ;;
+ -clean)
+ CLEAN_BUILD='--clean'
+ ;;
+ -wipe)
+ DO_WIPE=true
+ ;;
+ -kill)
+ KILL=true
+ ;;
+ -rpms)
+ needarg
+ BUILD_RPMS="$ARG"
+ shift
+ ;;
+ -arch)
+ needarg
+ BUILD_ARCH="$ARG"
+ shift
+ ;;
+ -hostarch|-host-arch)
+ needarg
+ BUILD_HOST_ARCH="$ARG"
+ shift
+ ;;
+ -verify)
+ export VERIFY_BUILD_SYSTEM=true
+ ;;
+ -target)
+ needarg
+ ABUILD_TARGET="$ARG"
+ shift
+ ;;
+ -jobs)
+ needarg
+ BUILD_JOBS="$ARG"
+ shift
+ ;;
+ -threads)
+ needarg
+ BUILD_THREADS="$ARG"
+ shift
+ ;;
+ -extrapacks|-extra-packs|-X)
+ needarg
+ BUILD_EXTRA_PACKS="$BUILD_EXTRA_PACKS $ARG"
+ shift
+ ;;
+ -lint)
+ DO_LINT=true
+ ;;
+ -baselibs)
+ CREATE_BASELIBS=true
+ ;;
+ -baselibs-internal)
+ CREATE_BASELIBS=internal
+ ;;
+ -root)
+ needarg
+ BUILD_ROOT="$ARG"
+ shift
+ ;;
+ -cachedir)
+ needarg
+ CACHE_DIR="$ARG"
+ shift
+ ;;
+ -oldpackages)
+ needarg
+ old_packages=("${old_packages[@]}" "$ARG")
+ shift
+ ;;
+ -dist)
+ needarg
+ BUILD_DIST="$ARG"
+ shift
+ ;;
+ -release)
+ needarg
+ RELEASE="$ARG"
+ shift
+ ;;
+ -logfile)
+ needarg
+ LOGFILE="$ARG"
+ shift
+ ;;
+ -reason)
+ needarg
+ REASON="$ARG"
+ shift
+ ;;
+ -norootforbuild)
+ NOROOTFORBUILD=true
+ ;;
+ -useusedforbuild)
+ USEUSEDFORBUILD="--useusedforbuild"
+ ;;
+ -configdir)
+ needarg
+ CONFIG_DIR="$ARG"
+ shift
+ ;;
+ -list*state)
+ LIST_STATE=true
+ ;;
+ -define|-with|-without)
+ needarg
+ PARAM="-${PARAM/#--/-}"
+ definesnstuff[${#definesnstuff[@]}]="$PARAM"
+ definesnstuff[${#definesnstuff[@]}]="$ARG"
+ shift
+ ;;
+ -repository|-repo)
+ needarg
+ repos[${#repos[@]}]="--repository"
+ repos[${#repos[@]}]="$ARG"
+ shift
+ ;;
+ -icecream)
+ needarg
+ icecream="$ARG"
+ test "$icecream" -gt 0 && BUILD_JOBS="$ARG"
+ shift
+ ;;
+ -ccache)
+ CCACHE=true
+ ;;
+ -statistics)
+ DO_STATISTICS=1
+ ;;
+ -debug)
+ BUILD_DEBUG=1
+ ;;
+ -incarnation)
+ needarg
+ INCARNATION=$ARG
+ shift
+ ;;
+ -disturl)
+ needarg
+ DISTURL=$ARG
+ shift
+ ;;
+ -linksources)
+ LINKSOURCES=true
+ ;;
+ -changelog)
+ CHANGELOG=true
+ ;;
+ -overlay)
+ needarg
+ OVERLAY=$ARG
+ shift
+ ;;
+ -rsync-src)
+ needarg
+ RSYNCSRC=$ARG
+ shift
+ ;;
+ -rsync-dest)
+ needarg
+ RSYNCDEST=$ARG
+ shift
+ ;;
+ -uid)
+ needarg
+ if test -n "${ARG//[0-9:]/}" ; then
+ cleanup_and_exit 1 "--uid argument must be uid:gid"
+ fi
+ ABUILD_UID=${ARG%:*}
+ ABUILD_GID=${ARG#*:}
+ shift
+ ;;
+ -rpmlist)
+ needarg
+ RPMLIST="--rpmlist $ARG"
+ BUILD_RPMS=
+ shift
+ ;;
+ -shell)
+ RUN_SHELL=1
+ shift
+ ;;
+ -signdummy)
+ SIGNDUMMY=1
+ ;;
+ -nosignature)
+ DLNOSIGNATURE="--nosignature"
+ ;;
+ ---noarg)
+ cleanup_and_exit 1 "$ARG does not take an argument"
+ ;;
+ -*)
+ if vm_parse_options "$@" ; then
+ set -- "${nextargs[@]}"
+ elif recipe_parse_options "$@" ; then
+ set -- "${nextargs[@]}"
+ else
+ cleanup_and_exit 1 "Unknown option '$PARAM'. Exit."
+ fi
+ ;;
+ *)
+ RECIPEFILES[${#RECIPEFILES[@]}]="$PARAM"
+ # skip validation
+ PARAM=
+ ;;
+ esac
+ if test -n "$PARAM" ; then
+ validate_param "$PARAM" "$ARG"
+ fi
+done
+
+# validate params coming from the environment
+test -n "$BUILD_ARCH" && validate_param "--arch" "$BUILD_ARCH" BUILD_ARCH
+test -n "$BUILD_HOST_ARCH" && validate_param "--hostarch" "$BUILD_HOST_ARCH" BUILD_HOST_ARCH
+test -n "$BUILD_RPMS" && validate_param "--rpms" "$BUILD_RPMS" BUILD_RPMS
+test -n "$BUILD_EXTRA_PACKS" && validate_param "--extrapacks" "$BUILD_EXTRA_PACKS" BUILD_EXTRA_PACKS
+test -n "$BUILD_DIST" && validate_param "--dist" "$BUILD_DIST" BUILD_DIST
+test -n "$VERIFY_BUILD_SYSTEM" && validate_param "--verify" "$VERIFY_BUILD_SYSTEM" VERIFY_BUILD_SYSTEM
+test -n "$BUILD_RPM_BUILD_STAGE" && validate_param "--stage" "$BUILD_RPM_BUILD_STAGE" BUILD_RPM_BUILD_STAGE
+test "$BUILD_ROOT" != /var/tmp/build-root && validate_param "--root" "$BUILD_ROOT" BUILD_ROOT
+test "$CONFIG_DIR" != "$BUILD_DIR/configs" && validate_param "--configdir" "$CONFIG_DIR" CONFIG_DIR
+
+# validate the buildroot
+validate_buildroot "$BUILD_ROOT"
+
+# done option parsing
+BUILD_OPTIONS_PARSED=true
+
+if test "$DO_WIPE" = true ; then
+ wipe_build_environment
+ cleanup_and_exit 0
+fi
+
+if test -n "$KILL" ; then
+ test -z "$SRCDIR" || usage
+ if test -n "$VM_IMAGE" -a -n "$VM_SWAP" -a -n "$VM_TYPE" -a "$VM_SWAP" != __not_attached__ ; then
+ # mark job as failed so that we don't extract packages
+ if test "$VM_TYPE" != zvm ; then
+ echo -n "BUILDSTATUS1" >"$VM_SWAP"
+ fi
+ fi
+ (set -C; > "$BUILD_ROOT/exit" 2>/dev/null || true)
+ if test -n "$VM_TYPE" ; then
+ vm_kill
+ else
+ if ! $BUILD_DIR/killchroot -s 9 $BUILD_ROOT ; then
+ cleanup_and_exit 1 "could not kill build in $BUILD_ROOT"
+ fi
+ fi
+ cleanup_and_exit
+fi
+
+if test -n "$CLEAN_BUILD" ; then
+ DO_INIT=true
+ DO_INIT_TOPDIR=true
+fi
+
+if test -n "$VM_TYPE" -a -z "$RUNNING_IN_VM" ; then
+ vm_verify_options
+fi
+
+if test -z "$RPMLIST" -a -z "$RUNNING_IN_VM" ; then
+ if test -z "$repos" -a -z "$BUILD_RPMS" ; then
+ repos=(--repository 'zypp://')
+ fi
+else
+ repos=()
+fi
+
+set_build_arch
+
+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
+ 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[@]}" $DLNOSIGNATURE $USEUSEDFORBUILD $RECIPEFILE $BUILD_EXTRA_PACKS
+ ERR=$?
+ rm -rf "$BUILD_ROOT"
+ cleanup_and_exit $ERR
+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
+
+if test "$BUILD_ROOT" = / ; then
+ browner="$(stat -c %u /)"
+fi
+
+rm -f $BUILD_ROOT/exit
+
+if test -z "$VM_IMAGE" -a -z "$LOGFILE" ; then
+ if test -z "$RUNNING_IN_VM"; then
+ LOGFILE="$BUILD_ROOT/.build.log"
+ else
+ # lxc and docker are special cases: vm shares logfile with host
+ case "$VM_TYPE" in
+ lxc|docker)
+ ;;
+ *)
+ LOGFILE="$BUILD_ROOT/.build.log"
+ ;;
+ esac
+ fi
+fi
+
+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 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
+ # external run of virtualization build
+ exec 1> >(exec -a 'build logging' perl -e 'open(F,">>",$ARGV[0])||die("$ARGV[0]: $!\n");$|=1;select(F);$|=1;while(<STDIN>){my $p=sprintf("[%5ds] ", time()-'$STARTTIME');print STDOUT $p.$_;s/^\r//s;s/\r\n/\n/gs;print F $p.$_}' $LOGFILE) 2>&1
+ else
+ # plain chroot
+ exec 1> >(exec -a 'build logging' perl -e 'open(F,">>",$ARGV[0])||die("$ARGV[0]: $!\n");$|=1;select(F);$|=1;while(<STDIN>){my $p=sprintf("[%5ds] ", time()-'$STARTTIME');print STDOUT $p.$_;print F $p.$_}' $LOGFILE) 2>&1
+ fi
+fi
+
+setmemorylimit
+
+#
+# say hello
+#
+test -z "$HOST" && HOST=`hostname`
+
+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
+ test -n "$VM_TYPE" && echo "Doing $VM_TYPE build${VM_IMAGE:+ in $VM_IMAGE}"
+ echo
+fi
+
+test "$BUILD_ARCH" = all && BUILD_ARCH=
+BUILD_USER_ABUILD_USED=
+
+for RECIPEFILE in "${RECIPEFILES[@]}" ; do
+
+ SRCDIR="${RECIPEFILE%/*}"
+ RECIPEFILE="${RECIPEFILE##*/}"
+
+ recipe_set_buildtype
+
+ if test -z "$RUNNING_IN_VM" ; then
+ echo
+ echo "$HOST started \"build $RECIPEFILE\" at `date --utc`."
+ echo
+ test -n "$REASON" && echo "$REASON"
+ echo
+ TIME_START_TIME=`date +%s` # for statistics
+ fi
+
+ #
+ # first setup building directory...
+ #
+ cd "$SRCDIR"
+ if ! test -s "$RECIPEFILE" ; then
+ cleanup_and_exit 1 "$RECIPEFILE is empty. This should not happen..."
+ fi
+ MYSRCDIR="$SRCDIR"
+
+ # special hack to build from a .src.rpm
+ test "$RECIPEFILE" != "${RECIPEFILE%.src.rpm}" && recipe_unpack_srcrpm
+
+ echo "processing recipe $MYSRCDIR/$RECIPEFILE ..."
+
+ ADDITIONAL_PACKS=
+ test -z "$BUILD_EXTRA_PACKS" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS $BUILD_EXTRA_PACKS"
+ test -z "$CREATE_BASELIBS" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS build"
+ 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"
+
+ # 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 $RECIPEFILE in
+ *.dsc) CFFORMAT=debian ;;
+ *) CFFORMAT=rpm ;;
+ esac
+ 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
+ vm_first_stage
+ cleanup_and_exit
+ fi
+
+ if test "$DO_INIT" = true ; then
+ start_time=`date +%s`
+ #
+ # create legacy .buildenv file
+ #
+ test -z "$INCARNATION" && INCARNATION=0
+ echo "BUILD_INCARNATION=$INCARNATION" > $BUILD_ROOT/.buildenv
+ CREATE_BUILD_BINARIES=
+ test "$BUILDTYPE" = preinstallimage && mkdir -p $BUILD_ROOT/.preinstall_image
+ egrep '^#[[:blank:]]*needsbinariesforbuild[[:blank:]]*$' >/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
+ test "$BUILDTYPE" = snapcraft && CREATE_BUILD_BINARIES=--create-build-binaries
+ set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $DLNOSIGNATURE $USEUSEDFORBUILD $CREATE_BUILD_BINARIES $RPMLIST "$MYSRCDIR/$RECIPEFILE" $ADDITIONAL_PACKS
+ echo "$* ..."
+ start_time=`date +%s`
+ "$@" || cleanup_and_exit 1
+ check_exit
+ TIME_INSTALL=$(( `date +%s` - $start_time ))
+ unset start_time
+ # arbitrary limit of 10MB
+ if test $((`stat -f -c "%a*%S/1024/1024" $BUILD_ROOT`)) -lt 10; then
+ # ensure that old stat is not failing (RHEL4)
+ if df $BUILD_ROOT 2>/dev/null | grep -q "100%"; then
+ df -h $BUILD_ROOT
+ cleanup_and_exit 1 "build does not work on a completely full filesystem"
+ fi
+ fi
+ copy_oldpackages
+ fi
+
+ # mount stuff (/dev/shm needed for POSIX semaphores)
+ if test -n "$BUILD_ROOT" -a "$BUILD_ROOT" != / ; then
+ test -d $BUILD_ROOT/dev/shm || rm -f $BUILD_ROOT/dev/shm
+ mkdir -p $BUILD_ROOT/proc
+ mkdir -p $BUILD_ROOT/sys
+ mkdir -p $BUILD_ROOT/dev/pts
+ mkdir -p $BUILD_ROOT/dev/shm
+ mount -n -tproc none $BUILD_ROOT/proc
+ mount -n -tdevpts -omode=0620,gid=5 none $BUILD_ROOT/dev/pts
+ mount -n -ttmpfs none $BUILD_ROOT/dev/shm
+ fi
+
+ # hack to process preinstallimages early
+ if test "$BUILDTYPE" = preinstallimage ; then
+ recipe_build
+ continue
+ fi
+
+ if test -z "$BUILD_DIST" -a -e "$BUILD_ROOT/.guessed_dist" ; then
+ read BUILD_DIST < $BUILD_ROOT/.guessed_dist
+ fi
+
+ #
+ # install dummy sign program if needed
+ #
+ test -f $BUILD_ROOT/usr/bin/sign_installed && mv $BUILD_ROOT/usr/bin/sign_installed $BUILD_ROOT/usr/bin/sign
+ if test -n "$SIGNDUMMY" ; then
+ test -f $BUILD_ROOT/usr/bin/sign && mv $BUILD_ROOT/usr/bin/sign $BUILD_ROOT/usr/bin/sign_installed
+ cp $BUILD_DIR/signdummy $BUILD_ROOT/usr/bin/sign
+ chmod 755 $BUILD_ROOT/usr/bin/sign
+ fi
+
+ #
+ # check if we want to build with the abuild user
+ #
+ BUILD_USER=abuild
+ if test -x $BUILD_ROOT/bin/rpm ; then
+ SUSE_VERSION=`chroot $BUILD_ROOT /bin/rpm --eval '%{?suse_version}' 2>/dev/null`
+ test -n "$SUSE_VERSION" -a "${SUSE_VERSION:-0}" -le 1020 && BUILD_USER=root
+ fi
+ if test "$BUILD_USER" = abuild ; then
+ egrep '^#[[:blank:]]*needsrootforbuild[[:blank:]]*$' >/dev/null <$RECIPEFILE && BUILD_USER=root
+ else
+ egrep '^#[[:blank:]]*norootforbuild[[:blank:]]*$' >/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 $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
+ echo 'abuild:*:::::::' >>$BUILD_ROOT/etc/shadow # This is needed on Mandriva 2009
+ echo 'abuild:*::' >>$BUILD_ROOT/etc/gshadow # This is needed on Ubuntu
+ echo "abuild:x:${ABUILD_GID}:" >>$BUILD_ROOT/etc/group
+ mkdir -p $BUILD_ROOT/home/abuild
+ chown "$ABUILD_UID:$ABUILD_GID" $BUILD_ROOT/home/abuild
+ else
+ if ! egrep "^abuild:x?:${ABUILD_UID}:${ABUILD_GID}" >/dev/null <$BUILD_ROOT/etc/passwd ; then
+ echo "abuild user present in the buildroot ($BUILD_ROOT) but uid:gid does not match"
+ echo "buildroot currently using:"
+ egrep "^abuild:" <$BUILD_ROOT/etc/passwd
+ echo "build script attempting to use:"
+ echo "abuild::${ABUILD_UID}:${ABUILD_GID}:..."
+ echo "build aborting"
+ cleanup_and_exit 1
+ fi
+ fi
+ if test -f $BUILD_ROOT/etc/shadow ; then
+ sed -i -e "s@^root::@root:*:@" $BUILD_ROOT/etc/shadow
+ fi
+ if test -f $BUILD_ROOT/etc/gshadow ; then
+ sed -i -e "s@^root::@root:*:@" $BUILD_ROOT/etc/gshadow
+ fi
+ BUILD_USER_ABUILD_USED=true
+ else
+ # building as root
+ ABUILD_UID=0
+ ABUILD_GID=0
+ if egrep '^abuild:' >/dev/null <$BUILD_ROOT/etc/passwd ; then
+ rm -rf "$BUILD_ROOT/home/abuild"
+ 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
+ sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/shadow
+ fi
+ if test -f $BUILD_ROOT/etc/gshadow ; then
+ sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/gshadow
+ fi
+ fi
+ fi
+
+ if test -n "$RUNNING_IN_VM" ; then
+ vm_setup_network
+ 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
+
+ cd $BUILD_ROOT$TOPDIR/SOURCES || cleanup_and_exit 1
+ for i in *.obscpio ; do
+ test -e "$i" || continue
+ echo "Unpacking $i ..."
+ echo "#!/bin/sh -e" > $BUILD_ROOT/.unpack.command
+ shellquote cd "$TOPDIR/SOURCES" >> $BUILD_ROOT/.unpack.command
+ echo >> $BUILD_ROOT/.unpack.command
+ echo -n 'cpio --extract --owner="'$BUILD_USER'" --unconditional --preserve-modification-time --make-directories <' >> $BUILD_ROOT/.unpack.command
+ shellquote "$i" >> $BUILD_ROOT/.unpack.command
+ echo >> $BUILD_ROOT/.unpack.command
+ shellquote rm -f "$i" >> $BUILD_ROOT/.unpack.command
+ echo >> $BUILD_ROOT/.unpack.command
+ chmod 0755 $BUILD_ROOT/.unpack.command
+ chroot $BUILD_ROOT su -c /.unpack.command - $BUILD_USER
+ rm -f $BUILD_ROOT/.unpack.command
+ done
+
+ if test -e _service; then
+ echo "Running build time source services..."
+ $BUILD_DIR/runservices --buildroot "$BUILD_ROOT" || cleanup_and_exit 1
+ fi
+
+ # get rid of old src dir, it is no longer needed and just wastes space
+ test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir && rm -rf "$MYSRCDIR"
+
+ # patch recipes
+ recipe_prepare
+
+ # hmmm
+ chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
+
+ echo -----------------------------------------------------------------
+ if test "$BUILD_USER" = root ; then
+ echo ----- building $RECIPEFILE
+ else
+ echo ----- building $RECIPEFILE "(user $BUILD_USER)"
+ fi
+ echo -----------------------------------------------------------------
+ echo -----------------------------------------------------------------
+ BUILD_SUCCEEDED=false
+
+ if test -n "$OVERLAY" ; then
+ copy_overlay
+ fi
+
+ if test -n "$RSYNCSRC" ; then
+ run_rsync
+ fi
+
+ start_time=`date +%s`
+ recipe_build
+ if test "$DO_STATISTICS" = 1; then
+ mkdir -p $TOPDIR/OTHER
+ echo "TIME_main_build: $(( `date +%s` - $start_time ))" >> $TOPDIR/OTHER/_statistics
+ fi
+ unset start_time
+
+ test "$BUILD_SUCCEEDED" = true || cleanup_and_exit 1
+ test -d "$SRCDIR" && cd "$SRCDIR"
+
+ # unmount stuff
+ if test -n "$BUILD_ROOT" -a "$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/sys 2>/dev/null || true
+ fi
+done
+
+if test -n "$RUNNING_IN_VM" -a -n "$DO_STATISTICS" ; then
+ touch /.build/_statistics.exit
+fi
+
+# mount /proc for the post processing steps
+if test -n "$BUILD_ROOT" -a "$BUILD_ROOT" != / ; then
+ mount -n -tproc none $BUILD_ROOT/proc
+fi
+
+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
+ recipe_check_file_owners
+fi
+
+if test -n "$RPMS" -a -d "$BUILD_ROOT/usr/lib/build/checks" ; then
+ export DO_RPM_REMOVE=true
+ # workaround for broken 13.1 check scripts which umount /proc
+ if test -n "$RUNNING_IN_VM" -a "$BUILD_ROOT" = / ; then
+ umount -n $BUILD_ROOT/proc/sys/fs/binfmt_misc 2>/dev/null
+ fi
+ # 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
+ for CHECKSCRIPT in $BUILD_ROOT/usr/lib/build/checks/* ; do
+ echo "... running ${CHECKSCRIPT##*/}"
+ $CHECKSCRIPT || cleanup_and_exit 1
+ done
+ # workaround for broken 13.1 check scripts which umount /proc
+ test -e "$BUILD_ROOT/proc/self" || mount -n -tproc none $BUILD_ROOT/proc
+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 ; then
+ recipe_run_rpmlint
+fi
+
+if test \( -n "$RPMS" -o -n "$DEBS" \) -a -n "$CREATE_BASELIBS"; then
+ create_baselibs
+fi
+
+exitcode=0
+
+# 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/.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
+ vm_wrapup_build $(recipe_resultdirs) OTHER
+fi
+
+echo
+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
index 0000000..fce1de2
--- /dev/null
+++ b/build-pkg
@@ -0,0 +1,90 @@
+#
+# 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 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
+#
+################################################################
+
+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
+ cleanup_and_exit 1 "cannot autodetect build type when using a preinstall image"
+ 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
+ cleanup_and_exit 1 "could not autodetect package type"
+ 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
+ ;;
+ *)
+ cleanup_and_exit 1 "unknown package type '$PSUF'"
+ ;;
+ esac
+}
diff --git a/build-pkg-arch b/build-pkg-arch
new file mode 100644
index 0000000..d81558a
--- /dev/null
+++ b/build-pkg-arch
@@ -0,0 +1,76 @@
+#
+# 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
+#
+################################################################
+
+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() {
+ # Pacman can't handle chroot
+ # https://bbs.archlinux.org/viewtopic.php?id=129661
+ (cd $BUILD_ROOT/etc && sed -i "s/^CheckSpace/#CheckSpace/g" pacman.conf)
+ # -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|looking for conflicting packages|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|:: Processing package changes|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
index 0000000..2465204
--- /dev/null
+++ b/build-pkg-deb
@@ -0,0 +1,159 @@
+#
+# 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
+#
+################################################################
+
+#
+# A wrapper around chroot to set the environment correctly for dpkg and
+# pre/postinst scripts.
+#
+deb_chroot ()
+{
+ #
+ # to workaround some version of fileutils that doesn't do a 'chdir /'
+ # when doing a 'chroot /' call lets subshell and change dir manually
+ #
+ (
+ cd $1 &&
+ DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical \
+ DEBCONF_NONINTERACTIVE_SEEN=true \
+ LC_ALL=C LANGUAGE=C LANG=C \
+ chroot $*
+ )
+}
+
+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
+ deb_chroot $BUILD_ROOT dpkg --install --force-depends .init_b_cache/dpkg.deb >/dev/null 2>&1
+}
+
+pkg_prepare_deb() {
+ :
+}
+
+pkg_install_deb() {
+ ( deb_chroot $BUILD_ROOT dpkg --install --force-depends .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() {
+ deb_chroot $BUILD_ROOT dpkg --purge --force-depends $PKG 2>&1 | {
+ local retry
+ while read line; do
+ case "$line" in
+ subprocess\ installed\ *script\ returned\ error\ exit\ status*)
+ chroot $BUILD_ROOT rm -f /var/lib/dpkg/info/$PKG.{pre,post}rm
+ retry=1
+ ;;
+ *) echo "$line" ;;
+ esac
+ done
+ if test -n "$retry"; then
+ echo "re-try deleting $PKG without post/pre remove scripts"
+ deb_chroot $BUILD_ROOT dpkg --purge --force-depends $PKG 2>&1 || touch $BUILD_ROOT/exit
+ fi
+ } | 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 ! deb_chroot $BUILD_ROOT dpkg --configure --pending 2>&1; then
+ echo "first configure attempt failed, trying again..."
+ deb_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"
+ deb_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"
+ deb_chroot $BUILD_ROOT ".init_b_cache/scripts/$PKG.post" configure '' \
+ < /dev/null
+ rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post"
+ fi
+}
+
+# Local Variables:
+# mode: Shell-script
+# End:
diff --git a/build-pkg-rpm b/build-pkg-rpm
new file mode 100644
index 0000000..fc6a421
--- /dev/null
+++ b/build-pkg-rpm
@@ -0,0 +1,203 @@
+#
+# 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() {
+ export ADDITIONAL_PARAMS=
+ if test "$USE_FORCE" = true ; then
+ export ADDITIONAL_PARAMS="$ADDITIONAL_PARAMS --force"
+ fi
+ # 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
+ ( cd $BUILD_ROOT && 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
+ ( cd $BUILD_ROOT && 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"
+ (cd $BUILD_ROOT && 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"
+ (cd $BUILD_ROOT && 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
index 0000000..a233464
--- /dev/null
+++ b/build-recipe
@@ -0,0 +1,146 @@
+#
+# 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 collax preinstallimage simpleimage mock livebuild snapcraft debootstrap debbuild; 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 ;;
+ snapcraft.yaml) BUILDTYPE=snapcraft ;;
+ build.collax) BUILDTYPE=collax ;;
+ _preinstallimage) BUILDTYPE=preinstallimage ;;
+ simpleimage) BUILDTYPE=simpleimage ;;
+ *.livebuild) BUILDTYPE=livebuild ;;
+ esac
+ if test -z "$BUILDTYPE" ; then
+ cleanup_and_exit 1 "I don't know how to build $RECIPEFILE"
+ 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
+ if test "$BUILDENGINE" = debbuild -a "$BUILDTYPE" = spec ; then
+ BUILDTYPE=debbuild
+ 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" ;;
+ collax) types="build.collax" ;;
+ livebuild) types=".livebuild" ;;
+ snapcraft) types="snapcraft.yaml" ;;
+ esac
+ fi
+ types="$types .spec .dsc PKGBUILD build.collax .kiwi .src.rpm .nosrc.rpm simpleimage snapcraft.yaml"
+ 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
+ cleanup_and_exit 1 "no recipe files found in $@. exit..."
+ fi
+}
diff --git a/build-recipe-arch b/build-recipe-arch
new file mode 100644
index 0000000..4937a58
--- /dev/null
+++ b/build-recipe-arch
@@ -0,0 +1,59 @@
+#
+# 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
+ test "$DO_INIT_TOPDIR" = false || 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..."
+ if ! _arch_recipe_makepkg -so "2>&1" ">/dev/null" ; then
+ cleanup_and_exit 1 "failed to prepare sources"
+ fi
+}
+
+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-collax b/build-recipe-collax
new file mode 100644
index 0000000..7729bc7
--- /dev/null
+++ b/build-recipe-collax
@@ -0,0 +1,64 @@
+#
+# Copyright 2015 Zarafa B.V. and its licensors
+#
+# 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 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.
+#
+
+recipe_setup_collax()
+{
+ TOPDIR="/usr/src/packages"
+ test "$DO_INIT_TOPDIR" != false && rm -Rf "$BUILD_ROOT/$TOPDIR"
+ mkdir -p "$BUILD_ROOT/$TOPDIR"/{SOURCES,SOURCES.DEB,DEBS,OTHER}
+ cp -p "$MYSRCDIR"/* "$BUILD_ROOT/$TOPDIR/SOURCES/"
+ chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/$TOPDIR"
+}
+
+recipe_prepare_collax()
+{
+ DEB_SOURCEDIR="$TOPDIR/SOURCES"
+ DEB_DSCFILE="$RECIPEFILE"
+ chmod -v +x "$BUILD_ROOT/$DEB_SOURCEDIR/build.collax"
+ ln -fsv build.collax "$BUILD_ROOT/$DEB_SOURCEDIR/build"
+}
+
+collax_build()
+{
+ local buildroot="$1"
+
+ if test -n "$RUN_SHELL"; then
+ chroot "$buildroot" su -
+ ret=$?
+ else
+ chroot "$buildroot" su - $BUILD_USER -c \
+ "cd $TOPDIR/SOURCES && ./build"
+ ret=$?
+ fi
+ if test "$ret" = 0; then
+ BUILD_SUCCEEDED=true
+ fi
+}
+
+collax_move_build_result()
+{
+ for f in "$BUILD_ROOT/$DEB_SOURCEDIR"/*.{deb,changes}; do
+ test -f "$f" && mv -v "$f" "$BUILD_ROOT/$TOPDIR/DEBS/"
+ done
+}
+
+recipe_build_collax()
+{
+ collax_build "$BUILD_ROOT"
+ collax_move_build_result
+}
+
+recipe_resultdirs_collax()
+{
+ echo DEBS
+}
diff --git a/build-recipe-debbuild b/build-recipe-debbuild
new file mode 100644
index 0000000..08a33a3
--- /dev/null
+++ b/build-recipe-debbuild
@@ -0,0 +1,52 @@
+#
+# debbuild specific functions.
+#
+################################################################
+#
+# Copyright (c) 2015 SUSE Linux 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_debbuild() {
+ TOPDIR=`chroot $BUILD_ROOT su -c "debbuild --eval '%_topdir'" - $BUILD_USER`
+ if test -z "$TOPDIR"; then
+ cleanup_and_exit 1 "Error: TOPDIR empty"
+ fi
+ test "$DO_INIT_TOPDIR" = false || 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"
+ mkdir -p "$BUILD_ROOT$TOPDIR/SDEBS"
+ mkdir -p "$BUILD_ROOT$TOPDIR/BUILD"
+ test -e "$BUILD_ROOT$TOPDIR/SPECS" || ln -s SOURCES "$BUILD_ROOT$TOPDIR/SPECS"
+ chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
+ cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
+}
+
+recipe_prepare_debbuild() {
+ recipe_prepare_spec "$@"
+}
+
+recipe_build_debbuild() {
+ recipe_build_spec "$@"
+}
+
+recipe_resultdirs_debbuild() {
+ echo DEBS SDEBS
+}
+
diff --git a/build-recipe-debootstrap b/build-recipe-debootstrap
new file mode 100644
index 0000000..65bbfbd
--- /dev/null
+++ b/build-recipe-debootstrap
@@ -0,0 +1,80 @@
+#
+# 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 --keep-debootstrap-dir --no-check-gpg --variant=buildd --arch="${arch}" --include="$FULL_PKG_LIST" "$dist" "$myroot" file:///.build.binaries
+ echo "running debootstrap..."
+ if ! "$@" || ! chroot $BUILD_ROOT dpkg --configure -a; then
+ cat $BUILD_ROOT/debootstrap/debootstrap.log
+ cleanup_and_exit 1 "Failed to setup debootstrap chroot"
+ fi
+
+ # 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 "$BUILD_ROOT/$myroot"
+
+ # move topdir back
+ mv "$BUILD_ROOT/$myroot/$TOPDIR" "$BUILD_ROOT/${TOPDIR%/*}"
+
+ # move result
+ dsc_move_build_result
+}
+
+recipe_resultdirs_debootstrap() {
+ echo DEBS
+}
+
diff --git a/build-recipe-dsc b/build-recipe-dsc
new file mode 100644
index 0000000..dcd168e
--- /dev/null
+++ b/build-recipe-dsc
@@ -0,0 +1,136 @@
+#
+# 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
+ test "$DO_INIT_TOPDIR" = false || 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
+ # remove rpm macros (everything after "%")
+ # they are not evaluated by the Debian build process
+ DEB_RELEASE=`sed 's/%.*$//' <<< $RELEASE`
+ OBS_DCH_RELEASE=""
+
+ if test -n "$DEB_TRANSFORM" ; then
+ CHANGELOGARGS=
+ test -n "$CHANGELOG" -a -f "$BUILD_ROOT/.build-changelog" && CHANGELOGARGS="--changelog $BUILD_ROOT/.build-changelog"
+ echo "Found files matching debian.*, running debian transformer..."
+ if [ "$RELEASE" ]; then
+ 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
+ cleanup_and_exit 1 "debian transforming failed."
+ 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
+
+ # Alternative to debtransform: apply OBS release number if tag OBS-DCH-RELEASE is set.
+ if test -z "$DEB_TRANSFORM" && grep -Eq '^OBS-DCH-RELEASE: 1' $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE; then
+ OBS_DCH_RELEASE="+$DEB_RELEASE"
+ chroot $BUILD_ROOT su -c /bin/sh <<EOF
+cd $TOPDIR/BUILD
+[ ! -f debian/changelog ] && exit 0
+# avoid devscripts dependency and mimic dch
+PACKAGE=\$(dpkg-parsechangelog 2> /dev/null | grep -E '^Source:' | awk '{ print \$NF }')
+VERSION=\$(dpkg-parsechangelog 2> /dev/null | grep -E '^Version:' | awk '{ print \$NF }')
+sed -i "s/\${PACKAGE} (\${VERSION})/\${PACKAGE} (\${VERSION}$OBS_DCH_RELEASE)/" debian/changelog
+EOF
+ fi
+
+}
+
+dsc_build() {
+ local buildroot=$1
+
+ 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 $buildroot/$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 $buildroot/$TOPDIR/SOURCES/build.script
+ fi
+
+ if test -n "$RUN_SHELL"; then
+ chroot $buildroot su -
+ else
+ chroot $buildroot 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" && ( chroot $buildroot su -c "which lintian > /dev/null" - $BUILD_USER < /dev/null ); then
+ DEB_CHANGESFILE=${DEB_DSCFILE%.dsc}$OBS_DCH_RELEASE"_"$(chroot $buildroot su -c 'dpkg-architecture -qDEB_BUILD_ARCH')".changes"
+ chroot $buildroot su -c "cd $TOPDIR && echo Running lintian && (set -x && lintian -i $TOPDIR/$DEB_CHANGESFILE)" - $BUILD_USER < /dev/null || BUILD_SUCCEEDED=false
+ fi
+ fi
+}
+
+dsc_move_build_result() {
+ for DEB in $BUILD_ROOT/$TOPDIR/*.{deb,changes} ; 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_build_dsc() {
+ dsc_build "$BUILD_ROOT"
+ dsc_move_build_result
+}
+
+recipe_resultdirs_dsc() {
+ echo DEBS
+}
diff --git a/build-recipe-kiwi b/build-recipe-kiwi
new file mode 100644
index 0000000..5d230b9
--- /dev/null
+++ b/build-recipe-kiwi
@@ -0,0 +1,621 @@
+#
+# 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 for legacy bundling
+#
+# used for kiwi versions below 5.06.106 that do not support
+# a bundling method
+#
+
+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
+}
+
+legacy_image_bundle() {
+ # 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_setup_kiwi() {
+ TOPDIR=/usr/src/packages
+ test "$DO_INIT_TOPDIR" = false || 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/KIWI"
+ # compat, older build versions did not clean TOPDIR ...
+ mkdir -p "$BUILD_ROOT$TOPDIR/BUILD"
+ mkdir -p "$BUILD_ROOT$TOPDIR/RPMS"
+ mkdir -p "$BUILD_ROOT$TOPDIR/SRPMS"
+
+ 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
+ cleanup_and_exit 1 "source copy failed"
+ 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
+}
+
+perform_product_bundle() {
+ pushd $BUILD_ROOT/$TOPDIR/KIWIROOT/main
+ for i in * ; do
+ test -e "$i" || continue
+ case $i 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
+ popd
+}
+
+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 destination
+ perform_product_bundle
+}
+
+perform_image_build() {
+ local imgtype=$1
+ local legacy=$2
+ local profile=$3
+ local prepare_call
+ local create_call
+ # When people test mixed build with legacy and new kiwi version
+ # The zypper cache was used in different ways. Therefore this
+ # needs a cleanup before the build starts
+ echo "Cleanup zypper image build cache"
+ if [ -d "$BUILD_ROOT/var/cache/kiwi/zypper" ];then
+ rm -rf $BUILD_ROOT/var/cache/kiwi/zypper
+ fi
+ if test -n "$profile" -a "$profile" != __not__set ; then
+ echo "running kiwi --prepare for $imgtype, profile $profile..."
+ else
+ echo "running kiwi --prepare for $imgtype..."
+ fi
+ # Do not use $BUILD_USER here, since we always need root permissions
+ prepare_call="cd $TOPDIR/SOURCES && rm -rf $TOPDIR/KIWIROOT-$imgtype"
+ if [ "$legacy" = "true" ]; then
+ prepare_call="$prepare_call && /usr/sbin/kiwi --logfile terminal"
+ else
+ prepare_call="$prepare_call && LANG=en_US.UTF-8 /usr/bin/kiwi"
+ prepare_call="$prepare_call --compat -- --debug"
+ fi
+ prepare_call="$prepare_call --prepare $TOPDIR/SOURCES"
+ prepare_call="$prepare_call --root $TOPDIR/KIWIROOT-$imgtype"
+ if test -n "$profile" -a "$profile" != __not__set ; then
+ prepare_call="$prepare_call --add-profile $profile"
+ fi
+ prepare_call="$prepare_call $KIWI_PARAMETERS"
+ echo "$prepare_call"
+ chroot $BUILD_ROOT \
+ su -c "$prepare_call" - root < /dev/null || cleanup_and_exit 1
+
+ if test -n "$profile" -a "$profile" != __not__set ; then
+ echo "running kiwi --create for $imgtype, profile $profile..."
+ else
+ echo "running kiwi --create for $imgtype..."
+ fi
+ mkdir -p $BUILD_ROOT/$TOPDIR/KIWI-$imgtype
+ create_call="cd $TOPDIR/SOURCES"
+ if [ "$legacy" = "true" ]; then
+ create_call="$create_call && LANG=en_US.UTF-8 /usr/sbin/kiwi"
+ create_call="$create_call --logfile terminal"
+ else
+ create_call="$create_call && /usr/bin/kiwi --compat -- --debug"
+ fi
+ create_call="$create_call --create $TOPDIR/KIWIROOT-$imgtype"
+ create_call="$create_call --type $imgtype"
+ create_call="$create_call -d $TOPDIR/KIWI-$imgtype"
+ if test -n "$profile" -a "$profile" != __not__set ; then
+ create_call="$create_call --add-profile $profile"
+ fi
+ create_call="$create_call $KIWI_PARAMETERS"
+ echo "$create_call"
+ chroot $BUILD_ROOT \
+ su -c "$create_call" - root < /dev/null || cleanup_and_exit 1
+}
+
+perform_image_bundle() {
+ local imgtype=$1
+ local legacy=$2
+ local profile=$3
+ local bundle_call
+
+ local kiwi_profile=""
+ if [ "$profile" != "__not__set" ]; then
+ kiwi_profile="${profile}-"
+ fi
+
+ rm -rf "/$TOPDIR/KIWI.bundle"
+ if [ "$legacy" = "true" ]; then
+ bundle_call="/usr/sbin/kiwi --bundle-build $TOPDIR/KIWI-$imgtype"
+ bundle_call="$bundle_call -d /$TOPDIR/KIWI.bundle/"
+ bundle_call="$bundle_call --bundle-id ${kiwi_profile}Build$RELEASE"
+ else
+ bundle_call="LANG=en_US.UTF-8 /usr/bin/kiwi result bundle"
+ bundle_call="$bundle_call --target-dir $TOPDIR/KIWI-$imgtype"
+ bundle_call="$bundle_call --id ${kiwi_profile}Build$RELEASE"
+ bundle_call="$bundle_call --bundle-dir /$TOPDIR/KIWI.bundle/"
+ fi
+ echo "$bundle_call"
+ if chroot $BUILD_ROOT su -c "$bundle_call" - root < /dev/null; then
+ mv "$BUILD_ROOT/$TOPDIR/KIWI.bundle/"* \
+ "$BUILD_ROOT/$TOPDIR/KIWI/" || cleanup_and_exit 1
+ rmdir "$BUILD_ROOT/$TOPDIR/KIWI.bundle"
+ # success
+ return 0
+ fi
+ # need another way to bundle
+ return 1
+}
+
+is_legacy_kiwi() {
+ if [ -L "$BUILD_ROOT/usr/bin/kiwi" ];then
+ # The next generation of kiwi is installed to /usr/bin
+ # If this file is found we expect the new kiwi to be
+ # installed
+ return 1
+ fi
+ # in any other case stick to the legacy kiwi
+ return 0
+}
+
+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
+ local kiwi_profile=$(queryconfig \
+ --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" \
+ --archpath "$BUILD_ARCH" buildflags kiwiprofile
+ )
+ if test -z "$kiwi_profile"; then
+ kiwi_profile=__not__set
+ fi
+ local legacy=false
+ if is_legacy_kiwi ; then
+ legacy=true
+ fi
+ RUN_BUNDLE=true
+ for imgtype in $imagetype ; do
+ for prof in ${kiwi_profile//,/ } ; do
+ perform_image_build $imgtype $legacy $prof
+ if perform_image_bundle $imgtype $legacy $prof; then
+ # bundling successful, skip legacy bundler
+ unset RUN_BUNDLE
+ fi
+ done
+ done
+ BUILD_SUCCEEDED=true
+
+ if test -n "$RUN_BUNDLE"; then
+ # results are not bundled yet
+ legacy_image_bundle
+ fi
+}
+
+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
index 0000000..c53b69b
--- /dev/null
+++ b/build-recipe-livebuild
@@ -0,0 +1,249 @@
+#################################################################
+#
+# 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
+ test "$DO_INIT_TOPDIR" = false || 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"
+ LIVE_IMAGE_NAME="${RECIPEFILE%.livebuild}"
+ 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/*)
+ if [ ${#files[@]} -gt 0 ]; then
+ cleanup_and_exit 1 "E: No configuration in config/archives/* allowed"
+ fi
+
+ # 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 \
+ "export RECIPEFILE=${RECIPEFILE}; /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 \
+ "export RECIPEFILE=${RECIPEFILE}; /.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
+
+ # extract build result basenames
+ local build_results=""
+ for i in $BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT/* ; do
+ test -f "$i" || continue
+ case "${i##*/}" in
+ *.hybrid.iso)
+ build_results="${build_results}\n${i%%.hybrid.iso}"
+ ;;
+ *.iso)
+ build_results="${build_results}\n${i%%.iso}"
+ ;;
+ *.img)
+ build_results="${build_results}\n${i%%.img}"
+ ;;
+ *.netboot.tar*)
+ build_results="${build_results}\n${i%%.netboot.tar*}"
+ ;;
+ *.tar*)
+ build_results="${build_results}\n${i%%.tar*}"
+ ;;
+ *)
+ ;;
+ esac
+ done
+
+ # Fail the build if no build results are found
+ if [ -z "${build_results}" ] ; then
+ cleanup_and_exit 1 "No live-build result found"
+ fi
+
+ # move created products (and their metadata files) to destination
+ local buildnum="${RELEASE:+-Build${RELEASE}}"
+ for prefix in $(echo -e ${build_results} | sort | uniq) ; do
+ for f in ${prefix}.* ; do
+ mv ${f} \
+ $BUILD_ROOT/$TOPDIR/OTHER/${prefix##*/}${buildnum}${f#${prefix}}
+ BUILD_SUCCEEDED=true
+ done
+ done
+}
+
+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
index 0000000..3298fce
--- /dev/null
+++ b/build-recipe-mock
@@ -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
index 0000000..446236f
--- /dev/null
+++ b/build-recipe-preinstallimage
@@ -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-simpleimage b/build-recipe-simpleimage
new file mode 100644
index 0000000..54a90f6
--- /dev/null
+++ b/build-recipe-simpleimage
@@ -0,0 +1,108 @@
+################################################################
+#
+# 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_simpleimage() {
+ 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_simpleimage() {
+ BUILD_USER="root"
+}
+
+recipe_build_simpleimage() {
+ TOPDIR=/usr/src/packages
+
+ echo "creating simple image..."
+ cd $BUILD_ROOT || cleanup_and_exit 1
+ export SRCDIR="$TOPDIR/SOURCES"
+
+ NAME="`sed -n 's|Name:[[:blank:]]*||p' $BUILD_ROOT$TOPDIR/SOURCES/simpleimage`"
+ [ -n "$NAME" ] || NAME="simpleimage"
+ VERSION="`sed -n 's|Version:[[:blank:]]*||p' $BUILD_ROOT$TOPDIR/SOURCES/simpleimage`"
+ [ -n "$VERSION" ] || VERSION="`date -u +%y.%m.%d-%H.%M.%S`"
+
+ SHELL="/bin/sh"
+ [ -x $BUILD_ROOT/bin/bash ] && SHELL="/bin/bash"
+ if [ "`grep '^%build$' $BUILD_ROOT$TOPDIR/SOURCES/simpleimage`" ]; then
+ echo "Running integration script..."
+ sed -n '/%build/,$ p' $BUILD_ROOT$TOPDIR/SOURCES/simpleimage | tail -n +2 | chroot $BUILD_ROOT $SHELL -x || cleanup_and_exit 1
+ echo "Integration script finished."
+ fi
+
+ echo "Compresing the final image, this can take a while..."
+ echo
+ 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 ;;
+ .simpleimage*) continue ;;
+ .srcfiles*) continue ;;
+ .pkgs) continue ;;
+ .rpm-cache) continue ;;
+ .tmp) continue ;;
+ installed-pkg) continue ;;
+ proc|sys) continue ;;
+ esac
+ TOPDIRS="$TOPDIRS $DIR"
+ done
+ rm -rf "$BUILD_ROOT$TOPDIR"
+ mkdir -p .tmp/{proc,sys}
+ if ! $TAR -cvzf .simpleimage.tar.gz --one-file-system $TOPDIRS -C .tmp proc sys; then
+ cleanup_and_exit 1
+ fi
+ if [ -x "`which mksquashfs 2> /dev/null`" ]; then
+ echo
+ echo "Tarball done, creating squashfs image as well"
+ echo
+ mksquashfs $TOPDIRS .tmp/proc .tmp/sys .simpleimage.squashfs -info -keep-as-directory -no-progress || cleanup_and_exit 1
+ fi
+ echo "simple image created."
+
+ DEST="$BUILD_ROOT$TOPDIR/OTHER"
+ mkdir -p "$DEST"
+ mv $BUILD_ROOT/.simpleimage.tar.gz $DEST/$NAME-${VERSION}_${BUILD_ARCH%%:*}.tar.gz
+ if [ -r .simpleimage.squashfs ]; then
+ mv $BUILD_ROOT/.simpleimage.squashfs $DEST/$NAME-${VERSION}_${BUILD_ARCH%%:*}.squashfs
+ fi
+ rm -f $BUILD_ROOT/.build.packages
+ ln -s ${TOPDIR#/} $BUILD_ROOT/.build.packages
+ test -d "$SRCDIR" && cd "$SRCDIR"
+ cleanup_and_exit
+}
+
+recipe_resultdirs_simpleimage() {
+ :
+}
+
diff --git a/build-recipe-snapcraft b/build-recipe-snapcraft
new file mode 100644
index 0000000..e4b5e98
--- /dev/null
+++ b/build-recipe-snapcraft
@@ -0,0 +1,192 @@
+#################################################################
+#
+# snapcraft specific functions.
+#
+# Author: Adrian Schroeter <adrian@suse.de>
+#
+################################################################
+#
+# Copyright (c) 2016 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_snapcraft() {
+ TOPDIR=/usr/src/packages
+ test "$DO_INIT_TOPDIR" = false || rm -rf "$BUILD_ROOT$TOPDIR"
+ for i in OTHER SOURCES SNAPCRAFT_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_snapcraft() {
+ :
+}
+
+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
+}
+
+collect_prebuild_parts() {
+
+ mkdir -p $BUILD_ROOT/root/.local/share/snapcraft/
+ rm -f $BUILD_ROOT/root/.local/share/snapcraft/parts.yaml
+ for part in $BUILD_ROOT/.build.snap_parts/*; do
+ if [ -e "$part" ]; then
+ cat "$part/part.yaml" >> \
+ $BUILD_ROOT/root/.local/share/snapcraft/parts.yaml
+ fi
+ done
+}
+
+# This script expects that the $BUILD_ROOT is a Debian installation with
+# snapcraft already installed!
+#
+# Variables:
+# $BUILD_ROOT the Debian chroot
+# $TOPDIR/SOURCES includes the snapcraft sources
+# $TOPDIR/$SNAPCRAFT_ROOT where snapcraft will be called
+# $RECIPEFILE the name of the snapcraft.yaml config file
+
+recipe_build_snapcraft() {
+ local ARCH=$(chroot $BUILD_ROOT su -c "dpkg-architecture -qDEB_BUILD_ARCH")
+ local DIST="OBS"
+ local SNAPCRAFT_ROOT="SNAPCRAFT_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}
+ # setup /etc/apt/sources.list
+ mkdir -p "$BUILD_ROOT/etc/apt"
+ echo "deb [trusted=yes] file:/.build.binaries OBS main" >> "$BUILD_ROOT/etc/apt/sources.list"
+ fi
+
+ collect_prebuild_parts
+
+ chroot $BUILD_ROOT su -c "cd $TOPDIR/SOURCES && snapcraft pull" - root \
+ || cleanup_and_exit 1
+ chroot $BUILD_ROOT su -c "cd $TOPDIR/SOURCES && snapcraft build" - root \
+ || cleanup_and_exit 1
+ chroot $BUILD_ROOT su -c "cd $TOPDIR/SOURCES && snapcraft snap" - root \
+ || cleanup_and_exit 1
+
+ # extract build result basenames
+ local build_results=""
+ for i in $BUILD_ROOT/$TOPDIR/SOURCES/* ; do
+ test -f "$i" || continue
+ case "${i##*/}" in
+ *.snap)
+ build_results="${build_results}\n${i%%.snap}"
+ ;;
+ *)
+ ;;
+ esac
+ done
+
+ # Fail the build if no build results are found
+ if [ -z "${build_results}" ] ; then
+ cleanup_and_exit 1 "No live-build result found"
+ fi
+
+ # move created products (and their metadata files) to destination
+ local buildnum="${RELEASE:+-Build${RELEASE}}"
+ for prefix in $(echo -e ${build_results} | sort | uniq) ; do
+ for f in ${prefix}.* ; do
+ mv ${f} \
+ $BUILD_ROOT/$TOPDIR/OTHER/${prefix##*/}${buildnum}${f#${prefix}}
+ BUILD_SUCCEEDED=true
+ done
+ done
+}
+
+recipe_resultdirs_snapcraft() {
+ :
+}
+
+# Local Variables:
+# mode: Shell-script
+# End:
diff --git a/build-recipe-spec b/build-recipe-spec
new file mode 100644
index 0000000..a5123c9
--- /dev/null
+++ b/build-recipe-spec
@@ -0,0 +1,235 @@
+#
+# 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
+ cleanup_and_exit 1 "Error: TOPDIR empty"
+ fi
+ test "$DO_INIT_TOPDIR" = false || 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
+ 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
+
+ rawcfgmacros=.rpmmacros
+ test "$BUILDTYPE" = debbuild && rawcfgmacros=.debmacros
+
+ # 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
+
+ # extract macros from configuration
+ queryconfig rawmacros --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" > $BUILD_ROOT/root/$rawcfgmacros
+ if test -n "$BUILD_DEBUG" && test "$BUILDTYPE" != debbuild ; 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/$rawcfgmacros
+ fi
+
+ if test -n "$BUILD_JOBS" ; then
+ cat >> $BUILD_ROOT/root/$rawcfgmacros <<-EOF
+ %jobs $BUILD_JOBS
+ %_smp_mflags -j$BUILD_JOBS
+ EOF
+ fi
+ test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/$rawcfgmacros $BUILD_ROOT/home/abuild/$rawcfgmacros
+
+ # 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
+ test "$BUILDTYPE" = debbuild && rpmbuild=debbuild
+
+ # XXX: move _srcdefattr to macro file?
+ rpmbopts=("$BUILD_RPM_BUILD_STAGE" "--define" "_srcdefattr (-,root,root)")
+ if test "$DO_CHECKS" != true ; then
+ if chroot "$BUILD_ROOT" "$rpmbuild" --nocheck --help >/dev/null 2>&1; then
+ rpmbopts[${#rpmbopts[@]}]="--nocheck"
+ else
+ echo "warning: --nocheck is not supported by this $rpmbuild version"
+ fi
+ 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
+ toshellscript $rpmbuild \
+ "${definesnstuff[@]}" \
+ "${rpmbopts[@]}" \
+ "$TOPDIR/SOURCES/$RECIPEFILE" \
+ > $BUILD_ROOT/.build.command
+ 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 || {
+ cleanup_and_exit 1 "could not unpack $RECIPEFILE."
+ }
+ 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
+ cleanup_and_exit 1 "please fix your filelist (e.g. add defattr)"
+ 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
+ chroot $BUILD_ROOT su -s /opt/testing/bin/rpmlint "$BUILD_USER" -- \
+ --info ${LINT_RPM_FILE_LIST[*]#$BUILD_ROOT} \
+ ${SRPM_FILE_LIST[*]#$BUILD_ROOT} > >(tee "$BUILD_ROOT$rpmlint_logfile") 2>&1 || ret=1
+ echo
+ 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"
+ 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
+ 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-validate-params b/build-validate-params
new file mode 100644
index 0000000..27027bb
--- /dev/null
+++ b/build-validate-params
@@ -0,0 +1,103 @@
+#
+# parameter validation functions
+#
+################################################################
+#
+# Copyright (c) 2016 SUSE LLC
+#
+# 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
+#
+################################################################
+
+validate_param=()
+validate_buildroot=()
+
+validate_init() {
+ local cf="$1"
+ if ! test -f "$cf" ; then
+ return
+ fi
+ local _key _flag _arg
+ while read _key _flag _arg; do
+ case $_key in
+ \#* | '')
+ continue ;;
+ ALLOW_PARAM:)
+ validate_param[${#validate_param[@]}]="${_flag#--} $_arg"
+ ;;
+ ALLOW_BUILD_ROOT:)
+ validate_buildroot[${#validate_buildroot[@]}]="$_flag"
+ ;;
+ *)
+ cleanup_and_exit 1 "unknown directive in $cf: $_key"
+ ;;
+ esac
+ done < "$cf"
+}
+
+validate_param() {
+ local param="$1"
+ local arg="$2"
+ local envvar="$3"
+
+ if test ${#validate_param[@]} -eq 0 ; then
+ return
+ fi
+ param=${param#-}
+ param=${param#-}
+ local t ok=
+ for t in "${validate_param[@]}" ; do
+ local targ="${t#$param }"
+ if test "$t" != "$targ" ; then
+ if test -z "$targ" -o "$targ" == "$arg" ; then
+ ok=true
+ break
+ fi
+ fi
+ done
+ if test -z "$ok" ; then
+ if test -n "$envvar" ; then
+ cleanup_and_exit 1 "build: environment variable $envvar=$arg not allowed"
+ else
+ cleanup_and_exit 1 "build: parameter --$param $arg not allowed"
+ fi
+ fi
+}
+
+validate_buildroot() {
+ local br="$1"
+
+ if test ${#validate_buildroot[@]} -eq 0 ; then
+ return
+ fi
+ local user=${SUDO_USER:-$USER}
+ local t ok= error="Build root $br not allowed for user $user"
+ for t in "${validate_buildroot[@]}" ; do
+ t=${t//\%user/$user}
+ t=$(readlink -m "$t")
+ if [[ "$br" == $t ]] ; then
+ local tp=$(readlink -m "${t%/*}")
+ if test -d "$tp" ; then
+ ok=true
+ break
+ fi
+ error="Directory $tp does not exist"
+ fi
+ done
+ if test -z "$ok" ; then
+ cleanup_and_exit 1 "$error"
+ fi
+}
+
diff --git a/build-vm b/build-vm
new file mode 100644
index 0000000..6231e93
--- /dev/null
+++ b/build-vm
@@ -0,0 +1,994 @@
+#
+# 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=
+VM_NETOPT=()
+VM_NETDEVOPT=()
+VM_DEVICEOPT=()
+VM_TELNET=
+VM_CONSOLE_INPUT=
+VM_USER=
+VMDISK_ROOTSIZE=4096
+VMDISK_SWAPSIZE=1024
+VMDISK_FILESYSTEM=
+VMDISK_MOUNT_OPTIONS=__default
+VMDISK_CLEAN=
+VM_VOLUME_NAME=
+VM_VOLUME_SWAP=
+VM_HOSTNAME=
+
+# zvm specific?
+VM_WORKER_NR=
+
+# kvm specific?
+HUGETLBFSPATH=
+VM_CUSTOMOPT=
+
+# emulator specific?
+EMULATOR_SCRIPT=
+
+for i in ec2 emulator kvm lxc openstack qemu uml xen zvm docker pvm; 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|docker) ;;
+ ec2|xen|kvm|uml|qemu|emulator|openstack|zvm|pvm)
+ test -z "$VM_IMAGE" && VM_IMAGE=1
+ ;;
+ none|chroot) VM_TYPE= ;;
+ *)
+ cleanup_and_exit 1 "VM '$VM_TYPE' is not supported"
+ ;;
+ 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
+ ;;
+ -vm-user)
+ needarg
+ VM_USER="$ARG"
+ shift
+ ;;
+ -vm-enable-console)
+ VM_CONSOLE_INPUT=true
+ ;;
+ -vm-telnet)
+ needarg
+ VM_TELNET="$ARG"
+ shift
+ ;;
+ -vm-net)
+ needarg
+ VM_NETOPT=("${VM_NETOPT[@]}" "$ARG")
+ shift
+ ;;
+ -vm-netdev)
+ needarg
+ VM_NETDEVOPT=("${VM_NETDEVOPT[@]}" "$ARG")
+ shift
+ ;;
+ -vm-device)
+ needarg
+ VM_DEVICEOPT=("${VM_DEVICEOPT[@]}" "$ARG")
+ shift
+ ;;
+ -vm-custom-opt)
+ needarg
+ VM_CUSTOMOPT="$ARG"
+ shift
+ ;;
+ -*)
+ return 1
+ ;;
+ esac
+ nextargs=("$@")
+ return 0
+}
+
+
+#
+# shutdown the system from inside the VM
+#
+vm_shutdown() {
+ test -n "$VM_WATCHDOG" && echo "### VM INTERACTION 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 -o "$VM_TYPE" = docker && 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"
+
+ if test -e "${img}" ; then
+ local origsize=$(cat "${img}.size" 2> /dev/null)
+ if test -z "$origsize" -o "$origsize" != "$size" ; then
+ echo "Resizing $img (${size}M)"
+ fi
+ else
+ echo "Creating $img (${size}M)"
+ rm -f "${img}.size"
+ fi
+
+ mkdir -p "${img%/*}" || cleanup_and_exit 3
+ # truncate file to the desired size
+ dd if=/dev/zero of="$img" bs=1M count=0 seek="$size" || cleanup_and_exit 3
+ echo "$size" > "${img}.size"
+ # allocate blocks
+ if type -p fallocate > /dev/null ; then
+ fallocate -p -l "${size}M" "$img" 2> /dev/null
+ errout=$( fallocate -l "${size}M" "$img" 2>&1 )
+ if test $? != 0; then
+ echo $errout
+ if test "${errout/Operation not supported/}" = "$errout"; then
+ # Do not fail on not support file systems, eg ext2 or ext3
+ cleanup_and_exit 3
+ fi
+ fi
+ fi
+}
+
+vm_img_wipe() {
+ vm_wipe_$VM_TYPE "$@"
+
+ if test -n "$VM_IMAGE" -a "$VM_IMAGE" != __not_attached__ -a ! -b "$VM_IMAGE" ; then
+ rm -f "$VM_IMAGE"
+ fi
+ if test -n "$VM_SWAP" -a "$VM_SWAP" != __not_attached__ -a ! -b "$VM_SWAP" ; then
+ rm -f "$VM_SWAP"
+ 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
+ cleanup_and_exit 3 "filesystem \"$fs\" is not supported"
+ 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
+ BUILD_OPTIONS_PARSED=
+ while sleep 5 ; do
+ WATCH=`grep -a "### VM INTERACTION" "$LOGFILE" | tail -n 1`
+ case $WATCH in
+ *VM\ INTERACTION\ START*) test -n "$WATCHDOG_START" || WATCHDOG_START=`date +%s` ;;
+ *VM\ INTERACTION\ 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 ###"
+ vm_kill
+ 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 ;;
+ *) cleanup_and_exit 1 "Unknown architecture personality: '$archname'" ;;
+ 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
+ BUILD_OPTIONS_PARSED=true
+ 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 "### VM INTERACTION END ###"
+ echo "2nd stage started in virtual machine"
+ # fedora packages sometimes do not have the needed links
+ ldconfig
+ 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 -a "$VM_TYPE" != docker ; 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
+ # Docker already has sysfs mounted ro elsewhere,
+ # need to remount rw explicitly.
+ mount -o remount,rw 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
+ test -d /dev/shm || rm -f /dev/shm
+ mkdir -p /dev/pts
+ mkdir -p /dev/shm
+ mount -n -tdevpts -omode=0620,gid=5 none /dev/pts
+ mount -n -ttmpfs none /dev/shm
+
+ if test -n "$VM_SWAP" ; then
+ if "$VM_SWAP" != "${VM_SWAP#LABEL=}" ; then
+ i=$(blkid -l -o device -t "$VM_SWAP")
+ if test "$i" = "${i#/}" ; then
+ cleanup_and_exit 1 "could not find swap device with $VM_SWAP"
+ fi
+ echo "resolved swap device $VM_SWAP to $i"
+ VM_SWAP=$i
+ fi
+ 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="$VM_HOSTNAME"
+
+ # repair dracut damage, see bsc#922676
+ test -L /var/run -a ! -e /var/run && rm -f /var/run
+ test -L /var/lock -a ! -e /var/lock && rm -f /var/lock
+
+ # 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
+ fi
+ echo "VM_IMAGE: $VM_IMAGE, VM_SWAP: $VM_SWAP"
+ vm_attach_root
+ # 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 "$VM_IMAGE" != __not_attached__ -a -f "$VM_IMAGE" ; then
+ echo "Deleting old $VM_IMAGE"
+ rm -rf "$VM_IMAGE"
+ fi
+ if test -n "$VM_SWAP" -a "$VM_SWAP" != __not_attached__ -a -f "$VM_SWAP" ; then
+ echo "Deleting old $VM_SWAP"
+ rm -rf "$VM_SWAP"
+ fi
+ fi
+ if test ! -b "$VM_IMAGE" ; then
+ vm_img_create "$VM_IMAGE" "$VMDISK_ROOTSIZE"
+ fi
+ if test -z "$CLEAN_BUILD" ; then
+ vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE"
+ fi
+ if test -n "$VM_SWAP" -a "$VM_SWAP" != __not_attached__ -a ! -b "$VM_SWAP" ; then
+ vm_img_create "$VM_SWAP" "$VMDISK_SWAPSIZE"
+ fi
+ if test ! -e "$VM_IMAGE" ; then
+ cleanup_and_exit 3 "you need to create $VM_IMAGE first"
+ 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
+ if "$VM_SWAPDEV" != "${VM_SWAPDIR#LABEL=}"; then
+ # call mkswap to set a label
+ mkswap -L "${VM_SWAPDIR#LABEL=}" "$VM_SWAP"
+ fi
+ vm_detach_swap
+ # mkswap happens inside of the vm
+ fi
+}
+
+vm_update_hostarch() {
+ local kernel="$vm_kernel"
+ local hostarchfile
+ local newhostarch
+ if test -z "$VM_KERNEL" -a -e "$BUILD_ROOT/.build.kernel.$VM_TYPE" ; then
+ kernel="$BUILD_ROOT/.build.kernel.$VM_TYPE"
+ hostarchfile="$BUILD_ROOT/.build.hostarch.$VM_TYPE"
+ elif test -n "$kernel" -a -e "$kernel" -a -e "$kernel.hostarch" ; then
+ hostarchfile="$kernel.hostarch"
+ fi
+ if test -n "$hostarchfile" -a -e "$hostarchfile"; then
+ newhostarch=`cat "$hostarchfile"`
+ elif test -n "$kernel" -a -e "$kernel" ; then
+ case `objdump -f "$kernel" | sed -ne 's/.*file format //p'` in
+ elf64-powerpcle) newhostarch=ppc64le ;;
+ elf64-powerpc) newhostarch=ppc64 ;;
+ esac
+ fi
+ if test -n "$newhostarch" -a "$newhostarch" != "$BUILD_HOST_ARCH" ; then
+ echo "setting hostarch to $newhostarch"
+ BUILD_HOST_ARCH="$newhostarch"
+ # update BUILD_INITVM_ARCH
+ build_host_arch
+ 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
+
+ # update the hostarch
+ if test -n "$VM_IMAGE" ; then
+ vm_update_hostarch
+ fi
+
+ # 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 "DO_INIT_TOPDIR='${DO_INIT_TOPDIR//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+ echo "KIWI_PARAMETERS='${KIWI_PARAMETERS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+ echo "VM_TELNET='${VM_TELNET//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
+ echo "VM_CONSOLE_INPUT='${VM_CONSOLE_INPUT//"'"/$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[567]}" && PERSONALITY=8 ;; # workaround, to be removed
+ esac
+ test "$VM_TYPE" = lxc -o "$VM_TYPE" = docker && PERSONALITY=0
+ echo "PERSONALITY='$PERSONALITY'" >> $BUILD_ROOT/.build/build.data
+ echo "VM_HOSTNAME='$HOST'" >> $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
+
+ echo "booting $VM_TYPE..."
+
+ # start watchdog if requested
+ if test -n "$VM_WATCHDOG" ; then
+ start_watchdog
+ echo "### VM INTERACTION START ###"
+ fi
+
+ vm_startup
+
+ # kill watchdog again
+ if test -n "$VM_WATCHDOG" ; then
+ echo "### VM INTERACTION 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/xvda && device="xvda" # in newer XEN setups
+ 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
+}
+
+vm_setup_network() {
+ 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 "$VM_TELNET"; then
+ VM_TELNET_DEVICE=$( cd /sys/class/net/; echo * )
+ VM_TELNET_DEVICE=${VM_TELNET_DEVICE#lo }
+ VM_TELNET_DEVICE=${VM_TELNET_DEVICE%% *}
+ if test -z "$VM_TELNET_DEVICE" ; then
+ cleanup_and_exit 1 "ERROR: no network device found for telnet server"
+ fi
+ if test -x /sbin/ip ; then
+ ip addr add 10.0.2.15/8 dev ${VM_TELNET_DEVICE}
+ ip addr add ::1/24 dev ${VM_TELNET_DEVICE}
+ ip link set ${VM_TELNET_DEVICE} up
+ elif test -x /sbin/ifconfig ; then
+ ifconfig ${VM_TELNET_DEVICE} 10.0.2.15 up
+ ifconfig ${VM_TELNET_DEVICE} add ::1/24
+ else
+ cleanup_and_exit 1 "ERROR: neither /sbin/ifconfig nor /sbin/ip is installed, please specify correct package via -x option"
+ fi
+ fi
+ if test -n "$VM_HOSTNAME" ; then
+ hostname "$VM_HOSTNAME"
+ fi
+ if test -n "$VM_TELNET"; then
+ echo WARNING: telnet option used, setting up telnet server ${VM_TELNET_DEVICE}
+ if test -x /usr/sbin/in.telnetd; then
+ ( /usr/sbin/in.telnetd -L /.build/telnet_login_wrapper -debug 23 & )
+ else
+ cleanup_and_exit 1 "ERROR: /usr/sbin/in.telnetd is not installed, please specify correct package via -x option"
+ fi
+ fi
+}
diff --git a/build-vm-docker b/build-vm-docker
new file mode 100644
index 0000000..b11ed43
--- /dev/null
+++ b/build-vm-docker
@@ -0,0 +1,80 @@
+#
+# Docker specific functions
+#
+################################################################
+#
+# Copyright (c) 2015 Oleg Girko
+# Copyright (c) 2015 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_docker() {
+ VM_IMAGE=
+ VM_SWAP=
+}
+
+vm_startup_docker() {
+ local name="obsbuild.${BUILD_ROOT##*/}"
+ docker rm "$name" >/dev/null 2>&1 || true
+ docker run \
+ --rm --name "$name" --cap-add=sys_admin --cap-add=MKNOD --net=none \
+ -v "$BUILD_ROOT:/mnt" busybox /bin/chroot /mnt "$vm_init_script"
+ BUILDSTATUS="$?"
+ test "$BUILDSTATUS" != 255 || BUILDSTATUS=3
+ cleanup_and_exit "$BUILDSTATUS"
+}
+
+vm_kill_docker() {
+ local name="obsbuild.${BUILD_ROOT##*/}"
+ docker stop -t 2 "$name" || true
+}
+
+vm_fixup_docker() {
+ # loop devices are needed for kiwi builds at least
+ max_loop=`cat /sys/module/loop/parameters/max_loop`
+ if [ "$max_loop" = "0" ]; then
+ max_loop=16
+ fi
+ for $num in `seq 0 $max_loop`; do
+ test -b /dev/loop$num || mknod -m660 /dev/loop$num b 7 $num
+ done
+}
+
+vm_attach_root_docker() {
+ :
+}
+
+vm_attach_swap_docker() {
+ :
+}
+
+vm_detach_root_docker() {
+ :
+}
+
+vm_detach_swap_docker() {
+ :
+}
+
+vm_cleanup_docker() {
+ :
+}
+
+vm_wipe_docker() {
+ local name="obsbuild.${BUILD_ROOT##*/}"
+ docker rm "$name" >/dev/null 2>&1 || true
+}
diff --git a/build-vm-ec2 b/build-vm-ec2
new file mode 100644
index 0000000..2803b82
--- /dev/null
+++ b/build-vm-ec2
@@ -0,0 +1,226 @@
+#
+# 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_wipe_ec2() {
+ # not yet implemented
+ :
+}
+
+vm_verify_options_ec2() {
+ # verify settings
+ if test -z "$AWS_ACCESS_KEY" -o -z "$AWS_ACCESS_KEY" ; then
+ cleanup_and_exit 3 "ERROR: No amazon EC2 environment set. Set AWS_ACCESS_KEY and AWS_SECRET_KEY."
+ 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
+ cleanup_and_exit 1 "Unknown Amazon EC2 Zone: $BUILD_EC2_ZONE"
+ fi
+ if test -z "$BUILD_EC2_AKI" ; then
+ cleanup_and_exit 3 "ERROR: No image refering to kernel and ramdisk is defined in BUILD_EC2_AKI env."
+ fi
+ if test -z "$VM_VOLUME_NAME" ; then
+ cleanup_and_exit 3 "ERROR: No worker root VM volume name specified."
+ fi
+ if test -z "$VM_VOLUME_SWAP" ; then
+ cleanup_and_exit 3 "ERROR: No worker swap VM volume name specified."
+ 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
+ cleanup_and_exit 1 "could not kill EC2 instance $VM_BUILD_INSTANCE"
+ 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
+ cleanup_and_exit 3 "ERROR: Failed to create snapshot for root disk $VM_VOLUME_NAME"
+ 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
index 0000000..a4f3cd5
--- /dev/null
+++ b/build-vm-emulator
@@ -0,0 +1,94 @@
+#
+# 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
+ cleanup_and_exit 3 "ERROR: The emulator returned with a failure"
+ 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
+ cleanup_and_exit 1 "could not kill build in $VM_IMAGE"
+ 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() {
+ :
+}
+vm_wipe_emulator() {
+ :
+}
+
diff --git a/build-vm-kvm b/build-vm-kvm
new file mode 100644
index 0000000..a8702e0
--- /dev/null
+++ b/build-vm-kvm
@@ -0,0 +1,320 @@
+#
+# 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_serial_device=
+kvm_rng_device=virtio-rng-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
+ cleanup_and_exit 3 "put kvm_rma_count=<VM number> or kvm_hpt_count=<> to your boot options"
+ fi
+}
+
+kvm_check_hugetlb() {
+ if ! grep -q "$HUGETLBFSPATH" /proc/mounts ; then
+ cleanup_and_exit 3 "hugetlbfs is not mounted to $HUGETLBFSPATH"
+ 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
+ cleanup_and_exit 3 "could not determine hugetlbfs block size"
+ 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 virt -cpu host"
+ 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
+ kvm_rng_device=virtio-rng-device
+ ;;
+ armv8l|aarch64)
+ kvm_bin="/usr/bin/qemu-system-aarch64"
+ kvm_console=ttyAMA0
+ vm_kernel=/boot/Image
+ vm_initrd=/boot/initrd
+ if test "${BUILD_ARCH#aarch}" != "$BUILD_ARCH" -o "${BUILD_ARCH#armv8}" != "$BUILD_ARCH"; then
+ kvm_options="-enable-kvm -cpu host "
+ test -e /boot/Image.guest && vm_kernel=/boot/Image.guest
+ test -e /boot/initrd.guest && vm_initrd=/boot/initrd.guest
+ else
+ # Running an armv7 kernel on aarch64
+ kvm_options="-enable-kvm -cpu host,aarch64=off "
+ # prefer the guest kernel/initrd
+ test -e /boot/Image.guest32 && vm_kernel=/boot/Image.guest32
+ test -e /boot/initrd.guest32 && vm_initrd=/boot/initrd.guest32
+ fi
+ # This option only exists with QEMU 2.5 or newer
+ if $kvm_bin -machine 'virt,?' 2>&1 | grep -q gic-version ; then
+ # We want to use the host gic version in order to make use
+ # of all available features (e.g. more than 8 CPUs) and avoid
+ # the emulation overhead of vGICv2 on a GICv3 host.
+ kvm_options+="-M virt,gic-version=host"
+ else
+ kvm_options+="-M virt"
+ fi
+ kvm_device=virtio-blk-device
+ kvm_rng_device=virtio-rng-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
+ if test -e /boot/vmlinuxbe -a -e /boot/initrdbe ; then
+ if test "$BUILD_ARCH" = ppc -o "$BUILD_ARCH" = ppc64 ; then
+ vm_kernel=/boot/vmlinuxbe
+ vm_initrd=/boot/initrdbe
+ fi
+ 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
+ kvm_serial_device=virtio-serial-ccw
+ kvm_rng_device=virtio-rng-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
+
+ test -n "$VM_CUSTOMOPT" && kvm_options="$kvm_options $VM_CUSTOMOPT"
+ if test -n "$VM_NETOPT" -o -n "$VM_NETDEVOPT" ; then
+ if test -n "$VM_NETOPT" ; then
+ for item in "${VM_NETOPT[@]}" ; do
+ kvm_options="$kvm_options -net $item"
+ done
+ fi
+ if test -n "$VM_NETDEVOPT" ; then
+ for item in "${VM_NETDEVOPT[@]}" ; do
+ kvm_options="$kvm_options -netdev $item"
+ done
+ fi
+ fi
+
+ if test -n "$VM_DEVICEOPT" ; then
+ for item in "${VM_DEVICEOPT[@]}" ; do
+ kvm_options="$kvm_options -device $item"
+ done
+ fi
+
+ if test -n "$kvm_rng_device" ; then
+ if test -c /dev/hwrng &&
+ test -f /sys/class/misc/hw_random/rng_current &&
+ test "$(cat /sys/class/misc/hw_random/rng_current)" != none; then
+ rng_dev="/dev/hwrng"
+ else
+ rng_dev="/dev/random"
+ fi
+ kvm_options="$kvm_options -object rng-random,filename=$rng_dev,id=rng0 -device $kvm_rng_device,rng=rng0"
+ fi
+}
+
+vm_startup_kvm() {
+ qemu_bin="$kvm_bin"
+ qemu_args=(-drive file="$VM_IMAGE",format=raw,if=none,id=disk,serial=0,cache=unsafe -device "$kvm_device",drive=disk)
+ if [ -n "$VM_USER" ] ; then
+ getent passwd "$VM_USER" > /dev/null || cleanup_and_exit 3 "cannot find KVM user '$VM_USER'"
+ else
+ # use qemu user by default if available
+ getent passwd qemu >/dev/null && VM_USER=qemu
+ fi
+ [ -n "$VM_USER" ] && kvm_options="$kvm_options -runas $VM_USER"
+ if test -n "$VM_SWAP" ; then
+ qemu_args=("${qemu_args[@]}" -drive file="$VM_SWAP",format=raw,if=none,id=swap,serial=1,cache=unsafe -device "$kvm_device",drive=swap)
+ fi
+ # the serial console device needs to be compiled into the target kernel
+ # which is why we can not use virtio-serial on other platforms
+ if test -n "$kvm_serial_device" ; then
+ if test -n "$VM_CONSOLE_INPUT" ; then
+ qemu_args=("${qemu_args[@]}" -device "$kvm_serial_device" -device virtconsole,chardev=virtiocon0 -chardev stdio,mux=on,id=virtiocon0 -mon chardev=virtiocon0)
+ else
+ qemu_args=("${qemu_args[@]}" -device "$kvm_serial_device" -device virtconsole,chardev=virtiocon0 -chardev stdio,id=virtiocon0)
+ fi
+ elif test -n "$VM_CONSOLE_INPUT" ; then
+ qemu_args=("${qemu_args[@]}" -serial mon:stdio)
+ else
+ qemu_args=("${qemu_args[@]}" -serial stdio)
+ 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
+ qemu_rootfstype=""
+ if test -n "$VMDISK_FILESYSTEM" ; then
+ qemu_rootfstype="rootfstype=$VMDISK_FILESYSTEM"
+ fi
+ qemu_rootflags=""
+ if test -n "$VMDISK_MOUNT_OPTIONS" ; then
+ qemu_rootflags="rootflags=${VMDISK_MOUNT_OPTIONS#-o }"
+ fi
+ if test -z "$VM_NETOPT" -a -z "$VM_NETDEVOPT"; then
+ kvm_options="$kvm_options -net none"
+ fi
+ if test -n "$VM_TELNET"; then
+ kvm_options="$kvm_options -netdev user,id=telnet,hostfwd=tcp:127.0.0.1:$VM_TELNET-:23 -device e1000,netdev=telnet"
+ fi
+ set -- $qemu_bin -nodefaults -no-reboot -nographic -vga none $kvm_options \
+ -kernel $vm_kernel \
+ -initrd $vm_initrd \
+ -append "root=$qemu_rootdev $qemu_rootfstype $qemu_rootflags 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
+ cleanup_and_exit 1 "could not kill build in $VM_IMAGE"
+ 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() {
+ :
+}
+
+vm_wipe_kvm() {
+ :
+}
diff --git a/build-vm-lxc b/build-vm-lxc
new file mode 100644
index 0000000..2a0453e
--- /dev/null
+++ b/build-vm-lxc
@@ -0,0 +1,197 @@
+#
+# 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
+#
+################################################################
+
+lxc_get_id() {
+ LXCID="obsbuild:${BUILD_ROOT##*/}"
+ if which lxc-config >/dev/null 2>&1; then
+ LXC_TYPE=standalone
+ elif which virsh >/dev/null 2>&1; then
+ LXC_TYPE=libvirt
+ else
+ LXC_TYPE=unknown
+ fi
+}
+
+vm_verify_options_lxc() {
+ VM_IMAGE=
+ VM_SWAP=
+}
+
+lxcsh() {
+ virsh -c lxc:/// "$@"
+}
+
+vm_startup_lxc() {
+ lxc_get_id
+ LXCCONF="$BUILD_ROOT/.build.lxc.conf"
+ rm -f "$LXCCONF"
+ vm_startup_lxc_$LXC_TYPE
+ BUILDSTATUS="$?"
+ test "$BUILDSTATUS" != 255 || BUILDSTATUS=3
+ cleanup_and_exit "$BUILDSTATUS"
+}
+
+vm_startup_lxc_standalone() {
+ LXCDIR="`lxc-config lxc.lxcpath`/$LXCID"
+ LXCROOTFS="$LXCDIR/rootfs"
+ LXCHOOK="$LXCDIR/pre-mount.hook"
+ cat $BUILD_DIR/lxc.conf > "$LXCCONF"
+ cat >> "$LXCCONF" <<-EOF
+ lxc.rootfs = $LXCROOTFS
+ lxc.hook.pre-mount = $LXCHOOK
+ EOF
+ # XXX: do this always instead of leaking the hosts' one?
+ echo "rootfs / rootfs rw 0 0" > $BUILD_ROOT/etc/mtab
+ lxc-destroy -n "$LXCID" >/dev/null 2>&1 || true
+ mkdir -p "$LXCROOTFS"
+ cat > "$LXCHOOK" <<-EOF
+ #!/bin/sh
+ mount --bind "$BUILD_ROOT" "$LXCROOTFS"
+ EOF
+ chmod a+x "$LXCHOOK"
+ case "$(lxc-create --version)" in
+ 1.0.8|1.1.*|2.*)
+ lxc-create -n "$LXCID" -f "$LXCCONF" -t none || cleanup_and_exit 1
+ lxc-start -n "$LXCID" -F "$vm_init_script"
+ ;;
+ 1.0.*)
+ lxc-create -n "$LXCID" -f "$LXCCONF" || cleanup_and_exit 1
+ lxc-start -n "$LXCID" "$vm_init_script"
+ ;;
+ esac
+}
+
+vm_startup_lxc_libvirt() {
+ local lxc_arch
+ # x86 i686 x86_64 amd64
+ case $BUILD_ARCH in
+ i586:*) lxc_arch=i686 ;;
+ x86_64:*) lxc_arch=x86_64 ;;
+ *) lxc_arch=${BUILD_ARCH/:*} ;;
+ esac
+
+ lxcsh destroy "$LXCID" >/dev/null 2>&1 || true
+ cat <<-EOF > "$LXCCONF"
+ <domain type='lxc'>
+ <name>$LXCID</name>
+ <memory unit='MiB'>${VM_MEMSIZE:-512}</memory>
+ <os>
+ <type arch='$lxc_arch'>exe</type>
+ <init>$vm_init_script</init>
+ </os>
+ <vcpu>1</vcpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/lib64/libvirt/libvirt_lxc</emulator>
+ <filesystem type='mount'>
+ <source dir='$BUILD_ROOT'/>
+ <target dir='/'/>
+ </filesystem>
+ <!-- SLES11 and OpenSUSE 13.1 fails if cannot change /sys owner -->
+ <!-- BTW, ro mode can be overlapped with mount -o remount,rw -->
+ <filesystem type='mount'>
+ <source dir='/sys'/>
+ <target dir='/sys'/>
+ </filesystem>
+ <console type='pty'/>
+ </devices>
+ <features>
+ <privnet/>
+ <!-- SLES11 fails if cannot create nodes (mknode) -->
+ <capabilities policy='default'>
+ <mknod state='on'/>
+ </capabilities>
+ </features>
+ </domain>
+ EOF
+ # XXX: do this always instead of leaking the hosts' one?
+ echo "rootfs / rootfs rw 0 0" > $BUILD_ROOT/etc/mtab
+ # could LOGFILE be used instead?
+ lxcsh create --console $LXCCONF | sed -ure 's/\x0d//g;:redo /.\x08/{s/.\x08//; b redo}'
+ exitcode="${PIPESTATUS[0]}"
+ if [ "$exitcode" -gt 0 ]; then
+ return $exitcode # libvirt errors
+ fi
+ if ! [ -r "$BUILD_ROOT/.build/_exitcode" ]; then
+ echo "'$BUILD_ROOT/.build/_exitcode' not found"
+ return 3
+ fi
+ exitcode=$(cat $BUILD_ROOT/.build/_exitcode)
+ return "$exitcode"
+}
+
+vm_kill_lxc() {
+ lxc_get_id
+ vm_kill_lxc_$LXC_TYPE
+}
+
+vm_kill_lxc_standalone() {
+ lxc-stop -n "$LXCID" || true
+}
+
+vm_kill_lxc_libvirt() {
+ lxcsh destroy "$LXCID" || true
+}
+
+vm_fixup_lxc() {
+ :
+}
+
+vm_attach_root_lxc() {
+ :
+}
+
+vm_attach_swap_lxc() {
+ :
+}
+
+vm_detach_root_lxc() {
+ :
+}
+
+vm_detach_swap_lxc() {
+ :
+}
+
+vm_wipe_lxc() {
+ :
+}
+
+vm_cleanup_lxc() {
+ if test $$ -ne 1 && test $$ -ne 2 ; then
+ lxc_get_id
+ vm_cleanup_lxc_$LXC_TYPE
+ fi
+}
+
+vm_cleanup_lxc_standalone() {
+ lxc-destroy -n "$LXCID"
+}
+
+vm_cleanup_lxc_libvirt() {
+ lxcsh destroy "$LXCID" >/dev/null 2>&1 || true
+}
+
diff --git a/build-vm-openstack b/build-vm-openstack
new file mode 100644
index 0000000..bd2328d
--- /dev/null
+++ b/build-vm-openstack
@@ -0,0 +1,143 @@
+#
+# 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
+ cleanup_and_exit 3 "ERROR: No openstack environment set. This vm-type works only inside of an openstack VM."
+ fi
+ if test -z "$OBS_OPENSTACK_KERNEL_IMAGE_ID" ; then
+ cleanup_and_exit 3 "ERROR: No image refering to kernel and ramdisk is defined in OBS_OPENSTACK_KERNEL_IMAGE_ID env."
+ fi
+ if test -z "$VM_VOLUME_NAME" ; then
+ cleanup_and_exit 3 "ERROR: No worker root VM volume name specified."
+ fi
+ if test -z "$VM_VOLUME_SWAP" ; then
+ cleanup_and_exit 3 "ERROR: No worker swap VM volume name specified."
+ fi
+ if test -z "$VM_SERVER" ; then
+ cleanup_and_exit 3 "ERROR: No VM server nod name specified (usually this instance)."
+ 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_wipe_openstack() {
+ :
+}
+
+vm_kill_openstack() {
+ if nova show "$VM_VOLUME_NAME" >/dev/null 2>&1 ; then
+ if ! nova delete "$VM_VOLUME_NAME" ; then
+ cleanup_and_exit 1 "could not kill openstack vm build $VM_VOLUME_NAME"
+ 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-pvm b/build-vm-pvm
new file mode 100644
index 0000000..d3a7d50
--- /dev/null
+++ b/build-vm-pvm
@@ -0,0 +1,193 @@
+#PowerVM build functions
+
+pvm_setup_bootloader(){
+ disk=$1
+ parted -s $disk mklabel msdos
+ parted -s $disk mkpart primary ext2 0 $bootloader_size
+ parted -s $disk set 1 boot on
+ parted -s $disk set 1 prep on
+ parted -s $disk mkpart primary ext3 8M 100%
+ bl_target=${disk}1
+}
+
+pvm_getdiskname(){
+ lv=$1
+ if [ -z "$SKIP" ];then
+ args=$(pvmctl scsi list -f ' ' -d VirtualDisk.udid ClientAdapter.loc_code --where VirtualDisk.name=$lv)
+ eval $args
+ host=$(ls-vscsi | grep $loc_code| awk -F " " '{print $1}')
+ udid=$(echo $udid | cut -c 3-)
+ devid="/dev/disk/by-id/scsi-SAIX_VDASD_$udid"
+ until test -L $devid;do
+ sleep 1;
+ echo "- - -" > /sys/class/scsi_host/$host/scan
+ done
+ dev=$(readlink -f $devid)
+ fi
+ case $lv in
+ *root) test -z "$SKIP" && pvm_setup_bootloader "$dev";
+ VM_IMAGE="${dev}2";;
+ *swap) VM_SWAP="${dev}";;
+ esac
+}
+
+pvm_execute(){
+ cmd=$@
+ pvmctl $cmd
+}
+
+pvm_is_created() {
+ dev=$1
+ $(pvmctl lv list -d LogicalVolume.name | grep -q $dev) && SKIP=1
+}
+
+pvm_createdev() {
+ name=$1
+ size=$2
+ target=$3
+ size_gb=`expr $size / 1024`
+ test -z $3 && target=$master_lpar
+ pvm_is_created $name
+ if [ -z "$SKIP" ];then
+ pvm_execute lv create --name $name --size $size_gb
+ target=$master_lpar
+ fi
+ pvm_execute scsi create --vg name=rootvg --type lv --lpar name=$target --stor-id $name
+ test -z "$SKIP" && pvm_getdiskname $name
+}
+
+pvm_lpar_is_running(){
+ state=$(pvmctl lpar list -d LogicalPartition.state --where LogicalPartition.name=$lpname |awk -F "=" '{print $2}')
+ CONSOLEPID=`pgrep -f "cat $hvcdev"`
+ if [ "$state" = "running" ];then
+ return 0
+ else
+ test -n $CONSOLEPID && kill -TERM $CONSOLEPID
+ return 1
+ fi
+}
+
+pvm_watch_build(){
+ while pvm_lpar_is_running $lpname;do
+ sleep 10
+ done
+}
+
+pvm_detachdev(){
+ lv=$1
+ lpar=$2
+ pvm_execute scsi delete --lpar name=$lpar --type lv --stor-id $lv
+}
+
+pvm_deletelv(){
+ viosvrcmd --id 1 -c "rmbdsp -bd $1"
+}
+
+pvm_nametoid(){
+ local id
+ name=$1
+ lparid=$(pvmctl lpar list -d LogicalPartition.id -i name=$name | awk -F "=" '{print $2}')
+}
+
+
+pvm_openconsole(){
+ id=$1
+ pvmutil -o create_vterm_dev --id $id
+ hvcsadmin -console $id
+ hvcdev=$(hvcsadmin -console $id|awk '{print $4}')
+}
+
+pvm_closeconsole(){
+ hvcdev=$(hvcsadmin -console $id|awk '{print $4}')
+ hvcsadmin -close $hvcdev
+ pvmutil -o delete_vterm_dev --id $1
+}
+
+vm_kill_pvm() {
+ pvm_execute lpar power-off --hard -i name="$VM_NAME"
+}
+
+vm_startup_pvm(){
+ cpus=$BUILD_JOBS
+ cores=`echo 0.05 \* $cpus| bc -l`
+ pvm_execute lpar create --name $lpname --mem $VM_MEMSIZE --proc-unit $cores --proc $cpus --proc-type shared --sharing-mode uncapped --type $lpartype
+ pvm_nametoid $lpname
+ vm_attach_root_pvm $lpname
+ vm_attach_swap_pvm $lpname
+ pvm_openconsole $lparid
+ pvm_execute lpar power-on -i name=$lpname
+ pvm_watch_build &
+ PID=$!
+ cat $hvcdev
+ vm_detach_root_pvm $lpname
+ vm_detach_swap_pvm $lpname
+}
+
+vm_verify_options_pvm(){
+ test -z "$VM_WORKER_NR" && VM_WORKER_NR=1
+ lpname="worker-$VM_WORKER_NR"
+ lpartype="AIX/Linux"
+ bootloader_size="8M"
+ rootlv="$lpname"-root
+ swaplv="$lpname"-swap
+ master_lpar=$(cat /proc/device-tree/ibm,partition-name)
+}
+
+vm_attach_root_pvm(){
+ target=$1
+ pvm_createdev $rootlv $VMDISK_ROOTSIZE $target
+}
+
+vm_attach_swap_pvm(){
+ pvm_createdev $swaplv $VMDISK_SWAPSIZE $target
+}
+
+vm_detach_swap_pvm(){
+ lpar=$1
+ test -z $lpar && lpar=$master_lpar
+ pvm_detachdev $swaplv $lpar
+}
+
+vm_detach_root_pvm(){
+ lpar=$1
+ test -z $lpar && lpar=$master_lpar
+ pvm_detachdev $rootlv $lpar
+}
+
+vm_cleanup_pvm(){
+ pvm_nametoid $lpname
+ pvm_closeconsole $lparid
+ vm_detach_root_pvm $lpname
+ vm_detach_root_pvm
+ vm_detach_swap_pvm $lpname
+ vm_detach_swap_pvm
+ pvm_execute lpar delete -i name=$lpname
+ pvm_deletelv $rootlv
+ pvm_deletelv $swaplv
+}
+
+vm_wipe_pvm(){
+ :
+}
+
+vm_fixup_pvm(){
+ VM_SWAPDEV=/dev/sdb
+ GRUBDIR=`mktemp -d /tmp/grubinstall.XXXX`
+ modules="ext2 part_msdos linux disk elf"
+ grubcfg="$GRUBDIR/grub.cfg"
+ grubimg="$GRUBDIR/grub.img"
+ cat <<'EOF' >> $GRUBDIR/grub.cfg
+insmod ext2
+insmod part_msdos
+insmod linux
+insmod disk
+insmod elf
+set root='ieee1275//vdevice/v-scsi@30000002/disk@8100000000000000,msdos2'
+linux /.build.kernel.kvm init=/.build/build console=hvc0 root=/dev/sda2 rw elevator=noop
+initrd /.build.initrd.kvm
+boot
+EOF
+ grub2-mkimage -O powerpc-ieee1275 -o $grubimg -c $grubcfg $modules
+ dd if=$grubimg of=$bl_target
+ rm -rf $GRUBDIR
+}
diff --git a/build-vm-qemu b/build-vm-qemu
new file mode 100644
index 0000000..3b3b780
--- /dev/null
+++ b/build-vm-qemu
@@ -0,0 +1,65 @@
+#
+# 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
+}
+
+vm_wipe_qemu() {
+ :
+}
+
diff --git a/build-vm-uml b/build-vm-uml
new file mode 100644
index 0000000..bb9c95e
--- /dev/null
+++ b/build-vm-uml
@@ -0,0 +1,70 @@
+#
+# 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
+ cleanup_and_exit 1 "could not kill build in $VM_IMAGE"
+ fi
+}
+
+vm_fixup_uml() {
+ :
+}
+
+vm_attach_root_uml() {
+ :
+}
+
+vm_attach_swap_uml() {
+ :
+}
+
+vm_detach_root_uml() {
+ :
+}
+
+vm_detach_swap_uml() {
+ :
+}
+
+vm_cleanup_uml() {
+ :
+}
+
+vm_wipe_uml() {
+ :
+}
+
diff --git a/build-vm-xen b/build-vm-xen
new file mode 100644
index 0000000..4aad687
--- /dev/null
+++ b/build-vm-xen
@@ -0,0 +1,147 @@
+#
+# 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"
+ XMCMD=xm
+ if test ! -x /usr/sbin/xm -a -x /usr/sbin/xl ; then
+ XMCMD=xl
+ VM_ROOTDEV=/dev/xvda
+ VM_SWAPDEV=/dev/xvdb
+ VM_CONSOLE=hvc0
+ else
+ VM_ROOTDEV=/dev/hda1
+ VM_SWAPDEV=/dev/hda2
+ VM_CONSOLE=ttyS0
+ fi
+}
+
+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,${VM_ROOTDEV#/dev/},w"
+ XMSWAP=
+ if test -n "$VM_SWAP" ; then
+ XMSWAP="file:$(readlink -f $VM_SWAP)"
+ XMSWAP=${XMSWAP/#file:\/dev/phy:/dev}
+ XMSWAP="disk=$XMSWAP,${VM_SWAPDEV#/dev/},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 = \"$VM_ROOTDEV ro\"" >> $XEN_CONF_FILE
+ echo "extra = \"init=/bin/bash console=$VM_CONSOLE 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=$VM_CONSOLE"
+ 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=$VM_CONSOLE"\"
+ 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
+ cleanup_and_exit 1 "could not kill xen build $XENID"
+ 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() {
+ :
+}
+
+vm_wipe_xen() {
+ :
+}
+
diff --git a/build-vm-zvm b/build-vm-zvm
new file mode 100644
index 0000000..72eee64
--- /dev/null
+++ b/build-vm-zvm
@@ -0,0 +1,367 @@
+#
+# 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"
+
+ZVM_CLEANUP=
+
+#######################################################################################
+
+# this once was in zvm_functions
+
+zvm_fatal() {
+ echo "$1"
+ test -n "$ZVM_CLEANUP" && exit 1
+ cleanup_and_exit 1
+}
+
+zvm_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)
+ zvm_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
+ zvm_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
+ cleanup_and_exit 3 "ERROR: No z/VM worker id specified"
+ fi
+ if test -z "$VM_WORKER_NR" ; then
+ cleanup_and_exit 3 "ERROR: No z/VM worker number specified"
+ 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
+ cleanup_and_exit 3 "ERROR: No z/VM kernel specified"
+ 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
+ cleanup_and_exit 3 "ERROR: No z/VM initrd specified"
+ 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
+ cleanup_and_exit 1 "could not kill zvm worker $VM_WORKER"
+ 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
+ cleanup_and_exit 3 "did not get a real device for VM_IMAGE: $VM_IMAGE"
+ 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
+ cleanup_and_exit 3 "did not get a real device for VM_SWAP: $VM_SWAP"
+ 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
+}
+
+vm_wipe_zvm() {
+ :
+}
diff --git a/build.1 b/build.1
new file mode 100644
index 0000000..8c721db
--- /dev/null
+++ b/build.1
@@ -0,0 +1,233 @@
+.de TQ \"follow a TP item with several TQ items to define several
+. \"entities with one shared description.
+.br
+.ns
+.TP \\$1
+..
+.TH build 1 "(c) 1997-2008 SuSE Linux AG Nuernberg, Germany"
+.SH NAME
+build \- build SuSE Linux RPMs in a chroot environment
+.SH SYNOPSIS
+.B build
+.RB [ --clean | --no-init]
+.RB [ --repo
+.IR dir_or_url ]
+.RB [ --repo ...]
+.RB [ --root
+.IR buildroot ]
+.RB [ recipefile ]
+.br
+.B build
+.B --help
+.br
+.B build
+.B --verify
+.SH DESCRIPTION
+\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 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 no recipe argument is provided, build will search the
+current directory for a file.
+.P
+The
+.B build
+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.
+.TP
+.B build.collax
+A shell script used to generate a Collax binary package.
+.P
+.SH OPTIONS
+.TP
+.B --clean
+Remove the build system and reinitialize it from scratch.
+.TP
+.B --no-init
+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 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 packages needed to create the
+build system. This option overrides the BUILD_RPMS environment
+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
+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
+list of packages to install from "# usedforbuild" lines or, if none
+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 --stage
+Pass a stage option to rpmbuild. The default is \fB-ba\fP.
+.TP
+.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.
+
+.SH VIRTUAL MACHINE SPECIFIC OPTIONS
+.TP
+.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.
+.TP
+.B "--vm-telnet" PORT
+Is forwarding PORT to a telnet session inside of the VM.
+Specify also needed extra packages via -x parameter, usually:
+.I --vm-telnet 1234 -x telnet-server -x net-tools
+ And connect from the host via:
+.I telnet localhost 1234
+ NOTE: The telnet server gets started after all packages got installed.
+
+
+.SH RECIPE FILE OPTIONS
+The
+.B build
+command interprets some special control comments in the recipe file:
+.TP
+.B # norootforbuild
+.TQ
+.B # needsrootforbuild
+.B build
+uses either user
+.I root
+or user
+.I abuild
+in the build system to do the build. For non-SUSE distros as well as
+since SUSE 10.2, the default build user is
+.I abuild.
+For 10.2 and before, the default build user is
+.I root.
+These two flags in the spec file allow to deviate from the defaults
+and force-set the build user to
+.I abuild
+and
+.I root
+.RI "(for " "#\ norootforbuild" " and " "#\ needsrootforbuild" " respectively."
+.TP
+.B # needsbinariesforbuild
+provide the binary rpms that have been used to set up the build root
+in
+.I /.build.binaries
+within the build root.
+.SH ENVIRONMENT
+.TP
+.B BUILD_ROOT
+The directory where build should install the chrooted build system.
+"/var/tmp/build-root" is used by default. See the \fB--root\fP option.
+.TP
+.B BUILD_RPMS
+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 should probably use the \fB--stage\fP
+option instead.
+
+.SH SEE ALSO
+.BR rpm (8), dpkg (8), pacman (8), kiwi (8)
+.TP
+.BR "Maximum RPM":
+.I http://www.rpm.org/max-rpm/
+.TP
+.BR "cross distribution packaging":
+.I http://en.opensuse.org/openSUSE:Build_Service_cross_distribution_howto
+.TP
+.BR "openSUSE packaging standards and guidelines":
+.I http://en.opensuse.org/Portal:Packaging
diff --git a/build.conf.example b/build.conf.example
new file mode 100644
index 0000000..6f85a6d
--- /dev/null
+++ b/build.conf.example
@@ -0,0 +1,27 @@
+# Example configuration for buildroot and parameter whitelisting.
+# Can be used to make multi-user environments more secure. Everything is
+# allowed by default if no whitelist is defined.
+#
+# List of whitelisted build roots.
+# %user will be replaced with $SUDO_USER (or $USER when running without sudo)
+#
+# ALLOW_BUILD_ROOT: /var/tmp/%user/build-root
+# ALLOW_BUILD_ROOT: /var/tmp/build-root
+
+# List of whitelisted parameters. Allowed parameters
+# must be listed in double dash format.
+#
+# ALLOW_PARAM: --arch
+# ALLOW_PARAM: --changelog
+# ALLOW_PARAM: --clean
+# ALLOW_PARAM: --dist
+# ALLOW_PARAM: --jobs
+# ALLOW_PARAM: --noinit
+# ALLOW_PARAM: --norootforbuild
+# ALLOW_PARAM: --root
+# ALLOW_PARAM: --rpmlist
+#
+# Specific parameter arguments can be whitelisted (other arguments
+# are not allowed in that case):
+#
+# ALLOW_PARAM: --jobs 1
diff --git a/changelog2spec b/changelog2spec
new file mode 100755
index 0000000..d95ab85
--- /dev/null
+++ b/changelog2spec
@@ -0,0 +1,247 @@
+#!/usr/bin/perl -w
+
+#
+# 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');
+}
+
+use Date::Parse;
+use Time::Zone;
+
+use strict;
+
+my @wday = qw{Sun Mon Tue Wed Thu Fri Sat};
+my @mon = qw{Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec};
+
+my $ok;
+my $zone;
+my $test;
+my $printtype;
+my $input = '';
+my $target = 'rpm';
+
+while (@ARGV) {
+ if ($ARGV[0] eq '--test') {
+ $test = 1;
+ shift @ARGV;
+ next;
+ }
+ if ($ARGV[0] eq '--type') {
+ $printtype = 1;
+ shift @ARGV;
+ next;
+ }
+ if (@ARGV > 1 && $ARGV[0] eq '--target') {
+ shift @ARGV;
+ $target = shift @ARGV;
+ next;
+ }
+ last;
+}
+
+if (@ARGV == 2 && $ARGV[0] eq '--file') {
+ die("bad --file arg\n") unless $ARGV[1] =~ /^(.*)\/([^\/]+)$/;
+ my ($dir, $file) = ($1, $2);
+ $file =~ s/\.(?:spec|dsc)$//;
+ 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) {
+ while ($file ne '') {
+ my @c = grep {/\Q$file\E/} @changes;
+ if (@c) {
+ @changes = @c;
+ last;
+ }
+ last unless $file =~ s/[-.][^-.]*$//;
+ }
+ }
+ @ARGV = ("$dir/$changes{$changes[0]}");
+}
+
+sub parse_suse {
+ $_ = $_[0];
+
+ my $dline;
+ die("bad changelog heading\n") unless /^(?:\* )?([A-Za-z]+\s+[A-Za-z]+\s+[0-9][^-]*?[0-9][0-9][0-9][0-9])(.*\@.*$)/;
+ my $dt = $1;
+ my $who = $2;
+ $dt = lc($dt);
+ $who =~ s/^\s+//;
+ $who =~ s/^-\s*//;
+ $dt =~ /([0-9][0-9][0-9][0-9])/;
+ $dline = $_;
+ my $year = $1;
+ if (!defined($zone) && $dt =~ /\s([a-z]{3,4})(dst)?\s[0-9]{4}/) {
+ my $dst = $2;
+ $zone = tz_offset($1);
+ $zone += 3600 if defined($zone) && $dst;
+ }
+ my $tdt = str2time($dt);
+ $dt =~ /([0-9]+)/;
+ my $day = $1;
+ if (!$tdt) {
+ if ($dt =~ /([a-z]{3})\s+([a-z]{3})/) {
+ $tdt = str2time("$1 $2 $day $year");
+ }
+ }
+ if (!$tdt) {
+ if ($dt =~ /([a-z]{3})/) {
+ $tdt = str2time("$1 $day $year");
+ }
+ }
+ if (!$tdt) {
+ $tdt = str2time("$year-1-1");
+ }
+ $tdt += 12 * 3600 unless $dt =~ /\d:\d/; # 12:00 if not specified
+ $tdt += ($zone || 0);
+ my $ok = 1;
+ my $change = '';
+ while(<>) {
+ chomp;
+ last if /^(?:\* )?([A-Za-z]+\s+[A-Za-z]+\s+[0-9][^-]*?[0-9][0-9][0-9][0-9])(.*\@.*$)/;
+ next if (/^--------------/);
+ next if (/^========================/);
+ s/\s+$//;
+ next if $_ eq '';
+ s/^\s*-/-/ if $ok == 1; # obsolete?
+ s/^\s*\*\s*/ * /;
+ if (!/^-/) {
+ s/^\s+-\s*/ - /;
+ s/^\s*/ / unless s/^ \s*/ /;
+ }
+ $change .= "$_\n";
+ $ok = 2;
+ }
+ return ($_, $tdt, $dline, $who, $change);
+}
+
+sub parse_debian {
+ $_ = $_[0];
+
+ die("bad line: $_\n") unless /^(\w[-+0-9a-z.]*) \(([^\(\) \t]+)\)((\s+[-+0-9a-z.]+)+)\;.*$/;
+ my $package = $1;
+ my $version = $2;
+ my $distribution = $3;
+ my $who;
+ my $date;
+ my $changes = "- version $version\n";
+ while(<>) {
+ chomp;
+ s/\s+$//;
+ next if $_ eq '';
+ if (/^ --/) {
+ die("bad maintainer line\n") unless /^ \-\- (.* <.*>) (.*)$/;
+ $who = $1;
+ $date = $2;
+ last;
+ }
+ die("bad change details line: $_\n") unless s/^ //;
+ s/^\*/-/;
+ s/\s*\(closes:\s*(?:bug)?\#?\s?\d+(?:,\s*(?:bug)?\#?\s?\d+)*\)//i;
+ s/\s+$//;
+ next if $_ eq '';
+ $changes .= "$_\n";
+ }
+ die("no maintainer line in last entry\n") unless defined $date;
+ if (!defined($zone) && ($date =~ /([-+])(\d\d)(\d\d)$/)) {
+ $zone = 60 * ($3 + 60 * $2);
+ $zone = -$zone if $1 eq '-';
+ }
+ my $tdt = str2time($date);
+ return ('', $tdt, $_, $who, $changes);
+}
+
+my $format;
+while (<>) {
+ chomp;
+ next if /^\s*$/;
+ next if (/^--------------/);
+ next if (/^========================/);
+ if (/^(?:\* )?([A-Za-z]+\s+[A-Za-z]+\s+[0-9][^-]*?[0-9][0-9][0-9][0-9])(.*\@.*$)/) {
+ # suse : * Fri Jun 07 2013 First Last <first.last@example.com>
+ # tizen: * Fri Jun 07 2013 First Last <first.last@example.com> tagname@commitid
+ $format = 'suse';
+ } elsif (/^(\w[-+0-9a-z.]*) \(([^\(\) \t]+)\)((\s+[-+0-9a-z.]+)+)\;.*$/) {
+ $format = 'debian';
+ } else {
+ die("unknown changelog format\n");
+ }
+ last;
+}
+exit(0) unless $format;
+
+if ($printtype) {
+ print "$format\n";
+ exit(0);
+}
+
+if ($target eq $format) {
+ print "$_\n";
+ while (<>) {
+ print $_;
+ }
+ exit(0);
+}
+
+die("don't know how to convert changelog to format '$target'\n") if $target ne 'rpm';
+
+my ($lastt, $t, $dline, $who, $changes);
+while(defined($_)) {
+ if (/^\s*$/) {
+ $_ = <>;
+ last unless $_;
+ chomp;
+ next;
+ }
+ if ($format eq 'suse') {
+ ($_, $t, $dline, $who, $changes) = parse_suse($_);
+ } elsif ($format eq 'debian') {
+ ($_, $t, $dline, $who, $changes) = parse_debian($_);
+ }
+ if (defined($lastt) && $lastt < $t) {
+ die("changes file not incremental: $dline\n") if $test;
+ warn("changes file not incremental: $dline\n");
+ }
+ $lastt = $t;
+ my @gm = gmtime($t);
+ # silly rpm can't hande dates < 1997, so we fold everything to
+ # Thu Jan 02 1997
+ @gm = (0, 0, 0, 2, 0, 97, 4) if $gm[5] < 97 || ($gm[5] == 97 && $gm[4] == 0 && $gm[3] <= 1);
+ printf("* %s %s %2d %4d %s\n", $wday[$gm[6]], $mon[$gm[4]], $gm[3], $gm[5] + 1900, $who);
+ $changes =~ s/%/%%/g;
+ $changes =~ s/^(\s*)%%(\S*)/$1\[%%$2\]/;
+ $changes =~ s/^(\s*)(\#\d*)/$1\[$2\]/mg;
+ $changes =~ s/^\*/ */mg;
+ print $changes;
+}
+exit(0);
diff --git a/common_functions b/common_functions
new file mode 100755
index 0000000..512d826
--- /dev/null
+++ b/common_functions
@@ -0,0 +1,140 @@
+#!/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
+#
+################################################################
+
+build_host_arch() {
+ : ${BUILD_HOST_ARCH:=`uname -m`}
+ # the linux kernel only knows armv7l, armv7hl is a userland definition
+ test armv7l == "$BUILD_HOST_ARCH" && BUILD_HOST_ARCH=armv7hl
+
+ BUILD_INITVM_ARCH="$BUILD_HOST_ARCH"
+ # avoid multiple initvm.* helpers for i586 and i686
+ test i686 != "$BUILD_INITVM_ARCH" || BUILD_INITVM_ARCH=i586
+}
+
+extend_build_arch() {
+ case $BUILD_ARCH in
+ aarch64) BUILD_ARCH="aarch64:aarch64_ilp32:armv8l" ;;
+ aarch64_ilp32) BUILD_ARCH="aarch64_ilp32:aarch64:armv8l" ;;
+ armv8l) BUILD_ARCH="armv8l" ;; # armv8l is aarch64 in 32bit mode. not a superset of armv7
+ armv7hl) BUILD_ARCH="armv7hl:armv7l:armv6hl:armv6l:armv5tel" ;;
+ armv7l) BUILD_ARCH="armv7l:armv6l:armv5tel" ;;
+ armv6hl) BUILD_ARCH="armv6hl:armv6l:armv5tel" ;;
+ armv6l) BUILD_ARCH="armv6l:armv5tel" ;;
+ armv5tel) BUILD_ARCH="armv5tel" ;;
+ m68k) BUILD_ARCH="m68k" ;;
+ mips64) BUILD_ARCH="mips64:mips" ;;
+ mips) BUILD_ARCH="mips" ;;
+ i686) BUILD_ARCH="i686:i586:i486:i386" ;;
+ i586) BUILD_ARCH="i586:i486:i386" ;;
+ i486) BUILD_ARCH="i486:i386" ;;
+ i386) BUILD_ARCH="i386" ;;
+ ia64) BUILD_ARCH="ia64" ;;
+ parisc64) BUILD_ARCH="hppa64:hppa" ;;
+ parisc) BUILD_ARCH="hppa" ;;
+ ppc) BUILD_ARCH="ppc" ;;
+ ppc64) BUILD_ARCH="ppc64:ppc" ;;
+ ppc64le) BUILD_ARCH="ppc64le" ;;
+ s390x) BUILD_ARCH="s390x:s390" ;;
+ s390) BUILD_ARCH="s390" ;;
+ sparc64v) BUILD_ARCH="sparc64v:sparc64:sparcv9v:sparcv9:sparcv8:sparc" ;;
+ sparc64) BUILD_ARCH="sparc64:sparcv9:sparcv8:sparc" ;;
+ sparcv9v) BUILD_ARCH="sparcv9v:sparcv9:sparcv8:sparc" ;;
+ sparcv9) BUILD_ARCH="sparcv9:sparcv8:sparc" ;;
+ sparcv8) BUILD_ARCH="sparcv8:sparc" ;;
+ 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 "
+ if test "$cpuflags" = "${cpuflags/ cx8 /}" -o "$cpuflags" = "${cpuflags/ cmov /}"; then
+ echo "Your cpu doesn't support i686 rpms. Exit."
+ cleanup_and_exit 1
+ fi
+ fi
+}
+
+check_exit() {
+ if test -e $BUILD_ROOT/exit; then
+ echo "exit ..."
+ cleanup_and_exit 1
+ fi
+}
+
+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 vm, we need to
+ # register it with a static program or shell script
+ 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
+}
+
+# usage:
+# progress_setup LIST
+# for I in $LIST; do
+# progress_step LIST
+# action $I
+# done
+
+# $1 name of a textual list
+progress_setup() {
+ eval "$1__ARRAY__=(\$$1)"
+ eval "$1__INDEX__=1"
+ eval "$1__LENGTH__=\${#$1__ARRAY__[@]}"
+}
+
+# $1 name of a textual list
+# $2 optional, printf format for 2 numeric arguments (current, total)
+progress_step() {
+ local IDX=$1__INDEX__
+ local LEN=$1__LENGTH__
+ printf "${2-[%d/%d] }" $(($IDX++)) ${!LEN}
+}
diff --git a/computeblocklists b/computeblocklists
new file mode 100755
index 0000000..1370f50
--- /dev/null
+++ b/computeblocklists
@@ -0,0 +1,187 @@
+#!/usr/bin/perl -w
+# compute the blocks used by a file
+# usage:
+# computeblocklists [options] <files...>
+# options:
+# --padstart NUM, --padend NUM, --verbose
+#
+# output:
+# <file base name> <size> <blocksize> <block numbers...>
+#
+# a block is either a number or a range (start-end)
+#
+
+################################################################
+#
+# 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, $opt_manifest, $opt_mani0);
+$opt_verbose = 0;
+
+while (@ARGV) {
+ if ($ARGV[0] eq '--padstart') {
+ shift @ARGV;
+ $opt_padstart = shift @ARGV;
+ next;
+ }
+ if ($ARGV[0] eq '--padend') {
+ shift @ARGV;
+ $opt_padend = shift @ARGV;
+ next;
+ }
+ if ($ARGV[0] eq '--verbose' || $ARGV[0] eq '-v') {
+ shift @ARGV;
+ $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;
+}
+
+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");
+ }
+}
+
+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/([\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)) {
+ 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;
+
+ print "f $n $st_size $bsize";
+ my $blocks = int(($st_size+$bsize-1)/$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: $!\n";
+ }
+ }
+ $block = unpack('I', $block);
+ 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 = $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";
+}
+
+print "\n"x$opt_padend if $opt_padend;
diff --git a/configs/arch.conf b/configs/arch.conf
new file mode 100644
index 0000000..3b37cd6
--- /dev/null
+++ b/configs/arch.conf
@@ -0,0 +1,25 @@
+Repotype: arch
+
+Preinstall: glibc bash perl sed grep coreutils pacman pacman-mirrorlist
+Preinstall: gawk gzip filesystem curl libidn acl gpgme libarchive
+Preinstall: openssl libssh2 zlib libassuan libgpg-error attr
+Preinstall: expat xz bzip2 readline lzo krb5 e2fsprogs keyutils
+Preinstall: ncurses lz4 libpsl icu gcc-libs
+
+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 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
+
diff --git a/configs/collax.conf b/configs/collax.conf
new file mode 100644
index 0000000..4323f31
--- /dev/null
+++ b/configs/collax.conf
@@ -0,0 +1,7 @@
+Type: collax
+Repotype: debian
+
+Preinstall: acl akutils attr base-files bash bzip2 coreutils diffutils file
+Preinstall: findutils gawk grep gzip heirloom less lbzip2 libc6 libcap libdb
+Preinstall: libgcc1 libgdbmg1 libpam0 libstdc++-v3 m4 ncurses5 patch perl5.8
+Preinstall: pigz sed shadow tar texinfo unzip vim zlib1g
diff --git a/configs/debian.conf b/configs/debian.conf
new file mode 100644
index 0000000..14451cc
--- /dev/null
+++ b/configs/debian.conf
@@ -0,0 +1,182 @@
+Repotype: debian
+
+Preinstall: bash perl-base sed grep coreutils debianutils
+Preinstall: libc6 libncurses5 libacl1 libattr1
+Preinstall: libreadline4 tar gawk dpkg
+Preinstall: sysv-rc gzip base-files
+
+Runscripts: base-files initscripts
+
+VMinstall: util-linux binutils libblkid1 libuuid1 libdevmapper1.02 mount
+
+Required: autoconf automake binutils bzip2 gcc gettext libc6
+Required: libtool libncurses5 perl zlib1g dpkg
+
+Support: build-essential fakeroot
+Support: bison cpio cracklib2 cvs login
+Support: file findutils flex diff
+Support: groff-base gzip info less
+Support: make man module-init-tools
+Support: net-tools util-linux
+Support: patch procps psmisc rcs strace
+Support: texinfo unzip vim ncurses-base sysvinit
+
+Keep: binutils cpp cracklib file findutils gawk gcc gcc-ada gcc-c++
+Keep: gzip libada libstdc++ libunwind
+Keep: libunwind-devel libzio make mktemp pam-devel pam-modules
+Keep: patch perl rcs timezone
+
+Prefer: xorg-x11-libs libpng fam mozilla mozilla-nss xorg-x11-Mesa
+Prefer: unixODBC libsoup glitz java-1_4_2-sun gnome-panel
+Prefer: desktop-data-SuSE gnome2-SuSE mono-nunit gecko-sharp2
+Prefer: apache2-prefork openmotif-libs ghostscript-mini gtk-sharp
+Prefer: glib-sharp libzypp-zmd-backend mDNSResponder
+
+Prefer: gnome-sharp2:art-sharp2 gnome-sharp:art-sharp
+Prefer: ifolder3:gnome-sharp2 ifolder3:gconf-sharp2
+Prefer: nautilus-ifolder3:gnome-sharp2
+Prefer: gconf-sharp2:glade-sharp2 gconf-sharp:glade-sharp
+Prefer: tomboy:gconf-sharp tomboy:gnome-sharp
+Prefer: zmd:libzypp-zmd-backend
+Prefer: yast2-packagemanager-devel:yast2-packagemanager
+
+Prefer: -libgcc-mainline -libstdc++-mainline -gcc-mainline-c++
+Prefer: -libgcj-mainline -viewperf -compat -compat-openssl097g
+Prefer: -zmd -OpenOffice_org -pam-laus -libgcc-tree-ssa -busybox-links
+Prefer: -crossover-office
+
+Conflict: ghostscript-library:ghostscript-mini
+
+Ignore: sysvinit:initscripts
+
+Ignore: aaa_base:aaa_skel,suse-release,logrotate,ash,mingetty,distribution-release
+Ignore: gettext-devel:libgcj,libstdc++-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: fontconfig:freetype2
+Ignore: fontconfig-devel:freetype2-devel
+Ignore: xorg-x11-libs:freetype2
+Ignore: xorg-x11:x11-tools,resmgr,xkeyboard-config,xorg-x11-Mesa,libusb,freetype2,libjpeg,libpng
+Ignore: apache2:logrotate
+Ignore: arts:alsa,audiofile,resmgr,libogg,libvorbis
+Ignore: kdelibs3:alsa,arts,pcre,OpenEXR,aspell,cups-libs,mDNSResponder,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,krb5,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:libidl
+Ignore: orbit2-devel:libidl,libidl-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,sgml-skel
+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: postfix:pcre
+Ignore: docbook_4:iso_ent,sgml-skel,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-SuSELinux,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:perl-XML-Writer,libxslt,pkgconfig
+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
+Ignore: yast2-x11:sax2-libsax-perl
+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: kernel-um:xorg-x11-libs
+Ignore: tetex:xorg-x11-libs,expat,fontconfig,freetype2,libjpeg,libpng,ghostscript-x11,xaw3d,gd,dialog,ed
+Ignore: yast2-country:yast2-trans-stats
+Ignore: susehelp:susehelp_lang,suse_help_viewer
+Ignore: mailx:smtp_daemon
+Ignore: cron:smtp_daemon
+Ignore: hotplug:syslog
+Ignore: pcmcia: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: OpenOffice_org-de:myspell-german-dictionary
+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: 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: 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
+
+Substitute: utempter
+
+%ifnarch s390 s390x ppc ia64
+Substitute: java2-devel-packages java-1_4_2-sun-devel
+%else
+ %ifnarch s390x
+Substitute: java2-devel-packages java-1_4_2-ibm-devel
+ %else
+Substitute: java2-devel-packages java-1_4_2-ibm-devel xorg-x11-libs-32bit
+ %endif
+%endif
+
+Substitute: yast2-devel-packages docbook-xsl-stylesheets doxygen libxslt perl-XML-Writer popt-devel sgml-skel update-desktop-files yast2 yast2-devtools yast2-packagemanager-devel yast2-perl-bindings yast2-testsuite
+
+Substitute: glibc-devel-32bit
+
+%ifarch %ix86
+Substitute: kernel-binary-packages kernel-default kernel-smp kernel-bigsmp kernel-debug kernel-um kernel-xen kernel-kdump
+%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 kernel-kdump
+%endif
+%ifarch ppc
+Substitute: kernel-binary-packages kernel-default kernel-kdump kernel-ppc64 kernel-iseries64
+%endif
+%ifarch ppc64
+Substitute: kernel-binary-packages kernel-ppc64 kernel-iseries64
+%endif
+%ifarch s390
+Substitute: kernel-binary-packages kernel-s390
+%enidf
+%ifarch s390x
+Substitute: kernel-binary-packages kernel-default
+%enidf
diff --git a/configs/sl10.0.conf b/configs/sl10.0.conf
new file mode 100644
index 0000000..e9de0b1
--- /dev/null
+++ b/configs/sl10.0.conf
@@ -0,0 +1,202 @@
+Repotype: rpm-md suse
+
+Preinstall: aaa_base acl attr bash bzip2 coreutils db devs diffutils
+Preinstall: filesystem fillup glibc grep insserv libacl libattr
+Preinstall: libgcc libnscd libselinux libxcrypt m4 ncurses pam
+Preinstall: permissions popt pwdutils readline rpm sed tar zlib
+
+Runscripts: aaa_base
+
+VMinstall: util-linux perl
+
+Required: autoconf automake binutils bzip2 db gcc gdbm gettext glibc
+Required: libtool ncurses perl rpm zlib
+
+Support: bind-libs bind-utils bison cpio cpp cracklib cvs cyrus-sasl
+Support: e2fsprogs file findutils flex gawk gdbm-devel gettext-devel
+Support: glibc-devel glibc-locale gpm groff gzip info klogd less
+Support: libcom_err libstdc++ libzio make man mktemp module-init-tools
+Support: ncurses-devel net-tools netcfg openldap2-client openssl
+Support: pam-modules patch procinfo procps psmisc rcs strace sysvinit
+Support: tcpd texinfo timezone unzip util-linux vim zlib-devel
+
+Keep: binutils cpp cracklib file findutils gawk gcc gcc-ada gcc-c++
+Keep: gdbm glibc-devel glibc-locale gzip libada libstdc++ libunwind
+Keep: libunwind-devel libzio make mktemp pam-devel pam-modules
+Keep: patch perl rcs timezone
+
+Prefer: xorg-x11-libs libpng fam mozilla mozilla-nss xorg-x11-Mesa
+Prefer: unixODBC libsoup glitz java-1_4_2-sun gnome-panel
+Prefer: desktop-data-SuSE gnome2-SuSE mono-nunit gecko-sharp2
+Prefer: apache2-prefork openmotif-libs ghostscript-mini gtk-sharp
+Prefer: glib-sharp libzypp-zmd-backend mDNSResponder
+
+Prefer: gnome-sharp2:art-sharp2 gnome-sharp:art-sharp
+Prefer: ifolder3:gnome-sharp2 ifolder3:gconf-sharp2
+Prefer: nautilus-ifolder3:gnome-sharp2
+Prefer: gconf-sharp2:glade-sharp2 gconf-sharp:glade-sharp
+Prefer: tomboy:gconf-sharp tomboy:gnome-sharp
+Prefer: zmd:libzypp-zmd-backend
+Prefer: yast2-packagemanager-devel:yast2-packagemanager
+
+Prefer: -libgcc-mainline -libstdc++-mainline -gcc-mainline-c++
+Prefer: -libgcj-mainline -viewperf -compat -compat-openssl097g
+Prefer: -zmd -OpenOffice_org -pam-laus -libgcc-tree-ssa -busybox-links
+Prefer: -crossover-office
+
+Conflict: ghostscript-library:ghostscript-mini
+
+Ignore: aaa_base:aaa_skel,suse-release,logrotate,ash,mingetty,distribution-release
+Ignore: gettext-devel:libgcj,libstdc++-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: fontconfig:freetype2
+Ignore: fontconfig-devel:freetype2-devel
+Ignore: xorg-x11-libs:freetype2
+Ignore: xorg-x11:x11-tools,resmgr,xkeyboard-config,xorg-x11-Mesa,libusb,freetype2,libjpeg,libpng
+Ignore: apache2:logrotate
+Ignore: arts:alsa,audiofile,resmgr,libogg,libvorbis
+Ignore: kdelibs3:alsa,arts,pcre,OpenEXR,aspell,cups-libs,mDNSResponder,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,krb5,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:libidl
+Ignore: orbit2-devel:libidl,libidl-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,sgml-skel
+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: postfix:pcre
+Ignore: docbook_4:iso_ent,sgml-skel,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-SuSELinux,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:perl-XML-Writer,libxslt,pkgconfig
+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
+Ignore: yast2-x11:sax2-libsax-perl
+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: kernel-um:xorg-x11-libs
+Ignore: tetex:xorg-x11-libs,expat,fontconfig,freetype2,libjpeg,libpng,ghostscript-x11,xaw3d,gd,dialog,ed
+Ignore: yast2-country:yast2-trans-stats
+Ignore: libgcc:glibc-32bit
+Ignore: libstdc++:glibc-32bit
+Ignore: susehelp:susehelp_lang,suse_help_viewer
+Ignore: mailx:smtp_daemon
+Ignore: cron:smtp_daemon
+Ignore: hotplug:syslog
+Ignore: pcmcia: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: OpenOffice_org-de:myspell-german-dictionary
+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: 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: 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
+
+%ifnarch s390 s390x ia64
+Substitute: java2-devel-packages java-1_4_2-sun-devel jpackage-utils update-alternatives
+%else
+ %ifarch ppc
+Substitute: java2-devel-packages IBMJava2-JRE IBMJava2-SDK jpackage-utils update-alternatives
+ %endif
+ %ifarch s390 ia64
+Substitute: java2-devel-packages java-1_4_2-ibm-devel jpackage-utils update-alternatives
+ %endif
+ %ifarch s390x
+Substitute: java2-devel-packages java-1_4_2-ibm-devel xorg-x11-libs-32bit jpackage-utils update-alternatives
+ %endif
+%endif
+
+Substitute: yast2-devel-packages docbook-xsl-stylesheets doxygen libxslt perl-XML-Writer popt-devel sgml-skel update-desktop-files yast2 yast2-devtools yast2-packagemanager-devel yast2-perl-bindings yast2-testsuite
+
+%ifarch x86_64 ppc64 s390x sparc64
+Substitute: glibc-devel-32bit glibc-devel-32bit glibc-32bit
+%else
+ %ifarch ppc
+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-um 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-iseries64
+%endif
+%ifarch ppc64
+Substitute: kernel-binary-packages kernel-ppc64 kernel-iseries64
+%endif
+%ifarch s390
+Substitute: kernel-binary-packages kernel-s390
+%endif
+%ifarch s390x
+Substitute: kernel-binary-packages kernel-default
+%endif
+
+Macros:
+%insserv_prereq insserv sed
+%fillup_prereq fillup coreutils
+%suseconfig_fonts_prereq perl aaa_base
+%install_info_prereq info
+%suse_version 1000
+%sles_version 0
+%ul_version 0
+%do_profiling 1
+%_vendor suse
diff --git a/configs/sl10.1.conf b/configs/sl10.1.conf
new file mode 100644
index 0000000..654ea3e
--- /dev/null
+++ b/configs/sl10.1.conf
@@ -0,0 +1,196 @@
+Preinstall: aaa_base acl attr bash bzip2 coreutils db diffutils
+Preinstall: filesystem fillup glibc grep insserv libacl libattr
+Preinstall: libgcc libnscd libxcrypt m4 ncurses pam
+Preinstall: permissions popt pwdutils readline rpm sed tar zlib
+
+Runscripts: aaa_base
+
+VMinstall: util-linux perl
+
+Required: autoconf automake binutils bzip2 db gcc gdbm gettext glibc
+Required: libtool ncurses perl rpm zlib
+
+Support: bind-libs bind-utils bison cpio cpp cracklib cvs cyrus-sasl
+Support: e2fsprogs file findutils flex gawk gdbm-devel gettext-devel
+Support: glibc-devel glibc-locale gpm groff gzip info klogd less
+Support: libcom_err libstdc++ libzio make man mktemp module-init-tools
+Support: ncurses-devel net-tools netcfg openldap2-client openssl
+Support: pam-modules patch procinfo procps psmisc rcs strace sysvinit
+Support: tcpd texinfo timezone unzip util-linux vim zlib-devel
+
+Keep: binutils cpp cracklib file findutils gawk gcc gcc-ada gcc-c++
+Keep: gdbm glibc-devel glibc-locale gzip libada libstdc++ libunwind
+Keep: libunwind-devel libzio make mktemp pam-devel pam-modules
+Keep: patch perl rcs timezone
+
+Prefer: xorg-x11-libs libpng fam mozilla mozilla-nss xorg-x11-Mesa
+Prefer: unixODBC libsoup glitz java-1_4_2-sun gnome-panel
+Prefer: desktop-data-SuSE gnome2-SuSE mono-nunit gecko-sharp2
+Prefer: apache2-prefork openmotif-libs ghostscript-mini gtk-sharp
+Prefer: glib-sharp libzypp-zmd-backend mDNSResponder
+
+Prefer: gnome-sharp2:art-sharp2 gnome-sharp:art-sharp
+Prefer: ifolder3:gnome-sharp2 ifolder3:gconf-sharp2
+Prefer: nautilus-ifolder3:gnome-sharp2
+Prefer: gconf-sharp2:glade-sharp2 gconf-sharp:glade-sharp
+Prefer: tomboy:gconf-sharp tomboy:gnome-sharp
+Prefer: zmd:libzypp-zmd-backend
+Prefer: yast2-packagemanager-devel:yast2-packagemanager
+
+Prefer: -libgcc-mainline -libstdc++-mainline -gcc-mainline-c++
+Prefer: -libgcj-mainline -viewperf -compat -compat-openssl097g
+Prefer: -zmd -OpenOffice_org -pam-laus -libgcc-tree-ssa -busybox-links
+Prefer: -crossover-office
+
+Conflict: ghostscript-library:ghostscript-mini
+
+Ignore: aaa_base:aaa_skel,suse-release,logrotate,ash,mingetty,distribution-release
+Ignore: gettext-devel:libgcj,libstdc++-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: fontconfig:freetype2
+Ignore: fontconfig-devel:freetype2-devel
+Ignore: xorg-x11-libs:freetype2
+Ignore: xorg-x11:x11-tools,resmgr,xkeyboard-config,xorg-x11-Mesa,libusb,freetype2,libjpeg,libpng
+Ignore: apache2:logrotate
+Ignore: arts:alsa,audiofile,resmgr,libogg,libvorbis
+Ignore: kdelibs3:alsa,arts,pcre,OpenEXR,aspell,cups-libs,mDNSResponder,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,krb5,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:libidl
+Ignore: orbit2-devel:libidl,libidl-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,sgml-skel
+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: postfix:pcre
+Ignore: docbook_4:iso_ent,sgml-skel,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-SuSELinux,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:perl-XML-Writer,libxslt,pkgconfig
+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
+Ignore: yast2-x11:sax2-libsax-perl
+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: kernel-um:xorg-x11-libs
+Ignore: tetex:xorg-x11-libs,expat,fontconfig,freetype2,libjpeg,libpng,ghostscript-x11,xaw3d,gd,dialog,ed
+Ignore: yast2-country:yast2-trans-stats
+Ignore: libgcc:glibc-32bit
+Ignore: libstdc++:glibc-32bit
+Ignore: susehelp:susehelp_lang,suse_help_viewer
+Ignore: mailx:smtp_daemon
+Ignore: cron:smtp_daemon
+Ignore: hotplug:syslog
+Ignore: pcmcia: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: OpenOffice_org-de:myspell-german-dictionary
+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: 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: 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
+
+%ifnarch s390 s390x ppc ia64
+Substitute: java2-devel-packages java-1_4_2-sun-devel update-alternatives
+%else
+ %ifnarch s390x
+Substitute: java2-devel-packages java-1_4_2-ibm-devel update-alternatives
+ %else
+Substitute: java2-devel-packages java-1_4_2-ibm-devel xorg-x11-libs-32bit update-alternatives
+ %endif
+%endif
+
+Substitute: yast2-devel-packages docbook-xsl-stylesheets doxygen libxslt perl-XML-Writer popt-devel sgml-skel update-desktop-files yast2 yast2-devtools yast2-packagemanager-devel yast2-perl-bindings yast2-testsuite
+
+%ifarch x86_64 ppc64 s390x sparc64
+Substitute: glibc-devel-32bit glibc-devel-32bit glibc-32bit
+%else
+ %ifarch ppc
+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-um kernel-xen kernel-kdump
+%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 kernel-kdump
+%endif
+%ifarch ppc
+Substitute: kernel-binary-packages kernel-default kernel-kdump kernel-ppc64 kernel-iseries64
+%endif
+%ifarch ppc64
+Substitute: kernel-binary-packages kernel-ppc64 kernel-iseries64
+%endif
+%ifarch s390
+Substitute: kernel-binary-packages kernel-s390
+%endif
+%ifarch s390x
+Substitute: kernel-binary-packages kernel-default
+%endif
+
+Macros:
+%insserv_prereq insserv sed
+%fillup_prereq fillup coreutils
+%suseconfig_fonts_prereq perl aaa_base
+%install_info_prereq info
+%suse_version 1010
+%sles_version 0
+%ul_version 0
+%do_profiling 1
+%_vendor suse
diff --git a/configs/sl10.2.conf b/configs/sl10.2.conf
new file mode 100644
index 0000000..fdf5ec6
--- /dev/null
+++ b/configs/sl10.2.conf
@@ -0,0 +1,208 @@
+Preinstall: aaa_base acl attr bash bzip2 coreutils db diffutils
+Preinstall: filesystem fillup glibc grep insserv libacl libattr
+Preinstall: libgcc41 libnscd libxcrypt m4 ncurses pam
+Preinstall: permissions popt pwdutils readline rpm sed tar zlib
+
+Runscripts: aaa_base
+
+VMinstall: util-linux perl libvolume_id
+
+Required: autoconf automake binutils bzip2 db gcc gcc41
+Required: gdbm gettext glibc libtool ncurses perl rpm zlib
+
+Support: audit-libs bind-libs
+Support: bind-utils bison cpio cpp cpp41 cracklib cvs cyrus-sasl
+Support: e2fsprogs file findutils flex gawk gdbm-devel gettext-devel
+Support: glibc-devel glibc-locale gpm groff gzip info klogd less
+Support: libcom_err libltdl libmudflap41 libstdc++41 libzio
+Support: linux-kernel-headers make man mktemp module-init-tools
+Support: ncurses-devel net-tools netcfg openldap2-client openssl
+Support: pam-modules patch procinfo procps psmisc rcs strace sysvinit
+Support: tcpd texinfo timezone unzip util-linux vim zlib-devel
+
+Keep: binutils cpp cracklib file findutils gawk gcc gcc-ada gcc-c++
+Keep: gdbm glibc-devel glibc-locale gzip libada libstdc++ libunwind
+Keep: libunwind-devel libzio make mktemp pam-devel pam-modules
+Keep: patch perl rcs timezone
+
+Prefer: xorg-x11-libs libpng fam mozilla mozilla-nss xorg-x11-Mesa
+Prefer: unixODBC libsoup glitz java-1_4_2-sun java-1_4_2-sun-jdbc gnome-panel
+Prefer: desktop-data-SuSE gnome2-SuSE mono-nunit gecko-sharp2
+Prefer: apache2-prefork Mesa openmotif-libs ghostscript-mini ghostscript-library gtk-sharp
+Prefer: glib-sharp libzypp-zmd-backend mDNSResponder-lib
+
+Prefer: gnome-sharp2:art-sharp2 gnome-sharp:art-sharp
+Prefer: ifolder3:gnome-sharp2 ifolder3:gconf-sharp2
+Prefer: nautilus-ifolder3:gnome-sharp2
+Prefer: gconf-sharp2:glade-sharp2 gconf-sharp:glade-sharp
+Prefer: tomboy:gconf-sharp tomboy:gnome-sharp
+Prefer: zmd:libzypp-zmd-backend
+Prefer: yast2-packagemanager-devel:yast2-packagemanager
+Prefer: glitz-32bit:Mesa-32bit libcdio-mini faac-min
+
+Prefer: -libgcc-mainline -libstdc++-mainline -gcc-mainline-c++
+Prefer: -libgcj-mainline -viewperf -compat -compat-openssl097g
+Prefer: -zmd -OpenOffice_org -pam-laus -libgcc-tree-ssa -busybox-links
+Prefer: -crossover-office -java-1_5_0-ibm -java-1_5_0-ibm-jdbc
+Prefer: -java-1_4_2-gcj-compat -NX
+
+Conflict: ghostscript-library:ghostscript-mini
+
+Ignore: aaa_base:aaa_skel,suse-release,logrotate,ash,mingetty,distribution-release
+Ignore: gettext-devel:libgcj,libstdc++-devel,libgcj41,libstdc++41-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: fontconfig:freetype2
+Ignore: fontconfig-devel:freetype2-devel
+Ignore: xorg-x11-libs:freetype2
+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,pcre,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:libidl
+Ignore: orbit2-devel:libidl,libidl-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: postfix:pcre
+Ignore: docbook_4:iso_ent,sgml-skel,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-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
+Ignore: yast2-x11:sax2-libsax-perl
+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: kernel-um:xorg-x11-libs
+Ignore: tetex:xorg-x11-libs,expat,fontconfig,freetype2,libjpeg,ghostscript-x11,xaw3d,gd,dialog,ed
+Ignore: yast2-country:yast2-trans-stats
+Ignore: tpb:tpctl-kmp
+Ignore: tpctl:tpctl-kmp
+Ignore: mkinitrd:pciutils
+Ignore: libgcc:glibc-32bit
+Ignore: libstdc++:glibc-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: 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: OpenOffice_org-de:myspell-german-dictionary
+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: 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: 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
+
+%ifnarch s390 s390x ppc ia64
+Substitute: java2-devel-packages java-1_4_2-sun-devel update-alternatives
+%else
+ %ifnarch s390 ppc
+Substitute: java2-devel-packages java-1_4_2-ibm-devel update-alternatives
+ %endif
+ %ifarch s390x
+Substitute: java2-devel-packages java-1_4_2-ibm-devel xorg-x11-libs-32bit update-alternatives
+ %endif
+ %ifarch ia64
+Substitute: java2-devel-packages java-1_5_0-bea-devel update-alternatives
+ %endif
+%endif
+
+%ifarch x86_64 ppc64 s390x sparc64
+Substitute: glibc-devel-32bit glibc-devel-32bit glibc-32bit
+%else
+ %ifarch ppc
+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-um kernel-xen kernel-kdump
+%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 kernel-kdump
+%endif
+%ifarch ppc
+Substitute: kernel-binary-packages kernel-default kernel-kdump kernel-ppc64 kernel-iseries64
+%endif
+%ifarch ppc64
+Substitute: kernel-binary-packages kernel-ppc64 kernel-iseries64
+%endif
+%ifarch s390
+Substitute: kernel-binary-packages kernel-s390
+%endif
+%ifarch s390x
+Substitute: kernel-binary-packages kernel-default
+%endif
+
+Macros:
+%insserv_prereq insserv sed
+%fillup_prereq fillup coreutils
+%suseconfig_fonts_prereq perl aaa_base
+%install_info_prereq info
+%kernel_module_package_buildreq kernel-source kernel-syms
+%suse_version 1020
+%sles_version 0
+%ul_version 0
+%do_profiling 1
+%_vendor suse
diff --git a/configs/sl10.3.conf b/configs/sl10.3.conf
new file mode 100644
index 0000000..03b71c0
--- /dev/null
+++ b/configs/sl10.3.conf
@@ -0,0 +1,316 @@
+%define gcc_version 42
+
+Preinstall: aaa_base acl attr bash coreutils diffutils
+Preinstall: filesystem fillup glibc grep insserv libacl libattr
+Preinstall: libbz2-1 libgcc%{gcc_version} libxcrypt m4 ncurses pam
+Preinstall: permissions popt libreadline5 rpm sed tar zlib
+
+Runscripts: aaa_base
+
+VMinstall: util-linux perl-base libdb-4_5 libvolume_id
+
+Required: autoconf automake binutils bzip2 gcc gcc%{gcc_version}
+Required: gettext glibc libtool ncurses perl rpm zlib
+
+Support: audit-libs cpio cpp cpp%{gcc_version} cracklib cvs
+Support: file findutils gawk gdbm gettext-devel
+Support: glibc-devel glibc-locale groff gzip info less
+Support: libbz2-devel libdb-4_5
+Support: libltdl-3 libmudflap%{gcc_version} libstdc++%{gcc_version}
+Support: libvolume_id libxcrypt libzio
+Support: linux-kernel-headers make man mktemp netcfg
+Support: net-tools pam-modules patch perl-base sysvinit
+Support: texinfo timezone util-linux
+%ifarch ia64
+Support: libunwind libunwind-devel
+%endif
+
+Keep: audit-libs binutils bzip2 cpp cracklib file findutils gawk gcc gcc-ada gcc-c++
+Keep: gdbm glibc-devel glibc-locale gzip libada
+Keep: libunwind libunwind-devel libzio make mktemp pam-devel pam-modules
+Keep: patch perl-base perl rcs timezone
+Keep: cpp%{gcc_version} gcc%{gcc_version} gcc%{gcc_version}-ada libstdc++%{gcc_version}
+Keep: cpp41 gcc41 gcc41-ada libstdc++41
+
+Prefer: libreadline5
+Prefer: libdb_java-4_5 libltdl-3 libicu
+Prefer: cracklib-dict-small postfix
+Prefer: jta libpng fam mozilla mozilla-nss
+Prefer: unixODBC libsoup glitz
+Prefer: java-1_5_0-sun java-1_5_0-sun-jdbc java-1_5_0-sun-devel java-1_5_0-bea-devel
+Prefer: gnome-panel desktop-data-SuSE gnome2-SuSE
+Prefer: mono-nunit gecko-sharp2
+Prefer: apache2-prefork Mesa openmotif-libs ghostscript-mini ghostscript-library
+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
+Prefer: libstdc++%{gcc_version} libgcc%{gcc_version} libmudflap%{gcc_version}
+
+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: saxon:java-1_4_2-cacao gjdoc:antlr
+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: banshee:banshee-engine-gst helix-banshee:helix-banshee-engine-gst
+Prefer: java-1_5_0-ibm:java-1_5_0-ibm-alsa
+Prefer: java-1_5_0-ibm-devel
+Prefer: microcode_ctl:kernel-default
+Prefer: notification-daemon
+Prefer: pkg-config gtk-doc wlan-kmp-default lua-libs
+Prefer: gnu-jaf gnu-javamail avahi-compat-mDNSResponder yast2-control-center-qt
+Prefer: vim-normal myspell-american wine
+Prefer: eclipse-platform eclipse-scripts
+Prefer: yast2-theme-openSUSE
+
+Prefer: -bundle-lang-kde-de -bundle-lang-kde-en -bundle-lang-kde-es
+Prefer: -bundle-lang-kde-fr -bundle-lang-kde-pt
+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
+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-common-es -bundle-lang-common-de -bundle-lang-common-fr
+Prefer: -bundle-lang-common-pt -bundle-lang-common-en
+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 -OpenOffice_org -pam-laus -libgcc-tree-ssa -busybox-links
+%if ! 0%{?opensuse_bs}
+Prefer: -crossover-office -java-1_5_0-ibm -java-1_5_0-ibm-jdbc
+Prefer: -java-1_4_2-gcj-compat -java-1_4_2-gcj-compat-devel
+%endif
+Prefer: -java-1_4_2-cacao -java-1_4_2-cacao-devel -java-1_4_2-ibm -java-1_4_2-ibm-devel
+Prefer: -NX -xaw3dd -db43
+Prefer: -xerces-j2-xml-resolver -xerces-j2-xml-apis
+Prefer: -vmware-player
+Prefer: -libgcc41 -libgcc41-32bit -libgcc41-64bit
+Prefer: -libffi41
+Prefer: -libgcc43 -libgcc43-32bit -libgcc43-64bit
+Prefer: -libffi43 -libgomp43
+Prefer: -libnetpbm -libcdio7-mini -libiso9660-5-mini
+Prefer: -libcdio-mini -faac-mini
+
+Conflict: ghostscript-library:ghostscript-mini
+
+Ignore: cracklib:cracklib-dict
+Ignore: aaa_base:aaa_skel,suse-release,logrotate,ash,mingetty,distribution-release,udev
+Ignore: gettext-devel:libgcj,libstdc++-devel,libgcj41,libstdc++41-devel,libgcj42,libstdc++42-devel
+Ignore: libgcj43,libstdc++43-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: fontconfig:freetype2
+Ignore: fontconfig-devel:freetype2-devel
+Ignore: xorg-x11-libs:freetype2
+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,pcre,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:libidl
+Ignore: orbit2-devel:libidl,libidl-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: postfix:pcre
+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-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
+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: libgcc:glibc-32bit
+Ignore: libgcc41:glibc-32bit
+Ignore: libgcc42:glibc-32bit
+Ignore: libgcc43:glibc-32bit
+Ignore: libstdc++:glibc-32bit
+Ignore: libstdc41++:glibc-32bit
+Ignore: libstdc42++:glibc-32bit
+Ignore: libstdc43++:glibc-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: 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: OpenOffice_org-de:myspell-german-dictionary
+Ignore: OpenOffice_org:OpenOffice_org-i18n
+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: 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: 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: 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: icecream:gcc-c++
+Ignore: no
+Ignore: package
+Ignore: provides
+
+%if 0%{?opensuse_bs}
+Substitute: java2-devel-packages gcc-java java-1_4_2-gcj-compat-devel
+%else
+ %ifnarch s390 s390x ppc ppc64 ia64
+Substitute: java2-devel-packages java-1_5_0-sun-devel unzip update-alternatives
+ %else
+ %ifarch s390 s390x ppc ppc64
+Substitute: java2-devel-packages java-1_5_0-ibm-devel unzip update-alternatives
+ %endif
+ %ifarch ia64
+Substitute: java2-devel-packages java-1_5_0-bea-devel unzip update-alternatives
+ %endif
+ %endif
+%endif
+
+%ifarch x86_64 ppc64 s390x sparc64
+Substitute: glibc-devel-32bit glibc-devel-32bit glibc-32bit
+%else
+ %ifarch ppc
+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 kernel-xenpae
+%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-kdump kernel-ppc64 kernel-iseries64
+%endif
+%ifarch ppc64
+Substitute: kernel-binary-packages kernel-ppc64 kernel-iseries64
+%endif
+%ifarch s390
+Substitute: kernel-binary-packages kernel-s390
+%endif
+%ifarch s390x
+Substitute: kernel-binary-packages kernel-default
+%endif
+
+%ifarch ppc64
+Substitute: mono-devel mono-devel mono-biarchcompat
+Substitute: mono-basic mono-basic mono-biarchcompat
+Substitute: mono-tools mono-tools mono-biarchcompat
+%endif
+
+
+Optflags: i586 -march=i586 -mtune=i686 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector
+Optflags: i686 -march=i686 -mtune=i686 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector
+Optflags: x86_64 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector
+Optflags: ppc -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector
+Optflags: ppc64 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector
+
+Optflags: * -O2
+
+%define suse_version 1030
+
+Macros:
+%insserv_prereq insserv sed
+%fillup_prereq fillup coreutils
+%suseconfig_fonts_prereq perl aaa_base
+%install_info_prereq info
+%kernel_module_package_buildreq kernel-source kernel-syms
+%suse_version 1030
+%sles_version 0
+%ul_version 0
+%do_profiling 1
+%_vendor suse
diff --git a/configs/sl11.0.conf b/configs/sl11.0.conf
new file mode 100644
index 0000000..3b1a048
--- /dev/null
+++ b/configs/sl11.0.conf
@@ -0,0 +1,377 @@
+%define gcc_version 43
+
+Preinstall: aaa_base acl attr bash coreutils diffutils
+Preinstall: filesystem fillup glibc grep insserv libacl libattr
+Preinstall: libbz2-1 libgcc%{gcc_version} libxcrypt m4 libncurses5 pam
+Preinstall: permissions popt libreadline5 rpm sed tar zlib
+
+Runscripts: aaa_base
+
+VMinstall: util-linux perl-base libdb-4_5 libvolume_id
+
+Required: autoconf automake binutils bzip2 gcc gcc%{gcc_version}
+Required: gettext-runtime glibc libtool perl rpm zlib libmpfr1 gmp
+Required: libncurses5
+
+Support: audit-libs cpio cpp cpp%{gcc_version} cracklib cvs
+Support: file findutils gawk gdbm gettext-tools
+Support: glibc-devel glibc-locale groff gzip info less
+Support: libbz2-devel libdb-4_5
+Support: libltdl-3 libmudflap%{gcc_version} libstdc++%{gcc_version}
+Support: libvolume_id libxcrypt libzio
+Support: linux-kernel-headers make man netcfg
+Support: net-tools pam-modules patch perl-base sysvinit
+Support: texinfo timezone util-linux login
+Support: terminfo-base libgomp43 libuuid1 psmisc
+%ifarch ia64
+Support: libunwind libunwind-devel
+%endif
+
+Keep: audit-libs binutils bzip2 cpp cracklib file findutils gawk gcc gcc-ada gcc-c++
+Keep: gdbm glibc-devel glibc-locale gzip libada
+Keep: libunwind libunwind-devel libzio make pam-devel pam-modules
+Keep: patch perl-base perl rcs timezone gmp libmpfr1
+Keep: cpp43 gcc43 gcc43-ada libstdc++43
+Keep: cpp42 gcc42 gcc42-ada libstdc++42
+Keep: cpp41 gcc41 gcc41-ada libstdc++41
+Keep: java-1_6_0-openjdk java-1_6_0-openjdk-devel
+
+Prefer: libreadline5
+Prefer: libdb_java-4_5 libltdl-3 libicu
+Prefer: cracklib-dict-small postfix
+Prefer: jta libpng fam mozilla mozilla-nss
+Prefer: unixODBC libsoup glitz
+Prefer: java-1_5_0-sun java-1_5_0-sun-jdbc java-1_5_0-sun-devel java-1_5_0-bea java-1_5_0-bea-devel
+Prefer: java-1_7_0-icedtea
+%ifarch ppc ppc64
+Prefer: java-1_5_0-ibm
+%endif
+%ifarch s390 s390x
+Prefer: java-1_6_0-ibm
+%endif
+Prefer: gnome-panel desktop-data-openSUSE gnome2-SuSE
+Prefer: mono-nunit gecko-sharp2
+Prefer: apache2-prefork Mesa openmotif-libs ghostscript-mini ghostscript-library
+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
+Prefer: libstdc++%{gcc_version} libgcc%{gcc_version}
+Prefer: libstdc++%{gcc_version}-32bit libstdc++%{gcc_version}-64bit
+Prefer: libstroke
+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: saxon:java-1_4_2-cacao gjdoc:antlr
+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: banshee:banshee-engine-gst helix-banshee:helix-banshee-engine-gst
+Prefer: java-1_5_0-ibm:java-1_5_0-ibm-alsa
+Prefer: java-1_5_0-ibm-devel
+Prefer: microcode_ctl:kernel-default
+Prefer: notification-daemon
+Prefer: pkg-config gtk-doc wlan-kmp-default lua-libs
+Prefer: gnu-jaf gnu-javamail avahi-compat-mDNSResponder yast2-control-center-qt
+Prefer: vim-normal myspell-american wine
+Prefer: eclipse-platform eclipse-scripts
+Prefer: yast2-theme-openSUSE
+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: xfce4-desktop:xfce4-desktop-branding-openSUSE
+Prefer: bundle-lang-gnome:gnome-session-branding-openSUSE
+Prefer: texlive-xmltex texlive-tools texlive-jadetex
+Prefer: mono-web:mono-data-sqlite
+Prefer: gnome-games:gnuchess
+Prefer: OpenOffice_org:OpenOffice_org-branding-upstream
+Prefer: gimp:gimp-branding-upstream
+Prefer: libesd-devel:esound
+Prefer: glib2:glib2-branding-upstream
+Prefer: kdebase4-workspace:kdebase4-workspace-branding-upstream
+Prefer: mysql-connector-java:java-1_5_0-gcj-compat
+Prefer: -geronimo-jta-1_0_1B-api
+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: -bundle-lang-kde-de -bundle-lang-kde-en -bundle-lang-kde-es
+Prefer: -bundle-lang-kde-fr -bundle-lang-kde-pt
+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
+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-common-es -bundle-lang-common-de -bundle-lang-common-fr
+Prefer: -bundle-lang-common-pt -bundle-lang-common-en
+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 -OpenOffice_org -pam-laus -libgcc-tree-ssa -busybox-links
+%if ! 0%{?opensuse_bs}
+Prefer: -crossover-office
+%ifnarch s390 s390x
+Prefer: -java-1_6_0-ibm
+%endif
+%ifnarch ppc
+Prefer: -java-1_5_0-ibm -java-1_5_0-ibm-jdbc
+%endif
+Prefer: -java-1_4_2-gcj-compat -java-1_4_2-gcj-compat-devel
+%endif
+Prefer: -java-1_4_2-cacao -java-1_4_2-cacao-devel -java-1_4_2-ibm -java-1_4_2-ibm-devel
+Prefer: -NX -xaw3dd -db43
+Prefer: -xerces-j2-xml-resolver -xerces-j2-xml-apis
+Prefer: -vmware-player
+Prefer: libgcc%{gcc_version} libgcc%{gcc_version}-32bit libgcc%{gcc_version}-64bit
+Prefer: libgcc%{gcc_version}-x86 libffi%{gcc_version} libgcj_bc%{gcc_version}
+Prefer: libgomp%{gcc_version} libgomp%{gcc_version}-32bit libgomp%{gcc_version}-64bit
+Prefer: libmudflap%{gcc_version} libmudflap%{gcc_version}-32bit libmudflap%{gcc_version}-64bit
+Prefer: libobjc%{gcc_version}
+Prefer: -libnetpbm -libcdio7-mini -libiso9660-5-mini
+Prefer: -libcdio-mini -faac-mini
+Prefer: -seamonkey
+Prefer: -libdb-4_4-devel
+
+Conflict: ghostscript-library:ghostscript-mini
+Conflict: ghostscript-fonts-std:ghostscript-mini
+
+Ignore: cracklib:cracklib-dict
+Ignore: aaa_base:aaa_skel,suse-release,logrotate,ash,mingetty,distribution-release,udev
+Ignore: gettext-tools:libgcj,libstdc++-devel,libgcj41,libstdc++41-devel,libgcj42,libstdc++42-devel
+Ignore: libgcj43,libstdc++43-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: fontconfig:freetype2
+Ignore: fontconfig-devel:freetype2-devel
+Ignore: xorg-x11-libs:freetype2
+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,pcre,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:libidl
+Ignore: orbit2-devel:libidl,libidl-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: postfix:pcre
+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-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
+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: libgcc:glibc-32bit
+Ignore: libgcc41:glibc-32bit
+Ignore: libgcc42:glibc-32bit
+Ignore: libgcc43:glibc-32bit
+Ignore: libstdc++:glibc-32bit
+Ignore: libstdc41++:glibc-32bit
+Ignore: libstdc42++:glibc-32bit
+Ignore: libstdc43++: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: 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: OpenOffice_org-de:myspell-german-dictionary
+Ignore: OpenOffice_org:OpenOffice_org-i18n
+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: 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: 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: gpg2:gpg2-lang
+Ignore: util-linux:util-linux-lang
+
+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: yast2-casa-ats:CASA_auth_token_svc
+
+%if 0%{?opensuse_bs}
+Substitute: java2-devel-packages gcc-java java-1_4_2-gcj-compat-devel
+%else
+ %ifnarch s390 s390x ppc ppc64 ia64
+Substitute: java2-devel-packages java-1_5_0-sun-devel unzip update-alternatives
+ %else
+ %ifarch s390 s390x ppc ppc64
+Substitute: java2-devel-packages java-1_5_0-ibm-devel unzip update-alternatives
+ %endif
+ %ifarch ia64
+Substitute: java2-devel-packages java-1_5_0-bea-devel unzip update-alternatives
+ %endif
+ %endif
+%endif
+
+%ifarch x86_64 ppc64 s390x sparc64
+Substitute: glibc-devel-32bit glibc-devel-32bit glibc-32bit
+%else
+ %ifarch ppc
+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-kdump kernel-ppc64 kernel-iseries64
+%endif
+%ifarch ppc64
+Substitute: kernel-binary-packages kernel-ppc64 kernel-iseries64
+%endif
+%ifarch s390
+Substitute: kernel-binary-packages kernel-s390
+%endif
+%ifarch s390x
+Substitute: kernel-binary-packages kernel-default
+%endif
+
+%ifarch ppc64
+Substitute: mono-devel mono-devel mono-biarchcompat
+Substitute: mono-basic mono-basic mono-biarchcompat
+Substitute: mono-tools mono-tools mono-biarchcompat
+%endif
+
+
+Optflags: i586 -march=i586 -mtune=i686 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector
+Optflags: i686 -march=i686 -mtune=i686 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector
+Optflags: x86_64 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector
+Optflags: ppc -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector
+Optflags: ppc64 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector
+
+Optflags: * -O2
+
+%define suse_version 1100
+
+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 kernel-source kernel-syms
+%kernel_module_package_buildreqs kernel-source kernel-syms
+%suse_version 1100
+%sles_version 0
+%ul_version 0
+%do_profiling 1
+%_vendor suse
diff --git a/configs/sl11.1.conf b/configs/sl11.1.conf
new file mode 100644
index 0000000..ef63de8
--- /dev/null
+++ b/configs/sl11.1.conf
@@ -0,0 +1,407 @@
+%define gcc_version 43
+
+Preinstall: aaa_base acl attr bash coreutils diffutils
+Preinstall: filesystem fillup glibc grep insserv libacl libattr
+Preinstall: libbz2-1 libgcc%{gcc_version} libxcrypt m4 libncurses5 pam
+Preinstall: permissions popt libreadline5 rpm sed tar zlib libselinux1
+
+Runscripts: aaa_base
+
+Order: libopenssl0_9_8:openssl-certs
+
+VMinstall: util-linux perl-base libdb-4_5 libvolume_id1 libsepol1
+
+Required: autoconf automake binutils bzip2 gcc gcc%{gcc_version}
+Required: gettext-runtime glibc libtool perl rpm zlib libmpfr1 gmp
+Required: libncurses5
+
+Support: audit-libs cpio cpp cpp%{gcc_version} cracklib cvs
+Support: file findutils gawk gdbm gettext-tools
+Support: glibc-devel glibc-locale groff gzip info less
+Support: libbz2-devel libdb-4_5
+Support: libstdc++%{gcc_version}
+Support: libvolume_id1 libxcrypt libzio
+Support: linux-kernel-headers make man netcfg
+Support: net-tools pam-modules patch perl-base sysvinit
+Support: texinfo timezone util-linux login
+Support: libgomp43 libuuid1 psmisc
+Support: terminfo-base
+
+Support: build brp-check-suse post-build-checks rpmlint-Factory
+Keep: brp-check-suse
+
+%ifarch ia64
+Support: libunwind libunwind-devel
+%endif
+
+Keep: audit-libs binutils bzip2 cpio cpp cracklib file findutils gawk gcc gcc-ada gcc-c++
+Keep: gdbm glibc-devel glibc-locale gzip libada
+Keep: libunwind libunwind-devel libzio make pam-devel pam-modules
+Keep: patch perl-base perl rcs timezone gmp libmpfr1
+Keep: cpp43 gcc43 gcc43-ada libstdc++43
+Keep: cpp42 gcc42 gcc42-ada libstdc++42
+Keep: cpp41 gcc41 gcc41-ada libstdc++41
+Keep: java-1_6_0-openjdk java-1_6_0-openjdk-devel
+Keep: libvolume_id libvolume_id1
+
+Prefer: -openSUSE-build-key
+Prefer: libreadline5
+Prefer: libdb_java-4_5 libicu
+Prefer: cracklib-dict-small postfix
+Prefer: jta libpng fam mozilla mozilla-nss
+Prefer: unixODBC libsoup glitz
+Prefer: gnome-panel desktop-data-openSUSE gnome2-SuSE
+Prefer: mono-nunit gecko-sharp2
+Prefer: apache2-prefork Mesa openmotif-libs ghostscript-mini ghostscript-library
+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
+Prefer: libstdc++%{gcc_version} libgcc%{gcc_version}
+Prefer: libstdc++%{gcc_version}-32bit libstdc++%{gcc_version}-64bit
+Prefer: libstroke
+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: banshee:banshee-engine-gst helix-banshee:helix-banshee-engine-gst
+Prefer: java-1_5_0-ibm:java-1_5_0-ibm-alsa
+Prefer: microcode_ctl:kernel-default
+Prefer: notification-daemon
+Prefer: pkg-config gtk-doc wlan-kmp-default lua-libs
+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: 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: xfce4-desktop:xfce4-desktop-branding-openSUSE
+Prefer: bundle-lang-gnome:gnome-session-branding-openSUSE
+Prefer: texlive-xmltex texlive-tools texlive-jadetex
+Prefer: mono-web:mono-data-sqlite
+Prefer: gnome-games:gnuchess
+Prefer: OpenOffice_org:OpenOffice_org-branding-upstream
+Prefer: gimp:gimp-branding-upstream
+Prefer: libesd-devel:esound
+Prefer: libesd0:esound-daemon
+Prefer: glib2:glib2-branding-upstream
+Prefer: kdebase4-workspace:kdebase4-workspace-branding-upstream
+Prefer: mysql-connector-java:java-1_5_0-gcj-compat
+Prefer: -geronimo-jta-1_0_1B-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-xulrunner190-32bit
+Prefer: boo tog-pegasus
+Prefer: kde4-kupdateapplet:kde4-kupdateapplet-zypp
+Prefer: ant:xerces-j2
+Prefer: -bundle-lang-kde-de -bundle-lang-kde-en -bundle-lang-kde-es
+Prefer: -bundle-lang-kde-fr -bundle-lang-kde-pt
+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
+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-common-es -bundle-lang-common-de -bundle-lang-common-fr
+Prefer: -bundle-lang-common-pt -bundle-lang-common-en
+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 -OpenOffice_org -pam-laus -libgcc-tree-ssa -busybox-links
+
+Prefer: -NX -xaw3dd -db43
+Prefer: -xerces-j2-xml-resolver -xerces-j2-xml-apis
+Prefer: -vmware-player
+Prefer: libgcc%{gcc_version} libgcc%{gcc_version}-32bit libgcc%{gcc_version}-64bit
+Prefer: libgcc%{gcc_version}-x86 libffi%{gcc_version} libgcj_bc%{gcc_version}
+Prefer: libgomp%{gcc_version} libgomp%{gcc_version}-32bit libgomp%{gcc_version}-64bit
+Prefer: libmudflap%{gcc_version} libmudflap%{gcc_version}-32bit libmudflap%{gcc_version}-64bit
+Prefer: libobjc%{gcc_version}
+Prefer: -libnetpbm -libcdio7-mini -libiso9660-5-mini
+Prefer: -libcdio-mini -faac-mini
+Prefer: -seamonkey
+Prefer: -libdb-4_4-devel -libevoldap-2_4-2
+Conflict: ghostscript-library:ghostscript-mini
+Conflict: ghostscript-fonts-std:ghostscript-mini
+Prefer: -libopenal0-soft -openal-soft -lsb-buildenv
+Prefer: gnu-crypto libusb-compat-devel
+Prefer: libusb-0_1-4
+Prefer: CASA_auth_token_svc:xerces-j2
+Prefer: OpenOffice_org:xerces-j2
+Prefer: k3b:libdvdread4
+Prefer: glibc-devel
+Prefer: NetworkManager:dhcp-client
+Prefer: kdebase3-SuSE:kdebase3
+
+Ignore: openSUSE-release:openSUSE-release-ftp,openSUSE-release-dvd5,openSUSE-release-dvd9,openSUSE-release-livecdkde,openSUSE-release-livecdgnome
+Ignore: cracklib:cracklib-dict
+Ignore: aaa_base:aaa_skel,suse-release,logrotate,ash,mingetty,distribution-release,udev
+Ignore: gettext-tools:libgcj,libstdc++-devel,libgcj41,libstdc++41-devel,libgcj42,libstdc++42-devel
+Ignore: libgcj43,libstdc++43-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: fontconfig:freetype2
+Ignore: fontconfig-devel:freetype2-devel
+Ignore: xorg-x11-libs:freetype2
+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,pcre,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:libidl
+Ignore: orbit2-devel:libidl,libidl-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: postfix:pcre
+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-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
+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: libgcc:glibc-32bit
+Ignore: libgcc41:glibc-32bit
+Ignore: libgcc42:glibc-32bit
+Ignore: libgcc43:glibc-32bit
+Ignore: libstdc++:glibc-32bit
+Ignore: libstdc41++:glibc-32bit
+Ignore: libstdc42++:glibc-32bit
+Ignore: libstdc43++: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: 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: OpenOffice_org-de:myspell-german-dictionary
+Ignore: OpenOffice_org:OpenOffice_org-i18n
+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: 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: 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: 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: phonon:phonon-backend
+Ignore: openwbem-devel
+Ignore: MozillaFirefox:MozillaFirefox-branding
+Ignore: yast2:yast2-branding
+Ignore: yast2-theme-SLE:yast2-branding
+Ignore: yast2-registration:yast2-registration-branding
+
+%ifarch s390 s390x
+Ignore: yast2-all-packages:yast2-x11
+%endif
+
+%ifnarch ia64 s390 s390x ppc ppc64
+Prefer: java-1_6_0-openjdk java-1_6_0-openjdk-devel
+%endif
+%ifarch s390 s390x ppc ppc64
+Prefer: java-1_6_0-ibm java-1_6_0-ibm-devel
+%endif
+%ifarch ia64
+Prefer: java-1_6_0-bea java-1_6_0-bea-devel
+%endif
+
+Prefer: -java-1_5_0-gcj-compat-devel
+%ifnarch ia64 s390 s390x ppc ppc64
+Substitute: java2-devel-packages java-1_6_0-openjdk-devel
+%else
+ %ifarch s390 s390x ppc ppc64
+Substitute: java2-devel-packages java-1_6_0-ibm-devel unzip update-alternatives
+ %endif
+ %ifarch ia64
+Substitute: java2-devel-packages java-1_6_0-bea-devel unzip update-alternatives
+ %endif
+%endif
+
+%ifarch x86_64 ppc64 s390x sparc64
+Substitute: glibc-devel-32bit glibc-devel-32bit glibc-32bit
+%else
+ %ifarch ppc
+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
+
+%ifarch ppc64
+Substitute: mono-devel mono-devel mono-biarchcompat
+Substitute: mono-basic mono-basic mono-biarchcompat
+Substitute: mono-tools mono-tools mono-biarchcompat
+Substitute: mono-data-sqlite mono-data-sqlite libsqlite3-0-32bit
+%endif
+
+
+Optflags: i586 -march=i586 -mtune=i686 -fmessage-length=0
+Optflags: i686 -march=i686 -mtune=i686 -fmessage-length=0
+Optflags: x86_64 -fmessage-length=0
+Optflags: ppc -fmessage-length=0
+Optflags: ppc64 -fmessage-length=0
+Optflags: ia64 -fmessage-length=0
+Optflags: s390 -fmessage-length=0
+Optflags: s390x -fmessage-length=0
+
+Optflags: * -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables
+
+%define suse_version 1110
+
+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 module-init-tools kernel-syms
+%kernel_module_package_buildreqs module-init-tools kernel-syms
+
+%suse_version 1110
+%sles_version 0
+%ul_version 0
+%do_profiling 1
+%_vendor suse
diff --git a/configs/sl11.2.conf b/configs/sl11.2.conf
new file mode 100644
index 0000000..daa1bcb
--- /dev/null
+++ b/configs/sl11.2.conf
@@ -0,0 +1,452 @@
+%define gcc_version 44
+
+Substitute: kiwi-packagemanager:zypper zypper
+Substitute: kiwi-packagemanager:smart smart
+Substitute: kiwi-packagemanager:instsource kiwi-instsource cdrkit-cdrtools-compat syslinux
+Substitute: kiwi-filesystem:ext3 e2fsprogs procps psmisc reiserfs
+Substitute: kiwi-filesystem:squashfs squashfs
+Substitute: kiwi-boot:isoboot kiwi-desc-isoboot module-init-tools elfutils squashfs aufs aufs-kmp-default
+Substitute: kiwi-boot:netboot kiwi-desc-netboot kiwi-desc-xenboot ncurses-utils curl dhcpcd iputils nbd net-tools netcfg nfs-client parted grub mdadm
+Substitute: kiwi-boot:oemboot kiwi-desc-oemboot
+Substitute: kiwi-boot:usbboot kiwi-desc-usbboot
+Substitute: kiwi-boot:vmxboot kiwi-desc-vmxboot
+Substitute: kiwi-boot:xenboot kiwi-desc-xenboot
+
+Substitute: build:debug vim strace gdb
+
+Preinstall: aaa_base acl attr bash coreutils diffutils
+Preinstall: filesystem fillup glibc grep insserv libacl libattr
+Preinstall: libbz2-1 libgcc%{gcc_version} libxcrypt m4 libncurses5 pam
+Preinstall: permissions libreadline6 rpm sed tar zlib libselinux1
+Preinstall: liblzma0 libcap2 libpcre0
+Preinstall: libpopt0 libelf1 liblua5_1
+
+Runscripts: aaa_base
+
+Order: libopenssl0_9_8:openssl-certs
+
+VMinstall: util-linux perl-base libdb-4_5 libsepol1 libblkid1 libuuid1
+
+Required: autoconf automake binutils bzip2 gcc gcc%{gcc_version}
+Required: gettext-runtime glibc libtool perl rpm zlib libmpfr1
+Required: libncurses5 libgmp3 libgmpxx4
+
+Support: audit-libs cpio cpp cpp%{gcc_version} cracklib cvs
+Support: file findutils gawk gdbm gettext-tools
+Support: glibc-devel glibc-locale groff gzip info less
+Support: libbz2-devel libdb-4_5
+Support: libstdc++%{gcc_version}
+Support: libxcrypt libzio
+Support: linux-kernel-headers make man netcfg
+Support: net-tools pam-modules patch perl-base sysvinit
+Support: texinfo timezone util-linux login
+Support: libgomp%{gcc_version} libuuid1 psmisc
+Support: terminfo-base
+
+# build tools packages
+Support: build brp-check-suse post-build-checks
+Support: rpmlint-Factory
+Keep: brp-check-suse
+# remove build-compare support to disable "same result" package dropping
+Support: build-compare
+
+%ifarch ia64
+Support: libunwind libunwind-devel
+%endif
+
+Keep: audit-libs binutils bzip2 cpio cpp cracklib file findutils gawk gcc gcc-ada gcc-c++
+Keep: gdbm glibc-devel glibc-locale gzip libada libpcre0
+Keep: libunwind libunwind-devel libzio make pam-devel pam-modules
+Keep: patch perl-base perl rcs timezone libmpfr1 libcap2
+Keep: gmp libgmp3 libgmpxx4
+Keep: cpp44 gcc44 gcc44-ada libstdc++44
+Keep: cpp43 gcc43 gcc43-ada libstdc++43
+Keep: cpp42 gcc42 gcc42-ada libstdc++42
+Keep: cpp41 gcc41 gcc41-ada libstdc++41
+Keep: java-1_6_0-openjdk java-1_6_0-openjdk-devel libcloog0 libppl7 libppl_c2
+Keep: libpopt0
+
+Prefer: -suse-build-key
+Prefer: krb5 krb5-devel
+Prefer: krb5-mini-devel:krb5-mini
+Prefer: libreadline5
+Prefer: libdb_java-4_5 libicu
+Prefer: cracklib-dict-small postfix
+Prefer: jta libpng fam mozilla mozilla-nss
+Prefer: unixODBC libsoup glitz
+Prefer: gnome-panel desktop-data-openSUSE gnome2-SuSE
+Prefer: mono-nunit gecko-sharp2
+Prefer: apache2-prefork Mesa openmotif-libs ghostscript-mini ghostscript-library
+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 preload-kmp-default
+Prefer: libstdc++%{gcc_version} libgcc%{gcc_version}
+Prefer: libstdc++%{gcc_version}-32bit libstdc++%{gcc_version}-64bit
+Prefer: libstroke
+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: banshee:banshee-engine-gst helix-banshee:helix-banshee-engine-gst
+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
+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: 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: bundle-lang-gnome:gnome-session-branding-openSUSE
+Prefer: texlive-xmltex texlive-tools texlive-jadetex
+Prefer: mono-web:mono-data-sqlite
+Prefer: gnome-games:gnuchess
+Prefer: OpenOffice_org:OpenOffice_org-branding-upstream
+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: kdebase4-workspace:kdebase4-workspace-branding-upstream
+Prefer: mysql-connector-java:java-1_5_0-gcj-compat
+Prefer: -geronimo-jta-1_0_1B-api -geronimo-jms-1_1-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: ant:xerces-j2
+Prefer: dhcp-client:dhcp
+Prefer: beagle-index:preload-kmp-default
+Prefer: -bundle-lang-kde-de -bundle-lang-kde-en -bundle-lang-kde-es
+Prefer: -bundle-lang-kde-fr -bundle-lang-kde-pt
+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
+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
+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
+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 -OpenOffice_org -pam-laus -libgcc-tree-ssa -busybox-links
+
+Prefer: -NX -xaw3dd -db43
+Prefer: -xerces-j2-xml-resolver -xerces-j2-xml-apis
+Prefer: -vmware-player
+Prefer: libgcc%{gcc_version} libgcc%{gcc_version}-32bit libgcc%{gcc_version}-64bit
+Prefer: libgcc%{gcc_version}-x86 libffi%{gcc_version} libgcj_bc%{gcc_version}
+Prefer: libgomp%{gcc_version} libgomp%{gcc_version}-32bit libgomp%{gcc_version}-64bit
+Prefer: libmudflap%{gcc_version} libmudflap%{gcc_version}-32bit libmudflap%{gcc_version}-64bit
+Prefer: libobjc%{gcc_version} libgfortran%{gcc_version}
+Prefer: -libnetpbm -libcdio7-mini -libiso9660-5-mini -libiso9660-7-mini -libcdio10-mini
+Prefer: -libcdio-mini -faac-mini
+Prefer: -seamonkey
+Prefer: -libdb-4_4-devel -libevoldap-2_4-2
+Conflict: ghostscript-library:ghostscript-mini
+Conflict: ghostscript-fonts-std:ghostscript-mini
+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: OpenOffice_org:xerces-j2
+Prefer: k3b:libdvdread4
+Prefer: glibc-devel
+Prefer: -libpcap -java-1_7_0-icedtea-devel -libiniparser -loudmouth -libkonq4 -libnetcdf-4
+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
+
+#Temporary hack to solve #442202
+Ignore: yast2-all-packages:yast2-boot-server,yast2-heartbeat,yast2-issleconfig,yast2-linux-user-mgmt,yast2-trans-am,yast2-trans-be,yast2-trans-he,yast2-trans-ms,yast2-trans-my,yast2-trans-tk
+
+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,mingetty,distribution-release,udev
+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: 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: fontconfig:freetype2
+Ignore: fontconfig-devel:freetype2-devel
+Ignore: xorg-x11-libs:freetype2
+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: postfix:pcre,libpcre0
+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-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
+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: libgcc:glibc-32bit
+Ignore: libgcc41:glibc-32bit
+Ignore: libgcc42:glibc-32bit
+Ignore: libgcc43:glibc-32bit
+Ignore: libgcc44:glibc-32bit
+Ignore: libstdc++:glibc-32bit
+Ignore: libstdc41++:glibc-32bit
+Ignore: libstdc42++:glibc-32bit
+Ignore: libstdc43++:glibc-32bit
+Ignore: libstdc44++: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: 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: OpenOffice_org-de:myspell-german-dictionary
+Ignore: OpenOffice_org:OpenOffice_org-i18n
+Ignore: OpenOffice_org:OpenOffice_org-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: 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: 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: 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: phonon:phonon-backend
+Ignore: openwbem-devel
+Ignore: MozillaFirefox:MozillaFirefox-branding
+Ignore: yast2: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: pulseaudio:kernel
+
+%ifarch s390 s390x
+Ignore: yast2-all-packages:yast2-x11
+%endif
+
+%ifnarch ia64 s390 s390x
+Prefer: java-1_6_0-openjdk java-1_6_0-openjdk-devel
+%endif
+%ifarch s390 s390x
+Prefer: java-1_6_0-ibm java-1_6_0-ibm-devel
+%endif
+%ifarch ia64
+Prefer: java-1_6_0-bea java-1_6_0-bea-devel
+%endif
+
+Prefer: -java-1_5_0-gcj-compat-devel
+%ifarch %ix86 x86_64
+Prefer: -java-1_5_0-ibm-devel
+%endif
+Substitute: java2-devel-packages java-1_6_0-openjdk-devel
+
+%ifarch x86_64 ppc64 s390x sparc64
+Substitute: glibc-devel-32bit glibc-devel-32bit glibc-32bit
+%else
+ %ifarch ppc
+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
+
+# until the builds of the packages are fixed...
+Substitute: yast2-theme-SLED
+Substitute: yast2-theme-SLE
+
+Optflags: i586 -fomit-frame-pointer -fmessage-length=0
+Optflags: i686 -march=i686 -mtune=generic -fomit-frame-pointer -fmessage-length=0
+Optflags: x86_64 -fmessage-length=0
+Optflags: ppc -fmessage-length=0
+Optflags: ppc64 -fmessage-length=0
+Optflags: ia64 -fmessage-length=0
+Optflags: s390 -fmessage-length=0
+Optflags: s390x -fmessage-length=0
+
+Optflags: * -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables
+
+%define suse_version 1120
+
+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 module-init-tools kernel-syms
+%kernel_module_package_buildreqs module-init-tools kernel-syms
+
+%suse_version 1120
+%sles_version 0
+%ul_version 0
+%do_profiling 1
+%_vendor suse
diff --git a/configs/sl11.3.conf b/configs/sl11.3.conf
new file mode 100644
index 0000000..4155315
--- /dev/null
+++ b/configs/sl11.3.conf
@@ -0,0 +1,489 @@
+%define gcc_version 45
+
+Substitute: kiwi-packagemanager:zypper zypper
+Substitute: kiwi-packagemanager:smart smart
+Substitute: kiwi-packagemanager:instsource kiwi-instsource cdrkit-cdrtools-compat syslinux kiwi-instsource-plugins-openSUSE-11-3
+Substitute: kiwi-filesystem:ext3 e2fsprogs procps psmisc reiserfs
+Substitute: kiwi-filesystem:squashfs squashfs
+Substitute: kiwi-boot:isoboot kiwi-desc-isoboot module-init-tools elfutils squashfs clicfs e2fsprogs fribidi gfxboot-devel gawk gfxboot gfxboot-devel grub hdparm hwinfo iproute2 kiwi-tools lvm2 make memtest86+ netcfg psmisc
+Substitute: kiwi-boot:netboot kiwi-desc-netboot kiwi-desc-xenboot ncurses-utils curl dhcpcd iputils nbd net-tools netcfg nfs-client parted grub mdadm
+Substitute: kiwi-boot:oemboot kiwi-desc-oemboot
+Substitute: kiwi-boot:usbboot kiwi-desc-usbboot
+Substitute: kiwi-boot:vmxboot kiwi-desc-vmxboot
+Substitute: kiwi-boot:xenboot kiwi-desc-xenboot
+
+Substitute: build:debug vim strace gdb
+
+Preinstall: aaa_base acl attr bash coreutils diffutils
+Preinstall: filesystem fillup glibc grep insserv libacl libattr
+Preinstall: libbz2-1 libgcc%{gcc_version} libxcrypt m4 libncurses5 pam
+Preinstall: permissions libreadline6 rpm sed tar zlib libselinux1
+Preinstall: liblzma0 libcap2 libpcre0
+Preinstall: libpopt0 libelf1 liblua5_1
+
+Runscripts: aaa_base
+
+Order: libopenssl0_9_8:openssl-certs
+
+VMinstall: util-linux perl-base libdb-4_5 libsepol1 libblkid1 libuuid1
+
+Required: autoconf automake binutils bzip2 gcc gcc%{gcc_version}
+Required: gettext-runtime glibc libtool perl rpm zlib libmpfr1
+Required: libncurses5 libgmp3 libgmpxx4
+
+Support: libaudit1
+Support: cpio cpp cpp%{gcc_version} cracklib cvs
+Support: file findutils gawk gdbm gettext-tools
+Support: glibc-devel glibc-locale groff gzip info less
+Support: libbz2-devel libdb-4_5
+Support: libstdc++%{gcc_version}
+Support: libxcrypt libzio
+Support: make man netcfg
+Support: linux-glibc-devel
+Support: net-tools pam-modules patch perl-base sysvinit-tools
+Support: texinfo timezone util-linux login
+Support: libgomp%{gcc_version} libuuid1 psmisc
+Support: terminfo-base update-alternatives pwdutils build-mkbaselibs
+Support: brp-check-suse post-build-checks rpmlint-Factory
+Keep: brp-check-suse
+# remove build-compare support to disable "same result" package dropping
+Support: build-compare
+
+%ifarch ia64
+Support: libunwind libunwind-devel
+%endif
+
+Keep: libaudit1 binutils bzip2 cpio cpp cracklib file findutils gawk gcc gcc-ada gcc-c++
+Keep: gdbm glibc-devel glibc-locale gzip libada libpcre0
+Keep: libunwind libunwind-devel libzio make pam-devel pam-modules
+Keep: patch perl-base perl rcs timezone libmpfr1 libcap2
+Keep: gmp libgmp3 libgmpxx4 libmpc2
+Keep: cpp45 gcc45 gcc45-ada libstdc++45
+Keep: cpp44 gcc44 gcc44-ada libstdc++44
+Keep: cpp43 gcc43 gcc43-ada libstdc++43
+Keep: cpp42 gcc42 gcc42-ada libstdc++42
+Keep: cpp41 gcc41 gcc41-ada libstdc++41
+Keep: java-1_6_0-openjdk java-1_6_0-openjdk-devel libcloog0 libppl7 libppl_c2
+Keep: libpopt0 pkg-config
+
+Prefer: -suse-build-key
+Prefer: krb5 krb5-devel
+Prefer: krb5-mini-devel:krb5-mini
+Prefer: libreadline5
+Prefer: libdb_java-4_5 libicu
+Prefer: cracklib-dict-small postfix
+Prefer: jta libpng fam mozilla mozilla-nss
+Prefer: unixODBC libsoup glitz
+Prefer: gnome-panel desktop-data-openSUSE gnome2-SuSE
+Prefer: mono-nunit gecko-sharp2
+Prefer: apache2-prefork Mesa openmotif-libs ghostscript-mini ghostscript-library
+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 preload-kmp-default
+Prefer: libstdc++%{gcc_version} libgcc%{gcc_version}
+Prefer: libstdc++%{gcc_version}-32bit libstdc++%{gcc_version}-64bit
+%ifarch s390x
+Prefer: -libstdc++41
+%endif
+Prefer: libstroke
+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: banshee:banshee-engine-gst helix-banshee:helix-banshee-engine-gst
+Prefer: banshee-1:banshee-1-client-classic
+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
+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: 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: bundle-lang-gnome:gnome-session-branding-openSUSE
+Prefer: texlive-xmltex texlive-tools texlive-jadetex
+Prefer: mono-web:mono-data-sqlite
+Prefer: gnome-games:gnuchess
+Prefer: glchess:gnuchess
+Prefer: OpenOffice_org:OpenOffice_org-branding-upstream
+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: kdelibs4:kdelibs4-branding-upstream
+Prefer: kdebase4-workspace:kdebase4-workspace-branding-upstream
+Prefer: kdelibs4-branding:kdelibs4-branding-upstream
+Prefer: PackageKit:PackageKit-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: ant:xerces-j2
+Prefer: dhcp-client:dhcp
+Prefer: beagle-index:preload-kmp-default
+Prefer: dummy-release
+Prefer: -bundle-lang-kde-de -bundle-lang-kde-en -bundle-lang-kde-es
+Prefer: -bundle-lang-kde-fr -bundle-lang-kde-pt
+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
+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
+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
+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 -OpenOffice_org -pam-laus -libgcc-tree-ssa -busybox-links
+
+Prefer: -NX -xaw3dd -db43
+Prefer: -xerces-j2-xml-resolver -xerces-j2-xml-apis
+Prefer: -vmware-player
+Prefer: libgcc%{gcc_version} libgcc%{gcc_version}-32bit libgcc%{gcc_version}-64bit
+Prefer: libgcc%{gcc_version}-x86 libffi%{gcc_version} libffi%{gcc_version}-devel libgcj_bc%{gcc_version}
+Prefer: libgomp%{gcc_version} libgomp%{gcc_version}-32bit libgomp%{gcc_version}-64bit
+Prefer: libmudflap%{gcc_version} libmudflap%{gcc_version}-32bit libmudflap%{gcc_version}-64bit
+Prefer: libobjc%{gcc_version} libgfortran%{gcc_version}
+Prefer: -libnetpbm -libcdio7-mini -libiso9660-5-mini -libiso9660-7-mini -libcdio10-mini
+Prefer: -libcdio-mini -faac-mini
+Prefer: -seamonkey
+Prefer: -libdb-4_4-devel -libevoldap-2_4-2
+Conflict: ghostscript-library:ghostscript-mini
+Conflict: ghostscript-fonts-std:ghostscript-mini
+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: OpenOffice_org:xerces-j2
+Prefer: k3b:libdvdread4
+Prefer: glibc-devel
+Prefer: -libpcap -java-1_7_0-icedtea-devel -libiniparser -loudmouth -libkonq4 -libnetcdf-4
+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: libpng14-compat-devel
+Prefer: -python3 -x11-video-fglrxG02 -libpng12-0
+Prefer: perl-Mail-SPF:perl-Error libldb0 -audit-libs mysql-community-server mysql-community-server-client
+
+#Temporary hack to solve #442202
+Ignore: yast2-all-packages:yast2-boot-server,yast2-heartbeat,yast2-issleconfig,yast2-linux-user-mgmt,yast2-trans-am,yast2-trans-be,yast2-trans-he,yast2-trans-ms,yast2-trans-my,yast2-trans-tk
+
+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,mingetty,distribution-release,udev
+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: 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: postfix:pcre,libpcre0
+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-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
+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: libgcc:glibc-32bit
+Ignore: libgcc41:glibc-32bit
+Ignore: libgcc42:glibc-32bit
+Ignore: libgcc43:glibc-32bit
+Ignore: libgcc44:glibc-32bit
+Ignore: libgcc45: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: 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: 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: OpenOffice_org-de:myspell-german-dictionary
+Ignore: OpenOffice_org:OpenOffice_org-i18n
+Ignore: OpenOffice_org:OpenOffice_org-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: 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: 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: 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: phonon:phonon-backend
+Ignore: openwbem-devel
+Ignore: MozillaFirefox:MozillaFirefox-branding
+Ignore: yast2: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: pulseaudio:kernel
+Ignore: transmission-common:transmission-ui
+Ignore: mutter-moblin:moblin-branding
+Ignore: sysvinit-tools:mkinitrd cifs-utils:mkinitrd
+Ignore: opensc:pinentry
+Ignore: gpg2:pinentry
+Ignore: NetworkManager:dhcp
+# sysconfig requires it at runtime, not buildtime
+Ignore: sysconfig:dbus-1
+Ignore: sysconfig:procps
+Ignore: sysconfig:iproute2
+# no build dependencies
+Ignore: libksuseinstall1:yast2-packager
+Ignore: libksuseinstall1:zypper
+Ignore: libqca2:gpg2
+Ignore: NetworkManager:wpa_supplicant
+Ignore: NetworkManager:dhcp-client
+
+%ifnarch ia64 s390 s390x
+Prefer: java-1_6_0-openjdk java-1_6_0-openjdk-devel
+%endif
+%ifarch s390 s390x
+Prefer: java-1_6_0-ibm java-1_6_0-ibm-devel
+%endif
+%ifarch ia64
+Prefer: java-1_6_0-bea java-1_6_0-bea-devel
+%endif
+
+Prefer: -java-1_5_0-gcj-compat-devel
+%ifarch %ix86 x86_64
+Prefer: -java-1_5_0-ibm-devel
+%endif
+# We use always openjdk on openSUSE !
+#%ifnarch ia64 s390 s390x
+Substitute: java2-devel-packages java-1_6_0-openjdk-devel
+#%else
+# %ifarch s390 s390x
+#Substitute: java2-devel-packages java-1_6_0-ibm-devel unzip update-alternatives
+# %endif
+# %ifarch ia64
+#Substitute: java2-devel-packages java-1_6_0-bea-devel unzip update-alternatives
+# %endif
+#%endif
+
+%ifarch x86_64 ppc64 s390x sparc64
+Substitute: glibc-devel-32bit glibc-devel-32bit glibc-32bit
+%else
+ %ifarch ppc
+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
+
+# until the builds of the packages are fixed...
+Substitute: yast2-theme-SLED
+Substitute: yast2-theme-SLE
+
+Optflags: i586 -fomit-frame-pointer -fmessage-length=0
+Optflags: i686 -march=i686 -mtune=generic -fomit-frame-pointer -fmessage-length=0
+Optflags: x86_64 -fmessage-length=0
+Optflags: ppc -fmessage-length=0
+Optflags: ppc64 -fmessage-length=0
+Optflags: ia64 -fmessage-length=0
+Optflags: s390 -fmessage-length=0
+Optflags: s390x -fmessage-length=0
+
+Optflags: * -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables
+
+%define suse_version 1130
+
+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 module-init-tools kernel-syms
+%kernel_module_package_buildreqs module-init-tools kernel-syms
+
+%suse_version 1130
+%sles_version 0
+%ul_version 0
+%do_profiling 1
+%_vendor suse
diff --git a/configs/sl11.4.conf b/configs/sl11.4.conf
new file mode 100644
index 0000000..787b42b
--- /dev/null
+++ b/configs/sl11.4.conf
@@ -0,0 +1,600 @@
+%define gcc_version 45
+%define opensuse_bs 1
+
+Patterntype: rpm-md ymp
+%if "%_repository" == "images"
+Type: kiwi
+Repotype: none
+Patterntype: none
+Prefer: openSUSE-release
+%endif
+
+Substitute: kiwi-packagemanager:zypper zypper
+Substitute: kiwi-packagemanager:smart smart
+Substitute: kiwi-packagemanager:instsource kiwi-instsource cdrkit-cdrtools-compat syslinux kiwi-instsource-plugins-openSUSE-11-3
+Substitute: kiwi-filesystem:ext3 e2fsprogs procps psmisc reiserfs
+Substitute: kiwi-filesystem:squashfs squashfs
+Substitute: kiwi-boot:isoboot kiwi-desc-isoboot module-init-tools elfutils squashfs fribidi gfxboot-devel gawk gfxboot gfxboot-devel grub hdparm hwinfo iproute2 kiwi-tools lvm2 make memtest86+ netcfg psmisc squashfs sysfsutils syslinux clicfs e2fsprogs
+Substitute: kiwi-boot:oemboot kiwi-desc-oemboot adaptec-firmware atftp bc bind-libs bind-utils bootsplash bootsplash-branding-openSUSE busybox bzip2 clicfs cryptsetup curl dhcpcd dialog e2fsprogs eject fbiterm file fribidi gettext-runtime gfxboot gfxboot-devel grub hwinfo kernel-default kernel-default-base kernel-desktop kexec-tools kiwi-tools lvm2 make module-init-tools netcfg net-tools parted pciutils psmisc squashfs sysconfig sysfsutils tar util-linux jing
+Substitute: kiwi-boot:netboot kiwi-desc-netboot kiwi-desc-xenboot ncurses-utils curl dhcpcd iputils nbd net-tools netcfg nfs-client parted grub mdadm
+Substitute: kiwi-boot:usbboot kiwi-desc-usbboot
+Substitute: kiwi-boot:vmxboot kiwi-desc-vmxboot
+Substitute: kiwi-boot:xenboot kiwi-desc-xenboot
+
+Preinstall: aaa_base acl attr bash coreutils diffutils
+Preinstall: filesystem fillup glibc grep insserv libacl libattr
+Preinstall: libbz2-1 libgcc%{gcc_version} libxcrypt m4 libncurses5 pam
+Preinstall: permissions libreadline6 rpm sed tar zlib libselinux1
+Preinstall: liblzma5 libcap2 libpcre0
+Preinstall: libpopt0 libelf1 liblua5_1
+
+Runscripts: aaa_base
+
+Order: libopenssl0_9_8:openssl-certs
+
+VMinstall: util-linux libmount1 perl-base libdb-4_8 libsepol1 libblkid1 libuuid1
+
+ExportFilter: \.x86_64\.rpm$ x86_64
+ExportFilter: \.ia64\.rpm$ ia64
+ExportFilter: \.s390x\.rpm$ s390x
+ExportFilter: \.ppc64\.rpm$ ppc64
+ExportFilter: \.ppc\.rpm$ ppc
+ExportFilter: \.i686\.rpm$ i686
+ExportFilter: -ia32-.*\.rpm$
+ExportFilter: -32bit-.*\.sparc64\.rpm$
+ExportFilter: -64bit-.*\.sparcv9\.rpm$
+ExportFilter: ^glibc(?:-devel)?-32bit-.*\.sparc64\.rpm$ sparc64
+ExportFilter: ^glibc(?:-devel)?-64bit-.*\.sparcv9\.rpm$ sparcv9
+ExportFilter: ^blocxx-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^boost-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^bzip2-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^curl-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^dbus-1-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^dbus-1-glib-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^e2fsprogs-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^expat-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^fontconfig-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^freetype2-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^gcc45-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^gcc44-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^gcc43-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^glib2-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^glibc-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^hal-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^hwinfo-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^icu-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^jpeg-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^kdelibs3-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^kernel-default-.*(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^kernel-desktop-.*(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^kernel-pae-.*(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^libidn-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^libpng12-0-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^libqt4-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^libxcrypt-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^libxml2-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^libzypp-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^openssl-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^pcre-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^perl-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^perl-gettext-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^qt3-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^rpm-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^sysfsutils-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^wireless-tools-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-libICE-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-libSM-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-libX11-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-libXau-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-libXdmcp-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-libXext-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-libXfixes-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-libXmu-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-libXrender-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-libfontenc-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-libs-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-libxcb-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^xorg-x11-server-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^yast2-core-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^yast2-hardware-detection-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^yast2-perl-bindings-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^yast2-pkg-bindings-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^yast2-qt-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^yast2-xml-(?:debuginfo|debugsource)-.*\.rpm$ .
+ExportFilter: ^zlib-(?:debuginfo|debugsource)-.*\.rpm$ .
+#ExportFilter: -debuginfo-.*\.rpm$
+#ExportFilter: -debugsource-.*\.rpm$
+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
+ExportFilter: ^avmailgate.*\.s390.rpm$ . s390x
+ExportFilter: ^flash-player.*\.i586.rpm$ . x86_64
+ExportFilter: ^novell-messenger-client.*\.i586.rpm$ . x86_64
+ExportFilter: ^openCryptoki-32bit.*\.s390.rpm$ . s390x
+ExportFilter: ^wine.*\.i586.rpm$ . x86_64
+
+#Required: autoconf automake binutils bzip2 gcc gcc%{gcc_version}
+#Required: gettext-runtime glibc libtool perl rpm zlib libmpfr4
+#Required: libncurses5 libgmp10 libgmpxx4 libppl9 libppl_c4
+Required: gcc gcc%{gcc_version} glibc perl rpm tar patch
+
+Support: autoconf automake binutils bzip2 gcc gcc%{gcc_version}
+Support: gettext-runtime glibc libtool perl rpm zlib
+Support: libncurses5
+Support: libaudit1 cpio cpp cpp%{gcc_version} cracklib cvs
+Support: file findutils gawk gdbm gettext-tools
+Support: glibc-devel glibc-locale groff gzip info less
+Support: libbz2-devel libdb-4_8
+Support: libstdc++%{gcc_version}
+# for boot.udev
+Support: udev
+Support: libxcrypt libzio
+Support: linux-glibc-devel make man netcfg
+Support: net-tools pam-modules patch perl-base sysvinit-tools
+Support: texinfo timezone util-linux libmount1 login
+Support: libgomp%{gcc_version} libuuid1 psmisc
+Support: terminfo-base update-alternatives pwdutils build-mkbaselibs
+Support: brp-check-suse post-build-checks rpmlint-Factory
+Keep: brp-check-suse
+# remove build-compare support to disable "same result" package dropping
+Support: build-compare
+
+# testing deltas (only for O:F for now!)
+#Support: build-mkdrpms deltarpm
+
+%ifarch ia64
+Support: libunwind libunwind-devel
+%endif
+
+Keep: libaudit1 binutils bzip2 cpio cpp cracklib file findutils gawk gcc gcc-ada gcc-c++
+Keep: gdbm glibc-devel glibc-locale gzip libada libpcre0
+Keep: libunwind libunwind-devel libzio make pam-devel pam-modules
+Keep: patch perl-base perl rcs timezone libmpfr4 libcap2
+Keep: gmp libgmp10 libgmpxx4 libmpc2
+Keep: cpp45 gcc45 gcc45-ada libstdc++45
+Keep: cpp44 gcc44 gcc44-ada libstdc++44
+Keep: cpp43 gcc43 gcc43-ada libstdc++43
+Keep: cpp42 gcc42 gcc42-ada libstdc++42
+Keep: cpp41 gcc41 gcc41-ada libstdc++41
+Keep: java-1_6_0-openjdk java-1_6_0-openjdk-devel libcloog0 libppl9 libppl_c4
+Keep: libpopt0 pkg-config libmount1
+
+Prefer: -suse-build-key
+Prefer: krb5 krb5-devel
+Prefer: krb5-mini-devel:krb5-mini
+Prefer: libreadline5
+Prefer: libdb_java-4_8 libicu
+Prefer: cracklib-dict-small postfix
+Prefer: jta libpng fam mozilla mozilla-nss
+Prefer: unixODBC libsoup glitz
+Prefer: gnome-panel desktop-data-openSUSE gnome2-SuSE
+Prefer: mono-nunit gecko-sharp2
+Prefer: apache2-prefork Mesa openmotif-libs ghostscript-mini ghostscript-library
+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 preload-kmp-default
+Prefer: libstdc++%{gcc_version} libgcc%{gcc_version}
+Prefer: libstdc++%{gcc_version}-32bit libstdc++%{gcc_version}-64bit
+%ifarch s390x
+Prefer: -libstdc++41
+%endif
+Prefer: libstroke
+# for symbol syslog (syslogd is best as it has the least dependencies)
+Prefer: 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: banshee:banshee-engine-gst helix-banshee:helix-banshee-engine-gst
+Prefer: banshee-1:banshee-1-client-classic
+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
+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: 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: bundle-lang-gnome:gnome-session-branding-openSUSE
+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: 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: 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: 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: beagle-index:preload-kmp-default
+Prefer: dummy-release
+Prefer: -bundle-lang-kde-de -bundle-lang-kde-en -bundle-lang-kde-es
+Prefer: -bundle-lang-kde-fr -bundle-lang-kde-pt
+Prefer: -bundle-lang-kde-zh -bundle-lang-kde-ja -bundle-lang-kde-ru -bundle-lang-kde-pl