mirror of
https://github.com/xcat2/xcat-dep.git
synced 2026-10-20 14:45:43 +00:00
fix(genesis): harden staged release publication
This commit is contained in:
+5
-12
@@ -120,12 +120,11 @@ command -v gpg >/dev/null 2>&1 \
|
||||
|| die "gpg not found. Install: sudo apt-get install gnupg"
|
||||
command -v cmp >/dev/null 2>&1 \
|
||||
|| die "cmp not found. Install: sudo apt-get install diffutils"
|
||||
command -v dpkg-deb >/dev/null 2>&1 \
|
||||
|| die "dpkg-deb not found. Install: sudo apt-get install dpkg"
|
||||
command -v sha256sum >/dev/null 2>&1 \
|
||||
|| die "sha256sum not found. Install: sudo apt-get install coreutils"
|
||||
|
||||
if [[ -n "$GENESIS_RELEASE" ]]; then
|
||||
command -v dpkg-deb >/dev/null 2>&1 \
|
||||
|| die "dpkg-deb not found. Install: sudo apt-get install dpkg"
|
||||
command -v sha256sum >/dev/null 2>&1 \
|
||||
|| die "sha256sum not found. Install: sudo apt-get install coreutils"
|
||||
GENESIS_CHECKSUMS=$(mktemp "${TMPDIR:-/tmp}/xcat-genesis-checksums.XXXXXX")
|
||||
cp -- "$GENESIS_RELEASE/SHA256SUMS" "$GENESIS_CHECKSUMS"
|
||||
"$GENESIS_VERIFIER" --complete --format deb "$GENESIS_RELEASE"
|
||||
@@ -198,12 +197,7 @@ copy_genesis_deb() {
|
||||
name=$(basename "$source")
|
||||
destination="$directory/$name"
|
||||
relative="deb/$name"
|
||||
if [[ -e "$destination" ]]; then
|
||||
cmp -s "$source" "$destination" \
|
||||
|| die "Package collision with different content: $destination"
|
||||
else
|
||||
cp -- "$source" "$destination"
|
||||
fi
|
||||
cp -- "$source" "$destination"
|
||||
expected=$(awk -v path="$relative" '$2 == path { print $1 }' "$GENESIS_CHECKSUMS")
|
||||
[[ -n "$expected" ]] || die "Missing verified checksum for $relative"
|
||||
actual=$(sha256sum "$destination")
|
||||
@@ -225,7 +219,6 @@ for ver in "${SELECTED_VERS[@]}"; do
|
||||
copy_deb "$deb" "$dst"
|
||||
done
|
||||
if [[ -n "$GENESIS_RELEASE" ]]; then
|
||||
rm -f -- "$dst"/xcat-genesis-openembedded-*.deb
|
||||
for deb in "$GENESIS_RELEASE"/deb/*.deb; do
|
||||
copy_genesis_deb "$deb" "$dst"
|
||||
done
|
||||
|
||||
@@ -112,7 +112,7 @@ sub _build_rpm {
|
||||
|
||||
my $archive = "$rpm_top/SOURCES/$source_name.tar.gz";
|
||||
_run(
|
||||
'tar', '--sort=name', '--owner=0', '--group=0',
|
||||
'tar', '--sort=name', '--owner=0', '--group=0', '--numeric-owner',
|
||||
"--mtime=\@$source_date_epoch", '--use-compress-program=gzip -n',
|
||||
'-cf', $archive, '-C', dirname($source_root), basename($source_root),
|
||||
);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
Name: xCAT-genesis-openembedded-%{genesis_arch}
|
||||
Version: %{?version}%{!?version:0}
|
||||
Release: %{?release}%{!?release:1}
|
||||
Epoch: 1
|
||||
Summary: xCAT OpenEmbedded Genesis netboot image
|
||||
License: Various
|
||||
URL: https://xcat.org/
|
||||
@@ -24,6 +23,7 @@ service actions before a node boots its installed operating system.
|
||||
rm -rf %{buildroot}
|
||||
install -d -m 0755 %{buildroot}/opt/xcat/share/xcat/netboot/genesis-openembedded/%{genesis_arch}
|
||||
install -m 0644 image/* %{buildroot}/opt/xcat/share/xcat/netboot/genesis-openembedded/%{genesis_arch}/
|
||||
# Keep this path stable across RPM build hosts. %%{_docdir} differs on SUSE.
|
||||
install -d -m 0755 %{buildroot}/usr/share/doc/%{name}
|
||||
install -m 0644 xcat-core-revision %{buildroot}/usr/share/doc/%{name}/
|
||||
|
||||
|
||||
@@ -61,14 +61,23 @@ sub _verify_rpm {
|
||||
my ($path, $expected_arch, $expected_source) = @{$package};
|
||||
my $metadata = _capture(
|
||||
'rpm', '-qp', '--qf',
|
||||
"%{NAME}\t%{VERSION}\t%{RELEASE}\t%{ARCH}\t%{EPOCHNUM}\t%{SOURCERPM}\n",
|
||||
"%{NAME}\t%{VERSION}\t%{RELEASE}\t%{ARCH}\t%{EPOCHNUM}\t%{SOURCERPM}"
|
||||
. "\t%{BUILDHOST}\t%{BUILDTIME}\n",
|
||||
$path,
|
||||
);
|
||||
my $expected = join(
|
||||
"\t", $name, $manifest->{xcat_version}, $manifest->{xcat_release},
|
||||
$expected_arch, '1', $expected_source,
|
||||
$expected_arch, '0', $expected_source, 'xcat-release',
|
||||
$manifest->{source_date_epoch},
|
||||
);
|
||||
die "Unexpected RPM identity for $path: $metadata\n" unless $metadata eq $expected;
|
||||
for my $relationship (qw(conflicts obsoletes)) {
|
||||
my $value = _capture('rpm', '-qp', "--$relationship", $path);
|
||||
die "Unexpected RPM $relationship for $path: $value\n" if $value ne '';
|
||||
}
|
||||
my $provides = _capture('rpm', '-qp', '--provides', $path);
|
||||
die "Legacy RPM relationship in $path: $provides\n"
|
||||
if $provides =~ /xCAT-genesis-base/;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +96,7 @@ sub _verify_deb {
|
||||
'all',
|
||||
);
|
||||
die "Unexpected DEB identity for $path: $metadata\n" unless $metadata eq $expected;
|
||||
for my $field (qw(Conflicts Replaces)) {
|
||||
for my $field (qw(Breaks Conflicts Provides Replaces)) {
|
||||
my $value = _capture('dpkg-deb', '-f', $path, $field);
|
||||
die "Unexpected DEB $field for $path: $value\n" if $value ne '';
|
||||
}
|
||||
|
||||
+36
-17
@@ -466,7 +466,6 @@ push @collect_roots, @extra_collect_dirs;
|
||||
my @srpm_collect_roots = (!$skip_xcat)
|
||||
? uniq(@collect_roots, $xcat_srpms_dir)
|
||||
: uniq(@collect_roots);
|
||||
@srpm_collect_roots = uniq(@srpm_collect_roots);
|
||||
|
||||
if ($genesis_release && !$dry_run) {
|
||||
remove_genesis_packages($repo_dir, 0);
|
||||
@@ -609,11 +608,21 @@ sub deploy_target {
|
||||
print_step("Deploy $tgt -> $dest");
|
||||
return if $dry_run;
|
||||
make_path($dest);
|
||||
remove_genesis_packages($dest, 0) if $genesis_release;
|
||||
for my $rpm (bsd_glob("$src/*.rpm")) {
|
||||
next if $rpm =~ /\.src\.rpm$/;
|
||||
copy($rpm, "$dest/" . basename($rpm))
|
||||
or die "Failed to copy $rpm -> $dest: $!\n";
|
||||
my $destination = "$dest/" . basename($rpm);
|
||||
my $temporary = "$destination.$$.new";
|
||||
die "Deployment staging file already exists: $temporary\n"
|
||||
if -e $temporary || -l $temporary;
|
||||
copy($rpm, $temporary)
|
||||
or die "Failed to stage $rpm -> $temporary: $!\n";
|
||||
rename($temporary, $destination)
|
||||
or die "Failed to publish $temporary -> $destination: $!\n";
|
||||
}
|
||||
if ($genesis_release) {
|
||||
my @keep = map { basename($_) } genesis_release_files('rpm');
|
||||
remove_genesis_packages($dest, 0, \@keep);
|
||||
verify_genesis_release_packages('rpm', $dest);
|
||||
}
|
||||
assert_required_deps($dest);
|
||||
sign_and_index_repo($dest);
|
||||
@@ -935,12 +944,14 @@ sub assert_required_deps {
|
||||
}
|
||||
|
||||
sub remove_genesis_packages {
|
||||
my ($directory, $source) = @_;
|
||||
my ($directory, $source, $keep_names) = @_;
|
||||
return unless -d $directory;
|
||||
my %keep = map { $_ => 1 } @{ $keep_names // [] };
|
||||
opendir(my $dh, $directory) or die "Cannot read $directory: $!\n";
|
||||
my @names = grep { /^xCAT-genesis-openembedded-.*\.rpm\z/ } readdir($dh);
|
||||
closedir($dh) or die "Cannot close $directory: $!\n";
|
||||
for my $name (@names) {
|
||||
next if $keep{$name};
|
||||
my $path = "$directory/$name";
|
||||
next if $source && $path !~ /\.src\.rpm\z/;
|
||||
next if !$source && $path =~ /\.src\.rpm\z/;
|
||||
@@ -953,11 +964,7 @@ sub install_genesis_release_packages {
|
||||
remove_genesis_packages($destination_root, $prefix eq 'srpm');
|
||||
|
||||
my $copied = 0;
|
||||
for my $relative (
|
||||
sort grep { /^\Q$prefix\E\/xCAT-genesis-openembedded-[^\/]+\.rpm\z/ }
|
||||
keys %{$genesis_release_checksums}
|
||||
)
|
||||
{
|
||||
for my $relative (genesis_release_files($prefix)) {
|
||||
my $source = "$genesis_release/$relative";
|
||||
my $destination = "$destination_root/" . basename($relative);
|
||||
copy($source, $destination)
|
||||
@@ -969,6 +976,24 @@ sub install_genesis_release_packages {
|
||||
return $copied;
|
||||
}
|
||||
|
||||
sub genesis_release_files {
|
||||
my ($prefix) = @_;
|
||||
return sort grep {
|
||||
/^\Q$prefix\E\/xCAT-genesis-openembedded-[^\/]+\.rpm\z/
|
||||
} keys %{$genesis_release_checksums};
|
||||
}
|
||||
|
||||
sub verify_genesis_release_packages {
|
||||
my ($prefix, $destination_root) = @_;
|
||||
my @files = genesis_release_files($prefix);
|
||||
die "Genesis release has no $prefix packages\n" unless @files;
|
||||
for my $relative (@files) {
|
||||
my $destination = "$destination_root/" . basename($relative);
|
||||
verify_release_file($genesis_release_checksums, $relative, $destination);
|
||||
}
|
||||
return scalar(@files);
|
||||
}
|
||||
|
||||
sub assert_genesis_release_copied {
|
||||
my ($binary_directory, $source_directory) = @_;
|
||||
for my $entry (
|
||||
@@ -976,13 +1001,7 @@ sub assert_genesis_release_copied {
|
||||
[ 'srpm', $source_directory ],
|
||||
) {
|
||||
my ($prefix, $destination_root) = @{$entry};
|
||||
for my $relative (
|
||||
sort grep { /^\Q$prefix\E\/[^\/]+\.rpm\z/ } keys %{$genesis_release_checksums}
|
||||
)
|
||||
{
|
||||
my $destination = "$destination_root/" . basename($relative);
|
||||
verify_release_file($genesis_release_checksums, $relative, $destination);
|
||||
}
|
||||
verify_genesis_release_packages($prefix, $destination_root);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user