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