mirror of
https://github.com/xcat2/xcat-dep.git
synced 2026-09-12 12:36:23 +00:00
fix(genesis): validate release manifests
This commit is contained in:
@@ -64,6 +64,11 @@ $xcat_source = abs_path($xcat_source) or die "Cannot resolve xcat-core source\n"
|
||||
for my $path (qw(Version xCAT-genesis-builder/oe/build xCAT-genesis-builder/oe/export)) {
|
||||
die "xcat-core source is missing $path\n" unless -f "$xcat_source/$path";
|
||||
}
|
||||
for my $architecture (@requested_architectures) {
|
||||
my $machine = "xCAT-genesis-builder/oe/kas/$architecture.yml";
|
||||
die "xcat-core source does not support Genesis architecture $architecture\n"
|
||||
unless -f "$xcat_source/$machine";
|
||||
}
|
||||
die "xcat-core checkout is not clean\n"
|
||||
if capture_command('git', '-C', $xcat_source, 'status', '--porcelain') ne '';
|
||||
|
||||
|
||||
@@ -178,9 +178,13 @@ sub _validate_release {
|
||||
unless $manifest->{source_date_epoch} =~ /^\d+$/;
|
||||
|
||||
my @architectures = split(/,/, $manifest->{architectures});
|
||||
my %version_architecture = map { $_ => 1 }
|
||||
@{ $RELEASE_ARCHITECTURES{ $manifest->{version} } };
|
||||
my %seen_arch;
|
||||
for my $architecture (@architectures) {
|
||||
validate_architecture($architecture);
|
||||
die "Genesis architecture $architecture is not valid in release version $manifest->{version}\n"
|
||||
unless $version_architecture{$architecture};
|
||||
die "Duplicate release architecture: $architecture\n" if $seen_arch{$architecture}++;
|
||||
}
|
||||
die "Release manifest has no architectures\n" unless @architectures;
|
||||
|
||||
+17
-7
@@ -33,8 +33,9 @@ use XCAT::BuildUtils qw(
|
||||
shell_quote
|
||||
);
|
||||
use XCAT::GenesisRelease qw(
|
||||
architectures
|
||||
read_release_manifest
|
||||
rpm_package_name
|
||||
validate_complete_release
|
||||
validated_release_checksums
|
||||
verify_release_file
|
||||
);
|
||||
@@ -373,11 +374,11 @@ if ($genesis_release ne '') {
|
||||
# before with the one taken after is what closes that window.
|
||||
my $checksums_before = validated_release_checksums($genesis_release);
|
||||
run_command($^X, $verifier, '--complete', '--format', 'rpm', $genesis_release);
|
||||
my $manifest = read_release_manifest($genesis_release);
|
||||
my $checksums_after = validated_release_checksums($genesis_release);
|
||||
die "Genesis release changed during verification\n"
|
||||
unless hashes_equal($checksums_before, $checksums_after);
|
||||
$genesis_release_checksums = $checksums_before;
|
||||
my $manifest = validate_complete_release($genesis_release);
|
||||
@genesis_release_architectures = split(/,/, $manifest->{architectures});
|
||||
}
|
||||
|
||||
@@ -1088,9 +1089,9 @@ sub publish_genesis_common_repo {
|
||||
|
||||
=head3 verify_common_repo
|
||||
|
||||
Assert the shared OpenEmbedded Genesis repository carries every package the manifest's [common]
|
||||
section requires, at a version satisfying its pin. [common] is not a build target: it describes
|
||||
the one repository published beside the per-EL cells, which no [<target>] section covers.
|
||||
Assert the shared OpenEmbedded Genesis repository carries every package declared by the
|
||||
verified release, at a version satisfying the [common] pin. [common] must describe every
|
||||
currently supported Genesis architecture.
|
||||
|
||||
Arguments:
|
||||
$dir - the repository to check (the staging directory, before it is swapped into place)
|
||||
@@ -1108,9 +1109,18 @@ sub verify_common_repo {
|
||||
die "FATAL: no [common] section in $manifest -- cannot verify the shared Genesis repository\n"
|
||||
if !%common;
|
||||
|
||||
my @supported_names = map { rpm_package_name($_) } architectures();
|
||||
my %supported = map { $_ => 1 } @supported_names;
|
||||
my @manifest_missing = grep { !exists($common{$_}) } @supported_names;
|
||||
my @manifest_unknown = grep { !$supported{$_} } sort keys %common;
|
||||
die "FATAL: [common] is missing supported packages: @manifest_missing\n"
|
||||
if @manifest_missing;
|
||||
die "FATAL: [common] has unsupported packages: @manifest_unknown\n"
|
||||
if @manifest_unknown;
|
||||
|
||||
die "FATAL: Genesis release has no architectures\n"
|
||||
unless @genesis_release_architectures;
|
||||
my @names = map { rpm_package_name($_) } @genesis_release_architectures;
|
||||
my @missing = grep { !exists($common{$_}) } @names;
|
||||
die "FATAL: [common] is missing release packages: @missing\n" if @missing;
|
||||
my %req = map { $_ => $common{$_} } @names;
|
||||
|
||||
@names = sort @names;
|
||||
|
||||
+21
-12
@@ -315,11 +315,11 @@ if ($genesis_release ne '') {
|
||||
require XCAT::GenesisRelease;
|
||||
my $before = XCAT::GenesisRelease::validated_release_checksums($genesis_release);
|
||||
XCAT::BuildUtils::run_command($^X, $verifier, '--complete', '--format', 'deb', $genesis_release);
|
||||
my $release_manifest = XCAT::GenesisRelease::read_release_manifest($genesis_release);
|
||||
my $after = XCAT::GenesisRelease::validated_release_checksums($genesis_release);
|
||||
die "FATAL: Genesis release changed during verification\n"
|
||||
unless XCAT::BuildUtils::hashes_equal($before, $after);
|
||||
$genesis_release_checksums = $before;
|
||||
my $release_manifest = XCAT::GenesisRelease::validate_complete_release($genesis_release);
|
||||
@genesis_release_architectures = split(/,/, $release_manifest->{architectures});
|
||||
# Every suite's Packages index points into the shared Genesis pool, and publishing a release
|
||||
# replaces that pool -- so a run that rebuilt only some suites would leave the others indexing
|
||||
@@ -1050,21 +1050,30 @@ sub install_genesis_release_debs {
|
||||
return scalar(@files);
|
||||
}
|
||||
|
||||
# verify_shared_pool($pool): assert the shared Genesis pool carries every package the manifest's
|
||||
# [shared] section requires, at a version satisfying its pin. [shared] is not a build target: it
|
||||
# describes the one pool every suite indexes, which no [<codename>-<arch>] section covers. Run on
|
||||
# the SIDE TREE, before it is swapped into place, so an incomplete pool is never published.
|
||||
# Completeness only -- the release checksums cover the bytes.
|
||||
# verify_shared_pool($pool): assert the pool carries every package declared by the verified release,
|
||||
# at a version satisfying the [shared] pin. [shared] must cover every supported Genesis architecture.
|
||||
sub verify_shared_pool {
|
||||
my ($pool) = @_;
|
||||
my %shared = %{ $MANIFEST{shared} // {} };
|
||||
die "FATAL: no [shared] section in $manifest -- cannot verify the shared Genesis pool\n"
|
||||
if !%shared;
|
||||
|
||||
my @supported_names = map {
|
||||
XCAT::GenesisRelease::deb_package_name($_)
|
||||
} XCAT::GenesisRelease::architectures();
|
||||
my %supported = map { $_ => 1 } @supported_names;
|
||||
my @manifest_missing = grep { !exists($shared{$_}) } @supported_names;
|
||||
my @manifest_unknown = grep { !$supported{$_} } sort keys %shared;
|
||||
die "FATAL: [shared] is missing supported packages: @manifest_missing\n"
|
||||
if @manifest_missing;
|
||||
die "FATAL: [shared] has unsupported packages: @manifest_unknown\n"
|
||||
if @manifest_unknown;
|
||||
|
||||
die "FATAL: Genesis release has no architectures\n"
|
||||
unless @genesis_release_architectures;
|
||||
my @names = map {
|
||||
XCAT::GenesisRelease::deb_package_name($_)
|
||||
} @genesis_release_architectures;
|
||||
my @missing = grep { !exists($shared{$_}) } @names;
|
||||
die "FATAL: [shared] is missing release packages: @missing\n" if @missing;
|
||||
my %req = map { $_ => $shared{$_} } @names;
|
||||
@names = sort @names;
|
||||
my %present = map { $_ => deb_version($pool, $_) } @names;
|
||||
@@ -1480,10 +1489,10 @@ Publish an B<OpenEmbedded Genesis package release> alongside the packages this r
|
||||
release is produced separately (see F<genesis-openembedded/README.md>); this option only verifies it
|
||||
and copies the verified bytes into every selected suite.
|
||||
|
||||
The release must be B<complete> (every supported Genesis architecture) and must carry C<deb>
|
||||
packages. It is validated before any build or publish: its C<SHA256SUMS> is read, the shared
|
||||
verifier runs, and the checksums are read again -- a release rewritten together with its checksums
|
||||
while the verifier runs is rejected.
|
||||
The release must be complete for its manifest version and must carry C<deb> packages. Version 1
|
||||
requires seven architectures; version 2 also requires C<s390x>. It is validated before any build or
|
||||
publish: its C<SHA256SUMS> is read, the shared verifier runs, and the checksums are read again -- a
|
||||
release rewritten together with its checksums while the verifier runs is rejected.
|
||||
|
||||
The packages are published B<once>, into F<pool/main/xcat-genesis-openembedded>, and every suite's
|
||||
C<Packages> index points at that one copy: they are C<Architecture: all> and identical everywhere,
|
||||
|
||||
Reference in New Issue
Block a user