diff options
author | SoonKyu Park <sk7.park@samsung.com> | 2016-06-15 14:18:44 +0900 |
---|---|---|
committer | SoonKyu Park <sk7.park@samsung.com> | 2016-06-15 14:18:44 +0900 |
commit | d4cd5999ff27f5b00208cc39446ab07ddceefaeb (patch) | |
tree | 66b90e83d8352eac4569271f7ca03de5e3977e50 | |
parent | 43a15ec55888f27e1377df0066898fd079510a9c (diff) | |
download | build-d4cd5999ff27f5b00208cc39446ab07ddceefaeb.tar.gz build-d4cd5999ff27f5b00208cc39446ab07ddceefaeb.tar.bz2 build-d4cd5999ff27f5b00208cc39446ab07ddceefaeb.zip |
update to upstream 20150115
Change-Id: I8943d5a8c98049843e6753c38beac89927690d72
-rw-r--r-- | Build.pm | 377 | ||||
-rw-r--r-- | Build/Arch.pm | 68 | ||||
-rw-r--r-- | Build/Archrepo.pm | 75 | ||||
-rw-r--r-- | Build/Deb.pm | 167 | ||||
-rw-r--r-- | Build/Debrepo.pm | 116 | ||||
-rw-r--r-- | Build/Kiwi.pm | 21 | ||||
-rw-r--r-- | Build/LiveBuild.pm | 102 | ||||
-rw-r--r-- | Build/Repo.pm | 61 | ||||
-rw-r--r-- | Build/Rpm.pm | 177 | ||||
-rw-r--r-- | Build/Rpmmd.pm | 205 | ||||
-rw-r--r-- | Build/Susetags.pm | 142 | ||||
-rw-r--r-- | Build/Zypp.pm | 81 | ||||
-rw-r--r-- | COPYING | 340 | ||||
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | README | 24 | ||||
-rwxr-xr-x | build | 2636 | ||||
-rw-r--r-- | build-pkg | 93 | ||||
-rw-r--r-- | build-pkg-arch | 73 | ||||
-rw-r--r-- | build-pkg-deb | 124 | ||||
-rw-r--r-- | build-pkg-rpm | 193 | ||||
-rw-r--r-- | build-recipe | 140 | ||||
-rw-r--r-- | build-recipe-arch | 57 | ||||
-rw-r--r-- | build-recipe-debootstrap | 92 | ||||
-rw-r--r-- | build-recipe-dsc | 111 | ||||
-rw-r--r-- | build-recipe-kiwi | 494 | ||||
-rw-r--r-- | build-recipe-livebuild | 225 | ||||
-rw-r--r-- | build-recipe-mock | 100 | ||||
-rw-r--r-- | build-recipe-preinstallimage | 79 | ||||
-rw-r--r-- | build-recipe-spec | 261 | ||||
-rw-r--r-- | build-vm | 828 | ||||
-rw-r--r-- | build-vm-ec2 | 228 | ||||
-rw-r--r-- | build-vm-emulator | 93 | ||||
-rw-r--r-- | build-vm-kvm | 228 | ||||
-rw-r--r-- | build-vm-lxc | 76 | ||||
-rw-r--r-- | build-vm-openstack | 145 | ||||
-rw-r--r-- | build-vm-qemu | 61 | ||||
-rw-r--r-- | build-vm-uml | 67 | ||||
-rw-r--r-- | build-vm-xen | 133 | ||||
-rw-r--r-- | build-vm-zvm | 369 | ||||
-rw-r--r-- | build.1 | 182 | ||||
-rwxr-xr-x | changelog2spec | 26 | ||||
-rwxr-xr-x | common_functions | 86 | ||||
-rwxr-xr-x | computeblocklists | 165 | ||||
-rw-r--r-- | configs/arch.conf | 17 | ||||
-rw-r--r-- | configs/sl13.2.conf | 96 | ||||
-rw-r--r-- | configs/sles12.conf | 668 | ||||
-rwxr-xr-x | createarchdeps | 72 | ||||
-rwxr-xr-x | createdebdeps | 79 | ||||
-rwxr-xr-x | createdirdeps | 99 | ||||
-rwxr-xr-x | createrepomddeps | 524 | ||||
-rwxr-xr-x | createyastdeps | 139 | ||||
-rwxr-xr-x | createzyppdeps | 64 | ||||
-rw-r--r-- | debian/changelog | 6 | ||||
-rwxr-xr-x | debtransform | 71 | ||||
-rwxr-xr-x | debtransformbz2 | 20 | ||||
-rwxr-xr-x | debtransformzip | 20 | ||||
-rwxr-xr-x | download | 24 | ||||
-rwxr-xr-x | emulator/emulator.sh | 22 | ||||
-rwxr-xr-x | expanddeps | 195 | ||||
-rwxr-xr-x | extractbuild | 108 | ||||
-rwxr-xr-x | getbinaryid | 20 | ||||
-rwxr-xr-x | init_buildsystem | 967 | ||||
-rw-r--r-- | initvm.c | 56 | ||||
-rwxr-xr-x | killchroot | 20 | ||||
-rwxr-xr-x | listinstalled | 59 | ||||
-rwxr-xr-x | livebuild_pre_run.template | 69 | ||||
-rwxr-xr-x | mkbaselibs | 29 | ||||
-rwxr-xr-x | mkdrpms | 20 | ||||
-rwxr-xr-x | order | 23 | ||||
-rw-r--r-- | packaging/build.spec | 14 | ||||
-rw-r--r-- | qemu-reg | 7 | ||||
-rwxr-xr-x | queryconfig | 84 | ||||
-rwxr-xr-x | signdummy | 20 | ||||
-rwxr-xr-x | spec2changelog | 19 | ||||
-rwxr-xr-x | spec_add_patch | 20 | ||||
-rwxr-xr-x | spectool | 20 | ||||
-rwxr-xr-x | substitutedeps | 53 | ||||
-rw-r--r-- | t/bad.livebuild | bin | 0 -> 40960 bytes | |||
-rw-r--r-- | t/directory.livebuild | bin | 0 -> 30720 bytes | |||
-rwxr-xr-x | t/dist | 20 | ||||
-rwxr-xr-x | t/live-build | 72 | ||||
-rw-r--r-- | t/standard.livebuild | bin | 0 -> 30720 bytes | |||
-rw-r--r-- | test/common | 8 | ||||
-rwxr-xr-x | test/testbuild.sh | 19 | ||||
-rwxr-xr-x | unrpm | 20 | ||||
-rw-r--r-- | unrpm.1 | 17 | ||||
-rwxr-xr-x | vc | 24 | ||||
-rw-r--r-- | vc.1 | 25 |
88 files changed, 9312 insertions, 3958 deletions
@@ -1,3 +1,23 @@ +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + package Build; use strict; @@ -11,6 +31,7 @@ our $do_rpm; our $do_deb; our $do_kiwi; our $do_arch; +our $do_livebuild; sub import { for (@_) { @@ -18,8 +39,9 @@ sub import { $do_deb = 1 if $_ eq ':deb'; $do_kiwi = 1 if $_ eq ':kiwi'; $do_arch = 1 if $_ eq ':arch'; + $do_livebuild = 1 if $_ eq ':livebuild'; } - $do_rpm = $do_deb = $do_kiwi = $do_arch = 1 if !$do_rpm && !$do_deb && !$do_kiwi && !$do_arch; + $do_rpm = $do_deb = $do_kiwi = $do_arch = $do_livebuild = 1 if !$do_rpm && !$do_deb && !$do_kiwi && !$do_arch && !$do_livebuild; if ($do_deb) { require Build::Deb; } @@ -29,6 +51,9 @@ sub import { if ($do_arch) { require Build::Arch; } + if ($do_livebuild) { + require Build::LiveBuild; + } } package Build::Features; @@ -204,6 +229,7 @@ sub read_config { $config->{'fileprovides'} = {}; $config->{'constraint'} = []; $config->{'expandflags'} = []; + $config->{'buildflags'} = []; for my $l (@spec) { $l = $l->[1] if ref $l; next unless defined $l; @@ -220,7 +246,7 @@ sub read_config { } next; } - if ($l0 eq 'preinstall:' || $l0 eq 'vminstall:' || $l0 eq 'required:' || $l0 eq 'support:' || $l0 eq 'keep:' || $l0 eq 'prefer:' || $l0 eq 'ignore:' || $l0 eq 'conflict:' || $l0 eq 'runscripts:' || $l0 eq 'expandflags:') { + if ($l0 eq 'preinstall:' || $l0 eq 'vminstall:' || $l0 eq 'required:' || $l0 eq 'support:' || $l0 eq 'keep:' || $l0 eq 'prefer:' || $l0 eq 'ignore:' || $l0 eq 'conflict:' || $l0 eq 'runscripts:' || $l0 eq 'expandflags:' || $l0 eq 'buildflags:') { my $t = substr($l0, 0, -1); for my $l (@l) { if ($l eq '!*') { @@ -271,13 +297,15 @@ sub read_config { $config->{'order'}->{$l} = 1; } } - } elsif ($l0 eq 'repotype:') { #type of generated repository data + } elsif ($l0 eq 'repotype:') { # type of generated repository data $config->{'repotype'} = [ @l ]; - } elsif ($l0 eq 'type:') { #kind of packaging system (spec,dsc,arch,kiwi,...) + } elsif ($l0 eq 'type:') { # kind of recipe system (spec,dsc,arch,kiwi,...) $config->{'type'} = $l[0]; - } elsif ($l0 eq 'binarytype:') { #rpm,deb,arch,... + } elsif ($l0 eq 'buildengine:') { # build engine (build,mock) + $config->{'buildengine'} = $l[0]; + } elsif ($l0 eq 'binarytype:') { # kind of binary packages (rpm,deb,arch,...) $config->{'binarytype'} = $l[0]; - } elsif ($l0 eq 'patterntype:') { #kind of generated patterns in repository + } elsif ($l0 eq 'patterntype:') { # kind of generated patterns in repository $config->{'patterntype'} = [ @l ]; } elsif ($l0 eq 'release:') { $config->{'release'} = $l[0]; @@ -285,6 +313,8 @@ sub read_config { $config->{'cicntstart'} = $l[0]; } elsif ($l0 eq 'releaseprg:') { $config->{'releaseprg'} = $l[0]; + } elsif ($l0 eq 'releasesuffix:') { + $config->{'releasesuffix'} = join(' ', @l); } elsif ($l0 eq 'changetarget:' || $l0 eq 'target:') { $config->{'target'} = join(' ', @l); push @macros, "%define _target_cpu ".(split('-', $config->{'target'}))[0] if $config->{'target'}; @@ -297,8 +327,6 @@ sub read_config { } else { push @{$config->{'constraint'}}, $l; } - } elsif ($l0 eq 'rpmbuildstage:') { # use the rpmbuild --stage option - $config->{'rpmbuildstage'} = $l[0]; } elsif ($l0 !~ /^[#%]/) { warn("unknown keyword in config: $l0\n"); } @@ -326,7 +354,7 @@ sub read_config { } if (!$config->{'binarytype'}) { $config->{'binarytype'} = 'rpm' if $config->{'type'} eq 'spec' || $config->{'type'} eq 'kiwi'; - $config->{'binarytype'} = 'deb' if $config->{'type'} eq 'dsc'; + $config->{'binarytype'} = 'deb' if $config->{'type'} eq 'dsc' || $config->{'type'} eq 'livebuild'; $config->{'binarytype'} = 'arch' if $config->{'type'} eq 'arch'; $config->{'binarytype'} ||= 'UNDEFINED'; } @@ -353,6 +381,13 @@ sub read_config { $config->{"expandflags:$_"} = 1; } } + for (@{$config->{'buildflags'} || []}) { + if (/^([^:]+):(.*)$/s) { + $config->{"buildflags:$1"} = $2; + } else { + $config->{"buildflags:$_"} = 1; + } + } return $config; } @@ -396,32 +431,94 @@ sub do_subst_vers { return @res; } +sub add_livebuild_packages { + my ($config, @deps) = @_; + + if ($config->{'substitute'}->{'build-packages:livebuild'}) { + push @deps, @{$config->{'substitute'}->{'build-packages:livebuild'}}; + } else { + # defaults live-build package dependencies base on 4.0~a26 gathered with: + # grep Check_package -r /usr/lib/live/build + push @deps, ( + 'apt-utils', 'dctrl-tools', 'debconf', 'dosfstools', 'e2fsprogs', 'grub', + 'librsvg2-bin', 'live-boot', 'live-config', 'mtd-tools', 'parted', + 'squashfs-tools', 'syslinux', 'syslinux-common', 'wget', 'xorriso', + 'zsync' ); + } + return @deps; +} + # Delivers all packages which get used for building sub get_build { my ($config, $subpacks, @deps) = @_; + + @deps = add_livebuild_packages($config, @deps) if $config->{'type'} eq 'livebuild'; my @ndeps = grep {/^-/} @deps; + my %ndeps = map {$_ => 1} @ndeps; + my @directdepsend; + if ($ndeps{'--directdepsend--'}) { + @directdepsend = @deps; + for (splice @deps) { + last if $_ eq '--directdepsend--'; + push @deps, $_; + } + @directdepsend = grep {!/^-/} splice(@directdepsend, @deps + 1); + } my @extra = (@{$config->{'required'}}, @{$config->{'support'}}); if (@{$config->{'keep'} || []}) { my %keep = map {$_ => 1} (@deps, @{$config->{'keep'} || []}, @{$config->{'preinstall'}}); for (@{$subpacks || []}) { - push @ndeps, "-$_" unless $keep{$_}; + next if $keep{$_}; + push @ndeps, "-$_"; + $ndeps{"-$_"} = 1; } } else { # new "empty keep" mode, filter subpacks from required/support my %subpacks = map {$_ => 1} @{$subpacks || []}; @extra = grep {!$subpacks{$_}} @extra; } - my %ndeps = map {$_ => 1} @ndeps; @deps = grep {!$ndeps{$_}} @deps; push @deps, @{$config->{'preinstall'}}; push @deps, @extra; @deps = grep {!$ndeps{"-$_"}} @deps; @deps = do_subst($config, @deps); @deps = grep {!$ndeps{"-$_"}} @deps; - @deps = expand($config, @deps, @ndeps); + if (@directdepsend) { + @directdepsend = do_subst($config, @directdepsend); + @directdepsend = grep {!$ndeps{"-$_"}} @directdepsend; + unshift @directdepsend, '--directdepsend--' if @directdepsend; + } + @deps = expand($config, @deps, @ndeps, @directdepsend); return @deps; } +# return the package needed for setting up the build environment. +# an empty result means that the packages from get_build should +# be used instead. +sub get_sysbuild { + my ($config, $buildtype) = @_; + my $engine = $config->{'buildengine'} || ''; + $buildtype ||= $config->{'type'} || ''; + my @sysdeps; + if ($engine eq 'mock' && $buildtype ne 'kiwi') { + @sysdeps = @{$config->{'substitute'}->{'system-packages:mock'} || []}; + @sysdeps = ('mock', 'createrepo') unless @sysdeps; + } elsif ($engine eq 'debootstrap' && $buildtype ne 'kiwi') { + @sysdeps = @{$config->{'substitute'}->{'system-packages:debootstrap'} || []}; + @sysdeps = ('debootstrap', 'lsb-release') unless @sysdeps; + } elsif ($buildtype eq 'livebuild') { + # packages used for build environment setup (build-recipe-livebuild deps) + @sysdeps = @{$config->{'substitute'}->{'system-packages:livebuild'} || []}; + @sysdeps = ('apt-utils', 'cpio', 'dpkg-dev', 'live-build', 'lsb-release', 'tar') unless @sysdeps; + } + return () unless @sysdeps; + @sysdeps = Build::get_build($config, [], @sysdeps); + return @sysdeps unless $sysdeps[0]; + shift @sysdeps; + @sysdeps = unify(@sysdeps, get_preinstalls($config)); + return (1, @sysdeps); +} + # Delivers all packages which shall have an influence to other package builds (get_build reduced by support packages) sub get_deps { my ($config, $subpacks, @deps) = @_; @@ -478,23 +575,40 @@ sub get_cbinstalls { return @{[]}; } sub readdeps { my ($config, $pkginfo, @depfiles) = @_; - my %requires = (); + my %requires; local *F; my %provides; - my $dofileprovides = %{$config->{'fileprovides'}}; + my %pkgconflicts; + my %pkgobsoletes; + my $dofileprovides = %{$config->{'fileprovides'} || {}}; for my $depfile (@depfiles) { if (ref($depfile) eq 'HASH') { for my $rr (keys %$depfile) { $provides{$rr} = $depfile->{$rr}->{'provides'}; $requires{$rr} = $depfile->{$rr}->{'requires'}; + $pkgconflicts{$rr} = $depfile->{$rr}->{'conflicts'}; + $pkgobsoletes{$rr} = $depfile->{$rr}->{'obsoletes'}; } next; } # XXX: we don't support different architectures per file - open(F, "<$depfile") || die("$depfile: $!\n"); + open(F, '<', $depfile) || die("$depfile: $!\n"); while(<F>) { my @s = split(' ', $_); my $s = shift @s; + if ($pkginfo && ($s =~ /^I:(.*)\.(.*)-\d+\/\d+\/\d+:$/)) { + my $pkgid = $1; + my $arch = $2; + my $evr = $s[0]; + $pkginfo->{$pkgid}->{'arch'} = $1 if $s[1] && $s[1] =~ s/-(.*)$//; + $pkginfo->{$pkgid}->{'buildtime'} = $s[1] if $s[1]; + if ($evr =~ s/^\Q$pkgid-//) { + $pkginfo->{$pkgid}->{'epoch'} = $1 if $evr =~ s/^(\d+)://; + $pkginfo->{$pkgid}->{'release'} = $1 if $evr =~ s/-([^-]*)$//; + $pkginfo->{$pkgid}->{'version'} = $evr; + } + next; + } my @ss; while (@s) { if (!$dofileprovides && $s[0] =~ /^\//) { @@ -506,48 +620,94 @@ sub readdeps { next; } push @ss, shift @s; - while (@s) { - if ($s[0] =~ /^[\(<=>|]/) { - $ss[-1] .= " $s[0] $s[1]"; - $ss[-1] =~ s/ \((.*)\)/ $1/; - $ss[-1] =~ s/(<|>){2}/$1/; - splice(@s, 0, 2); - } else { - last; - } + while (@s && $s[0] =~ /^[\(<=>|]/) { + $ss[-1] .= " $s[0] $s[1]"; + $ss[-1] =~ s/ \((.*)\)/ $1/; + $ss[-1] =~ s/(<|>){2}/$1/; + splice(@s, 0, 2); } } my %ss; @ss = grep {!$ss{$_}++} @ss; - if ($s =~ /^(P|R):(.*)\.(.*)-\d+\/\d+\/\d+:$/) { + if ($s =~ /^(P|R|C|O):(.*)\.(.*)-\d+\/\d+\/\d+:$/) { my $pkgid = $2; my $arch = $3; + if ($1 eq "P") { + $provides{$pkgid} = \@ss; + if ($pkginfo) { + $pkginfo->{$pkgid}->{'name'} = $pkgid; + $pkginfo->{$pkgid}->{'arch'} = $arch; + $pkginfo->{$pkgid}->{'provides'} = \@ss; + } + } if ($1 eq "R") { $requires{$pkgid} = \@ss; $pkginfo->{$pkgid}->{'requires'} = \@ss if $pkginfo; next; } - # handle provides - $provides{$pkgid} = \@ss; - if ($pkginfo) { - # extract ver and rel from self provides - my ($v, $r) = map { /\Q$pkgid\E = ([^-]+)(?:-(.+))?$/ } @ss; - die("$pkgid: no self provides\n") unless defined($v) && $v ne ''; - $pkginfo->{$pkgid}->{'name'} = $pkgid; - $pkginfo->{$pkgid}->{'version'} = $v; - $pkginfo->{$pkgid}->{'release'} = $r if defined($r); - $pkginfo->{$pkgid}->{'arch'} = $arch; - $pkginfo->{$pkgid}->{'provides'} = \@ss; + if ($1 eq "C") { + $pkgconflicts{$pkgid} = \@ss; + $pkginfo->{$pkgid}->{'conflicts'} = \@ss if $pkginfo; + next; + } + if ($1 eq "O") { + $pkgobsoletes{$pkgid} = \@ss; + $pkginfo->{$pkgid}->{'obsoletes'} = \@ss if $pkginfo; + next; } } } close F; } + if ($pkginfo) { + # extract evr from self provides if there is no 'I' line + for my $pkg (values %$pkginfo) { + next if defined $pkg->{'version'}; + my $n = $pkg->{'name'}; + next unless defined $n; + my @sp = grep {/^\Q$n\E\s*=\s*/} @{$pkg->{'provides'} || []}; + next unless @sp; + my $evr = $sp[-1]; + $evr =~ s/^\Q$n\E\s*=\s*//; + $pkg->{'epoch'} = $1 if $evr =~ s/^(\d+)://; + $pkg->{'release'} = $1 if $evr =~ s/-([^-]*)$//; + $pkg->{'version'} = $evr; + } + } $config->{'providesh'} = \%provides; $config->{'requiresh'} = \%requires; + $config->{'pkgconflictsh'} = \%pkgconflicts; + $config->{'pkgobsoletesh'} = \%pkgobsoletes; makewhatprovidesh($config); } +sub getbuildid { + my ($q) = @_; + my $evr = $q->{'version'}; + $evr = "$q->{'epoch'}:$evr" if $q->{'epoch'}; + $evr .= "-$q->{'release'}" if defined $q->{'release'};; + my $buildtime = $q->{'buildtime'} || 0; + $evr .= " $buildtime"; + $evr .= "-$q->{'arch'}" if defined $q->{'arch'}; + return "$q->{'name'}-$evr"; +} + +sub writedeps { + my ($fh, $pkg, $url) = @_; + $url = '' unless defined $url; + return unless defined($pkg->{'name'}) && defined($pkg->{'arch'}); + return if $pkg->{'arch'} eq 'src' || $pkg->{'arch'} eq 'nosrc'; + my $id = $pkg->{'id'}; + $id = ($pkg->{'buildtime'} || 0)."/".($pkg->{'filetime'} || 0)."/0" unless $id; + $id = "$pkg->{'name'}.$pkg->{'arch'}-$id: "; + print $fh "F:$id$url$pkg->{'location'}\n"; + print $fh "P:$id".join(' ', @{$pkg->{'provides'} || []})."\n"; + print $fh "R:$id".join(' ', @{$pkg->{'requires'}})."\n" if $pkg->{'requires'}; + print $fh "C:$id".join(' ', @{$pkg->{'conflicts'}})."\n" if $pkg->{'conflicts'}; + print $fh "O:$id".join(' ', @{$pkg->{'obsoletes'}})."\n" if $pkg->{'obsoletes'}; + print $fh "I:$id".getbuildid($pkg)."\n"; +} + sub makewhatprovidesh { my ($config) = @_; @@ -578,6 +738,8 @@ sub forgetdeps { delete $config->{'providesh'}; delete $config->{'whatprovidesh'}; delete $config->{'requiresh'}; + delete $config->{'pkgconflictsh'}; + delete $config->{'pkgobsoletesh'}; } my %addproviders_fm = ( @@ -649,24 +811,69 @@ sub addproviders { return \@p; } +# XXX: should also check the package EVR +sub nevrmatch { + my ($config, $r, @p) = @_; + my $rn = $r; + $rn =~ s/\s*([<=>]{1,2}).*$//; + return grep {$_ eq $rn} @p; +} + +sub checkconflicts { + my ($config, $ins, $q, $eq, @r) = @_; + my $whatprovides = $config->{'whatprovidesh'}; + for my $r (@r) { + my @eq = grep {$ins->{$_}} @{$whatprovides->{$r} || addproviders($config, $r)}; + next unless @eq; + push @$eq, map {"provider $q conflicts with installed $_"} @eq; + return 1; + } + return 0; +} + +sub checkobsoletes { + my ($config, $ins, $q, $eq, @r) = @_; + my $whatprovides = $config->{'whatprovidesh'}; + for my $r (@r) { + my @eq = grep {$ins->{$_}} nevrmatch($config, $r, @{$whatprovides->{$r} || addproviders($config, $r)}); + next unless @eq; + push @$eq, map {"provider $q is obsoleted by installed $_"} @eq; + return 1; + } + return 0; +} + sub expand { my ($config, @p) = @_; my $conflicts = $config->{'conflicth'}; + my $pkgconflicts = $config->{'pkgconflictsh'} || {}; + my $pkgobsoletes = $config->{'pkgobsoletesh'} || {}; my $prefer = $config->{'preferh'}; my $ignore = $config->{'ignoreh'}; + my $ignoreconflicts = $config->{'expandflags:ignoreconflicts'}; my $whatprovides = $config->{'whatprovidesh'}; my $requires = $config->{'requiresh'}; my %xignore = map {substr($_, 1) => 1} grep {/^-/} @p; + my @directdepsend; + if ($xignore{'-directdepsend--'}) { + delete $xignore{'-directdepsend--'}; + my @directdepsend = @p; + for my $p (splice @p) { + last if $p eq '--directdepsend--'; + push @p, $p; + } + @directdepsend = grep {!/^-/} splice(@directdepsend, @p + 1); + } @p = grep {!/^-/} @p; my %p; # expanded packages my %aconflicts; # packages we are conflicting with # add direct dependency packages. this is different from below, - # because we add packages even if to dep is already provided and + # because we add packages even if the dep is already provided and # we break ambiguities if the name is an exact match. for my $p (splice @p) { my @q = @{$whatprovides->{$p} || addproviders($config, $p)}; @@ -679,11 +886,21 @@ sub expand { push @p, $p; next; } + return (undef, "$q[0] $aconflicts{$q[0]}") if $aconflicts{$q[0]}; print "added $q[0] because of $p (direct dep)\n" if $expand_dbg; push @p, $q[0]; $p{$q[0]} = 1; - $aconflicts{$_} = 1 for @{$conflicts->{$q[0]} || []}; + $aconflicts{$_} = "conflict from project config with $q[0]" for @{$conflicts->{$q[0]} || []}; + if (!$ignoreconflicts) { + for my $r (@{$pkgconflicts->{$q[0]}}) { + $aconflicts{$_} = "conflicts with installed $q[0]" for @{$whatprovides->{$r} || addproviders($config, $r)}; + } + for my $r (@{$pkgobsoletes->{$q[0]}}) { + $aconflicts{$_} = "is obsoleted by installed $q[0]" for nevrmatch($config, $r, @{$whatprovides->{$r} || addproviders($config, $r)}); + } + } } + push @p, @directdepsend; my @pamb = (); my $doamb = 0; @@ -699,13 +916,24 @@ sub expand { next if grep {$p{$_}} @q; next if grep {$xignore{$_}} @q; next if grep {$ignore->{"$p:$_"} || $xignore{"$p:$_"}} @q; + my @eq = map {"provider $_ $aconflicts{$_}"} grep {$aconflicts{$_}} @q; @q = grep {!$aconflicts{$_}} @q; + if (!$ignoreconflicts) { + for my $q (splice @q) { + push @q, $q unless @{$pkgconflicts->{$q} || []} && checkconflicts($config, \%p, $q, \@eq, @{$pkgconflicts->{$q}}); + } + for my $q (splice @q) { + push @q, $q unless @{$pkgobsoletes->{$q} || []} && checkobsoletes($config, \%p, $q, \@eq, @{$pkgobsoletes->{$q}}); + } + } if (!@q) { + my $eq = @eq ? " (".join(', ', @eq).")" : ''; + my $msg = @eq ? 'conflict for providers of' : 'nothing provides'; if ($r eq $p) { - push @rerror, "nothing provides $r"; + push @rerror, "$msg $r$eq"; } else { - next if $r =~ /^\//; - push @rerror, "nothing provides $r needed by $p"; + next if $r =~ /^\// && !@eq; + push @rerror, "$msg $r needed by $p$eq"; } next; } @@ -748,7 +976,15 @@ sub expand { push @p, $q[0]; print "added $q[0] because of $p:$r\n" if $expand_dbg; $p{$q[0]} = 1; - $aconflicts{$_} = 1 for @{$conflicts->{$q[0]} || []}; + $aconflicts{$_} = "conflict from project config with $q[0]" for @{$conflicts->{$q[0]} || []}; + if (!$ignoreconflicts) { + for my $r (@{$pkgconflicts->{$q[0]}}) { + $aconflicts{$_} = "conflicts with installed $q[0]" for @{$whatprovides->{$r} || addproviders($config, $r)}; + } + for my $r (@{$pkgobsoletes->{$q[0]}}) { + $aconflicts{$_} = "is obsoleted by installed $q[0]" for nevrmatch($config, $r, @{$whatprovides->{$r} || addproviders($config, $r)}); + } + } @error = (); $doamb = 0; } @@ -883,6 +1119,16 @@ sub add_all_providers { ########################################################################### +sub recipe2buildtype { + my ($recipe) = @_; + return $1 if $recipe =~ /\.(spec|dsc|kiwi|livebuild)$/; + $recipe =~ s/.*\///; + $recipe =~ s/^_service:.*://; + return 'arch' if $recipe eq 'PKGBUILD'; + return 'preinstallimage' if $recipe eq '_preinstallimage'; + return undef; +} + sub show { my ($conffile, $fn, $field, $arch) = @ARGV; my $cf = read_config($arch, $conffile); @@ -908,8 +1154,25 @@ sub parse { return Build::Deb::parse($cf, $fn, @args) if $do_deb && $fn =~ /\.dsc$/; return Build::Kiwi::parse($cf, $fn, @args) if $do_kiwi && $fn =~ /config\.xml$/; return Build::Kiwi::parse($cf, $fn, @args) if $do_kiwi && $fn =~ /\.kiwi$/; - return Build::Arch::parse($cf, $fn, @args) if $do_arch && $fn =~ /(^|\/|-)PKGBUILD$/; - return parse_preinstallimage($cf, $fn, @args) if $fn =~ /(^|\/|-)_preinstallimage$/; + return Build::LiveBuild::parse($cf, $fn, @args) if $do_livebuild && $fn =~ /\.livebuild$/; + my $fnx = $fn; + $fnx =~ s/.*\///; + $fnx =~ s/^[0-9a-f]{32,}-//; # hack for OBS srcrep implementation + $fnx =~ s/^_service:.*://; + return Build::Arch::parse($cf, $fn, @args) if $do_arch && $fnx eq 'PKGBUILD'; + return parse_preinstallimage($cf, $fn, @args) if $fnx eq '_preinstallimage'; + return undef; +} + +sub parse_typed { + my ($cf, $fn, $buildtype, @args) = @_; + $buildtype ||= ''; + return Build::Rpm::parse($cf, $fn, @args) if $do_rpm && $buildtype eq 'spec'; + return Build::Deb::parse($cf, $fn, @args) if $do_deb && $buildtype eq 'dsc'; + return Build::Kiwi::parse($cf, $fn, @args) if $do_kiwi && $buildtype eq 'kiwi'; + return Build::LiveBuild::parse($cf, $fn, @args) if $do_livebuild && $buildtype eq 'livebuild'; + return Build::Arch::parse($cf, $fn, @args) if $do_arch && $buildtype eq 'arch'; + return parse_preinstallimage($cf, $fn, @args) if $buildtype eq 'preinstallimage'; return undef; } @@ -928,6 +1191,24 @@ sub query { return undef; } +sub showquery { + my ($fn, $field) = @ARGV; + my %opts; + $opts{'evra'} = 1 if grep {$_ eq $field} qw{epoch version release arch buildid}; + $opts{'weakdeps'} = 1 if grep {$_ eq $field} qw{suggests enhances recommends supplements}; + $opts{'conflicts'} = 1 if grep {$_ eq $field} qw{conflicts obsoletes}; + $opts{'description'} = 1 if grep {$_ eq $field} qw{summary description}; + $opts{'filelist'} = 1 if $field eq 'filelist'; + $opts{'buildtime'} = 1 if grep {$_ eq $field} qw{buildtime buildid}; + my $d = Build::query($fn, %opts); + die("cannot query $fn\n") unless $d; + $d->{'buildid'} = getbuildid($d); + my $x = $d->{$field}; + $x = [] unless defined $x; + $x = [ $x ] unless ref $x; + print "$_\n" for @$x; +} + sub queryhdrmd5 { my ($binname) = @_; return Build::Rpm::queryhdrmd5(@_) if $do_rpm && $binname =~ /\.rpm$/; @@ -940,4 +1221,12 @@ sub queryhdrmd5 { return undef; } +sub queryinstalled { + my ($binarytype, @args) = @_; + return Build::Rpm::queryinstalled(@args) if $binarytype eq 'rpm'; + return Build::Deb::queryinstalled(@args) if $binarytype eq 'deb'; + return Build::Arch::queryinstalled(@args) if $binarytype eq 'arch'; + return undef; +} + 1; diff --git a/Build/Arch.pm b/Build/Arch.pm index 8e561c3..e685a24 100644 --- a/Build/Arch.pm +++ b/Build/Arch.pm @@ -1,3 +1,23 @@ +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + package Build::Arch; use strict; @@ -55,7 +75,7 @@ sub parse { my $var = $1; my $val = $3; if ($2) { - while ($val !~ s/\)\s*$//s) { + while ($val !~ s/\)\s*(?:#.*)?$//s) { my $nextline = <PKG>; last unless defined $nextline; chomp $nextline; @@ -68,6 +88,7 @@ sub parse { $ret->{'name'} = $vars{'pkgname'}->[0] if $vars{'pkgname'}; $ret->{'version'} = $vars{'pkgver'}->[0] if $vars{'pkgver'}; $ret->{'deps'} = $vars{'makedepends'} || []; + push @{$ret->{'deps'}}, @{$vars{'checkdepends'} || []}; push @{$ret->{'deps'}}, @{$vars{'depends'} || []}; $ret->{'source'} = $vars{'source'} if $vars{'source'}; return $ret; @@ -147,7 +168,7 @@ sub query { $ret->{'hdrmd5'} = Digest::MD5::md5_hex($vars->{'_pkginfo'}); $ret->{'provides'} = $vars->{'provides'} || []; $ret->{'requires'} = $vars->{'depend'} || []; - if ($vars->{'pkgname'}) { + if ($vars->{'pkgname'} && $opts{'addselfprovides'}) { my $selfprovides = $vars->{'pkgname'}->[0]; $selfprovides .= "=$vars->{'pkgver'}->[0]" if $vars->{'pkgver'}; push @{$ret->{'provides'}}, $selfprovides unless @{$ret->{'provides'} || []} && $ret->{'provides'}->[-1] eq $selfprovides; @@ -170,9 +191,19 @@ sub query { if ($opts{'description'}) { $ret->{'description'} = $vars->{'pkgdesc'}->[0] if $vars->{'pkgdesc'}; } + if ($opts{'conflicts'}) { + $ret->{'conflicts'} = $vars->{'conflict'} if $vars->{'conflict'}; + $ret->{'obsoletes'} = $vars->{'replaces'} if $vars->{'replaces'}; + } + if ($opts{'weakdeps'}) { + my @suggests = @{$vars->{'optdepend'} || []}; + s/:.*// for @suggests; + $ret->{'suggests'} = \@suggests if @suggests; + } # arch packages don't seem to have a source :( # fake it so that the package isn't confused with a src package $ret->{'source'} = $ret->{'name'} if defined $ret->{'name'}; + $ret->{'buildtime'} = $vars->{'builddate'}->[0] if $opts{'buildtime'} && $vars->{'builddate'}; return $ret; } @@ -214,9 +245,42 @@ sub parserepodata { push @{$d->{'provides'}}, @p; } elsif ($p eq '%DEPENDS%') { push @{$d->{'requires'}}, @p; + } elsif ($p eq '%CONFLICTS%') { + push @{$d->{'conflicts'}}, @p; + } elsif ($p eq '%REPLACES%') { + push @{$d->{'obsoletes'}}, @p; } } return $d; } +sub queryinstalled { + my ($root, %opts) = @_; + + $root = '' if !defined($root) || $root eq '/'; + local *D; + local *F; + opendir(D, "$root/var/lib/pacman/local") || return []; + my @pn = sort(grep {!/^\./} readdir(D)); + closedir(D); + my @pkgs; + for my $pn (@pn) { + next unless open(F, '<', "$root/var/lib/pacman/local/$pn/desc"); + my $data = ''; + 1 while sysread(F, $data, 8192, length($data)); + close F; + my $d = parserepodata(undef, $data); + next unless defined $d->{'name'}; + my $q = {}; + for (qw{name arch buildtime version}) { + $q->{$_} = $d->{$_} if defined $d->{$_}; + } + $q->{'epoch'} = $1 if $q->{'version'} =~ s/^(\d+)://s; + $q->{'release'} = $1 if $q->{'version'} =~ s/-([^-]*)$//s; + push @pkgs, $q; + } + return \@pkgs; +} + + 1; diff --git a/Build/Archrepo.pm b/Build/Archrepo.pm new file mode 100644 index 0000000..b2b0ee4 --- /dev/null +++ b/Build/Archrepo.pm @@ -0,0 +1,75 @@ +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +package Build::Archrepo; + +use strict; +use Build::Arch; + +eval { require Archive::Tar; }; +*Archive::Tar::new = sub {die("Archive::Tar is not available\n")} unless defined &Archive::Tar::new; + +sub addpkg { + my ($res, $data, $options) = @_; + return unless defined $data->{'version'}; + if ($options->{'addselfprovides'}) { + my $selfprovides = $data->{'name'}; + $selfprovides .= "=$data->{'version'}" if defined $data->{'version'}; + push @{$data->{'provides'}}, $selfprovides unless @{$data->{'provides'} || []} && $data->{'provides'}->[-1] eq $selfprovides; + } + if (defined($data->{'version'})) { + # split version into evr + $data->{'epoch'} = $1 if $data->{'version'} =~ s/^(\d+)://s; + $data->{'release'} = $1 if $data->{'version'} =~ s/-([^-]*)$//s; + } + $data->{'location'} = delete($data->{'filename'}) if exists $data->{'filename'}; + if (ref($res) eq 'CODE') { + $res->($data); + } else { + push @$res, $data; + } +} + +sub parse { + my ($in, $res, %options) = @_; + $res ||= []; + die("Build::Archrepo::parse needs a filename\n") if ref($in); + die("$in: $!\n") unless -e $in; + my $repodb = Archive::Tar->iter($in, 1); + die("$in is not a tar archive\n") unless $repodb; + my $e; + my $lastfn = ''; + my $d; + while ($e = $repodb->()) { + next unless $e->type() == Archive::Tar::Constant::FILE; + my $fn = $e->name(); + next unless $fn =~ s/\/(?:depends|desc|files)$//s; + if ($lastfn ne $fn) { + addpkg($res, $d, \%options) if $d->{'name'}; + $d = {}; + $lastfn = $fn; + } + Build::Arch::parserepodata($d, $e->get_content()); + } + addpkg($res, $d, \%options) if $d->{'name'}; + return $res; +} + +1; diff --git a/Build/Deb.pm b/Build/Deb.pm index 3878fd4..f7c9958 100644 --- a/Build/Deb.pm +++ b/Build/Deb.pm @@ -1,3 +1,23 @@ +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + package Build::Deb; use strict; @@ -9,6 +29,31 @@ eval { $have_zlib = 1; }; +my %obs2debian = ( + "i486" => "i386", + "i586" => "i386", + "i686" => "i386", + "ppc" => "powerpc", + "ppc64le" => "ppc64el", + "x86_64" => "amd64", + "armv4l" => "armel", + "armv5l" => "armel", + "armv6l" => "armel", + "armv7l" => "armel", + "armv7hl" => "armhf" +); + +sub basearch { + my ($arch) = @_; + return 'all' if !defined($arch) || $arch eq 'noarch'; + return $obs2debian{$arch} || $arch; +} + +sub obsarch { + my ($arch) = @_; + return grep {$obs2debian{$_} eq $arch} sort keys %obs2debian; +} + sub parse { my ($bconf, $fn) = @_; my $ret; @@ -22,12 +67,7 @@ sub parse { } # map to debian names $os = 'linux' if !defined($os); - $arch = 'all' if !defined($arch) || $arch eq 'noarch'; - $arch = 'i386' if $arch =~ /^i[456]86$/; - $arch = 'powerpc' if $arch eq 'ppc'; - $arch = 'amd64' if $arch eq 'x86_64'; - $arch = 'armel' if $arch =~ /^armv[4567]l$/; - $arch = 'armhf' if $arch eq 'armv7hl'; + $arch = basearch($arch); if (ref($fn) eq 'ARRAY') { @control = @$fn; @@ -45,6 +85,7 @@ sub parse { my $name; my $version; my @deps; + my @exclarch; while (@control) { my $c = shift @control; last if $c eq ''; # new paragraph @@ -59,10 +100,18 @@ sub parse { if ($tag eq 'VERSION') { $version = $data; $version =~ s/-[^-]+$//; + } elsif ($tag eq 'ARCHITECTURE') { + my @archs = split('\s+', $data); + map { s/$os-//; s/any-// } @archs; + next if grep { $_ eq "any" || $_ eq "all" } @archs; + @exclarch = map { obsarch($_) } @archs; + # unify + my %exclarch = map {$_ => 1} @exclarch; + @exclarch = sort keys %exclarch; } elsif ($tag eq 'SOURCE') { $name = $data; } elsif ($tag eq 'BUILD-DEPENDS' || $tag eq 'BUILD-CONFLICTS' || $tag eq 'BUILD-IGNORE' || $tag eq 'BUILD-DEPENDS-INDEP') { - my @d = split(/,\s*/, $data); + my @d = split(/\s*,\s*/, $data); for my $d (@d) { my @alts = split('\s*\|\s*', $d); my @needed; @@ -75,11 +124,11 @@ sub parse { $isneg = 1 if $q =~ s/^\!//; $bad = 1 if !defined($bad) && !$isneg; if ($isneg) { - if ($q eq $arch || $q eq 'any' || $q eq "$os-$arch" || $q eq "$os-any") { + if ($q eq $arch || $q eq 'any' || $q eq "$os-$arch" || $q eq "$os-any" || $q eq "any-$arch") { $bad = 1; last; } - } elsif ($q eq $arch || $q eq 'any' || $q eq "$os-$arch" || $q eq "$os-any") { + } elsif ($q eq $arch || $q eq 'any' || $q eq "$os-$arch" || $q eq "$os-any" || $q eq "any-$arch") { $bad = 0; } } @@ -104,6 +153,7 @@ sub parse { $ret->{'name'} = $name; $ret->{'version'} = $version; $ret->{'deps'} = \@deps; + $ret->{'exclarch'} = \@exclarch if @exclarch; return $ret; } @@ -127,6 +177,26 @@ sub ungzip { return $data; } +sub control2res { + my ($control) = @_; + my %res; + my @control = split("\n", $control); + while (@control) { + my $c = shift @control; + last if $c eq ''; # new paragraph + my ($tag, $data) = split(':', $c, 2); + next unless defined $data; + $tag = uc($tag); + while (@control && $control[0] =~ /^\s/) { + $data .= "\n".substr(shift @control, 1); + } + $data =~ s/^\s+//s; + $data =~ s/\s+$//s; + $res{$tag} = $data; + } + return %res; +} + sub debq { my ($fn) = @_; @@ -202,21 +272,7 @@ sub debq { } $data = substr($data, $blen); } - my %res; - my @control = split("\n", $control); - while (@control) { - my $c = shift @control; - last if $c eq ''; # new paragraph - my ($tag, $data) = split(':', $c, 2); - next unless defined $data; - $tag = uc($tag); - while (@control && $control[0] =~ /^\s/) { - $data .= "\n".substr(shift @control, 1); - } - $data =~ s/^\s+//s; - $data =~ s/\s+$//s; - $res{$tag} = $data; - } + my %res = control2res($control); $res{'CONTROL_MD5'} = $controlmd5; return %res; } @@ -233,22 +289,27 @@ sub query { $src =~ s/\s.*$//; } my @provides = split(',\s*', $res{'PROVIDES'} || ''); - push @provides, "$name = $res{'VERSION'}"; + if ($opts{'addselfprovides'}) { + push @provides, "$name (= $res{'VERSION'})"; + } my @depends = split(',\s*', $res{'DEPENDS'} || ''); - my @predepends = split(',\s*', $res{'PRE-DEPENDS'} || ''); - push @depends, @predepends; - s/ \(([^\)]*)\)/ $1/g for @provides; - s/ \(([^\)]*)\)/ $1/g for @depends; - s/>>/>/g for @provides; - s/<</</g for @provides; - s/>>/>/g for @depends; - s/<</</g for @depends; + push @depends, split(',\s*', $res{'PRE-DEPENDS'} || ''); my $data = { name => $name, hdrmd5 => $res{'CONTROL_MD5'}, provides => \@provides, requires => \@depends, }; + if ($opts{'conflicts'}) { + my @conflicts = split(',\s*', $res{'CONFLICTS'} || ''); + push @conflicts, split(',\s*', $res{'BREAKS'} || ''); + $data->{'conflicts'} = \@conflicts if @conflicts; + } + if ($opts{'weakdeps'}) { + for my $dep ('SUGGESTS', 'RECOMMENDS', 'ENHANCES') { + $data->{lc($dep)} = [ split(',\s*', $res{$dep} || '') ] if defined $res{$dep}; + } + } $data->{'source'} = $src if $src ne ''; if ($opts{'evra'}) { $res{'VERSION'} =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s; @@ -260,6 +321,16 @@ sub query { if ($opts{'description'}) { $data->{'description'} = $res{'DESCRIPTION'}; } + if ($opts{'normalizedeps'}) { + for my $dep (qw{provides requires conflicts suggests enhances recommends}) { + next unless $data->{$dep}; + for (@{$data->{$dep}}) { + s/ \(([^\)]*)\)/ $1/g; + s/<</</g; + s/>>/>/g; + } + } + } return $data; } @@ -340,4 +411,34 @@ sub verscmp { return verscmp_part($r1, $r2); } +sub queryinstalled { + my ($root, %opts) = @_; + + $root = '' if !defined($root) || $root eq '/'; + my @pkgs; + local *F; + if (open(F, '<', "$root/var/lib/dpkg/status")) { + my $ctrl = ''; + while(<F>) { + if ($_ eq "\n") { + my %res = control2res($ctrl); + if (defined($res{'PACKAGE'})) { + my $data = {'name' => $res{'PACKAGE'}}; + $res{'VERSION'} =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s; + $data->{'epoch'} = $1 if defined $1; + $data->{'version'} = $2; + $data->{'release'} = $3 if defined $3; + $data->{'arch'} = $res{'ARCHITECTURE'}; + push @pkgs, $data; + } + $ctrl = ''; + next; + } + $ctrl .= $_; + } + close F; + } + return \@pkgs; +} + 1; diff --git a/Build/Debrepo.pm b/Build/Debrepo.pm new file mode 100644 index 0000000..2f30dfd --- /dev/null +++ b/Build/Debrepo.pm @@ -0,0 +1,116 @@ +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +package Build::Debrepo; + +use strict; + +sub addpkg { + my ($res, $data, $options) = @_; + return unless defined $data->{'version'}; + my $selfprovides; + $selfprovides = "= $data->{'version'}" if $options->{'addselfprovides'}; + # split version into evr + $data->{'epoch'} = $1 if $data->{'version'} =~ s/^(\d+)://s; + $data->{'release'} = $1 if $data->{'version'} =~ s/-([^-]*)$//s; + for my $d (qw{provides requires conflicts recommends suggests enhances breaks prerequires}) { + next unless $data->{$d}; + if ($options->{'normalizedeps'}) { + $data->{$d} =~ s/\(([^\)]*)\)/$1/g; + $data->{$d} =~ s/<</</g; + $data->{$d} =~ s/>>/>/g; + } + $data->{$d} = [ split(/\s*,\s*/, $data->{$d}) ]; + } + push @{$data->{'requires'}}, @{$data->{'prerequires'}} if $data->{'prerequires'}; + delete $data->{'prerequires'}; + push @{$data->{'conflicts'}}, @{$data->{'breaks'}} if $data->{'breaks'}; + delete $data->{'breaks'}; + if (defined($selfprovides)) { + $selfprovides = "($selfprovides)" unless $options->{'normalizedeps'}; + $selfprovides = "$data->{'name'} $selfprovides"; + push @{$data->{'provides'}}, $selfprovides unless @{$data->{'provides'} || []} && $data->{'provides'}->[-1] eq $selfprovides; + } + if (ref($res) eq 'CODE') { + $res->($data); + } else { + push @$res, $data; + } +} + +my %tmap = ( + 'package' => 'name', + 'version' => 'version', + 'architecture' => 'arch', + 'provides' => 'provides', + 'depends' => 'requires', + 'pre-depends' => 'prerequires', + 'conflicts' => 'conflicts', + 'breaks' => 'breaks', + 'recommends' => 'recommends', + 'suggests' => 'suggests', + 'enhances' => 'enhances', + 'filename' => 'location', + 'source' => 'source', +); + +sub parse { + my ($in, $res, %options) = @_; + $res ||= []; + my $fd; + if (ref($in)) { + $fd = $in; + } else { + if ($in =~ /\.gz$/) { + open($fd, '-|', "gzip", "-dc", $in) || die("$in: $!\n"); + } else { + open($fd, '<', $in) || die("$in: $!\n"); + } + } + my $pkg = {}; + my $tag; + while (<$fd>) { + chomp; + if ($_ eq '') { + addpkg($res, $pkg, \%options) if %$pkg; + $pkg = {}; + next; + } + if (/^\s/) { + next unless $tag; + $pkg->{$tag} .= "\n".substr($_, 1); + next; + } + my $data; + ($tag, $data) = split(':', $_, 2); + next unless defined $data; + $tag = $tmap{lc($tag)}; + next unless $tag; + $data =~ s/^\s*//; + $pkg->{$tag} = $data; + } + addpkg($res, $pkg, \%options) if %$pkg; + if (!ref($in)) { + close($fd) || die("close $in: $!\n"); + } + return $res; +} + +1; diff --git a/Build/Kiwi.pm b/Build/Kiwi.pm index f976029..5d730d7 100644 --- a/Build/Kiwi.pm +++ b/Build/Kiwi.pm @@ -1,3 +1,23 @@ +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + package Build::Kiwi; use strict; @@ -188,6 +208,7 @@ sub kiwiparse { if ($instsource->{'productoptions'}) { my $productoptions = $instsource->{'productoptions'}->[0] || {}; for my $po (@{$productoptions->{'productvar'} || []}) { + $ret->{'drop_repository'} = $po->{'_content'} if $po->{'name'} eq 'DROP_REPOSITORY'; $ret->{'version'} = $po->{'_content'} if $po->{'name'} eq 'VERSION'; } for my $po (@{$productoptions->{'productoption'} || []}) { diff --git a/Build/LiveBuild.pm b/Build/LiveBuild.pm new file mode 100644 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/Repo.pm b/Build/Repo.pm new file mode 100644 index 0000000..7cd495f --- /dev/null +++ b/Build/Repo.pm @@ -0,0 +1,61 @@ +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +package Build::Repo; + +use strict; + +our $do_rpmmd; +our $do_deb; +our $do_arch; +our $do_susetags; + +sub import { + for (@_) { + $do_rpmmd = 1 if $_ eq ':rpmmd'; + $do_deb = 1 if $_ eq ':deb'; + $do_arch = 1 if $_ eq ':arch'; + $do_susetags = 1 if $_ eq ':susetags'; + } + $do_rpmmd = $do_deb = $do_arch = $do_susetags = 1 unless $do_rpmmd || $do_deb || $do_arch || $do_susetags; + if ($do_rpmmd) { + require Build::Rpmmd; + } + if ($do_susetags) { + require Build::Susetags; + } + if ($do_deb) { + require Build::Debrepo; + } + if ($do_arch) { + require Build::Archrepo; + } +} + +sub parse { + my ($type, @args) = @_; + return Build::Rpmmd::parse(@args) if $do_rpmmd && $type eq 'rpmmd'; + return Build::Susetags::parse(@args) if $do_susetags && $type eq 'susetags'; + return Build::Debrepo::parse(@args) if $do_deb && $type eq 'deb'; + return Build::Archrepo::parse(@args) if $do_arch && $type eq 'arch'; + die("parse repo: unknown type '$type'\n"); +} + +1; diff --git a/Build/Rpm.pm b/Build/Rpm.pm index e6a1815..d9c6028 100644 --- a/Build/Rpm.pm +++ b/Build/Rpm.pm @@ -1,3 +1,23 @@ +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + package Build::Rpm; our $unfilteredprereqs = 0; @@ -108,6 +128,9 @@ sub expr { ($v2, $expr) = expr(substr($expr, 1), 4); return undef unless defined $v2 && 0 + $v2; $v /= $v2; + } elsif ($expr =~ /^([=&|])/) { + warn("syntax error while parsing $1$1\n"); + return ($v, $expr); } else { return ($v, $expr); } @@ -130,7 +153,8 @@ sub grabargs { my %m; $m{'0'} = $macname; $m{'**'} = join(' ', @args); - my %go = (split(/(:?)/, $getopt, -1), undef); + my %go; + %go = ($getopt =~ /(.)(:*)/sg) if defined $getopt; while (@args && $args[0] =~ s/^-//) { my $o = shift @args; last if $o eq '-'; @@ -341,17 +365,27 @@ reexpand: $line = $2; } push @expandstack, ($expandedline, $line, $optmacros); - $optmacros = adaptmacros(\%macros, $optmacros, grabargs($macname, $macros_args{$macname}, split(/ /, $macdata))); + $optmacros = adaptmacros(\%macros, $optmacros, grabargs($macname, $macros_args{$macname}, split(' ', $macdata))); $line = $macros{$macname}; $expandedline = ''; next; } $macalt = $macros{$macname} unless defined $macalt; $macalt = '' if $mactest == -1; - $line = "$macalt$line"; + if ($macalt =~ /%/) { + push @expandstack, ('', $line, 1) if $line ne ''; + $line = $macalt; + } else { + $expandedline .= $macalt; + } } elsif ($mactest) { $macalt = '' if !defined($macalt) || $mactest == 1; - $line = "$macalt$line"; + if ($macalt =~ /%/) { + push @expandstack, ('', $line, 1) if $line ne ''; + $line = $macalt; + } else { + $expandedline .= $macalt; + } } else { $expandedline .= "%$macorig" unless $macname =~ /^-/; } @@ -360,12 +394,15 @@ reexpand: if (@expandstack) { my $m = pop(@expandstack); if ($m) { - $optmacros = adaptmacros(\%macros, $optmacros, $m); + $optmacros = adaptmacros(\%macros, $optmacros, $m) if ref $m; $expandstack[-2] .= $line; - $line = ''; + $line = pop(@expandstack); + $expandedline = pop(@expandstack); + } else { + my $todo = pop(@expandstack); + $expandedline = pop(@expandstack); + push @expandstack, ('', $todo, 1) if $todo ne ''; } - $line = $line . pop(@expandstack); - $expandedline = pop(@expandstack); goto reexpand; } } @@ -565,6 +602,7 @@ my %rpmstag = ( "EPOCH" => 1003, "SUMMARY" => 1004, "DESCRIPTION" => 1005, + "BUILDTIME" => 1006, "ARCH" => 1022, "OLDFILENAMES" => 1027, "SOURCERPM" => 1044, @@ -580,6 +618,31 @@ my %rpmstag = ( "DIRINDEXES" => 1116, "BASENAMES" => 1117, "DIRNAMES" => 1118, + "DISTURL" => 1123, + "CONFLICTFLAGS" => 1053, + "CONFLICTNAME" => 1054, + "CONFLICTVERSION" => 1055, + "OBSOLETENAME" => 1090, + "OBSOLETEFLAGS" => 1114, + "OBSOLETEVERSION" => 1115, + "OLDSUGGESTSNAME" => 1156, + "OLDSUGGESTSVERSION" => 1157, + "OLDSUGGESTSFLAGS" => 1158, + "OLDENHANCESNAME" => 1159, + "OLDENHANCESVERSION" => 1160, + "OLDENHANCESFLAGS" => 1161, + "RECOMMENDNAME" => 5046, + "RECOMMENDVERSION" => 5047, + "RECOMMENDFLAGS" => 5048, + "SUGGESTNAME" => 5049, + "SUGGESTVERSION" => 5050, + "SUGGESTFLAGS" => 5051, + "SUPPLEMENTNAME" => 5052, + "SUPPLEMENTVERSION" => 5053, + "SUPPLEMENTFLAGS" => 5054, + "ENHANCENAME" => 5055, + "ENHANCEVERSION" => 5056, + "ENHANCEFLAGS" => 5057, ); sub rpmq { @@ -744,12 +807,9 @@ sub rpmq { } sub add_flagsvers { - my $res = shift; - my $name = shift; - my $flags = shift; - my $vers = shift; + my ($res, $name, $flags, $vers) = @_; - return unless $res; + return unless $res && $res->{$name}; my @flags = @{$res->{$flags} || []}; my @vers = @{$res->{$vers} || []}; for (@{$res->{$name}}) { @@ -765,6 +825,25 @@ sub add_flagsvers { } } +sub filteroldweak { + my ($res, $name, $flags, $data, $strong, $weak) = @_; + + return unless $res && $res->{$name}; + my @flags = @{$res->{$flags} || []}; + my @strong; + my @weak; + for (@{$res->{$name}}) { + if (@flags && ($flags[0] & 0x8000000)) { + push @strong, $_; + } else { + push @weak, $_; + } + shift @flags; + } + $data->{$strong} = \@strong if @strong; + $data->{$weak} = \@weak if @weak; +} + sub verscmp_part { my ($s1, $s2) = @_; if (!defined($s1)) { @@ -842,6 +921,11 @@ sub query { push @tags, qw{EPOCH VERSION RELEASE ARCH}; push @tags, qw{FILENAMES} if $opts{'filelist'}; push @tags, qw{SUMMARY DESCRIPTION} if $opts{'description'}; + push @tags, qw{DISTURL} if $opts{'disturl'}; + push @tags, qw{BUILDTIME} if $opts{'buildtime'}; + push @tags, qw{CONFLICTNAME CONFLICTVERSION CONFLICTFLAGS OBSOLETENAME OBSOLETEVERSION OBSOLETEFLAGS} if $opts{'conflicts'}; + push @tags, qw{RECOMMENDNAME RECOMMENDVERSION RECOMMENDFLAGS SUGGESTNAME SUGGESTVERSION SUGGESTFLAGS SUPPLEMENTNAME SUPPLEMENTVERSION SUPPLEMENTFLAGS ENHANCENAME ENHANCEVERSION ENHANCEFLAGS OLDSUGGESTSNAME OLDSUGGESTSVERSION OLDSUGGESTSFLAGS OLDENHANCESNAME OLDENHANCESVERSION OLDENHANCESFLAGS} if $opts{'weakdeps'}; + my %res = rpmq($handle, @tags); return undef unless %res; my $src = $res{'SOURCERPM'}->[0]; @@ -860,6 +944,27 @@ sub query { $data->{'provides'} = [ grep {!/^rpmlib\(/ && !/^\//} @{$res{'PROVIDENAME'} || []} ]; $data->{'requires'} = [ grep {!/^rpmlib\(/ && !/^\//} @{$res{'REQUIRENAME'} || []} ]; } + if ($opts{'conflicts'}) { + add_flagsvers(\%res, 'CONFLICTNAME', 'CONFLICTFLAGS', 'CONFLICTVERSION'); + add_flagsvers(\%res, 'OBSOLETENAME', 'OBSOLETEFLAGS', 'OBSOLETEVERSION'); + $data->{'conflicts'} = [ @{$res{'CONFLICTNAME'}} ] if $res{'CONFLICTNAME'}; + $data->{'obsoletes'} = [ @{$res{'OBSOLETENAME'}} ] if $res{'OBSOLETENAME'}; + } + if ($opts{'weakdeps'}) { + for (qw{RECOMMEND SUGGEST SUPPLEMENT ENHANCE}) { + next unless $res{"${_}NAME"}; + add_flagsvers(\%res, "${_}NAME", "${_}FLAGS", "${_}VERSION"); + $data->{lc($_)."s"} = [ @{$res{"${_}NAME"}} ]; + } + if ($res{'OLDSUGGESTSNAME'}) { + add_flagsvers(\%res, 'OLDSUGGESTSNAME', 'OLDSUGGESTSFLAGS', 'OLDSUGGESTSVERSION'); + filteroldweak(\%res, 'OLDSUGGESTSNAME', 'OLDSUGGESTSFLAGS', $data, 'recommends', 'suggests'); + } + if ($res{'OLDENHANCESNAME'}) { + add_flagsvers(\%res, 'OLDENHANCESNAME', 'OLDENHANCESFLAGS', 'OLDENHANCESVERSION'); + filteroldweak(\%res, 'OLDENHANCESNAME', 'OLDENHANCESFLAGS', $data, 'supplements', 'enhances'); + } + } # rpm3 compatibility: retrofit missing self provides if ($src ne '') { @@ -894,6 +999,8 @@ sub query { $data->{'summary'} = $res{'SUMMARY'}->[0]; $data->{'description'} = $res{'DESCRIPTION'}->[0]; } + $data->{'buildtime'} = $res{'BUILDTIME'}->[0] if $opts{'buildtime'}; + $data->{'disturl'} = $res{'DISTURL'}->[0] if $opts{'disturl'} && $res{'DISTURL'}; return $data; } @@ -950,4 +1057,48 @@ sub queryhdrmd5 { return unpack("\@${md5off}H32", $buf); } +sub queryinstalled { + my ($root, %opts) = @_; + + $root = '' if !defined($root) || $root eq '/'; + local *F; + my $dochroot = $root ne '' && !$opts{'nochroot'} && !$< ? 1 : 0; + my $pid = open(F, '-|'); + die("fork: $!\n") unless defined $pid; + if (!$pid) { + if ($dochroot && chroot($root)) { + chdir('/') || die("chdir: $!\n"); + $root = ''; + } + my @args; + unshift @args, '--nodigest', '--nosignature' if -e "$root/usr/bin/rpmquery "; + unshift @args, '--dbpath', "$root/var/lib/rpm" if $root ne ''; + push @args, '--qf', '%{NAME}/%{ARCH}/%|EPOCH?{%{EPOCH}}:{0}|/%{VERSION}/%{RELEASE}/%{BUILDTIME}\n'; + if (-x "$root/usr/bin/rpm") { + exec("$root/usr/bin/rpm", '-qa', @args); + die("$root/usr/bin/rpm: $!\n"); + } + if (-x "$root/bin/rpm") { + exec("$root/bin/rpm", '-qa', @args); + die("$root/bin/rpm: $!\n"); + } + die("rpm: command not found\n"); + } + my @pkgs; + while (<F>) { + chomp; + my @s = split('/', $_); + next unless @s >= 5; + my $q = {'name' => $s[0], 'arch' => $s[1], 'version' => $s[3], 'release' => $s[4]}; + $q->{'epoch'} = $s[2] if $s[2]; + $q->{'buildtime'} = $s[5] if $s[5]; + push @pkgs, $q; + } + if (!close(F)) { + return queryinstalled($root, %opts, 'nochroot' => 1) if !@pkgs && $dochroot; + die("rpm: exit status $?\n"); + } + return \@pkgs; +} + 1; diff --git a/Build/Rpmmd.pm b/Build/Rpmmd.pm new file mode 100644 index 0000000..de5cfb6 --- /dev/null +++ b/Build/Rpmmd.pm @@ -0,0 +1,205 @@ +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +package Build::Rpmmd; + +use strict; + +use XML::Parser; + +sub generic_parse { + my ($how, $in, $res, %options) = @_; + $res ||= []; + my @cursor = ([undef, $how, undef, $res, undef, \%options]); + my $p = new XML::Parser(Handlers => { + Start => sub { + my ($p, $el) = @_; + my $h = $cursor[-1]->[1]; + return unless exists $h->{$el}; + $h = $h->{$el}; + push @cursor, [$el, $h]; + $cursor[-1]->[2] = '' if $h->{'_text'}; + $h->{'_start'}->($h, \@cursor, @_) if exists $h->{'_start'}; + }, + End => sub { + my ($p, $el) = @_; + if ($cursor[-1]->[0] eq $el) { + my $h = $cursor[-1]->[1]; + $h->{'_end'}->($h, \@cursor, @_) if exists $h->{'_end'}; + pop @cursor; + } + }, + Char => sub { + my ($p, $text) = @_; + $cursor[-1]->[2] .= $text if defined $cursor[-1]->[2]; + }, + }, ErrorContext => 2); + if (ref($in)) { + $p->parse($in); + } else { + $p->parsefile($in); + } + return $res; +} + +sub generic_store_text { + my ($h, $c, $p, $el) = @_; + my $data = $c->[0]->[4]; + $data->{$h->{'_tag'}} = $c->[-1]->[2] if defined $c->[-1]->[2]; +} + +sub generic_store_attr { + my ($h, $c, $p, $el, %attr) = @_; + my $data = $c->[0]->[4]; + $data->{$h->{'_tag'}} = $attr{$h->{'_attr'}} if defined $attr{$h->{'_attr'}}; +} + +sub generic_new_data { + my ($h, $c, $p, $el, %attr) = @_; + $c->[0]->[4] = {}; + generic_store_attr(@_) if $h->{'_attr'}; +} + +sub generic_add_result { + my ($h, $c, $p, $el) = @_; + my $data = $c->[0]->[4]; + return unless $data; + my $res = $c->[0]->[3]; + if (ref($res) eq 'CODE') { + $res->($data); + } else { + push @$res, $data; + } + undef $c->[0]->[4]; +} + +my $repomdparser = { + repomd => { + data => { + _start => \&generic_new_data, + _attr => 'type', + _tag => 'type', + _end => \&generic_add_result, + location => { _start => \&generic_store_attr, _attr => 'href', _tag => 'location'}, + size => { _text => 1, _end => \&generic_store_text, _tag => 'size'}, + }, + }, +}; + +my $primaryparser = { + metadata => { + 'package' => { + _start => \&generic_new_data, + _attr => 'type', + _tag => 'type', + _end => \&primary_add_result, + name => { _text => 1, _end => \&generic_store_text, _tag => 'name' }, + arch => { _text => 1, _end => \&generic_store_text, _tag => 'arch' }, + version => { _start => \&primary_handle_version }, + 'time' => { _start => \&primary_handle_time }, + format => { + 'rpm:provides' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'provides' }, }, + 'rpm:requires' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'requires' }, }, + 'rpm:conflicts' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'conflicts' }, }, + 'rpm:recommends' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'recommends' }, }, + 'rpm:suggests' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'suggests' }, }, + 'rpm:supplements' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'supplements' }, }, + 'rpm:enhances' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'enhances' }, }, + 'rpm:obsoletes' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'obsoletes' }, }, + 'rpm:buildhost' => { _text => 1, _end => \&generic_store_text, _tag => 'buildhost' }, + 'rpm:sourcerpm' => { _text => 1, _end => \&primary_handle_sourcerpm , _tag => 'source' }, +### currently commented out, as we ignore file provides in expanddeps +# file => { _text => 1, _end => \&primary_handle_file_end, _tag => 'provides' }, + }, + location => { _start => \&generic_store_attr, _attr => 'href', _tag => 'location'}, + }, + }, +}; + +sub primary_handle_sourcerpm { + my ($h, $c, $p, $el, %attr) = @_; + my $data = $c->[0]->[4]; + return unless defined $c->[-1]->[2]; + $c->[-1]->[2] =~ s/-[^-]*-[^-]*\.[^\.]*\.rpm$//; + $data->{$h->{'_tag'}} = $c->[-1]->[2]; +} + +sub primary_handle_version { + my ($h, $c, $p, $el, %attr) = @_; + my $data = $c->[0]->[4]; + $data->{'epoch'} = $attr{'epoch'} if $attr{'epoch'}; + $data->{'version'} = $attr{'ver'}; + $data->{'release'} = $attr{'rel'}; +} + +sub primary_handle_time { + my ($h, $c, $p, $el, %attr) = @_; + my $data = $c->[0]->[4]; + $data->{'filetime'} = $attr{'file'} if $attr{'file'}; + $data->{'buildtime'} = $attr{'build'} if $attr{'build'}; +} + +sub primary_handle_file_end { + my ($h, $c, $p, $el) = @_; + primary_handle_dep($h, $c, $p, $el, 'name', $c->[-1]->[2]); +} + +my %flagmap = ( EQ => '=', LE => '<=', GE => '>=', GT => '>', LT => '<', NE => '!=' ); + +sub primary_handle_dep { + my ($h, $c, $p, $el, %attr) = @_; + my $dep = $attr{'name'}; + return if $dep =~ /^rpmlib\(/; + if(exists $attr{'flags'}) { + my $evr = $attr{'ver'}; + return unless defined($evr) && exists($flagmap{$attr{'flags'}}); + $evr = "$attr{'epoch'}:$evr" if $attr{'epoch'}; + $evr .= "-$attr{'rel'}" if defined $attr{'rel'}; + $dep .= " $flagmap{$attr{'flags'}} $evr"; + } + my $data = $c->[0]->[4]; + push @{$data->{$h->{'_tag'}}}, $dep; +} + +sub primary_add_result { + my ($h, $c, $p, $el) = @_; + my $options = $c->[0]->[5] || {}; + my $data = $c->[0]->[4]; + if ($options->{'addselfprovides'} && defined($data->{'name'}) && defined($data->{'version'})) { + if (($data->{'arch'} || '') ne 'src' && ($data->{'arch'} || '') ne 'nosrc') { + my $evr = $data->{'version'}; + $evr = "$data->{'epoch'}:$evr" if $data->{'epoch'}; + $evr = "$evr-$data->{'release'}" if defined $data->{'release'}; + my $s = "$data->{'name'} = $evr"; + push @{$data->{'provides'}}, $s unless grep {$_ eq $s} @{$data->{'provides'} || []}; + } + } + return generic_add_result(@_); +} + +sub parse_repomd { + return generic_parse($repomdparser, @_); +} + +sub parse { + return generic_parse($primaryparser, @_); +} + +1; diff --git a/Build/Susetags.pm b/Build/Susetags.pm index cd0a103..c1836de 100644 --- a/Build/Susetags.pm +++ b/Build/Susetags.pm @@ -1,66 +1,128 @@ +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + package Build::Susetags; use strict; -use warnings; -use Data::Dumper; + +# compatibility to old OBS code +sub parse_obs_compat { + my ($file, undef, undef, @arches) = @_; + $file = "$file.gz" if ! -e $file && -e "$file.gz"; + my $pkgs = {}; + parse($file, sub { + my ($data) = @_; + my $medium = delete($data->{'medium'}); + my $loc = delete($data->{'location'}); + if (defined($medium) && defined($loc)) { + $loc =~ s/^\Q$data->{'arch'}\E\///; + $data->{'path'} = "$medium $loc"; + } + return unless !@arches || grep { /$data->{'arch'}/ } @arches; + $pkgs->{"$data->{'name'}-$data->{'version'}-$data->{'release'}-$data->{'arch'}"} = $data; + }, 'addselfprovides' => 1); + return $pkgs; +} + +my %tmap = ( + 'Pkg' => '', + 'Loc' => 'location', + 'Src' => 'source', + 'Prv' => 'provides', + 'Req' => 'requires', + 'Con' => 'conflicts', + 'Obs' => 'obsoletes', + 'Rec' => 'recommends', + 'Sug' => 'suggests', + 'Sup' => 'supplements', + 'Enh' => 'enhances', + 'Tim' => 'buildtime', +); sub addpkg { - my ($pkgs, $cur, $order, $cb, $cbdata, @arches) = @_; - if (defined($cur) && (!@arches || grep { /$cur->{'arch'}/ } @arches)) { - if(!$cb || &$cb($cur, $cbdata)) { - my $k = "$cur->{'name'}-$cur->{'version'}-$cur->{'release'}-$cur->{'arch'}"; - $pkgs->{$k} = $cur; - # keep order (or should we use Tie::IxHash?) - push @{$order}, $k if defined $order; + my ($res, $data, $options) = @_; + # fixup location and source + if (exists($data->{'location'})) { + my ($medium, $dir, $loc) = split(' ', $data->{'location'}, 3); + $data->{'medium'} = $medium; + $data->{'location'} = defined($loc) ? "$dir/$loc" : "$data->{'arch'}/$dir"; + } + $data->{'source'} =~ s/\s.*// if exists $data->{'source'}; + if ($options->{'addselfprovides'} && defined($data->{'name'}) && defined($data->{'version'})) { + if (($data->{'arch'} || '') ne 'src' && ($data->{'arch'} || '') ne 'nosrc') { + my $evr = $data->{'version'}; + $evr = "$data->{'epoch'}:$evr" if $data->{'epoch'}; + $evr = "$evr-$data->{'release'}" if defined $data->{'release'}; + my $s = "$data->{'name'} = $evr"; + push @{$data->{'provides'}}, $s unless grep {$_ eq $s} @{$data->{'provides'} || []}; } } + if (ref($res) eq 'CODE') { + $res->($data); + } else { + push @$res, $data; + } } sub parse { - # if @arches is empty take all arches - my ($file, $tmap, $order, @arches) = @_; - my $cb; - my $cbdata; - if (ref $order eq 'HASH') { - my $d = $order; - $order = undef; - $cb = $d->{'cb'} if (exists $d->{'cb'}); - $cbdata = $d->{'data'} if (exists $d->{'data'}); - } - - # if @arches is empty take all arches - my @needed = keys %$tmap; - my $r = '(' . join('|', @needed) . '|Pkg):\s*(.*)'; - - if (!open(F, '<', $file)) { - if (!open(F, '-|', "gzip", "-dc", $file.'.gz')) { - die "$file: $!"; + return parse_obs_compat(@_) if @_ > 2 && !defined $_[2]; + my ($in, $res, %options) = @_; + $res ||= []; + my $fd; + if (ref($in)) { + $fd = $in; + } else { + if ($in =~ /\.gz$/) { + open($fd, '-|', "gzip", "-dc", $in) || die("$in: $!\n"); + } else { + open($fd, '<', $in) || die("$in: $!\n"); } } - my $cur; - my $pkgs = {}; - while (<F>) { + my $r = join('|', sort keys %tmap); + $r = qr/^([\+=])($r):\s*(.*)/; + while (<$fd>) { chomp; - next unless $_ =~ /([\+=])$r/; + next unless /$r/; my ($multi, $tag, $data) = ($1, $2, $3); if ($multi eq '+') { - while (<F>) { + while (<$fd>) { chomp; - last if $_ =~ /-$tag/; - push @{$cur->{$tmap->{$tag}}}, $_; + last if /^-\Q$tag\E/; + next if $tag eq 'Req' && /^rpmlib\(/; + push @{$cur->{$tmap{$tag}}}, $_; } } elsif ($tag eq 'Pkg') { - addpkg($pkgs, $cur, $order, $cb, $cbdata, @arches); + addpkg($res, $cur, \%options) if $cur; $cur = {}; ($cur->{'name'}, $cur->{'version'}, $cur->{'release'}, $cur->{'arch'}) = split(' ', $data); + $cur->{'epoch'} = $1 if $cur->{'version'} =~ s/^(\d+)://; } else { - $cur->{$tmap->{$tag}} = $data; + $cur->{$tmap{$tag}} = $data; } } - addpkg($pkgs, $cur, $order, $cb, $cbdata, @arches); - close(F); - return $pkgs; + addpkg($res, $cur, \%options) if $cur; + if (!ref($in)) { + close($fd) || die("close $in: $!\n"); + } + return $res; } - + 1; diff --git a/Build/Zypp.pm b/Build/Zypp.pm index 354adca..8ec554b 100644 --- a/Build/Zypp.pm +++ b/Build/Zypp.pm @@ -1,33 +1,94 @@ +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + package Build::Zypp; use strict; our $root = ''; -sub parsecfg($) -{ - my $file = shift; - my $repocfg = "$root/etc/zypp/repos.d/$file.repo"; +sub parsecfg { + my ($repocfg, $reponame, $allrepos) = @_; + local *REPO; - open(REPO, '<', $repocfg) or return undef; + open(REPO, '<', "$root/etc/zypp/repos.d/$repocfg") or return undef; my $name; my $repo = {}; while (<REPO>) { chomp; + next if /^\s*#/; + s/\s+$//; if (/^\[(.+)\]/) { - $name = $1; - } else { - my ($key, $value) = split(/=/,$_,2); + if ($allrepos && defined($name)) { + $repo->{'description'} = $repo->{'name'} if defined $repo->{'name'}; + $repo->{'name'} = $name; + push @$allrepos, $repo; + undef $name; + $repo = {}; + } + last if defined $name; + $name = $1 if !defined($reponame) || $reponame eq $1; + } elsif (defined($name)) { + my ($key, $value) = split(/=/, $_, 2); $repo->{$key} = $value if defined $key; } } close(REPO); - return undef unless $name; - $repo->{'description'} = $repo->{'name'} if exists $repo->{'name'}; + return undef unless defined $name; + $repo->{'description'} = $repo->{'name'} if defined $repo->{'name'}; $repo->{'name'} = $name; + push @$allrepos, $repo if $allrepos; return $repo; } +sub repofiles { + local *D; + return () unless opendir(D, "/etc/zypp/repos.d"); + my @r = grep {!/^\./ && /.repo$/} readdir(D); + closedir D; + return sort(@r); +} + +sub parseallrepos { + my @r; + for my $r (repofiles()) { + parsecfg($r, undef, \@r); + } + return @r; +} + +sub parserepo($) { + my ($reponame) = @_; + # first try matching .repo file + if (-e "$root/etc/zypp/repos.d/$reponame.repo") { + my $repo = parsecfg("$reponame.repo", $reponame); + return $repo if $repo; + } + # then try all repo files + for my $r (repofiles()) { + my $repo = parsecfg($r, $reponame); + return $repo if $repo; + } + die("could not find repo '$reponame'\n"); +} + 1; # vim: sw=2 @@ -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. @@ -3,7 +3,7 @@ SCM=$(shell if test -d .svn; then echo svn; elif test -d .git; then echo git; fi DATE=$(shell date +%Y%m%d%H%M) BUILD=build -INITVM_ARCH=$(shell bash detect_architecture.sh) +INITVM_ARCH=$(shell bash -c '. common_functions ; build_host_arch; echo $$BUILD_INITVM_ARCH') ifeq ($(SCM),svn) SVNVER=_SVN$(shell LANG=C svnversion .) @@ -30,29 +30,27 @@ install: $(DESTDIR)$(man1dir) install -m755 \ build \ - build_kiwi.sh \ vc \ - createrpmdeps \ + createdirdeps \ order \ expanddeps \ computeblocklists \ extractbuild \ getbinaryid \ killchroot \ - getmacros \ - getoptflags \ - gettype \ - getchangetarget \ + queryconfig \ common_functions \ init_buildsystem \ - initscript_qemu_vm \ substitutedeps \ debtransform \ debtransformbz2 \ debtransformzip \ mkbaselibs \ mkdrpms \ + listinstalled \ + createzyppdeps \ createarchdeps \ + createdebdeps \ createrepomddeps \ createyastdeps \ changelog2spec \ @@ -62,14 +60,18 @@ install: spectool \ signdummy \ unrpm \ - zvm_functions \ $(DESTDIR)$(pkglibdir) install -m755 emulator/emulator.sh $(DESTDIR)$(pkglibdir)/emulator/ install -m644 Build/*.pm $(DESTDIR)$(pkglibdir)/Build install -m644 qemu-reg $(DESTDIR)$(pkglibdir) + install -m644 build-vm build-vm-* $(DESTDIR)$(pkglibdir) + install -m644 build-recipe build-recipe-* $(DESTDIR)$(pkglibdir) + install -m644 build-pkg build-pkg-* $(DESTDIR)$(pkglibdir) install -m644 *.pm baselibs_global*.conf lxc.conf $(DESTDIR)$(pkglibdir) install -m644 configs/* $(DESTDIR)$(pkglibdir)/configs install -m644 build.1 $(DESTDIR)$(man1dir) + install -m644 vc.1 $(DESTDIR)$(man1dir) + install -m644 unrpm.1 $(DESTDIR)$(man1dir) ln -sf $(pkglibdir)/build $(DESTDIR)$(bindir)/build ln -sf $(pkglibdir)/vc $(DESTDIR)$(bindir)/buildvc ln -sf $(pkglibdir)/unrpm $(DESTDIR)$(bindir)/unrpm @@ -1,21 +1,11 @@ -This script is used for building SUSE Linux RPMs in -a clean and safe chroot'ed build environment. +This is a tool to build binary packages in a safe and reproducible +way. The default is to build in a chroot sandbox, but it also +supports building in a virtual machine for better security. -At first you need to copy your SUSE Linux CDs into a -path reachable by the build script, for example /home/suse-8.2-i386. +The build tool can work with multiple package and recipe formats. +The currently supported package formats are deb, rpm, and arch. +The supported recipe formats are spec, dsc, kiwi, and PKGBUILD. -If you have a DVD Drive and the SUSE Linux DVD, you can mount it -and use this as the source for the RPMs. +See the man page for more information. -To build an RPM, change into the directory with the sources -and the SPEC file. Then start the build script: -env BUILD_RPMS=/home/suse-8.2-i386/suse build - -If this was successful you can find the binary and source RPMs below -/var/tmp/build-root/usr/src/packages/ - -Note: Depending on which package you want to build, you'll need -a few hundred megabytes for the build in /var/tmp/build-root. - -For more information on using build, see 'man build'. @@ -1,17 +1,36 @@ #!/bin/bash # Script to build a package. It uses init_buildsystem to setup a chroot # building tree. This script needs a directory as parameter. This directory -# has to include sources and a spec file. +# has to include sources and a recipe file. # # BUILD_ROOT here the packages will be built # -# (c) 1997-2008 SuSE GmbH Nuernberg, Germany +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ # some VMs do not allow to specify the init process... -if test "$0" = "/sbin/init" ; then - exec /.build/build "$@" +if test "$0" = /sbin/init ; then + exec /.build/build "$@" fi +test -z "$BUILD_DIR" -a -e /.build/build.data -a -z "$BUILD_IGNORE_2ND_STAGE" && BUILD_DIR=/.build test -z "$BUILD_DIR" && BUILD_DIR=/usr/lib/build test -z "$BUILD_ROOT" && BUILD_ROOT=/var/tmp/build-root test -z "$CONFIG_DIR" && CONFIG_DIR="$BUILD_DIR/configs" @@ -19,55 +38,23 @@ test -z "$CONFIG_DIR" && CONFIG_DIR="$BUILD_DIR/configs" export BUILD_ARCH BUILD_HOST_ARCH BUILD_ROOT BUILD_RPMS BUILD_DIR BUILD_DEBUG export BUILD_DIST -ccache=0 icecream=0 -statistics=0 -shell= definesnstuff=() repos=() old_packages=() -# defaults for vm_img_mkfs -vm_img_mkfs_ext4_options='-O ^has_journal,^huge_file,^resize_inode,sparse_super' -vm_img_mkfs_ext4_extra='-E lazy_itable_init,discard' -vm_img_mkfs_ext4="mkfs.ext4 -m 0 -q -F $vm_img_mkfs_ext4_options" -vm_img_tunefs_ext4='tune2fs -c 0' -vm_img_mkfs_ext3='mkfs.ext3 -m 0 -q -F' -vm_img_tunefs_ext3='tune2fs -c 0 -o journal_data_writeback' -vm_img_mkfs_ext2='mkfs.ext2 -m 0 -q -F' -vm_img_tunefs_ext2='tune2fs -c 0' -vm_img_mkfs_reiserfs='mkreiserfs -q -f' -vm_img_mkfs_btrfs='mkfs.btrfs' -vm_img_mkfs_xfs='mkfs.xfs -f' - -vm_kernel=/boot/vmlinuz -vm_initrd=/boot/initrd -qemu_bin=/usr/bin/qemu -uml_kernel=/boot/vmlinux-um -uml_initrd=/boot/initrd-um - -# z/VM: use default kernel image from local machine -# lets go with the default parameters. However zvm_initrd will be a required parameter -#zvm_kernel=/boot/image -#zvm_initrd=/boot/initrd_worker -zvm_param="root=/dev/disk/by-path/ccw-0.0.0150-part1 hvc_iucv=8 console=hvc0" -zvm_mult_pass="THR4ME" -#zvm_worker_nr="1" -zvm_init_script="/.build/build" - -kvm_bin=/usr/bin/qemu-kvm -# whether we have virtio support -kvm_virtio= - -# guest visible console device name -console=ttyS0 +# slurp in vm support +. "$BUILD_DIR/build-vm" + +# slurp in recipe support +. "$BUILD_DIR/build-recipe" + +# slurp in package binary support +. "$BUILD_DIR/build-pkg" # need to restore build root owner for non-root builds browner= -# additional kiwi parameters, used for appliance builds with obsrepositories:/ directive -KIWI_PARAMETERS= - # Default uid:gid for the build user ABUILD_UID=399 ABUILD_GID=399 @@ -79,27 +66,15 @@ DO_CHECKS=true SHORT_CIRCUIT=false NO_TOPDIR_CLEANUP=false CLEAN_BUILD= -USE_SYSTEM_QEMU= KEEP_PACKS= -SPECFILES=() +RECIPEFILES=() SRCDIR= BUILD_JOBS= ABUILD_TARGET= CREATE_BASELIBS= USEUSEDFORBUILD= LIST_STATE= -VM_IMAGE= -VM_SWAP= -VM_KERNEL= -VM_INITRD= -VMDISK_ROOTSIZE=4096 -VMDISK_SWAPSIZE=1024 -VMDISK_FILESYSTEM=ext4 -# settings are for speed and not data safety, we format anyway on next run -VMDISK_MOUNT_OPTIONS=__default -VMDISK_CLEAN= -HUGETLBFSPATH= -MEMSIZE= + RUNNING_IN_VM= RPMLIST= RELEASE= @@ -109,7 +84,6 @@ LOGFILE= KILL= CHANGELOG= BUILD_DEBUG= -PERSONALITY_SYSCALL= INCARNATION= DISTURL= LINKSOURCES= @@ -118,10 +92,11 @@ RSYNCSRC= RSYNCDEST= RSYNCDONE= SIGNDUMMY= -HOST_ARCH= -EMULATOR_SCRIPT= -KVM_OPTIONS= -BUILD_EC2_TYPE="t1.micro" +DO_STATISTICS= +RUN_SHELL= +CCACHE= +DLNOSIGNATURE= +CACHE_DIR=/var/cache/build # This is for insserv @@ -138,7 +113,7 @@ echo_help () { Some comments for build ----------------------- -With build you can create rpm packages. They will be built in a chroot +With build you can create binary packages. They will be built in a chroot system. This chroot system will be setup automatically. Normally you can simply call build with a spec file as parameter - nothing else has to be set. @@ -178,7 +153,7 @@ Known Parameters: --no-init Skip initialization of build root and start with build immediately. - --no-checks Do not run post-build checks + --no-checks Do not run checks (postbuild and %check) --lint Run rpmlint after build. @@ -186,14 +161,13 @@ Known Parameters: Capture build output to logfile. Defaults to .build.log in the build root for non-VM builds. - --repository PATH - Use package repository at PATH. Supported formats are - rpm-md and yast2. + --repo PATH_OR_URL + Use package repository at PATH_OR_URL. Supported formats + are rpm-md, yast2, debian, and arch linux. Alternatively zypp://NAME specifies the zypp repository NAME. The repo must be refreshed with zypp so package meta data is available locally. With emtpy NAME all enabled repositories are used. - a url can specify a remote repo. --rpms path1:path2:... Specify path where to find the RPMs for the build system @@ -211,9 +185,9 @@ Known Parameters: Use 'rootdir' to setup chroot environment --cachedir cachedir - Use 'cachedir' to cache remote repo's packages, the + Use 'cachedir' to cache remote repo's packages. The default cache dir is /var/cache/build, every repo - given by --repository corresponds to a subdir named + given by --repo corresponds to a subdir named as md5sum of its repo url, for example: /var/cache/build/3e8ea9b47808629414a0cebc33ea285e @@ -307,7 +281,6 @@ Known Parameters: --emulator Use any generic emulator to isolate the build process. You need to write an emulator/emulator.sh script and put it next to the build script sources. - You must NOT use any vm swap file for this. --emulator-script SCRIPT specify another emulator instead of emulator.sh @@ -347,7 +320,7 @@ Known Parameters: --vm-memory SIZEINMB Set amount of RAM for VMs - --hugetlbfs HUGETLBFSPATH + --vm-hugetlbfs HUGETLBFSPATH Use hugetlb for memory management, path to mounted hugetlbfs. --vm-kernel FILE @@ -362,8 +335,9 @@ Remember to have fun! [*] Maximum RPM: http://www.rpm.org/max-rpm/ EOT } + usage () { - echo "Usage: `basename $0` [--no-init|--clean|--rpms path|--verify|--help] [dir-to-build|spec-to-build]" + echo "Usage: `basename $0` [--no-init|--clean|--rpms path|--verify|--help] [dir-to-build|recipe-to-build]" cleanup_and_exit 1 } @@ -388,62 +362,25 @@ cleanup_and_exit () { if test -n "$RUNNING_IN_VM" ; then echo "$1" > /.build/_exitcode test -n "$browner" && chown "$browner" $BUILD_ROOT - cd / - if test -n "$VM_SWAP" -a -e "$VM_SWAP" ; then - swapoff "$VM_SWAP" 2>/dev/null - echo -n "BUILDSTATUS$1" >"$VM_SWAP" - fi - exec >&0 2>&0 # so that the logging tee finishes - sleep 1 # wait till tee terminates - if test "$VM_TYPE" != lxc; then - kill -9 -1 # goodbye cruel world - if ! test -x /sbin/halt ; then - test -e /proc/sysrq-trigger || mount -n -tproc none /proc - sync - sleep 2 # like halt does - if test -e /proc/sysrq-trigger; then - echo o > /proc/sysrq-trigger - sleep 5 # wait for sysrq to take effect - else - echo "Warning: VM doesn't support sysrq and /sbin/halt not installed" - fi - else - halt -f -p - fi - echo "Warning: clean shut down of the VM didn't work" - fi + vm_shutdown "$1" else - # nop if unused - cloud_volume_detach "$VM_SERVER" "$VM_VOLUME_NAME" - cloud_volume_detach "$VM_SERVER" "$VM_VOLUME_SWAP" - cloud_volume_detach "$VM_SERVER" "$EC2_EXTRACT_VOLUME_root" - cloud_volume_detach "$VM_SERVER" "$EC2_EXTRACT_VOLUME_swap" - - [ -n "$EC2_SNAP_root" ] && ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" - [ -n "$EC2_SNAP_swap" ] && ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap" - [ -n "$EC2_EXTRACT_VOLUME_root" ] && ec2-delete-volume --region "$BUILD_EC2_REGION" "$EC2_EXTRACT_VOLUME_root" - [ -n "$EC2_EXTRACT_VOLUME_swap" ] && ec2-delete-volume --region "$BUILD_EC2_REGION" "$EC2_EXTRACT_VOLUME_swap" - umount -n $BUILD_ROOT/proc/sys/fs/binfmt_misc 2> /dev/null || true umount -n $BUILD_ROOT/proc 2>/dev/null || true umount -n $BUILD_ROOT/dev/pts 2>/dev/null || true umount -n $BUILD_ROOT/dev/shm 2>/dev/null || true - test "$VM_IMAGE" = 1 && VM_IMAGE= - [ -n "$VM_IMAGE" ] && umount $BUILD_ROOT 2>/dev/null || true + umount -n $BUILD_ROOT/sys 2>/dev/null || true + test -n "$VM_IMAGE" -a "$VM_IMAGE" != 1 && umount $BUILD_ROOT 2>/dev/null || true + test -n "$VM_TYPE" && vm_cleanup fi - -# echo "pid $$ exit $1" exit $1 } -fail_exit() -{ - cleanup_and_exit 1 +fail_exit() { + cleanup_and_exit 1 } -shellquote() -{ - for arg; do +shellquote() { + for arg ; do arg=${arg/\\/\\\\} arg=${arg/\$/\\\$} arg=${arg/\"/\\\"} @@ -454,17 +391,15 @@ shellquote() # create a shell script from command line. Used for preserving arguments # through /bin/su -c -toshellscript() -{ - echo "#!/bin/sh -x" - echo -n exec - shellquote "$@" - echo +toshellscript() { + echo "#!/bin/sh -x" + echo -n exec + shellquote "$@" + echo } -setupccache() -{ - if [ "$ccache" = 1 ]; then +setupccache() { + if test -n "$CCACHE" ; then if mkdir -p $BUILD_ROOT/var/lib/build/ccache/bin; then for i in $(ls $BUILD_ROOT/usr/bin | grep -E '^(cc|gcc|[cg][+][+])([-]?[234][.]?[0-9])*$'); do # ln -sf /usr/bin/ccache $BUILD_ROOT/var/lib/build/ccache/bin/$i @@ -478,7 +413,7 @@ setupccache() echo "Installed ccache wrapper as $BUILD_ROOT/var/lib/build/ccache/bin/$i" done fi - mkdir -p "$BUILD_ROOT"/.ccache + mkdir -p "$BUILD_ROOT/.ccache" chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/.ccache" echo "export CCACHE_DIR=/.ccache" > "$BUILD_ROOT"/etc/profile.d/build_ccache.sh echo 'export PATH=/var/lib/build/ccache/bin:$PATH' >> "$BUILD_ROOT"/etc/profile.d/build_ccache.sh @@ -487,23 +422,21 @@ setupccache() fi } -setupicecream() -{ - if [ "$icecream" -eq 0 ]; then +setupicecream() { + if test "$icecream" -eq 0 ; then rm -rf "$BUILD_ROOT/var/run/icecream" rm -f "$BUILD_ROOT/etc/profile.d/build_icecream.sh" - return + return 0 fi if ! chroot "$BUILD_ROOT" rpm -q icecream >/dev/null 2>/dev/null; then echo "*** icecream package not installed ***" - false - return + return 1 fi echo "using icecream with $icecream jobs" - if [ "$ccache" -ne 1 ]; then + if test -z "$CCACHE" ; then echo 'export PATH=/usr/lib/icecc/bin:/opt/icecream/bin:$PATH' > "$BUILD_ROOT"/etc/profile.d/build_icecream.sh else echo 'export CCACHE_PATH=/usr/lib/icecc/bin:/opt/icecream/bin' > "$BUILD_ROOT"/etc/profile.d/build_icecream.sh @@ -514,25 +447,24 @@ setupicecream() # XXX use changelog like autobuild does instead? # only run create-env if compiler or glibc changed - if [ -z "$icecc_vers" \ + if test -z "$icecc_vers" \ -o ! -e "$BUILD_ROOT/$icecc_vers" \ -o "$BUILD_ROOT/usr/bin/gcc" -nt "$BUILD_ROOT/$icecc_vers" \ -o "$BUILD_ROOT/usr/bin/g++" -nt "$BUILD_ROOT/$icecc_vers" \ -o "$BUILD_ROOT/usr/bin/as" -nt "$BUILD_ROOT/$icecc_vers" \ - -o "$BUILD_ROOT/lib/libc.so.6" -nt "$BUILD_ROOT/$icecc_vers" ] + -o "$BUILD_ROOT/lib/libc.so.6" -nt "$BUILD_ROOT/$icecc_vers" then rm -rf "$BUILD_ROOT/var/run/icecream" mkdir -p "$BUILD_ROOT/var/run/icecream" - if [ -e "$BUILD_ROOT"/usr/bin/create-env ]; then - createenv=/usr/bin/create-env - elif [ -e "$BUILD_ROOT"/usr/lib/icecc/icecc-create-env ]; then - createenv="/usr/lib/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX - elif [ -e "$BUILD_ROOT"/usr/lib64/icecc/icecc-create-env ]; then - createenv="/usr/lib64/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX + if test -e "$BUILD_ROOT"/usr/bin/create-env ; then + createenv=/usr/bin/create-env + elif test -e "$BUILD_ROOT"/usr/lib/icecc/icecc-create-env ; then + createenv="/usr/lib/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX + elif test -e "$BUILD_ROOT"/usr/lib64/icecc/icecc-create-env ; then + createenv="/usr/lib64/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX else - echo "create-env not found" - false - return + echo "create-env not found" + return 1 fi chroot $BUILD_ROOT bash -c "cd /var/run/icecream; $createenv" || cleanup_and_exit 1 icecc_vers=(`shopt -s nullglob; echo $BUILD_ROOT/var/run/icecream/*.tar.{bz2,gz}`) @@ -540,14 +472,13 @@ setupicecream() else echo "reusing existing icecream environment $icecc_vers" fi - if [ -n "$icecc_vers" ]; then - echo "export ICECC_VERSION=$icecc_vers" >> "$BUILD_ROOT"/etc/profile.d/build_icecream.sh + if test -n "$icecc_vers" ; then + echo "export ICECC_VERSION=$icecc_vers" >> "$BUILD_ROOT"/etc/profile.d/build_icecream.sh fi } -setmemorylimit() -{ - if [ -n "$VM_IMAGE" -o -n "$RUNNING_IN_VM" ]; then +setmemorylimit() { + if test -n "$VM_IMAGE" -o -n "$RUNNING_IN_VM" ; then return fi local mem @@ -569,17 +500,16 @@ setmemorylimit() echo "Memory limit set to ${limit}KB" } -create_baselibs() -{ +create_baselibs() { local pkgs=() local line BASELIBS_CFG= - if test "$BUILDTYPE" == "arch" ; then + if test "$BUILDTYPE" == arch ; then return fi - if test "$BUILDTYPE" == "dsc" ; then + if test "$BUILDTYPE" == dsc ; then pkgs=($DEBS) else # spec and kiwi if test -e $BUILD_ROOT$TOPDIR/SOURCES/baselibs.conf ; then @@ -638,20 +568,19 @@ create_baselibs() rm -rf "$BUILD_ROOT/.mkbaselibs" } -copy_oldpackages() -{ +copy_oldpackages() { local i=0 local d local dest - [ -z "$RUNNING_IN_VM" ] || return 0 - if [ -z "$old_packages" ]; then + test -z "$RUNNING_IN_VM" || return 0 + if test -z "$old_packages" ; then rm -rf "$BUILD_ROOT"/.build.oldpackages* return 0 fi for d in "${old_packages[@]}"; do dest="$BUILD_ROOT/.build.oldpackages" test "$i" = 0 || dest="$dest$i" - if [ -d "$d" -a "$d" != "$dest" ] ; then + if test -d "$d" -a "$d" != "$dest" ; then rm -rf "$dest" mkdir -p "$dest" cp -L $d/* "$dest" @@ -660,379 +589,73 @@ copy_oldpackages() done } -vm_img_create() -{ - local img="$1" - local size="$2" - - echo "Creating $img (${size}M)" - mkdir -p "${img%/*}" || cleanup_and_exit 3 - - # prefer fallocate, which avoids fragmentation - r=1 - if type -p fallocate > /dev/null; then - fallocate -l "${size}M" "$img" - r=$? - fi - # fall back to dd method if fallocate is not supported - if [ "$r" -gt "0" ]; then - dd if=/dev/zero of="$img" bs=1M count=0 seek="$size" || cleanup_and_exit 3 - fi -} - -vm_img_mkfs() -{ - local fs="$1" - local img="$2" - local mkfs tunefs - eval "mkfs=\"\$vm_img_mkfs_${fs}\"" - eval "mkfs_exta_options=\"\$vm_img_mkfs_${fs}_extra\"" - eval "tunefs=\"\$vm_img_tunefs_${fs}\"" - - if test -z "$mkfs"; then - echo "filesystem \"$fs\" isn't supported" - cleanup_and_exit 3 - fi - - - echo "Creating $fs filesystem on $img" - if ! $mkfs $mkfs_exta_options "$img"; then - if test -z "$mkfs_exta_options"; then - cleanup_and_exit 3 - else - echo "Format call failed, trying again without extra options..." - $mkfs "$img" || cleanup_and_exit 3 - fi - fi - if test -n "$tunefs" ; then - $tunefs "$img" || cleanup_and_exit 3 - fi -} - -background_monitor_process() -{ - max_disk=0 - max_mem=0 - while sleep 5; do - - # memory usage - if [ -e /proc/meminfo ]; then - memtotal=0 - while read key value unit; do - case $key in - MemTotal:|SwapTotal:) - memtotal=$(( $memtotal + $value )) - ;; - MemFree:|SwapFree:|SwapCached:|Cached:|Buffers:) - memtotal=$(( $memtotal - $value )) - ;; - esac - done < /proc/meminfo - - if [ ${memtotal} -gt $max_mem ]; then - max_mem="${memtotal}" - echo -n $(( $max_mem / 1024 )) > /.build/_statistics.memory.new && mv /.build/_statistics.memory.new /.build/_statistics.memory - fi - fi - - # disk storage usage - if type -p df >& /dev/null; then - c=(`df -m / 2>/dev/null | tail -n 1`) - - if [ ${c[2]} -gt $max_disk ]; then - max_disk="${c[2]}" - echo -n $max_disk > /.build/_statistics.df.new && mv /.build/_statistics.df.new /.build/_statistics.df - fi - fi - - [ -e /.build/_statistics.exit ] && exit 0 - done -} - -detect_vm_2nd_stage() -{ - if test -e /.build/build.data; then - . /.build/build.data - fi - if test -z "$VM_TYPE" ; then - return 1 - fi - if test $$ -eq 1 || test $$ -eq 2; then - # ignore special init signals if we're init - # we're using ' ' instead of '' so that the signal handlers - # are reset in the child processes - trap ' ' HUP TERM - $0 "$@" - cleanup_and_exit $? - fi - echo "2nd stage started in virtual machine" - BUILD_ROOT=/ - BUILD_DIR=/.build - echo "machine type: `uname -m`" - if test "$PERSONALITY" != 0 -a -z "$PERSONALITY_SET" ; then - export PERSONALITY_SET=true - echo "switching personality to $PERSONALITY..." - # this is 32bit perl/glibc, thus the 32bit syscall number - exec perl -e 'syscall(136, '$PERSONALITY') == -1 && warn("personality: $!\n");exec "/.build/build" || die("/.build/build: $!\n")' - fi - RUNNING_IN_VM=true - test -e /proc/version || mount -orw -n -tproc none /proc - if test "$VM_TYPE" != 'lxc'; then - mount -n ${VMDISK_MOUNT_OPTIONS},remount,rw / - fi - umount /run >/dev/null 2>&1 -# qemu inside of xen does not work, check again with kvm later before enabling this -# if [ -e /dev/kqemu ]; then -# # allow abuild user to run qemu -# chmod 0666 /dev/kqemu -# fi - if test "$VM_TYPE" = 'zvm' ; then - VM_SWAP='/dev/dasdb1' - fi - if test "$VM_TYPE" = 'ec2' ; then - VM_SWAP='/dev/sdb1' - # Usually the external system is writing the swap signature, but EC2 volume - # attach is very slow, so let's do it in the VM for now. - mkswap "$VM_SWAP" - fi - if test -n "$VM_SWAP" ; then - for i in 1 2 3 4 5 6 7 8 9 10 ; do - test -e "$VM_SWAP" && break - test $i = 1 && echo "waiting for $VM_SWAP to appear" - echo -n . - sleep 1 - done - test $i = 1 || echo - # recreate the swap device manually if it didn't exist for some - # reason, hardcoded to hda2 atm - if ! test -b "$VM_SWAP" ; then - rm -f "$VM_SWAP" - umask 027 - mknod "$VM_SWAP" b 3 2 - umask 022 - fi - swapon -v "$VM_SWAP" || exit 1 - fi - HOST="$MYHOSTNAME" - - # fork a process monitoring max filesystem fillment during build - if test "$statistics" = "1"; then - background_monitor_process & - fi - - if [ ! -e /dev/.udev ]; then - echo "WARNING: udev not running, creating extra device nodes" - test -e /dev/fd || ln -sf /proc/self/fd /dev/fd - test -e /etc/mtab || ln -sf /proc/mounts /etc/mtab - fi - - # set date to build start on broken systems (now < build start) - if [ $(date '+%s') -lt $(date -r /.build/.date '+%s') ]; then - echo -n "WARNING: system has a broken clock, setting it to a newer time: " - date -s `cat /.build/.date` - fi - - return 0 -} - -find_spec_files() -{ - local spec files - if [ -z "$SPECFILES" ]; then - set -- "`pwd`" - else - set -- "${SPECFILES[@]}" - fi - SPECFILES=() - for spec in "$@"; do - if [ "$spec" = "${spec#/}" ]; then - spec="`pwd`/$spec" - fi - - if [ -d "$spec" ]; then - specs=("$spec"/*.spec) - if [ -n "$specs" ]; then - SPECFILES=("${SPECFILES[@]}" "${specs[@]}") - else - specs=("$spec"/*.spec) - if [ -n "$specs" ]; then - SPECFILES=("${SPECFILES[@]}" "${specs[@]}") - fi - fi - else - SPECFILES[${#SPECFILES[@]}]="$spec"; - fi - done - - if test -z "$SPECFILES"; then - echo no spec files or src rpms found in $@. exit... - cleanup_and_exit 1 - fi -} - -become_root_or_fail() -{ - if [ ! -w /root ]; then +become_root_or_fail() { + if test ! -w /root ; then echo "You have to be root to use $0" >&2 exit 1 fi cleanup_and_exit 1 } -mkdir_build_root() -{ - if [ -d "$BUILD_ROOT" ]; then +mkdir_build_root() { + # strip trailing slash + test "$BUILD_ROOT" != / && BUILD_ROOT="${BUILD_ROOT%/}" + if test -d "$BUILD_ROOT" ; then # check if it is owned by root - if [ -z "$RUNNING_IN_VM" -a \! -O "$BUILD_ROOT" -a "`stat -c %u $BUILD_ROOT`" -ne 0 ]; then + if test -z "$RUNNING_IN_VM" -a \! -O "$BUILD_ROOT" -a "`stat -c %u $BUILD_ROOT`" -ne 0 ; then echo "BUILD_ROOT=$BUILD_ROOT must be owned by root. Exit..." cleanup_and_exit 1 fi else test "$BUILD_ROOT" != "${BUILD_ROOT%/*}" && mkdir -p "${BUILD_ROOT%/*}" - if ! mkdir $BUILD_ROOT; then + if ! mkdir $BUILD_ROOT ; then echo "can not create BUILD_ROOT=$BUILD_ROOT. Exit..." cleanup_and_exit 1 fi fi - if [ ! -w "$BUILD_ROOT" ]; then + if test ! -w "$BUILD_ROOT" ; then echo "Error: BUILD_ROOT=$BUILD_ROOT not writeable, try --clean." cleanup_and_exit 3 fi rm -rf "$BUILD_ROOT/.build.packages" - if [ -z "$VM_TYPE" -a -z "$RUNNING_IN_VM" ]; then - # don't touch this in VM - rm -rf "$BUILD_ROOT/.build" - mkdir -p "$BUILD_ROOT/.build" + if test -z "$VM_TYPE" -a -z "$RUNNING_IN_VM" ; then + # don't touch this in VM + rm -rf "$BUILD_ROOT/.build" + mkdir -p "$BUILD_ROOT/.build" fi } -ec2_volume_state() -{ - local VM_VOL_NAME="$1" - temp_file=`mktemp` - ec2-describe-volumes "$VM_VOL_NAME" --region "$BUILD_EC2_REGION" > $temp_file - - if grep -q ^ATTACHMENT "$temp_file"; then - grep ^ATTACHMENT "$temp_file" | awk '{ print $5 }' +copy_overlay() { + if test -d "$OVERLAY"; then + pushd $OVERLAY + echo "Copying overlay to BUILD_ROOT" + tar -cpf - . | (cd $BUILD_ROOT ; tar -xvf -) + popd else - grep ^VOLUME "$temp_file" | awk '{ print $5 }' - fi - rm "$temp_file" -} - -cloud_volume_attach() -{ - local VM_SERVER="$1" - local VM_VOL_NAME="$2" - local VM_VOL_DEV="$3" - - if [ "$VM_TYPE" = 'openstack' ]; then - if ! nova volume-attach "$VM_SERVER" "$VM_VOL_NAME" "$VM_VOL_DEV"; then - echo "ERROR: nova attach failed. $?" >&2 - return 3 - fi - while true; do - state=`nova volume-show "$VM_VOL_NAME" | sed -n 's,^|[ ]*status[ ]*|[ ]*\([^ ]*\).*,\1,p'` - [ "$state" == "in-use" ] && break - if [ -z "$state" ]; then - echo "ERROR: unable to find state of volume $VM_VOL_NAME" >&2 - return 3 - fi - if [ "$state" == "available" ]; then - echo "WARNING: volume $VM_VOL_NAME got not attached, retrying" >&2 - if ! nova volume-attach "$VM_SERVER" "$VM_VOL_NAME" "$VM_VOL_DEV"; then - echo "ERROR: nova attach failed. $?" >&2 - return 3 - fi - fi - sleep 3 - done - - if [ ! -e "$VM_VOL_DEV" ]; then - #GROSS HACK: kernel does not care about the given device name -# VM_VOL_DEV="/dev/"`dmesg| sed -n 's,.*\(vd.\): unknown partition tab.*,\1,p' | tail -n 1` - VM_VOL_DEV=`ls -1 /dev/vd? | tail -n 1` - fi - echo "$VM_VOL_DEV" - elif [ "$VM_TYPE" = 'ec2' ]; then - temp_file=`mktemp` - if ! ec2-attach-volume "$VM_VOL_NAME" -d /dev/sdz -i `ec2-instance-id` --region $BUILD_EC2_REGION > "$temp_file"; then - rm "$temp_file" - cleanup_and_exit 1 - fi - # wait that it becomes available - while true; do - state=`ec2_volume_state "$VM_VOL_NAME"` - [ "$state" = "attached" ] && break - sleep 1 - done - # print device node - grep ^ATTACHMENT "$temp_file" | awk '{ print $4 }' - rm "$temp_file" - fi -} - -cloud_volume_detach() -{ - local VM_SERVER="$1" - local VM_VOL_NAME="$2" - if [ "$VM_TYPE" = 'openstack' ]; then - # needed at all? - nova volume-show "$VM_VOL_NAME" | grep -q in-use || return 0 - - # umount seems not to be enough - sync - - if ! nova volume-detach "$VM_SERVER" "$VM_VOL_NAME"; then - echo "ERROR: nova detach of $VM_VOL_NAME failed." >&2 - return 3 - fi - while nova volume-show "$VM_VOL_NAME" | grep -q availabe; do - sleep 3 - done - elif [ "$VM_TYPE" = 'ec2' ]; then - state=`ec2_volume_state "$VM_VOL_NAME"` - if [ "$state" != "available" ]; then - ec2-detach-volume "$VM_VOL_NAME" --region $BUILD_EC2_REGION || return 3 - fi + echo "OVERLAY ($OVERLAY) is no directory - skipping" fi - return 0 -} - -linux64() -{ - perl -e 'syscall('$PERSONALITY_SYSCALL', 0); exec(@ARGV) || die("$ARGV[0]: $!\n")' "$@" } -check_for_arm() -{ - local uname - - uname=$(uname -m) - - if [ "$uname" != "armv7l" ]; then - return - fi - - export HOST_ARCH=armv7l - - export kvm_bin="/usr/bin/qemu-system-arm" - export console=ttyAMA0 - export KVM_OPTIONS="-enable-kvm -M vexpress-a15 -dtb /boot/a15-guest.dtb -cpu cortex-a15" - VM_KERNEL=/boot/zImage - VM_INITRD=/boot/initrd - # prefer the guest kernel - if [ -e /boot/zImage.guest ]; then - VM_KERNEL=/boot/zImage.guest - fi - # prefer the guest initrd - if [ -e /boot/initrd.guest ]; then - VM_INITRD=/boot/initrd.guest +run_rsync() { + if test -n "$RSYNCDEST" ; then + if test -d "$RSYNCSRC" ; then + if ! test -d "$BUILD_ROOT/$RSYNCDEST" ; then + echo "ATTENTION! Creating missing target directory ($BUILD_ROOT/$RSYNCDEST)." + mkdir -p $BUILD_ROOT/$RSYNCDEST + fi + echo "Running rsync ..." + rsync -av $RSYNCSRC/* $BUILD_ROOT/$RSYNCDEST/ + chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/$RSYNCDEST" + RSYNCDONE=true + echo "... done" + else + echo "RSYNCSRC is not a directory - skipping" + fi + else + echo "RSYNCSRC given, but not RSYNCDEST - skipping" fi - export VM_KERNEL - export VM_INITRD } hide_passwords() @@ -1053,425 +676,226 @@ hide_passwords() echo ${repos[@]} } -check_for_ppc() -{ - local uname - - uname=$(uname -m) - - case $uname in - ppc|ppc64) export VM_KERNEL=/boot/vmlinux - export VM_INITRD=/boot/initrd - ;; - ppc64le) export VM_INITRD=/boot/vmlinuxle - export VM_INITRD=/boot/initrdle - ;; - *) return ;; - esac - - grep -q "PowerNV" /proc/cpuinfo && export HOST_ARCH=power7 || export HOST_ARCH=ppc970 - - export kvm_bin="/usr/bin/qemu-system-ppc64" - export console=hvc0 - export KVM_OPTIONS="-enable-kvm -M pseries" - if [ -z "$RUNNING_IN_VM" -a -n "$HUGETLBFSPATH" ];then - if ! grep -q "$HUGETLBFSPATH" /proc/mounts; then - echo "hugetlbfs is not mounted" - exit 1 - fi - PAGES_FREE=$(cat /sys/kernel/mm/hugepages/hugepages-16384kB/free_hugepages) - PAGES_REQ=$(( ${MEMSIZE:-64} / 16 )) - if [ "$PAGES_FREE" -lt "$PAGES_REQ" ];then - echo "please adjust nr_hugepages" - exit 1 - fi - if [ "$HOST_ARCH" = "ppc970" ];then - if ! grep -q -E '(kvm_rma_count.*kvm_hpt_count)|(kvm_hpt_count.*kvm_rma_count)' /proc/cmdline; then - echo "put kvm_rma_count=<VM number> or kvm_hpt_count=<> to your boot options" - exit 1 - fi - fi - fi -} #### main #### trap fail_exit EXIT -archname=`perl -V:archname` -archname="${archname#archname=?}" -case "$archname" in - x86_64*) PERSONALITY_SYSCALL=135 ;; - alpha*) PERSONALITY_SYSCALL=324 ;; - sparc*) PERSONALITY_SYSCALL=191 ;; - ia64*) PERSONALITY_SYSCALL=1140 ;; - i?86*|ppc*|aarch64*|arm*|sh4|cris|m68k*|s390*|unicore32|microblaze) PERSONALITY_SYSCALL=136 ;; - *) echo "ARCHITECTURE PERSONALITY IS UNKNOWN"; exit 1;; -esac - shopt -s nullglob -export PATH=$BUILD_DIR:/sbin:/usr/sbin:$PATH +export PATH=$BUILD_DIR:/sbin:/usr/sbin:/bin:/usr/bin:$PATH -if detect_vm_2nd_stage ; then - set "/.build-srcdir/$SPECFILE" +if vm_detect_2nd_stage ; then + set "/.build-srcdir/$RECIPEFILE" export PATH=/.build:$PATH fi . $BUILD_DIR/common_functions || exit 1 -. $BUILD_DIR/zvm_functions || exit 1 export HOST -needarg() -{ - if [ -z "$ARG" ]; then - echo "$PARAM needs an agrument" >&2 - cleanup_and_exit 1 - fi +needarg() { + if test -z "$ARG" ; then + echo "$PARAM needs an agrument" >&2 + cleanup_and_exit 1 + fi } while test -n "$1"; do - PARAM="$1" - UNSTRIPPED_ARG="$2" - ARG="$2" - [ "$ARG" = "${ARG#-}" ] || ARG="" - ARG2="$3" - [ "$ARG2" = "${ARG2#-}" ] || ARG2="" - shift - case $PARAM in - *-*=*) - ARG=${PARAM#*=} - PARAM=${PARAM%%=*} - set -- "----noarg=$PARAM" "$@" - esac - case $PARAM in - *-help|-h) + PARAM="$1" + ARG="$2" + test "$ARG" = "${ARG#-}" || ARG= + shift + case $PARAM in + *-*=*) + ARG=${PARAM#*=} + PARAM=${PARAM%%=*} + set -- "----noarg=$PARAM" "$@" + ;; + esac + case ${PARAM/#--/-} in + -help|-h) echo_help cleanup_and_exit ;; - *-no*init) + -noinit|-no-init) DO_INIT=false ;; - *-no-build) - DO_BUILD=false + -no-build) + DO_BUILD=false ;; - *-no*checks) + -nochecks|-no-checks) DO_CHECKS=false ;; - -clean|--clean) + -clean) CLEAN_BUILD='--clean' ;; - *-kill) + -kill) KILL=true ;; - *-rpms) + -rpms) needarg BUILD_RPMS="$ARG" shift ;; - *-arch) + -arch) needarg BUILD_ARCH="$ARG" shift ;; - *-verify) + -verify) export VERIFY_BUILD_SYSTEM=true ;; - *-target) + -target) needarg ABUILD_TARGET="$ARG" shift ;; - *-jobs) + -jobs) needarg BUILD_JOBS="$ARG" shift ;; - *-threads) + -threads) needarg BUILD_THREADS="$ARG" shift ;; - *-extra*packs|-X) + -extrapacks|-extra-packs|-X) needarg BUILD_EXTRA_PACKS="$BUILD_EXTRA_PACKS $ARG" shift ;; - *-lint) + -lint) DO_LINT=true ;; - *-baselibs) + -baselibs) CREATE_BASELIBS=true ;; - --kiwi-parameter) - KIWI_PARAMETERS="$KIWI_PARAMETERS $UNSTRIPPED_ARG" - shift - ;; - *-baselibs-internal) + -baselibs-internal) CREATE_BASELIBS=internal ;; - *-use-system-qemu) - USE_SYSTEM_QEMU="--use-system-qemu" - ;; - --keep-packs) - KEEP_PACKS="--keep-packs" - ;; - *-root) + -keep-packs) + KEEP_PACKS="--keep-packs" + ;; + -root) needarg BUILD_ROOT="$ARG" shift ;; - *-cachedir) + -cachedir) needarg CACHE_DIR="$ARG" shift ;; - *-oldpackages) + -oldpackages) needarg old_packages=("${old_packages[@]}" "$ARG") shift ;; - *-dist) + -dist) needarg BUILD_DIST="$ARG" shift ;; - *-emulator-script) - needarg - EMULATOR_SCRIPT="$ARG" - shift - ;; - *-xen|*-kvm|--uml|--qemu|--emulator) - VM_TYPE=${PARAM##*-} - if [ -n "$ARG" ]; then - VM_IMAGE="$ARG" - shift - else - VM_IMAGE=1 - fi - ;; - *-zvm) - VM_TYPE="zvm" - shift - ;; - --lxc) - VM_TYPE=${PARAM##*-} - ;; - --vm-type) - needarg - VM_TYPE="$ARG" - case "$VM_TYPE" in - zvm) ;; - ec2) - test -z "$VM_IMAGE" && VM_IMAGE=1 - . /etc/profile.d/ec2.sh - EC2_INSTANCE_ID=`ec2-instance-id` - BUILD_EC2_ZONE=`ec2-meta-data placement/availability-zone` - BUILD_EC2_REGION=${BUILD_EC2_ZONE%?} - ;; - xen|kvm|uml|qemu|lxc|emulator|openstack) - test -z "$VM_IMAGE" && VM_IMAGE=1 - ;; - none|chroot) VM_TYPE='' ;; - *) - echo "VM $VM_TYPE not supported" - cleanup_and_exit - ;; - esac - shift - ;; - --vm-worker) - needarg - VM_WORKER="$ARG" - shift - ;; - --vm-worker-nr) - needarg - zvm_worker_nr="$ARG" - shift - ;; - --vm-server|--vm-region) - needarg - VM_SERVER="$ARG" - shift - ;; - --vm-volumes) - needarg - VM_VOLUME_NAME="$ARG" - shift - needarg - VM_VOLUME_SWAP="$ARG2" - shift - ;; - --vm-disk) - needarg - VM_IMAGE="$ARG" - shift - ;; - *-xenswap|*-swap) - needarg - VM_SWAP="$ARG" - shift - ;; - *-xenmemory|*-memory) - needarg - MEMSIZE="$ARG" - shift - ;; - *-vm-kernel) - needarg - VM_KERNEL="$ARG" - shift - ;; - *-vm-initrd) - needarg - VM_INITRD="$ARG" - shift - ;; - *-vmdisk-rootsize|--vm-disk-size) - needarg - VMDISK_ROOTSIZE="$ARG" - shift - ;; - *-vmdisk-swapsize|--vm-swap-size) - needarg - VMDISK_SWAPSIZE="$ARG" - shift - ;; - *-vmdisk-filesystem|--vm-disk-filesystem) - needarg - VMDISK_FILESYSTEM="$ARG" - shift - ;; - *-vmdisk-mount-options|--vm-disk-mount-options) - needarg - # options needs to be quoted to handle argument which might start with "-o ..." - VMDISK_MOUNT_OPTIONS=$(echo $ARG | sed 's/^\"\(.*\)\"$/\1/g') - shift - ;; - *-vmdisk-clean) - # delete old root/swap to get rid of the old blocks - VMDISK_CLEAN=true - ;; - *-rpmlist) - needarg - RPMLIST="--rpmlist $ARG" - BUILD_RPMS= - shift - ;; - *-hugetlbfs) - HUGETLBFSPATH="$ARG" - shift - ;; - *-release) + -release) needarg RELEASE="$ARG" shift ;; - *-logfile) + -logfile) needarg LOGFILE="$ARG" shift ;; - *-reason) + -reason) needarg REASON="$ARG" shift ;; - *-norootforbuild) + -norootforbuild) NOROOTFORBUILD=true ;; - *-stage) - needarg - BUILD_RPM_BUILD_STAGE="$ARG" - shift - ;; - *-short-circuit) + -short-circuit) SHORT_CIRCUIT=true ;; - *-no-topdir-cleanup) + -no-topdir-cleanup) NO_TOPDIR_CLEANUP=true ;; - *-useusedforbuild) + -useusedforbuild) USEUSEDFORBUILD="--useusedforbuild" ;; - *-configdir) + -configdir) needarg CONFIG_DIR="$ARG" shift ;; - *-list*state) + -list*state) LIST_STATE=true ;; - --define|--with|--without) + -define|-with|-without) needarg - definesnstuff[${#definesnstuff[@]}]="$PARAM"; - definesnstuff[${#definesnstuff[@]}]="$ARG"; + PARAM="-${PARAM/#--/-}" + definesnstuff[${#definesnstuff[@]}]="$PARAM" + definesnstuff[${#definesnstuff[@]}]="$ARG" shift ;; - --repository|--repo) + -repository|-repo) needarg - repos[${#repos[@]}]="$PARAM"; - repos[${#repos[@]}]="$ARG"; + repos[${#repos[@]}]="--repository" + repos[${#repos[@]}]="$ARG" shift ;; - --icecream) + -icecream) needarg icecream="$ARG" - if [ "$icecream" -gt 0 ]; then - BUILD_JOBS="$ARG" - fi + test "$icecream" -gt 0 && BUILD_JOBS="$ARG" shift ;; - --ccache) - ccache=1 + -ccache) + CCACHE=true ;; - --statistics) - statistics=1 + -statistics) + DO_STATISTICS=1 ;; - --debug) + -debug) BUILD_DEBUG=1 ;; - --incarnation) + -incarnation) needarg INCARNATION=$ARG shift ;; - --disturl) + -disturl) needarg DISTURL=$ARG shift ;; - --linksources) + -linksources) LINKSOURCES=true ;; - ----noarg) - echo "$ARG does not take an argument" - cleanup_and_exit - ;; - *-changelog) + -changelog) CHANGELOG=true ;; - --overlay) + -overlay) needarg OVERLAY=$ARG shift ;; - --rsync-src) + -rsync-src) needarg RSYNCSRC=$ARG shift ;; - --rsync-dest) + -rsync-dest) needarg RSYNCDEST=$ARG shift ;; - --uid) + -uid) needarg ABUILD_ID="$ARG" - if test -n "${ABUILD_ID//[0-9:]/}"; then + if test -n "${ABUILD_ID//[0-9:]/}" ; then echo "--uid argument must be uid:gid" cleanup_and_exit fi @@ -1479,353 +903,77 @@ while test -n "$1"; do ABUILD_GID=${ABUILD_ID#*:} shift ;; - --shell) - shell=1 - shift + -rpmlist) + needarg + RPMLIST="--rpmlist $ARG" + BUILD_RPMS= + shift + ;; + -shell) + RUN_SHELL=1 + shift ;; - --signdummy) + -signdummy) SIGNDUMMY=1 ;; + -nosignature) + DLNOSIGNATURE="--nosignature" + ;; + ---noarg) + echo "$ARG does not take an argument" + cleanup_and_exit + ;; -*) - echo Unknown Option "$PARAM". Exit. - cleanup_and_exit 1 + if vm_parse_options "$@" ; then + set -- "${nextargs[@]}" + elif recipe_parse_options "$@" ; then + set -- "${nextargs[@]}" + else + echo "Unknown option '$PARAM'. Exit." + cleanup_and_exit 1 + fi ;; *) - SPECFILES[${#SPECFILES[@]}]="$PARAM"; + RECIPEFILES[${#RECIPEFILES[@]}]="$PARAM" ;; esac done -check_for_ppc -check_for_arm - if [ "$SHORT_CIRCUIT" = true -a -z "$BUILD_RPM_BUILD_STAGE" ]; then echo "--short-circuit needs a stage (use --stage)" cleanup_and_exit 1 fi -if test "$VM_TYPE" = "lxc"; then - VM_IMAGE='' - VM_SWAP='' -fi - -if test "$VM_TYPE" = "zvm"; then - VM_IMAGE='/dev/dasda1' - VM_SWAP='/dev/dasdb1' -fi - -if test "$VM_TYPE" = "ec2"; then - # We can not use bash hashes because old bash does not support it - # This is always the x86_64 loader, we use also by default the - # local x86_64 kernel, which should be able to run a 32bit system - if [ "$BUILD_EC2_ZONE" = "us-east-1" ]; then - BUILD_EC2_AKI="aki-88aa75e1" - elif [ "$BUILD_EC2_ZONE" = "us-west-1" ]; then - BUILD_EC2_AKI="aki-f77e26b2" - elif [ "$BUILD_EC2_ZONE" = "us-west-2" ]; then - BUILD_EC2_AKI="aki-fc37bacc" - elif [ "$BUILD_EC2_ZONE" = "eu-west-1" ]; then - BUILD_EC2_AKI="aki-71665e05" - elif [ "$BUILD_EC2_ZONE" = "ap-southeast-1" ]; then - BUILD_EC2_AKI="aki-fe1354ac" - elif [ "$BUILD_EC2_ZONE" = "ap-southeast-2" ]; then - BUILD_EC2_AKI="aki-3f990e05" - elif [ "$BUILD_EC2_ZONE" = "ap-northeast-1" ]; then - BUILD_EC2_AKI="aki-44992845" - elif [ "$BUILD_EC2_ZONE" = "sa-east-1" ]; then - BUILD_EC2_AKI="aki-c48f51d9" - elif [ "$BUILD_EC2_ZONE" = "us-gov-west-1" ]; then - BUILD_EC2_AKI="aki-79a4c05a" - else - echo "Unknown Amazon EC2 Zone: $BUILD_EC2_ZONE" - exit 1 - fi -fi - -if test "$VMDISK_MOUNT_OPTIONS" = __default; then - if test "$VMDISK_FILESYSTEM" = reiserfs ; then - VMDISK_MOUNT_OPTIONS='-o data=writeback,commit=150,noatime' - elif test "$VMDISK_FILESYSTEM" = btrfs ; then - VMDISK_MOUNT_OPTIONS='-o nobarrier,noatime' - elif test "$VMDISK_FILESYSTEM" = "ext4" ; then - VMDISK_MOUNT_OPTIONS='-o noatime' - elif test "$VMDISK_FILESYSTEM" = "ext3" ; then - VMDISK_MOUNT_OPTIONS='-o data=writeback,nobarrier,commit=150,noatime' - elif test "$VMDISK_FILESYSTEM" = "ext2" ; then - VMDISK_MOUNT_OPTIONS='-o noacl,noatime' - elif test "$VMDISK_FILESYSTEM" = "xfs" ; then - VMDISK_MOUNT_OPTIONS='-o noatime' - else - VMDISK_MOUNT_OPTIONS='-o noatime' - fi -fi - if test -n "$KILL" ; then test -z "$SRCDIR" || usage if test -n "$VM_IMAGE" -a -n "$VM_SWAP" -a -n "$VM_TYPE"; then # mark job as failed so that we don't extract packages - if test "$VM_TYPE" != "zvm"; then + if test "$VM_TYPE" != zvm ; then echo -n "BUILDSTATUS1" >"$VM_SWAP" fi fi (set -C; > "$BUILD_ROOT/exit" 2>/dev/null || true) - if test "$VM_TYPE" = 'lxc'; then - LXCID=${BUILD_ROOT##*/} - lxc-stop -n "$LXCID" || true - lxc-destroy -n "$LXCID" - elif test -z "$VM_IMAGE" ; then + if test -n "$VM_TYPE" ; then + vm_kill + else if ! $BUILD_DIR/killchroot -s 9 $BUILD_ROOT ; then echo "could not kill build in $BUILD_ROOT" cleanup_and_exit 1 fi - elif test "$VM_TYPE" = 'xen'; then - XENID="${VM_IMAGE%/root}" - XENID="${XENID%/tmpfs}" - XENID="${XENID##*/}" - XENID="${XENID#root_}" - if xm list "build_$XENID" >/dev/null 2>&1 ; then - if ! xm destroy "build_$XENID" ; then - echo "could not kill xen build $XENID" - cleanup_and_exit 1 - fi - fi - elif test "$VM_TYPE" = 'zvm'; then - if vmcp q "$VM_WORKER" > /dev/null 2>&1 ; then - if ! zvm_cp destroy $VM_WORKER ; then - echo "could not kill zvm worker $VM_WORKER" - cleanup_and_exit 1 - fi - fi - elif test "$VM_TYPE" = 'ec2'; then - if ec2-describe-instance-status "$VM_BUILD_INSTANCE" --region $BUILD_EC2_REGION >/dev/null 2>&1 ; then - if ec2-terminate-instances "$VM_BUILD_INSTANCE" >/dev/null 2>&1 ; then - echo "could not kill EC2 instance $VM_BUILD_INSTANCE" - cleanup_and_exit 1 - fi - fi - elif test "$VM_TYPE" = 'openstack'; then - if nova show "$VM_VOLUME_NAME" >/dev/null 2>&1 ; then - if ! nova delete "$VM_VOLUME_NAME" ; then - echo "could not kill openstack vm build $VM_VOLUME_NAME" - cleanup_and_exit 1 - fi - fi - elif test -n "$VM_TYPE"; then - if ! fuser -k -TERM "$VM_IMAGE"; then - echo "could not kill build in $VM_IMAGE" - cleanup_and_exit 1 - fi - else - echo "don't know how to kill this build job" - cleanup_and_exit 1 fi cleanup_and_exit 0 fi -if [ "$VM_TYPE" = 'xen' -a -z "$RUNNING_IN_VM" ]; then - # XXX: merge with kvm path? - if [ -n "$VM_KERNEL" ]; then - vm_kernel="$VM_KERNEL" - elif [ -e "/boot/vmlinuz-xen" ]; then - vm_kernel="/boot/vmlinuz-xen" - fi - if [ -n "$VM_INITRD" ]; then - vm_initrd="$VM_INITRD" - elif [ -e "/boot/initrd-xen" ]; then - vm_initrd="/boot/initrd-xen" - fi -fi - -if [ "$VM_TYPE" = 'zvm' -a -z "$RUNNING_IN_VM" ]; then - # verify settings - # In z/VM, this is a 4 digit hex number instead of a linux device. - # This is the root disk defined in user direct - # This number can be given with the parameter --root NR. - if [ -z "$VM_VOLUME_ROOT" ]; then - if [ -n "$BUILD_ROOT" -a ${#BUILD_ROOT} -le 4 ]; then - VM_VOLUME_ROOT="$BUILD_ROOT" - else - VM_VOLUME_ROOT="0150" - fi - fi - # In z/VM, this is a 4 digit hex number instead of a linux device. - # This is the swap disk defined in user direct - # This number can be given with the parameter --swap NR. - if [ -z "$VM_VOLUME_SWAP" ]; then - if [ -n "$VM_SWAP" -a ${#VM_SWAP} -le 4 ]; then - VM_VOLUME_SWAP="$VM_SWAP" - else - VM_VOLUME_SWAP="0250" - fi - fi - # z/VM guest name that is already defined in z/VM - if [ -z "$VM_WORKER" ]; then - echo "ERROR: No z/VM worker id specified" - cleanup_and_exit 3 - fi - if [ -z "$zvm_worker_nr" ]; then - echo "ERROR: No z/VM worker number specified" - cleanup_and_exit 3 - fi - # need the name for a kernel in zvm - if [ -n "$VM_KERNEL" ]; then - vm_kernel="$VM_KERNEL" - elif [ -e "/boot/vmlinux.gz" ]; then - vm_kernel="/boot/vmlinux.gz" - else - echo "ERROR: No z/VM kernel specified" - cleanup_and_exit 3 - fi - # need the name for an initrd in zvm - # this normally will not be the local initrd - if [ -n "$VM_INITRD" ]; then - vm_initrd="$VM_INITRD" - else - echo "ERROR: No z/VM initrd specified" - cleanup_and_exit 3 - fi -fi - -if [ "$VM_TYPE" = 'ec2' -a -z "$RUNNING_IN_VM" ]; then - # verify settings - if [ -z "$AWS_ACCESS_KEY" -o -z "$AWS_ACCESS_KEY" ]; then - echo "ERROR:No amazon EC2 environment set. Set AWS_ACCESS_KEY and AWS_SECRET_KEY." - cleanup_and_exit 3 - fi - if [ -z "$BUILD_EC2_AKI" ]; then - echo "ERROR: No image refering to kernel and ramdisk is defined in BUILD_EC2_AKI env." - cleanup_and_exit 3 - fi - if [ -z "$VM_VOLUME_NAME" ]; then - echo "ERROR: No worker root VM volume name specified." - cleanup_and_exit 3 - fi - if [ -z "$VM_VOLUME_SWAP" ]; then - echo "ERROR: No worker swap VM volume name specified." - cleanup_and_exit 3 - fi - - # go - VM_IMAGE=`cloud_volume_attach "$VM_SERVER" "$VM_VOLUME_NAME" "$VM_IMAGE"` - [ "${VM_IMAGE:0:5}" == "/dev/" ] || cleanup_and_exit 3 -fi - -if [ "$VM_TYPE" = 'openstack' -a -z "$RUNNING_IN_VM" ]; then - # verify settings - if [ -z "$OS_AUTH_URL" ]; then - echo "ERROR:No openstack environment set. This vm-type works only inside of an openstack VM." - cleanup_and_exit 3 - fi - if [ -z "$OBS_OPENSTACK_KERNEL_IMAGE_ID" ]; then - echo "ERROR: No image refering to kernel and ramdisk is defined in OBS_OPENSTACK_KERNEL_IMAGE_ID env." - cleanup_and_exit 3 - fi - if [ -z "$VM_VOLUME_NAME" ]; then - echo "ERROR: No worker root VM volume name specified." - cleanup_and_exit 3 - fi - if [ -z "$VM_VOLUME_SWAP" ]; then - echo "ERROR: No worker swap VM volume name specified." - cleanup_and_exit 3 - fi - if [ -z "$VM_SERVER" ]; then - echo "ERROR: No VM server nod name specified (usually this instance)." - cleanup_and_exit 3 - fi - - # go - VM_IMAGE=`cloud_volume_attach "$VM_SERVER" "$VM_VOLUME_NAME" "$VM_IMAGE"` - [ "${VM_IMAGE:0:5}" == "/dev/" ] || cleanup_and_exit 3 -fi - -if [ "$VM_TYPE" = 'kvm' -a -z "$RUNNING_IN_VM" ]; then - if [ ! -r /dev/kvm -o ! -x "$kvm_bin" ]; then - echo "host doesn't support kvm" - echo "either the kvm kernel-module is not loaded or kvm is not installed or hardware virtualization is deactivated in the BIOS." - cleanup_and_exit 3 - fi - qemu_bin="$kvm_bin" - if [ -n "$VM_KERNEL" ]; then - vm_kernel="$VM_KERNEL" - fi - - # check if a SUSE system with virtio initrd is running - if [ -z "$VM_INITRD" -a -e /etc/sysconfig/kernel ]; then - a=$( source /etc/sysconfig/kernel; echo $INITRD_MODULES ) - have_virtio_pci="" - have_virtio_blk="" - for i in $a; do - [ "$i" == "virtio_pci" ] && have_virtio_pci="1" - [ "$i" == "virtio_blk" ] && have_virtio_blk="1" - done - [ -n "$have_virtio_pci" -a -n "$have_virtio_blk" ] && VM_INITRD="/boot/initrd" - fi - - if [ -n "$VM_INITRD" ]; then - vm_initrd="$VM_INITRD" - kvm_virtio=1 - elif [ -e "${vm_initrd}-build" ]; then - vm_initrd="${vm_initrd}-build" - kvm_virtio=1 - else - if [ -L "$vm_initrd" ]; then - vm_initrd=`readlink -f "$vm_initrd"` || cleanup_and_exit 3 - fi - vm_initrd_virtio="${vm_initrd}-virtio" - - if [ ! -e ${vm_initrd_virtio} -o $vm_kernel -nt ${vm_initrd_virtio} ]; then - mkinitrd_virtio_cmd=(env rootfstype="$VMDISK_FILESYSTEM" \ - mkinitrd -d /dev/null \ - -m "ext3 ext4 btrfs reiserfs binfmt_misc virtio_pci virtio_blk" \ - -k $vm_kernel \ - -i ${vm_initrd_virtio}) - if [ ! -w /root -o -n "$RPMLIST" ]; then - echo "No initrd that provides virtio support found. virtio accelleration disabled." - echo "Run the following command as root to enable virtio:" - shellquote "${mkinitrd_virtio_cmd[@]}" - echo - elif /sbin/modinfo virtio_pci >/dev/null 2>&1; then - echo "creating $vm_initrd_virtio" - "${mkinitrd_virtio_cmd[@]}" || cleanup_and_exit 1 - kvm_virtio=1 - vm_initrd="${vm_initrd_virtio}" - fi - else - kvm_virtio=1 - vm_initrd="${vm_initrd_virtio}" - fi - fi - - case $HOST_ARCH in - power7|armv7l) kvm_virtio=1;; - ppc970) kvm_virtio=;; - esac - - if [ "$kvm_virtio" = 1 ]; then - VM_SWAPDEV=/dev/vdb - qemu_rootdev=/dev/vda - else - VM_SWAPDEV=/dev/sdb - qemu_rootdev=/dev/sda - fi -fi - -if [ "$VM_TYPE" = 'openstack' ]; then - VM_SWAPDEV=/dev/vdb - qemu_rootdev=/dev/vda -fi - -if [ "$VM_TYPE" = 'qemu' ]; then - VM_SWAPDEV=/dev/sdb - qemu_rootdev=/dev/sda +if test -n "$CLEAN_BUILD" ; then + DO_INIT=true fi -if [ "$VM_TYPE" = 'uml' ]; then - VM_SWAPDEV=/dev/ubdb +if test -n "$VM_TYPE" -a -z "$RUNNING_IN_VM" ; then + vm_verify_options fi -if [ -z "$RPMLIST" -a -z "$RUNNING_IN_VM" ]; then - if [ -z "$repos" -a -z "$BUILD_RPMS" ]; then +if test -z "$RPMLIST" -a -z "$RUNNING_IN_VM" ; then + if test -z "$repos" -a -z "$BUILD_RPMS" ; then repos=(--repository 'zypp://') fi else @@ -1834,159 +982,57 @@ fi set_build_arch -if [ -n "$CLEAN_BUILD" ]; then - DO_INIT=true -fi - -find_spec_files +expand_recipe_directories if test -n "$LIST_STATE" ; then BUILD_ROOT=`mktemp -d /var/tmp/build-list-state-XXXXXX` test -d "$BUILD_ROOT" || cleanup_and_exit 3 - SPECFILE=$SPECFILES # only one specified anyways - if test "$SPECFILE" != "${SPECFILE%.src.rpm}" ; then - rm -rf "$BUILD_ROOT/usr/src/packages" - mkdir -p $BUILD_ROOT/usr/src/packages/SOURCES $BUILD_ROOT/usr/src/packages/SPECS - rpm -i --nodigest --nosignature --root $BUILD_ROOT $SPECFILE || { - echo "could not install $SPECFILE." 2>&1 - rm -rf "$BUILD_ROOT" - cleanup_and_exit 3 - } - for SPECFILE in $BUILD_ROOT/usr/src/packages/SPECS/*.spec ; do : ; done + RECIPEFILE=$RECIPEFILES # only one specified anyways + if test "$RECIPEFILE" != "${RECIPEFILE%.src.rpm}" ; then + MYSRCDIR="$BUILD_ROOT/usr/src/packages/SOURCES" + recipe_unpack_srcrpm + RECIPEFILE="$MYSRCDIR/$RECIPEFILE" fi - init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --list-state "${definesnstuff[@]}" "${repos[@]}" $USEUSEDFORBUILD $SPECFILE $BUILD_EXTRA_PACKS + init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --list-state "${definesnstuff[@]}" "${repos[@]}" $DLNOSIGNATURE $KEEP_PACKS $USEUSEDFORBUILD $RECIPEFILE $BUILD_EXTRA_PACKS ERR=$? rm -rf "$BUILD_ROOT" cleanup_and_exit $ERR fi -# z/VM: -# 1. make sure that no buildjob exists anymore by doing an ipl of cms -# 2. detach the root device from the worker -# 3. link the device to the controlling guest -# -> Need a uniq worker id to calculate a uniq device address for linking -# -> VM_IMAGE is the resulting block device -if [ "$VM_TYPE" = 'zvm' ]; then - if [ ! "$0" = "/.build/build" ] ; then - echo "in controlling guest" - zvm_cp worker_init $VM_WORKER $VM_VOLUME_ROOT $VM_VOLUME_SWAP $zvm_worker_nr - zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT - zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP - VM_IMAGE=$(zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_ROOT $zvm_mult_pass $zvm_worker_nr ) - VM_SWAP=$(zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_SWAP $zvm_mult_pass $zvm_worker_nr ) - if [ ! "${VM_IMAGE}" = "dasd${VM_IMAGE#dasd}" -o ! "${VM_SWAP}" = "dasd${VM_SWAP#dasd}" ]; then - echo "did not get a real device for VM_IMAGES: $VM_IMAGE $VM_SWAP" - cleanup_and_exit 3 - else - VM_IMAGE="/dev/"${VM_IMAGE} - VM_SWAP="/dev/"${VM_SWAP} - fi - fi -fi - -echo "VM_IMAGE: $VM_IMAGE, VM_SWAP: $VM_SWAP" - -# doing setup -if test -z "$RUNNING_IN_VM" ; then - if test -n "$VM_IMAGE" ; then - if test "$VM_IMAGE" = 1 ; then - VM_IMAGE="$BUILD_ROOT.img" - echo "using $VM_IMAGE as vm image" - if test -z "$VM_SWAP" -a "$VM_TYPE" != "emulator"; then - VM_SWAP="$BUILD_ROOT.swap" - echo "using $VM_SWAP as vm swap" - fi - fi - if [ "$VM_TYPE" = 'xen' ]; then - # this should not be needed, but sometimes a xen instance got lost - XENID="${VM_IMAGE%/root}" - XENID="${XENID%/tmpfs}" - XENID="${XENID##*/}" - XENID="${XENID#root_}" - xm destroy "build_$XENID" >/dev/null 2>&1 - fi - if test -n "$VMDISK_CLEAN" ; then - # delete old root/swap to get rid of the old blocks - if test -f "$VM_IMAGE" ; then - echo "Deleting old $VM_IMAGE" - rm -rf "$VM_IMAGE" - fi - if test -n "$VM_SWAP" -a -f "$VM_SWAP" ; then - echo "Deleting old $VM_SWAP" - rm -rf "$VM_SWAP" - fi - fi - if test ! -e "$VM_IMAGE"; then - vm_img_create "$VM_IMAGE" "$VMDISK_ROOTSIZE" - if test -z "$CLEAN_BUILD" ; then - vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE" - fi - fi - if test -n "$VM_SWAP" -a ! -e "$VM_SWAP" -a ! -b "$VM_SWAP"; then - vm_img_create "$VM_SWAP" "$VMDISK_SWAPSIZE" - fi - if test ! -e "$VM_IMAGE" ; then - echo "you need to create $VM_IMAGE first" - cleanup_and_exit 3 - fi - if test -n "$CLEAN_BUILD" ; then - vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE" || cleanup_and_exit 3 - fi - mkdir_build_root - if [ -w /root ]; then - if [ -b $VM_IMAGE ]; then - # mount device directly - mount $VMDISK_MOUNT_OPTIONS $VM_IMAGE $BUILD_ROOT || cleanup_and_exit 3 - else - mount ${VMDISK_MOUNT_OPTIONS},loop $VM_IMAGE $BUILD_ROOT || cleanup_and_exit 3 - fi - else - if ! mount $BUILD_ROOT; then - echo "mounting the build root failed. An fstab entry is probably missing or incorrect." - echo "/etc/fstab should contain an entry like this:" - echo "$VM_IMAGE $BUILD_ROOT auto noauto,user,loop 0 0" - cleanup_and_exit 3 - fi - fi - else - test -w /root || become_root_or_fail - fi - if test -n "$VM_SWAP" ; then - dd if=/dev/zero of="$VM_SWAP" bs=1024 count=1 conv=notrunc 2>/dev/null - echo "mkswap $VM_SWAP" - mkswap "$VM_SWAP" - [ "$VM_TYPE" = 'openstack' ] && openstack_volume_detach "$VM_SERVER" "$VM_VOLUME_SWAP" - fi +# do vm setup if needed +if test -z "$RUNNING_IN_VM" -a -n "$VM_TYPE" -a -n "$VM_IMAGE" ; then + vm_setup fi mkdir_build_root hide_passwords -if [ "$BUILD_ROOT" = / ]; then +if test "$BUILD_ROOT" = / ; then browner="$(stat -c %u /)" fi rm -f $BUILD_ROOT/exit -if [ -w /root ]; then +if test -w /root ; then mkdir -p $BUILD_ROOT/proc + mkdir -p $BUILD_ROOT/sys mkdir -p $BUILD_ROOT/dev/pts mount -n -tproc none $BUILD_ROOT/proc || true mount -n -tdevpts -omode=0620,gid=5 none $BUILD_ROOT/dev/pts fi -if test -z "$VM_IMAGE" -a -z "$LOGFILE"; then +if test -z "$VM_IMAGE" -a -z "$LOGFILE" ; then LOGFILE="$BUILD_ROOT/.build.log" fi -if test -n "$LOGFILE" -a -z "$shell" ; then - echo logging output to $LOGFILE... +if test -n "$LOGFILE" -a -z "$RUN_SHELL" ; then + echo "logging output to $LOGFILE..." rm -f $LOGFILE touch $LOGFILE # set start time, to be substracted for build log timestamps STARTTIME=`perl -e 'print time()'` - if [ -n "$RUNNING_IN_VM" ]; then + if test -n "$RUNNING_IN_VM" ; then # no additional timestamps in inner vm build system exec 1> >(exec -a 'build logging' tee -a $LOGFILE) 2>&1 elif test -n "$VM_IMAGE" ; then @@ -2005,7 +1051,7 @@ setmemorylimit # test -z "$HOST" && HOST=`hostname` -if [ -z "$RUNNING_IN_VM" ]; then +if test -z "$RUNNING_IN_VM" ; then echo Using BUILD_ROOT=$BUILD_ROOT test -n "$BUILD_RPMS" && echo Using BUILD_RPMS=$BUILD_RPMS echo Using BUILD_ARCH=$BUILD_ARCH @@ -2016,29 +1062,16 @@ fi test "$BUILD_ARCH" = all && BUILD_ARCH= BUILD_USER_ABUILD_USED= -for SPECFILE in "${SPECFILES[@]}" ; do +for RECIPEFILE in "${RECIPEFILES[@]}" ; do - SRCDIR="${SPECFILE%/*}" - SPECFILE="${SPECFILE##*/}" - - BUILDTYPE= - case $SPECFILE in - *.spec|*.src.rpm) BUILDTYPE=spec ;; - *.dsc) BUILDTYPE=dsc ;; - *.kiwi) BUILDTYPE=kiwi ;; - PKGBUILD) BUILDTYPE=arch ;; - _preinstallimage) BUILDTYPE=preinstallimage ;; - esac - if test -z "$BUILDTYPE" ; then - echo "don't know how to build $SPECFILE" - cleanup_and_exit 1 - fi + SRCDIR="${RECIPEFILE%/*}" + RECIPEFILE="${RECIPEFILE##*/}" - cd "$SRCDIR" + recipe_set_buildtype - if [ -z "$RUNNING_IN_VM" ]; then + if test -z "$RUNNING_IN_VM" ; then echo - echo "$HOST started \"build $SPECFILE\" at `date --utc`." + echo "$HOST started \"build $RECIPEFILE\" at `date --utc`." echo test -n "$REASON" && echo "$REASON" echo @@ -2048,588 +1081,42 @@ for SPECFILE in "${SPECFILES[@]}" ; do # # first setup building directory... # - test -s "$SPECFILE" || { - echo "$SPECFILE" is empty. This should not happen... - cleanup_and_exit 1 - } - - if test "$SPECFILE" != "${SPECFILE%.src.rpm}" ; then - echo processing src rpm $SRCDIR/$SPECFILE ... - MYSRCDIR=$BUILD_ROOT/.build-srcdir - rm -rf "$MYSRCDIR" - mkdir -p "$MYSRCDIR" - cd $MYSRCDIR || cleanup_and_exit 1 - $BUILD_DIR/unrpm -q $SRCDIR/$SPECFILE || { - echo "could not install $SPECFILE." - cleanup_and_exit 1 - } - for SPECFILE in *.spec ; do : ; done - else - MYSRCDIR="$SRCDIR" - fi - - # FIX to work with baselibs_$PROJ etc - if test "$BUILDTYPE" == "dsc" -a -e ${SRCDIR}/baselibs-deb.conf ; then - # Set CREATE_BASELIBS if not set - echo "dsc build and baselibs-deb.conf present: forcing --baselibs to true" - CREATE_BASELIBS=true + cd "$SRCDIR" + if ! test -s "$RECIPEFILE" ; then + echo "$RECIPEFILE is empty. This should not happen..." + cleanup_and_exit 1 fi + MYSRCDIR="$SRCDIR" -# Currently local osc build does not allow extra .deb packages to be -# specified on the command line. Both init_buildsystem and expanddeps -# need to handle .deb dependencies first -# if test -n "$CREATE_BASELIBS" ; then -# case $BUILDTYPE in -# spec) ;; -# dsc) BUILD_EXTRA_PACKS="$BUILD_EXTRA_PACKS libparse-debcontrol-perl" ;; -# esac -# fi + # special hack to build from a .src.rpm + test "$RECIPEFILE" != "${RECIPEFILE%.src.rpm}" && recipe_unpack_srcrpm - echo processing specfile $MYSRCDIR/$SPECFILE ... + echo "processing recipe $MYSRCDIR/$RECIPEFILE ..." - ADDITIONAL_PACKS="" + ADDITIONAL_PACKS= test -z "$BUILD_EXTRA_PACKS" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS $BUILD_EXTRA_PACKS" test -z "$CREATE_BASELIBS" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS build" - test "$ccache" = '0' || ADDITIONAL_PACKS="$ADDITIONAL_PACKS ccache" + test -z "$CCACHE" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS ccache" test "$icecream" = 0 || ADDITIONAL_PACKS="$ADDITIONAL_PACKS icecream gcc-c++" test -z "$DO_LINT" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS rpmlint-Factory" - test "$VMDISK_FILESYSTEM" = 'xfs' && ADDITIONAL_PACKS="$ADDITIONAL_PACKS libblkid1" - test "$VM_TYPE" = 'zvm' && ADDITIONAL_PACKS="$ADDITIONAL_PACKS udev libcap2" + test "$VMDISK_FILESYSTEM" = xfs && ADDITIONAL_PACKS="$ADDITIONAL_PACKS libblkid1" + test "$VM_TYPE" = zvm && ADDITIONAL_PACKS="$ADDITIONAL_PACKS udev libcap2" + # we need to do this before the vm is started if test -n "$CHANGELOG" -a -z "$RUNNING_IN_VM" ; then rm -f $BUILD_ROOT/.build-changelog - case $SPECFILE in - *.dsc) CFFORMAT=debian ;; - *) CFFORMAT=rpm ;; + case $RECIPEFILE in + *.dsc) CFFORMAT=debian ;; + *) CFFORMAT=rpm ;; esac - echo "running changelog2spec --target $CFFORMAT --file $MYSRCDIR/$SPECFILE" - if ! $BUILD_DIR/changelog2spec --target $CFFORMAT --file "$MYSRCDIR/$SPECFILE" > $BUILD_ROOT/.build-changelog ; then + echo "running changelog2spec --target $CFFORMAT --file $MYSRCDIR/$RECIPEFILE" + if ! $BUILD_DIR/changelog2spec --target $CFFORMAT --file "$MYSRCDIR/$RECIPEFILE" > $BUILD_ROOT/.build-changelog ; then rm -f $BUILD_ROOT/.build-changelog fi fi if test -n "$VM_TYPE" -a -z "$RUNNING_IN_VM"; then - rm -rf "$BUILD_ROOT/.build" - mkdir -p "$BUILD_ROOT/.build" - if test "$DO_INIT" = true ; then - # do first stage of init_buildsystem - rm -f $BUILD_ROOT/.build.success - set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --prepare "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $USE_SYSTEM_QEMU $KEEP_PACKS $USEUSEDFORBUILD $RPMLIST "$MYSRCDIR/$SPECFILE" $ADDITIONAL_PACKS - echo "$* ..." - start_time=`date +%s` - "$@" || cleanup_and_exit 1 - check_exit - TIME_PREINSTALL=$(( `date +%s` - $start_time )) - unset start_time - if [ ! -w /root ]; then - # remove setuid bit if files belong to user to make e.g. mount work - find $BUILD_ROOT/{bin,sbin,usr/bin,usr/sbin} -type f -uid $UID -perm +4000 -print0 | xargs -0 --no-run-if-empty chmod -s - fi - copy_oldpackages - fi - - # start up xen, rerun ourself - cp -a $BUILD_DIR/. $BUILD_ROOT/.build - if ! test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then - rm -rf "$BUILD_ROOT/.build-srcdir" - mkdir "$BUILD_ROOT/.build-srcdir" - if test "$BUILDTYPE" = kiwi ; then - cp -pRL "$MYSRCDIR"/* $BUILD_ROOT/.build-srcdir - else - cp -p "$MYSRCDIR"/* $BUILD_ROOT/.build-srcdir - fi - MYSRCDIR=$BUILD_ROOT/.build-srcdir - else - # cwd is at $BUILD_ROOT/.build-srcdir which we want to - # umount later so step aside - cd "$SRCDIR" - fi - Q="'\''" - echo "SPECFILE='${SPECFILE//"'"/$Q}'" > $BUILD_ROOT/.build/build.data - echo "BUILD_JOBS='${BUILD_JOBS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "BUILD_ARCH='${BUILD_ARCH//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "BUILD_RPMS='${BUILD_RPMS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - case $BUILD_DIST in - */*) - cp $BUILD_DIST $BUILD_ROOT/.build/build.dist - BUILD_DIST=/.build/build.dist - ;; - esac - echo "BUILD_DIST='${BUILD_DIST//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "RELEASE='${RELEASE//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "BUILD_DEBUG='${BUILD_DEBUG//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "SIGNDUMMY='${SIGNDUMMY//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "DO_LINT='${DO_LINT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "DO_CHECKS='${DO_CHECKS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "NOROOTFORBUILD='${NOROOTFORBUILD//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "CREATE_BASELIBS='$CREATE_BASELIBS'" >> $BUILD_ROOT/.build/build.data - echo "REASON='${REASON//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "CHANGELOG='${CHANGELOG//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "INCARNATION='${INCARNATION//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "DISTURL='${DISTURL//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "DO_INIT='${DO_INIT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - echo "KIWI_PARAMETERS='${KIWI_PARAMETERS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data - # FIXME: this depends on the kernel and vm. - # could be hda2, sda2 for xen or hdb/sdb for qemu - test -n "$VM_SWAP" && echo "VM_SWAP='${VM_SWAPDEV:-/dev/hda2}'" >> $BUILD_ROOT/.build/build.data - test -n "$VMDISK_MOUNT_OPTIONS" && echo "VMDISK_MOUNT_OPTIONS='${VMDISK_MOUNT_OPTIONS}'" >> $BUILD_ROOT/.build/build.data - PERSONALITY=0 - if test "$VM_TYPE" != 'lxc'; then - test -n "$PERSONALITY_SYSCALL" && PERSONALITY=`perl -e 'print syscall('$PERSONALITY_SYSCALL', 0)."\n"'` - fi - if test "$(uname -m)" = 'ppc'; then - # ppc kernel never tells us if a 32bit personality is active - PERSONALITY=8 - fi - echo "PERSONALITY='$PERSONALITY'" >> $BUILD_ROOT/.build/build.data - echo "MYHOSTNAME='`hostname`'" >> $BUILD_ROOT/.build/build.data - echo -n "definesnstuff=(" >> $BUILD_ROOT/.build/build.data - shellquote "${definesnstuff[@]}" >> $BUILD_ROOT/.build/build.data - echo ")" >> $BUILD_ROOT/.build/build.data - echo -n "repos=(" >> $BUILD_ROOT/.build/build.data - shellquote "${repos[@]}" >> $BUILD_ROOT/.build/build.data - echo ")" >> $BUILD_ROOT/.build/build.data - echo "VM_TYPE='$VM_TYPE'" >> $BUILD_ROOT/.build/build.data - echo "shell='$shell'" >> $BUILD_ROOT/.build/build.data - echo "statistics='$statistics'" >> $BUILD_ROOT/.build/build.data - # use the rpmbuild --stage option - if [ ! -z $BUILD_RPM_BUILD_STAGE ]; then - echo "BUILD_RPM_BUILD_STAGE='-$BUILD_RPM_BUILD_STAGE'" >> $BUILD_ROOT/.build/build.data - fi - # fallback time for broken hosts - date '+@%s' > $BUILD_ROOT/.build/.date - if [ "$VM_TYPE" = 'emulator' ]; then - ln -sf /.build/build $BUILD_ROOT/sbin/init - fi - if [ "$VM_TYPE" = 'zvm' ]; then - # initrd is created in obsstoragesetup. - # If it is desired to use a project dependent kernel, use make_guestinitrd from zvm_functions. - # have to copy kernel/initrd and run zipl to be able to IPL - # have to set init_script before unmounting, thus doing it statically for now. - zvm_init_script="/.build/build" - mkdir -p $BUILD_ROOT/boot - cp $vm_kernel $vm_initrd $BUILD_ROOT/boot - mkdir -p $BUILD_ROOT/boot/zipl - # finally, install bootloader to the worker disk - zipl -t $BUILD_ROOT/boot/zipl -i ${BUILD_ROOT}${vm_kernel} -r ${BUILD_ROOT}${vm_initrd} \ - --parameters "${zvm_param} init=$zvm_init_script rootfsopts=noatime" - fi - umount -n $BUILD_ROOT/proc/sys/fs/binfmt_misc 2> /dev/null || true - umount -n $BUILD_ROOT/proc 2> /dev/null || true - umount -n $BUILD_ROOT/dev/pts 2> /dev/null || true - umount -n $BUILD_ROOT/dev/shm 2> /dev/null || true - umount -n $BUILD_ROOT/mnt 2> /dev/null || true - - if check_use_emulator; then - if [ -e $BUILD_DIR/initvm.$BUILD_HOST_ARCH -a -e "$BUILD_DIR/qemu-reg" ]; then - chmod 0755 "$BUILD_DIR/initvm.$BUILD_HOST_ARCH" - vm_init_script="/.build/initvm.$BUILD_HOST_ARCH" - else - echo "Warning: can't find initscript to register binfmts" - fi - else - vm_init_script="/.build/build" - fi - - if [ "$VM_TYPE" = 'emulator' ]; then - # generic emulator hook. an external script is needed to define - # the emulator startup - sync - pushd $BUILD_DIR/emulator - if [ -z "$EMULATOR_SCRIPT" ]; then - EMULATOR_SCRIPT="./emulator.sh" - elif [ "${EMULATOR_SCRIPT:0:1}" != "/" ]; then - EMULATOR_SCRIPT="./$EMULATOR_SCRIPT" - fi - set -- "$EMULATOR_SCRIPT" "$VM_IMAGE" - echo "$@" - if ! "$@"; then - popd - echo "ERROR: The emulator return with an failure" - cleanup_and_exit 3 - fi - popd - - fi - - if [ "$VM_TYPE" = 'openstack' -o "$VM_TYPE" = 'ec2' ]; then - # No way to handle this via init= parameter here.... - echo "#!/bin/sh" > "$BUILD_ROOT/sbin/init" - echo 'exec /.build/build "$@"' >> "$BUILD_ROOT/sbin/init" - chmod 0755 "$BUILD_ROOT/sbin/init" - fi - if [ "$VM_TYPE" = 'ec2' ]; then - # use the instance kernel, if no kernel got installed via preinstall - if ! test -e "$BUILD_ROOT/boot/vmlinuz"; then - cp /boot/vmlinuz-ec2 "$BUILD_ROOT/boot/vmlinuz" - cp /boot/initrd-ec2 "$BUILD_ROOT/boot/initrd" - fi - # install menu.lst for pv grub - if ! test -e "$BUILD_ROOT/boot/grub/menu.lst"; then - mkdir -p "$BUILD_ROOT/boot/grub" - echo "serial --unit=0 --speed=9600" > "$BUILD_ROOT/boot/grub/menu.lst" - echo "terminal --dumb serial" >> "$BUILD_ROOT/boot/grub/menu.lst" - echo "default 0" >> "$BUILD_ROOT/boot/grub/menu.lst" - echo "timeout 0" >> "$BUILD_ROOT/boot/grub/menu.lst" - echo "hiddenmenu" >> "$BUILD_ROOT/boot/grub/menu.lst" - echo "" >> "$BUILD_ROOT/boot/grub/menu.lst" - echo "title default" >> "$BUILD_ROOT/boot/grub/menu.lst" - echo " root (hd0)" >> "$BUILD_ROOT/boot/grub/menu.lst" - echo " kernel /boot/vmlinuz root=/dev/sda1 xencons=xvc0 console=xvc0 splash=silent" >> "$BUILD_ROOT/boot/grub/menu.lst" - echo " initrd /boot/initrd" >> "$BUILD_ROOT/boot/grub/menu.lst" - fi - fi - if [ -n "$VM_IMAGE" ]; then - check_exit - # needs to work otherwise we have a corrupted file system - umount $BUILD_ROOT || cleanup_and_exit 3 - fi - - if [ "$VM_TYPE" = 'openstack' -o "$VM_TYPE" = 'ec2' ]; then - cloud_volume_detach "$VM_SERVER" "$VM_VOLUME_NAME" || cleanup_and_exit 3 - fi - - if [ -n "$VM_IMAGE" -a "$VM_TYPE" = "zvm" ]; then - # detach the worker root and swap locally and link it in the worker - zvm_cp volume_detach_local $VM_VOLUME_ROOT ${zvm_worker_nr} - zvm_cp volume_detach_local $VM_VOLUME_SWAP ${zvm_worker_nr} - zvm_cp volume_attach $VM_WORKER $VM_VOLUME_ROOT - zvm_cp volume_attach $VM_WORKER $VM_VOLUME_SWAP - fi - - if [ "$VM_TYPE" = 'xen' ]; then - XMROOT="file:$(readlink -f $VM_IMAGE)" - XMROOT=${XMROOT/#file:\/dev/phy:/dev} - XMROOT="disk=$XMROOT,hda1,w" - XMSWAP= - if test -n "$VM_SWAP" ; then - XMSWAP="file:$(readlink -f $VM_SWAP)" - XMSWAP=${XMSWAP/#file:\/dev/phy:/dev} - XMSWAP="disk=$XMSWAP,hda2,w" - fi - XENID="${VM_IMAGE%/root}" - XENID="${XENID%/tmpfs}" - XENID="${XENID##*/}" - XENID="${XENID#root_}" - - echo "booting XEN kernel ..." - if xm list "build_$XENID" >/dev/null 2>&1 ; then - echo "Instance already exist, something really went wrong..." - echo "Please report to your server admin, there might be multiple services running for same domain" - cleanup_and_exit 3 - fi - XEN_CONF_FILE=`mktemp /var/tmp/build.xen.conf-XXXXXXXXX` || cleanup_and_exit 3 - echo "kernel = \"$vm_kernel\"" > $XEN_CONF_FILE - echo "ramdisk = \"$vm_initrd\"" >> $XEN_CONF_FILE - echo "memory = ${MEMSIZE:-64}" >> $XEN_CONF_FILE - echo "vcpus = $BUILD_JOBS" >> $XEN_CONF_FILE - echo "root = \"/dev/hda1 ro\"" >> $XEN_CONF_FILE - echo "extra = \"init=/bin/bash console=ttyS0 panic=1 udev_timeout=360\"" >> $XEN_CONF_FILE - echo "on_poweroff = 'destroy'" >> $XEN_CONF_FILE - echo "on_reboot = 'destroy'" >> $XEN_CONF_FILE - echo "on_crash = 'destroy'" >> $XEN_CONF_FILE - set -- xm create -c $XEN_CONF_FILE name="build_$XENID" $XMROOT $XMSWAP extra="quiet init="$vm_init_script" elevator=noop panic=1 console=ttyS0" - if test "$PERSONALITY" != 0 ; then - # have to switch back to PER_LINUX to make xm work - set -- linux64 "$@" - fi - echo "$@" - "$@" || cleanup_and_exit 3 - rm "$XEN_CONF_FILE" - elif [ "$VM_TYPE" = 'uml' ]; then - echo "booting UML kernel ..." - set -- $uml_kernel initrd=$uml_initrd root=ubda init="$vm_init_script" panic=1 elevator=noop quiet ubda=$VM_IMAGE ubdb=$VM_SWAP ${MEMSIZE:+mem=$MEMSIZE} - echo "$@" - "$@" - elif [ "$VM_TYPE" = 'qemu' -o "$VM_TYPE" = 'kvm' ]; then - echo "booting $VM_TYPE ..." - if [ "$VM_TYPE" = 'kvm' -a -b "$VM_IMAGE" ]; then - # speed optimization when using kvm with raw devices - CACHE=",cache=none" - else - # speed optimization when using kvm with raw files - CACHE=",cache=unsafe" - fi - - # we do not want to have sound inside the VMs - export QEMU_AUDIO_DRV=none - - if [ "$kvm_virtio" = 1 ]; then - qemu_args=(-drive file="$VM_IMAGE",if=virtio$CACHE -drive file="$VM_IMAGE",if=ide,index=0$CACHE) - if [ -n "$VM_SWAP" ]; then - qemu_args=("${qemu_args[@]}" "-drive") - qemu_args=("${qemu_args[@]}" "file=$VM_SWAP,if=virtio$CACHE") - fi - if [ "$HOST_ARCH" = "armv7l" ]; then - qemu_args=(-drive file="$VM_IMAGE",if=none,id=disk$CACHE -device virtio-blk,transport=virtio-mmio.0,drive=disk) - qemu_args=("${qemu_args[@]}" "-drive") - qemu_args=("${qemu_args[@]}" "file=$VM_SWAP,if=none,id=swap$CACHE") - qemu_args=("${qemu_args[@]}" "-device") - qemu_args=("${qemu_args[@]}" "virtio-blk,transport=virtio-mmio.1,drive=swap") - fi - else - if [ "$HOST_ARCH" = "ppc970" ];then - qemu_args=( "-drive" ) - qemu_args=("${qemu_args[@]}" "file=$VM_IMAGE,if=scsi,cache=unsafe") - else - qemu_args=(-hda "$VM_IMAGE") - fi - if [ -n "$VM_SWAP" ]; then - qemu_args=("${qemu_args[@]}" "-drive") - if [ "$HOST_ARCH" = "ppc970" ];then - DISK_IF=scsi - else - DISK_IF=ide - fi - qemu_args=("${qemu_args[@]}" "file=$VM_SWAP,if=$DISK_IF,index=1$CACHE") - fi - fi - if [ -n "$BUILD_JOBS" -a "$icecream" = 0 -a -z "$BUILD_THREADS" ]; then - qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS") - elif [ -n "$BUILD_JOBS" -a -n "$BUILD_THREADS" ]; then - qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS,threads=$BUILD_THREADS") - fi - if [ "$VM_TYPE" = 'kvm' -a "$HOST_ARCH" != "armv7l" ]; then - KVM_OPTIONS="$KVM_OPTIONS -cpu host" - if [ -n "$HUGETLBFSPATH" ]; then - KVM_OPTIONS="$KVM_OPTIONS -mem-path $HUGETLBFSPATH" - fi - fi - - set -- $qemu_bin -no-reboot -nographic -vga none -net none $KVM_OPTIONS \ - -kernel $vm_kernel \ - -initrd $vm_initrd \ - -append "root=$qemu_rootdev panic=1 quiet no-kvmclock nmi_watchdog=0 rw elevator=noop console=$console init=$vm_init_script" \ - ${MEMSIZE:+-m $MEMSIZE} \ - "${qemu_args[@]}" - - if test "$PERSONALITY" != 0 ; then - # have to switch back to PER_LINUX to make qemu work - set -- linux64 "$@" - fi - echo "$@" - "$@" - elif [ "$VM_TYPE" = 'ec2' ]; then - echo "booting $VM_TYPE ..." - EC2_SNAP_root=`ec2-create-snapshot --region "$BUILD_EC2_REGION" "$VM_VOLUME_NAME" | awk '{ print $2 }'` - if [ "$EC2_SNAP_root" == "${EC2_SNAP_root#snap-}" ]; then - echo "ERROR: Failed to create snapshot for root disk $VM_VOLUME_NAME" - cleanup_and_exit 3 - fi - EC2_SNAP_swap=`ec2-create-snapshot --region "$BUILD_EC2_REGION" "$VM_VOLUME_SWAP" | awk '{ print $2 }'` - if [ "$EC2_SNAP_swap" == "${EC2_SNAP_swap#snap-}" ]; then - echo "ERROR: Failed to create snapshot for swap disk $VM_VOLUME_SWAP" - ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" - cleanup_and_exit 3 - fi - # wait for snapshots being processed - while true; do - c=`ec2-describe-snapshots --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" "$EC2_SNAP_swap" | grep completed | wc -l` - [ "$c" == "2" ] && break - done - EC2_AMI=`ec2-register --region "$BUILD_EC2_REGION" -n build-$VM_VOLUME_NAME -a x86_64 -b "/dev/sda1=$EC2_SNAP_root::false" -b "/dev/sdb1=$EC2_SNAP_swap::false" --kernel "$BUILD_EC2_AKI" | awk '{ print $2 }'` - if [ "$EC2_AMI" == "${EC2_AMI#ami-}" ]; then - echo "ERROR: Failed to register the AMI" - ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" - ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap" - cleanup_and_exit 3 - fi - INSTANCE=`ec2-run-instances --region "$BUILD_EC2_REGION" -z "$BUILD_EC2_ZONE" -t $BUILD_EC2_TYPE --kernel "$BUILD_EC2_AKI" --instance-initiated-shutdown-behavior terminate "$EC2_AMI" | grep ^INSTANCE | awk '{ print $2 }'` - if [ "$INSTANCE" == "${INSTANCE#i-}" ]; then - echo "ERROR: Failed to run the instance for AMI $EC2_AMI" - ec2-deregister --region "$BUILD_EC2_REGION" "$EC2_AMI" - ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" - ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap" - cleanup_and_exit 3 - fi - echo "Waiting for finishing the build. No log file until then on EC2 ...." - I=0 - L=0 - EC2_EXTRACT_VOLUME_root="" - EC2_EXTRACT_VOLUME_swap="" - temp_file=`mktemp` - while true; do - ec2-describe-instances --region "$BUILD_EC2_REGION" "$INSTANCE" > $temp_file - state=`grep ^INSTANCE "$temp_file"` - if [ -z "$EC2_EXTRACT_VOLUME_root" ]; then - EC2_EXTRACT_VOLUME_root=`grep ^BLOCKDEVICE $temp_file | grep /dev/sda1 | awk '{ print $3 }'` - EC2_EXTRACT_VOLUME_swap=`grep ^BLOCKDEVICE $temp_file | grep /dev/sdb1 | awk '{ print $3 }'` - fi - # the column of the state is at a differen position depending on the state :/ -# [ "$state" == "${state/stopped/}" ] || break - [ "$state" == "${state/terminated/}" ] || break - I=$(( $I + 1 )) - if [ $I -gt 10 ]; then - echo -n . - I="0" - L=$(( $L + 1 )) - fi - if [ $L -gt 10 ]; then - # dump entire console log as raw here - ec2-get-console-output --region "$BUILD_EC2_REGION" -r "$INSTANCE" - L="0" - fi - sleep 1 - done - rm "$temp_file" - echo - ec2-deregister --region "$BUILD_EC2_REGION" "$EC2_AMI" - # snapshots get deleted after extract - elif [ "$VM_TYPE" = 'openstack' ]; then - echo "booting $VM_TYPE ..." - nova boot --image $OBS_OPENSTACK_KERNEL_IMAGE_ID --flavor m1.small --block_device_mapping vda=${VM_VOLUME_NAME}::$(( $VMDISK_ROOTSIZE / 1024 )):0 --block_device_mapping vdb=${VM_VOLUME_SWAP}::1:0 --poll "build-$VM_VOLUME_NAME" || cleanup_and_exit 3 - -# while [ `nova show "build-$VM_VOLUME_NAME" | sed -n -e 's,|[ ]*status[ ]*|[ ]*\([^ ]*\).*,\1,p'` == "ACTIVE" ]; do -# sleep 5 -# done - nova console-log "build-$VM_VOLUME_NAME" - elif [ "$VM_TYPE" = 'lxc' ]; then - echo "booting $VM_TYPE ..." - LXCCONF="$BUILD_ROOT/.build.lxc.conf" - rm -f "$LXCCONF" - cat $BUILD_DIR/lxc.conf > "$LXCCONF" - cat >> "$LXCCONF" <<-EOF - lxc.rootfs = $BUILD_ROOT - EOF - # XXX: do this always instead of leaking the hosts' one? - echo "rootfs / rootfs rw 0 0" > $BUILD_ROOT/etc/mtab - LXCID=${BUILD_ROOT##*/} - lxc-destroy -n "$LXCID" >/dev/null 2>&1 || true - lxc-create -n "$LXCID" -f "$LXCCONF" || cleanup_and_exit 1 - lxc-start -n "$LXCID" "$vm_init_script" - BUILDSTATUS="$?" - test "$BUILDSTATUS" != 255 || BUILDSTATUS=3 - cleanup_and_exit "$BUILDSTATUS" - elif [ "$VM_TYPE" = 'zvm' ]; then - echo "booting $VM_TYPE ..." - zvm_cp ipl $VM_WORKER $VM_VOLUME_ROOT - # start IUCV Console - # IPL needs some time until IPL really starts... - sleep 2 - # start iucv console. This blocks until build process is finished. - iucvconn $VM_WORKER lnxhvc0 - # Take root and swap devices from worker - # This might be critical regarding timing (IUCV_CONSOLE down, but machine still running) - sleep 5 - zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT - zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP - VM_IMAGE="/dev/$(zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_ROOT $zvm_mult_pass $zvm_worker_nr)" - VM_SWAP="/dev/$(zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_SWAP $zvm_mult_pass $zvm_worker_nr)" - fi - - if [ "$VM_TYPE" = 'openstack' ]; then - VM_IMAGE=`cloud_volume_attach "$VM_SERVER" "$VM_VOLUME_NAME" "$VM_IMAGE"` - [ "${VM_IMAGE:0:5}" == "/dev/" ] || cleanup_and_exit 3 - VM_SWAP=`cloud_volume_attach "$VM_SERVER" "$VM_VOLUME_SWAP" "$VM_SWAP"` - [ "${VM_SWAP:0:5}" == "/dev/" ] || cleanup_and_exit 3 - fi - if [ "$VM_TYPE" = 'ec2' ]; then - VM_IMAGE=`cloud_volume_attach "$VM_SERVER" "$EC2_EXTRACT_VOLUME_root" "$VM_IMAGE"` - [ "${VM_IMAGE:0:5}" == "/dev/" ] || cleanup_and_exit 3 - VM_SWAP=`cloud_volume_attach "$VM_SERVER" "$EC2_EXTRACT_VOLUME_swap" "$VM_SWAP"` - [ "${VM_SWAP:0:5}" == "/dev/" ] || cleanup_and_exit 3 - fi - - # Exctract build resutls from VM - if [ "$VM_TYPE" = 'emulator' ]; then - # Emulators may not offer to use a second swap space. - # So we just mount the filesystem. - # WARNING: This is not safe against attacks. - - mkdir -p $BUILD_ROOT/.build.packages - cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1 - mkdir -p .mount - mount $VM_IMAGE -o loop .mount - if [ -e .mount/.build.packages ]; then - cp -a .mount/.build.packages/* . - fi - exitcode=`cat .mount/.build/_exitcode` - umount .mount - rmdir .mount - - cleanup_and_exit "$exitcode" - - elif test -n "$VM_SWAP" ; then - BUILDSTATUS=`dd if="$VM_SWAP" bs=12 count=1 2>/dev/null` - case $BUILDSTATUS in - BUILDSTATUS[02]) - mkdir -p $BUILD_ROOT/.build.packages - cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1 - echo "build: extracting built packages..." - extractbuild --disk "$VM_IMAGE" --input "$VM_SWAP" --skip 512 -v || cleanup_and_exit 3 - # create same layout as with plain chroot - if test "$BUILDTYPE" = spec ; then - mkdir -p SRPMS - for i in *src.rpm *.desktopfiles ; do - test -e "$i" || continue - mv "$i" SRPMS/ - done - for i in *.rpm ; do - test -e "$i" || continue - arch=${i%.rpm} - arch=${i%.delta} - arch=${arch##*\.} - mkdir -p RPMS/$arch - mv "$i" RPMS/$arch/ - done - elif test "$BUILDTYPE" = dsc ; then - mkdir -p DEBS - find . -type f | while read i; do mv "$i" DEBS/; done - elif test "$BUILDTYPE" = arch ; then - mkdir -p ARCHPKGS - find . -type f | while read i; do mv "$i" ARCHPKGS/; done - elif test "$BUILDTYPE" = kiwi ; then - mkdir -p KIWI - find . -type f | while read i; do mv "$i" KIWI/; done - fi - for i in * ; do - test -f "$i" || continue - case $i in - _*|.*) ;; - *) mkdir -p OTHER ; mv $i OTHER/ ;; - esac - done - if test "$statistics" = 1; then - mkdir -p OTHER - [ -e _statistics ] && mv _statistics OTHER/ - [ -n "$TIME_PREINSTALL" ] && echo "TIME_preinstall: $TIME_PREINSTALL" >> OTHER/_statistics - TIME_TOTAL=$(( `date +%s` - $TIME_START_TIME )) - echo "TIME_total: $TIME_TOTAL" >> OTHER/_statistics - fi - if [ "$VM_TYPE" = 'zvm' ]; then - # free worker devices - zvm_cp volume_detach_local $VM_VOLUME_ROOT ${zvm_worker_nr} - zvm_cp volume_detach_local $VM_VOLUME_SWAP ${zvm_worker_nr} - fi - if [ "$VM_TYPE" = 'openstack' ]; then - cloud_volume_detach "$VM_SERVER" "$VM_VOLUME_NAME" - cloud_volume_detach "$VM_SERVER" "$VM_VOLUME_SWAP" - fi - cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS} - ;; - BUILDSTATUS*) - if [ "$VM_TYPE" = 'zvm' ]; then - # free worker devices - zvm_cp volume_detach_local $VM_VOLUME_ROOT ${zvm_worker_nr} - zvm_cp volume_detach_local $VM_VOLUME_SWAP ${zvm_worker_nr} - fi - cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS} - ;; - *) - if [ "$VM_TYPE" = 'zvm' ]; then - # free worker devices - zvm_cp volume_detach_local $VM_VOLUME_ROOT ${zvm_worker_nr} - zvm_cp volume_detach_local $VM_VOLUME_SWAP ${zvm_worker_nr} - fi - echo "No buildstatus set, either the base system is broken (glibc/bash/perl)" - echo "or the build host has a kernel or hardware problem..." - cleanup_and_exit 3 - ;; - esac - - cleanup_and_exit 1 - fi - + vm_first_stage cleanup_and_exit 0 fi @@ -2642,8 +1129,11 @@ for SPECFILE in "${SPECFILES[@]}" ; do echo "BUILD_INCARNATION=$INCARNATION" > $BUILD_ROOT/.buildenv CREATE_BUILD_BINARIES= test "$BUILDTYPE" = preinstallimage && mkdir -p $BUILD_ROOT/.preinstall_image - egrep '^#[ ]*needsbinariesforbuild[ ]*$' >/dev/null <$MYSRCDIR/$SPECFILE && CREATE_BUILD_BINARIES=--create-build-binaries - set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $USE_SYSTEM_QEMU $KEEP_PACKS $USEUSEDFORBUILD $CREATE_BUILD_BINARIES $RPMLIST "$MYSRCDIR/$SPECFILE" $ADDITIONAL_PACKS + egrep '^#[ ]*needsbinariesforbuild[ ]*$' >/dev/null <$MYSRCDIR/$RECIPEFILE && CREATE_BUILD_BINARIES=--create-build-binaries + test "$BUILDTYPE" = mock && CREATE_BUILD_BINARIES=--create-build-binaries + test "$BUILDTYPE" = debootstrap && CREATE_BUILD_BINARIES=--create-build-binaries + test "$BUILDTYPE" = livebuild && CREATE_BUILD_BINARIES=--create-build-binaries + set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $DLNOSIGNATURE $KEEP_PACKS $USEUSEDFORBUILD $CREATE_BUILD_BINARIES $RPMLIST "$MYSRCDIR/$RECIPEFILE" $ADDITIONAL_PACKS echo "$* ..." start_time=`date +%s` "$@" || cleanup_and_exit 1 @@ -2665,45 +1155,9 @@ for SPECFILE in "${SPECFILES[@]}" ; do copy_oldpackages fi + # hack to process preinstallimages early if test "$BUILDTYPE" = preinstallimage ; then - echo "creating preinstall image..." - test -d "$BUILD_ROOT/.preinstall_image" || cleanup_and_exit 1 - cd $BUILD_ROOT || cleanup_and_exit 1 - TAR="tar" - if test -x /usr/bin/bsdtar; then - TAR="/usr/bin/bsdtar --format gnutar --chroot" - fi - TOPDIRS= - for DIR in .* * ; do - case "$DIR" in - .|..) continue ;; - .build*) continue ;; - .preinstallimage*) continue ;; - .srcfiles*) continue ;; - .pkgs) continue ;; - .rpm-cache) continue ;; - installed-pkg) continue ;; - proc|sys) continue ;; - esac - TOPDIRS="$TOPDIRS $DIR" - done - if ! $TAR -czf .preinstallimage.$$.tar.gz --one-file-system $TOPDIRS ; then - cleanup_and_exit 1 - fi - echo "image created." - TOPDIR=/usr/src/packages - mkdir -p $BUILD_ROOT$TOPDIR/OTHER - rm -f $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.info - for PKG in $BUILD_ROOT/.preinstall_image/* ; do - PKG=${PKG##*/} - read PKG_HDRMD5 PKGID < $BUILD_ROOT/.preinstall_image/$PKG - test -n "$PKG_HDRMD5" || cleanup_and_exit 1 - echo "$PKG_HDRMD5 $PKG" >> $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.info - done - mv $BUILD_ROOT/.preinstallimage.$$.tar.gz $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.tar.gz - rm -f $BUILD_ROOT/.build.packages - ln -s ${TOPDIR#/} $BUILD_ROOT/.build.packages - test -d "$SRCDIR" && cd "$SRCDIR" + recipe_build continue fi @@ -2712,18 +1166,6 @@ for SPECFILE in "${SPECFILES[@]}" ; do fi # - # fix rpmrc if we are compiling for i686 - # - test -f $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 && mv $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 $BUILD_ROOT/usr/lib/rpm/rpmrc - if test -e $BUILD_ROOT/usr/lib/rpm/rpmrc -a "$BUILD_ARCH" != "${BUILD_ARCH#i686}" ; then - mv $BUILD_ROOT/usr/lib/rpm/rpmrc $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 - sed -e 's/^buildarchtranslate: athlon.*/buildarchtranslate: athlon: i686/' -e 's/^buildarchtranslate: i686.*/buildarchtranslate: i686: i686/' < $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 > $BUILD_ROOT/usr/lib/rpm/rpmrc - fi - if test "$DO_BUILD" = false ; then - cleanup_and_exit 0 - fi - - # # install dummy sign program if needed # test -f $BUILD_ROOT/usr/bin/sign_installed && mv $BUILD_ROOT/usr/bin/sign_installed $BUILD_ROOT/usr/bin/sign @@ -2739,23 +1181,22 @@ for SPECFILE in "${SPECFILES[@]}" ; do BUILD_USER=abuild if test -x $BUILD_ROOT/bin/rpm ; then SUSE_VERSION=`chroot $BUILD_ROOT /bin/rpm --eval '%{?suse_version}' 2>/dev/null` - if test -n "$SUSE_VERSION" && test "$SUSE_VERSION" -le 1020 ; then - BUILD_USER=root - fi + test -n "$SUSE_VERSION" -a "${SUSE_VERSION:-0}" -le 1020 && BUILD_USER=root fi if test "$BUILD_USER" = abuild ; then - egrep '^#[ ]*needsrootforbuild[ ]*$' >/dev/null <$SPECFILE && BUILD_USER=root + egrep '^#[ ]*needsrootforbuild[ ]*$' >/dev/null <$RECIPEFILE && BUILD_USER=root else - egrep '^#[ ]*norootforbuild[ ]*$' >/dev/null <$SPECFILE && BUILD_USER=abuild + egrep '^#[ ]*norootforbuild[ ]*$' >/dev/null <$RECIPEFILE && BUILD_USER=abuild fi test -n "$NOROOTFORBUILD" && BUILD_USER=abuild # appliance builds must run as root - if test "$BUILDTYPE" = kiwi; then - imagetype=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $SPECFILE imagetype) - test "$imagetype" = 'product' || BUILD_USER=root + if test "$BUILDTYPE" = kiwi ; then + imagetype=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $RECIPEFILE imagetype) + test "$imagetype" = product || BUILD_USER=root fi + # fixup passwd/group if test $BUILD_USER = abuild ; then if ! egrep '^abuild:' >/dev/null <$BUILD_ROOT/etc/passwd ; then echo "abuild:x:${ABUILD_UID}:${ABUILD_GID}:Autobuild:/home/abuild:/bin/bash" >>$BUILD_ROOT/etc/passwd @@ -2774,10 +1215,10 @@ for SPECFILE in "${SPECFILES[@]}" ; do fi fi if test -f $BUILD_ROOT/etc/shadow ; then - sed -e "s@^root::@root:*:@" < $BUILD_ROOT/etc/shadow > $BUILD_ROOT/etc/shadow.t && mv $BUILD_ROOT/etc/shadow.t $BUILD_ROOT/etc/shadow + sed -i -e "s@^root::@root:*:@" $BUILD_ROOT/etc/shadow fi if test -f $BUILD_ROOT/etc/gshadow ; then - sed -e "s@^root::@root:*:@" < $BUILD_ROOT/etc/gshadow > $BUILD_ROOT/etc/gshadow.t && mv $BUILD_ROOT/etc/gshadow.t $BUILD_ROOT/etc/gshadow + sed -i -e "s@^root::@root:*:@" $BUILD_ROOT/etc/gshadow fi BUILD_USER_ABUILD_USED=true else @@ -2786,340 +1227,92 @@ for SPECFILE in "${SPECFILES[@]}" ; do ABUILD_GID=0 if egrep '^abuild:' >/dev/null <$BUILD_ROOT/etc/passwd ; then rm -rf "$BUILD_ROOT/home/abuild" - egrep -v '^abuild:' <$BUILD_ROOT/etc/passwd >$BUILD_ROOT/etc/passwd.new - mv $BUILD_ROOT/etc/passwd.new $BUILD_ROOT/etc/passwd - egrep -v '^abuild:' <$BUILD_ROOT/etc/group >$BUILD_ROOT/etc/group.new - mv $BUILD_ROOT/etc/group.new $BUILD_ROOT/etc/group + sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/passwd + sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/group if test -f $BUILD_ROOT/etc/shadow ; then - egrep -v '^abuild:' <$BUILD_ROOT/etc/shadow >$BUILD_ROOT/etc/shadow.new - mv $BUILD_ROOT/etc/shadow.new $BUILD_ROOT/etc/shadow + sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/shadow fi if test -f $BUILD_ROOT/etc/gshadow ; then - egrep -v '^abuild:' <$BUILD_ROOT/etc/gshadow >$BUILD_ROOT/etc/gshadow.new - mv $BUILD_ROOT/etc/gshadow.new $BUILD_ROOT/etc/gshadow + sed -i -e '/^abuild:/d' $BUILD_ROOT/etc/gshadow fi fi fi - if test "$BUILDTYPE" = spec ; then - TOPDIR=`chroot $BUILD_ROOT su -c "rpm --eval '%_topdir'" - $BUILD_USER` - if test -z "$TOPDIR"; then - echo "Error: TOPDIR empty" - cleanup_and_exit 1 - fi - else - TOPDIR=/usr/src/packages - mkdir -p $BUILD_ROOT$TOPDIR - fi - - rm -f $BUILD_ROOT/.build.packages - ln -s ${TOPDIR#/} $BUILD_ROOT/.build.packages - mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null mount -n -tdevpts -omode=0620,gid=5 none $BUILD_ROOT/dev/pts 2> /dev/null # needed for POSIX semaphores + test -d $BUILD_ROOT/dev/shm || rm -f $BUILD_ROOT/dev/shm + mkdir -p $BUILD_ROOT/dev/shm mount -n -ttmpfs none $BUILD_ROOT/dev/shm 2> /dev/null - setupicecream + if test -n "$RUNNING_IN_VM" ; then + if test -x /sbin/ip ; then + ip addr add 127.0.0.1/8 dev lo + ip addr add ::1/128 dev lo + ip link set lo up + else + ifconfig lo 127.0.0.1 up + ifconfig lo add ::1/128 + fi + if test -n "$MYHOSTNAME" ; then + hostname "$MYHOSTNAME" + fi + fi + setupicecream setupccache + # fill build directories with sources. Also sets TOPDIR + recipe_setup + + # strip prefix from autogenerated files of source services. + for i in $BUILD_ROOT$TOPDIR/SOURCES/_service\:* ; do + mv "$i" "${i%/*}/${i##*:}" + done + RECIPEFILE="${RECIPEFILE##*:}" + + # create .build.packages link + rm -f $BUILD_ROOT/.build.packages + ln -s ${TOPDIR#/} $BUILD_ROOT/.build.packages + # nasty hack to prevent rpath on known paths # FIXME: do this only for suse if test -d "$BUILD_ROOT/etc/profile.d" ; then echo "export SUSE_IGNORED_RPATHS=/etc/ld.so.conf" > "$BUILD_ROOT/etc/profile.d/buildsystem.sh" fi - # - # now clean up RPM building directories - if [ "$NO_TOPDIR_CLEANUP" = false ]; then - rm -rf "$BUILD_ROOT$TOPDIR" - for i in BUILD RPMS/`uname -m` RPMS/i386 RPMS/noarch SOURCES SPECS SRPMS BUILDROOT OTHER ; do - mkdir -p $BUILD_ROOT$TOPDIR/$i - done - fi - - chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR" - check_exit - - mkdir -p $BUILD_ROOT$TOPDIR/SOURCES - if test "$BUILDTYPE" = kiwi ; then - mkdir -p $BUILD_ROOT$TOPDIR/KIWI - if test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then - mv "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/ - else - if test -z "$LINKSOURCES" ; then - cp -dLR "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/ - else - cp -lR "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/ - fi - if test "$?" != 0 ; then - echo "source copy failed" - cleanup_and_exit 1 - fi - fi - else - cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/ - fi - # strip prefix from autogenerated files of source services. - for i in $BUILD_ROOT$TOPDIR/SOURCES/_service\:*; do - mv "$i" "${i%/*}/${i##*:}" - done - SPECFILE="${SPECFILE##*:}" - + # get rid of old src dir, it is no longer needed and just wastes space test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir && rm -rf "$MYSRCDIR" - CHANGELOGARGS= - test -n "$CHANGELOG" -a -f "$BUILD_ROOT/.build-changelog" && CHANGELOGARGS="--changelog $BUILD_ROOT/.build-changelog" - - if test "$BUILDTYPE" = spec ; then - # do buildrequires/release substitution - args=() - if test -n "$RELEASE"; then - args=(--release "$RELEASE") - fi - substitutedeps "${args[@]}" --root "$BUILD_ROOT" --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" $CHANGELOGARGS "$BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE" "$BUILD_ROOT/.spec.new" || cleanup_and_exit 1 - # extract macros from configuration - getmacros --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" > $BUILD_ROOT/root/.rpmmacros - if test -n "$BUILD_DEBUG" ; then - echo ' -%prep %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%prep -%package %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%package -%_build_insert_debug_package \ -%global __debug_package 1 \ -%undefine _enable_debug_packages \ -%debug_package - -' >> $BUILD_ROOT/root/.rpmmacros - fi - if [ -n "$BUILD_JOBS" ]; then - cat >> $BUILD_ROOT/root/.rpmmacros <<-EOF - %jobs $BUILD_JOBS - %_smp_mflags -j$BUILD_JOBS - EOF - fi - test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmmacros $BUILD_ROOT/home/abuild/.rpmmacros - # extract optflags from configuration - getoptflags --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" ${BUILD_DEBUG:+--debug} > $BUILD_ROOT/root/.rpmrc - test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmrc $BUILD_ROOT/home/abuild/.rpmrc - if test -z "$ABUILD_TARGET"; then - ABUILD_TARGET=$(getchangetarget --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" ) - test -z "$ABUILD_TARGET" || echo "build target is $ABUILD_TARGET" - fi - fi - if test -f $BUILD_ROOT/.spec.new ; then - if ! cmp -s $BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE $BUILD_ROOT/.spec.new ; then - echo ----------------------------------------------------------------- - echo "I have the following modifications for $SPECFILE:" - sed -e "/^%changelog/q" $BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE > $BUILD_ROOT/.spec.t1 - sed -e "/^%changelog/q" $BUILD_ROOT/.spec.new > $BUILD_ROOT/.spec.t2 - diff $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2 - rm -f $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2 - mv $BUILD_ROOT/.spec.new $BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE - else - rm -f $BUILD_ROOT/.spec.new - fi - fi - - if test "$BUILDTYPE" = dsc ; then - rm -rf "$BUILD_ROOT$TOPDIR/BUILD" - mkdir -p $BUILD_ROOT$TOPDIR/SOURCES.DEB - chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR" - DEB_TRANSFORM= - DEB_SOURCEDIR=$TOPDIR/SOURCES - DEB_DSCFILE=$SPECFILE - for f in $BUILD_ROOT$TOPDIR/SOURCES/debian.* ; do - test -f $f && DEB_TRANSFORM=true - done - if test -n "$DEB_TRANSFORM" ; then - echo "running debian transformer..." - if ! debtransform $CHANGELOGARGS $BUILD_ROOT$TOPDIR/SOURCES $BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE $BUILD_ROOT$TOPDIR/SOURCES.DEB ; then - echo "debian transforming failed." - cleanup_and_exit 1 - fi - DEB_SOURCEDIR=$TOPDIR/SOURCES.DEB - for DEB_DSCFILE in $BUILD_ROOT/$DEB_SOURCEDIR/*.dsc ; do : ; done - DEB_DSCFILE="${DEB_DSCFILE##*/}" - fi - chroot $BUILD_ROOT su -c "dpkg-source -x $DEB_SOURCEDIR/$DEB_DSCFILE $TOPDIR/BUILD" - $BUILD_USER - fi - - if test "$BUILDTYPE" = arch ; then - echo "Preparing sources..." - chroot $BUILD_ROOT su -c "cd $TOPDIR/SOURCES && makepkg -s -o 2>&1 >/dev/null" - $BUILD_USER - mv $BUILD_ROOT/$TOPDIR/SOURCES/* -t $BUILD_ROOT/$TOPDIR/BUILD - fi + # patch recipes + recipe_prepare + # hmmm chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR" + cd $BUILD_ROOT$TOPDIR/SOURCES || cleanup_and_exit 1 echo ----------------------------------------------------------------- if test "$BUILD_USER" = root ; then - echo ----- building $SPECFILE + echo ----- building $RECIPEFILE else - echo ----- building $SPECFILE "(user $BUILD_USER)" + echo ----- building $RECIPEFILE "(user $BUILD_USER)" fi echo ----------------------------------------------------------------- echo ----------------------------------------------------------------- - if [ -n "$RUNNING_IN_VM" ]; then - if [ -x /sbin/ip ]; then - ip addr add 127.0.0.1/8 dev lo - ip link set lo up - else - ifconfig lo 127.0.0.1 up - fi - if [ -n "$MYHOSTNAME" ]; then - hostname "$MYHOSTNAME" - fi - fi - BUILD_SUCCEEDED=false if test -n "$OVERLAY" ; then - if test -d "$OVERLAY"; then - pushd $OVERLAY - echo "Copying overlay to BUILD_ROOT" - tar -cpf - . | (cd $BUILD_ROOT ; tar -xvf -) - popd - else - echo "OVERLAY ($OVERLAY) is no directory - skipping" - fi + copy_overlay fi if test -n "$RSYNCSRC" ; then - if test -n "$RSYNCDEST"; then - if test -d "$RSYNCSRC"; then - if ! test -d "$BUILD_ROOT/$RSYNCDEST"; then - echo "ATTENTION! Creating target directory ($BUILD_ROOT/$RSYNCDEST) as its not there." - mkdir -p $BUILD_ROOT/$RSYNCDEST - fi - echo "Running rsync ..." - rsync -av $RSYNCSRC/* $BUILD_ROOT/$RSYNCDEST/ - chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/$RSYNCDEST" - RSYNCDONE=true - echo "... done" - else - echo "RSYNCSRC is no directory - skipping" - fi - else - echo "RSYNCSRC given, but not RSYNCDEST - skipping" - fi + run_rsync fi start_time=`date +%s` - if test "$BUILDTYPE" = spec ; then - test -z "$BUILD_RPM_BUILD_STAGE" && BUILD_RPM_BUILD_STAGE=-ba - - rpmbuild=rpmbuild - test -x $BUILD_ROOT/usr/bin/rpmbuild || rpmbuild=rpm - - # XXX: move _srcdefattr to macro file? - rpmbopts=("--define" "_srcdefattr (-,root,root)") - if test "$rpmbuild" == "rpmbuild" ; then - # use only --nosignature for rpm v4 - rpmbopts[${#rpmbopts[@]}]="--nosignature" - fi - if test -n "$ABUILD_TARGET" ; then - rpmbopts[${#rpmbopts[@]}]="--target=$ABUILD_TARGET" - fi - if test -n "$BUILD_DEBUG" ; then - rpmbopts[${#rpmbopts[@]}]='--define' - rpmbopts[${#rpmbopts[@]}]="_build_create_debug 1" - fi - if test -n "$DISTURL" ; then - rpmbopts[${#rpmbopts[@]}]='--define' - rpmbopts[${#rpmbopts[@]}]="disturl $DISTURL" - fi - if test -n "$RSYNCDONE" ; then - rpmbopts[${#rpmbopts[@]}]='--define' - rpmbopts[${#rpmbopts[@]}]="RSYNCDONE 1" - fi - - # su involves a shell which would require even more - # complicated quoting to bypass than this - if test "$SHORT_CIRCUIT" = false ; then - rpmbopts[${#rpmbopts[@]}]="$BUILD_RPM_BUILD_STAGE" - toshellscript $rpmbuild \ - "${definesnstuff[@]}" \ - "${rpmbopts[@]}" \ - "$TOPDIR/SOURCES/$SPECFILE" \ - > $BUILD_ROOT/.build.command - else - rpmbopts[${#rpmbopts[@]}]='--short-circuit' - buildopts="-bc -bi -bb -bs" - cmds="" - echo "#!/bin/sh -x" >$BUILD_ROOT/.build.command - echo "set -e" >>$BUILD_ROOT/.build.command - for opt in $buildopts - do - shellquote $rpmbuild \ - "${definesnstuff[@]}" \ - "${rpmbopts[@]}" $opt \ - "$TOPDIR/SOURCES/$SPECFILE" \ - >> $BUILD_ROOT/.build.command - echo >>$BUILD_ROOT/.build.command - [ "$opt" == "$BUILD_RPM_BUILD_STAGE" ] && break - done - fi - - chmod 755 $BUILD_ROOT/.build.command - check_exit - if test -n "$shell"; then - chroot $BUILD_ROOT su - - else - chroot $BUILD_ROOT su -c /.build.command - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true - fi - fi - - if test "$BUILDTYPE" = dsc ; then - # Checks to see if a build script should be used - # this allows the build environment to be manipulated - # and alternate build commands can be used -# Debian policy requires to build with single CPU by default -# if [ -n "$BUILD_JOBS" ]; then -# DSC_BUILD_JOBS="-j$BUILD_JOBS" -# fi - DSC_BUILD_CMD="dpkg-buildpackage -us -uc -rfakeroot-tcp $DSC_BUILD_JOBS" - if test -e $BUILD_ROOT/$TOPDIR/SOURCES/build.script ; then - echo "Sourcing build.script to build - it should normally run 'dpkg-buildpackage -us -uc -rfakeroot-tcp'" - DSC_BUILD_CMD="source $TOPDIR/SOURCES/build.script" - chmod +x $BUILD_ROOT/$TOPDIR/SOURCES/build.script - fi - - if test -n "$shell"; then - chroot $BUILD_ROOT su - - else - chroot $BUILD_ROOT su -c "cd $TOPDIR/BUILD && $DSC_BUILD_CMD" - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true - if test "$BUILD_SUCCEEDED" = true -a "$DO_CHECKS" != "false"; then - DEB_CHANGESFILE=${SPECFILE%.dsc}_"$(chroot $BUILD_ROOT su -c 'dpkg-architecture -qDEB_BUILD_ARCH')".changes - chroot $BUILD_ROOT su -c "which lintian > /dev/null && cd $TOPDIR && echo Running lintian && (set -x && lintian -i $DEB_SOURCEDIR/$DEB_DSCFILE)" - $BUILD_USER < /dev/null - fi - fi - - mkdir -p $BUILD_ROOT/$TOPDIR/DEBS - for DEB in $BUILD_ROOT/$TOPDIR/*.deb ; do - test -e "$DEB" && mv "$DEB" "$BUILD_ROOT/$TOPDIR/DEBS" - done - # link sources over - ln $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE $BUILD_ROOT/$TOPDIR/DEBS/ - while read f ; do - ln $BUILD_ROOT/$DEB_SOURCEDIR/$f $BUILD_ROOT/$TOPDIR/DEBS/ - done < <(sed -ne '/^Files:/,$s/^ ................................ [0-9][0-9]* //p' < $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE) - fi - - if test "$BUILDTYPE" = arch ; then - chroot $BUILD_ROOT su -c "cd $TOPDIR/BUILD && makepkg -f" - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true - mkdir -p $BUILD_ROOT/$TOPDIR/ARCHPKGS - for PKG in $BUILD_ROOT/$TOPDIR/BUILD/*.pkg.tar.?z ; do - test -e "$PKG" && mv "$PKG" "$BUILD_ROOT/$TOPDIR/ARCHPKGS" - done - fi - - if test "$BUILDTYPE" = kiwi ; then - . $BUILD_DIR/build_kiwi.sh - run_kiwi - fi - if test "$statistics" = 1; then + recipe_build + if test "$DO_STATISTICS" = 1; then mkdir -p $TOPDIR/OTHER echo "TIME_main_build: $(( `date +%s` - $start_time ))" >> $TOPDIR/OTHER/_statistics fi @@ -3129,7 +1322,7 @@ for SPECFILE in "${SPECFILES[@]}" ; do test -d "$SRCDIR" && cd "$SRCDIR" done -if test -n "$RUNNING_IN_VM" -a -n "$VM_SWAP"; then +if test -n "$RUNNING_IN_VM" -a -n "$DO_STATISTICS" ; then touch /.build/_statistics.exit fi @@ -3137,60 +1330,30 @@ RPMS=`find $BUILD_ROOT/$TOPDIR/RPMS -type f -name "*.rpm" 2>/dev/null || true` DEBS=`find $BUILD_ROOT/$TOPDIR/DEBS -type f -name "*.deb" 2>/dev/null || true` if test -n "$RPMS" -a -n "$BUILD_USER_ABUILD_USED" ; then - echo "... checking for files with abuild user/group" - BADFILE= - while read un gn fn ; do - if test "$un" = abuild -o "$gn" = abuild -o "$un" = ${ABUILD_UID} -o "$gn" = ${ABUILD_GID} ; then - echo " $un $gn $fn" - BADFILE=true - fi - done < <(rpm -qp --qf '[%{FILEUSERNAME} %{FILEGROUPNAME} %{FILENAMES}\n]' $RPMS) - if test -n "$BADFILE" ; then - echo "please fix your filelist (e.g. add defattr)" - cleanup_and_exit 1 - fi + recipe_check_file_owners fi if test -n "$RPMS" -a -d "$BUILD_ROOT/usr/lib/build/checks" ; then - export PNAME="" export DO_RPM_REMOVE=true + # find package name + export PNAME= for SRPM in $BUILD_ROOT/$TOPDIR/SRPMS/*src.rpm ; do test -f "$SRPM" && PNAME=`rpm --nodigest --nosignature -qp --qf "%{NAME}" $SRPM` done mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null for CHECKSCRIPT in $BUILD_ROOT/usr/lib/build/checks/* ; do - echo "... running `basename $CHECKSCRIPT`" + echo "... running ${CHECKSCRIPT##*/}" $CHECKSCRIPT || cleanup_and_exit 1 done umount -n $BUILD_ROOT/proc 2>/dev/null || true fi +# checkscripts may have deleted some binaries RPMS=`find $BUILD_ROOT/$TOPDIR/RPMS -type f -name "*.rpm" 2>/dev/null || true` DEBS=`find $BUILD_ROOT/$TOPDIR/DEBS -type f -name "*.deb" 2>/dev/null || true` -if test -n "$RPMS" -a "$DO_CHECKS" != "false" -a -x "$BUILD_ROOT/opt/testing/bin/rpmlint" ; then - LINT_RPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/RPMS \ - \( -name "*-debuginfo-*" -o -name "*-debugsource-*" \ - -o -name "*-32bit-*" -o -name "*-64bit-*" \ - -o -name "*-x86-*" -o -name "*-ia32-*" \) -prune \ - -o -type f -name '*.rpm' -print)) - SRPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/SRPMS -type f -name "*.rpm")) - echo - echo "RPMLINT report:" - echo "===============" - rpmlint_logfile=$TOPDIR/OTHER/rpmlint.log - rm -f "$BUILD_ROOT$rpmlint_logfile" - ret=0 - mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null - chroot $BUILD_ROOT su -s /opt/testing/bin/rpmlint "$BUILD_USER" -- \ - --info ${LINT_RPM_FILE_LIST[*]#$BUILD_ROOT} \ - ${SRPM_FILE_LIST[*]#$BUILD_ROOT} > "$BUILD_ROOT$rpmlint_logfile" || ret=1 - cat "$BUILD_ROOT$rpmlint_logfile" - echo - umount -n $BUILD_ROOT/proc 2>/dev/null || true - if test "$ret" = 1; then - cleanup_and_exit 1 - fi +if test -n "$RPMS" -a "$DO_CHECKS" != false ; then + recipe_run_rpmlint fi if test \( -n "$RPMS" -o -n "$DEBS" \) -a -n "$CREATE_BASELIBS"; then @@ -3198,102 +1361,23 @@ if test \( -n "$RPMS" -o -n "$DEBS" \) -a -n "$CREATE_BASELIBS"; then fi exitcode=0 -# post build scripts + +# post build work # TODO: don't hardcode. instead run scripts in a directory as it's done for the checks -if test -n "$RPMS" \ - -a -d "$BUILD_ROOT/$TOPDIR/RPMS" \ - -a -d "$BUILD_ROOT/.build.oldpackages" \ - ; then - if test -x "$BUILD_ROOT/usr/lib/build/same-build-result.sh" ; then - echo "... comparing built packages with the former built" - mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null - if chroot $BUILD_ROOT /usr/lib/build/same-build-result.sh /.build.oldpackages "$TOPDIR/RPMS" "$TOPDIR/SRPMS"; then - chroot $BUILD_ROOT touch /.build/.same_result_marker - # XXX: dirty build service hack. fix bs_worker. Search for - # 'same_result_marker' for traces of a first try to get rid of this - if test -n "$REASON" -a -n "$DISTURL"; then - exitcode=2 - fi - fi - umount -n $BUILD_ROOT/proc 2>/dev/null || true - fi - if test ! -e $BUILD_ROOT/.build/.same_result_marker \ - -a -x "$BUILD_ROOT/usr/bin/makedeltarpm" \ - -a -x $BUILD_ROOT/usr/lib/build/mkdrpms; then - echo "... creating delta rpms" - ds=("$BUILD_ROOT/$TOPDIR"/RPMS/* "$BUILD_ROOT$TOPDIR/SRPMS") - chroot $BUILD_ROOT /usr/lib/build/mkdrpms /.build.oldpackages "${ds[@]#$BUILD_ROOT}" +if test -n "$RPMS" -a -d "$BUILD_ROOT/.build.oldpackages" ; then + recipe_compare_oldpackages + # no need to create deltas if the build is the same + if test ! -e $BUILD_ROOT/.build/.same_result_marker ; then + recipe_create_deltarpms fi fi -if test -n "$RUNNING_IN_VM"; then - if test "$statistics" = 1; then - echo "... saving built statistics" - [ -n "$TIME_INSTALL" ] && echo "TIME_install: $TIME_INSTALL" >> $BUILD_ROOT$TOPDIR/OTHER/_statistics - if [ -e /.build/_statistics.df ]; then - echo -n "MAX_mb_used_on_disk: " >> $TOPDIR/OTHER/_statistics - cat /.build/_statistics.df >> $TOPDIR/OTHER/_statistics - echo "" >> $TOPDIR/OTHER/_statistics - rm /.build/_statistics.df - fi - if [ -e /.build/_statistics.memory ]; then - echo -n "MAX_mb_used_memory: " >> $TOPDIR/OTHER/_statistics - cat /.build/_statistics.memory >> $TOPDIR/OTHER/_statistics - echo "" >> $TOPDIR/OTHER/_statistics - rm /.build/_statistics.memory - fi - mkdir -p /sys - mount -n sys /sys -t sysfs - device="hda1" - [ -e /dev/sda ] && device="sda" - [ -e /dev/vda ] && device="vda" - [ -e /dev/dasda ] && device="dasda" # in z/VM - [ -e /dev/nfhd0 ] && device="nfhd0" # in aranym - if [ -e /sys/block/${device}/stat ]; then - disk=(`cat /sys/block/${device}/stat`) - [ "0${disk[0]}" -gt 0 ] && echo "IO_requests_read: ${disk[0]}" >> $TOPDIR/OTHER/_statistics - [ "0${disk[2]}" -gt 0 ] && echo "IO_sectors_read: ${disk[2]}" >> $TOPDIR/OTHER/_statistics - [ "0${disk[4]}" -gt 0 ] && echo "IO_requests_write: ${disk[4]}" >> $TOPDIR/OTHER/_statistics - [ "0${disk[6]}" -gt 0 ] && echo "IO_sectors_write: ${disk[6]}" >> $TOPDIR/OTHER/_statistics - else - echo "ERROR: no root disk device found, yet another new device name?" - ls -l /sys/block/ - fi - umount /sys - fi - - if test -n "$VM_SWAP"; then - echo "... saving built packages" - swapoff "$VM_SWAP" - args="--padstart 512 --padend 512 -v" - case "$BUILDTYPE" in - spec) - computeblocklists $args $TOPDIR/RPMS/*/*.{d,}rpm $TOPDIR/SRPMS/* $TOPDIR/OTHER/* > "$VM_SWAP" - ;; - dsc) - computeblocklists $args $TOPDIR/DEBS/*.deb $TOPDIR/SOURCES.DEB/* $TOPDIR/OTHER/* > "$VM_SWAP" - ;; - kiwi) - computeblocklists $args $TOPDIR/KIWI/* $TOPDIR/OTHER/* > "$VM_SWAP" - ;; - arch) - computeblocklists $args $TOPDIR/ARCHPKGS/* $TOPDIR/OTHER/* > "$VM_SWAP" - ;; - preinstallimage) - computeblocklists $args $TOPDIR/OTHER/* > "$VM_SWAP" - ;; - *) - cleanup_and_exit 1 - ;; - esac || cleanup_and_exit 1 - else - # quit inside of the emulator - cleanup_and_exit "$exitcode" - fi +if test -n "$RUNNING_IN_VM" ; then + vm_wrapup_build $(recipe_resultdirs) OTHER fi echo -echo "$HOST finished \"build $SPECFILE\" at `date --utc`." +echo "$HOST finished \"build $RECIPEFILE\" at `date --utc`." echo cleanup_and_exit "$exitcode" diff --git a/build-pkg b/build-pkg new file mode 100644 index 0000000..4ffcfb1 --- /dev/null +++ b/build-pkg @@ -0,0 +1,93 @@ +# +# binary package specific functions for the build script +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +for i in rpm deb arch ; do + . "$BUILD_DIR/build-pkg-$i" +done + +pkg_initdb() { + pkg_initdb_$PSUF "$@" +} + +pkg_prepare() { + pkg_prepare_$PSUF "$@" +} + +pkg_install() { + pkg_install_$PSUF "$@" +} + +pkg_verify_installed() { + pkg_verify_installed_$PSUF "$@" +} + +pkg_erase() { + pkg_erase_$PSUF "$@" +} + +pkg_cumulate() { + pkg_cumulate_$PSUF "$@" +} + +pkg_finalize() { + pkg_finalize_$PSUF "$@" +} + +pkg_preinstall() { + pkg_preinstall_$PSUF "$@" +} + +pkg_runscripts() { + pkg_runscripts_$PSUF "$@" +} + +pkg_autodetect_type() { + if test -n "$PREINSTALL_IMAGE" ; then + echo "cannot autodetect build type when using a preinstall image" >&2 + cleanup_and_exit 1 + fi + PSUF= + test -e $BUILD_ROOT/.init_b_cache/rpms/rpm.rpm && PSUF=rpm + test -e $BUILD_ROOT/.init_b_cache/rpms/dpkg.deb && PSUF=deb + test -e $BUILD_ROOT/.init_b_cache/rpms/pacman.arch && PSUF=arch + if test -z "$PSUF" ; then + echo "could not autodetect package type" >&2 + cleanup_and_exit 1 + fi +} + +pkg_set_type() { + PSUF=`queryconfig binarytype --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH"` + test "$PSUF" = UNDEFINED && PSUF= + case "$PSUF" in + rpm|deb|arch) + ;; + '') + pkg_autodetect_type + ;; + *) + echo "unknown package type '$PSUF'" >&2 + cleanup_and_exit 1 + ;; + esac +} diff --git a/build-pkg-arch b/build-pkg-arch new file mode 100644 index 0000000..eadab2b --- /dev/null +++ b/build-pkg-arch @@ -0,0 +1,73 @@ +# +# Arch specific functions. +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +pkg_initdb_arch() { + mkdir -p $BUILD_ROOT/var/lib/pacman/sync + touch $BUILD_ROOT/var/lib/pacman/sync/core.db + touch $BUILD_ROOT/var/lib/pacman/sync/extra.db + touch $BUILD_ROOT/var/lib/pacman/sync/community.db +} + +pkg_prepare_arch() { + : +} + +pkg_erase_arch() { + ( cd $BUILD_ROOT && chroot $BUILD_ROOT pacman -R -n -d -d --noconfirm $PKG 2>&1 || touch $BUILD_ROOT/exit ) | \ + perl -ne '$|=1;/^(Total Removed Size: |Packages \(\d+\):|:: Do you want to remove these packages|deleting |removing | )/||/^$/||print' +} + +pkg_verify_installed_arch() { + return 1 +} + +pkg_cumulate_arch() { + return 1 +} + +pkg_install_arch() { + # -d -d disables deps checking + ( cd $BUILD_ROOT && chroot $BUILD_ROOT pacman -U --force -d -d --noconfirm .init_b_cache/$PKG.$PSUF 2>&1 || touch $BUILD_ROOT/exit ) | \ + perl -ne '$|=1;/^(warning: could not get filesystem information for |loading packages|looking for inter-conflicts|Targets |Total Installed Size: |Net Upgrade Size: |Proceed with installation|checking package integrity|loading package files|checking for file conflicts|checking keyring|Packages \(\d+\):|:: Proceed with installation|checking available disk space|installing |upgrading |warning:.*is up to date -- reinstalling|Optional dependencies for| )/||/^$/||print' +} + +pkg_finalize_arch() { + : +} + +pkg_preinstall_arch() { + $TAR -f "$BUILD_ROOT/.init_b_cache/rpms/$PKG.arch" + if test -f .INSTALL ; then + cat .INSTALL > ".init_b_cache/scripts/$PKG.post" + echo 'type post_install >/dev/null 2>&1 && post_install' >> ".init_b_cache/scripts/$PKG.post" + fi + rm -f .PKGINFO .INSTALL +} + +pkg_runscripts_arch() { + if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post" ; then + echo "running $PKG postinstall script" + ( cd $BUILD_ROOT && chroot $BUILD_ROOT ".init_b_cache/scripts/$PKG.post" < /dev/null ) + rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post" + fi +} diff --git a/build-pkg-deb b/build-pkg-deb new file mode 100644 index 0000000..83a4afe --- /dev/null +++ b/build-pkg-deb @@ -0,0 +1,124 @@ +# +# Debian dpkg specific functions. +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +deb_setup() { + mkdir -p $BUILD_ROOT/var/lib/dpkg + mkdir -p $BUILD_ROOT/var/log + mkdir -p $BUILD_ROOT/etc/default + :>> $BUILD_ROOT/var/lib/dpkg/status + :>> $BUILD_ROOT/var/lib/dpkg/available + :>> $BUILD_ROOT/var/log/dpkg.log + :>> $BUILD_ROOT/etc/ld.so.conf + :>> $BUILD_ROOT/etc/default/rcS +} + +pkg_initdb_deb() { + deb_setup + # force dpkg into database to make epoch test work + if ! test "$BUILD_ROOT/.init_b_cache/rpms/dpkg.deb" -ef "$BUILD_ROOT/.init_b_cache/dpkg.deb" ; then + rm -f $BUILD_ROOT/.init_b_cache/dpkg.deb + cp $BUILD_ROOT/.init_b_cache/rpms/dpkg.deb $BUILD_ROOT/.init_b_cache/dpkg.deb || cleanup_and_exit 1 + fi + chroot $BUILD_ROOT dpkg -i --force all .init_b_cache/dpkg.deb >/dev/null 2>&1 +} + +pkg_prepare_deb() { + : +} + +pkg_install_deb() { + export DEBIAN_FRONTEND=noninteractive + export DEBIAN_PRIORITY=critical + ( cd $BUILD_ROOT && chroot $BUILD_ROOT dpkg --install --force all .init_b_cache/$PKG.deb 2>&1 || touch $BUILD_ROOT/exit ) | \ + perl -ne '$|=1;/^(Configuration file|Installing new config file|Selecting previously deselected|Selecting previously unselected|\(Reading database|Unpacking |Setting up|Creating config file|Preparing to replace dpkg|Preparing to unpack )/||/^$/||print' + # ugly workaround for upstart system. some packages (procps) try + # to start a service in their configure phase. As we don't have + # a running upstart, we just link the start binary to /bin/true + if test -e "$BUILD_ROOT/sbin/start"; then + if test "$BUILD_ROOT/sbin/start" -ef "$BUILD_ROOT/sbin/initctl" ; then + echo "linking /sbin/start to /bin/true" + mv "$BUILD_ROOT/sbin/start" "$BUILD_ROOT/sbin/start.disabled" + ln -s "/bin/true" "$BUILD_ROOT/sbin/start" + fi + fi + # another workaround, see bug bnc#733699 + rm -f "$BUILD_ROOT/var/run/init.upgraded" +} + +pkg_erase_deb() { + export DEBIAN_FRONTEND=noninteractive + export DEBIAN_PRIORITY=critical + ( cd $BUILD_ROOT && chroot $BUILD_ROOT dpkg --purge --force all $PKG 2>&1 || touch $BUILD_ROOT/exit ) | \ + perl -ne '$|=1;/^(\(Reading database|Removing |Purging configuration files for )/||/^$/||print' +} + +pkg_cumulate_deb() { + return 1 +} + +pkg_verify_installed_deb() { + return 1 +} + +pkg_finalize_deb() { + echo "configuring all installed packages..." + # configure all packages after complete installation, not for each package like rpm does + # We need to run this twice, because of cyclic dependencies as it does not succeed on most + # debian based distros in the first attempt. + if ! chroot $BUILD_ROOT dpkg --configure --pending 2>&1; then + echo "first configure attempt failed, trying again..." + chroot $BUILD_ROOT dpkg --configure --pending 2>&1 || cleanup_and_exit 1 + fi +} + +pkg_preinstall_deb() { + ar x "$BUILD_ROOT/.init_b_cache/rpms/$PKG.deb" + mkdir -p .init_b_cache/scripts/control + $TAR -C .init_b_cache/scripts/control -z -f control.tar.gz + if test -f "data.tar.gz" ; then + $TAR -z -f data.tar.gz + elif test -f "data.tar.xz" ; then + $TAR -J -f data.tar.xz + fi + if test -e ".init_b_cache/scripts/$PKG.run" ; then + test -e .init_b_cache/scripts/control/preinst && mv .init_b_cache/scripts/control/preinst ".init_b_cache/scripts/$PKG.pre" + test -e .init_b_cache/scripts/control/postinst && mv .init_b_cache/scripts/control/postinst ".init_b_cache/scripts/$PKG.post" + fi + rm -rf .init_b_cache/scripts/control control.tar.gz data.tar.{g,x}z +} + +pkg_runscripts_deb() { + if ! test -e $BUILD_ROOT/var/lib/dpkg/status ; then + deb_setup + fi + if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.pre" ; then + echo "running $PKG preinstall script" + (cd $BUILD_ROOT && chroot $BUILD_ROOT ".init_b_cache/scripts/$PKG.pre" install < /dev/null ) + rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.pre" + fi + if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post" ; then + echo "running $PKG postinstall script" + (cd $BUILD_ROOT && chroot $BUILD_ROOT ".init_b_cache/scripts/$PKG.post" configure '' < /dev/null ) + rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post" + fi +} diff --git a/build-pkg-rpm b/build-pkg-rpm new file mode 100644 index 0000000..c0f9653 --- /dev/null +++ b/build-pkg-rpm @@ -0,0 +1,193 @@ +# +# RPM specific functions. +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + + +pkg_initdb_rpm() { + echo "initializing rpm db..." + mkdir -p $BUILD_ROOT/var/lib/rpm + # rpm v5 does not have initdb + if ! test -e $BUILD_ROOT/usr/lib/rpm/cpuinfo.yaml ; then + if test -x $BUILD_ROOT/usr/bin/rpmdb ; then + chroot $BUILD_ROOT /usr/bin/rpmdb --initdb || cleanup_and_exit 1 + else + chroot $BUILD_ROOT rpm --initdb || cleanup_and_exit 1 + fi + fi + # hack: add nofsync to db config to speed up install + mkdir -p $BUILD_ROOT/root + DBI_OTHER=`chroot $BUILD_ROOT rpm --eval '%{?__dbi_other}'` + echo "%__dbi_other $DBI_OTHER nofsync" > $BUILD_ROOT/.rpmmacros + echo "%__dbi_other $DBI_OTHER nofsync" > $BUILD_ROOT/root/.rpmmacros +} + +pkg_prepare_rpm() { + rpm_set_checkopts + rpm_init_cumulate +} + +pkg_erase_rpm() { + chroot $BUILD_ROOT rpm --nodeps -e $PKG 2>&1 | { + local retry + while read line; do + case "$line" in + r*failed:\ No\ such\ file\ or\ directory) ;; + error:\ failed\ to\ stat\ *:\ No\ such\ file\ or\ directory) ;; + error:\ *scriptlet\ failed*) + echo "$line" + retry=1 + ;; + *) echo "$line" ;; + esac + done + if test -n "$retry" ; then + echo "re-try deleting $PKG using --noscripts" + chroot $BUILD_ROOT rpm --nodeps --noscripts -e $PKG || true + fi + } +} + +rpm_set_checkopts() { + RPMCHECKOPTS= + # on Fedora 10 rpmbuild is in a separate package so we need something else to + # detect rpm4 + test -x $BUILD_ROOT/usr/bin/rpmquery && RPMCHECKOPTS="--nodigest --nosignature" +} + +rpm_init_cumulate() { + cumulate=-1 + CUMULATED_LIST=() + CUMULATED_PIDS=() + CUMULATED_HMD5=() + DO_CUMULATE= + typeset -ri suse_version=$(chroot $BUILD_ROOT rpm --eval '%{?suse_version}' 2>/dev/null) + if ((suse_version > 1220)) ; then + DO_CUMULATE=true + fi +} + +pkg_verify_installed_rpm() { + chroot $BUILD_ROOT rpm --verify $PKG 2>&1 | tee $TMPFILE + if grep ^missing $TMPFILE > /dev/null ; then + return 1 + fi + return 0 +} + +pkg_cumulate_rpm() { + test "$DO_CUMULATE" = true || return 1 + # work around for cross-build installs, we must not overwrite the running rpm + if test "$PKG" = rpm ; then + for i in $BUILD_ROOT/.init_b_cache/preinstalls/rpm-x86-* ; do + test -e "$i" && return 1 + done + fi + let cumulate++ + CUMULATED_LIST[$cumulate]=".init_b_cache/$PKG.rpm" + CUMULATED_PIDS[$cumulate]="$PKGID" + CUMULATED_HMD5[$cumulate]="$PKG_HDRMD5" + return 0 +} + +pkg_install_rpm() { + ( chroot $BUILD_ROOT rpm --ignorearch --nodeps -U --oldpackage --ignoresize $RPMCHECKOPTS \ + $ADDITIONAL_PARAMS .init_b_cache/$PKG.rpm 2>&1 || \ + touch $BUILD_ROOT/exit ) | \ + grep -v "^warning:.*saved as.*rpmorig$" +} + +pkg_finalize_rpm() { + if test -n "${CUMULATED_LIST[*]}" ; then + echo "now installing cumulated packages" + for ((num=0; num<=cumulate; num++)) ; do + echo ${CUMULATED_LIST[$num]} + PKG=${CUMULATED_LIST[$num]##*/} + test "$BUILD_ROOT/.init_b_cache/rpms/$PKG" -ef "$BUILD_ROOT/${CUMULATED_LIST[$num]}" && continue + rm -f $BUILD_ROOT/${CUMULATED_LIST[$num]} + cp $BUILD_ROOT/.init_b_cache/rpms/$PKG $BUILD_ROOT/${CUMULATED_LIST[$num]} || cleanup_and_exit 1 + done > $BUILD_ROOT/.init_b_cache/manifest + chroot $BUILD_ROOT rpm --ignorearch --nodeps -Uh --oldpackage --ignoresize --verbose $RPMCHECKOPTS \ + $ADDITIONAL_PARAMS .init_b_cache/manifest 2>&1 || touch $BUILD_ROOT/exit + for ((num=0; num<=cumulate; num++)) ; do + rm -f $BUILD_ROOT/${CUMULATED_LIST[$num]} + done + rm -f $BUILD_ROOT/.init_b_cache/manifest + check_exit + for ((num=0; num<=cumulate; num++)) ; do + PKG=${CUMULATED_LIST[$num]##*/} + echo "${CUMULATED_PIDS[$num]}" > $BUILD_ROOT/installed-pkg/${PKG%.rpm} + test -n "${CUMULATED_HMD5[$num]}" || continue + echo "${CUMULATED_HMD5[$num]} ${CUMULATED_PIDS[$num]}" > $BUILD_ROOT/.preinstall_image/${PKG%.rpm} + done + fi +} + +pkg_preinstall_rpm() { + PAYLOADDECOMPRESS=cat + case `rpm -qp --nodigest --nosignature --qf "%{PAYLOADCOMPRESSOR}\n" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm"` in + lzma) rpm --showrc | egrep 'PayloadIsLzma|_lzma' > /dev/null || PAYLOADDECOMPRESS="lzma -d" ;; + xz) rpm --showrc | egrep 'PayloadIsXz|_xz' > /dev/null || PAYLOADDECOMPRESS="xz -d" ;; + esac + if test "$PAYLOADDECOMPRESS" = "lzma -d" ; then + if ! lzma </dev/null >/dev/null 2>&1 ; then + test -f "$BUILD_DIR/lzmadec.sh" && PAYLOADDECOMPRESS="bash $BUILD_DIR/lzmadec.sh" + fi + fi + if test "$PAYLOADDECOMPRESS" = "xz -d" ; then + if ! xz </dev/null >/dev/null 2>&1 ; then + test -f "$BUILD_DIR/xzdec.sh" && PAYLOADDECOMPRESS="bash $BUILD_DIR/xzdec.sh" + fi + fi + if test "$PAYLOADDECOMPRESS" = cat ; then + rpm2cpio "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" | $CPIO + else + rpm2cpio "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" | $PAYLOADDECOMPRESS | $CPIO + fi + if test -e ".init_b_cache/scripts/$PKG.run" ; then + rpm -qp --nodigest --nosignature --qf "%{PREIN}" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" > ".init_b_cache/scripts/$PKG.pre" + rpm -qp --nodigest --nosignature --qf "%{POSTIN}" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" > ".init_b_cache/scripts/$PKG.post" + echo -n '(none)' > .init_b_cache/scripts/.none + cmp -s ".init_b_cache/scripts/$PKG.pre" .init_b_cache/scripts/.none && rm -f ".init_b_cache/scripts/$PKG.pre" + cmp -s ".init_b_cache/scripts/$PKG.post" .init_b_cache/scripts/.none && rm -f ".init_b_cache/scripts/$PKG.post" + rm -f .init_b_cache/scripts/.none + fi + # hack for rpm erasures + if test -d "$BUILD_ROOT/installed-pkg" ; then + # call for rpm-4.x and not rpm-devel + test -z "${PKG##rpm-[0-9]*}" && chroot $BUILD_ROOT rpm --rebuilddb + # also exec for exchanged rpm ! naming is rpm-x86-<target>-<ver> + test -z "${PKG##rpm-x86-*[0-9]*}" && chroot $BUILD_ROOT rpm --rebuilddb + fi +} + +pkg_runscripts_rpm() { + if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.pre" ; then + echo "running $PKG preinstall script" + chroot $BUILD_ROOT sh ".init_b_cache/scripts/$PKG.pre" 0 + rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.pre" + fi + if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post" ; then + echo "running $PKG postinstall script" + chroot $BUILD_ROOT sh ".init_b_cache/scripts/$PKG.post" 1 + rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post" + fi +} diff --git a/build-recipe b/build-recipe new file mode 100644 index 0000000..4d9674a --- /dev/null +++ b/build-recipe @@ -0,0 +1,140 @@ +# +# recipe specific functions for the build script +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + + +KIWI_PARAMETERS= + +for i in spec dsc kiwi arch preinstallimage mock livebuild debootstrap; do + . "$BUILD_DIR/build-recipe-$i" +done + +recipe_setup() { + recipe_setup_$BUILDTYPE "$@" +} + +recipe_prepare() { + recipe_prepare_$BUILDTYPE "$@" +} + +recipe_build() { + recipe_build_$BUILDTYPE "$@" +} + +recipe_resultdirs () { + recipe_resultdirs_$BUILDTYPE "$@" +} + +recipe_parse_options() { + case ${PARAM/#--/-} in + -stage) + needarg + BUILD_RPM_BUILD_STAGE="$ARG" + shift + ;; + -kiwi-parameter) + test -z "$ARG" && ARG="$1" + needarg + KIWI_PARAMETERS="$KIWI_PARAMETERS $ARG" + shift + ;; + -*) + return 1 + ;; + esac + nextargs=("$@") + return 0 +} + +recipe_set_buildtype() { + BUILDTYPE= + case ${RECIPEFILE##_service:*:} in + *.spec|*.src.rpm) BUILDTYPE=spec ;; + *.dsc) BUILDTYPE=dsc ;; + *.kiwi) BUILDTYPE=kiwi ;; + PKGBUILD) BUILDTYPE=arch ;; + _preinstallimage) BUILDTYPE=preinstallimage ;; + *.livebuild) BUILDTYPE=livebuild ;; + esac + if test -z "$BUILDTYPE" ; then + echo "I don't know how to build $RECIPEFILE" + cleanup_and_exit 1 + fi + # we can't query right after vm startup, so we put the BUILDENGINE in the build.data + if test -z "$RUNNING_IN_VM" ; then + BUILDENGINE= + if test -n "$BUILD_DIST" ; then + BUILDENGINE=`queryconfig buildengine --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH"` + test "$BUILDENGINE" = UNDEFINED && BUILDENGINE= + fi + fi + if test "$BUILDENGINE" = mock -a "$BUILDTYPE" = spec ; then + BUILDTYPE=mock + fi + if test "$BUILDENGINE" = debootstrap -a "$BUILDTYPE" = dsc ; then + BUILDTYPE=debootstrap + fi +} + +# expands all directories into files +expand_recipe_directories() { + local f t ff found types + if test -z "$RECIPEFILES" ; then + set -- "`pwd`" + else + set -- "${RECIPEFILES[@]}" + fi + RECIPEFILES=() + for f in "$@" ; do + if test "$f" = "${f#/}" ; then + f="`pwd`/$f" + fi + if test -d "$f" ; then + if test -z "$types" ; then + if test -n "$BUILD_DIST" ; then + case $(queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" type) in + dsc) types=".dsc" ;; + kiwi) types=".kiwi" ;; + arch) types="PKGBUILD" ;; + livebuild) types=".livebuild" ;; + esac + fi + types="$types .spec .dsc PKGBUILD .kiwi .src.rpm .nosrc.rpm" + fi + for t in $types ; do + found= + for ff in "$f"/*$t ; do + test -f "$ff" || continue + RECIPEFILES=("${RECIPEFILES[@]}" "$ff") + found=true + done + test -n "$found" && break + done + else + RECIPEFILES[${#RECIPEFILES[@]}]="$f" + fi + done + if test -z "$RECIPEFILES" ; then + echo "no recipe files found in $@. exit..." + cleanup_and_exit 1 + fi +} diff --git a/build-recipe-arch b/build-recipe-arch new file mode 100644 index 0000000..2fe6159 --- /dev/null +++ b/build-recipe-arch @@ -0,0 +1,57 @@ +# +# Arch specific functions. +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +recipe_setup_arch() { + TOPDIR=/usr/src/packages + rm -rf "$BUILD_ROOT$TOPDIR" + mkdir -p "$BUILD_ROOT$TOPDIR" + mkdir -p "$BUILD_ROOT$TOPDIR/OTHER" + mkdir -p "$BUILD_ROOT$TOPDIR/SOURCES" + mkdir -p "$BUILD_ROOT/$TOPDIR/ARCHPKGS" + mkdir -p "$BUILD_ROOT/$TOPDIR/BUILD" + chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR" + cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/ + { + echo 'source /etc/makepkg.conf' + printf '%s=%s\n' \ + BUILDDIR $TOPDIR/BUILD \ + PKGDEST $TOPDIR/ARCHPKGS + } > $BUILD_ROOT$TOPDIR/makepkg.conf +} + +recipe_prepare_arch() { + echo "Preparing sources..." + _arch_recipe_makepkg -so "2>&1" ">/dev/null" +} + +recipe_build_arch() { + _arch_recipe_makepkg -ef < /dev/null && BUILD_SUCCEEDED=true +} + +recipe_resultdirs_arch() { + echo ARCHPKGS +} + +_arch_recipe_makepkg() { + chroot $BUILD_ROOT su -lc "source /etc/profile; cd $TOPDIR/SOURCES && makepkg --config ../makepkg.conf $*" $BUILD_USER +} diff --git a/build-recipe-debootstrap b/build-recipe-debootstrap new file mode 100644 index 0000000..265b6e2 --- /dev/null +++ b/build-recipe-debootstrap @@ -0,0 +1,92 @@ +# +# debootstrap specific functions. +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +recipe_setup_debootstrap() { + recipe_setup_dsc "$@" +} + +recipe_prepare_debootstrap() { + recipe_prepare_dsc "$@" +} + +recipe_build_debootstrap() { + local arch=$(chroot $BUILD_ROOT su -c "dpkg-architecture -qDEB_BUILD_ARCH") + local dist=$(chroot $BUILD_ROOT su -c "lsb_release --codename --short") + local myroot=debootstraproot + test -d $BUILD_ROOT/.build.binaries || cleanup_and_exit 1 + if test "$DO_INIT" = true -o ! -d "$BUILD_ROOT/.build.binaries/dists" ; then + echo "creating repository for debootstrap..." + createrepo_debian $BUILD_ROOT/.build.binaries ${arch} ${dist} + fi + FULL_PKG_LIST= + for PKG in $BUILD_ROOT/.build.binaries/*.deb ; do + PKG="${PKG##*/}" + FULL_PKG_LIST="$FULL_PKG_LIST,${PKG%.deb}" + done + FULL_PKG_LIST="${FULL_PKG_LIST#,}" + rm -rf "$BUILD_ROOT/$myroot" + set -- chroot $BUILD_ROOT debootstrap --no-check-gpg --variant=buildd --arch="${arch}" --include="$FULL_PKG_LIST" "$dist" "$myroot" file:///.build.binaries + echo "running debootstrap..." + "$@" + # adapt passwd + if test $BUILD_USER = abuild ; then + echo "abuild:x:${ABUILD_UID}:${ABUILD_GID}:Autobuild:/home/abuild:/bin/bash" >>$BUILD_ROOT/$myroot/etc/passwd + echo 'abuild:*::' >>$BUILD_ROOT/$myroot/etc/gshadow + echo "abuild:x:${ABUILD_GID}:" >>$BUILD_ROOT/$myroot/etc/group + mkdir -p $BUILD_ROOT/$myroot/home/abuild + chown "$ABUILD_UID:$ABUILD_GID" $BUILD_ROOT/$myroot/home/abuild + fi + # move topdir over + mv "$BUILD_ROOT/$TOPDIR" "$BUILD_ROOT/$myroot/${TOPDIR%/*}" + # do the build + DSC_BUILD_OPTIONS= + test -n "$BUILD_JOBS" && DSC_BUILD_OPTIONS="parallel=${BUILD_JOBS}" + DSC_BUILD_CMD="$(queryconfig --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" substitute dsc:build_cmd)" + test -z "$DSC_BUILD_CMD" && DSC_BUILD_CMD="dpkg-buildpackage -us -uc" + if test -e $BUILD_ROOT/$myroot/$TOPDIR/SOURCES/build.script ; then + echo "Sourcing build.script to build - it should normally run 'dpkg-buildpackage -us -uc'" + DSC_BUILD_CMD="source $TOPDIR/SOURCES/build.script" + chmod +x $BUILD_ROOT/$myroot/$TOPDIR/SOURCES/build.script + fi + chroot "$BUILD_ROOT/$myroot" su -c "export DEB_BUILD_OPTIONS=${DSC_BUILD_OPTIONS} ; cd $TOPDIR/BUILD && $DSC_BUILD_CMD" - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true + # run lintian + if test "$BUILD_SUCCEEDED" = true -a "$DO_CHECKS" != "false"; then + DEB_CHANGESFILE=${RECIPEFILE%.dsc}_"$(chroot "$BUILD_ROOT/$myroot" su -c 'dpkg-architecture -qDEB_BUILD_ARCH')".changes + chroot $BUILD_ROOT/$myroot su -c "which lintian > /dev/null && cd $TOPDIR && echo Running lintian && (set -x && lintian -i $DEB_SOURCEDIR/$DEB_DSCFILE)" - $BUILD_USER < /dev/null + fi + # move topdir back + mv "$BUILD_ROOT/$myroot/$TOPDIR" "$BUILD_ROOT/${TOPDIR%/*}" + for DEB in $BUILD_ROOT/$TOPDIR/*.deb ; do + test -e "$DEB" && mv "$DEB" "$BUILD_ROOT/$TOPDIR/DEBS" + done + # link used sources over to DEB directory + ln $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE $BUILD_ROOT/$TOPDIR/DEBS/ + while read f ; do + ln $BUILD_ROOT/$DEB_SOURCEDIR/$f $BUILD_ROOT/$TOPDIR/DEBS/ + done < <(sed -ne '/^Files:/,$s/^ ................................ [0-9][0-9]* //p' < $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE) +} + +recipe_resultdirs_debootstrap() { + echo DEBS +} + diff --git a/build-recipe-dsc b/build-recipe-dsc new file mode 100644 index 0000000..9b3ca33 --- /dev/null +++ b/build-recipe-dsc @@ -0,0 +1,111 @@ +# +# dsc specific functions. +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +recipe_setup_dsc() { + TOPDIR=/usr/src/packages + rm -rf "$BUILD_ROOT$TOPDIR" + mkdir -p "$BUILD_ROOT$TOPDIR" + mkdir -p "$BUILD_ROOT$TOPDIR/OTHER" + mkdir -p "$BUILD_ROOT$TOPDIR/SOURCES" + mkdir -p "$BUILD_ROOT/$TOPDIR/DEBS" + chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR" + cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/ + # FIX to work with baselibs_$PROJ etc + if test -e "$MYSRCDIR/baselibs-deb.conf" ; then + echo "dsc build and baselibs-deb.conf present: forcing --baselibs to true" + CREATE_BASELIBS=true + fi +} + +recipe_prepare_dsc() { + rm -rf "$BUILD_ROOT$TOPDIR/BUILD" + mkdir -p "$BUILD_ROOT$TOPDIR/SOURCES.DEB" + chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR" + DEB_TRANSFORM= + DEB_SOURCEDIR="$TOPDIR/SOURCES" + DEB_DSCFILE="$RECIPEFILE" + for f in $BUILD_ROOT$TOPDIR/SOURCES/debian.* ; do + test -f $f && DEB_TRANSFORM=true + done + if test -n "$DEB_TRANSFORM" ; then + CHANGELOGARGS= + test -n "$CHANGELOG" -a -f "$BUILD_ROOT/.build-changelog" && CHANGELOGARGS="--changelog $BUILD_ROOT/.build-changelog" + echo "running debian transformer..." + if [ "$RELEASE" ]; then + # remove rpm macros (everything after "%") + # they are not evaluated by the Debian build process + DEB_RELEASE=`sed 's/%.*$//' <<< $RELEASE` + echo "release: ($RELEASE), release (DEB) ($DEB_RELEASE)" + RELEASEARGS="--release $DEB_RELEASE" + fi + if ! debtransform $CHANGELOGARGS $RELEASEARGS $BUILD_ROOT$TOPDIR/SOURCES $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE $BUILD_ROOT$TOPDIR/SOURCES.DEB ; then + echo "debian transforming failed." + cleanup_and_exit 1 + fi + DEB_SOURCEDIR=$TOPDIR/SOURCES.DEB + for DEB_DSCFILE in $BUILD_ROOT/$DEB_SOURCEDIR/*.dsc ; do : ; done + DEB_DSCFILE="${DEB_DSCFILE##*/}" + fi + chroot $BUILD_ROOT su -c "dpkg-source -x $DEB_SOURCEDIR/$DEB_DSCFILE $TOPDIR/BUILD" - $BUILD_USER +} + +recipe_build_dsc() { + DSC_BUILD_OPTIONS= + if test -n "$BUILD_JOBS" ; then + DSC_BUILD_OPTIONS="parallel=${BUILD_JOBS}" + fi + # Checks to see if a build script should be used + # this allows the build environment to be manipulated + # and alternate build commands can be used + DSC_BUILD_CMD="$(queryconfig --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" substitute dsc:build_cmd)" + test -z "$DSC_BUILD_CMD" && DSC_BUILD_CMD="dpkg-buildpackage -us -uc" + if test -e $BUILD_ROOT/$TOPDIR/SOURCES/build.script ; then + echo "Sourcing build.script to build - it should normally run 'dpkg-buildpackage -us -uc'" + DSC_BUILD_CMD="source $TOPDIR/SOURCES/build.script" + chmod +x $BUILD_ROOT/$TOPDIR/SOURCES/build.script + fi + + if test -n "$RUN_SHELL"; then + chroot $BUILD_ROOT su - + else + chroot $BUILD_ROOT su -c "export DEB_BUILD_OPTIONS=${DSC_BUILD_OPTIONS} ; cd $TOPDIR/BUILD && $DSC_BUILD_CMD" - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true + if test "$BUILD_SUCCEEDED" = true -a "$DO_CHECKS" != "false"; then + DEB_CHANGESFILE=${RECIPEFILE%.dsc}_"$(chroot $BUILD_ROOT su -c 'dpkg-architecture -qDEB_BUILD_ARCH')".changes + chroot $BUILD_ROOT su -c "which lintian > /dev/null && cd $TOPDIR && echo Running lintian && (set -x && lintian -i $DEB_SOURCEDIR/$DEB_DSCFILE)" - $BUILD_USER < /dev/null + fi + fi + + for DEB in $BUILD_ROOT/$TOPDIR/*.deb ; do + test -e "$DEB" && mv "$DEB" "$BUILD_ROOT/$TOPDIR/DEBS" + done + + # link used sources over to DEB directory + ln $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE $BUILD_ROOT/$TOPDIR/DEBS/ + while read f ; do + ln $BUILD_ROOT/$DEB_SOURCEDIR/$f $BUILD_ROOT/$TOPDIR/DEBS/ + done < <(sed -ne '/^Files:/,$s/^ ................................ [0-9][0-9]* //p' < $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE) +} + +recipe_resultdirs_dsc() { + echo DEBS +} diff --git a/build-recipe-kiwi b/build-recipe-kiwi new file mode 100644 index 0000000..6f8e6a1 --- /dev/null +++ b/build-recipe-kiwi @@ -0,0 +1,494 @@ +# +# KIWI specific functions. Handle with care. +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + + +############################################################ + +# post scriptlet generation functions + +kiwi_post_oem() { + cat <<-EOF + echo "compressing oem images... " + cd /$TOPDIR/KIWI-oem + # do not store compressed file _and_ uncompressed one + [ -e "$imageout.gz" ] && rm -f "$imageout" + if [ -e "$imageout.iso" ]; then + echo "take iso file and create sha256..." + mv "$imageout.iso" "/$TOPDIR/KIWI/$imageout$buildnum.iso" + pushd /$TOPDIR/KIWI + if [ -x /usr/bin/sha256sum ]; then + /usr/bin/sha256sum "$imageout$buildnum.iso" > "$imageout$buildnum.iso.sha256" + fi + popd + fi + if [ -e "$imageout.install.iso" ]; then + echo "take install.iso file and create sha256..." + mv "$imageout.install.iso" "/$TOPDIR/KIWI/$imageout$buildnum.install.iso" + pushd /$TOPDIR/KIWI + if [ -x /usr/bin/sha256sum ]; then + /usr/bin/sha256sum "$imageout$buildnum.install.iso" > "$imageout$buildnum.install.iso.sha256" + fi + popd + fi + if [ -e "$imageout.qcow2" ]; then + mv "$imageout.qcow2" "/$TOPDIR/KIWI/$imageout$buildnum.qcow2" + pushd /$TOPDIR/KIWI + if [ -x /usr/bin/sha256sum ]; then + echo "Create sha256 file..." + /usr/bin/sha256sum "$imageout$buildnum.qcow2" > "$imageout$buildnum.qcow2.sha256" + fi + popd + fi + if [ -e "$imageout.raw.install.raw" ]; then + compress_tool="bzip2" + compress_suffix="bz2" + if [ -x /usr/bin/xz ]; then + # take xz to get support for sparse files + compress_tool="xz -2" + compress_suffix="xz" + fi + mv "$imageout.raw.install.raw" "/$TOPDIR/KIWI/$imageout$buildnum.raw.install.raw" + pushd /$TOPDIR/KIWI + echo "\$compress_tool raw.install.raw file..." + \$compress_tool "$imageout$buildnum.raw.install.raw" + if [ -x /usr/bin/sha256sum ]; then + echo "Create sha256 file..." + /usr/bin/sha256sum "$imageout$buildnum.raw.install.raw.\${compress_suffix}" > "$imageout$buildnum.raw.install.raw.\${compress_suffix}.sha256" + fi + popd + fi + if [ -e "$imageout.raw" ]; then + compress_tool="bzip2" + compress_suffix="bz2" + if [ -x /usr/bin/xz ]; then + # take xz to get support for sparse files + compress_tool="xz -2" + compress_suffix="xz" + fi + mv "$imageout.raw" "/$TOPDIR/KIWI/$imageout$buildnum.raw" + pushd /$TOPDIR/KIWI + echo "\$compress_tool raw file..." + \$compress_tool "$imageout$buildnum.raw" + if [ -x /usr/bin/sha256sum ]; then + echo "Create sha256 file..." + /usr/bin/sha256sum "$imageout$buildnum.raw.\${compress_suffix}" > "$imageout$buildnum.raw.\${compress_suffix}.sha256" + fi + popd + fi + EOF +} + +kiwi_post_vmx() { + cat <<-EOF + echo "compressing vmx images... " + cd /$TOPDIR/KIWI-vmx + compress_tool="bzip2" + compress_suffix="bz2" + if [ -x /usr/bin/xz ]; then + # take xz to get support for sparse files + compress_tool="xz -2" + compress_suffix="xz" + fi + VMXFILES="" + SHAFILES="" + for suffix in "ovf" "qcow2" "ova" "tar" "vhdfixed" "vhd"; do + if [ -e "$imageout.\$suffix" ]; then + if [ "\$suffix" == "vhd" -o "\$suffix" == "vhdfixed" ]; then + mv "$imageout.\$suffix" "/$TOPDIR/KIWI/$imageout$buildnum.\$suffix" + pushd /$TOPDIR/KIWI + echo "\$compress_tool \$suffix file..." + \$compress_tool "$imageout$buildnum.\$suffix" + SHAFILES="\$SHAFILES $imageout$buildnum.\$suffix.\${compress_suffix}" + popd + elif [ "\$suffix" == "ovf" ]; then + mv "$imageout.\${suffix}/$imageout.\$suffix" "/$TOPDIR/KIWI/$imageout$buildnum.\$suffix" + SHAFILES="\$SHAFILES $imageout$buildnum.\$suffix" + else + mv "$imageout.\$suffix" "/$TOPDIR/KIWI/$imageout$buildnum.\$suffix" + SHAFILES="\$SHAFILES $imageout$buildnum.\$suffix" + fi + fi + done + # This option has a number of format parameters + for i in "$imageout.vmx" "$imageout.vmdk" "$imageout-disk*.vmdk"; do + test -e \$i && VMXFILES="\$VMXFILES \$i" + done + # take raw files as fallback + if [ -n "\$VMXFILES" ]; then + tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-vmx.tar.bz2" \$VMXFILES + SHAFILES="\$SHAFILES $imageout$buildnum-vmx.tar.bz2" + elif [ -z "\$SHAFILES" -a -e "$imageout.raw" ]; then + mv "$imageout.raw" "/$TOPDIR/KIWI/$imageout$buildnum-vmx.raw" + pushd /$TOPDIR/KIWI + echo "\$compress_tool raw file..." + \$compress_tool "$imageout$buildnum-vmx.raw" + SHAFILES="\$SHAFILES $imageout$buildnum-vmx.raw.\${compress_suffix}" + popd + fi + if [ -e "$imageout.box" ]; then + tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-vmx-box.tar.bz2" $imageout.box $imageout.json + SHAFILES="\$SHAFILES $imageout$buildnum-vmx-box.tar.bz2" + fi + if [ -e "$imageout.xenconfig" ]; then + tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-vmx.tar.bz2" $imageout.xenconfig $imageout.raw initrd-* + SHAFILES="\$SHAFILES $imageout$buildnum-vmx.tar.bz2" + fi + # FIXME: do we need a single .raw file in any case ? + + cd /$TOPDIR/KIWI + if [ -n "\$SHAFILES" -a -x /usr/bin/sha256sum ]; then + for i in \$SHAFILES; do + echo "Create sha256 file..." + /usr/bin/sha256sum "\$i" > "\$i.sha256" + done + fi + tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-raw.tar.bz2" \ + --exclude="$imageout.iso" --exclude="$imageout.raw" --exclude="$imageout.qcow2" * + cd /$TOPDIR/KIWI + if [ -x /usr/bin/sha256sum ]; then + /usr/bin/sha256sum "$imageout$buildnum-raw.tar.bz2" > "$imageout$buildnum-raw.tar.bz2.sha256" + fi + EOF +} + +kiwi_post_xen() { + cat <<-EOF + echo "compressing xen images... " + cd /$TOPDIR/KIWI-xen + # do not store compressed file _and_ uncompressed one + [ -e "$imageout.gz" ] && rm -f "$imageout" + tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-xen.tar.bz2" \ + `grep ^kernel $imageout.xenconfig | cut -d'"' -f2` \ + `grep ^ramdisk $imageout.xenconfig | cut -d'"' -f2` \ + initrd-* \ + "$imageout.xenconfig" \ + "$imageout" + if [ -x /usr/bin/sha256sum ]; then + echo "Create sha256 file..." + cd $TOPDIR/KIWI + /usr/bin/sha256sum "$imageout$buildnum-xen.tar.bz2" > "$imageout$buildnum-xen.tar.bz2.sha256" + fi + EOF +} + +kiwi_post_pxe() { + cat <<-EOF + echo "compressing pxe images... " + cd /$TOPDIR/KIWI-pxe + # do not store compressed file _and_ uncompressed one + [ -e "$imageout.gz" ] && rm -f "$imageout" + tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-pxe.tar.bz2" ${imageout}* initrd-* + if [ -x /usr/bin/sha256sum ]; then + echo "Create sha256 file..." + cd $TOPDIR/KIWI + /usr/bin/sha256sum "$imageout$buildnum-pxe.tar.bz2" > "$imageout$buildnum-pxe.tar.bz2.sha256" + fi + EOF +} + +kiwi_post_iso() { + cat <<-EOF + cd /$TOPDIR/KIWI-iso + for i in *.iso; do + mv "\$i" "/$TOPDIR/KIWI/\${i%.iso}$buildnum.iso" + done + if [ -x /usr/bin/sha256sum ]; then + echo "creating sha256 sum for iso images... " + cd $TOPDIR/KIWI + for i in *.iso; do + /usr/bin/sha256sum "\$i" > "\$i.sha256" + done + fi + EOF +} + +kiwi_post_tbz() { + cat <<-EOF + cd /$TOPDIR/KIWI-tbz + for i in *.tbz; do + file=\$(readlink -f "\$i") + [ -z "\$file" ] && echo readlink failed for $i + mv "\$file" "/$TOPDIR/KIWI/\${i%.tbz}$buildnum.tbz" + done + if [ -x /usr/bin/sha256sum ]; then + echo "creating sha256 sum for tar balls... " + cd $TOPDIR/KIWI + for i in *.tbz; do + /usr/bin/sha256sum "\$i" > "\$i.sha256" + done + fi + EOF +} + +kiwi_post_unknown() { + cat <<-EOF + echo "compressing unkown images... " + cd /$TOPDIR/KIWI-$imgtype + # do not store compressed file _and_ uncompressed one + [ -e "$imageout.gz" ] && rm -f "$imageout" + tar cvjfS "/$TOPDIR/KIWI/$imageout$buildnum-$imgtype.tar.bz2" * + if [ -x /usr/bin/sha256sum ]; then + echo "Create sha256 file..." + cd /$TOPDIR/KIWI + /usr/bin/sha256sum "$imageout$buildnum-$imgtype.tar.bz2" > "$imageout$buildnum-$imgtype.tar.bz2.sha256" + fi + EOF +} + +############################################################ + +recipe_setup_kiwi() { + TOPDIR=/usr/src/packages + mkdir -p "$BUILD_ROOT$TOPDIR" + mkdir -p "$BUILD_ROOT$TOPDIR/OTHER" + mkdir -p "$BUILD_ROOT$TOPDIR/SOURCES" + mkdir -p "$BUILD_ROOT$TOPDIR/KIWI" + chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR" + if test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then + mv "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/ + else + if test -z "$LINKSOURCES" ; then + cp -dLR "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/ + else + cp -lR "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/ + fi + if test "$?" != 0 ; then + echo "source copy failed" + cleanup_and_exit 1 + fi + fi + + # extract macros from configuration + # some post scripts might call rpm-build and rely on the macros + queryconfig rawmacros --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" > $BUILD_ROOT/root/.rpmmacros +} + +recipe_prepare_kiwi() { + : +} + +## obsolete with current kiwi versions, only needed for kiwi 3.01 version +run_suse_isolinux() { + for i in $BUILD_ROOT/$TOPDIR/KIWIROOT/main/* ; do + test -d "$i" || continue + i="${i##*/}" + test "$i" = scripts && continue + test "$i" != "${i%0}" && continue + chroot $BUILD_ROOT su -c "suse-isolinux $TOPDIR/KIWIROOT/main/$i $TOPDIR/KIWI/$i.iso" - $BUILD_USER + done +} + +build_kiwi_product() { + echo "running kiwi --create-instsource..." + # runs always as abuild user + mkdir -p "$BUILD_ROOT/$TOPDIR/KIWIROOT" + # XXX: again? + chroot "$BUILD_ROOT" chown -R abuild.abuild "$TOPDIR" + chroot "$BUILD_ROOT" rm -rf "$TOPDIR/KIWIROOT" + ver=`chroot "$BUILD_ROOT" su -c "/usr/sbin/kiwi --version | sed -n 's,.*kiwi version v\(.*\),\1,p'"` + test -n "$ver" || ver=`chroot "$BUILD_ROOT" su -c "/usr/sbin/kiwi --version | sed -n 's,.* vnr: \(.*\),\1,p'"` + if test "${ver:0:1}" == "3" ; then + # old style kiwi 3 builds + chroot "$BUILD_ROOT" su -c "APPID=- LANG=POSIX /usr/sbin/kiwi --root $TOPDIR/KIWIROOT -v --logfile terminal -p $TOPDIR/SOURCES --instsource-local --create-instsource $TOPDIR/SOURCES" - abuild < /dev/null && BUILD_SUCCEEDED=true + test ${ver:2:2} == "01" && run_suse_isolinux + else + VERBOSE_OPTION="-v 2" + # broken kiwi version, not accepting verbose level + test "${ver:0:1}" == "4" -a "${ver:2:2}" -lt 90 && VERBOSE_OPTION="-v -v" + chroot "$BUILD_ROOT" su -c "APPID=- LANG=POSIX /usr/sbin/kiwi --root $TOPDIR/KIWIROOT $VERBOSE_OPTION --logfile terminal -p $TOPDIR/SOURCES --create-instsource $TOPDIR/SOURCES" - abuild < /dev/null && BUILD_SUCCEEDED=true + fi + + # move created product to correct destination + for i in $BUILD_ROOT/$TOPDIR/KIWIROOT/main/* ; do + test -e "$i" || continue + f=${i##*/} + case $f in + *.iso) if [ -x /usr/bin/sha256sum ]; then + /usr/bin/sha256sum "$i" > "$i.sha256" + mv "$i.sha256" $BUILD_ROOT/$TOPDIR/KIWI/. + fi + mv "$i" $BUILD_ROOT/$TOPDIR/KIWI/. ;; + *.packages) mv $i $BUILD_ROOT/$TOPDIR/OTHER/. ;; + *.report) mv $i $BUILD_ROOT/$TOPDIR/OTHER/. ;; + scripts) ;; + *0) ;; + *) test -d $i -a "$drop_repo" != true && mv $i $BUILD_ROOT/$TOPDIR/KIWI/. ;; + esac + done +} + +build_kiwi_appliance() { + if test -z "$RUNNING_IN_VM" ; then + # NOTE: this must be done with the outer system, because it loads the dm-mod kernel modules, which needs to fit to the kernel. + echo "starting device mapper for kiwi..." + test -x /etc/init.d/boot.device-mapper && /etc/init.d/boot.device-mapper start + fi + RUN_BUNDLE="true" + for imgtype in $imagetype ; do + echo "running kiwi --prepare for $imgtype..." + # Do not use $BUILD_USER here, since we always need root permissions + chroot $BUILD_ROOT su -c "cd $TOPDIR/SOURCES && rm -rf $TOPDIR/KIWIROOT-$imgtype && kiwi --prepare $TOPDIR/SOURCES --logfile terminal --root $TOPDIR/KIWIROOT-$imgtype $KIWI_PARAMETERS" - root < /dev/null || cleanup_and_exit 1 + echo "running kiwi --create for $imgtype..." + mkdir -p $BUILD_ROOT/$TOPDIR/KIWI-$imgtype + chroot $BUILD_ROOT su -c "cd $TOPDIR/SOURCES && kiwi --create $TOPDIR/KIWIROOT-$imgtype --logfile terminal --type $imgtype -d $TOPDIR/KIWI-$imgtype $KIWI_PARAMETERS" - root < /dev/null || cleanup_and_exit 1 + rm -rf "/$TOPDIR/KIWI.bundle" + if chroot $BUILD_ROOT su -c "kiwi --bundle-build $TOPDIR/KIWI-$imgtype -d /$TOPDIR/KIWI.bundle/ --bundle-id Build$RELEASE" - root < /dev/null; then + mv "$BUILD_ROOT/$TOPDIR/KIWI.bundle/"* "$BUILD_ROOT/$TOPDIR/KIWI/" || cleanup_and_exit 1 + rmdir "$BUILD_ROOT/$TOPDIR/KIWI.bundle" + unset RUN_BUNDLE + fi + done + BUILD_SUCCEEDED=true + + if test -z "$RUN_BUNDLE"; then + # new kiwi has bundled our result already :) + return + fi + + # + # Legacy bundling code for kiwi version below 5.06.106 + # + + # create tar.gz of images, in case it makes sense + buildnum= + if test -n "$RELEASE"; then + buildnum="-Build$RELEASE" + fi + imagearch=`uname -m` + imageout="$imagename.$imagearch-$imageversion" + for imgtype in $imagetype ; do + case "$imgtype" in + oem) kiwi_post_oem > $BUILD_ROOT/kiwi_post.sh ;; + vmx) kiwi_post_vmx > $BUILD_ROOT/kiwi_post.sh ;; + xen) kiwi_post_xen > $BUILD_ROOT/kiwi_post.sh ;; + pxe) kiwi_post_pxe > $BUILD_ROOT/kiwi_post.sh ;; + iso) kiwi_post_iso > $BUILD_ROOT/kiwi_post.sh ;; + tbz) kiwi_post_tbz > $BUILD_ROOT/kiwi_post.sh ;; + *) kiwi_post_unknown > $BUILD_ROOT/kiwi_post.sh ;; + esac + cat >> $BUILD_ROOT/kiwi_post.sh <<-EOF + cd /$TOPDIR/KIWI-$imgtype + if [ -e "$imageout.channel" ]; then + echo "Found kiwi channel list file, exporting as well..." + cp "$imageout.channel" "/$TOPDIR/OTHER/$imageout$buildnum-$imgtype.channel" + fi + if [ -e "$imageout.packages" ]; then + echo "Found kiwi package list file, exporting as well..." + cp "$imageout.packages" "/$TOPDIR/OTHER/$imageout$buildnum-$imgtype.packages" + fi + if [ -e "$imageout.verified" ]; then + echo "Found rpm verification report, exporting as well..." + cp "$imageout.verified" "/$TOPDIR/OTHER/$imageout$buildnum-$imgtype.verified" + fi + EOF + chroot $BUILD_ROOT su -c "sh -e /kiwi_post.sh" || cleanup_and_exit 1 + rm -f $BUILD_ROOT/kiwi_post.sh + done +} + +recipe_build_kiwi() { + imagetype=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $BUILD_ROOT/$TOPDIR/SOURCES/$RECIPEFILE imagetype) + imagename=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $BUILD_ROOT/$TOPDIR/SOURCES/$RECIPEFILE filename) + imageversion=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $BUILD_ROOT/$TOPDIR/SOURCES/$RECIPEFILE version) + drop_repo=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $BUILD_ROOT/$TOPDIR/SOURCES/$RECIPEFILE drop_repository) + + # prepare rpms as source and createrepo on the repositories + ln -sf $TOPDIR/SOURCES/repos $BUILD_ROOT/repos + cd $BUILD_ROOT/$TOPDIR/SOURCES/repos + for r in */* ; do + test -L $r && continue + test -d $r || continue + repo="$TOPDIR/SOURCES/repos/$r/" + # create compatibility link for old kiwi versions + rc="${r//:/:/}" + if test "$rc" != "$r" ; then + rl="${rc//[^\/]}" + rl="${rl//?/../}" + mkdir -p "${rc%/*}" + ln -s $rl$r "${rc%/*}/${rc##*/}" + repo="$TOPDIR/SOURCES/repos/${rc%/*}/${rc##*/}/" + fi + if test "$imagetype" != product -a "$DO_INIT" != "false" ; then + echo "creating repodata for $repo" + if chroot $BUILD_ROOT createrepo --no-database --simple-md-filenames --help >/dev/null 2>&1 ; then + chroot $BUILD_ROOT createrepo --no-database --simple-md-filenames "$repo" + else + chroot $BUILD_ROOT createrepo "$repo" + fi + fi + done + + # unpack root tar + for t in $BUILD_ROOT/$TOPDIR/SOURCES/root.tar* ; do + test -f $t || continue + mkdir -p $BUILD_ROOT/$TOPDIR/SOURCES/root + chroot $BUILD_ROOT tar -C $TOPDIR/SOURCES/root -xf "$TOPDIR/SOURCES/${t##*/}" + done + + # fix script permissions + chmod a+x $BUILD_ROOT/$TOPDIR/SOURCES/*.sh 2>/dev/null + + # unpack tar files in image directories + if test -d $BUILD_ROOT/$TOPDIR/SOURCES/images ; then + ( + cd $BUILD_ROOT/$TOPDIR/SOURCES/images + for r in */* ; do + test -L $r && continue + test -d $r || continue + for t in $r/root.tar* ; do + test -f $t || continue + mkdir -p $r/root + chroot $BUILD_ROOT tar -C $TOPDIR/SOURCES/images/$r/root -xf "$TOPDIR/SOURCES/images/$r/${t##*/}" + done + # fix script permissions + chmod a+x $BUILD_ROOT/$TOPDIR/SOURCES/images/$r/*.sh 2>/dev/null + # create compatibility link for old kiwi versions + rc="${r//:/:/}" + if test "$rc" != "$r" ; then + rl="${rc//[^\/]}" + rl="${rl//?/../}" + mkdir -p "${rc%/*}" + ln -s $rl$r "${rc%/*}/${rc##*/}" + fi + done + ) + fi + + rm -f $BUILD_ROOT/$TOPDIR/SOURCES/config.xml + ln -s $RECIPEFILE $BUILD_ROOT/$TOPDIR/SOURCES/config.xml + + if test "$imagetype" = product ; then + build_kiwi_product + else + build_kiwi_appliance + fi + + # Hook for running post kiwi build scripts like QA scripts if installed + if test -x $BUILD_ROOT/usr/lib/build/kiwi_post_run ; then + chroot $BUILD_ROOT su -c /usr/lib/build/kiwi_post_run || cleanup_and_exit 1 + fi +} + +recipe_resultdirs_kiwi() { + echo KIWI +} diff --git a/build-recipe-livebuild b/build-recipe-livebuild new file mode 100644 index 0000000..c9d3566 --- /dev/null +++ b/build-recipe-livebuild @@ -0,0 +1,225 @@ +################################################################# +# +# Debian live-build specific functions. +# +# Author: Jan Blunck <jblunck@infradead.org> +# +# This file is part of build. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################# + +recipe_setup_livebuild() { + + TOPDIR=/usr/src/packages + rm -rf "$BUILD_ROOT$TOPDIR" + for i in OTHER SOURCES LIVEBUILD_ROOT ; do + mkdir -p "$BUILD_ROOT$TOPDIR/$i" + done + chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR" + if test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then + mv "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/ + else + cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/ + fi +} + +recipe_prepare_livebuild() { + : +} + +createrepo_debian() { + local DIR=${1} + local ARCH=${2} + local DIST=${3} + + if [ -z "${DIR}" -o ! -d ${DIR} -o ${DIR} = ${DIR##${BUILD_ROOT}} ] ; then + return + fi + + pushd ${DIR} >/dev/null + + # cleanup existing repository files + rm -f Packages Packages.gz Release + rm -fr dists + + mkdir -p dists/${DIST} + # Suite is symlinked to Codename + ln -s ${DIST} dists/stable + + # create Packages and Sources files + mkdir -p dists/${DIST}/main/binary-${ARCH} + mkdir -p dists/${DIST}/main/source + cat > ${BUILD_ROOT}/.createrepo_debian.tmp.sh <<-EOF + cd /.build.binaries || exit 1 + dpkg-scanpackages -m . > dists/${DIST}/main/binary-${ARCH}/Packages + gzip -c9 < dists/${DIST}/main/binary-${ARCH}/Packages \ + > dists/${DIST}/main/binary-${ARCH}/Packages.gz + dpkg-scansources . > dists/${DIST}/main/source/Sources + gzip -c9 dists/${DIST}/main/source/Sources \ + > dists/${DIST}/main/source/Sources.gz + EOF + chroot $BUILD_ROOT su -c "sh /.createrepo_debian.tmp.sh" - root + local RESULT=$? + rm -f $BUILD_ROOT/.createrepo_debian.tmp.sh + [ "${RESULT}" != 0 ] && return + + # create Release file + pushd dists/${DIST} >/dev/null + cat > Release <<-EOF + Origin: Debian + Label: Debian + Suite: stable + Version: 7.1 + Codename: ${DIST} + Date: Sat, 15 Jun 2013 10:55:26 UTC + Description: Debian repository created by build-recipe-livebuild + Components: main + EOF + echo "SHA256:" >> Release + for file in main/binary-${ARCH}/Packages* ; do + local SUM=( $(sha256sum ${file}) ) + local SIZE=$(stat -c '%s' ${file}) + echo " ${SUM} ${SIZE} ${file}" >> Release + done + for file in main/source/Sources* ; do + local SUM=( $(sha256sum ${file}) ) + local SIZE=$(stat -c '%s' ${file}) + echo " ${SUM} ${SIZE} ${file}" >> Release + done + popd >/dev/null + + # TODO: this is missing the signature with the private key + + popd >/dev/null +} + +# This script expects that the $BUILD_ROOT is a Debian installation with +# live-build already installed! +# +# Variables: +# $BUILD_ROOT the Debian chroot +# $TOPDIR/SOURCES includes the live-build config tarball +# $TOPDIR/$LIVEBUILD_ROOT where live-build will be called +# $RECIPEFILE the name of the live-build config tarball + +recipe_build_livebuild() { + local ARCH=$(chroot $BUILD_ROOT su -c "dpkg-architecture -qDEB_BUILD_ARCH") + local DIST=$(chroot $BUILD_ROOT su -c "lsb_release --codename" | awk '{ print $2 }') + local LIVEBUILD_ROOT="LIVEBUILD_ROOT" + + [ -z "${ARCH}" -o -z "${DIST}" ] && cleanup_and_exit 1 + + test -d $BUILD_ROOT/.build.binaries || cleanup_and_exit 1 + if test "$DO_INIT" = true -o ! -d "$BUILD_ROOT/.build.binaries/dists" ; then + echo "creating repository metadata..." + createrepo_debian $BUILD_ROOT/.build.binaries ${ARCH} ${DIST} + fi + + # Write our default configuration variables + mkdir -p $BUILD_ROOT/etc/live + cat > $BUILD_ROOT/etc/live/build.conf <<-EOF + LB_DEBIAN_INSTALLER_DISTRIBUTION="${DIST}" + LB_DISTRIBUTION="${DIST}" + LB_PARENT_DISTRIBUTION="${DIST}" + LB_PARENT_DEBIAN_INSTALLER_DISTRIBUTION="${DIST}" + LB_PARENT_MIRROR_BOOTSTRAP="file:/.build.binaries/" + LB_PARENT_MIRROR_CHROOT="file:/.build.binaries/" + LB_PARENT_MIRROR_CHROOT_SECURITY="file:/.build.binaries/" + LB_PARENT_MIRROR_BINARY="file:/.build.binaries/" + LB_PARENT_MIRROR_BINARY_SECURITY="file:/.build.binaries/" + LB_PARENT_MIRROR_DEBIAN_INSTALLER="file:/.build.binaries/" + LB_MIRROR_BOOTSTRAP="file:/.build.binaries/" + LB_MIRROR_CHROOT="file:/.build.binaries/" + LB_MIRROR_CHROOT_SECURITY="file:/.build.binaries/" + LB_MIRROR_BINARY="file:/.build.binaries/" + LB_MIRROR_BINARY_SECURITY="file:/.build.binaries/" + LB_MIRROR_DEBIAN_INSTALLER="file:/.build.binaries/" + LB_APT_SECURE="false" + EOF + + # Expand live-build configuration to $TOPDIR/$LIVEBUILD_ROOT + echo "Expanding live-build configuration" + tar -xvf $BUILD_ROOT/$TOPDIR/SOURCES/$RECIPEFILE \ + -C $BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT || cleanup_and_exit 1 + + # Skip top-level directory if it matches recipe name, ... + local files=($BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT/*) + # ... but ignore some well known names + files=(${files[@]%%*/auto}) + files=(${files[@]%%*/config}) + files=(${files[@]%%*/local}) + if [ ${#files[@]} -eq 1 ] && \ + [ -d $BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT/${RECIPEFILE%.livebuild} ] + then + LIVEBUILD_ROOT="LIVEBUILD_ROOT/${RECIPEFILE%.livebuild}" + fi + + # Sanity check to not configure archives inside configuration + files=($BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT/config/archives/*) + [ ${#files[@]} -gt 0 ] && cleanup_and_exit 1 + + # TODO: Add the repository public key + # cp ... $BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT/config/archives/debian.key + + if [ -x $BUILD_ROOT/usr/lib/build/livebuild_pre_run ] ; then + echo "Running OBS build livebuild_pre_run hook" + chroot $BUILD_ROOT su -c "/usr/lib/build/livebuild_pre_run" - root \ + < /dev/null || cleanup_and_exit 1 + fi + + # TODO: this might move to lb auto/config file + if [ -f $BUILD_ROOT/$TOPDIR/SOURCES/livebuild_pre_run ] ; then + cp $BUILD_ROOT/$TOPDIR/SOURCES/livebuild_pre_run \ + $BUILD_ROOT/.build.livebuild_pre_run + chmod +x $BUILD_ROOT/.build.livebuild_pre_run + echo "Running package livebuild_pre_run hook" + chroot $BUILD_ROOT su -c "/.build.livebuild_pre_run" - root \ + < /dev/null || cleanup_and_exit 1 + fi + + chroot $BUILD_ROOT su -c "cd $TOPDIR/$LIVEBUILD_ROOT && lb build" - root \ + < /dev/null || cleanup_and_exit 1 + + # Move created product to destination + for i in $BUILD_ROOT/$TOPDIR/$LIVEBUILD_ROOT/* ; do + test -f "$i" || continue + case "${i##*/}" in + *.iso) + # all created files share the same name without suffix + mv ${i%%.iso}.* $BUILD_ROOT/$TOPDIR/OTHER/. + BUILD_SUCCEEDED=true + ;; + *) + ;; + esac + done + + # Fail the build if no ISO was created + if [ -z "$(ls $BUILD_ROOT/$TOPDIR/OTHER/*.iso)" ] ; then + echo "No ISO image found" + cleanup_and_exit 1 + fi +} + +recipe_resultdirs_livebuild() { + # our results are already in OTHER + : +} + +# Local Variables: +# mode: Shell-script +# End: diff --git a/build-recipe-mock b/build-recipe-mock new file mode 100644 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-spec b/build-recipe-spec new file mode 100644 index 0000000..c9a948c --- /dev/null +++ b/build-recipe-spec @@ -0,0 +1,261 @@ +# +# spec specific functions. +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +recipe_setup_spec() { + TOPDIR=`chroot $BUILD_ROOT su -c "rpm --eval '%_topdir'" - $BUILD_USER` + if test -z "$TOPDIR"; then + echo "Error: TOPDIR empty" + cleanup_and_exit 1 + fi + if [ "$NO_TOPDIR_CLEANUP" = false ]; then + rm -rf "$BUILD_ROOT$TOPDIR" + for i in BUILD RPMS/`uname -m` RPMS/i386 RPMS/noarch SOURCES SPECS SRPMS BUILDROOT OTHER ; do + mkdir -p $BUILD_ROOT$TOPDIR/$i + done + fi + + chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR" + mkdir -p $BUILD_ROOT$TOPDIR/SOURCES + cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/ +} + +recipe_prepare_spec() { + args=() + if test -n "$RELEASE"; then + args=(--release "$RELEASE") + fi + + # fixup specfile + CHANGELOGARGS= + test -n "$CHANGELOG" -a -f "$BUILD_ROOT/.build-changelog" && CHANGELOGARGS="--changelog $BUILD_ROOT/.build-changelog" + substitutedeps "${args[@]}" --root "$BUILD_ROOT" --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" $CHANGELOGARGS "$BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE" "$BUILD_ROOT/.spec.new" || cleanup_and_exit 1 + + # fix rpmrc if we are compiling for i686 + test -f $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 && mv $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 $BUILD_ROOT/usr/lib/rpm/rpmrc + if test -e $BUILD_ROOT/usr/lib/rpm/rpmrc -a "$BUILD_ARCH" != "${BUILD_ARCH#i686}" ; then + mv $BUILD_ROOT/usr/lib/rpm/rpmrc $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 + sed -e 's/^buildarchtranslate: athlon.*/buildarchtranslate: athlon: i686/' -e 's/^buildarchtranslate: i686.*/buildarchtranslate: i686: i686/' < $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 > $BUILD_ROOT/usr/lib/rpm/rpmrc + fi + if test "$DO_BUILD" = false ; then + cleanup_and_exit 0 + fi + + # extract macros from configuration + queryconfig rawmacros --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" > $BUILD_ROOT/root/.rpmmacros + if test -n "$BUILD_DEBUG" ; then + echo ' +%prep %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%prep +%package %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%package +%_build_insert_debug_package \ +%global __debug_package 1 \ +%undefine _enable_debug_packages \ +%debug_package + +' >> $BUILD_ROOT/root/.rpmmacros + fi + + if test -n "$BUILD_JOBS" ; then + cat >> $BUILD_ROOT/root/.rpmmacros <<-EOF + %jobs $BUILD_JOBS + %_smp_mflags -j$BUILD_JOBS + EOF + fi + test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmmacros $BUILD_ROOT/home/abuild/.rpmmacros + + # extract optflags from configuration + queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" optflags ${BUILD_DEBUG:+debug} > $BUILD_ROOT/root/.rpmrc + test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmrc $BUILD_ROOT/home/abuild/.rpmrc + + if test -z "$ABUILD_TARGET"; then + ABUILD_TARGET=$(queryconfig target --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" ) + test -z "$ABUILD_TARGET" || echo "build target is $ABUILD_TARGET" + fi + + # report specfile changes + if test -f $BUILD_ROOT/.spec.new ; then + if ! cmp -s $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE $BUILD_ROOT/.spec.new ; then + echo ----------------------------------------------------------------- + echo "I have the following modifications for $RECIPEFILE:" + sed -e "/^%changelog/q" $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE > $BUILD_ROOT/.spec.t1 + sed -e "/^%changelog/q" $BUILD_ROOT/.spec.new > $BUILD_ROOT/.spec.t2 + diff $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2 + rm -f $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2 + mv $BUILD_ROOT/.spec.new $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE + else + rm -f $BUILD_ROOT/.spec.new + fi + fi +} + +recipe_build_spec() { + test -z "$BUILD_RPM_BUILD_STAGE" && BUILD_RPM_BUILD_STAGE=-ba + + rpmbuild=rpmbuild + test -x $BUILD_ROOT/usr/bin/rpmbuild || rpmbuild=rpm + + # XXX: move _srcdefattr to macro file? + rpmbopts=("--define" "_srcdefattr (-,root,root)") + if test "$DO_CHECKS" != true ; then + rpmbopts[${#rpmbopts[@]}]="--nocheck" + fi + if test "$rpmbuild" == "rpmbuild" ; then + # use only --nosignature for rpm v4 + rpmbopts[${#rpmbopts[@]}]="--nosignature" + fi + if test -n "$ABUILD_TARGET" ; then + rpmbopts[${#rpmbopts[@]}]="--target=$ABUILD_TARGET" + fi + if test -n "$BUILD_DEBUG" ; then + rpmbopts[${#rpmbopts[@]}]='--define' + rpmbopts[${#rpmbopts[@]}]="_build_create_debug 1" + fi + if test -n "$DISTURL" ; then + rpmbopts[${#rpmbopts[@]}]='--define' + rpmbopts[${#rpmbopts[@]}]="disturl $DISTURL" + fi + if test -n "$RSYNCDONE" ; then + rpmbopts[${#rpmbopts[@]}]='--define' + rpmbopts[${#rpmbopts[@]}]="RSYNCDONE 1" + fi + + # su involves a shell which would require even more + # complicated quoting to bypass than this + if test "$SHORT_CIRCUIT" = false ; then + rpmbopts[${#rpmbopts[@]}]="$BUILD_RPM_BUILD_STAGE" + toshellscript $rpmbuild \ + "${definesnstuff[@]}" \ + "${rpmbopts[@]}" \ + "$TOPDIR/SOURCES/$RECIPEFILE" \ + > $BUILD_ROOT/.build.command + else + rpmbopts[${#rpmbopts[@]}]='--short-circuit' + buildopts="-bc -bi -bb -bs" + cmds="" + echo "#!/bin/sh -x" >$BUILD_ROOT/.build.command + echo "set -e" >>$BUILD_ROOT/.build.command + for opt in $buildopts + do + shellquote $rpmbuild \ + "${definesnstuff[@]}" \ + "${rpmbopts[@]}" $opt \ + "$TOPDIR/SOURCES/$RECIPEFILE" \ + >> $BUILD_ROOT/.build.command + echo >>$BUILD_ROOT/.build.command + [ "$opt" == "$BUILD_RPM_BUILD_STAGE" ] && break + done + fi + + chmod 755 $BUILD_ROOT/.build.command + check_exit + if test -n "$RUN_SHELL"; then + chroot $BUILD_ROOT su - + else + chroot $BUILD_ROOT su -c /.build.command - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true + fi +} + +recipe_resultdirs_spec() { + echo RPMS SRPMS +} + +recipe_unpack_srcrpm() { + test -n "$LIST_STATE" || echo "processing src rpm $SRCDIR/$RECIPEFILE ..." + MYSRCDIR="$BUILD_ROOT/.build-srcdir" + rm -rf "$MYSRCDIR" + mkdir -p "$MYSRCDIR" + cd $MYSRCDIR || cleanup_and_exit 1 + $BUILD_DIR/unrpm -q $SRCDIR/$RECIPEFILE || { + echo "could not unpack $RECIPEFILE." + cleanup_and_exit 1 + } + for RECIPEFILE in *.spec ; do : ; done +} + +# post build functions... move somewhere else? + +recipe_check_file_owners() { + echo "... checking for files with abuild user/group" + BADFILE= + while read un gn fn ; do + if test "$un" = abuild -o "$gn" = abuild -o "$un" = ${ABUILD_UID} -o "$gn" = ${ABUILD_GID} ; then + echo " $un $gn $fn" + BADFILE=true + fi + done < <(rpm -qp --qf '[%{FILEUSERNAME} %{FILEGROUPNAME} %{FILENAMES}\n]' $RPMS) + if test -n "$BADFILE" ; then + echo "please fix your filelist (e.g. add defattr)" + cleanup_and_exit 1 + fi +} + +recipe_run_rpmlint() { + if ! test -x "$BUILD_ROOT/opt/testing/bin/rpmlint" ; then + return + fi + LINT_RPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/RPMS \ + \( -name "*-debuginfo-*" -o -name "*-debugsource-*" \ + -o -name "*-32bit-*" -o -name "*-64bit-*" \ + -o -name "*-x86-*" -o -name "*-ia32-*" \) -prune \ + -o -type f -name '*.rpm' -print)) + SRPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/SRPMS -type f -name "*.rpm")) + echo + echo "RPMLINT report:" + echo "===============" + rpmlint_logfile=$TOPDIR/OTHER/rpmlint.log + rm -f "$BUILD_ROOT$rpmlint_logfile" + ret=0 + mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null + chroot $BUILD_ROOT su -s /opt/testing/bin/rpmlint "$BUILD_USER" -- \ + --info ${LINT_RPM_FILE_LIST[*]#$BUILD_ROOT} \ + ${SRPM_FILE_LIST[*]#$BUILD_ROOT} > "$BUILD_ROOT$rpmlint_logfile" || ret=1 + cat "$BUILD_ROOT$rpmlint_logfile" + echo + umount -n $BUILD_ROOT/proc 2>/dev/null || true + if test "$ret" = 1 ; then + cleanup_and_exit 1 + fi +} + +recipe_compare_oldpackages() { + if test -x "$BUILD_ROOT/usr/lib/build/same-build-result.sh" ; then + echo "... comparing built packages with the former built" + mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null + if chroot $BUILD_ROOT /usr/lib/build/same-build-result.sh /.build.oldpackages "$TOPDIR/RPMS" "$TOPDIR/SRPMS"; then + chroot $BUILD_ROOT touch /.build/.same_result_marker + # XXX: dirty build service hack. fix bs_worker. Search for + # 'same_result_marker' for traces of a first try to get rid of this + if test -n "$REASON" -a -n "$DISTURL" ; then + exitcode=2 + fi + fi + umount -n $BUILD_ROOT/proc 2>/dev/null || true + fi +} + +recipe_create_deltarpms() { + if test -x "$BUILD_ROOT/usr/bin/makedeltarpm" -a -x $BUILD_ROOT/usr/lib/build/mkdrpms ; then + echo "... creating delta rpms" + ds=("$BUILD_ROOT/$TOPDIR"/RPMS/* "$BUILD_ROOT$TOPDIR/SRPMS") + chroot $BUILD_ROOT /usr/lib/build/mkdrpms /.build.oldpackages "${ds[@]#$BUILD_ROOT}" + fi +} diff --git a/build-vm b/build-vm new file mode 100644 index 0000000..01070d9 --- /dev/null +++ b/build-vm @@ -0,0 +1,828 @@ +# +# VM specific functions for the build script +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +# defaults for vm_img_mkfs +vm_img_mkfs_ext4_options='-O ^has_journal,^huge_file,^resize_inode,sparse_super' +vm_img_mkfs_ext4_extra='-E lazy_itable_init,discard' +vm_img_mkfs_ext4="mkfs.ext4 -m 0 -q -F $vm_img_mkfs_ext4_options" +vm_img_tunefs_ext4='tune2fs -c 0' +vm_img_mkfs_ext3='mkfs.ext3 -m 0 -q -F' +vm_img_tunefs_ext3='tune2fs -c 0 -o journal_data_writeback' +vm_img_mkfs_ext2='mkfs.ext2 -m 0 -q -F' +vm_img_tunefs_ext2='tune2fs -c 0' +vm_img_mkfs_reiserfs='mkreiserfs -q -f' +vm_img_mkfs_btrfs='mkfs.btrfs' +vm_img_mkfs_xfs='mkfs.xfs -f' + +# guest visible swap device +VM_SWAPDEV=/dev/hda2 + +VM_TYPE= +VM_IMAGE= +VM_SWAP= +VM_KERNEL= +VM_INITRD= +VM_WORKER= +VM_SERVER= +VM_MEMSIZE= +VMDISK_ROOTSIZE=4096 +VMDISK_SWAPSIZE=1024 +VMDISK_FILESYSTEM= +VMDISK_MOUNT_OPTIONS=__default +VMDISK_CLEAN= + +# zvm specific? +VM_WORKER_NR= + +# kvm specific? +HUGETLBFSPATH= + +# emulator specific? +EMULATOR_SCRIPT= + +for i in ec2 emulator kvm lxc openstack qemu uml xen zvm ; do + . "$BUILD_DIR/build-vm-$i" +done + +VM_WATCHDOG= +VM_WATCHDOG_PID= + +# the following functions just call the corresponding vm versions +vm_kill() { + vm_kill_$VM_TYPE "$@" +} + +vm_verify_options() { + vm_verify_options_$VM_TYPE "$@" +} + +vm_attach_root() { + vm_attach_root_$VM_TYPE "$@" +} + +vm_attach_swap() { + vm_attach_swap_$VM_TYPE "$@" +} + +vm_detach_root() { + vm_detach_root_$VM_TYPE "$@" +} + +vm_detach_swap() { + vm_detach_swap_$VM_TYPE "$@" +} + +vm_fixup() { + vm_fixup_$VM_TYPE "$@" +} + +vm_startup() { + vm_startup_$VM_TYPE "$@" +} + +vm_kill() { + vm_kill_$VM_TYPE "$@" +} + +vm_cleanup() { + kill_watchdog + vm_cleanup_$VM_TYPE "$@" +} + +vm_parse_options() { + case ${PARAM/#--/-} in + -vm-emulator-script|-emulator-script) + needarg + EMULATOR_SCRIPT="$ARG" + shift + ;; + -xen|-kvm|-uml|-qemu|-emulator) + VM_TYPE=${PARAM##*-} + test -z "$VM_IMAGE" && VM_IMAGE=1 + if test -n "$ARG" ; then + VM_IMAGE="$ARG" + shift + fi + ;; + -zvm|-lxc) + VM_TYPE=${PARAM##*-} + shift + ;; + -vm-type) + needarg + VM_TYPE="$ARG" + case "$VM_TYPE" in + lxc) ;; + ec2|xen|kvm|uml|qemu|emulator|openstack|zvm) + test -z "$VM_IMAGE" && VM_IMAGE=1 + ;; + none|chroot) VM_TYPE= ;; + *) + echo "VM '$VM_TYPE' is not supported" + cleanup_and_exit + ;; + esac + shift + ;; + -vm-worker) + needarg + VM_WORKER="$ARG" + shift + ;; + -vm-worker-nr|-vm-worker-no) + needarg + VM_WORKER_NR="$ARG" + shift + ;; + -vm-server|-vm-region) + needarg + VM_SERVER="$ARG" + shift + ;; + -vm-volumes) + needarg + VM_VOLUME_NAME="$ARG" + shift + ARG="$1" + test "$ARG" = "${ARG#-}" || ARG= + needarg + VM_VOLUME_SWAP="$ARG" + shift + ;; + -vm-disk) + needarg + VM_IMAGE="$ARG" + shift + ;; + -vm-swap|-xenswap|-swap) + needarg + VM_SWAP="$ARG" + shift + ;; + -vm-memory|-xenmemory|-memory) + needarg + VM_MEMSIZE="$ARG" + shift + ;; + -vm-kernel) + needarg + VM_KERNEL="$ARG" + shift + ;; + -vm-initrd) + needarg + VM_INITRD="$ARG" + shift + ;; + -vm-disk-size|-vmdisk-rootsize) + needarg + VMDISK_ROOTSIZE="$ARG" + shift + ;; + -vm-swap-size|-vmdisk-swapsize) + needarg + VMDISK_SWAPSIZE="$ARG" + shift + ;; + -vm-disk-filesystem|-vmdisk-filesystem) + needarg + VMDISK_FILESYSTEM="$ARG" + shift + ;; + -vm-disk-mount-options|-vmdisk-mount-options) + needarg + # options needs to be quoted to handle argument which might start with "-o ..." + VMDISK_MOUNT_OPTIONS=$(echo $ARG | sed 's/^\"\(.*\)\"$/\1/g') + shift + ;; + -vm-disk-clean|-vmdisk-clean) + # delete old root/swap to get rid of the old blocks + VMDISK_CLEAN=true + ;; + -vm-hugetlbfs|-hugetlbfs) + needarg + HUGETLBFSPATH="$ARG" + shift + ;; + -vm-watchdog) + VM_WATCHDOG=true + ;; + -*) + return 1 + ;; + esac + nextargs=("$@") + return 0 +} + + +# +# shutdown the system from inside the VM +# +vm_shutdown() { + test -n "$VM_WATCHDOG" && echo "### WATCHDOG MARKER START ###" + cd / + test -n "$1" || set 1 + if test -n "$VM_SWAP" -a -e "$VM_SWAP" ; then + swapoff "$VM_SWAP" 2>/dev/null + echo -n "BUILDSTATUS$1" >"$VM_SWAP" + fi + exec >&0 2>&0 # so that the logging tee finishes + sleep 1 # wait till tee terminates + test "$VM_TYPE" = lxc && exit $1 + kill -9 -1 # goodbye cruel world + if ! test -x /sbin/halt ; then + test -e /proc/sysrq-trigger || mount -n -tproc none /proc + sync + sleep 2 # like halt does + if test -e /proc/sysrq-trigger; then + echo o > /proc/sysrq-trigger + sleep 5 # wait for sysrq to take effect + else + echo "Warning: VM doesn't support sysrq and /sbin/halt not installed" + fi + else + sync # halt from systemd is not syncing anymore. + halt -f -p + fi + echo "Warning: clean shut down of the VM didn't work" + exit $1 # init died... +} + +vm_img_create() { + local img="$1" + local size="$2" + + echo "Creating $img (${size}M)" + mkdir -p "${img%/*}" || cleanup_and_exit 3 + + # prefer fallocate, which avoids fragmentation + r=1 + if type -p fallocate > /dev/null ; then + fallocate -l "${size}M" "$img" + r=$? + fi + # fall back to dd method if fallocate is not supported + if test "$r" -gt 0 ; then + dd if=/dev/zero of="$img" bs=1M count=0 seek="$size" || cleanup_and_exit 3 + fi +} + +vm_img_mkfs() { + local fs="$1" + local img="$2" + local mkfs tunefs + eval "mkfs=\"\$vm_img_mkfs_${fs}\"" + eval "mkfs_exta_options=\"\$vm_img_mkfs_${fs}_extra\"" + eval "tunefs=\"\$vm_img_tunefs_${fs}\"" + + if test -z "$mkfs"; then + echo "filesystem \"$fs\" is not supported" + cleanup_and_exit 3 + fi + + echo "Creating $fs filesystem on $img" + export MKE2FS_SYNC=0 + if ! $mkfs $mkfs_exta_options "$img"; then + if test -z "$mkfs_exta_options"; then + cleanup_and_exit 3 + else + echo "Format call failed, trying again without extra options..." + $mkfs "$img" || cleanup_and_exit 3 + fi + fi + if test -n "$tunefs" ; then + $tunefs "$img" || cleanup_and_exit 3 + fi +} + +background_monitor_process() { + max_disk=0 + max_mem=0 + while sleep 5; do + test -e /.build/_statistics.exit && exit 0 + + # memory usage + if test -e /proc/meminfo ; then + memtotal=0 + while read key value unit; do + case $key in + MemTotal:|SwapTotal:) memtotal=$(( $memtotal + $value )) ;; + MemFree:|SwapFree:|SwapCached:|Cached:|Buffers:) memtotal=$(( $memtotal - $value )) ;; + esac + done < /proc/meminfo + if test ${memtotal} -gt $max_mem ; then + max_mem="${memtotal}" + echo -n $(( $max_mem / 1024 )) > /.build/_statistics.memory.new && mv /.build/_statistics.memory.new /.build/_statistics.memory + fi + fi + + # disk storage usage + if type -p df >& /dev/null; then + c=(`df -m / 2>/dev/null | tail -n 1`) + + if test ${c[2]} -gt $max_disk ; then + max_disk="${c[2]}" + echo -n $max_disk > /.build/_statistics.df.new && mv /.build/_statistics.df.new /.build/_statistics.df + fi + fi + done +} + +background_watchdog() { + WATCHDOG_START= + WATCHDOG_TIMEOUT=300 + while sleep 5 ; do + WATCH=`grep -a "### WATCHDOG MARKER" "$LOGFILE" | tail -n 1` + case $WATCH in + *WATCHDOG\ MARKER\ START*) test -n "$WATCHDOG_START" || WATCHDOG_START=`date +%s` ;; + *WATCHDOG\ MARKER\ END*) WATCHDOG_START= ;; + esac + if test -n "$WATCHDOG_START" ; then + NOW=`date +%s` + ELAPSED=$((NOW-WATCHDOG_START)) + if test $ELAPSED -gt $WATCHDOG_TIMEOUT ; then + # kill the VM + echo "### WATCHDOG TRIGGERED, KILLING VM ###" + fuser -k -TERM "$VM_IMAGE" + exit 0 + fi + fi + done +} + +start_watchdog() { + local wf=$(mktemp) + ( background_watchdog & echo $! > "$wf" ) + read VM_WATCHDOG_PID < "$wf" + rm -f "$wf" +} + +kill_watchdog() { + test -n "$VM_WATCHDOG_PID" && kill "$VM_WATCHDOG_PID" + VM_WATCHDOG_PID= +} + +vm_set_personality_syscall() { + local archname + archname=`perl -V:archname 2>/dev/null` + archname="${archname#archname=?}" + case "$archname" in + x86_64*) PERSONALITY_SYSCALL=135 ;; + alpha*) PERSONALITY_SYSCALL=324 ;; + sparc*) PERSONALITY_SYSCALL=191 ;; + ia64*) PERSONALITY_SYSCALL=1140 ;; + i?86*|ppc*|aarch64*|arm*|sh4|cris|m68k*|s390*|unicore32|microblaze) PERSONALITY_SYSCALL=136 ;; + *) echo "Unknown architecture personality: '$archname'"; cleanup_and_exit 1 ;; + esac +} + +# used before calling kvm or xen +linux64() { + perl -e 'syscall('$PERSONALITY_SYSCALL', 0); exec(@ARGV) || die("$ARGV[0]: $!\n")' "$@" +} + +vm_detect_2nd_stage() { + if test ! -e /.build/build.data -o -n "$BUILD_IGNORE_2ND_STAGE" ; then + return 1 + fi + . /.build/build.data + if test -z "$VM_TYPE" ; then + return 1 + fi + if test $$ -eq 1 || test $$ -eq 2 ; then + # ignore special init signals if we're init + # we're using ' ' instead of '' so that the signal handlers + # are reset in the child processes + trap ' ' HUP TERM + $0 "$@" + cleanup_and_exit $? + fi + + test -n "$VM_WATCHDOG" -a -z "$PERSONALITY_SET" && echo "### WATCHDOG MARKER END ###" + echo "2nd stage started in virtual machine" + BUILD_ROOT=/ + BUILD_DIR=/.build + echo "machine type: `uname -m`" + if test "$PERSONALITY" != 0 -a -z "$PERSONALITY_SET" ; then + export PERSONALITY_SET=true + echo "switching personality to $PERSONALITY..." + # this is 32bit perl/glibc, thus the 32bit syscall number + exec perl -e 'syscall(136, '$PERSONALITY') == -1 && warn("personality: $!\n");exec "/.build/build" || die("/.build/build: $!\n")' + fi + RUNNING_IN_VM=true + test -e /proc/version || mount -orw -n -tproc none /proc + if test "$VM_TYPE" != lxc ; then + mount -n ${VMDISK_MOUNT_OPTIONS},remount,rw / + fi + umount /run >/dev/null 2>&1 + # mount /sys + if ! test -e /sys/block; then + mkdir -p /sys + mount -orw -n -tsysfs sysfs /sys + fi +# qemu inside of xen does not work, check again with kvm later before enabling this +# if test -e /dev/kqemu ; then +# # allow abuild user to run qemu +# chmod 0666 /dev/kqemu +# fi + + if test -n "$VM_SWAP" ; then + for i in 1 2 3 4 5 6 7 8 9 10 ; do + test -e "$VM_SWAP" && break + test $i = 1 && echo "waiting for $VM_SWAP to appear" + echo -n . + sleep 1 + done + test $i = 1 || echo + # recreate the swap device manually if it didn't exist for some + # reason, hardcoded to hda2 atm + if ! test -b "$VM_SWAP" ; then + rm -f "$VM_SWAP" + umask 027 + mknod "$VM_SWAP" b 3 2 + umask 022 + fi + # Do not rely on external system writing the signature, it might differ... + mkswap "$VM_SWAP" + swapon -v "$VM_SWAP" || exit 1 + fi + HOST="$MYHOSTNAME" + + # fork a process monitoring max filesystem usage during build + if test "$DO_STATISTICS" = 1 ; then + rm -f /.build/_statistics.exit + ( background_monitor_process & ) + fi + + if test ! -e /dev/.udev ; then + echo "WARNING: udev not running, creating extra device nodes" + test -e /dev/fd || ln -sf /proc/self/fd /dev/fd + test -e /etc/mtab || ln -sf /proc/mounts /etc/mtab + fi + + # set date to build start on broken systems (now < build start) + if test $(date '+%s') -lt $(date -r /.build/.date '+%s') ; then + echo -n "WARNING: system has a broken clock, setting it to a newer time: " + date -s `cat /.build/.date` + fi + + return 0 +} + +vm_set_filesystem_type() { + if test -z "$VMDISK_FILESYSTEM" -a -n "$BUILD_DIST" ; then + VMDISK_FILESYSTEM=`queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" buildflags vmfstype` + fi + test -n "$VMDISK_FILESYSTEM" || VMDISK_FILESYSTEM=ext3 +} + +vm_set_mount_options() { + if test "$VMDISK_MOUNT_OPTIONS" = __default; then + if test "$VMDISK_FILESYSTEM" = reiserfs ; then + VMDISK_MOUNT_OPTIONS='-o data=writeback,commit=150,noatime' + elif test "$VMDISK_FILESYSTEM" = btrfs ; then + VMDISK_MOUNT_OPTIONS='-o nobarrier,noatime' + elif test "$VMDISK_FILESYSTEM" = "ext4" ; then + VMDISK_MOUNT_OPTIONS='-o noatime' + elif test "$VMDISK_FILESYSTEM" = "ext3" ; then + VMDISK_MOUNT_OPTIONS='-o data=writeback,nobarrier,commit=150,noatime' + elif test "$VMDISK_FILESYSTEM" = "ext2" ; then + VMDISK_MOUNT_OPTIONS='-o noacl,noatime' + elif test "$VMDISK_FILESYSTEM" = "xfs" ; then + VMDISK_MOUNT_OPTIONS='-o noatime' + else + VMDISK_MOUNT_OPTIONS='-o noatime' + fi + fi +} + +# +# create file system and swap space, mount file system to $BUILD_ROOT +# +vm_setup() { + vm_set_filesystem_type + vm_set_mount_options + if test "$VM_IMAGE" = 1 ; then + VM_IMAGE="$BUILD_ROOT.img" + if test -z "$VM_SWAP" -a "$VM_TYPE" != emulator; then + VM_SWAP="$BUILD_ROOT.swap" + fi + echo "VM_IMAGE: $VM_IMAGE, VM_SWAP: $VM_SWAP" + else + echo "VM_IMAGE: $VM_IMAGE, VM_SWAP: $VM_SWAP" + vm_attach_root + fi + # this should not be needed, but sometimes a xen instance got lost + test "$VM_TYPE" = xen && vm_purge_xen + if test -n "$VMDISK_CLEAN" ; then + # delete old root/swap to get rid of the old blocks + if test -n "$VM_IMAGE" -a -f "$VM_IMAGE" ; then + echo "Deleting old $VM_IMAGE" + rm -rf "$VM_IMAGE" + fi + if test -n "$VM_SWAP" -a -f "$VM_SWAP" ; then + echo "Deleting old $VM_SWAP" + rm -rf "$VM_SWAP" + fi + fi + if test ! -e "$VM_IMAGE" ; then + vm_img_create "$VM_IMAGE" "$VMDISK_ROOTSIZE" + if test -z "$CLEAN_BUILD" ; then + vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE" + fi + fi + if test -n "$VM_SWAP" -a ! -e "$VM_SWAP" -a ! -b "$VM_SWAP" ; then + vm_img_create "$VM_SWAP" "$VMDISK_SWAPSIZE" + fi + if test ! -e "$VM_IMAGE" ; then + echo "you need to create $VM_IMAGE first" + cleanup_and_exit 3 + fi + if test -n "$CLEAN_BUILD" ; then + vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE" || cleanup_and_exit 3 + fi + # now mount root/swap + mkdir_build_root + if test -w /root ; then + if test -b $VM_IMAGE ; then + # mount device directly + mount $VMDISK_MOUNT_OPTIONS $VM_IMAGE $BUILD_ROOT || cleanup_and_exit 3 + else + mount ${VMDISK_MOUNT_OPTIONS},loop $VM_IMAGE $BUILD_ROOT || cleanup_and_exit 3 + fi + else + if ! mount $BUILD_ROOT; then + echo "mounting the build root failed. An fstab entry is probably missing or incorrect." + echo "/etc/fstab should contain an entry like this:" + echo "$VM_IMAGE $BUILD_ROOT auto noauto,user,loop 0 0" + cleanup_and_exit 3 + fi + fi + if test -n "$VM_SWAP" ; then + vm_attach_swap + dd if=/dev/zero of="$VM_SWAP" bs=1024 count=1 conv=notrunc 2>/dev/null + vm_detach_swap + # mkswap happens inside of the vm + fi +} + +# +# prepare for vm startup +# +vm_first_stage() { + vm_set_personality_syscall + rm -rf "$BUILD_ROOT/.build" + mkdir -p "$BUILD_ROOT/.build" + TIME_PREINSTALL= + if test "$DO_INIT" = true ; then + # do first stage of init_buildsystem + rm -f $BUILD_ROOT/.build.success + set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --prepare "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $USEUSEDFORBUILD $RPMLIST "$MYSRCDIR/$RECIPEFILE" $ADDITIONAL_PACKS + echo "$* ..." + start_time=`date +%s` + "$@" || cleanup_and_exit 1 + check_exit + TIME_PREINSTALL=$(( `date +%s` - $start_time )) + unset start_time + if test ! -w /root ; then + # remove setuid bit if files belong to user to make e.g. mount work + find $BUILD_ROOT/{bin,sbin,usr/bin,usr/sbin} -type f -uid $UID -perm +4000 -print0 | xargs -0 --no-run-if-empty chmod -s + fi + copy_oldpackages + fi + + # start up VM, rerun ourself + cp -a $BUILD_DIR/. $BUILD_ROOT/.build + if ! test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then + rm -rf "$BUILD_ROOT/.build-srcdir" + mkdir "$BUILD_ROOT/.build-srcdir" + if test "$BUILDTYPE" = kiwi ; then + cp -pRL "$MYSRCDIR"/* $BUILD_ROOT/.build-srcdir + else + cp -p "$MYSRCDIR"/* $BUILD_ROOT/.build-srcdir + fi + MYSRCDIR=$BUILD_ROOT/.build-srcdir + else + # cwd is at $BUILD_ROOT/.build-srcdir which we want to + # umount later so step aside + cd "$SRCDIR" + fi + + # do vm specific fixups + vm_fixup + + # the watchdog needs a log file + test -n "$LOGFILE" || VM_WATCHDOG= + # put our config into .build/build.data + Q="'\''" + echo "RECIPEFILE='${RECIPEFILE//"'"/$Q}'" > $BUILD_ROOT/.build/build.data + echo "BUILD_JOBS='${BUILD_JOBS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "BUILD_ARCH='${BUILD_ARCH//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "BUILD_RPMS='${BUILD_RPMS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + case $BUILD_DIST in + */*) + cp $BUILD_DIST $BUILD_ROOT/.build/build.dist + BUILD_DIST=/.build/build.dist + ;; + esac + echo "BUILD_DIST='${BUILD_DIST//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "RELEASE='${RELEASE//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "BUILD_DEBUG='${BUILD_DEBUG//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "SIGNDUMMY='${SIGNDUMMY//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "DO_LINT='${DO_LINT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "DO_CHECKS='${DO_CHECKS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "NOROOTFORBUILD='${NOROOTFORBUILD//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "CREATE_BASELIBS='$CREATE_BASELIBS'" >> $BUILD_ROOT/.build/build.data + echo "REASON='${REASON//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "CHANGELOG='${CHANGELOG//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "INCARNATION='${INCARNATION//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "DISTURL='${DISTURL//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "DO_INIT='${DO_INIT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + echo "KIWI_PARAMETERS='${KIWI_PARAMETERS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + test -n "$VM_SWAP" && echo "VM_SWAP='${VM_SWAPDEV//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + test -n "$VMDISK_MOUNT_OPTIONS" && echo "VMDISK_MOUNT_OPTIONS='${VMDISK_MOUNT_OPTIONS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data + PERSONALITY=0 + test -n "$PERSONALITY_SYSCALL" && PERSONALITY=`perl -e 'print syscall('$PERSONALITY_SYSCALL', 0)."\n"'` + test "$PERSONALITY" = -1 && PERSONALITY=0 # syscall failed? + case $(uname -m) in + ppc|ppcle|s390) PERSONALITY=8 ;; # ppc/s390 kernel never tells us if a 32bit personality is active, assume we run on 64bit + aarch64) test "$BUILD_ARCH" != "${BUILD_ARCH#armv}" && PERSONALITY=8 ;; # workaround, to be removed + esac + test "$VM_TYPE" = lxc && PERSONALITY=0 + echo "PERSONALITY='$PERSONALITY'" >> $BUILD_ROOT/.build/build.data + echo "MYHOSTNAME='`hostname`'" >> $BUILD_ROOT/.build/build.data + echo -n "definesnstuff=(" >> $BUILD_ROOT/.build/build.data + shellquote "${definesnstuff[@]}" >> $BUILD_ROOT/.build/build.data + echo ")" >> $BUILD_ROOT/.build/build.data + echo -n "repos=(" >> $BUILD_ROOT/.build/build.data + shellquote "${repos[@]}" >> $BUILD_ROOT/.build/build.data + echo ")" >> $BUILD_ROOT/.build/build.data + echo "VM_TYPE='$VM_TYPE'" >> $BUILD_ROOT/.build/build.data + echo "RUN_SHELL='$RUN_SHELL'" >> $BUILD_ROOT/.build/build.data + echo "DO_STATISTICS='$DO_STATISTICS'" >> $BUILD_ROOT/.build/build.data + echo "TIME_PREINSTALL='$TIME_PREINSTALL'" >> $BUILD_ROOT/.build/build.data + echo "VM_WATCHDOG='$VM_WATCHDOG'" >> $BUILD_ROOT/.build/build.data + echo "BUILDENGINE='$BUILDENGINE'" >> $BUILD_ROOT/.build/build.data + echo "CCACHE='$CCACHE'" >> $BUILD_ROOT/.build/build.data + echo "ABUILD_TARGET='$ABUILD_TARGET'" >> $BUILD_ROOT/.build/build.data + # fallback time for broken hosts + date '+@%s' > $BUILD_ROOT/.build/.date + # we're done with the root file system, unmount + umount -n $BUILD_ROOT/proc/sys/fs/binfmt_misc 2> /dev/null || true + umount -n $BUILD_ROOT/proc 2> /dev/null || true + umount -n $BUILD_ROOT/dev/pts 2> /dev/null || true + umount -n $BUILD_ROOT/dev/shm 2> /dev/null || true + umount -n $BUILD_ROOT/mnt 2> /dev/null || true + + vm_init_script="/.build/build" + if check_use_emulator ; then + vm_init_script="/.build/$INITVM_NAME" + fi + if test -n "$VM_IMAGE" ; then + # copy out kernel & initrd (if they exist) during unmounting VM image + KERNEL_TEMP_DIR= + if test -z "$VM_KERNEL" -a -e "$BUILD_ROOT/.build.kernel.$VM_TYPE" ; then + KERNEL_TEMP_DIR=`mktemp -d` + cp "$BUILD_ROOT/.build.kernel.$VM_TYPE" "$KERNEL_TEMP_DIR/kernel" + if test -e "$BUILD_ROOT/.build.initrd.$VM_TYPE" ; then + cp "$BUILD_ROOT/.build.initrd.$VM_TYPE" "$KERNEL_TEMP_DIR/initrd" + fi + fi + check_exit + # needs to work otherwise we have a corrupted file system + if ! umount $BUILD_ROOT; then + rm -rf "$KERNEL_TEMP_DIR" + cleanup_and_exit 3 + fi + # copy back the kernel and set it for VM + if test -n "$KERNEL_TEMP_DIR" ; then + mkdir -p "$BUILD_ROOT/boot" + mv "$KERNEL_TEMP_DIR/kernel" "$BUILD_ROOT/boot/kernel" + vm_kernel="$BUILD_ROOT/boot/kernel" + if test -e "$KERNEL_TEMP_DIR/initrd" ; then + mv "$KERNEL_TEMP_DIR/initrd" "$BUILD_ROOT/boot/initrd" + test -z "$VM_INITRD" && vm_initrd="$BUILD_ROOT/boot/initrd" + fi + rmdir "$KERNEL_TEMP_DIR" + fi + fi + vm_detach_root + + # start watchdog if requested + if test -n "$VM_WATCHDOG" ; then + start_watchdog + echo "### WATCHDOG MARKER START ###" + fi + + echo "booting $VM_TYPE..." + vm_startup + + # kill watchdog again + if test -n "$VM_WATCHDOG" ; then + echo "### WATCHDOG MARKER END ###" + kill_watchdog + fi + + vm_attach_root + if test -n "$VM_SWAP" ; then + vm_attach_swap + BUILDSTATUS=`dd if="$VM_SWAP" bs=12 count=1 2>/dev/null` + case $BUILDSTATUS in + BUILDSTATUS[02]) + mkdir -p $BUILD_ROOT/.build.packages + cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1 + echo "build: extracting built packages..." + extractbuild --disk "$VM_IMAGE" --input "$VM_SWAP" --skip 512 -v || cleanup_and_exit 3 + if test "$DO_STATISTICS" = 1 ; then + mkdir -p OTHER + TIME_TOTAL=$(( `date +%s` - $TIME_START_TIME )) + echo "TIME_total: $TIME_TOTAL" >> OTHER/_statistics + fi + cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS} + ;; + BUILDSTATUS*) + cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS} + ;; + *) + echo "No buildstatus set, either the base system is broken (kernel/initrd/udev/glibc/bash/perl)" + echo "or the build host has a kernel or hardware problem..." + cleanup_and_exit 3 + ;; + esac + cleanup_and_exit 1 + fi +} + +vm_save_statistics() { + echo "... saving statistics" + local sys_mounted otherdir + otherdir="$BUILD_ROOT$TOPDIR/OTHER" + test -n "$TIME_PREINSTALL" && echo "TIME_preinstall: $TIME_PREINSTALL" >> $otherdir/_statistics + test -n "$TIME_INSTALL" && echo "TIME_install: $TIME_INSTALL" >> $otherdir/_statistics + if test -e /.build/_statistics.df ; then + echo -n "MAX_mb_used_on_disk: " >> $otherdir/_statistics + cat /.build/_statistics.df >> $otherdir/_statistics + echo "" >> $otherdir/_statistics + rm /.build/_statistics.df + fi + if test -e /.build/_statistics.memory ; then + echo -n "MAX_mb_used_memory: " >> $otherdir/_statistics + cat /.build/_statistics.memory >> $otherdir/_statistics + echo "" >> $otherdir/_statistics + rm /.build/_statistics.memory + fi + if ! test -e /sys/block; then + mkdir -p /sys + mount -n sys /sys -t sysfs + sys_mounted=1 + fi + device="hda1" + test -e /dev/sda && device="sda" + test -e /dev/vda && device="vda" + test -e /dev/dasda && device="dasda" # in z/VM + test -e /dev/nfhd0 && device="nfhd0" # in aranym + if test -e /sys/block/${device}/stat ; then + disk=(`cat /sys/block/${device}/stat`) + test "0${disk[0]}" -gt 0 && echo "IO_requests_read: ${disk[0]}" >> $otherdir/_statistics + test "0${disk[2]}" -gt 0 && echo "IO_sectors_read: ${disk[2]}" >> $otherdir/_statistics + test "0${disk[4]}" -gt 0 && echo "IO_requests_write: ${disk[4]}" >> $otherdir/_statistics + test "0${disk[6]}" -gt 0 && echo "IO_sectors_write: ${disk[6]}" >> $otherdir/_statistics + else + echo "ERROR: no root disk device found, yet another new device name?" + ls -l /sys/block/ + fi + test -n "$sys_mounted" && umount /sys +} + +# args: resultdirs +vm_wrapup_build() { + test "$DO_STATISTICS" = 1 && vm_save_statistics + if test -n "$VM_SWAP"; then + echo "... saving built packages" + swapoff "$VM_SWAP" + pushd "$BUILD_ROOT$TOPDIR" >/dev/null + find "$@" -print0 | computeblocklists --padstart 512 --padend 512 -v --manifest - -0 > "$VM_SWAP" + popd >/dev/null + fi +} diff --git a/build-vm-ec2 b/build-vm-ec2 new file mode 100644 index 0000000..3fefc61 --- /dev/null +++ b/build-vm-ec2 @@ -0,0 +1,228 @@ +# +# EC2 specific functions +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +BUILD_EC2_TYPE="t1.micro" + +cloud_volume_attach_ec2() { + local VM_SERVER="$1" + local VM_VOL_NAME="$2" + local VM_VOL_DEV="$3" + + temp_file=`mktemp` + if ! ec2-attach-volume "$VM_VOL_NAME" -d /dev/sdz -i `ec2-instance-id` --region "$BUILD_EC2_REGION" > "$temp_file"; then + rm -f "$temp_file" + cleanup_and_exit 1 + fi + # wait that it becomes available + while true; do + state=`ec2_volume_state "$VM_VOL_NAME"` + test "$state" = attached && break + sleep 1 + done + # print device node + grep ^ATTACHMENT "$temp_file" | awk '{ print $4 }' + rm -f "$temp_file" +} + +cloud_volume_detach_ec2() { + local VM_SERVER="$1" + local VM_VOL_NAME="$2" + state=`ec2_volume_state "$VM_VOL_NAME"` + if test "$state" != available ; then + ec2-detach-volume "$VM_VOL_NAME" --region "$BUILD_EC2_REGION" || return 3 + fi + return 0 +} + +vm_verify_options_ec2() { + # verify settings + if test -z "$AWS_ACCESS_KEY" -o -z "$AWS_ACCESS_KEY" ; then + echo "ERROR: No amazon EC2 environment set. Set AWS_ACCESS_KEY and AWS_SECRET_KEY." + cleanup_and_exit 3 + fi + . /etc/profile.d/ec2.sh + EC2_INSTANCE_ID=`ec2-instance-id` + BUILD_EC2_AKI= + BUILD_EC2_ZONE=`ec2-meta-data placement/availability-zone` + BUILD_EC2_REGION=${BUILD_EC2_ZONE%?} + case "$BUILD_EC2_ZONE" in + us-east-1) BUILD_EC2_AKI=aki-88aa75e1 ;; + us-west-1) BUILD_EC2_AKI=aki-f77e26b2 ;; + us-west-2) BUILD_EC2_AKI=aki-fc37bacc ;; + eu-west-1) BUILD_EC2_AKI=aki-71665e05 ;; + ap-southeast-1) BUILD_EC2_AKI=aki-fe1354ac ;; + ap-southeast-2) BUILD_EC2_AKI=aki-3f990e05 ;; + ap-northeast-1) BUILD_EC2_AKI=aki-44992845 ;; + sa-east-1) BUILD_EC2_AKI=aki-c48f51d9 ;; + us-gov-west-1) BUILD_EC2_AKI=aki-79a4c05a ;; + esac + if test -z "$BUILD_EC2_AKI" ; then + echo "Unknown Amazon EC2 Zone: $BUILD_EC2_ZONE" + cleanup_and_exit 1 + fi + if test -z "$BUILD_EC2_AKI" ; then + echo "ERROR: No image refering to kernel and ramdisk is defined in BUILD_EC2_AKI env." + cleanup_and_exit 3 + fi + if test -z "$VM_VOLUME_NAME" ; then + echo "ERROR: No worker root VM volume name specified." + cleanup_and_exit 3 + fi + if test -z "$VM_VOLUME_SWAP" ; then + echo "ERROR: No worker swap VM volume name specified." + cleanup_and_exit 3 + fi + + VM_SWAPDEV=/dev/sdb1 # in the vm +} + +vm_attach_root_ec2() { + VM_IMAGE=`cloud_volume_attach_ec2 "$VM_SERVER" "$VM_VOLUME_NAME" "$VM_IMAGE"` + test "${VM_IMAGE:0:5}" = /dev/ || cleanup_and_exit 3 +} + +vm_attach_swap_ec2() { + VM_SWAP=`cloud_volume_attach_ec2 "$VM_SERVER" "$EC2_EXTRACT_VOLUME_swap" "$VM_SWAP"` + test "${VM_SWAP:0:5}" = /dev/ || cleanup_and_exit 3 +} + +vm_detach_root_ec2() { + cloud_volume_detach_ec2 "$VM_SERVER" "$VM_VOLUME_NAME" +} + +vm_detach_swap_ec2() { + cloud_volume_detach_ec2 "$VM_SERVER" "$VM_VOLUME_SWAP" +} + +vm_fixup_ec2() { + # No way to handle this via init= parameter here.... + echo "#!/bin/sh" > "$BUILD_ROOT/sbin/init" + echo 'exec /.build/build "$@"' >> "$BUILD_ROOT/sbin/init" + chmod 0755 "$BUILD_ROOT/sbin/init" + # use the instance kernel, if no kernel got installed via preinstall + if ! test -e "$BUILD_ROOT/boot/vmlinuz"; then + cp /boot/vmlinuz-ec2 "$BUILD_ROOT/boot/vmlinuz" + cp /boot/initrd-ec2 "$BUILD_ROOT/boot/initrd" + fi + # install menu.lst for pv grub + if ! test -e "$BUILD_ROOT/boot/grub/menu.lst"; then + mkdir -p "$BUILD_ROOT/boot/grub" + echo "serial --unit=0 --speed=9600" > "$BUILD_ROOT/boot/grub/menu.lst" + echo "terminal --dumb serial" >> "$BUILD_ROOT/boot/grub/menu.lst" + echo "default 0" >> "$BUILD_ROOT/boot/grub/menu.lst" + echo "timeout 0" >> "$BUILD_ROOT/boot/grub/menu.lst" + echo "hiddenmenu" >> "$BUILD_ROOT/boot/grub/menu.lst" + echo "" >> "$BUILD_ROOT/boot/grub/menu.lst" + echo "title default" >> "$BUILD_ROOT/boot/grub/menu.lst" + echo " root (hd0)" >> "$BUILD_ROOT/boot/grub/menu.lst" + echo " kernel /boot/vmlinuz root=/dev/sda1 xencons=xvc0 console=xvc0 splash=silent" >> "$BUILD_ROOT/boot/grub/menu.lst" + echo " initrd /boot/initrd" >> "$BUILD_ROOT/boot/grub/menu.lst" + fi +} + +vm_cleanup_ec2() { + cloud_volume_detach_ec2 "$VM_SERVER" "$VM_VOLUME_NAME" + cloud_volume_detach_ec2 "$VM_SERVER" "$VM_VOLUME_SWAP" + test -n "$EC2_EXTRACT_VOLUME_root" && cloud_volume_detach_ec2 "$VM_SERVER" "$EC2_EXTRACT_VOLUME_root" + test -n "$EC2_EXTRACT_VOLUME_swap" && cloud_volume_detach_ec2 "$VM_SERVER" "$EC2_EXTRACT_VOLUME_swap" + test -n "$EC2_SNAP_root" && ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" + test -n "$EC2_SNAP_swap" && ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap" + test -n "$EC2_EXTRACT_VOLUME_root" && ec2-delete-volume --region "$BUILD_EC2_REGION" "$EC2_EXTRACT_VOLUME_root" + test -n "$EC2_EXTRACT_VOLUME_swap" && ec2-delete-volume --region "$BUILD_EC2_REGION" "$EC2_EXTRACT_VOLUME_swap" +} + +vm_kill_ec2() { + if ec2-describe-instance-status "$VM_BUILD_INSTANCE" --region "$BUILD_EC2_REGION" >/dev/null 2>&1 ; then + if ec2-terminate-instances "$VM_BUILD_INSTANCE" >/dev/null 2>&1 ; then + echo "could not kill EC2 instance $VM_BUILD_INSTANCE" + cleanup_and_exit 1 + fi + fi +} + +vm_startup_ec2() { + EC2_SNAP_root=`ec2-create-snapshot --region "$BUILD_EC2_REGION" "$VM_VOLUME_NAME" | awk '{ print $2 }'` + if test "$EC2_SNAP_root" = "${EC2_SNAP_root#snap-}" ; then + echo "ERROR: Failed to create snapshot for root disk $VM_VOLUME_NAME" + cleanup_and_exit 3 + fi + EC2_SNAP_swap=`ec2-create-snapshot --region "$BUILD_EC2_REGION" "$VM_VOLUME_SWAP" | awk '{ print $2 }'` + if test "$EC2_SNAP_swap" = "${EC2_SNAP_swap#snap-}" ; then + echo "ERROR: Failed to create snapshot for swap disk $VM_VOLUME_SWAP" + ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" + cleanup_and_exit 3 + fi + # wait for snapshots being processed + while true; do + c=`ec2-describe-snapshots --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" "$EC2_SNAP_swap" | grep completed | wc -l` + test "$c" = 2 && break + done + EC2_AMI=`ec2-register --region "$BUILD_EC2_REGION" -n build-$VM_VOLUME_NAME -a x86_64 -b "/dev/sda1=$EC2_SNAP_root::false" -b "/dev/sdb1=$EC2_SNAP_swap::false" --kernel "$BUILD_EC2_AKI" | awk '{ print $2 }'` + if test "$EC2_AMI" == "${EC2_AMI#ami-}" ; then + echo "ERROR: Failed to register the AMI" + ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" + ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap" + cleanup_and_exit 3 + fi + INSTANCE=`ec2-run-instances --region "$BUILD_EC2_REGION" -z "$BUILD_EC2_ZONE" -t $BUILD_EC2_TYPE --kernel "$BUILD_EC2_AKI" --instance-initiated-shutdown-behavior terminate "$EC2_AMI" | grep ^INSTANCE | awk '{ print $2 }'` + if test "$INSTANCE" == "${INSTANCE#i-}" ; then + echo "ERROR: Failed to run the instance for AMI $EC2_AMI" + ec2-deregister --region "$BUILD_EC2_REGION" "$EC2_AMI" + ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" + ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap" + cleanup_and_exit 3 + fi + echo "Waiting for finishing the build. No log file until then on EC2 ...." + I=0 + L=0 + EC2_EXTRACT_VOLUME_root= + EC2_EXTRACT_VOLUME_swap= + temp_file=`mktemp` + while true; do + ec2-describe-instances --region "$BUILD_EC2_REGION" "$INSTANCE" > $temp_file + state=`grep ^INSTANCE "$temp_file"` + if test -z "$EC2_EXTRACT_VOLUME_root" ; then + EC2_EXTRACT_VOLUME_root=`grep ^BLOCKDEVICE $temp_file | grep /dev/sda1 | awk '{ print $3 }'` + EC2_EXTRACT_VOLUME_swap=`grep ^BLOCKDEVICE $temp_file | grep /dev/sdb1 | awk '{ print $3 }'` + fi + # the column of the state is at a differen position depending on the state :/ +# test "$state" = "${state/stopped/}" || break + test "$state" = "${state/terminated/}" || break + I=$(( $I + 1 )) + if test $I -gt 10 ; then + echo -n . + I=0 + L=$(( $L + 1 )) + fi + if test $L -gt 10 ; then + # dump entire console log as raw here + ec2-get-console-output --region "$BUILD_EC2_REGION" -r "$INSTANCE" + L=0 + fi + sleep 1 + done + rm -f "$temp_file" + echo + ec2-deregister --region "$BUILD_EC2_REGION" "$EC2_AMI" + # snapshots get deleted after extract +} diff --git a/build-vm-emulator b/build-vm-emulator new file mode 100644 index 0000000..045d244 --- /dev/null +++ b/build-vm-emulator @@ -0,0 +1,93 @@ +# +# generic emulator specific functions +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +vm_verify_options_emulator() { + if test -f "$BUILD_DIR/emulator/verify-options.sh"; then + . "$BUILD_DIR/emulator/verify-options.sh" + else + VM_SWAP= + fi +} + +vm_startup_emulator() { + pushd "$BUILD_DIR/emulator" + if test -z "$EMULATOR_SCRIPT" ; then + EMULATOR_SCRIPT=./emulator.sh + elif test "${EMULATOR_SCRIPT:0:1}" != / ; then + EMULATOR_SCRIPT="./$EMULATOR_SCRIPT" + fi + set -- "$EMULATOR_SCRIPT" "$VM_IMAGE" "$VM_SWAP" + echo "$@" + if ! "$@"; then + popd + echo "ERROR: The emulator returned with a failure" + cleanup_and_exit 3 + fi + popd + + test -n "$VM_SWAP" && return + + # Emulators may not offer to use a second swap space. + # So we just mount the filesystem. + # WARNING: This is not safe against attacks. + mkdir -p $BUILD_ROOT/.build.packages + cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1 + mkdir -p .mount + mount $VM_IMAGE -o loop .mount + if test -e .mount/.build.packages ; then + cp -a .mount/.build.packages/* . + fi + exitcode=`cat .mount/.build/_exitcode` + umount .mount + rmdir .mount + cleanup_and_exit "$exitcode" +} + +vm_kill_emulator() { + if ! fuser -k -TERM "$VM_IMAGE" ; then + echo "could not kill build in $VM_IMAGE" + cleanup_and_exit 1 + fi +} + +vm_fixup_emulator() { + # emulator may not be able to hand over kernel parameters + ln -sf /.build/build $BUILD_ROOT/sbin/init +} + +vm_attach_root_emulator() { + : +} +vm_attach_swap_emulator() { + : +} +vm_detach_root_emulator() { + : +} +vm_detach_swap_emulator() { + : +} +vm_cleanup_emulator() { + : +} + diff --git a/build-vm-kvm b/build-vm-kvm new file mode 100644 index 0000000..455ecc1 --- /dev/null +++ b/build-vm-kvm @@ -0,0 +1,228 @@ +# +# kvm/qemu specific functions +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +kvm_bin=/usr/bin/qemu-kvm +kvm_console=ttyS0 + +# assume virtio support by default +kvm_device=virtio-blk-pci +kvm_options= + +kvm_check_ppc970() { + if ! grep -q -E '(kvm_rma_count.*kvm_hpt_count)|(kvm_hpt_count.*kvm_rma_count)' /proc/cmdline ; then + echo "put kvm_rma_count=<VM number> or kvm_hpt_count=<> to your boot options" + cleanup_and_exit 3 + fi +} + +kvm_check_hugetlb() { + if ! grep -q "$HUGETLBFSPATH" /proc/mounts ; then + echo "hugetlbfs is not mounted to $HUGETLBFSPATH" + cleanup_and_exit 3 + fi + local HUGETLBBLKSIZE=$(stat -f -c "%S" "$HUGETLBFSPATH") + HUGETLBBLKSIZE=$(( ${HUGETLBBLKSIZE:-0} / 1024 )) + if test "$HUGETLBBLKSIZE" -lt 1 -o ! -e "/sys/kernel/mm/hugepages/hugepages-${HUGETLBBLKSIZE}kB" ; then + echo "could not determine hugetlbfs block size" + cleanup_and_exit 3 + fi + local PAGES_FREE=$(cat /sys/kernel/mm/hugepages/hugepages-${HUGETLBBLKSIZE}kB/free_hugepages) + local PAGES_REQ=$(( ${VM_MEMSIZE:-64} * 1024 / $HUGETLBBLKSIZE )) + if test "$PAGES_FREE" -lt "$PAGES_REQ" ; then + echo "expected $PAGES_REQ to be available (have $PAGES_FREE)" + echo "please adjust nr_hugepages" + cleanup_and_exit 3 + fi +} + +vm_verify_options_kvm() { + vm_kernel= + vm_initrd= + + # overwrite some options for specific host architectures + case `uname -m` in + armv7l) + kvm_bin="/usr/bin/qemu-system-arm" + kvm_console=ttyAMA0 + kvm_options="-enable-kvm -M vexpress-a15 -dtb /boot/a15-guest.dtb -cpu cortex-a15" + vm_kernel=/boot/zImage + vm_initrd=/boot/initrd + # prefer the guest kernel/initrd + test -e /boot/zImage.guest && vm_kernel=/boot/zImage.guest + test -e /boot/initrd.guest && vm_initrd=/boot/initrd.guest + kvm_device=virtio-blk-device + ;; + aarch64) + kvm_bin="/usr/bin/qemu-system-aarch64" + kvm_console=ttyAMA0 + kvm_options="-enable-kvm -M virt -cpu host" + vm_kernel=/boot/Image + vm_initrd=/boot/initrd + # prefer the guest kernel/initrd + test -e /boot/Image.guest && vm_kernel=/boot/Image.guest + test -e /boot/initrd.guest && vm_initrd=/boot/initrd.guest + kvm_device=virtio-blk-device + ;; + ppc|ppcle|ppc64|ppc64le) + kvm_bin="/usr/bin/qemu-system-ppc64" + kvm_console=hvc0 + kvm_options="-enable-kvm -M pseries" + grep -q PPC970MP /proc/cpuinfo && kvm_check_ppc970 + vm_kernel=/boot/vmlinux + vm_initrd=/boot/initrd + if test "$BUILD_ARCH" = ppc64le -a -e /boot/vmlinuxle ; then + vm_kernel=/boot/vmlinuxle + vm_initrd=/boot/initrdle + fi + grep -q "pSeries" /proc/cpuinfo && kvm_device=scsi-hd # no virtio on pSeries + grep -q "PowerNV" /proc/cpuinfo || kvm_device=scsi-hd # no virtio on ppc != power7 yet + ;; + s390|s390x) + kvm_bin="/usr/bin/qemu-system-s390x" + kvm_options="-enable-kvm" + kvm_console=hvc0 + vm_kernel=/boot/image + vm_initrd=/boot/initrd + kvm_device=virtio-blk-ccw + ;; + esac + + # check if we can run kvm + if ! test -r /dev/kvm -a -x "$kvm_bin" ; then + echo "host does not support kvm" + echo "either the kvm kernel-module is not loaded or kvm is not installed or hardware virtualization is deactivated in the BIOS." + cleanup_and_exit 3 + fi + + # check hugepages + test -n "$HUGETLBFSPATH" -a "$VM_TYPE" = kvm && kvm_check_hugetlb + + # set kernel + test -n "$VM_KERNEL" && vm_kernel="$VM_KERNEL" + test -z "$vm_kernel" && vm_kernel=/boot/vmlinuz + + # set initrd + test -n "$VM_INITRD" && vm_initrd="$VM_INITRD" + if test -z "$vm_initrd" ; then + # find a nice default + if test -e "/boot/initrd-build" ; then + vm_initrd="/boot/initrd-build" + elif test -e "/boot/initrd-virtio" ; then + vm_initrd="/boot/initrd-virtio" + else + vm_initrd="/boot/initrd" + kvm_device=ide-hd + # use /etc/sysconfig/kernel as indication if we have virtio + if test -e /etc/sysconfig/kernel ; then + local im=$(INITRD_MODULES=; . /etc/sysconfig/kernel; echo "$INITRD_MODULES") + if test "$im" != "${im/virtio/}" ; then + kvm_device=virtio-blk-pci + fi + fi + fi + fi + + case $kvm_device in + virtio*) + qemu_rootdev=/dev/disk/by-id/virtio-0 + VM_SWAPDEV=/dev/disk/by-id/virtio-1 + ;; + *) + qemu_rootdev=/dev/sda + VM_SWAPDEV=/dev/sdb + ;; + esac +} + +vm_startup_kvm() { + qemu_bin="$kvm_bin" + qemu_args=(-drive file="$VM_IMAGE",if=none,id=disk,serial=0,cache=unsafe -device "$kvm_device",drive=disk) + if test -n "$VM_SWAP" ; then + qemu_args=("${qemu_args[@]}" -drive file="$VM_SWAP",if=none,id=swap,serial=1,cache=unsafe -device "$kvm_device",drive=swap) + fi + + if test -n "$BUILD_JOBS" -a "$icecream" = 0 -a -z "$BUILD_THREADS" ; then + qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS") + elif test -n "$BUILD_JOBS" -a -n "$BUILD_THREADS" ; then + qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS,threads=$BUILD_THREADS") + fi + if test "$VM_TYPE" = kvm ; then + test "$kvm_console" != ttyAMA0 && kvm_options="$kvm_options -cpu host" + test -n "$HUGETLBFSPATH" && kvm_options="$kvm_options -mem-prealloc -mem-path $HUGETLBFSPATH" + fi + set -- $qemu_bin -no-reboot -nographic -vga none -net none $kvm_options \ + -kernel $vm_kernel \ + -initrd $vm_initrd \ + -append "root=$qemu_rootdev panic=1 quiet no-kvmclock nmi_watchdog=0 rw rd.driver.pre=binfmt_misc elevator=noop console=$kvm_console init=$vm_init_script" \ + ${VM_MEMSIZE:+-m $VM_MEMSIZE} \ + "${qemu_args[@]}" + + if test "$PERSONALITY" != 0 ; then + # have to switch back to PER_LINUX to make qemu work + set -- linux64 "$@" + fi + export QEMU_AUDIO_DRV=none # we do not want to have sound inside the VMs + echo "$@" + "$@" +} + +vm_kill_kvm() { + if ! fuser -k -TERM "$VM_IMAGE" ; then + echo "could not kill build in $VM_IMAGE" + cleanup_and_exit 1 + fi +} + +vm_fixup_kvm() { + # check if we will use a kernel from the build root, in this case + # we assume the kernel does virtio + if test -z "$VM_KERNEL" -a -e "$BUILD_ROOT/.build.kernel.$VM_TYPE" ; then + # ide-hd is the non-virtio default + if test "$kvm_device" = ide-hd ; then + kvm_device=virtio-blk-pci + qemu_rootdev=/dev/disk/by-id/virtio-0 + VM_SWAPDEV=/dev/disk/by-id/virtio-1 + fi + fi +} + +vm_attach_root_kvm() { + : +} + +vm_attach_swap_kvm() { + : +} + +vm_detach_root_kvm() { + : +} + +vm_detach_swap_kvm() { + : +} + +vm_cleanup_kvm() { + : +} + diff --git a/build-vm-lxc b/build-vm-lxc new file mode 100644 index 0000000..6d9ef20 --- /dev/null +++ b/build-vm-lxc @@ -0,0 +1,76 @@ +# +# LXC specific functions +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +vm_verify_options_lxc() { + VM_IMAGE= + VM_SWAP= +} + +vm_startup_lxc() { + LXCCONF="$BUILD_ROOT/.build.lxc.conf" + rm -f "$LXCCONF" + cat $BUILD_DIR/lxc.conf > "$LXCCONF" + cat >> "$LXCCONF" <<-EOF + lxc.rootfs = $BUILD_ROOT + EOF + # XXX: do this always instead of leaking the hosts' one? + echo "rootfs / rootfs rw 0 0" > $BUILD_ROOT/etc/mtab + LXCID=${BUILD_ROOT##*/} + lxc-destroy -n "$LXCID" >/dev/null 2>&1 || true + lxc-create -n "$LXCID" -f "$LXCCONF" || cleanup_and_exit 1 + lxc-start -n "$LXCID" "$vm_init_script" + BUILDSTATUS="$?" + test "$BUILDSTATUS" != 255 || BUILDSTATUS=3 + cleanup_and_exit "$BUILDSTATUS" +} + +vm_kill_lxc() { + LXCID=${BUILD_ROOT##*/} + lxc-stop -n "$LXCID" || true + lxc-destroy -n "$LXCID" +} + +vm_fixup_lxc() { + : +} + +vm_attach_root_lxc() { + : +} + +vm_attach_swap_lxc() { + : +} + +vm_detach_root_lxc() { + : +} + +vm_detach_swap_lxc() { + : +} + +vm_cleanup_lxc() { + : +} + diff --git a/build-vm-openstack b/build-vm-openstack new file mode 100644 index 0000000..73688ec --- /dev/null +++ b/build-vm-openstack @@ -0,0 +1,145 @@ +# +# Openstack specific functions +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +cloud_volume_attach_openstack() { + local VM_SERVER="$1" + local VM_VOL_NAME="$2" + local VM_VOL_DEV="$3" + + if ! nova volume-attach "$VM_SERVER" "$VM_VOL_NAME" "$VM_VOL_DEV"; then + echo "ERROR: nova attach failed. $?" >&2 + return 3 + fi + while true; do + state=`nova volume-show "$VM_VOL_NAME" | sed -n 's,^|[ ]*status[ ]*|[ ]*\([^ ]*\).*,\1,p'` + test "$state" = "in-use" && break + if test -z "$state" ; then + echo "ERROR: unable to find state of volume $VM_VOL_NAME" >&2 + return 3 + fi + if test "$state" = available ; then + echo "WARNING: volume $VM_VOL_NAME got not attached, retrying" >&2 + if ! nova volume-attach "$VM_SERVER" "$VM_VOL_NAME" "$VM_VOL_DEV"; then + echo "ERROR: nova attach failed. $?" >&2 + return 3 + fi + fi + sleep 3 + done + if test ! -e "$VM_VOL_DEV" ; then + #GROSS HACK: kernel does not care about the given device name +# VM_VOL_DEV="/dev/"`dmesg| sed -n 's,.*\(vd.\): unknown partition tab.*,\1,p' | tail -n 1` + VM_VOL_DEV=`ls -1 /dev/vd? | tail -n 1` + fi + echo "$VM_VOL_DEV" +} + +cloud_volume_detach_openstack() { + local VM_SERVER="$1" + local VM_VOL_NAME="$2" + + # needed at all? + nova volume-show "$VM_VOL_NAME" | grep -q in-use || return 0 + # umount seems not to be enough + sync + if ! nova volume-detach "$VM_SERVER" "$VM_VOL_NAME"; then + echo "ERROR: nova detach of $VM_VOL_NAME failed." >&2 + return 3 + fi + while nova volume-show "$VM_VOL_NAME" | grep -q availabe; do + sleep 3 + done + return 0 +} + +vm_verify_options_openstack() { + # verify settings + if test -z "$OS_AUTH_URL" ; then + echo "ERROR: No openstack environment set. This vm-type works only inside of an openstack VM." + cleanup_and_exit 3 + fi + if test -z "$OBS_OPENSTACK_KERNEL_IMAGE_ID" ; then + echo "ERROR: No image refering to kernel and ramdisk is defined in OBS_OPENSTACK_KERNEL_IMAGE_ID env." + cleanup_and_exit 3 + fi + if test -z "$VM_VOLUME_NAME" ; then + echo "ERROR: No worker root VM volume name specified." + cleanup_and_exit 3 + fi + if test -z "$VM_VOLUME_SWAP" ; then + echo "ERROR: No worker swap VM volume name specified." + cleanup_and_exit 3 + fi + if test -z "$VM_SERVER" ; then + echo "ERROR: No VM server nod name specified (usually this instance)." + cleanup_and_exit 3 + fi + + # XXX why here? + VM_SWAPDEV=/dev/vdb + qemu_rootdev=/dev/vda +} + +vm_attach_root_openstack() { + VM_IMAGE=`cloud_volume_attach_openstack "$VM_SERVER" "$VM_VOLUME_NAME" "$VM_IMAGE"` + test "${VM_IMAGE:0:5}" = "/dev/" || cleanup_and_exit 3 +} + +vm_attach_swap_openstack() { + VM_SWAP=`cloud_volume_attach_openstack "$VM_SERVER" "$VM_VOLUME_SWAP" "$VM_SWAP"` + test "${VM_SWAP:0:5}" = /dev/ || cleanup_and_exit 3 +} + +vm_detach_root_openstack() { + cloud_volume_detach_openstack "$VM_SERVER" "$VM_VOLUME_NAME" +} + +vm_detach_swap_openstack() { + cloud_volume_detach_openstack "$VM_SERVER" "$VM_VOLUME_SWAP" +} + +vm_cleanup_openstack() { + cloud_volume_detach_openstack "$VM_SERVER" "$VM_VOLUME_NAME" + cloud_volume_detach_openstack "$VM_SERVER" "$VM_VOLUME_SWAP" +} + +vm_fixup_openstack() { + # No way to handle this via init= parameter here.... + echo "#!/bin/sh" > "$BUILD_ROOT/sbin/init" + echo 'exec /.build/build "$@"' >> "$BUILD_ROOT/sbin/init" + chmod 0755 "$BUILD_ROOT/sbin/init" +} + +vm_kill_openstack() { + if nova show "$VM_VOLUME_NAME" >/dev/null 2>&1 ; then + if ! nova delete "$VM_VOLUME_NAME" ; then + echo "could not kill openstack vm build $VM_VOLUME_NAME" + cleanup_and_exit 1 + fi + fi +} + +vm_startup_openstack() { + nova boot --image $OBS_OPENSTACK_KERNEL_IMAGE_ID --flavor m1.small --block_device_mapping vda=${VM_VOLUME_NAME}::$(( $VMDISK_ROOTSIZE / 1024 )):0 --block_device_mapping vdb=${VM_VOLUME_SWAP}::1:0 --poll "build-$VM_VOLUME_NAME" || cleanup_and_exit 3 + nova console-log "build-$VM_VOLUME_NAME" +} diff --git a/build-vm-qemu b/build-vm-qemu new file mode 100644 index 0000000..09e4250 --- /dev/null +++ b/build-vm-qemu @@ -0,0 +1,61 @@ +# +# qemu specific functions +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +# just forward everything to kvm... + +vm_verify_options_qemu() { + vm_verify_options_kvm +} + +vm_startup_qemu() { + vm_startup_kvm +} + +vm_kill_qemu() { + vm_kill_kvm +} + +vm_fixup_qemu() { + vm_setup_kvm +} + +vm_attach_root_qemu() { + vm_attach_root_kvm +} + +vm_attach_swap_qemu() { + vm_attach_swap_kvm +} + +vm_detach_root_qemu() { + vm_detach_root_kvm +} + +vm_detach_swap_qemu() { + vm_detach_swap_kvm +} + +vm_cleanup_qemu() { + vm_cleanup_kvm +} + diff --git a/build-vm-uml b/build-vm-uml new file mode 100644 index 0000000..4ca82e6 --- /dev/null +++ b/build-vm-uml @@ -0,0 +1,67 @@ +# +# UML specific functions +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +uml_kernel=/boot/vmlinux-um +uml_initrd=/boot/initrd-um + +vm_verify_options_uml() { + VM_SWAPDEV=/dev/sdb +} + +vm_startup_uml() { + set -- $uml_kernel initrd=$uml_initrd root=ubda init="$vm_init_script" panic=1 elevator=noop quiet ubda=$VM_IMAGE ubdb=$VM_SWAP ${VM_MEMSIZE:+mem=$VM_MEMSIZE} + echo "$@" + "$@" +} + +vm_kill_uml() { + if ! fuser -k -TERM "$VM_IMAGE"; then + echo "could not kill build in $VM_IMAGE" + cleanup_and_exit 1 + fi +} + +vm_fixup_uml() { + : +} + +vm_attach_root_uml() { + : +} + +vm_attach_swap_uml() { + : +} + +vm_detach_root_uml() { + : +} + +vm_detach_swap_uml() { + : +} + +vm_cleanup_uml() { + : +} + diff --git a/build-vm-xen b/build-vm-xen new file mode 100644 index 0000000..7366009 --- /dev/null +++ b/build-vm-xen @@ -0,0 +1,133 @@ +# +# XEN specific functions +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +vm_verify_options_xen() { + vm_kernel=/boot/vmlinuz + vm_initrd=/boot/initrd + test -e /boot/vmlinuz-xen && vm_kernel=/boot/vmlinuz-xen + test -e /boot/initrd-xen && vm_initrd=/boot/initrd-xen + test -n "$VM_KERNEL" && vm_kernel="$VM_KERNEL" + test -n "$VM_INITRD" && vm_initrd="$VM_INITRD" +} + +vm_startup_xen() { + XMCMD=xm + test ! -x /usr/sbin/xm -a -x /usr/sbin/xl && XMCMD=xl + XMROOT="file:$(readlink -f $VM_IMAGE)" + XMROOT=${XMROOT/#file:\/dev/phy:/dev} + XMROOT="disk=$XMROOT,hda1,w" + XMSWAP= + if test -n "$VM_SWAP" ; then + XMSWAP="file:$(readlink -f $VM_SWAP)" + XMSWAP=${XMSWAP/#file:\/dev/phy:/dev} + XMSWAP="disk=$XMSWAP,hda2,w" + fi + XENID="${VM_IMAGE%/root}" + XENID="${XENID%/tmpfs}" + XENID="${XENID##*/}" + XENID="${XENID#root_}" + + if $XMCMD list "build_$XENID" >/dev/null 2>&1 ; then + echo "Instance already exists, something really went wrong..." + echo "Please report to your server admin, there might be multiple services running for same domain" + cleanup_and_exit 3 + fi + XEN_CONF_FILE=`mktemp /var/tmp/build.xen.conf-XXXXXXXXX` || cleanup_and_exit 3 + + echo "kernel = \"$vm_kernel\"" > $XEN_CONF_FILE + echo "ramdisk = \"$vm_initrd\"" >> $XEN_CONF_FILE + echo "memory = ${VM_MEMSIZE:-64}" >> $XEN_CONF_FILE + test -n "$BUILD_JOBS" && echo "vcpus = $BUILD_JOBS" >> $XEN_CONF_FILE + echo "root = \"/dev/hda1 ro\"" >> $XEN_CONF_FILE + echo "extra = \"init=/bin/bash console=ttyS0 panic=1 udev_timeout=360\"" >> $XEN_CONF_FILE + echo "on_poweroff = \"destroy\"" >> $XEN_CONF_FILE + echo "on_reboot = \"destroy\"" >> $XEN_CONF_FILE + echo "on_crash = \"destroy\"" >> $XEN_CONF_FILE + if test "$XMCMD" = xm ; then + set -- xm create -c $XEN_CONF_FILE name="build_$XENID" $XMROOT $XMSWAP extra="panic=1 quiet init="$vm_init_script" rd.driver.pre=binfmt_misc elevator=noop console=ttyS0" + else + XLDISK= + XLDISK="\"${XMROOT#disk=}\"" + test -n "$XMSWAP" && XLDISK="$XLDISK, \"${XMSWAP#disk=}\"" + set -- xl create -c $XEN_CONF_FILE name="\"build_$XENID\"" "disk=[ $XLDISK ]" extra=\""panic=1 quiet init="$vm_init_script" rd.driver.pre=binfmt_misc elevator=noop console=ttyS0"\" + fi + if test "$PERSONALITY" != 0 ; then + # have to switch back to PER_LINUX to make xm work + set -- linux64 "$@" + fi + echo "$@" + "$@" || cleanup_and_exit 3 + rm -f "$XEN_CONF_FILE" +} + +vm_kill_xen() { + XMCMD=xm + test ! -x /usr/sbin/xm -a -x /usr/sbin/xl && XMCMD=xl + XENID="${VM_IMAGE%/root}" + XENID="${XENID%/tmpfs}" + XENID="${XENID##*/}" + XENID="${XENID#root_}" + if $XMCMD list "build_$XENID" >/dev/null 2>&1 ; then + if ! $XMCMD destroy "build_$XENID" ; then + echo "could not kill xen build $XENID" + cleanup_and_exit 1 + fi + fi +} + +# XEN only +vm_purge_xen() { + # this should not be needed, but sometimes a xen instance gets lost + XMCMD=xm + test ! -x /usr/sbin/xm -a -x /usr/sbin/xl && XMCMD=xl + XENID="${VM_IMAGE%/root}" + XENID="${XENID%/tmpfs}" + XENID="${XENID##*/}" + XENID="${XENID#root_}" + $XMCMD destroy "build_$XENID" >/dev/null 2>&1 +} + +vm_fixup_xen() { + : +} + +vm_attach_root_xen() { + : +} + +vm_attach_swap_xen() { + : +} + +vm_detach_root_xen() { + : +} + +vm_detach_swap_xen() { + : +} + +vm_cleanup_xen() { + : +} + diff --git a/build-vm-zvm b/build-vm-zvm new file mode 100644 index 0000000..c28442c --- /dev/null +++ b/build-vm-zvm @@ -0,0 +1,369 @@ +# +# z/VM specific functions +# +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +# z/VM: use default kernel image from local machine +# lets go with the default parameters. However zvm_initrd will be a required parameter +#zvm_kernel=/boot/image +#zvm_initrd=/boot/initrd_worker +zvm_param="root=/dev/disk/by-path/ccw-0.0.0150-part1 hvc_iucv=8 console=hvc0" +zvm_mult_pass="THR4ME" +zvm_init_script="/.build/build" + +####################################################################################### + +# this once was in zvm_functions + +zvm_fatal() { + echo "$1" + test -n "$ZVM_CLEANUP" && exit 1 + cleanup_and_exit 1 +} + +prevent_detach() { + if test "$1" = "150" -o "$1" = "0150"; then + zvm_fatal "don't detach local root" + fi +} + +zvm_memset() { + # defining the worker also resets the operating system. Be careful + # $1: user name + # $2: amount in MB + # Note, that this is also limited by the worker definition in the user directory + if test -n "$2"; then + if ! vmcp send $1 define storage ${2}M ; then + zvm_fatal "Could not redefine storage of $1 to ${2}M" + fi + fi +} + +zvm_logon() { + # kill machine if it already runs + # autolog machine + # Needs machine name as $1 + if test -n "$1" ; then + if $(vmcp q "$1" >& /dev/null) ; then + vmcp force $1 + sleep 1 + fi + if ! $(vmcp q "$1" >& /dev/null) ; then + if ! $(vmcp xautolog $1 >& /dev/null) ; then + zvm_fatal "Could not start machine $1. Is $1 defined in the user directory?" + else + # give the worker a moment to initialize + sleep 2 + zvm_memset $1 $VM_MEMSIZE + sleep 2 + fi + fi + fi +} + +zvm_ipl() { + # IPL worker. Needs user as $1 and ipl device as $2. + if test -n "$1" -a -n "$2" ; then + if ! $(vmcp q "$1" >& /dev/null); then + zvm_fatal "User $1 not logged on." + else + if ! $(vmcp send $1 ipl $2); then + zvm_fatal "Could not send command to $1" + fi + fi + else + zvm_fatal "Not enough arguments for ipl. Need user and device number." + fi +} + + +zvm_destroy() { + # Destroy build. Done by killing the worker machine. + # needs user as $1 + if test -n "$1"; then + if ! $(vmcp force $1 ) ; then + zvm_fatal "Could not force $1" + fi + fi +} + +zvm_get_local_devnr() { + # $1 is base address, either 150 or 250 + # $2 is worker number + # there is room for up to 100 workers for this controlling guest, however in our setup I expect only up to 10 workers. + #echo "Debug: zvm_get_local_devnr: arg1: $1 arg2: $2" + if test "$2" -ge 100 ; then + zvm_fatal "Not more than 100 workers supported by one controlling guest." + fi + if test "$1" = "0150" -o "$1" = "150" ; then + DEVNR=$((300+$2)) + else + if test "$1" = "0250" -o "$1" = "250" ; then + DEVNR=$((400+$2)) + else + zvm_fatal "The disk devices for root and swap must be 150 and 250 respectively." + fi + fi + echo $DEVNR +} + +zvm_volume_link_local() { + # attach worker disk to local system as preparation for + # a) prepare worker for build + # b) get rpms of the swap disk after build finished + # disk must be detached from worker first + # The following arguments are needed: + # 1. Worker user name + # 2. Worker disk device number + # 3. Mult password for the disk + # 4. Worker number to generate a uniq local device number + if test -n "$4"; then + DEVNR=$(zvm_get_local_devnr $2 $4) + if ! vmcp link $1 $2 $DEVNR MW pass=THR4ME >& /dev/null ; then + zvm_fatal "Could not link disk $2 from user $1 to local device $DEVNR." + fi + dasd_configure 0.0.0$DEVNR 1 0 >& /dev/null + udevadm settle + DEVICE=$(ls /sys/bus/ccw/devices/0.0.0$DEVNR/block/) + if ! test -b /dev/${DEVICE}1 ; then + zvm_fatal "The device /sys/bus/ccw/devices/0.0.0$DEVNR has not been setup correctly." + fi + echo "${DEVICE}1" + else + zvm_fatal "Not enough arguments given to volume_link_local." + fi +} + +zvm_volume_detach_local() { + # we need + # 1. worker device number + # 2. worker number + DEVNR=$(zvm_get_local_devnr $1 $2) + prevent_detach $DEVNR + dasd_configure 0.0.0$DEVNR 0 0 + if ! vmcp detach $DEVNR >& /dev/null ; then + zvm_fatal "Could not locally detach disk number $1 from worker $2" + fi +} + +zvm_volume_attach() { + # link the local disk of the worker + # $1: user name + # $2: disk device number + # send link * nr nr + if ! vmcp send $1 link \* $2 $2 ; then + zvm_fatal "Could not link remote worker disk number $2 from user $1" + fi +} + +zvm_volume_detach() { + # send machine detach nr + # $1: user name + # $2: disk + if ! vmcp send $1 detach $2 ; then + zvm_fatal "Could not detach disk $2 on worker $1" + fi +} + +zvm_worker_init() { + # 1. Worker user name + # 2. Worker root device number + # 3. Worker swap device number + # 4. Worker number to generate a uniq local device number + # Check for: + # - still mounted dasd + # - configured dasd + # - linked dasd + # - reset worker with force and autolog + DEVNR_ROOT=$(zvm_get_local_devnr $2 $4) + DEVNR_SWAP=$(zvm_get_local_devnr $3 $4) + # First, check for mounts: + for DEVNR in $DEVNR_ROOT $DEVNR_SWAP ; do + if test -d /sys/bus/ccw/devices/0.0.0$DEVNR/block ; then + DEV=$(ls /sys/bus/ccw/devices/0.0.0$DEVNR/block/) + echo "Found device of worker $1 available at $DEVNR, device is /dev/$DEV." + grep "/dev/$DEV" /proc/mounts >& /dev/null && umount /dev/${DEV}1 + fi + done + # Second, check if devices are online + for DEVNR in $DEVNR_ROOT $DEVNR_SWAP ; do + lsdasd $DEVNR | grep $DEVNR && dasd_configure 0.0.0$DEVNR 0 0 + done + # Third, remove stale links + for DEVNR in $DEVNR_ROOT $DEVNR_SWAP ; do + prevent_detach $DEVNR + if vmcp q v $DEVNR 2> /dev/null ; then + vmcp detach $DEVNR + fi + done + # Fourth, reset worker + zvm_logon $1 +} + +zvm_cp() { + modprobe vmcp || zvm_fatal "Cannod load vmcp module" + if test -n "$1" ; then + case "$1" in + start) shift ; zvm_logon "$@" ;; + ipl) shift ; zvm_ipl "$@" ;; + destroy) shift ; zvm_destroy "$@" ;; + volume_attach) shift ; zvm_volume_attach "$@" ;; + volume_detach) shift ; zvm_volume_detach "$@" ;; + volume_link_local) shift ; zvm_volume_link_local "$@" ;; + volume_detach_local) shift ; zvm_volume_detach_local "$@" ;; + memset) shift ; zvm_memset "$@" ;; + worker_init) shift ; zvm_worker_init "$@" ;; + esac + fi +} + +####################################################################################### + +vm_verify_options_zvm() { + VM_IMAGE=/dev/dasda1 + VM_SWAP=/dev/dasdb1 + + VM_SWAPDEV=/dev/dasdb1 # in the vm + + if test -z "$VM_VOLUME_ROOT" ; then + if test -n "$BUILD_ROOT" -a ${#BUILD_ROOT} -le 4 ; then + VM_VOLUME_ROOT="$BUILD_ROOT" + else + VM_VOLUME_ROOT="0150" + fi + fi + # In z/VM, this is a 4 digit hex number instead of a linux device. + # This is the swap disk defined in user direct + # This number can be given with the parameter --swap NR. + if test -z "$VM_VOLUME_SWAP" ; then + if test -n "$VM_SWAP" -a ${#VM_SWAP} -le 4 ; then + VM_VOLUME_SWAP="$VM_SWAP" + else + VM_VOLUME_SWAP="0250" + fi + fi + # z/VM guest name that is already defined in z/VM + if test -z "$VM_WORKER" ; then + echo "ERROR: No z/VM worker id specified" + cleanup_and_exit 3 + fi + if test -z "$VM_WORKER_NR" ; then + echo "ERROR: No z/VM worker number specified" + cleanup_and_exit 3 + fi + # need the name for a kernel in zvm + if test -n "$VM_KERNEL" ; then + vm_kernel="$VM_KERNEL" + elif test -e "/boot/vmlinux.gz" ; then + vm_kernel="/boot/vmlinux.gz" + else + echo "ERROR: No z/VM kernel specified" + cleanup_and_exit 3 + fi + # need the name for an initrd in zvm + # this normally will not be the local initrd + if test -n "$VM_INITRD" ; then + vm_initrd="$VM_INITRD" + else + echo "ERROR: No z/VM initrd specified" + cleanup_and_exit 3 + fi + zvm_cp worker_init $VM_WORKER $VM_VOLUME_ROOT $VM_VOLUME_SWAP $VM_WORKER_NR + zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT + zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP +} + +vm_startup_zvm() { + # link root/swap to the worker + zvm_cp volume_attach $VM_WORKER $VM_VOLUME_ROOT + zvm_cp volume_attach $VM_WORKER $VM_VOLUME_SWAP + zvm_cp ipl $VM_WORKER $VM_VOLUME_ROOT + # start IUCV Console + # IPL needs some time until IPL really starts... + sleep 2 + # start iucv console. This blocks until build process is finished. + iucvconn $VM_WORKER lnxhvc0 + # sleep some time before taking root and swap devices from worker + # This might be critical regarding timing (IUCV_CONSOLE down, but machine still running) + sleep 5 + zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT + zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP +} + +vm_kill_zvm() { + if vmcp q "$VM_WORKER" > /dev/null 2>&1 ; then + if ! zvm_cp destroy $VM_WORKER ; then + echo "could not kill zvm worker $VM_WORKER" + cleanup_and_exit 1 + fi + fi +} + +vm_fixup_zvm() { + # initrd is created in obsstoragesetup. + # If it is desired to use a project dependent kernel, use make_guestinitrd from zvm_functions. + # have to copy kernel/initrd and run zipl to be able to IPL + # have to set init_script before unmounting, thus doing it statically for now. + zvm_init_script="/.build/build" + mkdir -p $BUILD_ROOT/boot + cp $vm_kernel $vm_initrd $BUILD_ROOT/boot + mkdir -p $BUILD_ROOT/boot/zipl + # finally, install bootloader to the worker disk + zipl -t $BUILD_ROOT/boot/zipl -i ${BUILD_ROOT}${vm_kernel} -r ${BUILD_ROOT}${vm_initrd} \ + --parameters "${zvm_param} init=$zvm_init_script rootfsopts=noatime" +} + +vm_attach_root_zvm() { + VM_IMAGE=$(ZVM_CLEANUP=1 zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_ROOT $zvm_mult_pass $VM_WORKER_NR ) + if test "${VM_IMAGE}" = "${VM_IMAGE#dasd}" ; then + echo "did not get a real device for VM_IMAGE: $VM_IMAGE" + cleanup_and_exit 3 + fi + VM_IMAGE="/dev/$VM_IMAGE" +} + +vm_attach_swap_zvm() { + VM_SWAP=$(ZVM_CLEANUP=1 zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_SWAP $zvm_mult_pass $VM_WORKER_NR ) + if test "${VM_SWAP}" = "${VM_SWAP#dasd}" ; then + echo "did not get a real device for VM_SWAP: $VM_SWAP" + cleanup_and_exit 3 + fi + VM_SWAP="/dev/$VM_SWAP" +} + +vm_detach_root_zvm () { + zvm_cp volume_detach_local $VM_VOLUME_ROOT $VM_WORKER_NR +} + +vm_detach_swap_zvm() { + zvm_cp volume_detach_local $VM_VOLUME_SWAP $VM_WORKER_NR +} + +vm_cleanup_zvm() { + if test -n "$VM_WORKER" -a -n "$VM_WORKER_NR" -a -n "$VM_VOLUME_ROOT" -a -n "$VM_VOLUME_SWAP" ; then + ZVM_CLEANUP=1 + (zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT >/dev/null 2>&1) + (zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP >/dev/null 2>&1) + (zvm_cp volume_detach_local $VM_VOLUME_ROOT $VM_WORKER_NR >/dev/null 2>&1) + (zvm_cp volume_detach_local $VM_VOLUME_SWAP $VM_WORKER_NR >/dev/null 2>&1) + fi +} + @@ -10,13 +10,12 @@ build \- build SuSE Linux RPMs in a chroot environment .SH SYNOPSIS .B build .RB [ --clean | --no-init] -.RB [ --rpms -.IR path1 : path2 : ... ] -.RB [ --arch -.IR arch1 : arch2 : ... ] +.RB [ --repo +.IR dir_or_url ] +.RB [ --repo ...] .RB [ --root .IR buildroot ] -.RB [ specfile | srcrpm ] +.RB [ recipefile ] .br .B build .B --help @@ -24,67 +23,91 @@ build \- build SuSE Linux RPMs in a chroot environment .B build .B --verify .SH DESCRIPTION -\fBbuild\fR is a tool to build SuSE Linux RPMs in a safe and clean way. -.B build -will install a minimal SuSE Linux as build system into some directory -and will chroot to this system to compile the package. -This way you don't risk to corrupt your working system (due to a broken spec -file for example), even if the package does not use BuildRoot. - -.B build -searches the spec file for a -.I BuildRequires: -line; if such a line is found, all the specified rpms are installed. -Otherwise a selection of default packages are used. Note that -.B build -doesn't automatically resolve missing dependencies, so the specified -rpms have to be sufficient for the build. +\fBbuild\fR is a tool to build binary packages in a safe and reproducible +way. +The default is to build in a chroot sandbox, but \fBbuild\fP also supports +building in a virtual machine for better security. .P -If a spec file is specified on the command line, +If a recipe file is specified on the command line, .B build will use this file and all other files in the directory for building -the package. If a srcrpm is specified, -.B build -automatically unpacks it for the build. -If neither is given, +the package. If no recipe argument is provided, build will search the +current directory for a file. +.P +The .B build -will use all the specfiles in the current directory. +tool understands the following recipe file types: +.TP +.B spec +A specfile used to generate rpms. +.TP +.B src.rpm +A source rpm, which will be unpacked for the build. +.TP +.B kiwi +A kiwi config file used to generate a kiwi image. +.TP +.B dsc +A dsc file used to generate Debian binary packages. +.TP +.B PKGBUILD +A file used to generate Arch Linux binary packages. .P .SH OPTIONS .TP .B --clean -remove the build system and reinitialize it from scratch. +Remove the build system and reinitialize it from scratch. .TP .B --no-init -skip the build system initialization and start with build immediately. +Skip the build system initialization and start with build immediately. +.TP +.BI "\-\-repo " dir_or_url +Either a directory containing binary packages (optionally with repository +metadata), or a url pointing to some remote repository. Multiple +\fB--repo\fP options can be used so create a specific repository +layering. Note that packages are searched in the specified repository +order, i.e. the first repository containing a package with a specific +name wins regardless of the version. +As a special form, 'zypp://reponame' can be used to specify +a system repository. 'zypp://' selects all enabled system +repositories. This is also the default if BUILD_RPMS is not +set and no \fB--rpms\fP or \fB--repo\fP option is used. +.TP +.BI "\-\-dist " distribution +Set the distribution. If this option is not given, build tries to +guess the distribution by looking at the available packages. +The specified distribution can either be a string +like "11.2" or "sles9", "debian7", or the pathname of the build +configuration to use. +.TP +.BI "\-\-root " buildroot +Specifies where the build system is set up. Overrides the +BUILD_ROOT enviroment variable. +.TP +.B --help +Print a short help text. +.TP +.B --norootforbuild +Force building with user \fRabuild\fP. Otherwise, \fBbuild\fP searches +the recipe file for a "needsrootforbuild" hint to decide what user +to use. .TP .B --list-state -list rpms that would be used to create a fresh build root. +list packages that would be used to create a fresh build root. Does not create the build root or perform a build. .TP .BI "\-\-rpms " path1 : path2 : path3\fR...\fP -Where build can find the SuSE Linux RPMs needed to create the +Where build can find the packages needed to create the build system. This option overrides the BUILD_RPMS environment -variable. +variable. This option is deprecated, use \fB--repo\fP instead. .TP .BI "\-\-arch " arch1 : arch2 : arch3\fR...\fP What architectures to select from the RPMs. .B build automatically sets this to a sensible value for your host if you -don't specify this option. -.TP -.BI "\-\-repo " url_or_dir -Also use the specified repository to create the build system. -The repositories may be either of type rpmmd, yast2 (susetags), -or a simple directory. Multiple --repo options may be given. -As a special form, 'zypp://reponame' can be used to specify -a system repository. 'zypp://' selects all enabled system -repositories. This is also the default if BUILD_RPMS is not -set and no --rpms or --repo option is used. -.TP -.BI "\-\-root " buildroot -Specifies where the build system is set up. Overrides the -BUILD_ROOT enviroment variable. +do not specify this option so you should almost never need it. + +.SH RPM BUILD SPECIFIC OPTIONS .TP .B --useusedforbuild Tell build not to do dependency expansion, but to extract the @@ -93,27 +116,57 @@ are found, from all "BuildRequires" lines. This option is useful if you want to re-build a package from a srcrpm with exactly the same packages used for the srcrpm build. .TP -.B --norootforbuild - +.B --stage +Pass a stage option to rpmbuild. The default is \fB-ba\fP. .TP -.B --help -Print a short help text. +.B --target +Call rpmbuild with a target option. This can be used for cross building. .TP .B --verify -verify the files in an existing build system. +Verify the files in an existing build system. + +.SH VIRTUAL MACHINE SPECIFIC OPTIONS .TP -.BI "\-\--dist " distribution -Set the distribution. If this option is not given, build tries to -calculate the distribution by looking at the rpm package used in the -build. -The specified distribution can either be a string -like "11.2" or "sles9", or the pathname of the build configuration to -use. +.B "--xen --kvm --uml --qemu --emulator --zvm --lxc" +Sets a specific vm type. +.TP +.BI "--vm-type " type +As above. +.TP +.BI "--vm-disk " file +Specifies the location of the disk image to use. If this option is not +given, \fIbuildroot\fP\fB.img\fP is used (e.g. /var/tmp/build-root.img). +.TP +.BI "--vm-disk-size " size_in_mb +Specify the size of the disk image to create. +.TP +.BI "--vm-disk-filesystem " type +Sets the filesystem type to use when creating the disk image. The default +is to use the ext3 filesystem. +.TP +.BI "--vm-swap " file +Specifies the location of the swap file to use. If this option is not +given, \fIbuildroot\fP\fB.swap\fP is used (e.g. /var/tmp/build-root.swap). +.TP +.BI "--vm-swap-size " size_in_mb +Specify the size of the swap file to create. +.TP +.BI "--vm-memory " size_in_mb +Sets the desired memory size of the virtual machine. +.TP +.BI "--vm-kernel " kernel_file +Set a specific kernel to boot in the virtual machine. +.TP +.BI "--vm-initrd " initrd_file +Set a specific kernel to boot in the virtual machine. +.TP +.B --vm-disk-clean +Force the recreation of the disk image. -.SH .spec FILE OPTIONS +.SH RECIPE FILE OPTIONS The .B build -command interprets some special control comments in the specfile: +command interprets some special control comments in the recipe file: .TP .B # norootforbuild .TQ @@ -144,20 +197,19 @@ within the build root. .TP .B BUILD_ROOT The directory where build should install the chrooted build system. -"/var/tmp/build-root" is used by default. +"/var/tmp/build-root" is used by default. See the \fB--root\fP option. .TP .B BUILD_RPMS -Where build can find the SuSE Linux RPMs. build needs them to create the -build system. +This can be used instead of the \fB--rpms\fP option. Deprecated. .TP .B BUILD_RPM_BUILD_STAGE The rpm build stage (-ba, -bb, ...). This is just passed through to rpm, check the rpm manpage for a complete list and descriptions. -"-ba" is the default. -You can use this to add more options to RPM. +"-ba" is the default. You should probably use the \fB--stage\fP +option instead. .SH SEE ALSO -.BR rpm (8), +.BR rpm (8), dpkg (8), pacman (8), kiwi (8) .TP .BR "Maximum RPM": .I http://www.rpm.org/max-rpm/ diff --git a/changelog2spec b/changelog2spec index dceb7e5..d95ab85 100755 --- a/changelog2spec +++ b/changelog2spec @@ -4,6 +4,26 @@ # Convert a SUSE or Debian changelog file to rpm format # +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + BEGIN { unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build'); } @@ -49,6 +69,10 @@ if (@ARGV == 2 && $ARGV[0] eq '--file') { opendir(D, $dir) || die("$dir: $!\n"); my @changes = grep {/\.changes$/} readdir(D); closedir(D); + # support _service: prefixes, they need to be stripped + $file =~ s/^_service:.*://; + my %changes = map {/^((?:_service:.*:)?(.*?))$/ ? ($2, $1) : ($_, $_)} @changes; + @changes = keys %changes; @changes = sort {length($a) <=> length($b) || $a cmp $b} @changes; exit(1) unless @changes; # nothing to do if (@changes > 1) { @@ -61,7 +85,7 @@ if (@ARGV == 2 && $ARGV[0] eq '--file') { last unless $file =~ s/[-.][^-.]*$//; } } - @ARGV = ("$dir/$changes[0]"); + @ARGV = ("$dir/$changes{$changes[0]}"); } sub parse_suse { diff --git a/common_functions b/common_functions index a0e528f..2bfc988 100755 --- a/common_functions +++ b/common_functions @@ -1,22 +1,33 @@ #!/bin/bash -: ${CACHE_DIR:=/var/cache/build} +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ -build_host_arch() -{ +build_host_arch() { : ${BUILD_HOST_ARCH:=`uname -m`} + BUILD_INITVM_ARCH="$BUILD_HOST_ARCH" # avoid multiple initvm.* helpers for i586 and i686 - test i686 != "$BUILD_HOST_ARCH" || BUILD_HOST_ARCH=i586 + test i686 != "$BUILD_INITVM_ARCH" || BUILD_INITVM_ARCH=i586 } -set_build_arch() -{ - build_host_arch - - if [ -z "$BUILD_ARCH" ]; then - BUILD_ARCH="$BUILD_HOST_ARCH" - fi - +extend_build_arch() { case $BUILD_ARCH in armv7hl) BUILD_ARCH="armv7hl:armv7l:armv6hl:armv6l:armv5tel" ;; armv7l) BUILD_ARCH="armv7l:armv6l:armv5tel" ;; @@ -37,6 +48,14 @@ set_build_arch() sparc) BUILD_ARCH="sparc" ;; x86_64) BUILD_ARCH="x86_64:i686:i586:i486:i386" ;; esac +} + +set_build_arch() { + build_host_arch + if test -z "$BUILD_ARCH" ; then + BUILD_ARCH="$BUILD_HOST_ARCH" + fi + extend_build_arch if test "$BUILD_ARCH" != "${BUILD_ARCH#i686}" ; then cpuflags=`grep ^flags /proc/cpuinfo` cpuflags="$cpuflags " @@ -47,36 +66,39 @@ set_build_arch() fi } -check_exit() -{ +check_exit() { if test -e $BUILD_ROOT/exit; then echo "exit ..." cleanup_and_exit 1 fi } -check_use_emulator() -{ - arch=":$BUILD_ARCH:" - if test "$arch" != "${arch/:$BUILD_HOST_ARCH:/}"; then - # native supported arch, no emulator - return 1 +check_use_emulator() { + INITVM_NAME= + # check if the extended host arch contains the build arch + local old_build_arch="$BUILD_ARCH" + local arch="${BUILD_ARCH%%:*}" + BUILD_ARCH="$BUILD_HOST_ARCH" + extend_build_arch + BUILD_ARCH=":$BUILD_ARCH:" + if test "$BUILD_ARCH" != "${BUILD_ARCH/:$arch:/}" ; then + # native supported arch, no emulator + BUILD_ARCH="$old_build_arch" + return 1 fi + BUILD_ARCH="$old_build_arch" - # to run the qemu initialization in the XEN chroot, we need to + # to run the qemu initialization in the vm, we need to # register it with a static program or shell script - if test -e $BUILD_DIR/initvm.$BUILD_HOST_ARCH && \ - test -e $BUILD_DIR/qemu-reg; then - chmod 0755 "$BUILD_DIR/initvm.$BUILD_HOST_ARCH" - if [ -z "$PREPARE_VM" ]; then - return 0 # chroot build, we need to run - fi - # emulator in vm already registered during startup - else - # XXX: error? - echo "Warning: cross compile not possible due to missing static binaries. please install build-initvm package for that purpose." - echo " check that the right architecture is available for your build host, you need initvm.$BUILD_HOST_ARCH for this one." + INITVM_NAME="initvm.$BUILD_INITVM_ARCH" + if test -e "$BUILD_DIR/$INITVM_NAME" -a -e "$BUILD_DIR/qemu-reg" ; then + chmod 0755 "$BUILD_DIR/$INITVM_NAME" + return 0 # chroot build, we need to run fi + # XXX: error? + echo "Warning: cross compile not possible due to missing static binaries. please install build-initvm package for that purpose." + echo " check that the right architecture is available for your build host, you need $INITVM_NAME for this one." + INITVM_NAME= return 1 } diff --git a/computeblocklists b/computeblocklists index f9300d6..1370f50 100755 --- a/computeblocklists +++ b/computeblocklists @@ -10,12 +10,31 @@ # # a block is either a number or a range (start-end) # -# TODO: instead of printing zeroes for each block in a hole use -# something like 0*num + +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ use strict; -my ($opt_padstart, $opt_padend, $opt_verbose); +my ($opt_padstart, $opt_padend, $opt_verbose, $opt_manifest, $opt_mani0); +$opt_verbose = 0; while (@ARGV) { if ($ARGV[0] eq '--padstart') { @@ -30,71 +49,139 @@ while (@ARGV) { } if ($ARGV[0] eq '--verbose' || $ARGV[0] eq '-v') { shift @ARGV; - $opt_verbose = 1; + $opt_verbose++; + next; + } + if ($ARGV[0] eq '-0') { + shift @ARGV; + $opt_mani0 = 1; + next; + } + if ($ARGV[0] eq '--manifest') { + shift @ARGV; + $opt_manifest = shift @ARGV; next; } last; } -if($opt_padstart) { - print "\n"x$opt_padstart; +print "\n"x$opt_padstart if $opt_padstart; + +if ($opt_manifest) { + if ($opt_manifest eq '-') { + open(MANIFEST, '<&STDIN') || die("STDIN dup: $!\n"); + } else { + open(MANIFEST, '<', $opt_manifest) || die("$opt_manifest: $!\n"); + } } -for my $file (@ARGV) { - next unless -f $file; - print STDERR "$file\n" if $opt_verbose; +while (1) { + my $file; + if (@ARGV) { + $file = shift @ARGV; + } elsif ($opt_manifest) { + if ($opt_mani0) { + local $/ = "\0"; + $file = <MANIFEST>; + last unless defined $file; + $file =~ s/\0$//s; + } else { + $file = <MANIFEST>; + last unless defined $file; + chomp $file; + } + } else { + last; + } my $n = $file; - $n =~ s/.*\///; + $n =~ s/([\000-\037 %])/sprintf("%%%02X", ord($1))/ges; + if (-l $file) { + print STDERR "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//); + my $c = readlink($file); + die("$file: readlink: $!\n") unless defined $c; + if ("/$c/" =~ /\/\.?\//s) { + print STDERR "$file: bad symlink ($c) ignored\n"; + next; + } + if ("/$c/" =~ /^(\/\.\.)+\/(.*?)$/s) { + my ($head, $tail) = ($1, $2); + if (("/$tail/" =~ /\/\.\.\//s) || (($head =~ y!/!!) > ($file =~ y!/!!))) { + print STDERR "$file: bad symlink ($c) ignored\n"; + next; + } + } else { + if ("/$c/" =~ /\/\.\.\//s) { + print STDERR "$file: bad symlink ($c) ignored\n"; + next; + } + } + $c =~ s/([\000-\037 %])/sprintf("%%%02X", ord($1))/ges; + print "l $n $c\n"; + next; + } elsif (-d _) { + print STDERR "$file\n" if $opt_verbose && $opt_verbose > 1; + my @stat = stat(_); + print "d $n\n"; + next; + } elsif (!-f _) { + next; + } + print STDERR "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//); - if(!open(F, '<', $file)) { + if (!open(F, '<', $file)) { print STDERR "$file: $!"; next; } + my @stat = stat(F); + die unless @stat; + my $st_size = $stat[7]; + if ($st_size == 0) { + print "f $n 0\n"; + close F; + next; + } + my $bsize = 'xxxx'; ioctl(F, 2, $bsize) || ioctl(F, 536870914, $bsize) || die("FIGETBSZ: $!\n"); $bsize = unpack("L", $bsize); + die("$file: empty blocksize\n") unless $bsize != 0; - my @stat = stat(F); - my ($st_size, $st_blocks) = ($stat[7], $stat[11], $stat[12]); - + print "f $n $st_size $bsize"; my $blocks = int(($st_size+$bsize-1)/$bsize); - - print "$n $st_size $bsize "; - my ($firstblock, $lastblock); for ($b = 0; $b < $blocks; ++$b) { my $block = pack('I', $b); - if(not defined ioctl(F, 1, $block)) { - if(not defined ioctl(F, 536870913, $block)) { - die "$file: $!"; - } + if (not defined ioctl(F, 1, $block)) { + if (not defined ioctl(F, 536870913, $block)) { + die "$file: $!\n"; + } } $block = unpack('I', $block); - if($b == 0) { - print "$block"; - $firstblock = $block; - } else { - # blocks are non-contiguous - if($lastblock+1 != $block) { - # check if we skipped some that form a range - if($firstblock != $lastblock) { - printf "-$lastblock"; - } + if (!$firstblock && defined($firstblock)) { + # last block was hole + if (!$block) { + $lastblock++; # count holes, 0-2 means three hole blocks + } else { + # switch back from 'hole mode' into normal mode + printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock; print " $block"; - $firstblock = $block; - } - # last block, check if contiguous - if($b+1==$blocks && $lastblock+1 == $block) { - print "-$block"; + $firstblock = $lastblock = $block; } + next; + } + if (!$firstblock || $lastblock + 1 != $block) { + # start of a new run + printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock; + print " $block"; + $firstblock = $block; } $lastblock = $block; } + # finish last run + printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock; close F; print "\n"; } -if($opt_padend) { - print "\n"x$opt_padend; -} +print "\n"x$opt_padend if $opt_padend; diff --git a/configs/arch.conf b/configs/arch.conf index 466475e..05944fb 100644 --- a/configs/arch.conf +++ b/configs/arch.conf @@ -1,16 +1,25 @@ Repotype: arch Preinstall: glibc bash perl sed grep coreutils pacman pacman-mirrorlist -Preinstall: gawk gzip filesystem curl acl gpgme libarchive +Preinstall: gawk gzip filesystem curl libidn acl gpgme libarchive Preinstall: openssl libssh2 zlib libassuan libgpg-error attr -Preinstall: expat xz bzip2 +Preinstall: expat xz bzip2 readline lzo krb5 e2fsprogs keyutils +Preinstall: ncurses -VMinstall: util-linux binutils readline ncurses pcre libcap +VMinstall: util-linux libutil-linux binutils pcre libcap Required: binutils gcc glibc libtool Support: acl autoconf automake zlib bzip2 filesystem curl Support: libtool ncurses perl gpgme libarchive openssl libssh2 Support: libassuan libgpg-error attr expat xz pacman pacman-mirrorlist -Support: fakeroot file sudo patch make net-tools pkg-config +Support: fakeroot file sudo patch make net-tools pkg-config inetutils +Support: bison flex gettext which + +Prefer: zlib ttf-dejavu +Prefer: libgl jdk7-openjdk libdrm + +Prefer: -nvidia-libgl -nvidia-304xx-utils +Prefer: mesa-libgl +Prefer: curl:ca-certificates diff --git a/configs/sl13.2.conf b/configs/sl13.2.conf index 77cd7ae..37981f7 100644 --- a/configs/sl13.2.conf +++ b/configs/sl13.2.conf @@ -22,6 +22,7 @@ Conflict: kiwi:systemd-mini Conflict: libudev1:udev-mini FileProvides: /usr/sbin/groupadd pwdutils +FileProvides: /usr/sbin/useradd shadow FileProvides: /sbin/netconfig sysconfig-netconfig Preinstall: aaa_base attr bash coreutils diffutils @@ -37,14 +38,14 @@ Runscripts: aaa_base Order: libopenssl0_9_8:openssl-certs Prefer: libdb-4_8-devel -VMinstall: util-linux libmount1 perl-base libdb-4_8 libsepol1 libblkid1 libuuid1 net-tools +VMinstall: util-linux libmount1 perl-base libdb-4_8 libsepol1 libblkid1 libuuid1 net-tools +# kernel-obs-build - bnc#865554 ExportFilter: \.x86_64\.rpm$ x86_64 ExportFilter: \.ia64\.rpm$ ia64 ExportFilter: \.s390x\.rpm$ s390x ExportFilter: \.ppc64\.rpm$ ppc64 ExportFilter: \.ppc\.rpm$ ppc -ExportFilter: \.ppc64le\.rpm$ ppc64le ExportFilter: -ia32-.*\.rpm$ ExportFilter: -32bit-.*\.sparc64\.rpm$ ExportFilter: -64bit-.*\.sparcv9\.rpm$ @@ -55,7 +56,7 @@ ExportFilter: ^glibc(?:-devel)?-64bit-.*\.sparcv9\.rpm$ sparcv9 # it would be a great idea to have, but sometimes installation-images wants to build debuginfos in #ExportFilter: -debuginfo-.*\.rpm$ #ExportFilter: -debugsource-.*\.rpm$ -ExportFilter: ^master-boot-code.*\.i586.rpm$ . x86_64 +#ExportFilter: ^master-boot-code.*\.i586.rpm$ . x86_64 ExportFilter: ^acroread.*\.i586.rpm$ . x86_64 ExportFilter: ^avmailgate.*\.i586.rpm$ . x86_64 ExportFilter: ^avmailgate.*\.ppc.rpm$ . ppc64 @@ -134,7 +135,7 @@ Prefer: pkg-config gtk-doc wlan-kmp-default lua-libs lua-devel Prefer: gnu-jaf classpathx-mail avahi-compat-mDNSResponder yast2-control-center-qt Prefer: vim-normal myspell-american wine Prefer: eclipse-platform eclipse-scripts -Prefer: yast2-theme-openSUSE +Prefer: yast2-theme-openSUSE enlightenment-theme-upstream Prefer: amarok:amarok-xine Prefer: kdenetwork3-vnc:tightvnc Prefer: libgweather0 jessie ndesk-dbus ndesk-dbus-glib tomcat6-jsp-2_1-api tomcat6-servlet-2_5-api @@ -237,13 +238,14 @@ Prefer: typelib-1_0-Gst-0_10 gstreamer-0_10-utils-unversioned gstreamer-0_10-uti Prefer: libudev-mini-devel libudev-mini1 udev-debuginfo libudev1-debuginfo Prefer: systemd-mini systemd-mini-devel Prefer: systemd-mini-devel:systemd-mini -Prefer: udev-mini +Prefer: udev-mini libcom_err2-mini libext2fs2-mini Prefer: libudev1:udev Prefer: xmlgraphics-commons:apache-commons-io # the -32bit stuff provides things it shouldn't (hopefully temporary) Prefer: -typelib-1_0-GdkPixbuf-2_0-32bit -typelib-1_0-Pango-1_0-32bit Prefer: postgresql postgresql-server -Prefer: -unzip-rcc +Prefer: -unzip-rcc -linuxconsoletools + # kernel bug (coolo) Prefer: kernel-default-devel @@ -255,6 +257,7 @@ Prefer: -xerces-j2-xml-resolver -xerces-j2-xml-apis Prefer: -vmware-player Prefer: libgcc_s1 libgcc_s1-32bit libgcc_s1-64bit Prefer: libffi%{gcc_version} libffi%{gcc_version}-devel +Prefer: -libatomic1-gcc49 -libitm1-gcc49 -libgcj_bc1-gcc49 -libtsan0-gcc49 -libatomic1-gcc49-32bit -libitm1-gcc49-32bit Prefer: libgcc_s1-x86 libffi4 libgcj_bc1 Prefer: libffi4-32bit libffi4-64bit Prefer: libgomp1 libgomp1-32bit libgomp1-64bit @@ -304,8 +307,12 @@ Prefer: -kmod-compat Prefer: gettext-tools-mini gettext-runtime-mini # choice p11-kit-nss-trust Prefer: mozilla-nss-certs -# amarok dependency +# amarok dependency resolution Prefer: phonon-backend-gstreamer-0_10 +# replacing mkinitrd +Prefer: dracut +# Not sure if wicked is ready yet +Prefer: sysconfig-network Ignore: java-1_7_0-openjdk:mozilla-nss Ignore: java-1_7_0-openjdk:java-ca-certificates @@ -389,6 +396,7 @@ Ignore: mkinitrd:pciutils Ignore: pciutils:pciutils-ids Ignore: postfix:iproute2 Ignore: aaa_base:systemd +Ignore: gpm:systemd Ignore: ConsoleKit:systemd Ignore: openssh:systemd Ignore: cronie:systemd @@ -398,6 +406,8 @@ Ignore: systemd:dbus-1 Ignore: systemd:pam-config Ignore: systemd:udev Ignore: systemd-mini:this-is-only-for-build-envs +Ignore: udev-mini:this-is-only-for-build-envs +Ignore: libudev-mini1:this-is-only-for-build-envs Ignore: polkit:ConsoleKit Ignore: logrotate:cron Ignore: texlive-filesystem:cron @@ -428,6 +438,7 @@ Ignore: man:groff-full Ignore: git-core:rsync Ignore: apache2:systemd Ignore: icewm-lite:icewm +Ignore: cluster-glue:sudo Ignore: libgcc:glibc-32bit Ignore: libgcc41:glibc-32bit @@ -465,6 +476,7 @@ Ignore: libreoffice:libreoffice-i18n Ignore: libreoffice:libreoffice-icon-themes Ignore: mediawiki:php-session,php-gettext,php-zlib,php-mysql,mod_php_any Ignore: squirrelmail:mod_php_any,php-session,php-gettext,php-iconv,php-mbstring,php-openssl +Ignore: perl-Log-Log4perl:rrdtool Ignore: simias:mono(log4net) Ignore: zmd:mono(log4net) @@ -541,6 +553,7 @@ Ignore: NetworkManager:dhcp Ignore: sysconfig:dbus-1 Ignore: sysconfig:procps Ignore: sysconfig:iproute2 +Ignore: sysconfig-network:iproute2 Ignore: sysconfig:tunctl # no build dependencies Ignore: libksuseinstall1:yast2-packager @@ -553,17 +566,14 @@ Ignore: NetworkManager:dhcp-client Ignore: autoyast2:yast2-schema Ignore: libgio-2_0-0:dbus-1-x11 Ignore: weather-wallpaper:inkscape +Ignore: libgamin-1-0:gamin-server +Ignore: libfam0-gamin:gamin-server %ifarch %arm Prefer: java-1_7_0-icedtea java-1_7_0-icedtea-devel %else -%ifnarch s390 s390x Prefer: java-1_7_0-openjdk java-1_7_0-openjdk-devel %endif -%ifarch s390 s390x -Prefer: java-1_6_0-ibm java-1_6_0-ibm-devel -%endif -%endif Prefer: -java-1_5_0-gcj-compat-devel %ifarch %ix86 x86_64 @@ -612,62 +622,30 @@ Substitute: kernel-binary-packages kernel-default Substitute: yast2-theme-SLED Substitute: yast2-theme-SLE -Optflags: i586 -fomit-frame-pointer -fmessage-length=0 -grecord-gcc-switches -fstack-protector -Optflags: i686 -march=i686 -mtune=generic -fomit-frame-pointer -fmessage-length=0 -grecord-gcc-switches -fstack-protector -Optflags: x86_64 -fmessage-length=0 -grecord-gcc-switches -fstack-protector -Optflags: ppc -fmessage-length=0 -grecord-gcc-switches -fstack-protector -Optflags: ppc64 -fmessage-length=0 -grecord-gcc-switches -fstack-protector -Optflags: ia64 -fmessage-length=0 -grecord-gcc-switches -fstack-protector -Optflags: s390 -fmessage-length=0 -grecord-gcc-switches -fstack-protector -Optflags: s390x -fmessage-length=0 -grecord-gcc-switches -fstack-protector -Optflags: armv6l -fmessage-length=0 -grecord-gcc-switches -fstack-protector -Optflags: armv6hl -fmessage-length=0 -grecord-gcc-switches -fstack-protector -Optflags: armv7l -fmessage-length=0 -grecord-gcc-switches -fstack-protector -Optflags: armv7hl -fmessage-length=0 -grecord-gcc-switches -fstack-protector +Optflags: i586 -fomit-frame-pointer -fmessage-length=0 -grecord-gcc-switches +Optflags: i686 -march=i686 -mtune=generic -fomit-frame-pointer -fmessage-length=0 -grecord-gcc-switches +Optflags: x86_64 -fmessage-length=0 -grecord-gcc-switches +Optflags: ppc -fmessage-length=0 -grecord-gcc-switches +Optflags: ppc64 -fmessage-length=0 -grecord-gcc-switches +Optflags: ia64 -fmessage-length=0 -grecord-gcc-switches +Optflags: s390 -fmessage-length=0 -grecord-gcc-switches +Optflags: s390x -fmessage-length=0 -grecord-gcc-switches +Optflags: armv5el -fmessage-length=0 -grecord-gcc-switches +Optflags: armv5tel -fmessage-length=0 -grecord-gcc-switches +Optflags: armv7l -fmessage-length=0 -grecord-gcc-switches +Optflags: armv7hl -fmessage-length=0 -grecord-gcc-switches Optflags: aarch64 -fmessage-length=0 -grecord-gcc-switches # need mcpu=ultrasparc to complete sparcv8plus to sparcv9 (adds, for example, atomic ops) -Optflags: sparcv9 -fmessage-length=0 -grecord-gcc-switches -mcpu=ultrasparc -fstack-protector -Optflags: sparc64 -fmessage-length=0 -grecord-gcc-switches -mcpu=ultrasparc -fstack-protector +Optflags: sparcv9 -fmessage-length=0 -grecord-gcc-switches -mcpu=ultrasparc +Optflags: sparc64 -fmessage-length=0 -grecord-gcc-switches -mcpu=ultrasparc %ifarch sparcv9 Target: sparcv9 %endif -# Workaround buildservice bug (scheduler arch not matching target arch) -%ifarch armv7l armv7hl -Target: armv7hl-suse-linux -%endif -%ifarch armv6l armv6hl -Target: armv6hl-suse-linux -%endif -Optflags: * -O2 -Wall -D_FORTIFY_SOURCE=2 -funwind-tables -fasynchronous-unwind-tables +Optflags: * -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables %define suse_version 1320 -%ifarch aarch64 armv6l armv6hl -%define qemu_user_space_build 1 -%endif - -%if "%qemu_user_space_build" == "1" -Hostarch: x86_64 -Constraint: hostlabel QEMU_ARM - -Macros: -%qemu_user_space_build 1 -%_without_mono 1 -:Macros - -%ifarch armv6l armv6hl -Preinstall: qemu-linux-user -%endif - -%ifarch armv7l armv7hl -Preinstall: qemu-linux-user -%endif - -ExportFilter: ^qemu-linux-user.*\.x86_64\.rpm$ . armv7l armv6l -%endif - - Macros: %insserv_prereq insserv sed %fillup_prereq fillup coreutils grep diffutils diff --git a/configs/sles12.conf b/configs/sles12.conf new file mode 100644 index 0000000..931eaf1 --- /dev/null +++ b/configs/sles12.conf @@ -0,0 +1,668 @@ +%define gcc_version 48 + +Patterntype: rpm-md ymp + +Substitute: kiwi-packagemanager:instsource kiwi-instsource cdrkit-cdrtools-compat syslinux dosfstools kiwi-instsource-plugins-SLE-12 + +Conflict: kiwi:libudev-mini1 +Conflict: kiwi:systemd-mini +Conflict: libudev1:udev-mini +Conflict: udev:udev-mini +Conflict: sles-release:dummy-release + +FileProvides: /usr/sbin/groupadd pwdutils +FileProvides: /usr/sbin/useradd shadow +FileProvides: /sbin/netconfig sysconfig-netconfig +FileProvides: /usr/bin/docbook2man docbook-utils +FileProvides: /usr/bin/mkisofs cdrkit-cdrtools-compat +FileProvides: /usr/sbin/lockdev lockdev +FileProvides: /bin/logger util-linux-systemd + +Preinstall: aaa_base attr bash coreutils diffutils +Preinstall: filesystem fillup glibc grep +Preinstall: libbz2-1 libgcc_s1 m4 libncurses5 pam +Preinstall: permissions libreadline6 rpm sed tar libz1 libselinux1 +Preinstall: liblzma5 libcap2 libacl1 libattr1 +Preinstall: libpopt0 libelf1 liblua5_1 +Preinstall: libpcre1 libsmartcols1 + +Runscripts: aaa_base + +Order: libopenssl0_9_8:openssl-certs + +VMinstall: util-linux libmount1 perl-base libdb-4_8 libsepol1 libblkid1 libuuid1 net-tools +VMInstall: kernel-obs-build + +%ifarch aarch64 +Preinstall: qemu-linux-user +Runscripts: qemu-linux-user +Hostarch: x86_64 +Macros: +%qemu_user_space_build 1 +:Macros +%endif + +Required: rpm-build + +Support: pam-modules + +# the basic stuff +Support: perl build-mkbaselibs +Support: brp-check-suse post-build-checks rpmlint-Factory + +Prefer: libblkid1-mini libuuid1-mini libmount1-mini libsmartcols1-mini libdb-4_8-devel +Prefer: krb5-mini krb5-mini-devel +Conflict: krb5-devel:krb5-mini +Conflict: krb5:krb5-mini-devel +Prefer: libreadline5 +Prefer: libdb_java-4_8 libicu +Prefer: cracklib-dict-small postfix +Prefer: jta fam mozilla mozilla-nss +Prefer: unixODBC libsoup glitz +Prefer: gnome-panel desktop-data-SLE gnome2-SuSE +Prefer: mono-nunit gecko-sharp2 +Prefer: apache2-prefork Mesa openmotif-libs ghostscript-mini ghostscript +Prefer: gtk-sharp2 glib-sharp2 glade-sharp2 +Prefer: libzypp-zmd-backend novell-NLDAPsdk zaptel-kmp-default +Prefer: hbedv-dazuko-kmp-default dazuko-kmp-default vmware-wkstnmods-kmp-default +Prefer: virtualbox-kmp-default virtualbox-host-kmp-default +Prefer: libstdc++6 libgcc_s1 libquadmath0 +Prefer: libstdc++6-32bit libstdc++6-64bit +Prefer: libstdc++6-x86 +Prefer: libstdc++6-gcc%{gcc_version} libgcc_s1-gcc%{gcc_version} libgomp1-gcc%{gcc_version} +%ifarch s390x +Prefer: -libstdc++41 +%endif +Prefer: libstroke +Prefer: syslog-service syslogd +Prefer: gnome-sharp2:art-sharp2 gnome-sharp:art-sharp +Prefer: ifolder3:gnome-sharp2 ifolder3:gconf-sharp2 +Prefer: nautilus-ifolder3:gnome-sharp2 inkscape:gtkmm24 +Prefer: gconf-sharp2:glade-sharp2 gconf-sharp:glade-sharp +Prefer: gjdoc:antlr-bootstrap +Prefer: tomboy:gconf-sharp2 tomboy:gnome-sharp2 +Prefer: zmd:libzypp-zmd-backend +Prefer: yast2-packagemanager-devel:yast2-packagemanager +Prefer: glitz-32bit:Mesa-32bit +Prefer: poppler-tools +Prefer: libjpeg8-devel libjpeg-turbo +Prefer: banshee:banshee-engine-gst helix-banshee:helix-banshee-engine-gst +Prefer: banshee-1:banshee-1-client-classic +Prefer: libfam0 +Prefer: java-1_5_0-ibm:java-1_5_0-ibm-alsa +Prefer: java-1_5_0-ibm:java-1_5_0-ibm-fonts +Prefer: java-1_6_0-ibm:java-1_6_0-ibm-fonts +Prefer: microcode_ctl:kernel-default +Prefer: notification-daemon +Prefer: pkg-config gtk-doc wlan-kmp-default lua-libs lua-devel +Prefer: gnu-jaf classpathx-mail avahi-compat-mDNSResponder yast2-control-center-qt +Prefer: vim-normal myspell-american wine +Prefer: eclipse-platform eclipse-scripts +Prefer: yast2-theme-SLE +Prefer: amarok:amarok-xine +Prefer: kdenetwork3-vnc:tightvnc +Prefer: libgweather0 jessie ndesk-dbus ndesk-dbus-glib tomcat6-jsp-2_1-api tomcat6-servlet-2_5-api +Prefer: icewm-lite +Prefer: patterns-openSUSE-GNOME-cd:banshee +Prefer: yast2-ncurses-pkg +Prefer: monodevelop: mono-addins +Prefer: ant-trax:saxon +Prefer: gnome-session:gnome-session-branding-openSUSE +Prefer: gnome-session:gconf2-branding-openSUSE +Prefer: yast2-qt:yast2-qt-branding-openSUSE +Prefer: bundle-lang-gnome:gnome-session-branding-openSUSE +Prefer: fcitx:fcitx-branding-openSUSE +Prefer: xfce4-notifyd:xfce4-notifyd-branding-upstream +Prefer: exo-data:exo-branding-upstream +Prefer: xfce4-settings:xfce4-settings-branding-upstream +Prefer: xfdesktop:xfdesktop-branding-upstream +Prefer: texlive-xmltex texlive-tools texlive-jadetex +Prefer: mono-web:mono-data-sqlite +Prefer: gnome-games:gnuchess +Prefer: glchess:gnuchess +Prefer: libreoffice:libreoffice-branding-upstream +Prefer: yast2-branding-openSUSE +Prefer: gimp:gimp-branding-upstream +Prefer: libesd-devel:esound +Prefer: libesd0:esound-daemon +Prefer: package-lists-openSUSE-KDE-cd: esound-daemon +Prefer: glib2:glib2-branding-upstream +Prefer: libgio-2_0-0:gio-branding-upstream +Prefer: libglib-2_0-0:glib2-branding-upstream +Prefer: kdelibs4:kdelibs4-branding-upstream +Prefer: kdebase4-workspace:kdebase4-workspace-branding-upstream +Prefer: kdelibs4-branding:kdelibs4-branding-upstream +Prefer: PackageKit:PackageKit-branding-upstream +Prefer: lightdm-gtk-greeter:lightdm-gtk-greeter-branding-upstream +Prefer: mysql-connector-java:java-1_5_0-gcj-compat +Prefer: -geronimo-jta-1_0_1B-api -geronimo-jms-1_1-api -geronimo-el-1_0-api +Prefer: rhino:xmlbeans-mini +Prefer: ghostscript-devel:ghostscript-library +Prefer: gdm:gdm-branding-upstream +Prefer: rpcbind log4j-mini eclipse-source +Prefer: mx4j:log4j-mini +Prefer: podsleuth:sg3_utils +Prefer: libcdio_cdda0 libcdio_paranoia0 +Prefer: mozilla-xulrunner191 +Prefer: mozilla-xulrunner191-32bit +Prefer: boo tog-pegasus +Prefer: kde4-kupdateapplet:kde4-kupdateapplet-zypp +Prefer: kdebase4-workspace:kdebase4-workspace-ksysguardd +Prefer: ant:xerces-j2 +Prefer: dhcp-client:dhcp +Prefer: dummy-release +# provides typelib(St) +Prefer: -cinnamon +Prefer: -bundle-lang-kde-de -bundle-lang-kde-en -bundle-lang-kde-es +Prefer: -bundle-lang-kde-fr -bundle-lang-kde-pt -bundle-lang-kde-el +Prefer: -bundle-lang-kde-zh -bundle-lang-kde-ja -bundle-lang-kde-ru -bundle-lang-kde-pl +Prefer: -bundle-lang-kde-sv -bundle-lang-kde-ko -bundle-lang-kde-fi -bundle-lang-kde-da +Prefer: -bundle-lang-kde-cs -bundle-lang-kde-nl -bundle-lang-kde-hu -bundle-lang-kde-nb +Prefer: -bundle-lang-kde-it -bundle-lang-kde-ca -bundle-lang-kde-ar +Prefer: -bundle-lang-gnome-es -bundle-lang-gnome-de -bundle-lang-gnome-fr +Prefer: -bundle-lang-gnome-pt -bundle-lang-gnome-en -bundle-lang-gnome-el +Prefer: -bundle-lang-gnome-zh -bundle-lang-gnome-ja -bundle-lang-gnome-ru -bundle-lang-gnome-cs +Prefer: -bundle-lang-gnome-ko -bundle-lang-gnome-da -bundle-lang-gnome-nl -bundle-lang-gnome-hu +Prefer: -bundle-lang-gnome-pl -bundle-lang-gnome-fi -bundle-lang-gnome-nb -bundle-lang-gnome-sv +Prefer: -bundle-lang-gnome-it -bundle-lang-gnome-ca -bundle-lang-gnome-ar +Prefer: -bundle-lang-gnome-extras-es -bundle-lang-gnome-extras-de -bundle-lang-gnome-extras-fr +Prefer: -bundle-lang-gnome-extras-pt -bundle-lang-gnome-extras-en -bundle-lang-gnome-extras-el +Prefer: -bundle-lang-gnome-extras-zh -bundle-lang-gnome-extras-ja -bundle-lang-gnome-extras-ru -bundle-lang-gnome-extras-cs +Prefer: -bundle-lang-gnome-extras-ko -bundle-lang-gnome-extras-da -bundle-lang-gnome-extras-nl -bundle-lang-gnome-extras-hu +Prefer: -bundle-lang-gnome-extras-pl -bundle-lang-gnome-extras-fi -bundle-lang-gnome-extras-nb -bundle-lang-gnome-extras-sv +Prefer: -bundle-lang-gnome-extras-it -bundle-lang-gnome-extras-ca -bundle-lang-gnome-extras-ar +Prefer: -bundle-lang-common-es -bundle-lang-common-de -bundle-lang-common-fr +Prefer: -bundle-lang-common-pt -bundle-lang-common-en -bundle-lang-common-el +Prefer: -bundle-lang-common-ja -bundle-lang-common-zh -bundle-lang-common-cs -bundle-lang-common-ru +Prefer: -bundle-lang-common-nl -bundle-lang-common-hu -bundle-lang-common-pl -bundle-lang-common-da +Prefer: -bundle-lang-common-ko -bundle-lang-common-nb -bundle-lang-common-fi -bundle-lang-common-sv +Prefer: -bundle-lang-common-it -bundle-lang-common-ca -bundle-lang-common-ar +Prefer: -libgcc-mainline -libstdc++-mainline -gcc-mainline-c++ +Prefer: -libgcj-mainline -viewperf -compat -compat-openssl097g +Prefer: -zmd -libreoffice -pam-laus -libgcc-tree-ssa -busybox-links +Prefer: -python-setuptools +Prefer: -kdenetwork3-InstantMessenger +Prefer: -icc-profiles +Prefer: libsocialweb:libsocialweb-branding-upstream +Prefer: gnome-panel:gnome-panel-branding-upstream +Prefer: vala +Prefer: wallpaper-branding-SLE +Prefer: -crimson +Prefer: -rubygem-rack-1_1 -rubygem-rack-1_2 -rubygem-rack-1_3 -rubygem-tilt-1_1 -rubygem-rack-1_4 +Prefer: -rubygem-method_source-0_7 -rubygem-rails-2_3 -rubygem-activerecord-2_3 +Prefer: -rubygem-json_pure-1_5 +Prefer: geronimo-servlet-2_4-api +Prefer: -libhdf5-0-openmpi -libhdf5_hl0-openmpi -libhdf5_hl8-openmpi -libhdf5-8-openmpi +Prefer: typelib-1_0-Gst-0_10 gstreamer-0_10-utils-unversioned gstreamer-0_10-utils typelib-1_0-GstInterfaces-0_10 +# prefer the small systemd for building +Prefer: libudev-mini-devel libudev-mini1 udev-debuginfo libudev1-debuginfo +Prefer: systemd-mini systemd-mini-devel +Prefer: systemd-mini-devel:systemd-mini +Prefer: udev-mini libcom_err2-mini libext2fs2-mini +Prefer: libudev1:udev +Prefer: xmlgraphics-commons:apache-commons-io +# the -32bit stuff provides things it shouldn't (hopefully temporary) +Prefer: -typelib-1_0-GdkPixbuf-2_0-32bit -typelib-1_0-Pango-1_0-32bit +Prefer: postgresql postgresql-server +Prefer: -unzip-rcc + +Prefer: kernel-default-devel +Prefer: wxWidgets-2_9-devel + +Prefer: -NX -xaw3dd -db43 +Prefer: -xerces-j2-xml-resolver -xerces-j2-xml-apis +Prefer: -vmware-player +Prefer: libgcc_s1 libgcc_s1-32bit libgcc_s1-64bit +Prefer: libffi%{gcc_version} libffi%{gcc_version}-devel +Prefer: libgcc_s1-x86 libffi4 libgcj_bc1 +Prefer: libffi4-32bit libffi4-64bit +Prefer: libgomp1 libgomp1-32bit libgomp1-64bit +Prefer: libmudflap4 libmudflap4-32bit libmudflap4-64bit +Prefer: libobjc4 libgfortran3 libquadmath0 +Prefer: -libnetpbm -libcdio7-mini -libiso9660-5-mini -libiso9660-7-mini -libcdio10-mini -libcdio12-mini +Prefer: -libcdio-mini -faac-mini -libcdio-mini-devel +Prefer: -seamonkey +Prefer: -libdb-4_4-devel -libdb-4_5-devel -libevoldap-2_4-2 +Prefer: libopenal0-soft openal-soft -lsb-buildenv +Prefer: -libevent +Prefer: gnu-crypto libusb-compat-devel +Prefer: libusb-0_1-4 +Prefer: CASA_auth_token_svc:xerces-j2 +Prefer: libreoffice:xerces-j2 +Prefer: k3b:libdvdread4 +Prefer: glibc-devel +Prefer: -libpcap -libiniparser -loudmouth -libkonq4 -libnetcdf-4 -java-1_7_0-openjdk-javadoc -java-1_7_0-icedtea-javadoc +Prefer: -java-1_7_0-icedtea-devel +Prefer: NetworkManager:dhcp-client +Prefer: kdebase3-SuSE:kdebase3 +Prefer: kde4-kdm:kde4-kdm-branding-upstream +Prefer: kdm:kdm-branding-upstream +Prefer: pcre-tools +Prefer: libpopt0 +Prefer: -apache2-mod_perl -otrs -qa_apache_testsuite -ctcs2 +Prefer: libgnome-keyring-devel +Prefer: linux-glibc-devel +Prefer: squid sysvinit +Prefer: libpng16-compat-devel +Prefer: -python3 -python3-gobject-devel -python3-gobject2-devel -x11-video-fglrxG02 -libpng12-0 +Prefer: perl-Mail-SPF:perl-Error libldb0 -audit-libs mysql-community-server mysql-community-server-client +Prefer: xml-commons-resolver12 xml-commons-jaxp-1.3-apis +Prefer: xmlgraphics-fop:xerces-j2 +Prefer: libxfce4ui:libxfce4ui-branding-upstream +Prefer: libgarcon-1-0:libgarcon-branding-upstream +Prefer: libgarcon-data:libgarcon-branding-upstream +Prefer: libexo-1-0:libexo-1-0-branding-upstream +Prefer: gnome-shell:mozilla-js20 +Prefer: cogl-devel +Prefer: -perl-XML-SAX +Prefer: gettext-tools-mini gettext-runtime-mini +Prefer: mozilla-nss-certs +Prefer: phonon-backend-gstreamer-0_10 +Prefer: dracut +Prefer: kmod-compat + +Prefer: typelib-1_0-Wnck-3_0 +Prefer: -cups154-libs -cups154-client -cups154 + +Ignore: java-1_7_0-openjdk:mozilla-nss +Ignore: java-1_7_0-openjdk:java-ca-certificates +Ignore: openSUSE-release:openSUSE-release-ftp,openSUSE-release-dvd5,openSUSE-release-biarch,openSUSE-release-livecdkde,openSUSE-release-livecdgnome +Ignore: cracklib:cracklib-dict +Ignore: aaa_base:aaa_skel,suse-release,logrotate,ash,distribution-release,udev +Ignore: sysvinit:mingetty +Ignore: gettext-tools:libgcj,libstdc++-devel,libgcj41,libstdc++41-devel,libgcj42,libstdc++42-devel +Ignore: libgcj43,libstdc++43-devel +Ignore: libgcj44,libstdc++44-devel +Ignore: libgcj45,libstdc++45-devel +Ignore: libgcj46,libstdc++46-devel +Ignore: libgcj47,libstdc++47-devel +Ignore: pwdutils:openslp +Ignore: pam-modules:resmgr +Ignore: rpm:suse-build-key,build-key +Ignore: bind-utils:bind-libs +Ignore: alsa:dialog,pciutils +Ignore: portmap:syslogd +Ignore: xorg-x11:x11-tools,resmgr,xkeyboard-config,xorg-x11-Mesa,libusb,freetype2,libjpeg,libpng +Ignore: xorg-x11-server:xorg-x11-driver-input,xorg-x11-driver-video +Ignore: apache2:logrotate +Ignore: arts:alsa,audiofile,resmgr,libogg,libvorbis +Ignore: kdelibs3:alsa,arts,OpenEXR,aspell,cups-libs,mDNSResponder-lib,krb5,libjasper +Ignore: kdelibs3-devel:libvorbis-devel +Ignore: kdebase3:kdebase3-ksysguardd,OpenEXR,dbus-1,dbus-1-qt,hal,powersave,openslp,libusb +Ignore: kdebase3-SuSE:release-notes +Ignore: jack:alsa,libsndfile +Ignore: libxml2-devel:readline-devel +Ignore: gnome-vfs2:gnome-mime-data,desktop-file-utils,cdparanoia,dbus-1,dbus-1-glib,hal,libsmbclient,fam,file_alteration +Ignore: libgda:file_alteration +Ignore: gnutls:lzo,libopencdk +Ignore: gnutls-devel:lzo-devel,libopencdk-devel +Ignore: pango:cairo,glitz,libpixman,libpng +Ignore: pango-devel:cairo-devel +Ignore: cairo-devel:libpixman-devel +Ignore: libgnomeprint:libgnomecups +Ignore: libgnomeprintui:libgnomecups +Ignore: orbit2-devel:indent +Ignore: qt3:libmng +Ignore: qt-sql:qt_database_plugin +Ignore: gtk2:libpng,libtiff +Ignore: libgnomecanvas-devel:glib-devel +Ignore: libgnomeui:gnome-icon-theme,shared-mime-info +Ignore: scrollkeeper:docbook_4 +Ignore: gnome-desktop:libgnomesu,startup-notification +Ignore: python-devel:python-tk +Ignore: gnome-pilot:gnome-panel +Ignore: gnome-panel:control-center2 +Ignore: gnome-menus:kdebase3 +Ignore: gnome-main-menu:rug +Ignore: libbonoboui:gnome-desktop +Ignore: libxfce4ui-1-0:exo-tools +Ignore: docbook_4:iso_ent,xmlcharent +Ignore: control-center2:nautilus,evolution-data-server,gnome-menus,gstreamer-plugins,gstreamer,metacity,mozilla-nspr,mozilla,libxklavier,gnome-desktop,startup-notification +Ignore: docbook-xsl-stylesheets:xmlcharent +Ignore: liby2util-devel:libstdc++-devel,openssl-devel +Ignore: yast2:yast2-ncurses,yast2_theme,perl-Config-Crontab,yast2-xml,SuSEfirewall2 +Ignore: yast2-core:netcat,hwinfo,wireless-tools,sysfsutils +Ignore: yast2-core-devel:libxcrypt-devel,hwinfo-devel,blocxx-devel,sysfsutils,libstdc++-devel +Ignore: yast2-packagemanager-devel:rpm-devel,curl-devel,openssl-devel +Ignore: yast2-devtools:libxslt +Ignore: yast2-iscsi-lio-server:lio-utils +Ignore: yast2-installation:yast2-update,yast2-mouse,yast2-country,yast2-bootloader,yast2-packager,yast2-network,yast2-online-update,yast2-users,release-notes,autoyast2-installation +Ignore: yast2-bootloader:bootloader-theme +Ignore: yast2-packager:yast2-x11,libyui_pkg +Ignore: yui_backend +Ignore: yast2-x11:sax2-libsax-perl +Ignore: yast2-network:yast2-inetd +Ignore: openslp-devel:openssl-devel +Ignore: java-1_4_2-sun:xorg-x11-libs +Ignore: java-1_4_2-sun-devel:xorg-x11-libs +Ignore: tetex:xorg-x11-libs,expat,fontconfig,freetype2,libjpeg,ghostscript-x11,xaw3d,gd,dialog,ed +Ignore: texlive-bin:ghostscript-x11 +Ignore: texlive-bin-omega:ghostscript-x11 +Ignore: yast2-country:yast2-trans-stats +Ignore: tpb:tpctl-kmp +Ignore: tpctl:tpctl-kmp +Ignore: zaptel:zaptel-kmp +Ignore: mkinitrd:pciutils +Ignore: pciutils:pciutils-ids +Ignore: postfix:iproute2 +Ignore: aaa_base:systemd +Ignore: gpm:systemd +Ignore: ConsoleKit:systemd +Ignore: openssh:systemd +Ignore: cronie:systemd +Ignore: systemd:kbd +Ignore: systemd:kmod +Ignore: systemd:systemd-presets-branding +Ignore: systemd:dbus-1 +Ignore: systemd:pam-config +Ignore: systemd:udev +Ignore: pesign:systemd +Ignore: systemd-mini:this-is-only-for-build-envs +Ignore: udev-mini:this-is-only-for-build-envs +Ignore: libudev-mini1:this-is-only-for-build-envs +Ignore: polkit:ConsoleKit +Ignore: logrotate:cron +Ignore: texlive-filesystem:cron +Ignore: xinit:xterm +Ignore: xdm:xterm +Ignore: gnome-control-center:gnome-themes-accessibility +Ignore: coreutils:info +Ignore: cpio:info +Ignore: diffutils:info +Ignore: findutils:info +Ignore: gawk:info +Ignore: grep:info +Ignore: groff:info +Ignore: m4:info +Ignore: sed:info +Ignore: tar:info +Ignore: util-linux:info +Ignore: util-linux-mini:info +Ignore: gettext-tools:info +Ignore: gettext-runtime:info +Ignore: libgcrypt-devel:info +Ignore: binutils:info +Ignore: gzip:info +Ignore: make:info +Ignore: bison:info +Ignore: flex:info +Ignore: help2man:info +Ignore: man:groff-full +Ignore: git-core:rsync +Ignore: apache2:systemd +Ignore: icewm-lite:icewm +Ignore: cluster-glue:sudo + +Ignore: libgcc:glibc-32bit +Ignore: libgcc41:glibc-32bit +Ignore: libgcc42:glibc-32bit +Ignore: libgcc43:glibc-32bit +Ignore: libgcc44:glibc-32bit +Ignore: libgcc45:glibc-32bit +Ignore: libgcc46:glibc-32bit +Ignore: libgcc47:glibc-32bit +Ignore: libstdc++:glibc-32bit +Ignore: libstdc41++:glibc-32bit +Ignore: libstdc42++:glibc-32bit +Ignore: libstdc43++:glibc-32bit +Ignore: libstdc44++:glibc-32bit +Ignore: libstdc45++:glibc-32bit +Ignore: libstdc46++:glibc-32bit +Ignore: libstdc47++:glibc-32bit +Ignore: ncurses-32bit + +Ignore: susehelp:susehelp_lang,suse_help_viewer +Ignore: mailx:smtp_daemon +Ignore: cron:smtp_daemon +Ignore: hotplug:syslog +Ignore: pcmcia:syslog +Ignore: openct:syslog +Ignore: postfix:sysvinit(syslog) +Ignore: cups:sysvinit(syslog) +Ignore: avalon-logkit:servlet +Ignore: jython:servlet +Ignore: ispell:ispell_dictionary,ispell_english_dictionary +Ignore: aspell:aspel_dictionary,aspell_dictionary +Ignore: smartlink-softmodem:kernel,kernel-nongpl +Ignore: libreoffice-de:myspell-german-dictionary +Ignore: libreoffice:libreoffice-i18n +Ignore: libreoffice:libreoffice-icon-themes +Ignore: mediawiki:php-session,php-gettext,php-zlib,php-mysql,mod_php_any +Ignore: squirrelmail:mod_php_any,php-session,php-gettext,php-iconv,php-mbstring,php-openssl +Ignore: perl-Log-Log4perl:rrdtool + +Ignore: simias:mono(log4net) +Ignore: zmd:mono(log4net) +Ignore: horde:mod_php_any,php-gettext,php-mcrypt,php-imap,php-pear-log,php-pear,php-session,php + +Ignore: xerces-j2:xml-commons-apis,xml-commons-resolver +Ignore: xdg-menu:desktop-data +Ignore: nessus-libraries:nessus-core +Ignore: evolution:yelp +Ignore: e17:e17-branding e17:e17-theme + +Ignore: mono-tools:mono(gconf-sharp),mono(glade-sharp),mono(gnome-sharp),mono(gtkhtml-sharp),mono(atk-sharp),mono(gdk-sharp),mono(glib-sharp),mono(gtk-sharp),mono(pango-sharp) +Ignore: gecko-sharp2:mono(glib-sharp),mono(gtk-sharp) + +Ignore: vcdimager:libcdio.so.6,libcdio.so.6(CDIO_6),libiso9660.so.4,libiso9660.so.4(ISO9660_4) +Ignore: libcdio:libcddb.so.2 + +Ignore: gnome-libs:libgnomeui +Ignore: nautilus:gnome-themes +Ignore: gnome-panel:gnome-themes +Ignore: gnome-panel:tomboy +Ignore: NetworkManager:NetworkManager-client +Ignore: libbeagle:beagle +Ignore: coreutils:coreutils-lang +Ignore: cpio:cpio-lang +Ignore: glib2:glib2-lang +Ignore: gtk2:gtk2-lang +Ignore: gtk:gtk-lang +Ignore: atk:atk-lang +Ignore: hal:pm-utils +Ignore: MozillaThunderbird:pinentry-dialog +Ignore: seamonkey:pinentry-dialog +Ignore: pinentry:pinentry-dialog +Ignore: gpg2:gpg2-lang +Ignore: util-linux:util-linux-lang +Ignore: util-linux-mini:util-linux-mini-lang +Ignore: suseRegister:distribution-release +Ignore: compiz:compiz-decorator +Ignore: icecream:gcc-c++ +Ignore: no +Ignore: package +Ignore: provides +Ignore: j9vm/libjvm.so()(64bit) +Ignore: kdepim3:suse_help_viewer +Ignore: kdebase3-SuSE:kdebase3-SuSE-branding +Ignore: kio_sysinfo:kdebase3-SuSE-branding +Ignore: gnome-menus:gnome-menus-branding +Ignore: epiphany:epiphany-branding +Ignore: gnome-control-center:gnome-control-center-branding +Ignore: phonon:phonon-backend +Ignore: openwbem-devel +Ignore: MozillaFirefox:MozillaFirefox-branding +Ignore: yast2:yast2-branding +Ignore: plymouth:plymouth-branding +Ignore: plymouth:suspend +Ignore: yast2-qt:yast2-branding +Ignore: yast2-theme-SLE:yast2-branding +Ignore: yast2-registration:yast2-registration-branding +Ignore: compiz:compiz-branding +Ignore: texlive:perl-Tk texlive-bin:perl-Tk +Ignore: xfce4-desktop:xfce4-desktop-branding +Ignore: xfce4-panel:xfce4-panel-branding +Ignore: xfce4-session:xfce4-session-branding +Ignore: kdebase4-runtime:kdebase4-runtime-branding +Ignore: kwin:kdebase4-workspace-branding +Ignore: pulseaudio:kernel +Ignore: transmission-common:transmission-ui +Ignore: mutter-moblin:moblin-branding +Ignore: sysvinit-tools:mkinitrd cifs-utils:mkinitrd +Ignore: mkinitrd:sbin_init +Ignore: opensc:pinentry +Ignore: gpg2:pinentry +Ignore: NetworkManager:dhcp +Ignore: NetworkManager:iproute2 +Ignore: sysconfig:dbus-1 +Ignore: sysconfig:procps +Ignore: sysconfig:iproute2 +Ignore: sysconfig-network:iproute2 +Ignore: sysconfig:tunctl +# no build dependencies +Ignore: libksuseinstall1:yast2-packager +Ignore: libksuseinstall1:zypper +Ignore: syslog-service:logrotate +Ignore: libglue-devel:cluster-glue +Ignore: libqca2:gpg2 +Ignore: NetworkManager:wpa_supplicant +Ignore: NetworkManager:dhcp-client +Ignore: openSUSE-release:product_flavor(openSUSE) +Ignore: sles-release:product_flavor(SLES) +Ignore: autoyast2:yast2-schema +Ignore: libgio-2_0-0:dbus-1-x11 +Ignore: weather-wallpaper:inkscape +Ignore: libgamin-1-0:gamin-server +Ignore: libfam0-gamin:gamin-server +Ignore: avahi:sysvinit(network) +Ignore: sysconfig:sysvinit(network) + +Prefer: java-1_7_0-openjdk java-1_7_0-openjdk-devel + +Prefer: -java-1_5_0-gcj-compat-devel +Prefer: -java-1_6_0-ibm-devel +%ifarch %ix86 x86_64 +Prefer: -java-1_5_0-ibm-devel +%endif + +Substitute: java2-devel-packages java-1_7_0-openjdk-devel + +%ifarch x86_64 ppc64 s390x sparc64 +Substitute: glibc-devel-32bit glibc-devel-32bit glibc-32bit +%else + %ifarch ppc sparc sparcv9 +Substitute: glibc-devel-32bit glibc-devel-64bit + %else +Substitute: glibc-devel-32bit + %endif +%endif + +%ifarch %ix86 +Substitute: kernel-binary-packages kernel-default kernel-smp kernel-bigsmp kernel-debug kernel-xen +%endif +%ifarch ia64 +Substitute: kernel-binary-packages kernel-default kernel-debug +%endif +%ifarch x86_64 +Substitute: kernel-binary-packages kernel-default kernel-smp kernel-xen +%endif +%ifarch ppc +Substitute: kernel-binary-packages kernel-default kernel-ppc64 kernel-ps3 +%endif +%ifarch ppc64 +Substitute: kernel-binary-packages kernel-default kernel-ppc64 +%endif +%ifarch s390 +Substitute: kernel-binary-packages kernel-s390 +%endif +%ifarch s390x +Substitute: kernel-binary-packages kernel-default +%endif + +Optflags: i586 -fomit-frame-pointer -fmessage-length=0 -grecord-gcc-switches -fstack-protector +Optflags: i686 -march=i686 -mtune=generic -fomit-frame-pointer -fmessage-length=0 -grecord-gcc-switches -fstack-protector +Optflags: x86_64 -fmessage-length=0 -grecord-gcc-switches -fstack-protector +Optflags: ppc64le -fmessage-length=0 -grecord-gcc-switches -fstack-protector +Optflags: s390 -fmessage-length=0 -grecord-gcc-switches -fstack-protector +Optflags: s390x -fmessage-length=0 -grecord-gcc-switches -fstack-protector +Optflags: aarch64 -fmessage-length=0 -grecord-gcc-switches -fstack-protector + +Optflags: * -O2 -Wall -D_FORTIFY_SOURCE=2 -funwind-tables -fasynchronous-unwind-tables + +%define suse_version 1315 +%define _without_mono 1 +%define _without_vlc 1 +%define _without_compat_libs 1 + +%define rb_default_ruby ruby21 +%define rb_default_ruby_suffix ruby2.1 +%define rb_default_ruby_abi ruby:2.1.0 + +%define rb_build_ruby_abis ruby:2.1.0 +%define rb_build_versions ruby21 + +#Prefer: rubygem(%{rb_default_ruby_abi}:gem2rpm) +Prefer: %{rb_default_ruby_suffix}-rubygem-gem2rpm + +Macros: +%insserv_prereq insserv sed +%fillup_prereq fillup coreutils grep diffutils +%suseconfig_fonts_prereq perl aaa_base +%install_info_prereq info +%kernel_module_package_buildreq kmod-compat kernel-syms +%kernel_module_package_buildreqs kmod-compat kernel-syms +%maintenance_vendor SUSE LLC <https://www.suse.com/> +%maintenance_distribution SUSE Linux Enterprise 12 + +%suse_version 1315 +%sles_version 0 +%ul_version 0 +%do_profiling 1 +%opensuse_bs 1 +%_without_mono 1 +%_without_vlc 1 +%_without_compat_libs 1 +%rb_default_ruby ruby21 +%rb_default_ruby_suffix ruby2.1 +%rb_default_ruby_abi ruby:2.1.0 + +%rb_build_ruby_abis ruby:2.1.0 +%rb_build_versions ruby21 + +%rubygemsruby21() rubygem(ruby:2.1.0:%{expand:%%rubygemsx%*} %{expand:%%{rubygems%*}} +%rubygemsxruby21() %{expand:%%{rubygemsx%*}} +# +%rubygemsruby22() rubygem(ruby:2.2.0:%{expand:%%rubygemsx%*} %{expand:%%{rubygems%*}} +%rubygemsxruby22() %{expand:%%{rubygemsx%*}} +# +%rubygem() %{expand:%%{rubygems%rb_build_versions STOP %*}} +%rubygemsSTOP() %nil +%rubygemsxSTOP() %{expand:%%rubygemsxxSTOP -a %*} +%rubygemsxxSTOP(a:) %{-a*}) %* +# +%rubyruby21() ruby2.1 %{expand:%%rubyx%*} %{expand:%%{ruby%*}} +%rubyxruby21() %{expand:%%{rubyx%*}} +# +%rubyruby22() ruby2.2 %{expand:%%rubyx%*} %{expand:%%{ruby%*}} +%rubyxruby22() %{expand:%%{rubyx%*}} +# +%rubySTOP() %nil +%rubyxSTOP() %* +# +%ruby() %{expand:%%{ruby%rb_build_versions STOP %*}} +# +%rubydevelruby21() ruby2.1-devel %{expand:%%rubydevelx%*} %{expand:%%{rubydevel%*}} +%rubydevelxruby21() %{expand:%%{rubydevelx%*}} +# +%rubydevelruby22() ruby2.2-devel %{expand:%%rubydevelx%*} %{expand:%%{rubydevel%*}} +%rubydevelxruby22() %{expand:%%{rubydevelx%*}} +# +%rubydevel() %{expand:%%{rubydevel%rb_build_versions STOP %*}} +# +%rubydevelSTOP() %nil +%rubydevelxSTOP() %* + +%_vendor suse + +# define which gcc package builds the system libraries +%product_libs_gcc_ver 48 + +%ext_info .gz +%ext_man .gz + +%info_add(:-:) test -x /sbin/install-info -a -f %{?2}%{?!2:%{_infodir}}/%{1}%ext_info && /sbin/install-info --info-dir=%{?2}%{?!2:%{_infodir}} %{?2}%{?!2:%{_infodir}}/%{1}%ext_info \ +%{nil} + +%info_del(:-:) test -x /sbin/install-info -a ! -f %{?2}%{?!2:%{_infodir}}/%{1}%ext_info && /sbin/install-info --quiet --delete --info-dir=%{?2}%{?!2:%{_infodir}} %{?2}%{?!2:%{_infodir}}/%{1}%ext_info \ +%{nil} + diff --git a/createarchdeps b/createarchdeps index a97f762..aab8346 100755 --- a/createarchdeps +++ b/createarchdeps @@ -2,14 +2,34 @@ # Archlinux support, based on the GSoC work of Nikolay Rysev <mad.f3ka@gmail.com> +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + BEGIN { unshift @INC, ($::ENV{"BUILD_DIR"} || "/usr/lib/build"); } use strict; -use Archive::Tar; -use Build::Arch; -use Digest::MD5; +use Build ':arch'; +use Build::Archrepo; +use Digest::MD5 (); use File::Path; use Getopt::Long; @@ -17,56 +37,22 @@ Getopt::Long::Configure("no_ignore_case"); my $cachedir = "/var/cache/build"; -sub getrepodb { - my ($url, $reponame, $dir) = @_; - File::Path::mkpath($dir); - system($INC[0]."/download", $dir, "$url$reponame.db"); -} - sub getreponame { my ($url) = @_; return $1 if "/$url/" =~ /.*\/([^\/]+)\/os\//; return undef; } -sub printpkginfo { - my ($d, $repourl) = @_; - my $id = $d->{'name'} . "." . $d->{'arch'} . "-" . $d->{'buildtime'} . "/0/0"; - my $pkgurl = $repourl . $d->{'filename'}; - my $selfprovides = $d->{'name'}; - $selfprovides .= "=$d->{'version'}" if defined $d->{'version'}; - push @{$d->{'provides'}}, $selfprovides unless @{$d->{'provides'} || []} && $d->{'provides'}->[-1] eq $selfprovides; - print "F:$id: $pkgurl\n"; - print "P:$id: " . join(' ', @{$d->{'provides'}}) . "\n" if $d->{'provides'}; - print "R:$id: " . join(' ', @{$d->{'requires'}}) . "\n" if $d->{'requires'}; - print "I:$id: $d->{name}-$d->{'version'} $d->{'buildtime'}\n"; -} - GetOptions("cachedir=s" => \$cachedir) or exit(1); - for my $url (@ARGV) { - die("Not an Archlinux repo") unless $url =~ /^(ht|f)tp:\/\/([^\/]*)\/?/; + die("$url: not an remote Archlinux repo") unless $url =~ /^(:?ftps?|https?):\/\/([^\/]*)\/?/; my $reponame = getreponame($url); - my $repoid = Digest::MD5::md5_hex("arch\@$url"); + die("could not determine reponame from url $url\n") unless defined $reponame; + my $repoid = Digest::MD5::md5_hex($url); my $dir = "$cachedir/$repoid"; $url .= '/' unless $url =~ /\/$/; - getrepodb($url, $reponame, $dir); - - my $repodb = Archive::Tar->iter("$dir/$reponame.db", 1); - my $e; - my $lastfn = ''; - my $d; - while ($e = $repodb->()) { - next unless $e->type() == Archive::Tar::Constant::FILE; - my $fn = $e->name(); - next unless $fn =~ s/\/(?:depends|desc|files)$//s; - if ($lastfn ne $fn) { - printpkginfo($d, $url) if $d->{'name'}; - $d = {}; - $lastfn = $fn; - } - Build::Arch::parserepodata($d, $e->get_content()); - } - printpkginfo($d, $url) if $d->{'name'}; + File::Path::mkpath($dir); + system("$INC[0]/download", $dir, "$url$reponame.db"); + Build::Archrepo::parse("$dir/$reponame.db", sub { Build::writedeps(\*STDOUT, $_[0], $url) }, 'addselfprovides' => 1); } diff --git a/createdebdeps b/createdebdeps new file mode 100755 index 0000000..90207d8 --- /dev/null +++ b/createdebdeps @@ -0,0 +1,79 @@ +#!/usr/bin/perl -w + +BEGIN { + unshift @INC, ($::ENV{"BUILD_DIR"} || "/usr/lib/build"); +} + +use strict; +use Digest::MD5; +use File::Path; +use Getopt::Long; +use Build ':deb'; +use Build::Deb; +use Build::Debrepo; + +Getopt::Long::Configure("no_ignore_case"); + +# +# supported urls +# +# distribution: <baseurl>/<dist>/[components] +# flat repo: <baseurl>/. + +my $cachedir = "/var/cache/build"; +my $archpath; + +GetOptions('cachedir=s' => \$cachedir, 'archpath=s' => \$archpath) or exit(1); + +if (!$archpath) { + $archpath = `uname -p` || 'unknown'; + chomp $archpath; +} +my $basearch = $archpath; +$basearch =~ s/:.*//; +$basearch = Build::Deb::basearch($basearch); +my $pkgnum = 0; + +for my $url (@ARGV) { + die("$url: not an remote debian repo\n") unless $url =~ /^(:?ftps?|https?):\/\/([^\/]*)\/?/; + my $repoid = Digest::MD5::md5_hex($url); + my $dir = "$cachedir/$repoid"; + + my @components; + my $baseurl = $url; + + if ($url =~ /^(.*\/)\.(\/.*)?$/) { + # flat repo + $baseurl = $1; + @components = ('.'); + $url = defined($2) ? "$1$2" : $1; + $url .= '/' unless $url =~ /\/$/; + } else { + if ($url =~ /([^\/]+)$/) { + @components = split(/[,+]/, $1); + $url =~ s/([^\/]+)$//; + } + push @components, 'main' unless @components; + $url .= '/' unless $url =~ /\/$/; + $baseurl = $url; + $url =~ s/([^\/]+\/)$/dists\/$1/; + $baseurl =~ s/([^\/]+\/)$//; + } + + File::Path::mkpath($dir); + for my $component (@components) { + unlink("$dir/Packages.gz"); + if ($component eq '.') { + system($INC[0]."/download", $dir, "${url}Packages.gz"); + die("Packages.gz missing\n") unless -s "$dir/Packages.gz"; + } else { + system($INC[0]."/download", $dir, "$url$component/binary-$basearch/Packages.gz"); + die("Packages.gz missing for basearch $basearch, component $component\n") unless -s "$dir/Packages.gz"; + } + Build::Debrepo::parse("$dir/Packages.gz", sub { + $pkgnum++; + $_[0]->{'id'} = "$pkgnum/0/0"; + Build::writedeps(\*STDOUT, $_[0], $baseurl); + }, 'addselfprovides' => 1); + } +} diff --git a/createdirdeps b/createdirdeps new file mode 100755 index 0000000..e507004 --- /dev/null +++ b/createdirdeps @@ -0,0 +1,99 @@ +#!/usr/bin/perl -w + +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +BEGIN { + unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build'); +} + +use Build; +use Getopt::Long; + +use strict; + +Getopt::Long::Configure("no_ignore_case"); + +my $oldfile; + +GetOptions ("oldfile=s" => \$oldfile) or exit(1); + +sub queryfromfilename { + my ($fn) = @_; + $fn =~ s/.*\///; + return {'name' => $1, 'arch' => $2} if $fn =~ /^(.*)-[^-]+-[^-]+\.([^\. ]+)\.rpm$/; + return {'name' => $1, 'arch' => $2} if $fn =~ /^([^_]*)_(?:[^_]*)_([^_]*)\.deb$/; + return {'name' => $1, 'arch' => $2} if $fn =~ /^(.*)-[^-]+-[^-]+-([^-]+)\.pkg\.tar\.[gx]z$/; + return undef; +} + + +###################################################################### + +my %old; +if (defined($oldfile) && open(F, '<', $oldfile)) { + while (<F>) { + chomp; + $old{$1} = $_ if /^([PRCOI]:[^ ]+): /; + } + close F; +} + +my %seen; + +for my $dir (@ARGV) { + my $cmd = "find $dir -follow -type f \\( -name \"*.rpm\" -o -name \"*.deb\" -o -name \"*.pkg.tar.gz\" -o -name \"*.pkg.tar.xz\" \\) -a ! -name \"*src.rpm\" -printf '\%T@/\%s/\%i \%p\\n'"; + open(F, '-|', $cmd) or next; + while (<F>) { + chomp; + next unless /^([\d\.]+\/\d+\/\d+) (.*)$/; + my $id = $1; + my $path = $2; + # newer find version add a fraction part to %T@, strip it + $id =~ s/^(\d+)\.\d+/$1/; + next if $path =~ /\.(?:patch|delta)\.rpm$/; # not good for building... + if (%old) { + my $q = queryfromfilename($path); + if ($q && defined($q->{'name'}) && defined($q->{'arch'})) { + my $idx = "$q->{'name'}.$q->{'arch'}-$id"; + if ($old{"I:$idx"} && $old{"P:$idx"}) { + # reuse old data + next if $seen{$idx}; + $seen{$idx} = 1; + print "F:$idx: $path\n"; + for (qw{P R C O I}) { + print $old{"$_:$idx"}."\n" if $old{"$_:$idx"}; + } + next; + } + } + } + my $q = Build::query($path, 'addselfprovides' => 1, 'conflicts' => 1, 'evra' => 1, 'buildtime' => 1); + next unless $q && defined($q->{'name'}) && defined($q->{'arch'}) && defined($q->{'version'}); + my $idx = "$q->{'name'}.$q->{'arch'}-$id"; + next if $seen{$idx}; + $seen{$idx} = 1; + $q->{'id'} = $id; + $q->{'location'} = $path; + Build::writedeps(\*STDOUT, $q); + } + close F; +} + diff --git a/createrepomddeps b/createrepomddeps index 48a6b46..6f96434 100755 --- a/createrepomddeps +++ b/createrepomddeps @@ -1,449 +1,114 @@ #!/usr/bin/perl -w +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + BEGIN { unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build'); } use strict; -use XML::Parser; use Data::Dumper; use Getopt::Long; +use Build ':rpm'; use Build::Rpm; -use Digest::MD5 qw(md5 md5_hex md5_base64); +use Build::Rpmmd; +use Digest::MD5 (); use File::Path qw(mkpath rmtree); use File::Basename; -use LWP::UserAgent; -use URI; -Getopt::Long::Configure("no_ignore_case"); -my @parent = []; -my @primaryfiles = (); -my @packages = (); - -my $baseurl; # current url +Getopt::Long::Configure("no_ignore_case"); my $opt_dump; my $opt_old; my $opt_nosrc; my $opt_bc; +my $opt_zypp; my $cachedir = "/var/cache/build"; -my $old_seen = (); - -my $repomdparser = { - repomd => { - data => { - _start => \&repomd_handle_data_start, - _end => \&repomd_handle_data_end, - location => { - _start => \&repomd_handle_location, - }, - size => { - _text => \&repomd_handle_size, - }, - }, - }, -}; - -my $primaryparser = { - metadata => { - 'package' => { - _start => \&primary_handle_package_start, - _end => \&primary_handle_package_end, - name => { _text => \&primary_collect_text, _end => \&primary_store_text }, - arch => { _text => \&primary_collect_text, _end => \&primary_store_text }, - version => { _start => \&primary_handle_version }, - 'time' => { _start => \&primary_handle_time }, - format => { - 'rpm:provides' => { 'rpm:entry' => { _start => \&primary_handle_package_provides }, }, - 'rpm:requires' => { 'rpm:entry' => { _start => \&primary_handle_package_requires }, }, - 'rpm:conflicts' => { 'rpm:entry' => { _start => \&primary_handle_package_conflicts }, }, - 'rpm:obsoletes' => { 'rpm:entry' => { _start => \&primary_handle_package_obsoletes }, }, - 'rpm:buildhost' => { _text => \&primary_collect_text, _end => \&primary_store_text }, - 'rpm:sourcerpm' => { _text => \&primary_collect_text, _end => \&primary_store_text }, -### currently commented out, as we ignore file provides in createrpmdeps -# file => { -# _start => \&primary_handle_file_start, -# _text => \&primary_collect_text, -# _end => \&primary_handle_file_end -# }, - }, - location => { _start => \&primary_handle_package_location }, - }, - }, -}; - -# [ [tag, \%], ... ] -my @cursor = (); - -my %datafile; -sub repomd_handle_data_start -{ - my $p = shift; - my $el = shift; - - my $attr = map_attrs(@_); - %datafile = (); - if($attr->{'type'} ne 'primary') { - pop @cursor; - } -} - -sub repomd_handle_data_end -{ - my $p = shift; - my $el = shift; - push @primaryfiles, { %datafile } if exists $datafile{'location'}; -} - - -sub repomd_handle_location -{ - my $p = shift; - my $el = shift; - - my $attr = map_attrs(@_); - $datafile{'location'} = $attr->{'href'} if defined $attr->{'href'}; -} - -sub repomd_handle_size -{ - my $p = shift; - my $el = shift; - $datafile{'size'} = $el; -} - - -sub generic_handle_start -{ - my $p = shift; - my $el = shift; - - if(exists $cursor[-1]->[1]->{$el}) - { - my $h = $cursor[-1]->[1]->{$el}; - push @cursor, [$el, $h]; - if(exists $h->{'_start'}) { - &{$h->{'_start'}}($p, $el, @_); - } - } -} - -sub generic_handle_char -{ - my $p = shift; - my $text = shift; - - my $h = $cursor[-1]->[1]; - - if(exists $h->{'_text'}) { - &{$h->{'_text'}}($p, $text); - } -} - -sub generic_handle_end -{ - my $p = shift; - my $el = shift; - - if(!defined $cursor[-1]->[0] || $cursor[-1]->[0] eq $el) - { - my $h = $cursor[-1]->[1]; - - if(exists $h->{'_end'}) { - &{$h->{'_end'}}($p, $el); - } - - pop @cursor; - } -} - -sub map_attrs -{ - my %h; - while(@_) { - my $k = shift; - $h{$k} = shift; - } - - return \%h; -} - -# expat does not guarantee that character data doesn't get split up -# between multiple calls -my $textbuf = ''; -sub primary_collect_text -{ - my $p = shift; - my $text = shift; - - $textbuf .= $text; -} - -sub primary_store_text -{ - my $p = shift; - my $el = shift; - - $packages[-1]->{$cursor[-1]->[0]} = $textbuf; - $textbuf = ''; -} - -sub primary_handle_package_start -{ - my $p = shift; - my $el = shift; - - my $attr = map_attrs(@_); - - push @packages, { type => $attr->{'type'}, baseurl => $baseurl }; -} - -sub primary_handle_package_end -{ - my $p = shift; - my $el = shift; - - if($opt_bc) { - printasbuildcachefile(@packages); - shift @packages; - } elsif ($opt_old) { - foreach my $pkg (@packages) { - my $arch = $pkg->{'arch'}; - $arch = 'src' if $pkg->{'arch'} eq 'nosrc'; - next if ($arch eq 'src' && $opt_nosrc); - if(exists($old_seen->{$pkg->{'name'}}->{$arch})) { - my $pv = $old_seen->{$pkg->{'name'}}->{$arch}->{'ver'}; - my $rv = $pkg->{'ver'}.'-'.$pkg->{'rel'}; - my $vv = Build::Rpm::verscmp($pv, $rv, 0); - if($vv < 0) - { - print $old_seen->{$pkg->{'name'}}->{$arch}->{'loc'}."\n"; - $old_seen->{$pkg->{'name'}}->{$arch}->{'ver'} = $pkg->{'ver'}.'-'.$pkg->{'rel'}; - $old_seen->{$pkg->{'name'}}->{$arch}->{'loc'} = $pkg->{'baseurl'} . $pkg->{'location'}; - } else { - print $pkg->{'baseurl'} . $pkg->{'location'}."\n"; - } - } else { - $old_seen->{$pkg->{'name'}}->{$arch}->{'ver'} = $pkg->{'ver'}.'-'.$pkg->{'rel'}; - $old_seen->{$pkg->{'name'}}->{$arch}->{'loc'} = $pkg->{'baseurl'} . $pkg->{'location'}; - } - } - shift @packages; - } -} - -sub primary_handle_version -{ - my $p = shift; - my $el = shift; - - my $attr = map_attrs(@_); - $packages[-1]->{'ver'} = $attr->{'ver'}; - $packages[-1]->{'rel'} = $attr->{'rel'}; -} - -sub primary_handle_time -{ - my $p = shift; - my $el = shift; - - my $attr = map_attrs(@_); - $packages[-1]->{'filetime'} = $attr->{'file'}; - $packages[-1]->{'buildtime'} = $attr->{'build'}; -} - -sub primary_handle_package_location -{ - my $p = shift; - my $el = shift; - - my $attr = map_attrs(@_); - $packages[-1]->{'location'} = $attr->{'href'}; -} - -sub primary_handle_file_start -{ - my $p = shift; - my $el = shift; - - my $attr = map_attrs(@_); - if(exists $attr->{'type'}) { - pop @cursor; - } -} - -sub primary_handle_file_end -{ - my $p = shift; - my $text = shift; - - primary_handle_package_deps('provides', 'name', $textbuf); - $textbuf = ''; -} - -my %flagmap = ( - EQ => '=', - LE => '<=', - GE => '>=', - GT => '>', - LT => '<', - NE => '!=', -); - -sub primary_handle_package_deps -{ - my $dep = shift; - my $attr = map_attrs(@_); - - if(exists $attr->{'flags'}) { - if(!exists($flagmap{$attr->{'flags'}})) { - print STDERR "bogus relation: ", $attr->{'flags'}, "\n"; +sub printold { + my ($pkg, $baseurl, $old_seen) = @_; + + my $arch = $pkg->{'arch'}; + $arch = 'src' if $pkg->{'arch'} eq 'nosrc'; + return if $arch eq 'src' && $opt_nosrc; + my $evr = $pkg->{'version'}.'-'.$pkg->{'release'}; + $evr = "$pkg->{'epoch'}:$evr" if $pkg->{'epoch'}; + my $loc = $baseurl . $pkg->{'location'}; + if ($old_seen->{$pkg->{'name'}}->{$arch}) { + my $vv = Build::Rpm::verscmp($old_seen->{$pkg->{'name'}}->{$arch}->{'evr'}, $evr, 0); + if ($vv >= 0) { + print "$loc\n"; return; } - $attr->{'flags'} = $flagmap{$attr->{'flags'}}; - } - return if($attr->{'name'} =~ /^rpmlib\(/); - push @{$packages[-1]->{$dep}}, $attr; - -} - -sub primary_handle_package_conflicts -{ - shift;shift; primary_handle_package_deps('conflicts', @_); -} - -sub primary_handle_package_obsoletes -{ - shift;shift; primary_handle_package_deps('obsoletes', @_); -} - -sub primary_handle_package_requires -{ - shift;shift; primary_handle_package_deps('requires', @_); -} -sub primary_handle_package_provides -{ - shift;shift; primary_handle_package_deps('provides', @_); -} - -sub deps2string -{ - return join(' ', map { - my $s = $_->{'name'}; - if(exists $_->{'flags'}) { - $s .= ' '.$_->{'flags'}.' '; - $s .= $_->{'epoch'}.':' if(exists $_->{'epoch'} && $_->{'epoch'} != 0); - $s .= $_->{'ver'}; - $s .= '-'.$_->{'rel'} if exists $_->{'rel'}; - } - $s - } @_); -} - -sub printasbuildcachefile(@) -{ - foreach my $pkg (@_) { - next if $pkg->{'arch'} eq 'src' || $pkg->{'arch'} eq 'nosrc'; - my $id = sprintf("%s.%s-%d/%d/%d: ", - $pkg->{'name'}, - $pkg->{'arch'}, - $pkg->{'buildtime'}, - $pkg->{'filetime'}, - 0); - print "F:".$id. $pkg->{'baseurl'} . $pkg->{'location'} . "\n"; - - my $deps = deps2string(@{$pkg->{'provides'}}); - print "P:$id$deps\n"; - - $deps = deps2string(@{$pkg->{'requires'}}); - print "R:$id$deps\n"; - - my $tag = sprintf("%s-%s-%s %s", - $pkg->{'name'}, - $pkg->{'ver'}, - $pkg->{'rel'}, -# $pkg->{'rpm:buildhost'}, - $pkg->{'buildtime'}); - print "I:$id$tag\n"; + print $old_seen->{$pkg->{'name'}}->{$arch}->{'loc'}."\n"; } + $old_seen->{$pkg->{'name'}}->{$arch}->{'evr'} = $evr; + $old_seen->{$pkg->{'name'}}->{$arch}->{'loc'} = $loc; } -sub getmetadata -{ - my $url = $_[0]; - my $dir = $_[1]; - - my $dest = $dir . "repodata"; - mkpath($dest); - system($INC[0].'/download', $dest, $url . "repodata/repomd.xml"); -} - -### main - GetOptions ( - "nosrc" => \$opt_nosrc, - "dump" => \$opt_dump, - "old" => \$opt_old, - "cachedir=s" => \$cachedir, - ) or exit(1); + "nosrc" => \$opt_nosrc, + "dump" => \$opt_dump, + "old" => \$opt_old, + "zypp=s" => \$opt_zypp, + "cachedir=s" => \$cachedir, + ) or exit(1); -$opt_bc = 1 unless ($opt_dump || $opt_old); +$opt_bc = 1 unless $opt_dump || $opt_old; -my $p = new XML::Parser( - Handlers => { - Start => \&generic_handle_start, - End => \&generic_handle_end, - Char => \&generic_handle_char - }); +my $old_seen = {}; # for opt_old +my @packages; # for opt_dump -#my $url = '/mounts/mirror/SuSE/ftp.suse.com/pub/suse/update/10.1/'; for my $url (@ARGV) { my $dir; - if ($url =~ /^zypp:\/\/([^\/]*)\/?/) { - use Build::Zypp; - my $repo = Build::Zypp::parsecfg($1); - die "can't parse $1\n" unless $repo; - my $type = $repo->{'type'}; - if($type eq 'rpm-md') { - my $name = $repo->{'name'}; - $dir = "/var/cache/zypp/raw/$name/"; - $baseurl = $url; - $baseurl .= '/' unless $baseurl =~ /\/$/; - } elsif ($type eq 'yast2') { - # XXX - exec ($INC[0].'/createyastdeps', $url); - } else { - die "unsupported repo type: $type\n"; - } - } elsif ($url =~ /^http[s]?:\/\/([^\/]*)\/?/) { - my $repoid = md5_hex($url); + my $baseurl = $url; + if ($opt_zypp) { + $dir = $opt_zypp; + } elsif ($url =~ /^(?:ftps?|https?):\/\/([^\/]*)\/?/) { + my $repoid = Digest::MD5::md5_hex($url); $dir = "$cachedir/$repoid/"; - $baseurl = $url; $baseurl .= '/' unless $baseurl =~ /\/$/; - getmetadata($baseurl, $dir); - } elsif ($url =~ /^arch\@/) { - exec ("$INC[0]/createarchdeps", "--cachedir=$cachedir", substr($url, 5)); + mkpath("${dir}repodata"); + system($INC[0].'/download', "${dir}repodata", "${baseurl}repodata/repomd.xml"); } else { $dir = $url; - $dir .= '/' unless $dir =~ /\/$/; - $baseurl = $dir; } + $dir .= '/' unless $dir =~ /\/$/; + $baseurl .= '/' unless $baseurl =~ /\/$/; - @primaryfiles = (); - @cursor = ([undef, $repomdparser]); - - $p->parsefile($dir . 'repodata/repomd.xml'); + if (! -s "${dir}repodata/repomd.xml") { + die("zypp repo $url is not up to date, please refresh first\n") if $opt_zypp; + die("repo $url does not contain a repomd.xml file\n"); + } + my @primaryfiles; + Build::Rpmmd::parse_repomd("${dir}repodata/repomd.xml", \@primaryfiles); + @primaryfiles = grep {$_->{'type'} eq 'primary' && defined($_->{'location'})} @primaryfiles; # print Dumper(\@primaryfiles); - foreach my $f (@primaryfiles) { - @cursor = ([undef, $primaryparser]); - - my $u = $dir . $f->{'location'}; + for my $f (@primaryfiles) { + my $u = "$dir$f->{'location'}"; if ($] > 5.007) { - require Encode; - utf8::downgrade($u); + require Encode; + utf8::downgrade($u); } my $cached; if (-e $u) { @@ -451,45 +116,38 @@ for my $url (@ARGV) { $cached = 0 if exists($f->{'size'}) && $f->{'size'} != (-s _); $cached = 0 if !exists($f->{'size'}) && $u !~ /[0-9a-f]{32}-primary/; } - if ($url =~ /^http[s]?:\/\/([^\/]*)\/?/ and !$cached) { - if (system($INC[0].'/download', $dir . "repodata/", $baseurl . "repodata/" . basename($u))) { + if (!$cached) { + die("zypp repo $url is not up to date, please refresh first\n") if $opt_zypp; + if ($url =~ /^(?:ftps?|https?):\/\/([^\/]*)\/?/) { + if (system("$INC[0]/download", "${dir}repodata/", "${baseurl}repodata/" . basename($u))) { die("download failed\n"); } + } else { + die("inconsistent repodata in $url\n"); + } } my $fh; open($fh, '<', $u) or die "Error opening $u: $!\n"; if ($u =~ /\.gz$/) { - use IO::Uncompress::Gunzip qw($GunzipError); - $fh = new IO::Uncompress::Gunzip $fh or die "Error opening $u: $GunzipError\n"; + use IO::Uncompress::Gunzip qw($GunzipError); + $fh = new IO::Uncompress::Gunzip $fh or die "Error opening $u: $GunzipError\n"; } - $p->parse($fh); + Build::Rpmmd::parse($fh, sub { + if ($opt_dump) { + $_[0]->{'baseurl'} = $baseurl; + push @packages, $_[0] if $opt_dump; + } + if ($opt_bc) { + Build::writedeps(\*STDOUT, $_[0], $baseurl); + } elsif ($opt_old) { + printold($_[0], $baseurl, $old_seen); + } + }, 'addselfprovides' => 1); close($fh); } } if ($opt_dump) { - print Data::Dumper->Dump([\@packages], ['packages']); # caution: excessive memory consumption! + print Data::Dumper->Dump([\@packages], ['packages']); # caution: excessive memory consumption! } -#if($rpmdepdump) { -# my %amap = map { $_ => 1 } @archs; -# my $packages = do $rpmdepdump or die $!; -# -# foreach my $pkg (@$packages) { -# next if exists $packs{$pkg->{'name'}}; -# next unless exists $amap{$pkg->{'arch'}}; -# next if $pkg->{'arch'} eq 'src' || $pkg->{'arch'} eq 'nosrc'; -# next if $pkg->{'location'} =~ /\.(?:patch|delta)\.rpm$/; -# -# my $pa = $pkg->{'name'}.'.'.$pkg->{'arch'}; -# $packs{$pkg->{'name'}} = $pa; -# $fn{$pa} = $pkg->{'baseurl'}.$pkg->{'location'}; -# my $r = {}; -# # flags and version ignored -# my @pr = map { $_->{'name'} } @{$pkg->{'provides'}}; -# my @re = map { $_->{'name'} } @{$pkg->{'requires'}}; -# $r->{'provides'} = \@pr; -# $r->{'requires'} = \@re; -# $repo{$pkg->{'name'}} = $r; -# } -#} diff --git a/createyastdeps b/createyastdeps index a17bd74..b5fb603 100755 --- a/createyastdeps +++ b/createyastdeps @@ -1,104 +1,73 @@ #!/usr/bin/perl -w +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + BEGIN { unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build'); } -use Build; +use Build ':rpm'; use Build::Susetags; -use strict; +use Getopt::Long; +use File::Path qw(mkpath); -sub print_pkg($) -{ - my $pkg = shift; +use strict; - return if $pkg->{'arch'} eq 'src' || $pkg->{'arch'} eq 'nosrc'; - my $id = sprintf("%s.%s-%d/%d/%d: ", - $pkg->{'name'}, - $pkg->{'arch'}, - $pkg->{'buildtime'}, - 0, - 0); - print sprintf('F:%s%ssuse/%s/%s',$id,$pkg->{'baseurl'}, - $pkg->{'arch'}, $pkg->{'location'}), "\n"; +Getopt::Long::Configure("no_ignore_case"); - print "P:$id".$pkg->{'provides'}."\n"; - print "R:$id".$pkg->{'requires'}."\n"; +my $opt_zypp; +my $cachedir = "/var/cache/build"; - my $tag = sprintf("%s-%s-%s %s", - $pkg->{'name'}, - $pkg->{'version'}, - $pkg->{'release'}, -# $pkg->{'rpm:buildhost'}, - $pkg->{'buildtime'}); - print "I:$id$tag\n"; -} - -sub callback -{ - my ($pkg, $url) = @_; - $pkg->{'provides'} = [] unless exists $pkg->{'provides'}; - # add self provides (rpm3 misses that) - my $n = $pkg->{'name'}; - if(substr($pkg->{'arch'}, -3) ne 'src' && !scalar grep(/^\Q$n\E( =.*)?$/,@{$pkg->{'provides'}})) - { - push @{$pkg->{'provides'}}, sprintf("%s = %s-%s", $pkg->{'name'}, $pkg->{'version'}, $pkg->{'release'}); - } - $pkg->{'provides'} = join(' ', @{$pkg->{'provides'}}); - $pkg->{'requires'} = join(' ', @{$pkg->{'requires'}}) if $pkg->{'requires'}; - $pkg->{'baseurl'} = $url; - my @data = split(' ', $pkg->{'location'}); - # multi cd support hack - my $num = $data[0]; - if($pkg->{'baseurl'} =~ /1\/$/ && $num ne 0) { - $pkg->{'baseurl'} =~ s/1\/$/$num\//; - } - $pkg->{'location'} = $data[1]; - - print_pkg($pkg); - - return 0; -} +GetOptions ("zypp=s" => \$opt_zypp, "cachedir=s" => \$cachedir) or exit(1); for my $url (@ARGV) { + # XXX: use descrdir/datadir from content file + my $descrdir = 'suse/setup/descr'; + my $datadir = 'suse'; + my $dir; - if ($url =~ /^zypp:\/\/([^\/]*)\/?/) { - use Build::Zypp; - my $repo = Build::Zypp::parsecfg($1); - die "can't parse $1\n" unless $repo; - die "only yast2 repos supported\n" unless $repo->{'type'} eq 'yast2'; - my $name = $repo->{'name'}; - $dir = "/var/cache/zypp/raw/$name/"; + my $baseurl = $url; + if ($opt_zypp) { + $dir = $opt_zypp; + } elsif ($url =~ /^(?:ftps?|https?):\/\/([^\/]*)\/?/) { + my $repoid = Digest::MD5::md5_hex($url); + $dir = "$cachedir/$repoid/"; + $baseurl .= '/' unless $baseurl =~ /\/$/; + mkpath($dir); + system("$INC[0]/download", "$dir/", "${baseurl}$descrdir/packages.gz"); + $descrdir = '.'; } else { $dir = $url; } + $dir .= '/' unless $dir =~ /\/$/; + $baseurl .= '/' unless $baseurl =~ /\/$/; -# a really fucked up system -# if (-e $url."/yast/order") { -# if(open(F, '<', $url."/yast/order")) { -# my $found_products; -# while(<F>) { -# chomp; -# my ($a, $b) = split(/ /); -# $a =~ s/^\///; -# if(-e $url.$a) -# { -# push @ARGV, $url.$a; -# $found_products = 1; -# print STDERR "$url -> $url$a\n"; -# } -# } -# close(F); -# next if $found_products; -# } -# } - # XXX: location is actually defined in content file - my $packages = $dir.'/suse/setup/descr/packages'; - - $url .= '/' unless $url =~ /\/$/; - - my @order = (); - my $pkgs = Build::Susetags::parse($packages, - { 'Loc' => 'location', 'Prv' => 'provides', 'Req' => 'requires', 'Tim' => 'buildtime' }, - { cb => \&callback, data => $url }); + my $packages = "$dir$descrdir/packages"; + $packages = "$packages.gz" if ! -e $packages && -e "$packages.gz"; + Build::Susetags::parse($packages, sub { + my $xurl = $baseurl; + # multi cd support hack + $xurl =~ s/1\/$/$_[0]->{'medium'}/ if $_[0]->{'medium'}; + $xurl .= "$datadir/" if $datadir; + Build::writedeps(\*STDOUT, $_[0], $xurl); + }, 'addselfprovides' => 1); } + diff --git a/createzyppdeps b/createzyppdeps new file mode 100755 index 0000000..8d85e49 --- /dev/null +++ b/createzyppdeps @@ -0,0 +1,64 @@ +#!/usr/bin/perl -w + +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +BEGIN { + unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build'); +} + +use strict; + +use Build::Zypp; +use Getopt::Long; + +Getopt::Long::Configure("no_ignore_case"); + +my $cachedir = "/var/cache/build"; +my $opt_listrepos; + +GetOptions( + "cachedir=s" => \$cachedir, + "listrepos" => \$opt_listrepos, + ) or exit(1); + +if ($opt_listrepos) { + die("createzyppdeps --listrepos does not take an argument\n") if @ARGV; + for my $r (Build::Zypp::parseallrepos()) { + print "$r->{'name'}\n" if $r->{'enabled'}; + } + exit 0; +} +die("createzyppdeps needs exactly one argument\n") if @ARGV != 1; +my $url = $ARGV[0]; + +die("createzyppdeps argument must start with 'zypp://'\n") unless $url =~ /^zypp:\/\/([^\/]*)/; +my $repo = Build::Zypp::parserepo($1); + +my $type = $repo->{'type'}; +my $zyppcachedir = "/var/cache/zypp/raw/$repo->{'name'}"; + +if($type eq 'rpm-md') { + exec ("$INC[0]/createrepomddeps", '--cachedir', $cachedir, '--zypp', $zyppcachedir, $url); +} elsif ($type eq 'yast2') { + exec ("$INC[0]/createyastdeps", '--cachedir', $cachedir, '--zypp', $zyppcachedir, $url); +} else { + die "unsupported repo type: $type\n"; +} diff --git a/debian/changelog b/debian/changelog index c44d629..f16624f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -build (2015.01.15-tizen20160315) unstable; urgency=high +build (20150115-tizen20160302) unstable; urgency=high - * just update version to 2015.01.15 + * update to version 20150115 - -- Jiankang Fan <jiankang.fan@samsung.com> Tue, 15 Mar 2016 19:30:22 +0200 + -- Fan Jiankang <jiankang.fan@samsung.com> Wed, 2 Mar 2016 19:30:22 +0200 build (2013.11.12-tizen20140815) unstable; urgency=high diff --git a/debtransform b/debtransform index 272ff71..3d18326 100755 --- a/debtransform +++ b/debtransform @@ -1,8 +1,33 @@ #!/usr/bin/perl -w +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + use strict; use Digest::MD5; +sub usage +{ + die("usage: debtransform [--debug] [--changelog <changelog>] [--release <release number>] <srcdir> <dscfile> <outdir>\n"); +} + sub parsedsc { my ($fn) = @_; my @control; @@ -211,13 +236,30 @@ sub addfile { return "$md5 $size $base"; } +print "debtransform: ", join( " ", @ARGV ), "\n"; + +my $debug = 0; my $changelog; +my $release; + +while (@ARGV > 3) { + if ($ARGV[0] eq '--debug') { + shift @ARGV; + $debug = 1; + } elsif ($ARGV[0] eq '--changelog') { + shift @ARGV; + $changelog = shift @ARGV; + } elsif ($ARGV[0] eq '--release') { + shift @ARGV; + $release = shift @ARGV; + } else { + usage(); + } +} -if (@ARGV > 1 && $ARGV[0] eq '--changelog') { - shift @ARGV; - $changelog = shift @ARGV; +if( @ARGV != 3 ) { + usage(); } -die("usage: debtransform [--changelog <changelog>] <srcdir> <dscfile> <outdir>\n") unless @ARGV == 3; my $dir = $ARGV[0]; my $dsc = $ARGV[1]; @@ -263,6 +305,7 @@ my $version = $tags->{'VERSION'}; die("dsc file contains no version\n") unless defined($version); $version =~ s/^\d+://; # no epoch in version, please + # transform my $tmptar; if ($tarfile =~ /\.tar\.bz2/) { @@ -300,6 +343,18 @@ if( $tmptar ) { } push @files, addfile("$out/$ntarfile"); +if ( $tags->{'DEBTRANSFORM-RELEASE'} && $release ) { + # if dsc file contains the tag DEBTRANSFORM-RELEASE + # and "release" is given as a commad line parameter, + # replace "version" from dsc file by "version-release". + # From "version" the current release is stripped before + # (last "-" and the part after the last "-"). + # On OBS, release is incremented automatically + # (same as for RPMs) + $version = $v . "-" . $release; + $tags->{'VERSION'} = $version; +} + my $tarpath = "$out/$ntarfile"; my $tardir = $tarfile; $tardir =~ s/\.orig\.tar/\.tar/; @@ -368,5 +423,13 @@ delete $tags->{'DEBTRANSFORM-SERIES'}; delete $tags->{'DEBTRANSFORM-TAR'}; delete $tags->{'DEBTRANSFORM-FILES-TAR'}; delete $tags->{'DEBTRANSFORM-FILES'}; +delete $tags->{'DEBTRANSFORM-RELEASE'}; writedsc("$out/${name}_$version.dsc", $tags); + +if( $debug ) { + print `ls -la $out`; + print `cat $out/${name}_$version.dsc`; + print `zcat $out/${name}_$version.diff.gz`; +} + exit(0); diff --git a/debtransformbz2 b/debtransformbz2 index 01c1e9d..b49ed4c 100755 --- a/debtransformbz2 +++ b/debtransformbz2 @@ -1,5 +1,25 @@ #! /bin/bash +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + if test $# -ne 2; then exit 1 fi diff --git a/debtransformzip b/debtransformzip index 2054c12..2335745 100755 --- a/debtransformzip +++ b/debtransformzip @@ -1,5 +1,25 @@ #! /bin/bash +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + if test $# -ne 2; then exit 1 fi @@ -1,5 +1,25 @@ #!/usr/bin/perl -w +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + use Net::SSL (); BEGIN { $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0, @@ -31,11 +51,11 @@ for my $url (@ARGV) { my $original = $url; if ($url =~ /^zypp:\/\/([^\/]*)\/?/) { use Build::Zypp; - my $repo = Build::Zypp::parsecfg($1); + my $repo = Build::Zypp::parserepo($1); die "can't parse $1\n" unless $repo; die "missing url in repo ".$repo->{'name'}."\n" unless exists $repo->{'baseurl'}; my $u = $repo->{'baseurl'}; - $u .= '/' unless substr($u, -1, 1) eq '/'; + $u .= '/' unless $u =~ /\/$/; $url =~ s/^zypp:\/\/[^\/]*\/*//; $url = URI->new($u.$url); if ($url->scheme eq 'dir') { diff --git a/emulator/emulator.sh b/emulator/emulator.sh index 0051172..3320f9f 100755 --- a/emulator/emulator.sh +++ b/emulator/emulator.sh @@ -1,6 +1,26 @@ #!/bin/bash -echo "ERROR: the emulator.sh script got not changed to support your emulator!" +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +echo "ERROR: the emulator.sh script needs to be changed to support your emulator!" exit 1 @@ -1,5 +1,25 @@ #!/usr/bin/perl -w +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + BEGIN { unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build'); } @@ -9,7 +29,9 @@ use strict; use Build; use File::Basename; -my ($dist, $rpmdeps, $archs, $configdir, $useusedforbuild); +my ($dist, $rpmdeps, $archs, $configdir, $useusedforbuild, $installonly, $noinstall); + +$configdir = ($::ENV{'BUILD_DIR'} || '/usr/lib/build') . '/configs'; while (@ARGV) { if ($ARGV[0] eq '--dist') { @@ -57,23 +79,44 @@ while (@ARGV) { } last; } -$configdir = '.' unless defined $configdir; + $archs = '' unless defined $archs; die("you must specfiy a depfile!\n") unless defined $rpmdeps; -my @extradeps = grep {!/(^|\/)(?:PKGBUILD|_preinstallimage)$/ && !/\.(?:spec|dsc|kiwi)$/} @ARGV; -my @specs = grep {/(^|\/)(?:PKGBUILD|_preinstallimage)$/ || /\.(?:spec|dsc|kiwi)$/} @ARGV; -die("can only work with at most one spec\n") if @specs > 1; -my $spec = $specs[0]; +# split args in recipe and pkgnames +my $recipe; +my @extradeps; +for my $arg (@ARGV) { + my $buildtype = Build::recipe2buildtype($arg); + if ($buildtype) { + die("can only work with at most one recipe file\n") if defined $recipe; + $recipe = $arg; + } else { + push @extradeps, $arg; + } +} +my $binarytype; my @archs = split(':', $archs); -if ($spec =~ /(^|\/)PKGBUILD$/) { +if ($recipe =~ /(^|\/)PKGBUILD$/) { push @archs, 'any' unless grep {$_ eq 'any'} @archs; + $binarytype = 'arch'; +} elsif ($recipe =~ /\.dsc$/) { + push @archs, 'all' unless grep {$_ eq 'noarch'} @archs; + $binarytype = 'deb'; } else { push @archs, 'noarch' unless grep {$_ eq 'noarch'} @archs; + $binarytype = 'rpm'; } -my (%fn, %prov, %req); +# read dist if we can +my $cf; +if (defined($dist) && $dist ne '') { + $cf = Build::read_config_dist($dist, $archs[0], $configdir); + $binarytype = $cf->{'binarytype'} if $cf->{'binarytype'} && $cf->{'binarytype'} ne 'UNDEFINED'; +} + +my (%fn, %prov, %req, %con, %obs); my %packs; my %repo; @@ -81,7 +124,6 @@ my %ids; my %packs_arch; my %packs_done; - # XXX: move to separate tool if (!defined($dist) || $dist eq '') { my $rpmarch = (grep {$fn{"rpm.$_"}} @archs)[0]; @@ -109,15 +151,26 @@ if (!defined($dist) || $dist eq '') { print STDERR "Warning: distribution not specified, assuming '$dist' (see $configdir).\n"; } -my $cf = Build::read_config_dist($dist, $archs[0], $configdir); +$cf ||= Build::read_config_dist($dist, $archs[0], $configdir); $cf->{'warnings'} = 1; my $dofileprovides = %{$cf->{'fileprovides'}}; - +$dofileprovides = 1 if ($binarytype || 'rpm') ne 'rpm'; my %exportfilters = %{$cf->{'exportfilter'}}; + open(F, '<', $rpmdeps) || die("$rpmdeps: $!\n"); # WARNING: the following code assumes that the 'I' tag comes last -my ($pkgF, $pkgP, $pkgR); +my ($pkgF, $pkgP, $pkgR, $pkgC, $pkgO); + +my $verscmp = \&Build::Rpm::verscmp; + +if ($binarytype && $binarytype eq 'deb') { + $verscmp = \&Build::Deb::verscmp; + for my $arch (@archs) { + $arch = Build::Deb::basearch($arch) unless $arch =~ /^i[456]86$/; + } +} + while(<F>) { chomp; if (/^F:(.*?)-\d+\/\d+\/\d+: (.*)$/) { @@ -141,30 +194,35 @@ while(<F>) { } } elsif (/^P:(.*?)-\d+\/\d+\/\d+: (.*)$/) { $pkgP = $2; - next if $prov{$1}; - $prov{$1} = $2; } elsif (/^R:(.*?)-\d+\/\d+\/\d+: (.*)$/) { $pkgR = $2; - next if $req{$1}; - $req{$1} = $2; + } elsif (/^C:(.*?)-\d+\/\d+\/\d+: (.*)$/) { + $pkgC = $2; + } elsif (/^O:(.*?)-\d+\/\d+\/\d+: (.*)$/) { + $pkgO = $2; } elsif (/^I:(.*?)-\d+\/\d+\/\d+: (.*)$/) { - if ($ids{$1} && !$packs_done{$1} && defined($pkgF) && defined($pkgP) && defined($pkgR)) { - my $i = $1; - my $oldid = $ids{$1}; - my $newid = $2; - if (Build::Rpm::verscmp($oldid, $newid) < 0) { - $ids{$i} = $newid; - $fn{$i} = $pkgF; - $prov{$i} = $pkgP; - $req{$i} = $pkgR; - } - } else { - next if $ids{$1}; - $ids{$1} = $2; + next if $packs_done{$1}; + my ($i, $newid) = ($1, $2); + undef $i unless !$ids{$i} || $verscmp->($ids{$i}, $newid) < 0; + undef $i unless defined($pkgF) && defined($pkgP); + if (defined $i) { + $i =~ /^(.*)\.([^\.]+)$/ or die; + push @{$packs_arch{$2}}, $1; + $ids{$i} = $newid; + $fn{$i} = $pkgF; + $prov{$i} = $pkgP; + delete $req{$i}; + delete $con{$i}; + delete $obs{$i}; + $req{$i} = $pkgR; + $con{$i} = $pkgC if defined $pkgC; + $obs{$i} = $pkgO if defined $pkgO; } undef $pkgF; undef $pkgP; undef $pkgR; + undef $pkgC; + undef $pkgO; } elsif ($_ eq 'D:') { %packs_done = %ids; } @@ -174,9 +232,10 @@ close F; for my $arch (@archs) { $packs{$_} ||= "$_.$arch" for @{$packs_arch{$arch} || []}; } + for my $pack (keys %packs) { my $r = {}; - my (@s, $s, @pr, @re); + my (@s, $s, @pr, @re, @co, @ob); @s = split(' ', $prov{$packs{$pack}} || ''); while (@s) { $s = shift @s; @@ -186,7 +245,12 @@ for my $pack (keys %packs) { next; } push @pr, $s; - splice(@s, 0, 2) if @s && $s[0] =~ /^[<=>]/; + while (@s && $s[0] =~ /^[\(<=>|]/) { + $pr[-1] .= " $s[0] $s[1]"; + $pr[-1] =~ s/ \((.*)\)/ $1/; + $pr[-1] =~ s/(<|>){2}/$1/; + splice(@s, 0, 2); + } } @s = split(' ', $req{$packs{$pack}} || ''); while (@s) { @@ -197,18 +261,48 @@ for my $pack (keys %packs) { next; } push @re, $s; - splice(@s, 0, 2) if @s && $s[0] =~ /^[<=>]/; + while (@s && $s[0] =~ /^[\(<=>|]/) { + $re[-1] .= " $s[0] $s[1]"; + $re[-1] =~ s/ \((.*)\)/ $1/; + $re[-1] =~ s/(<|>){2}/$1/; + splice(@s, 0, 2); + } + } + @s = split(' ', $con{$packs{$pack}} || ''); + while (@s) { + $s = shift @s; + next if !$dofileprovides && $s =~ /^\//; + push @co, $s; + while (@s && $s[0] =~ /^[\(<=>|]/) { + $co[-1] .= " $s[0] $s[1]"; + $co[-1] =~ s/ \((.*)\)/ $1/; + $co[-1] =~ s/(<|>){2}/$1/; + splice(@s, 0, 2); + } + } + @s = split(' ', $obs{$packs{$pack}} || ''); + while (@s) { + $s = shift @s; + next if !$dofileprovides && $s =~ /^\//; + push @ob, $s; + while (@s && $s[0] =~ /^[\(<=>|]/) { + $ob[-1] .= " $s[0] $s[1]"; + $ob[-1] =~ s/ \((.*)\)/ $1/; + $ob[-1] =~ s/(<|>){2}/$1/; + splice(@s, 0, 2); + } } $r->{'provides'} = \@pr; $r->{'requires'} = \@re; + $r->{'conflicts'} = \@co; + $r->{'obsoletes'} = \@ob; $repo{$pack} = $r; } ####################################################################### -sub print_rpmlist -{ +sub print_rpmlist { for (@_) { print "$_ $fn{$packs{$_}}\n"; print "rpmid: $_:$ids{$packs{$_}}\n" if exists $ids{$packs{$_}}; @@ -217,12 +311,14 @@ sub print_rpmlist print "vminstall: @{$cf->{'vminstall'} || []}\n"; print "runscripts: @{$cf->{'runscripts'} || []}\n"; print "dist: $dist\n" if defined $dist; + print "installonly: $installonly\n" if defined $installonly; + print "noinstall: $noinstall\n" if defined $noinstall; } if ($useusedforbuild) { - die("Need a specfile/dscfile for --usedforbuild\n") unless defined $spec; + die("Need a recipe file for --usedforbuild\n") unless defined $recipe; local *F; - open(F, '<', $spec) || die("$spec: $!\n"); + open(F, '<', $recipe) || die("$recipe: $!\n"); my @usedforbuild; my @buildrequires; while(<F>) { @@ -255,11 +351,12 @@ if ($useusedforbuild) { my ($packname, $packvers, $subpacks, @packdeps); $subpacks = []; -if ($spec) { - my $d; - if ($spec =~ /\.kiwi$/) { +if ($recipe) { + my $d = Build::parse($cf, $recipe) || {}; + my $buildtype = Build::recipe2buildtype($recipe) || ''; + $cf->{'type'} = $buildtype if $buildtype; + if ($buildtype eq 'kiwi') { # lets see if this is a product or image build - $d = Build::parse($cf, $spec) || {}; my $type = $d->{'imagetype'} && $d->{'imagetype'}->[0] eq 'product' ? 'product' : 'image'; my @kdeps; if ($type eq 'image') { @@ -271,8 +368,6 @@ if ($spec) { } push @kdeps, grep {/^kiwi-.*:/} @{$d->{'deps'} || []}; $d = { 'deps' => \@kdeps, 'subpacks' => [] }; - } else { - $d = Build::parse($cf, $spec); } $packname = $d->{'name'}; $packvers = $d->{'version'}; @@ -280,7 +375,7 @@ if ($spec) { @packdeps = @{$d->{'deps'} || []}; if ($d->{'prereqs'}) { my %deps = map {$_ => 1} (@packdeps, @{$d->{'subpacks'} || []}); - push @packdeps, grep {!$deps{$_} && !/^%/} @{$d->{'prereqs'}}; + push @packdeps, '--directdepsend--', grep {!$deps{$_} && !/^%/} @{$d->{'prereqs'}}; } } @@ -296,6 +391,20 @@ if (!shift @bdeps) { exit(1); } +my @sysdeps = Build::get_sysbuild($cf); +if (@sysdeps) { + if (!shift @sysdeps) { + print STDERR "expansion error\n"; + print STDERR " $_\n" for @sysdeps; + exit(1); + } + my %sysdeps = map {$_ => 1} @sysdeps; + my %bdeps = map {$_ => 1} @bdeps; + $installonly = join(' ', grep {!$bdeps{$_}} @sysdeps); + $noinstall = join(' ', grep {!$sysdeps{$_}} @bdeps); + @bdeps = Build::unify(@sysdeps, @bdeps); +} + # make sure all preinstalls are in bdeps; # XXX: also add vmdeps? @bdeps = Build::unify(@bdeps, Build::get_preinstalls($cf)); diff --git a/extractbuild b/extractbuild index f46ffc1..d2d56ad 100755 --- a/extractbuild +++ b/extractbuild @@ -1,11 +1,32 @@ #!/usr/bin/perl -w +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + use strict; # buffer size for reading my $bufsize = 4*1024*1024; my ($opt_skip, $opt_disk, $opt_input, $opt_verbose); +$opt_verbose = 0; while (@ARGV) { if ($ARGV[0] eq '--skip') { @@ -25,7 +46,7 @@ while (@ARGV) { } if ($ARGV[0] eq '--verbose' || $ARGV[0] eq '-v') { shift @ARGV; - $opt_verbose = 1; + $opt_verbose++; next; } last; @@ -35,51 +56,86 @@ die "need to specify disk image\n" unless $opt_disk; open(F, '<', $opt_disk) || die "$opt_disk: $!\n"; -if($opt_input) { +if ($opt_input) { open(S, '<', $opt_input) || die "$opt_input: $!\n"; } else { open(S, '<&STDIN') || die "can't dup stdin: $!\n"; } # skip build status -if($opt_skip) { - seek(S, $opt_skip, 0) || die "$!\n"; +if ($opt_skip) { + seek(S, $opt_skip, 0) || die "seek: $!\n"; } -while(<S>) { +my %done; +while (<S>) { chomp; last unless length $_; - my ($file, $filesize, $blksize, @blocks) = split(/ /); - if($#blocks == -1 && $filesize) { - die "invalid input '$_'\n"; + my ($filetype, $file, $filesize, $blksize, @blocks) = split(/ /); + die("invalid input '$_'\n") unless defined($file); + $file =~ s/%([a-fA-F0-9]{2})/chr(hex($1))/ge; + die("bad file '$file'\n") if "/$file/" =~ /\/\.{0,2}\//s; + if ($file =~ /^(.*)\//s) { + die("file without directory: $file\n") unless $done{$1} && $done{$1} eq 'd'; + } + if ($filetype eq 'd') { # dir + print "$file\n" if $opt_verbose && $opt_verbose > 1; + mkdir($file) || die("mkdir $file: $!\n"); + $done{$file} = 'd'; + next; + } + if ($filetype eq 'l') { # symlink + my $target = $filesize; + die("symlink without target\n") unless defined $target; + $target =~ s/%([a-fA-F0-9]{2})/chr(hex($1))/ge; + die("bad symlink: $target\n") if "/$target/" =~ /\/\.?\//s; + if ("/$target/" =~ /^(\/\.\.)+\/(.*?)$/s) { + my ($head, $tail) = ($1, $2); + die("bad upref in symlink: $target\n") if "/$tail/" =~ /\/\.\.\//s; + die("bad upref in symlink: $target\n") if ($head =~ y!/!!) > ($file =~ y!/!!); + } else { + die("bad upref in symlink: $target\n") if "/$target/" =~ /\/\.\.\//s; + } + print "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//); + symlink($target, $file) || die("symlink $target $file: $!\n"); + $done{$file} = 'l'; + next; } + die("illegal file type: $filetype\n") unless $filetype eq 'f'; + die "invalid input '$_'\n" if !@blocks && $filesize; + $done{$file} = 'f'; $filesize = int($filesize); + if ($filesize == 0) { + print "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//); + open (O, '>', $file) or die "$file: $!\n"; + close O; + next; + } $blksize = int($blksize); - die "invalid block size" unless ($blksize > 0 && $blksize <= $bufsize); + die "$file: invalid block size $blksize\n" unless $blksize > 0 && $blksize <= $bufsize; my $maxblocks = int($bufsize/$blksize); - $file =~ s/.*\///; # ensure basename, also stops directory traversal - $file =~ s/[^[:print:]]/_/g; # no binary junk in file names - print "$file\n" if $opt_verbose; - open (O, '>', $file) or die "$file: $!"; + print "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//); + open (O, '>', $file) or die "$file: $!\n"; for my $block (@blocks) { - my ($block, $end) = split(/-/, $block); + my $end; + ($block, $end) = split(/-/, $block); $block = int($block); - - if($block == 0) { # a hole! - seek(O, $blksize, 1); - $filesize -= $blksize; + if ($block == 0) { # a hole! + $end = (($end || 0) + 1) * $blksize; + $end = $filesize if $end > $filesize; + seek(O, $end, 1); + $filesize -= $end; next; } - $end = $block unless $end; $end = int($end); seek(F, $block*$blksize, 0) || die "$file: seek: $!\n"; - while($block <= $end && $filesize) { + while ($block <= $end && $filesize) { my $size; - if($end == $block) { + if ($end == $block) { $size = $blksize; ++$block; - } elsif($maxblocks >= $end-$block) { + } elsif ($maxblocks >= $end-$block) { $size = ($end-$block)*$blksize; $block += $end-$block; } else { @@ -88,14 +144,12 @@ while(<S>) { } $size = $filesize if $size > $filesize; my $buf; - if((sysread(F, $buf, $size) || 0) != $size) { - die "$file: read: $!\n"; - } + (sysread(F, $buf, $size) || 0) == $size || die("$file: read: $!\n"); $filesize -= $size; - print O $buf; + (syswrite(O, $buf) || 0) == length($buf) || die("$file: write error\n"); } } - close O; + close(O) || die("$file: close error: $!\n"); # sanity check die "$file: invalid file size ($filesize byes left)\n" if $filesize != 0; } diff --git a/getbinaryid b/getbinaryid index 55c57f6..a85df82 100755 --- a/getbinaryid +++ b/getbinaryid @@ -1,5 +1,25 @@ #!/usr/bin/perl +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + BEGIN { unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build'); } diff --git a/init_buildsystem b/init_buildsystem index 6e83266..169158d 100755 --- a/init_buildsystem +++ b/init_buildsystem @@ -7,16 +7,37 @@ # BUILD_RPMS here we get our packages to install # BUILD_ARCH path of the architectures we try # -# (c) 1997-2005 SuSE GmbH Nuernberg, Germany +################################################################ +# +# Copyright (c) 1997-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ # # needed globals variables # export SRC -export YAST_IS_RUNNING="instsys" -export DEBIAN_FRONTEND=noninteractive -export DEBIAN_PRIORITY=critical export BUILD_DIR=${BUILD_DIR:-/usr/lib/build} + +export YAST_IS_RUNNING=instsys + +# slurp in package binary support +. "$BUILD_DIR/build-pkg" + # need to restore build root owner for non-root builds browner=0 definesnstuff=() @@ -24,23 +45,20 @@ repos=() . $BUILD_DIR/common_functions || exit 1 -# should RPMs be installed with --force ? -USE_FORCE=false - BUILD_IS_RUNNING=$BUILD_ROOT/not-ready TMPFILE=$BUILD_ROOT/tmpfile -#buildhost removed so that id can be generated from repo files -#RPMIDFMT="%{NAME}-%{VERSION}-%{RELEASE} %{BUILDHOST}-%{BUILDTIME}\n" -RPMIDFMT="%{NAME}-%{VERSION}-%{RELEASE} %{BUILDTIME}\n" +# should RPMs be installed with --force ? +USE_FORCE=false PREPARE_VM= -USE_SYSTEM_QEMU= KEEP_PACKS= USEUSEDFORBUILD= LIST_STATE= RPMLIST= CLEAN_BUILD= CREATE_BUILD_BINARIES= +DLNOSIGNATURE= +CACHE_DIR=/var/cache/build while test -n "$1" ; do case "$1" in @@ -48,14 +66,10 @@ while test -n "$1" ; do shift PREPARE_VM=true ;; - --use-system-qemu) - shift - USE_SYSTEM_QEMU=true - ;; - --keep-packs) - shift - KEEP_PACKS=true - ;; + --keep-packs) + shift + KEEP_PACKS=true + ;; --create-build-binaries) shift CREATE_BUILD_BINARIES=true @@ -80,12 +94,12 @@ while test -n "$1" ; do ;; --repository|--repo) repos[${#repos[@]}]="$2"; - shift 2; + shift 2 ;; --clean) CLEAN_BUILD="$1" shift - ;; + ;; --cachedir) CACHE_DIR="$2" shift 2 @@ -94,6 +108,10 @@ while test -n "$1" ; do CONFIG_DIR=$2 shift 2 ;; + --nosignature) + shift + DLNOSIGNATURE="--nosignature" + ;; *) break ;; @@ -105,8 +123,7 @@ PKGS=("$@") # needed functions # -cleanup_and_exit() -{ +cleanup_and_exit() { trap EXIT test "$BUILD_ROOT" = / -a -n "$browner" && chown "$browner" "$BUILD_ROOT" # umount so init_buildsystem can be used standalone @@ -118,31 +135,33 @@ cleanup_and_exit() exit ${1:-0} } -clean_build_root() -{ - test -n "$BUILD_ROOT" && { - umount -n "$BUILD_ROOT/proc/sys/fs/binfmt_misc" 2> /dev/null || true - umount -n "$BUILD_ROOT/proc" 2> /dev/null || true - umount -n "$BUILD_ROOT/dev/pts" 2> /dev/null || true - umount -n "$BUILD_ROOT/mnt" 2> /dev/null || true - rm -rf -- "$BUILD_ROOT"/* - rm -rf -- "$BUILD_ROOT/.build" - rm -rf -- "$BUILD_ROOT/.root" - rm -rf -- "$BUILD_ROOT/.init_b_cache" - rm -rf -- "$BUILD_ROOT/.preinstall_image/*" - rm -rf -- "$BUILD_ROOT/.preinstallimage"* - mkdir -p "$BUILD_ROOT/proc" - mkdir -p "$BUILD_ROOT/dev/pts" - if [ "$UID" = '0' ]; then - mount -n -tproc none "$BUILD_ROOT/proc" - mount -n -tdevpts -omode=0620,gid=5 none "$BUILD_ROOT/dev/pts" - fi - } +clean_build_root() { + if test -n "$BUILD_ROOT" ; then + umount -n "$BUILD_ROOT/proc/sys/fs/binfmt_misc" 2> /dev/null || true + umount -n "$BUILD_ROOT/proc" 2> /dev/null || true + umount -n "$BUILD_ROOT/dev/pts" 2> /dev/null || true + umount -n "$BUILD_ROOT/dev/shm" 2> /dev/null || true + umount -n "$BUILD_ROOT/mnt" 2> /dev/null || true + rm -rf -- "$BUILD_ROOT"/* 2> /dev/null || true + chattr -a -A -i -R -- "$BUILD_ROOT" 2> /dev/null || true + rm -rf -- "$BUILD_ROOT"/* + rm -rf -- "$BUILD_ROOT/.build" + rm -rf -- "$BUILD_ROOT"/.build.kernel.* + rm -rf -- "$BUILD_ROOT"/.build.initrd.* + rm -rf -- "$BUILD_ROOT/.root" + rm -rf -- "$BUILD_ROOT/.init_b_cache" + rm -rf -- "$BUILD_ROOT"/.preinstall_image/* + rm -rf -- "$BUILD_ROOT"/.preinstallimage* + mkdir -p "$BUILD_ROOT/proc" + mkdir -p "$BUILD_ROOT/dev/pts" + if test "$UID" = 0 ; then + mount -n -tproc none "$BUILD_ROOT/proc" + mount -n -tdevpts -omode=0620,gid=5 none "$BUILD_ROOT/dev/pts" + fi + fi } - -unsafe_preinstall_check() -{ +unsafe_preinstall_check() { # cpio isn't safe so we require bsdtar for VMs. chroot is # unsafe anyways so it's ok for that. if test -n "$PREPARE_VM" ; then @@ -152,22 +171,16 @@ unsafe_preinstall_check() fi } -preinstall_image_filter() -{ +preinstall_image_filter() { for PKG in "$@" ; do test -e "$BUILD_ROOT/.preinstall_image/$PKG" && continue echo $PKG done } -preinstall_image() -{ +preinstall_image() { check_exit - if test -n "$2" ; then - echo "unpacking preinstall image $2" - else - echo "unpacking preinstall image" - fi + echo "unpacking preinstall image${2:+ $2}" cd $BUILD_ROOT || cleanup_and_exit 1 if test -x /usr/bin/bsdtar ; then TAR="/usr/bin/bsdtar -P --chroot --numeric-owner -x" @@ -184,10 +197,10 @@ preinstall_image() rm -f "$BUILD_ROOT/.preinstallimage.unpack" } -preinstall() -{ +preinstall() { + local PKG="$1" check_exit - echo "preinstalling $1..." + echo "preinstalling $PKG..." cd $BUILD_ROOT || cleanup_and_exit 1 if test -x /usr/bin/bsdtar ; then CPIO="/usr/bin/bsdtar -P --chroot -o --numeric-owner -x -f-" @@ -195,128 +208,20 @@ preinstall() else unsafe_preinstall_check CPIO="cpio --extract --unconditional --preserve-modification-time --make-directories --no-absolute-filenames --quiet" - cpio --help 2>/dev/null | grep -q -e --extract-over-symlinks && CPIO="$CPIO --extract-over-symlinks" TAR="tar -x" fi - if test -e "$BUILD_ROOT/.init_b_cache/rpms/$1.rpm" ; then - PAYLOADDECOMPRESS=cat - case `rpm -qp --nodigest --nosignature --qf "%{PAYLOADCOMPRESSOR}\n" "$BUILD_ROOT/.init_b_cache/rpms/$1.rpm"` in - lzma) rpm --showrc | egrep 'PayloadIsLzma|_lzma' > /dev/null || PAYLOADDECOMPRESS="lzma -d" ;; - xz) rpm --showrc | egrep 'PayloadIsXz|_xz' > /dev/null || PAYLOADDECOMPRESS="xz -d" ;; - esac - if test "$PAYLOADDECOMPRESS" = "lzma -d" ; then - if ! lzma </dev/null >/dev/null 2>&1 ; then - test -f "$BUILD_DIR/lzmadec.sh" && PAYLOADDECOMPRESS="bash $BUILD_DIR/lzmadec.sh" - fi - fi - if test "$PAYLOADDECOMPRESS" = "xz -d" ; then - if ! xz </dev/null >/dev/null 2>&1 ; then - test -f "$BUILD_DIR/xzdec.sh" && PAYLOADDECOMPRESS="bash $BUILD_DIR/xzdec.sh" - fi - fi - if test "$PAYLOADDECOMPRESS" = cat ; then - rpm2cpio "$BUILD_ROOT/.init_b_cache/rpms/$1.rpm" | $CPIO - else - rpm2cpio "$BUILD_ROOT/.init_b_cache/rpms/$1.rpm" | $PAYLOADDECOMPRESS | $CPIO - fi - if test -e ".init_b_cache/scripts/$1.run" ; then - rpm -qp --nodigest --nosignature --qf "%{PREIN}" "$BUILD_ROOT/.init_b_cache/rpms/$1.rpm" > ".init_b_cache/scripts/$1.pre" - rpm -qp --nodigest --nosignature --qf "%{POSTIN}" "$BUILD_ROOT/.init_b_cache/rpms/$1.rpm" > ".init_b_cache/scripts/$1.post" - echo -n '(none)' > .init_b_cache/scripts/.none - cmp -s ".init_b_cache/scripts/$1.pre" .init_b_cache/scripts/.none && rm -f ".init_b_cache/scripts/$1.pre" - cmp -s ".init_b_cache/scripts/$1.post" .init_b_cache/scripts/.none && rm -f ".init_b_cache/scripts/$1.post" - rm -f .init_b_cache/scripts/.none - fi - elif test -e "$BUILD_ROOT/.init_b_cache/rpms/$1.deb" ; then - # fix issue for ubuntu15.04 "data.tar.xz" - ar x "$BUILD_ROOT/.init_b_cache/rpms/$1.deb" - mkdir -p .init_b_cache/scripts/control - $TAR -C .init_b_cache/scripts/control -z -f control.tar.gz - if test -f "data.tar.gz"; then - $TAR -z -f data.tar.gz - elif test -f "data.tar.xz"; then - $TAR -J -f data.tar.xz - fi - if test -e ".init_b_cache/scripts/$1.run" ; then - test -e .init_b_cache/scripts/control/preinst && mv .init_b_cache/scripts/control/preinst ".init_b_cache/scripts/$1.pre" - test -e .init_b_cache/scripts/control/postinst && mv .init_b_cache/scripts/control/postinst ".init_b_cache/scripts/$1.post" - fi - rm -rf .init_b_cache/scripts/control control.tar.gz data.tar.{g,x}z - elif test -e "$BUILD_ROOT/.init_b_cache/rpms/$1.arch" ; then - $TAR -f "$BUILD_ROOT/.init_b_cache/rpms/$1.arch" - if test -f .INSTALL ; then - cat .INSTALL > ".init_b_cache/scripts/$1.post" - echo 'type post_install >/dev/null 2>&1 && post_install' >> ".init_b_cache/scripts/$1.post" - fi - rm -f .PKGINFO .INSTALL - else - echo "warning: package $1 does not exist" - fi + pkg_preinstall } -run_pkg_scripts() -{ - # need to change to $BUILD_ROOT - cd $BUILD_ROOT +run_pkg_scripts() { chroot $BUILD_ROOT /sbin/ldconfig 2>/dev/null for PKG in $PACKAGES_TO_RUNSCRIPTS ; do - if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.pre" ; then - echo "running $PKG preinstall script" - if test -e "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" ; then - chroot $BUILD_ROOT sh ".init_b_cache/scripts/$PKG.pre" 0 - else - chroot $BUILD_ROOT ".init_b_cache/scripts/$PKG.pre" install < /dev/null - fi - rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.pre" - fi - if test -e "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post" ; then - echo "running $PKG postinstall script" - if test -e "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" ; then - chroot $BUILD_ROOT sh ".init_b_cache/scripts/$PKG.post" 1 - else - chroot $BUILD_ROOT ".init_b_cache/scripts/$PKG.post" configure '' < /dev/null - fi - rm -f "$BUILD_ROOT/.init_b_cache/scripts/$PKG.post" - fi + pkg_runscripts check_exit done } -init_db() -{ - if test $PSUF = rpm ; then - echo initializing rpm db... - if ! test -e $BUILD_ROOT/usr/lib/rpm/cpuinfo.yaml; then - # rpm v5 does not have initdb - # rpmdb --initdb is recommended and exists since SL9 - if [ -x $BUILD_ROOT/usr/bin/rpmdb ]; then - chroot $BUILD_ROOT /usr/bin/rpmdb --initdb || cleanup_and_exit 1 - else - chroot $BUILD_ROOT rpm --initdb || cleanup_and_exit 1 - fi - fi - # hack: add nofsync to db config to speed up install - mkdir -p $BUILD_ROOT/root - DBI_OTHER=`chroot $BUILD_ROOT rpm --eval '%{?__dbi_other}'` - echo "%__dbi_other $DBI_OTHER nofsync" > $BUILD_ROOT/.rpmmacros - echo "%__dbi_other $DBI_OTHER nofsync" > $BUILD_ROOT/root/.rpmmacros - elif test $PSUF = deb ; then - # force dpkg into database to make epoch test work - if ! test "$BUILD_ROOT/.init_b_cache/rpms/dpkg.deb" -ef "$BUILD_ROOT/.init_b_cache/dpkg.deb" ; then - rm -f $BUILD_ROOT/.init_b_cache/dpkg.deb - cp $BUILD_ROOT/.init_b_cache/rpms/dpkg.deb $BUILD_ROOT/.init_b_cache/dpkg.deb || cleanup_and_exit 1 - fi - chroot $BUILD_ROOT dpkg -i --force all .init_b_cache/dpkg.deb >/dev/null 2>&1 - elif test $PSUF = arch ; then - mkdir -p $BUILD_ROOT/var/lib/pacman/sync - touch $BUILD_ROOT/var/lib/pacman/sync/core.db - touch $BUILD_ROOT/var/lib/pacman/sync/extra.db - touch $BUILD_ROOT/var/lib/pacman/sync/community.db - fi -} - -reorder() -{ +reorder() { test -z "$*" && return rm -f $BUILD_ROOT/.init_b_cache/order.manifest for PKG in "$@" ; do @@ -326,12 +231,11 @@ reorder() rm -f $BUILD_ROOT/.init_b_cache/order.manifest } -create_devs() -{ +create_devs() { local com file mode arg mkdir -m 755 -p $BUILD_ROOT/dev/pts - test -f $BUILD_ROOT/dev/shm && rm -f $BUILD_ROOT/dev/shm + test -d $BUILD_ROOT/dev/shm || rm -f $BUILD_ROOT/dev/shm mkdir -m 755 -p $BUILD_ROOT/dev/shm while read com file mode arg ; do rm -f $BUILD_ROOT/dev/$file @@ -361,16 +265,14 @@ DEVLIST # check whether the repo list contains a plain "zypp://". Add all # enabled zypp repos in this case -maybe_add_all_zypp_repos() -{ +expand_plain_zypp_repo() { local i j r=() for i in "${repos[@]}"; do - if [ "$i" = "zypp://" ]; then - while read j; do - j="${j#/etc/zypp/repos.d/}" - r=("${r[@]}" "zypp://${j%.repo}") - done < <(grep -l enabled=1 /etc/zypp/repos.d/*.repo) + if test "$i" = "zypp://" ; then + for j in $($BUILD_DIR/createzyppdeps --listrepos) ; do + r=("${r[@]}" "zypp://$j") + done else r=("${r[@]}" "$i") fi @@ -378,25 +280,24 @@ maybe_add_all_zypp_repos() repos=("${r[@]}") } -validate_cache_file() -{ - local findonly='' - maybe_add_all_zypp_repos +create_cache_file() { + local findonly= + expand_plain_zypp_repo if ! test -f $CACHE_FILE || ! test -f $CACHE_FILE.id || \ test "${repos[*]} ${BUILD_RPMS//:/ /}" != "$(cat $CACHE_FILE.id 2>/dev/null)"; then rm -f $CACHE_FILE.id else for SRC in "${repos[@]}" ${BUILD_RPMS//:/ /}; do test -n "$SRC" || SRC=. - if [ "${SRC#zypp://}" != "$SRC" ]; then - SRC="/var/cache/zypp/raw" # XXX can't use name here as we'd need to parse the file + if test "${SRC#zypp://}" != "$SRC" ; then + SRC="/var/cache/zypp/raw/${SRC#zypp://}" fi if test "$SRC" -nt $CACHE_FILE; then rm -f $CACHE_FILE.id break fi # always rebuild if we have remote repositories and --clean is given - if test -n "$CLEAN_BUILD" -a "$SRC" != "${SRC#*://}" ; then + if test -n "$CLEAN_BUILD" -a "$SRC" != "${SRC#*://}" -a "${SRC#zypp://}" = "$SRC" ; then rm -f $CACHE_FILE.id break fi @@ -404,29 +305,50 @@ validate_cache_file() fi if ! test -f $CACHE_FILE.id ; then test -z "$LIST_STATE" && echo initializing $CACHE_FILE ... + BINTYPE= + if test -n "$BUILD_DIST" ; then + BINTYPE=`queryconfig binarytype --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH"` + test "$BINTYPE" = UNDEFINED && BINTYPE= + fi + if test -z "$BINTYPE" ; then + # check the first init_buildsystem arg, maybe it is a recipe + case ${PKGS[0]} in + *.spec) + BINTYPE=rpm ;; + *.dsc) + BINTYPE=deb ;; + */PKGBUILD|PKGBUILD) + BINTYPE=arch ;; + esac + fi for SRC in "${repos[@]}" -- ${BUILD_RPMS//:/ /}; do if test "$SRC" = '--' ; then findonly=1 continue fi test -z "$SRC" && SRC=`pwd` - if [ "${SRC#zypp://}" != "$SRC" ]; then - set -- $BUILD_DIR/createrepomddeps "$SRC" - elif [ "${SRC#http://}" != "$SRC" -o "${SRC#https://}" != "$SRC" -o "${SRC#ftp://}" != "$SRC" -o "${SRC#ftps://}" != "$SRC" ]; then - mkdir -p "$(getcachedir "$SRC")" - set -- $BUILD_DIR/createrepomddeps --cachedir="$CACHE_DIR" "$SRC" - elif [ "${SRC#arch@http://}" != "$SRC" -o "${SRC#arch@https://}" != "$SRC" -o "${SRC#arch@ftp://}" != "$SRC" -o "${SRC#arch@ftps://}" != "$SRC" ]; then + if test "${SRC#http://}" != "$SRC" -o "${SRC#https://}" != "$SRC" -o "${SRC#ftp://}" != "$SRC" -o "${SRC#ftps://}" != "$SRC" ; then + # remote repo, cache binary packages mkdir -p "$(getcachedir "$SRC")" - set -- $BUILD_DIR/createrepomddeps --cachedir="$CACHE_DIR" "$SRC" - elif [ ! -e "$SRC" ]; then + if test "$BINTYPE" = arch ; then + set -- $BUILD_DIR/createarchdeps --cachedir="$CACHE_DIR" "$SRC" + elif test "$BINTYPE" = deb ; then + set -- $BUILD_DIR/createdebdeps --cachedir="$CACHE_DIR" --archpath "$BUILD_ARCH" "$SRC" + else + set -- $BUILD_DIR/createrepomddeps --cachedir="$CACHE_DIR" "$SRC" + fi + elif test "${SRC#zypp://}" != "$SRC" ; then + # special zypp repo + set -- $BUILD_DIR/createzyppdeps --cachedir="$CACHE_DIR" "$SRC" + elif test ! -e "$SRC" ; then echo "*** $SRC does not exist" >&2 cleanup_and_exit 1 - elif [ -z "$findonly" -a \( -e "$SRC"/suse/setup/descr/packages -o -e "$SRC"/suse/setup/descr/packages.gz \) ]; then + elif test -z "$findonly" -a \( -e "$SRC"/suse/setup/descr/packages -o -e "$SRC"/suse/setup/descr/packages.gz \) ; then set -- $BUILD_DIR/createyastdeps "$SRC" - elif [ -z "$findonly" -a -e "$SRC"/repodata/repomd.xml ]; then + elif test -z "$findonly" -a -e "$SRC"/repodata/repomd.xml ; then set -- $BUILD_DIR/createrepomddeps "$SRC" else - set -- $BUILD_DIR/createrpmdeps "$SRC" + set -- $BUILD_DIR/createdirdeps --oldfile "$CACHE_FILE" "$SRC" fi echo "$@" >&2 "$@" || cleanup_and_exit 1 @@ -438,6 +360,71 @@ validate_cache_file() fi } +fail_exit() { + cleanup_and_exit 1 +} + +# modifies $SRC +downloadpkg() { + local url="$1" + local cachedir + + if test "${url:0:7}" == "zypp://" -o "${url:0:7}" == "http://" -o "${url:0:8}" == "https://" -o "${url:0:6}" == "ftp://" -o "${url:0:7}" == "ftps://" ; then + cachedir="$(getcachedir "$url")" + local name="$(basename "$url")" + name=${name/%.pkg.tar.?z/.arch} + SRC="$cachedir/$name" + else + echo "Invalid url: $url" + cleanup_and_exit 1 + fi + + local destdir="$cachedir/tmp_$$" + mkdir -p "$destdir" + echo "downloading $url ... "; + $BUILD_DIR/download "$destdir" "$url" || cleanup_and_exit 1 + local destfile="$destdir/${url##*/}" + if test ! -e "$destfile" ; then + echo "expected $destfile after download but it's missing" >&2 + cleanup_and_exit 1 + fi + # for rpm check integrity and the signature + case $destfile in + *.rpm) + rpm -K $DLNOSIGNATURE "$destfile" > $destfile.v || { echo "rpm verify failed" >&2; rm -rf "$destdir"; cleanup_and_exit 1; } + if grep "NOT OK" $destfile.v; then + rm -rf "$destdir" + cleanup_and_exit 1 + fi + rm -f "$destfile.v" + ;; + esac + mv "$destfile" "$SRC" || cleanup_and_exit 1 + rm -rf $destdir +} + +getcachedir() { + local url=$1 + for repo in "${repos[@]}" ; do + if test "${url:0:${#repo}}" == "$repo" ; then + read repoid dummy < <(echo -n "$repo" | md5sum) + echo "$CACHE_DIR/$repoid" + break + fi + done +} + +can_reuse_cached_package() { + local cachepkgid pkgid + test -s "$1" || return 1 + if test -s "$BUILD_ROOT/.init_b_cache/rpms/$PKG.id" ; then + pkgid=$(perl -I$BUILD_DIR -MBuild -e Build::showquery "$1" buildid) + read cachepkgid < $BUILD_ROOT/.init_b_cache/rpms/$PKG.id + test "$cachepkgid" = "$pkgid" || return 1 + fi + return 0 +} + check_copy_qemu() { local arch @@ -506,112 +493,24 @@ copy_qemu() fi } -check_binfmt_registered() -{ - local arch - for arch in $EMULATOR_DEVS; do - if test -e /proc/sys/fs/binfmt_misc/$arch; then - return 0 - fi - done - return 1 -} - -fail_exit() -{ - cleanup_and_exit 1 -} - -# modifies $SRC -downloadpkg() -{ - local url="$1" - local cachedir - - if [ "${url:0:7}" == "zypp://" ] ; then - cachedir="/var/cache/zypp/packages/" - SRC="$cachedir${url#zypp://}" - mkdir -p "${SRC%/*}" || cleanup_and_exit 1 - elif [ "${url:0:7}" == "http://" -o "${url:0:8}" == "https://" -o "${url:0:6}" == "ftp://" -o "${url:0:7}" == "ftps://" ] ; then - cachedir="$(getcachedir "$url")" - local name="$(basename "$url")" - name=${name/%.pkg.tar.?z/.arch} - SRC="$cachedir/$name" - else - echo "Invalid url: $url" - cleanup_and_exit 1 - fi - - local destdir="$cachedir/tmp_$$" - mkdir -p "$destdir" - echo "downloading $url ... "; - $BUILD_DIR/download "$destdir" "$url" || cleanup_and_exit 1 - local destfile="$destdir/${url##*/}" - if [ ! -e "$destfile" ]; then - echo "expected $destfile after download but it's missing" >&2 - cleanup_and_exit 1 - fi - case $destfile in - *.rpm) - rpm -K "$destfile" > $destfile.v || { echo "rpm verify failed" >&2; rm -rf "$destdir"; cleanup_and_exit 1; } - if grep "NOT OK" $destfile.v; then - rm -rf "$destdir" - cleanup_and_exit 1 - fi - rm -f "$destfile.v" - ;; - esac - mv "$destfile" "$SRC" || cleanup_and_exit 1 - rm -rf $destdir -} - -getcachedir() -{ - local url=$1 - case $url in - zypp://*) - url=${url#zypp:/} - echo "/var/cache/zypp/packages/${url%/*}" - return 0; - ;; - *.pkg.tar.?z) url="arch@$url" ;; - esac - for repo in "${repos[@]}" ; do - if [ "${url:0:${#repo}}" == "$repo" -o "${url:0:${#repo}}" == "$repo" ] ; then - read repoid dummy < <(echo -n "$repo" | md5sum) - echo "$CACHE_DIR/$repoid" - break - fi - done -} - -get_pkg_filename() -{ - local url="$1" - local name=$(basename $url) - local cachedir=$(getcachedir $url) - local destfile="$cachedir/$name" - echo $destfile -} - set_build_arch trap fail_exit EXIT -if [ "$BUILD_ROOT" = / ]; then +if test "$BUILD_ROOT" = / ; then browner="$(stat -c %u /)" fi -if [ -n "$CLEAN_BUILD" ]; then +if test -n "$CLEAN_BUILD" ; then clean_build_root fi # # now test if there was an incomplete run # -if test -e $BUILD_IS_RUNNING ; then - echo It seems that there was an incomplete setup of $BUILD_ROOT. - echo To be sure, we will build it again completely... +if test -e "$BUILD_IS_RUNNING" ; then + echo "It seems that there was an incomplete setup of $BUILD_ROOT." + echo "To be sure, we will build it again completely..." umount -n $BUILD_ROOT/proc/sys/fs/binfmt_misc 2> /dev/null || true umount -n $BUILD_ROOT/proc 2> /dev/null umount -n $BUILD_ROOT/dev/pts 2> /dev/null @@ -626,9 +525,12 @@ if test -e $BUILD_IS_RUNNING ; then echo -n "[y/N/c] " read ANSWER case "$ANSWER" in - c|C) rm -f $BUILD_IS_RUNNING ;; - y|Y) clean_build_root ;; - *) cleanup_and_exit 1 ;; + c|C) + rm -f $BUILD_IS_RUNNING ;; + y|Y) + clean_build_root ;; + *) + cleanup_and_exit 1 ;; esac fi @@ -642,13 +544,14 @@ touch $BUILD_IS_RUNNING if test -n "$PREPARE_VM" ; then rm -f $BUILD_ROOT/.build/init_buildsystem.data fi + if test -e $BUILD_ROOT/.build/init_buildsystem.data ; then # vm continuation . $BUILD_ROOT/.build/init_buildsystem.data if ! test -e $BUILD_ROOT/.init_b_cache/preinstall_finished ; then # finish preinstall run_pkg_scripts - init_db + pkg_initdb touch $BUILD_ROOT/.init_b_cache/preinstall_finished fi else @@ -663,7 +566,7 @@ else # create rpmdeps file # CACHE_FILE=$BUILD_ROOT/.srcfiles.cache - validate_cache_file + create_cache_file # # select and expand packages @@ -692,29 +595,31 @@ else fi # - # register the QEMU emulator + # register the QEMU emulator if needed + # (we do not need this for the prepare step, as we do not run scripts in this case) # - if check_use_emulator; then - [ -n "$USE_SYSTEM_QEMU" ] && copy_qemu - echo "registering binfmt handlers for VM" - - if [ -x "$BUILD_DIR/initvm.$BUILD_HOST_ARCH" -a -e "$BUILD_DIR/qemu-reg" ]; then - $BUILD_DIR/initvm.$BUILD_HOST_ARCH - else - echo "Warning: could not register binfmt handlers. Neither build-initvm nor /usr/sbin/qemu-binfmt-conf.sh exist" - fi - + if test -z "$PREPARE_VM" ; then + if check_use_emulator ; then + copy_qemu + echo "registering binfmt handlers for cross build" + "$BUILD_DIR/$INITVM_NAME" echo 0 > /proc/sys/vm/mmap_min_addr read mmap_min_addr < /proc/sys/vm/mmap_min_addr - if [ "$mmap_min_addr" != 0 ]; then - echo "Warning: mmap_min_addr is != 0. If programs fail at mmap this could be the reason" + if test "$mmap_min_addr" != 0 ; then + echo "Warning: mmap_min_addr is != 0. If programs fail at mmap this could be the reason." fi + fi fi + # + # extract the data from the (generated) rpm list + # PACKAGES_TO_INSTALL= PACKAGES_TO_PREINSTALL= PACKAGES_TO_RUNSCRIPTS= PACKAGES_TO_VMINSTALL= + PACKAGES_TO_INSTALLONLY= + PACKAGES_TO_NOINSTALL= PREINSTALL_IMAGE= PREINSTALL_IMAGE_SOURCE= RUNSCRIPTS_SEEN= @@ -731,6 +636,14 @@ else PACKAGES_TO_VMINSTALL=$SRC continue fi + if test "$PKG" = "installonly:" ; then + PACKAGES_TO_INSTALLONLY=$SRC + continue + fi + if test "$PKG" = "noinstall:" ; then + PACKAGES_TO_NOINSTALL=$SRC + continue + fi if test "$PKG" = "preinstallimage:" ; then PREINSTALL_IMAGE=${SRC##*/} ln -s "$SRC" "$BUILD_ROOT/.init_b_cache/rpms/${SRC##*/}" @@ -763,7 +676,7 @@ else continue fi PACKAGES_TO_INSTALL="$PACKAGES_TO_INSTALL $PKG" - if [ "${SRC#/}" = "$SRC" ]; then + if test "${SRC#/}" = "$SRC" ; then case "$SRC" in zypp://* | http://* | https://* | ftp://* | ftps://*) echo "$PKG $SRC" >>$BUILD_ROOT/.init_b_cache/rpmlist.download @@ -779,32 +692,51 @@ else ln -s "$SRC" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.${SRCSUF##*.}" done < $RPMLIST + PACKAGES_TO_ALL="$PACKAGES_TO_INSTALL" + PACKAGES_TO_AVAILABLE="$PACKAGES_TO_INSTALL" + + # subtract noinstall packages from PACKAGES_TO_INSTALL + if test -n "$PACKAGES_TO_NOINSTALL" ; then + settest=" $PACKAGES_TO_NOINSTALL " + PACKAGES_TO_INSTALL= + for PKG in $PACKAGES_TO_ALL ; do + test "$settest" = "${settest/ $PKG /}" && PACKAGES_TO_INSTALL="$PACKAGES_TO_INSTALL $PKG" + done + fi + # subtract installonly packages from PACKAGES_TO_AVAILABLE + if test -n "$PACKAGES_TO_INSTALLONLY" ; then + settest=" $PACKAGES_TO_INSTALLONLY " + PACKAGES_TO_AVAILABLE= + for PKG in $PACKAGES_TO_ALL ; do + test "$settest" = "${settest/ $PKG /}" && PACKAGES_TO_AVAILABLE="$PACKAGES_TO_AVAILABLE $PKG" + done + fi + # check if we really can use cached versions for packages on the download list if test -s $BUILD_ROOT/.init_b_cache/rpmlist.download ; then rm -f $BUILD_ROOT/.init_b_cache/rpmlist.download2 while read PKG SRC ; do cachepkg="${SRC##*/}" cachepkg="${cachepkg/%.pkg.tar.?z/.arch}" - cachedir="$(getcachedir "$SRC")" - if test -s "$cachedir/$cachepkg" ; then - if test -s "$BUILD_ROOT/.init_b_cache/rpms/$PKG.id" -a "${SRC%.rpm}" != "$SRC" ; then - PKGID=`rpm -qp --qf "$RPMIDFMT" $RPMCHECKOPTS_HOST "$cachedir/$cachepkg"` - read cachepkgid < $BUILD_ROOT/.init_b_cache/rpms/$PKG.id - if test "$cachepkgid" = "$PKGID" ; then - SRC="$cachedir/$cachepkg" - else - rm -f "$cachedir/$cachepkg" - fi - else - $SRC="$cachedir/$cachepkg" + if test "$SRC" != "${SRC#zypp://}" ; then + # for zypp packages also look in the zypp cache + cachedir="/var/cache/zypp/packages/${SRC#zypp://}" + cachedir="${cachedir%/*}" + if can_reuse_cached_package "$cachedir/$cachepkg" ; then + SRCSUF=${SRC/%.pkg.tar.?z/.arch} + ln -s "$cachedir/$cachepkg" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.${SRCSUF##*.}" + continue fi fi - if test "${SRC#/}" = "$SRC" ; then - echo "$PKG $SRC" >>$BUILD_ROOT/.init_b_cache/rpmlist.download2 - else + cachedir="$(getcachedir "$SRC")" + if can_reuse_cached_package "$cachedir/$cachepkg" ; then SRCSUF=${SRC/%.pkg.tar.?z/.arch} - ln -s "$SRC" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.${SRCSUF##*.}" + ln -s "$cachedir/$cachepkg" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.${SRCSUF##*.}" + continue fi + # not found in cache or cache has different package + rm -f "$cachedir/$cachepkg" + echo "$PKG $SRC" >>$BUILD_ROOT/.init_b_cache/rpmlist.download2 done < $BUILD_ROOT/.init_b_cache/rpmlist.download rm -f $BUILD_ROOT/.init_b_cache/rpmlist.download test -s $BUILD_ROOT/.init_b_cache/rpmlist.download2 && mv $BUILD_ROOT/.init_b_cache/rpmlist.download2 $BUILD_ROOT/.init_b_cache/rpmlist.download @@ -822,7 +754,7 @@ else ln -s "$SRC" "$BUILD_ROOT/.init_b_cache/rpms/$PKG.${SRCSUF##*.}" done < $BUILD_ROOT/.init_b_cache/rpmlist.download rm -f $BUILD_ROOT/.init_b_cache/rpmlist.download - printf "\n" + echo fi # compatibility... @@ -830,19 +762,8 @@ else echo "$GUESSED_DIST" > $BUILD_ROOT/.guessed_dist test -n "$BUILD_DIST" || BUILD_DIST="$GUESSED_DIST" - PSUF=`gettype --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH"` - case "$PSUF" in - UNKNOWN|'') - # auto detect from packages - if test -n "$PREINSTALL_IMAGE" ; then - echo "cannot autodetect build type when using a preinstall image" >&2 - cleanup_and_exit 1 - fi - PSUF=rpm - test -e $BUILD_ROOT/.init_b_cache/rpms/dpkg.deb && PSUF=deb - test -e $BUILD_ROOT/.init_b_cache/rpms/pacman.arch && PSUF=arch - ;; - esac + + pkg_set_type if test -n "$PREINSTALL_IMAGE" ; then for PKG in $PACKAGES_FROM_PREINSTALLIMAGE ; do @@ -854,24 +775,12 @@ else fi # -# now test if there is already a build dir. +# test if we need to preinstall # -if test ! -f $BUILD_ROOT/var/lib/rpm/packages.rpm -a ! -f $BUILD_ROOT/var/lib/rpm/Packages -a ! -e $BUILD_ROOT/.build/init_buildsystem.data ; then - mkdir -p $BUILD_ROOT/var/lib/rpm || cleanup_and_exit 1 - mkdir -p $BUILD_ROOT/usr/src/packages/SOURCES || cleanup_and_exit 1 +if test ! -e $BUILD_ROOT/installed-pkg -a ! -e $BUILD_ROOT/.build/init_buildsystem.data ; then mkdir -p $BUILD_ROOT/etc || cleanup_and_exit 1 mkdir -p $BUILD_ROOT/proc || cleanup_and_exit 1 test -f $BUILD_ROOT/etc/HOSTNAME || hostname -f > $BUILD_ROOT/etc/HOSTNAME - if test $PSUF = deb ; then - mkdir -p $BUILD_ROOT/var/lib/dpkg - mkdir -p $BUILD_ROOT/var/log - mkdir -p $BUILD_ROOT/etc/default - :> $BUILD_ROOT/var/lib/dpkg/status - :> $BUILD_ROOT/var/lib/dpkg/available - :> $BUILD_ROOT/var/log/dpkg.log - :> $BUILD_ROOT/etc/ld.so.conf - :> $BUILD_ROOT/etc/default/rcS - fi for PKG in $PACKAGES_TO_RUNSCRIPTS ; do : > $BUILD_ROOT/.init_b_cache/scripts/$PKG.run done @@ -889,7 +798,7 @@ if test ! -f $BUILD_ROOT/var/lib/rpm/packages.rpm -a ! -f $BUILD_ROOT/var/lib/rp progress_step PACKAGES_TO_PREINSTALL_FILTERED preinstall ${PKG##*/} done - printf "\n" + echo if test -n "$PREPARE_VM" ; then PACKAGES_TO_VMINSTALL_FILTERED=`reorder $PACKAGES_TO_VMINSTALL_FILTERED` progress_setup PACKAGES_TO_VMINSTALL_FILTERED @@ -900,21 +809,24 @@ if test ! -f $BUILD_ROOT/var/lib/rpm/packages.rpm -a ! -f $BUILD_ROOT/var/lib/rp fi # for reorder check_exit - if [ -w /root ]; then - test -c $BUILD_ROOT/dev/null || create_devs + if test -w /root ; then + test -c $BUILD_ROOT/dev/null || create_devs fi test -e $BUILD_ROOT/etc/fstab || touch $BUILD_ROOT/etc/fstab test ! -e $BUILD_ROOT/etc/ld.so.conf -a -e $BUILD_ROOT/etc/ld.so.conf.in && cp $BUILD_ROOT/etc/ld.so.conf.in $BUILD_ROOT/etc/ld.so.conf if test -z "$PREPARE_VM" ; then run_pkg_scripts - init_db + pkg_initdb touch $BUILD_ROOT/.init_b_cache/preinstall_finished fi + # mark as preinstalled no longer needed + rm -rf "$BUILD_ROOT/installed-pkg" + mkdir -p "$BUILD_ROOT/installed-pkg" fi if test -n "$PREPARE_VM" ; then echo "copying packages..." - for PKG in $PACKAGES_TO_INSTALL ; do + for PKG in $PACKAGES_TO_ALL ; do rm -f $BUILD_ROOT/.init_b_cache/$PKG.$PSUF cp $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF $BUILD_ROOT/.init_b_cache/$PKG.$PSUF || cleanup_and_exit 1 ln -s -f ../$PKG.$PSUF $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF @@ -930,11 +842,13 @@ if test -n "$PREPARE_VM" ; then echo "PACKAGES_TO_RUNSCRIPTS='${PACKAGES_TO_RUNSCRIPTS//"'"/$Q}'" >> $BUILD_ROOT/.build/init_buildsystem.data # needed for continuation in xen/kvm with rpm-x86 echo "PACKAGES_TO_PREINSTALL='${PACKAGES_TO_PREINSTALL//"'"/$Q}'" >> $BUILD_ROOT/.build/init_buildsystem.data + echo "PACKAGES_TO_AVAILABLE='${PACKAGES_TO_AVAILABLE//"'"/$Q}'" >> $BUILD_ROOT/.build/init_buildsystem.data echo "PSUF='$PSUF'" >> $BUILD_ROOT/.build/init_buildsystem.data rm -f $BUILD_IS_RUNNING cleanup_and_exit 0 fi + mkdir -p $BUILD_ROOT/proc mkdir -p $BUILD_ROOT/dev/pts mount -n -tproc none $BUILD_ROOT/proc 2>/dev/null || true @@ -947,7 +861,7 @@ rm -rf "$BUILD_ROOT/.build.binaries" if test -n "$CREATE_BUILD_BINARIES" ; then echo "creating .build.binaries directory..." mkdir -p "$BUILD_ROOT/.build.binaries" - for PKG in $PACKAGES_TO_INSTALL ; do + for PKG in $PACKAGES_TO_AVAILABLE ; do test -L "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" || continue LPKG=`readlink -f "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF"` ln "$LPKG" "$BUILD_ROOT/.build.binaries/$PKG.$PSUF" 2>/dev/null @@ -958,18 +872,6 @@ if test -n "$CREATE_BUILD_BINARIES" ; then fi # -# get list and ids of already installed rpms -# -mkdir -p $BUILD_ROOT/.init_b_cache/alreadyinstalled -if test -f $BUILD_ROOT/var/lib/rpm/packages.rpm -o -f $BUILD_ROOT/var/lib/rpm/Packages ; then - chroot $BUILD_ROOT rpm -qa --qf "%{NAME} $RPMIDFMT" | ( - while read pp ii; do - echo "$ii" > "$BUILD_ROOT/.init_b_cache/alreadyinstalled/$pp" - done - ) -fi - -# # reorder packages (already done in vm continuation) # if ! test -e $BUILD_ROOT/.build/init_buildsystem.data ; then @@ -979,23 +881,18 @@ if ! test -e $BUILD_ROOT/.build/init_buildsystem.data ; then echo 'done' fi -rpm_e() -{ - chroot $BUILD_ROOT rpm --nodeps -e $PKG 2>&1 | \ - while read line; do - case "$line" in - - r*failed:\ No\ such\ file\ or\ directory) ;; - error:\ failed\ to\ stat\ *:\ No\ such\ file\ or\ directory) ;; - error:\ *scriptlet\ failed*) - echo "$line" - echo "re-try deleting $PKG using --noscripts" - chroot $BUILD_ROOT rpm --nodeps --noscripts -e $PKG || true - ;; - *) echo "$line" ;; - esac +# +# get list and ids of already installed packages +# +mkdir -p $BUILD_ROOT/.init_b_cache/alreadyinstalled +listinstalled --root "$BUILD_ROOT" --type "$PSUF" --extraname | ( + while read id name buildid; do + echo "$buildid" > "$BUILD_ROOT/.init_b_cache/alreadyinstalled/$name" done -} +) + +# do pre-installation work +pkg_prepare # # delete all packages we don't want @@ -1014,7 +911,7 @@ if [ -z "$KEEP_PACKS" ]; then PKG=${PKG##*/} test "$PKG" = "*" && continue echo "deleting $PKG" - rpm_e "$PKG" + pkg_erase check_exit done rm -rf "$BUILD_ROOT/.init_b_cache/todelete" @@ -1029,70 +926,14 @@ done rm -rf "$BUILD_ROOT/installed-pkg" mkdir -p "$BUILD_ROOT/installed-pkg" -RPMCHECKOPTS= -RPMCHECKOPTS_HOST= -# on Fedora 10 rpmbuild is in a separate package so we need something else to -# detect rpm4 -test -x $BUILD_ROOT/usr/bin/rpmquery && RPMCHECKOPTS="--nodigest --nosignature" -test -x /usr/bin/rpmquery && RPMCHECKOPTS_HOST="--nodigest --nosignature" - test -x $BUILD_ROOT/sbin/ldconfig && chroot $BUILD_ROOT /sbin/ldconfig 2>&1 -typeset -ri suse_version=$(chroot $BUILD_ROOT rpm --eval '%{?suse_version}' 2>/dev/null) -typeset -i num cumulate=-1 -typeset -a CUMULATED_LIST=() -typeset -a CUMULATED_PIDS=() -typeset -a CUMULATED_HMD5=() - -DO_CUMULATE= -if ((suse_version > 1220)) ; then - DO_CUMULATE=true -fi - MAIN_LIST="$PACKAGES_TO_INSTALL" -test -n "$DO_CUMULATE" && MAIN_LIST="$MAIN_LIST CUMULATED" progress_setup MAIN_LIST -for PKG in $MAIN_LIST; do +for PKG in $MAIN_LIST ; do test -f $BUILD_ROOT/installed-pkg/$PKG && continue progress_step MAIN_LIST - case $PKG in - CUMULATED) - # - # Use the features of rpm which are reordering the list of packages to - # satisfy dependencies and the final execution of the %posttrans scriplets - # - echo "now installing cumulated packages" - ((cumulate < 0)) && continue - exec 4>$BUILD_ROOT/.init_b_cache/manifest - for ((num=0; num<=cumulate; num++)) ; do - echo ${CUMULATED_LIST[$num]} 1>&4 - PKG=${CUMULATED_LIST[$num]##*/} - test "$BUILD_ROOT/.init_b_cache/rpms/$PKG" -ef "$BUILD_ROOT/${CUMULATED_LIST[$num]}" && continue - rm -f $BUILD_ROOT/${CUMULATED_LIST[$num]} - cp $BUILD_ROOT/.init_b_cache/rpms/$PKG $BUILD_ROOT/${CUMULATED_LIST[$num]} || cleanup_and_exit 1 - done - exec 4>&- - chroot $BUILD_ROOT rpm --ignorearch --nodeps -Uh --oldpackage --ignoresize --verbose $RPMCHECKOPTS \ - $ADDITIONAL_PARAMS .init_b_cache/manifest 2>&1 || touch $BUILD_ROOT/exit - for ((num=0; num<=cumulate; num++)) ; do - rm -f $BUILD_ROOT/${CUMULATED_LIST[$num]} - done - rm -f .init_b_cache/manifest - check_exit - for ((num=0; num<=cumulate; num++)) ; do - PKG=${CUMULATED_LIST[$num]##*/} - echo "${CUMULATED_PIDS[$num]}" > $BUILD_ROOT/installed-pkg/${PKG%.rpm} - test -n "${CUMULATED_HMD5[$num]}" || continue - echo "${CUMULATED_HMD5[$num]} ${CUMULATED_PIDS[$num]}" > $BUILD_ROOT/.preinstall_image/${PKG%.rpm} - done - CUMULATED_LIST=() - CUMULATED_PIDS=() - CUMULATED_HMD5=() - let cumulate=-1 - continue - ;; - esac if test -e "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" -a ! -s "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" ; then # preinstallimage package, make sure it's in the image if ! test -e $BUILD_ROOT/.preinstall_image/$PKG ; then @@ -1104,152 +945,84 @@ for PKG in $MAIN_LIST; do echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG continue fi - PKG_HDRMD5= - if test -d $BUILD_ROOT/.preinstall_image ; then - if ! test -e $BUILD_ROOT/.preinstall_image/$PKG ; then - PKG_HDRMD5=`perl -I$BUILD_DIR -MBuild -e 'print Build::queryhdrmd5($ARGV[0])' $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF` - test -n "$PKG_HDRMD5" || cleanup_and_exit 1 - fi - fi - test -L $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF || continue - if test $PSUF = deb ; then - # debian world, install deb files - if ! test "$BUILD_ROOT/.init_b_cache/rpms/$PKG.deb" -ef "$BUILD_ROOT/.init_b_cache/$PKG.deb" ; then - rm -f $BUILD_ROOT/.init_b_cache/$PKG.deb - cp $BUILD_ROOT/.init_b_cache/rpms/$PKG.deb $BUILD_ROOT/.init_b_cache/$PKG.deb || cleanup_and_exit 1 - fi - PKGID=`readlink $BUILD_ROOT/.init_b_cache/rpms/$PKG.deb` - PKGID="${PKGID##*/}" - PKGID="${PKGID%.deb} debian" - echo "installing ${PKGID%% *}" - ( chroot $BUILD_ROOT dpkg --install --force all .init_b_cache/$PKG.deb 2>&1 || touch $BUILD_ROOT/exit ) | \ - perl -ne '$|=1;/^(Configuration file|Installing new config file|Selecting previously deselected|\(Reading database|Unpacking |Setting up|Creating config file|Preparing to replace dpkg)/||/^$/||print' - check_exit - echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG - test -n "$PKG_HDRMD5" && echo "$PKG_HDRMD5 $PKGID" > $BUILD_ROOT/.preinstall_image/$PKG - # ugly workaround for upstart system. some packages (procps) try - # to start a service in their configure phase. As we don't have - # a running upstart, we just link the start binary to /bin/true - if test -e "$BUILD_ROOT/sbin/start"; then - if test "$BUILD_ROOT/sbin/start" -ef "$BUILD_ROOT/sbin/initctl" ; then - echo "linking /sbin/start to /bin/true" - mv "$BUILD_ROOT/sbin/start" "$BUILD_ROOT/sbin/start.disabled" - ln -s "/bin/true" "$BUILD_ROOT/sbin/start" - fi - fi - # another workaround, see bug bnc#733699 - rm -f "$BUILD_ROOT/var/run/init.upgraded" - continue + # get the hdrmd5 if we want to create a preinstall image + PKG_HDRMD5= + if test -d $BUILD_ROOT/.preinstall_image -a ! -e $BUILD_ROOT/.preinstall_image/$PKG ; then + PKG_HDRMD5=`perl -I$BUILD_DIR -MBuild -e 'print Build::queryhdrmd5($ARGV[0])' $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF` + test -n "$PKG_HDRMD5" || cleanup_and_exit 1 fi - if test $PSUF = arch ; then - if ! test "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" -ef "$BUILD_ROOT/.init_b_cache/$PKG.$PSUF" ; then - rm -f $BUILD_ROOT/.init_b_cache/$PKG.$PSUF - cp $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF $BUILD_ROOT/.init_b_cache/$PKG.$PSUF || cleanup_and_exit 1 - fi - PKGID=`readlink $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF` - PKGID="${PKGID##*/}" - PKGID="${PKGID/%.pkg.tar.?z/.arch}" - PKGID="${PKGID%.arch} arch" - echo "installing ${PKGID%% *}" - # -d -d disables deps checking - ( chroot $BUILD_ROOT pacman -U --force -d -d --noconfirm .init_b_cache/$PKG.$PSUF 2>&1 || touch $BUILD_ROOT/exit ) | \ - perl -ne '$|=1;/^(warning: could not get filesystem information for |loading packages|looking for inter-conflicts|Targets |Total Installed Size: |Net Upgrade Size: |Proceed with installation|checking package integrity|loading package files|checking available disk space|installing |upgrading |warning:.*is up to date -- reinstalling|Optional dependencies for| )/||/^$/||print' - check_exit - echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG - test -n "$PKG_HDRMD5" && echo "$PKG_HDRMD5 $PKGID" > $BUILD_ROOT/.preinstall_image/$PKG - continue - fi + test -L $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF || continue - if test -f $BUILD_ROOT/.init_b_cache/rpms/$PKG.id -a -f $BUILD_ROOT/.init_b_cache/alreadyinstalled/$PKG ; then + # check if we can keep an already installed package + if test "$VERIFY_BUILD_SYSTEM" != true -a -f $BUILD_ROOT/.init_b_cache/rpms/$PKG.id -a -f $BUILD_ROOT/.init_b_cache/alreadyinstalled/$PKG ; then read PKGID < $BUILD_ROOT/.init_b_cache/rpms/$PKG.id read OLDPKGID < $BUILD_ROOT/.init_b_cache/alreadyinstalled/$PKG if test "$PKGID" = "$OLDPKGID" ; then #echo "keeping ${PKGID%% *}" + rm -f $BUILD_ROOT/.init_b_cache/$PKG.$PSUF echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG test -n "$PKG_HDRMD5" && echo "$PKG_HDRMD5 $PKGID" > $BUILD_ROOT/.preinstall_image/$PKG continue fi fi - PKGID=`rpm -qp --qf "$RPMIDFMT" $RPMCHECKOPTS_HOST $BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm` + PKGID=$(perl -I$BUILD_DIR -MBuild -e Build::showquery "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" buildid) if test -f $BUILD_ROOT/.init_b_cache/alreadyinstalled/$PKG ; then read OLDPKGID < $BUILD_ROOT/.init_b_cache/alreadyinstalled/$PKG if test "$PKGID" != "$OLDPKGID" ; then - echo deleting unwanted ${OLDPKGID%% *} - rpm_e "$PKG" - elif test "$VERIFY_BUILD_SYSTEM" = true ; then - chroot $BUILD_ROOT rpm --verify $PKG 2>&1 | tee $TMPFILE - if grep ^missing $TMPFILE > /dev/null ; then - echo deleting incomplete ${PKGID%% *} - rpm_e "$PKG" - else + echo "deleting unwanted ${OLDPKGID%% *}" + pkg_erase + else + if test "$VERIFY_BUILD_SYSTEM" != true || pkg_verify_installed ; then #echo "keeping ${PKGID%% *}" echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG test -n "$PKG_HDRMD5" && echo "$PKG_HDRMD5 $PKGID" > $BUILD_ROOT/.preinstall_image/$PKG continue fi - else - #echo "keeping ${PKGID%% *}" - echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG - test -n "$PKG_HDRMD5" && echo "$PKG_HDRMD5 $PKGID" > $BUILD_ROOT/.preinstall_image/$PKG - continue + echo "deleting incomplete ${OLDPKGID%% *}" + pkg_erase fi if test -e "$BUILD_ROOT/.init_b_cache/preinstalls/$PKG" ; then preinstall "$PKG" - # call for rpm-4.x and not rpm-devel - test -z "${PKG##rpm-[0-9]*}" && chroot $BUILD_ROOT rpm --rebuilddb - # also exec for exchanged rpm ! naming is rpm-x86-<target>-<ver> - test -z "${PKG##rpm-x86-*[0-9]*}" && chroot $BUILD_ROOT rpm --rebuilddb fi + check_exit fi + export ADDITIONAL_PARAMS= if test "$USE_FORCE" = true ; then export ADDITIONAL_PARAMS="$ADDITIONAL_PARAMS --force" fi - # FIXME: work around for cross-build installs, we must not overwrite the running rpm + # work around for cross-build installs, we must not overwrite the running rpm if test "$PKG" = rpm ; then for i in $BUILD_ROOT/.init_b_cache/preinstalls/rpm-x86-* ; do test -e "$i" && ADDITIONAL_PARAMS="$ADDITIONAL_PARAMS --justdb" done fi - if test -n "$DO_CUMULATE" -a "$ADDITIONAL_PARAMS" = "${ADDITIONAL_PARAMS%--justdb}"; then + + if pkg_cumulate ; then echo "cumulate ${PKGID%% *}" - let cumulate++ - CUMULATED_LIST[$cumulate]=".init_b_cache/$PKG.rpm" - CUMULATED_PIDS[$cumulate]="$PKGID" - CUMULATED_HMD5[$cumulate]="$PKG_HDRMD5" continue fi + + # install the package echo "installing ${PKGID%% *}" - if ! test "$BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm" -ef "$BUILD_ROOT/.init_b_cache/$PKG.rpm" ; then - rm -f $BUILD_ROOT/.init_b_cache/$PKG.rpm - cp $BUILD_ROOT/.init_b_cache/rpms/$PKG.rpm $BUILD_ROOT/.init_b_cache/$PKG.rpm || cleanup_and_exit 1 + if ! test "$BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF" -ef "$BUILD_ROOT/.init_b_cache/$PKG.$PSUF" ; then + rm -f $BUILD_ROOT/.init_b_cache/$PKG.$PSUF + cp $BUILD_ROOT/.init_b_cache/rpms/$PKG.$PSUF $BUILD_ROOT/.init_b_cache/$PKG.$PSUF || cleanup_and_exit 1 fi - ( chroot $BUILD_ROOT rpm --ignorearch --nodeps -U --oldpackage --ignoresize $RPMCHECKOPTS \ - $ADDITIONAL_PARAMS .init_b_cache/$PKG.rpm 2>&1 || \ - touch $BUILD_ROOT/exit ) | \ - grep -v "^warning:.*saved as.*rpmorig$" - # delete link so package is only installed once - rm -f $BUILD_ROOT/.init_b_cache/$PKG.rpm + pkg_install check_exit + rm -f $BUILD_ROOT/.init_b_cache/$PKG.$PSUF echo "$PKGID" > $BUILD_ROOT/installed-pkg/$PKG test -n "$PKG_HDRMD5" && echo "$PKG_HDRMD5 $PKGID" > $BUILD_ROOT/.preinstall_image/$PKG done -if test $PSUF = deb ; then - echo "configuring all installed packages..." - # configure all packages after complete installation, not for each package like rpm does - # We need to run this twice, because of cyclic dependencies as it does not succeed on most - # debian based distros in the first attempt. - if ! chroot $BUILD_ROOT dpkg --configure --pending 2>&1; then - echo "first configure attempt failed, trying again..." - chroot $BUILD_ROOT dpkg --configure --pending 2>&1 || touch $BUILD_ROOT/exit - fi -fi +# do post-installation work +pkg_finalize # devices can vanish if devs got uninstalled test -c $BUILD_ROOT/dev/null || create_devs @@ -1264,73 +1037,22 @@ cp /proc/mounts $BUILD_ROOT/etc/mtab chmod 644 $BUILD_ROOT/etc/mtab # -# to be sure, path is set correctly, we have to source /etc/profile before -# starting rpm. -# -# XXX -#rm -f $BUILD_ROOT/bin/rpm.sh -#cp $BUILD_LIBDIR/lib/rpm.sh $BUILD_ROOT/bin/rpm.sh -#chmod 755 $BUILD_ROOT/bin/rpm.sh -#test -f $BUILD_ROOT/bin/rpm -a ! -L $BUILD_ROOT/bin/rpm && \ -# mv $BUILD_ROOT/bin/rpm $BUILD_ROOT/bin/rpm.bin -#rm -f $BUILD_ROOT/bin/rpm -#ln -s rpm.sh $BUILD_ROOT/bin/rpm - -# -# some packages use uname -r to decide which kernel is used to build for. -# this does not work in autobuild always. Here is a wrapper script, that -# gets Version from kernel sources. -# -# XXX -#rm -f $BUILD_ROOT/bin/uname.sh -#cp -v $BUILD_LIBDIR/lib/uname.sh $BUILD_ROOT/bin/uname.sh -#chmod 755 $BUILD_ROOT/bin/uname.sh -#test -f $BUILD_ROOT/bin/uname -a ! -L $BUILD_ROOT/bin/uname && \ -# mv $BUILD_ROOT/bin/uname $BUILD_ROOT/bin/uname.bin -#rm -f $BUILD_ROOT/bin/uname -#ln -s uname.sh $BUILD_ROOT/bin/uname - -# -# some distributions have a /etc/rpmrc or /etc/rpm/macros and some not. -# make sure, that it is setup correctly. -# -# XXX -#rm -f $BUILD_ROOT/etc/rpmrc -#if test -e $BUILD_LIBDIR/lib/rpmrc.$BUILD_BASENAME ; then -# cp -v $BUILD_LIBDIR/lib/rpmrc.$BUILD_BASENAME $BUILD_ROOT/etc/rpmrc -#elif test -e $BUILD_LIBDIR/lib/rpmrc ; then -# cp -v $BUILD_LIBDIR/lib/rpmrc $BUILD_ROOT/etc/rpmrc -#fi - -# XXX -#rm -f $BUILD_ROOT/etc/rpm/macros $BUILD_ROOT/etc/rpm/suse_macros -#mkdir -p $BUILD_ROOT/etc/rpm -#if test -e $BUILD_LIBDIR/lib/macros.$BUILD_BASENAME ; then -# cp -v $BUILD_LIBDIR/lib/macros.$BUILD_BASENAME $BUILD_ROOT/etc/rpm/macros -# cp -v $BUILD_LIBDIR/lib/macros.$BUILD_BASENAME $BUILD_ROOT/etc/rpm/suse_macros -#elif test -e $BUILD_LIBDIR/lib/macros ; then -# cp -v $BUILD_LIBDIR/lib/macros $BUILD_ROOT/etc/rpm/macros -# cp -v $BUILD_LIBDIR/lib/macros $BUILD_ROOT/etc/rpm/suse_macros -#fi - -# # make sure, that our nis is not present in the chroot system # test -e $BUILD_ROOT/etc/nsswitch.conf && { - echo removing nis flags from $BUILD_ROOT/etc/nsswitch.conf... - cat $BUILD_ROOT/etc/nsswitch.conf | sed -e"s:nis::g" > \ - $BUILD_ROOT/etc/nsswitch.conf.tmp + echo "removing nis flags from $BUILD_ROOT/etc/nsswitch.conf..." + cat $BUILD_ROOT/etc/nsswitch.conf | sed -e"s:nis::g" > $BUILD_ROOT/etc/nsswitch.conf.tmp mv $BUILD_ROOT/etc/nsswitch.conf.tmp $BUILD_ROOT/etc/nsswitch.conf } # -# creating some default directories +# create some default directories and files +# for DIR in /usr/share/doc/packages \ /usr/X11R6/include/X11/pixmaps \ /usr/X11R6/include/X11/bitmaps ; do mkdir -p $BUILD_ROOT/$DIR done - for FILE in /var/run/utmp /var/log/wtmp /etc/fstab ; do mkdir -p $BUILD_ROOT/${FILE%/*} touch $BUILD_ROOT/$FILE @@ -1341,24 +1063,26 @@ if test -x $BUILD_ROOT/sbin/ldconfig ; then CHROOT_RETURN="`chroot $BUILD_ROOT /sbin/ldconfig 2>&1`" case "$CHROOT_RETURN" in *warning:*) - chroot $BUILD_ROOT /sbin/ldconfig - echo - echo chroot $BUILD_ROOT /sbin/ldconfig - echo - echo "$CHROOT_RETURN" - echo - echo "Problem with ldconfig. It's better to reinit the build system..." - echo - cleanup_and_exit 1 - ;; + chroot $BUILD_ROOT /sbin/ldconfig + echo + echo chroot $BUILD_ROOT /sbin/ldconfig + echo + echo "$CHROOT_RETURN" + echo + echo "Problem with ldconfig. It's better to reinit the build system..." + echo + cleanup_and_exit 1 + ;; esac fi -if test -x $BUILD_ROOT/usr/sbin/Check && ! grep -q "/usr/sbin/Check is obsolete" $BUILD_ROOT/usr/sbin/Check; then - chroot $BUILD_ROOT /usr/sbin/Check + +if test -x $BUILD_ROOT/usr/sbin/Check && ! grep -q "/usr/sbin/Check is obsolete" $BUILD_ROOT/usr/sbin/Check ; then + chroot $BUILD_ROOT /usr/sbin/Check fi mkdir -p $BUILD_ROOT/var/adm/packages touch $BUILD_ROOT/var/adm/packages + if test -x $BUILD_ROOT/sbin/SuSEconfig ; then if grep norestarts $BUILD_ROOT/sbin/SuSEconfig > /dev/null ; then chroot $BUILD_ROOT /sbin/SuSEconfig --norestarts --force @@ -1378,7 +1102,7 @@ done if test -e $BUILD_ROOT/usr/share/zoneinfo/UTC ; then for PROG in /usr/sbin/zic /usr/bin/zic /bin/zic /sbin/zic ; do - test -x $BUILD_ROOT/$PROG && chroot $BUILD_ROOT $PROG -l UTC + test -x $BUILD_ROOT/$PROG && chroot $BUILD_ROOT bash -c "$PROG -l $(readlink -f /usr/share/zoneinfo/UTC)" done fi @@ -1392,26 +1116,17 @@ if ! grep -F "127.0.0.1 $HOST" $BUILD_ROOT/etc/hosts > /dev/null ; then mv $BUILD_ROOT/etc/hosts.new $BUILD_ROOT/etc/hosts fi +# XXX: still needed? if test -x $BUILD_ROOT/bin/rpm -a ! -f $BUILD_ROOT/var/lib/rpm/packages.rpm -a ! -f $BUILD_ROOT/var/lib/rpm/Packages ; then - echo "initializing rpm db..." - if [ -x $BUILD_ROOT/usr/bin/rpmdb ]; then - chroot $BUILD_ROOT /usr/bin/rpmdb --initdb || cleanup_and_exit 1 - else - chroot $BUILD_ROOT rpm --initdb || cleanup_and_exit 1 - fi - # create provides index - chroot $BUILD_ROOT rpm -q --whatprovides rpm >/dev/null 2>&1 + pkg_initdb_rpm + chroot $BUILD_ROOT rpm -q --whatprovides rpm >/dev/null 2>&1 # create provides index fi -# create modules.dep in kvm/xen -# This can not work, until we use the native repository kernel -#if [ $BUILD_ROOT = "/" -a -x /sbin/depmod ]; then -# /sbin/depmod -a -#fi - rm -f $BUILD_ROOT/.rpmmacros $BUILD_ROOT/root/.rpmmacros rm -rf "$BUILD_ROOT/.init_b_cache" rm -f $BUILD_IS_RUNNING rm -f $TMPFILE cleanup_and_exit 0 + +# vim: set tabstop=8 softtabstop=4 shiftwidth=4 noexpandtab: @@ -19,7 +19,22 @@ * build script to execute once binfmts are set up * * AUTHOR - * James Perkins <james.perkins@linuxfoundation.org> + * Copyright (c) 2012 James Perkins <james.perkins@linuxfoundation.org> + * i Adrian Schroeter <adrian@suse.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include <sys/mount.h> @@ -177,7 +192,7 @@ enum okfail binfmt_register(char *datafile, char *regfile) if (buf[0] != ':') /* non-data input line */ { - goto skip; + continue; } /* copy buf and tokenize :-seperated fields into f[] */ @@ -200,21 +215,41 @@ enum okfail binfmt_register(char *datafile, char *regfile) { fprintf(stderr, "%s: line %d: extra fields, ignoring." " Content: %s", datafile, line, buf); - goto skip; + continue; } if (n < n_fields) { fprintf(stderr, "%s: line %d: missing fields, ignoring." " Content: %s", datafile, line, buf); - goto skip; + continue; } + int ret; + /* Is an interpreter for this arch already registered? */ + snprintf(path, sizeof(path), SYSFS_BINFMT_MISC "/%s", f[name]); + ret=access(path, X_OK); + fprintf(stderr, + "interpreter for '%s' is %d\n", + f[name], ret); + if (ret == 0) { +#ifdef DEBUG + fprintf(stderr, + "interpreter for '%s' already registered, ignoring\n", + f[name]); +#endif /* DEBUG */ + continue; + } - if (access(f[interpreter], X_OK) != 0) { - fprintf(stderr, - "warning: %s: line %d: interpreter '%s' not " - "found\n", datafile, line, f[interpreter]); + /* Does the interpreter exists? */ + ret=access(f[interpreter], X_OK); + if (ret != 0) { +#ifdef DEBUG + fprintf(stderr, + "%s: line %d: interpreter '%s' not found," + " ignoring, return %d\n", datafile, line, f[interpreter], ret); +#endif /* DEBUG */ + continue; } if (!write_file_string(regfile, buf)) { @@ -237,9 +272,6 @@ enum okfail binfmt_register(char *datafile, char *regfile) DBG(fprintf(stderr, "dumping: %s\n", path)); DBG(dump_file(path)); - -skip: - ; } @@ -326,7 +358,7 @@ int main(int argc, char* argv[], char* env[]) exit(1); } execve(BUILD, args, env); - perror("execve"); + perror("execve of "BUILD); exit(1); } @@ -1,5 +1,25 @@ #!/usr/bin/perl +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + my $sig = 15; my $verbose = 0; my $msg = ''; diff --git a/listinstalled b/listinstalled new file mode 100755 index 0000000..aa09eac --- /dev/null +++ b/listinstalled @@ -0,0 +1,59 @@ +#!/usr/bin/perl -w + +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +BEGIN { + unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build'); +} + +use Getopt::Long; +use Build; + +use strict; + +Getopt::Long::Configure("no_ignore_case"); + +my $opt_root; +my $opt_type; +my $opt_extraname; + +GetOptions ("root=s" => \$opt_root, "type=s" => \$opt_type, "extraname" => \$opt_extraname) or exit(1); + +$opt_type ||= 'rpm'; + +my $ql = Build::queryinstalled($opt_type, $opt_root); +die("cannot get list of installed packages for type $opt_type\n") unless $ql; + +for my $q (@$ql) { + next unless defined($q->{'name'}) && defined($q->{'arch'}); + next if $q->{'arch'} eq 'src' || $q->{'arch'} eq 'nosrc'; + my $id = "$q->{'name'}.$q->{'arch'}-0/0/0: "; + my $evr = $q->{'version'}; + $evr = "$q->{'epoch'}:$evr" if $q->{'epoch'}; + $evr .= "-$q->{'release'}" if defined $q->{'release'}; + my $buildtime = $q->{'buildtime'} || 0; + if ($opt_extraname) { + print "I:$id$q->{'name'} $q->{'name'}-$evr $buildtime-$q->{'arch'}\n"; + } else { + print "I:$id$q->{'name'}-$evr $buildtime-$q->{'arch'}\n"; + } +} + diff --git a/livebuild_pre_run.template b/livebuild_pre_run.template new file mode 100755 index 0000000..679220c --- /dev/null +++ b/livebuild_pre_run.template @@ -0,0 +1,69 @@ +#!/bin/bash +# +# This is a template for a livebuild_pre_run script. These scripts are +# executed by build_livebuild.sh in the chroot environment. +# + +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +fix_debootstrap() +{ + # debootstrap in Debian 7.0 does not like dash + + if [ -x /usr/sbin/debootstrap ] ; then + sed -i 's|^#!/bin/sh|#!/bin/bash|' /usr/sbin/debootstrap + fi +} + +fix_lb_bootstrap_archive-keys() +{ + if [ -e /usr/lib/live/build/bootstrap_archive-keys ] ; then + sed -i '/apt-get update/{ s/^/#/ }' \ + /usr/lib/live/build/bootstrap_archive-keys + fi +} + +# +# main +# + +: ${TOPDIR:=/usr/src/packages} + +# Distribution and live-build specific hooks +fix_debootstrap +fix_lb_bootstrap_archive-keys + +# Expand configuration based on defaults +cd $TOPDIR/LIVEBUILD_ROOT && lb config || exit 1 + +# Replace all occurances of LB_MIRROR with local repository +sed -i "s|^\(LB_MIRROR_[^=]\+=\).*|\1\"file:$TOPDIR/SOURCES/repos/\"|" \ + $TOPDIR/LIVEBUILD_ROOT/config/bootstrap +sed -i "s|^\(LB_PARENT_MIRROR_[^=]\+=\).*|\1\"file:$TOPDIR/SOURCES/repos/\"|" \ + $TOPDIR/LIVEBUILD_ROOT/config/bootstrap + +# Prevent debootstrap from cleaning our cache +sed -i 's|^\(LB_CACHE_PACKAGES=\).*|\1"false"|' \ + $TOPDIR/LIVEBUILD_ROOT/config/common + +# Disable GPG checking +sed -i 's|^\(LB_APT_SECURE=\).*|\1"false"|' \ + $TOPDIR/LIVEBUILD_ROOT/config/common @@ -1,5 +1,25 @@ #!/usr/bin/perl -w +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + use POSIX; use strict; use File::Temp qw/tempfile tempdir/; @@ -529,8 +549,8 @@ sub handle_rpms { $arch = $res{'ARCH'}->[0]; my @targets = get_targets($arch, $config); if (!@targets) { - print "no targets for arch $arch, nothing to do\n"; - exit(0); + print "no targets for arch $arch, skipping $rname\n"; + next; } for my $target (@targets) { @@ -637,6 +657,7 @@ sub handle_rpms { delete $alldirs{"$prefix$fn"}; } } + delete $alldirs{$_} for keys %symlinks; $ad = $prefix; delete $alldirs{$ad}; delete $alldirs{$ad} while $ad =~ s/\/[^\/]+$//; @@ -965,8 +986,8 @@ sub handle_debs { # line and get a list of target_arch-es my @targets = get_targets($arch, $config); if (!@targets) { - print "no targets for arch $arch, nothing to do\n"; - return; # there may be more debs to handle + print "no targets for arch $arch, skipping $d_name\n"; + next; # there may be more debs to handle } for my $target (@targets) { @@ -1,5 +1,25 @@ #!/usr/bin/perl -w +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + BEGIN { unshift @INC, '/usr/lib/build'; unshift @INC, $::ENV{'BUILD_DIR'} if $::ENV{'BUILD_DIR'}; @@ -1,5 +1,25 @@ #!/usr/bin/perl -w +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + BEGIN { unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build'); } @@ -9,6 +29,7 @@ use strict; my ($dist, $archs, $configdir, $manifest); +$configdir = ($::ENV{'BUILD_DIR'} || '/usr/lib/build') . '/configs'; while (@ARGV) { if ($ARGV[0] eq '--dist') { @@ -65,7 +86,7 @@ for my $p (@p) { $q = {'provides' => [], 'requires' => []}; # package from preinstallimage, no need to order last; } - $q = Build::query("$cachedir/$p.$suf", 'filelist' => 1, 'alldeps' => 1); + $q = Build::query("$cachedir/$p.$suf", 'filelist' => 1, 'alldeps' => 1, 'addselfprovides' => 1, 'normalizedeps' => 1); die("bad binary: $p.$suf\n") unless $q; push @{$q->{'provides'}}, @{$q->{'filelist'}} if $suf eq 'rpm' && $q->{'filelist'}; delete $q->{'filelist'}; diff --git a/packaging/build.spec b/packaging/build.spec index 0aa9f48..5824f7b 100644 --- a/packaging/build.spec +++ b/packaging/build.spec @@ -19,12 +19,13 @@ Name: build Summary: A Script to Build SUSE Linux RPMs License: GPL-2.0+ and GPL-2.0 +Epoch: 1 Group: Development/Tools/Building Epoch: 1 %if 0%{?suse_version} >= 1230 -Version: 20150115 +Version: 20150115 %else -Version: 2015.01.15 +Version: 20150115 %else %endif Release: 3.1 @@ -72,7 +73,7 @@ Requires: build-mkbaselibs %if 0%{?suse_version} > 1120 || 0%{?mdkversion} Recommends: build-mkdrpms %endif -Provides: tizen-build = 20160315 +Provides: tizen-build = 20160311 %description This package provides a script for building RPMs for SUSE Linux in a chroot environment. @@ -116,7 +117,7 @@ Group: Development/Tools/Building Requires: build BuildRequires: gcc BuildRequires: glibc-devel -Provides: tizen-build-initvm-%{initvm_arch} = 20160315 +Provides: tizen-build-initvm-%{initvm_arch} = 20160311 Obsoletes: build-initvm %if 0%{?suse_version} BuildRequires: glibc-devel-static @@ -134,6 +135,7 @@ chroot or a secure virtualized %build # initvm make CFLAGS="$RPM_BUILD_FLAGS" initvm-all + %if 0%{?fedora} == 23 cp -f find-debuginfo.sh /usr/lib/rpm/find-debuginfo.sh %endif @@ -167,6 +169,8 @@ test -e default.conf /usr/lib/build %config(noreplace) /usr/lib/build/emulator/emulator.sh %{_mandir}/man1/build.1* +%{_mandir}/man1/unrpm.1* +%{_mandir}/man1/vc.1* %exclude /usr/lib/build/initvm.* %if 0%{?suse_version} > 1120 || ! 0%{?suse_version} @@ -191,6 +195,8 @@ test -e default.conf /usr/lib/build/initvm.* %changelog +* Mon Feb 29 2016 jiankang.fan@samsung.com +- update to version 2015.11.12 * Tue Sep 11 2012 qiang.z.zhang@intel.com - update to version 2012.09.11 * Sat Aug 11 2012 qiang.z.zhang@intel.com @@ -4,10 +4,13 @@ # NOTE: this requires a qemu with the binfmt misc handler binary +:aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-aarch64-binfmt:P :aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-arm64-binfmt:P :arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfa\xff\xff\xff:/usr/bin/qemu-arm-static: :armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb-binfmt:P :ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc-binfmt:P +:ppc64:M::i\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff::/usr/bin/qemu-ppc64-binfmt:P +:ppc64le:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff::/usr/bin/qemu-ppc64le-binfmt:P :mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips-binfmt:P :mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel-binfmt:P #:mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32-binfmt:P @@ -15,6 +18,6 @@ #:mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64-binfmt:P #:mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el-binfmt:P -:sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4-binfmt:P -:sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb-binfmt:P +:sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4-binfmt:P +:sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb-binfmt:P diff --git a/queryconfig b/queryconfig new file mode 100755 index 0000000..ea319a1 --- /dev/null +++ b/queryconfig @@ -0,0 +1,84 @@ +#!/usr/bin/perl -w + +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +BEGIN { + unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build'); +} + +use strict; + +use Build; + +my ($dist, $archs, $configdir, $type, $argument); + +$configdir = ($::ENV{'BUILD_DIR'} || '/usr/lib/build') . '/configs'; + +while (@ARGV) { + if ($ARGV[0] eq '--dist') { + shift @ARGV; + $dist = shift @ARGV; + next; + } elsif ($ARGV[0] eq '--archpath') { + shift @ARGV; + $archs = shift @ARGV; + next; + } elsif ($ARGV[0] eq '--configdir') { + shift @ARGV; + $configdir = shift @ARGV; + next; + } elsif (defined($type)) { + $argument = shift @ARGV; + } else { + $type = shift @ARGV; + } +} + +die("Please specify what to query\n") unless defined $type; + +my $cf = Build::read_config_dist($dist, $archs, $configdir); +die("Unable to read config\n") unless $cf; + +if ($type eq 'buildflags') { + die("Specify which buildflag to query\n") unless $argument; + my $result = $cf->{"buildflags:$argument"}; + print "$result\n" if defined $result; +} elsif ($type eq 'target' || $type eq 'type' || $type eq 'binarytype' || $type eq 'buildengine' || $type eq 'rawmacros') { + print "$cf->{$type}\n" if $cf->{$type}; +} elsif ($type eq 'optflags') { + exit(0) unless $cf->{'optflags'}; + my $all = $cf->{'optflags'}->{'*'}; + $all = defined($all) && $all ne '' ? " $all" : ''; + $all .= " -g" if $argument && $argument eq 'debug'; + for (sort keys %{$cf->{'optflags'}}) { + next if $_ eq '*'; + print "optflags: $_ $cf->{'optflags'}->{$_}$all\n"; + } +} elsif ($type eq 'substitute') { + die("Specify which substitute to query\n") unless $argument; + my @res = @{$cf->{'substitute'}->{$argument} || []}; + print join(' ', @res)."\n" if @res; +} else { + die("unsupported query type: $type\n"); +} + +exit(0); + @@ -1,5 +1,25 @@ #!/usr/bin/perl +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + # simple "sign" replacement that does nothing but # write a 2048 byte file with a fixed signature. # sign is used in kiwi builds to sign repositories diff --git a/spec2changelog b/spec2changelog index 4ac2b0a..a7bcf1e 100755 --- a/spec2changelog +++ b/spec2changelog @@ -6,10 +6,25 @@ # # Usage: cat foo.spec | spec2changes.pl > foo.changes # +################################################################ +# # Copyright 2009 by Pascal Bleser <pascal.bleser@opensuse.org> -# This script is licensed under the GNU General Public License version 2 -# http://www.gnu.org/licenses/gpl-2.0.html # +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ use warnings; use strict; diff --git a/spec_add_patch b/spec_add_patch index fd62753..7b7cf36 100755 --- a/spec_add_patch +++ b/spec_add_patch @@ -2,6 +2,26 @@ # vim:sw=4:et # Author: Dirk Mueller +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + use strict; sub helpexit { @@ -1,5 +1,25 @@ #!/usr/bin/perl -w +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + =head1 spectool spectool - tool to work with rpm spec files diff --git a/substitutedeps b/substitutedeps index efea76a..92f5dbc 100755 --- a/substitutedeps +++ b/substitutedeps @@ -1,5 +1,25 @@ #!/usr/bin/perl -w +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + BEGIN { unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build'); } @@ -19,6 +39,8 @@ sub expand { my ($dist, $buildroot, $rpmdeps, $archs, $configdir, $release, $changelog); +$configdir = ($::ENV{'BUILD_DIR'} || '/usr/lib/build') . '/configs'; + while (@ARGV) { if ($ARGV[0] eq '--root') { shift @ARGV; @@ -142,6 +164,37 @@ for my $line (@$xspec) { $line =~ s/<CI_CNT>/0/; $line =~ s/<B_CNT>/0/; } + + if ($cf->{'releasesuffix'}) { + my $suffix = $cf->{'releasesuffix'}; + if ($suffix =~ /^file:(.+)$/) { + my $file = $1; + if ($file =~ /\//s || $file =~ /^\./) { + $suffix = "error:illegal release suffix"; + } else { + if (open(RP, '<', "$specdir$file")) { + $suffix = "error:no suffix in $file"; + for (<RP>) { + chomp; + s/^\s+//; + s/\s+$//; + $suffix = $_ if $_ && !/^#/; + } + close RP; + } else { + $suffix = "error:$file file does not exist"; + } + } + } + if ($suffix =~ /^error:(.*)$/) { + $suffix = $1; + $suffix =~ s/^\s+//; + $suffix =~ s/\s+$//; + $suffix = "Error: $suffix"; + } + $line =~ s/^(Release\s*:\s*.*?)\s*$/$1$suffix/i if $suffix; + } + # this is to be compatible to legacy autobuild. # you can specify a releaseprg in the project configuration, # if your package contains this file it is executed and its diff --git a/t/bad.livebuild b/t/bad.livebuild Binary files differnew file mode 100644 index 0000000..ae2cae0 --- /dev/null +++ b/t/bad.livebuild diff --git a/t/directory.livebuild b/t/directory.livebuild Binary files differnew file mode 100644 index 0000000..318d128 --- /dev/null +++ b/t/directory.livebuild @@ -1,5 +1,25 @@ #!/usr/bin/perl -w +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + use strict; use Test::More tests => 9; use Build; diff --git a/t/live-build b/t/live-build new file mode 100755 index 0000000..1b20be0 --- /dev/null +++ b/t/live-build @@ -0,0 +1,72 @@ +#!/usr/bin/perl -w -I .. + +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + +use strict; +use Test::More tests => 5; +use Build::LiveBuild; + +use Data::Dumper; +use Digest::MD5 qw(md5_hex); + +my $VAR = ' + + +a + +b +#comment + +! whatever +'; + +is(Build::LiveBuild::filter($VAR), 'a +b +'); + + +my $DEB_ARCHIVE = ' +# comment +deb obs://openSUSE.org:Debian:7.0/standard wheezy main contrib +deb-src obs://openSUSE.org:Debian:7.0/standard wheezy main contrib + +'; +my $DEB_ARCHIVE_RESULT = "\$VAR1 = 'openSUSE.org:Debian:7.0/standard'; +"; + +is(Dumper(Build::LiveBuild::parse_archive($DEB_ARCHIVE)), $DEB_ARCHIVE_RESULT); + +my $config = {}; +$Data::Dumper::Sortkeys = 1; +is(md5_hex(Dumper(Build::LiveBuild::parse( $config, 'standard.livebuild'))), + '9cfb69e8f0581293f207342edacd19e7'); + +#print Dumper(Build::LiveBuild::parse( $config, 'standard.livebuild')); + +is(md5_hex(Dumper(Build::LiveBuild::parse( $config, 'directory.livebuild'))), + 'bc803d2b4a375d9a02b3242117f6c93a'); + +#print Dumper(Build::LiveBuild::parse( $config, 'directory.livebuild')); + +is(md5_hex(Dumper(Build::LiveBuild::parse( $config, 'bad.livebuild'))), + '1e596160978007d1014e9c5e38574700'); + +#print Dumper(Build::LiveBuild::parse( $config, 'bad.livebuild')); diff --git a/t/standard.livebuild b/t/standard.livebuild Binary files differnew file mode 100644 index 0000000..bd96fda --- /dev/null +++ b/t/standard.livebuild diff --git a/test/common b/test/common index 6c42210..45c0da2 100644 --- a/test/common +++ b/test/common @@ -22,6 +22,8 @@ if [ -e ${0%/*}/config.local ]; then . ${0%/*}/config.local fi +: ${BUILD_DIR:=/usr/lib/build} + #if [ ! -e "$build_vm_img" ]; then # sudo dd if=/dev/zero of="$build_vm_img" bs=512 count=0 seek=$((build_vm_image_size*2*1024)) #fi @@ -89,8 +91,10 @@ run_build() build_args+=("$i") fi done - set -- $linux32 sudo env \ - /usr/bin/build \ + SU_WRAPPER="" + [ -x /usr/bin/sudo ] && SU_WRAPPER="sudo env" + set -- $linux32 $SU_WRAPPER \ + $BUILD_DIR/build \ --root "${build_root}" \ "${repos[@]}" \ "${build_args[@]}" diff --git a/test/testbuild.sh b/test/testbuild.sh new file mode 100755 index 0000000..b81c929 --- /dev/null +++ b/test/testbuild.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# +# This is the generic test case for the current distribution, it +# is to be called from the spec file while building a build.rpm + +. ${0%/*}/common +REPO="$1" +shift + +if [ -z "$REPO" ]; then + echo "No local path to binary packages is given as argument" + exit 1 +fi + +[ "$ARCH" == "i386" ] && arch32bit + +repo "$REPO" + +run_build "$@" @@ -1,5 +1,25 @@ #!/bin/bash +################################################################ +# +# Copyright (c) 1995-2014 SUSE Linux Products GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or 3 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program (see the file COPYING); if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################################ + function Usage () { echo "Usage: $(basename $0) [-vq] rpm-files..."; echo "Unpack rpm files in current directory."; @@ -0,0 +1,17 @@ +.TH unrpm 1 "(c) 1997-2014 SuSE Linux AG Nuernberg, Germany" +.SH NAME +unrpm \- unpack the contents of one or more rpm files +.SH SYNOPSIS +.B unrpm +.RB [ -v ] +.RB [ -q ] +.I rpm +.RB ... + +.SH DESCRIPTION +The \fBunrpm\fP tool unpacks one or more rpm files into the +current directory. The \fB-v\fP option makes it print the filenames +while unpacking, whereas the \fB-q\fP option suppresses any output. + +.SH SEE ALSO +.BR rpm2cpio (8), @@ -8,7 +8,7 @@ # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 2 or 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, @@ -125,7 +125,7 @@ set +e echo fi if [ -n "$message" ]; then - echo "- $message" + echo -e "- $message" echo elif [ -n "$content" ]; then cat "$content" @@ -133,24 +133,6 @@ set +e elif [ ! $just_edit ]; then echo "- " echo - if [ -d .osc -a -n "$(which osc 2>/dev/null)" ]; then - OSC_STATUS="$(cd "$pkgpath" &> /dev/null; osc st)" - ADDED="$(sed -n 's/^A[[:blank:]]\+\([^[:blank:]].*\.\(patch\|diff\)\)$/ * \1/p' <<< "$OSC_STATUS")" - DELETED="$(sed -n 's/^D[[:blank:]]\+\([^[:blank:]].*\.\(patch\|diff\)\)$/ * \1/p' <<< "$OSC_STATUS")" - MODIFIED="$(sed -n 's/^M[[:blank:]]\+\([^[:blank:]].*\.\(patch\|diff\)\)$/ * \1/p' <<< "$OSC_STATUS")" - if [ -n "$ADDED" ]; then - echo "- added patches:" - echo "$ADDED" - fi - if [ -n "$DELETED" ]; then - echo "- removed patches:" - echo "$DELETED" - fi - if [ -n "$MODIFIED" ]; then - echo "- modified patches:" - echo "$MODIFIED" - fi - fi fi cat $changelog } >> "$tmpfile" @@ -166,5 +148,7 @@ if [ -z "$message" ]; then fi fi mode=`stat -c "%a" "$changelog"` +user=`stat -c "%u:%g" "$changelog"` mv "$tmpfile" "$changelog" chmod $mode "$changelog" +chown $user "$changelog" @@ -0,0 +1,25 @@ +.TH vc 1 "(c) 1997-2014 SuSE Linux AG Nuernberg, Germany" +.SH NAME +vs \- create a SUSE stype changes entry +.SH SYNOPSIS +.B vc +.RB [ -m +.IR message ] +.RB [ -e ] +.RI [ changesfile_or_dir +.RI [ commentfile ]] + +.SH DESCRIPTION +The \fBvc\fP tool adds a new changes entry to a SUSE \fB.changes\fP file. +The \fB-m\fP option can be used to directly specify the entry, if it is +not given an editor is started to interactively enter the new changes +entry. If a \fIcommentfile\fP is given, its content is used as template +for the new entry instead of an empty entry, whereas the \fB-e\fP option +suppresses the creation of an empty entry. + +If no \fIchangesfile\fP is specified, \fBvc\fP will search the current +directory for a file ending with \fB.changes\fP. If a directory is +specified instead of a changes will, it will be searched instead. + +.SH SEE ALSO +.BR build (1), |