#!/usr/bin/perl use strict; use warnings; my $USAGE = "Usage: $0 []\n"; BEGIN { (my $path = $0) =~ s/^(.*?)[^\/]*$/$1/; if ($path !~ /^\//) { $path = "$ENV{'PWD'}/$path"; } push @INC, "${path}lib"; $ENV{PATH} = "$ENV{PATH}:$path"; } use Getopt::Long; use SUSE::MyBS; my $api; my $verbose = 1; my $no_init; my $ignore_kabi; my $debuginfo; my $enable_checks; my $rebuild; my $submit; my @maintainers; my @limit_packages; my @package_links; GetOptions( "A|apiurl=s" => \$api, "i|ignore-kabi" => \$ignore_kabi, "no-init" => \$no_init, "c|enable-checks" => \$enable_checks, "d|debuginfo" => \$debuginfo, "r|rebuild" => \$rebuild, "s|submit" => \$submit, "maintainer=s" => \@maintainers, "flavor=s" => \@limit_packages, "q|quiet" => sub { $verbose = 0 }, "v|verbose" => \$verbose, "h|help" => sub { print $USAGE; exit }, ) or die($USAGE); if (scalar(@ARGV) < 2 || @ARGV > 3 || !-d $ARGV[0]) { die($USAGE); } my ($dir, $project, $package) = @ARGV[0..2]; $project =~ s/\//:/g; if (!$package) { ($package = $dir) =~ s:/+\.?$::; $package =~ s@.*/@@; if (! -e "$dir/$package.spec") { opendir(my $dh, $dir) or die; my @specfiles = sort grep { /\.spec$/ } readdir($dh); if (!@specfiles) { die "No specfiles found in $dir and no package name specified\n"; } closedir($dh); ($package = $specfiles[0]) =~ s/\.spec//; } } if (@limit_packages) { s/^kernel-// for @limit_packages; s/^/kernel-/ for @limit_packages; push(@limit_packages, $package); } my ($branch, $commit) = get_git_info($dir); if ($commit) { $commit = "commit $commit"; } else { print STDERR "warning: $dir does not look like a kernel package\n"; $commit = "."; } my $bs = SUSE::MyBS->new($api); # hack for SLE12-SP1-ARM my $BS_SUFFIX; my %repos = get_repos($dir, $api); die "Project not specified in config.sh\n" unless exists $repos{""}; my $qa; if (glob("$dir/kernel-obs-*.spec")) { $qa = 1; } my @archs = get_archs($dir); if (!scalar(@archs)) { warn "No ExclusiveArch: headers in $dir/*.spec\n"; } if (!@limit_packages && !$BS_SUFFIX) { # Include currently disabled flavors and archs my @all_archs; get_all_archs_flavors($dir, \@all_archs, \@package_links); push(@archs, @all_archs); s/^/kernel-/ for @package_links; } my @add_packages = (); my @macros = ("%is_kotd 1"); if ($ignore_kabi) { push(@macros, "%ignore_kabi_badness 1"); } if (-e "$dir/klp-symbols") { push(@macros, "%klp_symbols 1"); } my @remove_packages = qw(kernel-dummy); if (!$enable_checks) { push(@remove_packages, "post-build-checks", "rpmlint-Factory", "post-build-checks-malwarescan"); } my $prjconf = ""; if (!-e "$dir/_constraints") { my $need_gb = $debuginfo ? 14 : 4; my $need_gb_2 = $need_gb / 2; $prjconf = "\%ifarch \%ix86 x86_64 Constraint: hardware:processors 8 \%endif \%ifarch \%ix86 x86_64 ia64 ppc ppc64 ppc64le Constraint: hardware:disk:size unit=G $need_gb \%else Constraint: hardware:disk:size unit=G $need_gb_2 \%endif "; } my $prj; if ($no_init) { $prj = $project; } else { $prj = $bs->create_project($project, { repos => \%repos, title => "Kernel builds for " . ($branch ? "branch $branch" : $commit), build => 1, publish => 1, qa => $qa, debuginfo => $debuginfo, remove_packages => \@remove_packages, add_packages => \@add_packages, prjconf => $prjconf, macros => \@macros, limit_archs => \@archs, maintainers => \@maintainers, rebuild => $rebuild, }); } my $progress_cb; if ($verbose) { $progress_cb = \&progress_verbose; } else { $progress_cb = \&progress_silent; } my $rev = $bs->upload_package($dir, $prj, $package, $commit, { no_init => $no_init, progresscb => $progress_cb, remove_packages => [qw(kernel-dummy)], limit_packages => \@limit_packages, extra_links => \@package_links, }); if ($submit) { if (!exists($repos{""})) { die "No default submit target found in config.sh\n"; } if (!$rev) { exit 0; } &$progress_cb('SUBMIT', "$project/$package($rev)"); $bs->submit_package($project, $package, $rev, $repos{""}, $commit); } exit 0; sub progress_verbose { print join(" ", @_), "\n"; } sub progress_silent {}; sub get_git_info { my $dir = shift; my $file = "$dir/source-timestamp"; if (! -f $file) { $file = "$dir/build-source-timestamp" } if (! -f $file) { return; } open(my $fh, '<', $file) or die "$file: $!\n"; my ($branch, $commit); while (<$fh>) { chomp; if (s/^GIT Revision: //) { $commit = $_; } if (s/^GIT Branch: //) { $branch = $_; } } close($fh); return ($branch, $commit); } sub get_repos { my ($dir, $api) = @_; my $file = "$dir/config.sh"; my $want_ibs = ($api && $api =~ /\.suse\.de/); my (%obs, %ibs); open(my $fh, '<', $file) or die "$file: $!\n"; while (<$fh>) { chomp; if (/^BS_SUFFIX=(.*)/) { $BS_SUFFIX = $1; } next unless /^(OBS|IBS)_PROJECT(_\w+)?=(.*)/; my ($api, $repo, $project) = ($1, $2, $3); next unless $project; $repo ||= ""; $repo =~ s/^_//; if ($api eq "OBS") { $obs{$repo} = $project; if (!exists($ibs{$repo})) { $ibs{$repo} = "openSUSE.org:$project"; } } else { $ibs{$repo} = $project; } } close($fh); return %ibs if $want_ibs; return %obs; } sub bs_arch { my @res; for my $a (@_) { if ($a =~ /^%?i.86$/) { push(@res, "i586"); } elsif ($a =~ /^armv(\d)h?l/) { push (@res, "armv$1l", "armv$1hl"); } elsif ($a eq "arm64") { push (@res, "aarch64"); } else { push(@res, $a); } } return @res; } sub get_archs { my $dir = shift; my %archs; my %limit_specs; $limit_specs{"$_.spec"} = 1 for @limit_packages; opendir(my $dh, $dir) or return; while (my $de = readdir($dh)) { next unless $de =~ /\.spec$/; next unless !@limit_packages || $limit_specs{$de}; my $f = "$dir/$de"; my $fh; if (!open($fh, '<', "$f")) { warn "warning: could not open $f: $!\n"; next; } while (<$fh>) { chomp; next unless s/^exclusivearch://i; $archs{$_} = 1 for bs_arch(split); last; } close($fh); } return sort(keys(%archs)); } sub get_all_archs_flavors { my ($dir, $archs, $flavors) = @_; my (%archs, %flavors); my $pipe; return unless -e "$dir/config.conf"; if (!open($pipe, '-|', "guards", "--list", "--config", "$dir/config.conf")) { warn "error running guards: $!\n"; return; } while (<$pipe>) { chomp; my ($arch, $flavor) = split(/\//); $archs{$_} = 1 for bs_arch($arch); $flavors{$flavor} = 1; } if (!close($pipe)) { warn "guards returned an error\n"; } @$archs = sort(keys(%archs)); @$flavors = sort(keys(%flavors)); }