mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-10-21 07:08:12 +00:00
test(mknb): exercise compression and archive publication
This commit is contained in:
@@ -9,7 +9,7 @@ jobs:
|
||||
- name: Refresh package indexes
|
||||
run: sudo apt-get update
|
||||
- name: Install dependencies
|
||||
run: sudo env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends --no-install-suggests bats bubblewrap cpio gawk mawk rpm rsyslog build-essential fakeroot reprepro devscripts debhelper libcapture-tiny-perl libfile-slurper-perl libjson-perl libyaml-pp-perl libparallel-forkmanager-perl libsoap-lite-perl libdbi-perl libdbd-sqlite3-perl libcgi-pm-perl quilt openssh-server dpkg looptools genometools software-properties-common grub-common grub-efi-amd64-bin squashfs-tools pigz
|
||||
run: sudo env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends --no-install-suggests bats bubblewrap cpio xz-utils gzip gawk mawk rpm rsyslog build-essential fakeroot reprepro devscripts debhelper libcapture-tiny-perl libfile-slurper-perl libjson-perl libyaml-pp-perl libparallel-forkmanager-perl libsoap-lite-perl libdbi-perl libdbd-sqlite3-perl libcgi-pm-perl quilt openssh-server dpkg looptools genometools software-properties-common grub-common grub-efi-amd64-bin squashfs-tools pigz
|
||||
- name: Enable postscript test namespaces
|
||||
run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
|
||||
- name: Install lifecycle test dependencies
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/../../../perl-xCAT";
|
||||
use lib "$FindBin::Bin/../../../xCAT-server/lib/perl";
|
||||
use JSON qw(encode_json);
|
||||
|
||||
$ENV{XCATROOT} = "$FindBin::Bin/../../../xCAT-server";
|
||||
$ENV{XCATCFG} = '/tmp/fixture/config';
|
||||
my $plugin = "$FindBin::Bin/../../../xCAT-server/lib/xcat/plugins/mknb.pm";
|
||||
require $plugin;
|
||||
$::XCATROOT = '/tmp/fixture/source';
|
||||
|
||||
no warnings qw(redefine once);
|
||||
local *xCAT::TableUtils::getTftpDir = sub { return '/tmp/fixture/tftp'; };
|
||||
local *xCAT::TableUtils::get_site_attribute = sub { return; };
|
||||
local *xCAT::NetworkUtils::my_nets = sub { return {}; };
|
||||
local *xCAT::NetworkUtils::my_hexnets = sub { return {}; };
|
||||
|
||||
my @responses;
|
||||
umask oct($ARGV[0]);
|
||||
xCAT_plugin::mknb::process_request(
|
||||
{ arg => ['x86_64'] }, sub { push @responses, @_; },
|
||||
);
|
||||
print encode_json(\@responses), "\n";
|
||||
exit((grep { $_->{error} || $_->{errorcode} } @responses) ? 1 : 0);
|
||||
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup()
|
||||
{
|
||||
[ "$(uname -s)" = Linux ] || skip 'Genesis compression requires Linux namespaces'
|
||||
fixture="$BATS_TEST_TMPDIR/build"
|
||||
[ -n "$BATS_TEST_TMPDIR" ] || return 1
|
||||
mkdir -p "$fixture"/{source/share/xcat/netboot/genesis/x86_64/fs,root/.ssh,etc/xcat,config,tftp,bin,unpacked}
|
||||
printf 'fixture payload\n' > "$fixture/source/share/xcat/netboot/genesis/x86_64/fs/payload"
|
||||
printf 'fixture kernel\n' > "$fixture/source/share/xcat/netboot/genesis/x86_64/kernel"
|
||||
printf 'fixture public key\n' > "$fixture/root/.ssh/id_rsa.pub"
|
||||
}
|
||||
|
||||
build_image()
|
||||
{
|
||||
bwrap --die-with-parent --unshare-net --ro-bind / / --dev /dev --proc /proc \
|
||||
--tmpfs /tmp --ro-bind "$BATS_TEST_DIRNAME/../.." /tmp/source \
|
||||
--bind "$fixture" /tmp/fixture --bind "$fixture/root" /root \
|
||||
--bind "$fixture/etc" /etc --chdir /tmp/fixture \
|
||||
--setenv PATH /tmp/fixture/bin:/usr/bin:/bin \
|
||||
perl /tmp/source/xCAT-test/bats/fixtures/mknb-compress.pl "$1"
|
||||
}
|
||||
|
||||
check_payload()
|
||||
{
|
||||
local image="$1" compression="$2" mode="$3"
|
||||
[ "$(stat -c '%a' "$image")" = "$mode" ]
|
||||
(cd "$fixture/unpacked" && "$compression" -dc "$image" | cpio -id)
|
||||
[ "$(cat "$fixture/unpacked/payload")" = 'fixture payload' ]
|
||||
[ "$(cat "$fixture/unpacked/.ssh/authorized_keys")" = 'fixture public key' ]
|
||||
[ "$(stat -c '%a' "$fixture/unpacked/.ssh/authorized_keys")" = 600 ]
|
||||
[ "$(cat "$fixture/tftp/xcat/genesis.kernel.x86_64")" = 'fixture kernel' ]
|
||||
[ "$(find "$fixture/tftp/xcat" -maxdepth 1 -type f | wc -l)" -eq 2 ]
|
||||
}
|
||||
|
||||
@test "mknb publishes a complete LZMA image with the caller's umask" {
|
||||
run build_image 022
|
||||
[ "$status" -eq 0 ] || { printf '%s\n' "$output"; return 1; }
|
||||
check_payload "$fixture/tftp/xcat/genesis.fs.x86_64.lzma" xz 644
|
||||
}
|
||||
|
||||
@test "mknb falls back to gzip and removes the failed LZMA staging file" {
|
||||
printf '#!/bin/sh\nprintf partial\nexit 42\n' > "$fixture/bin/lzma"
|
||||
cp "$fixture/bin/lzma" "$fixture/bin/xz"
|
||||
chmod +x "$fixture/bin/lzma" "$fixture/bin/xz"
|
||||
run build_image 027
|
||||
[ "$status" -eq 0 ] || { printf '%s\n' "$output"; return 1; }
|
||||
[[ "$output" == *'failed, falling back to gzip'* ]]
|
||||
check_payload "$fixture/tftp/xcat/genesis.fs.x86_64.gz" gzip 640
|
||||
}
|
||||
@@ -1,54 +1,45 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use File::Spec;
|
||||
use lib "$FindBin::Bin/../lib";
|
||||
use lib "$FindBin::Bin/../../perl-xCAT";
|
||||
use lib "$FindBin::Bin/../../xCAT-server/lib/perl";
|
||||
use File::Path qw(make_path);
|
||||
use File::Temp qw(tempdir);
|
||||
use File::Slurper qw(read_binary write_text);
|
||||
use Test::More;
|
||||
use XCAT::Test::File qw(repo_path);
|
||||
|
||||
my $plugin = File::Spec->catfile( $FindBin::Bin, '..', '..',
|
||||
'xCAT-server', 'lib', 'xcat', 'plugins', 'mknb.pm' );
|
||||
plan skip_all => 'mknb.pm not found' unless -r $plugin;
|
||||
my $root = tempdir(CLEANUP => 1);
|
||||
$ENV{XCATROOT} = repo_path('xCAT-server');
|
||||
$ENV{XCATCFG} = "$root/config";
|
||||
make_path($ENV{XCATCFG});
|
||||
require(repo_path('xCAT-server/lib/xcat/plugins/mknb.pm'));
|
||||
|
||||
open( my $fh, '<', $plugin ) or die "Unable to read $plugin: $!";
|
||||
my $source = do { local $/; <$fh> };
|
||||
close($fh);
|
||||
# xz supports the lzma invocation name even where the distribution omits that link.
|
||||
symlink('/usr/bin/xz', "$root/lzma") or die "create lzma alias: $!";
|
||||
local $ENV{PATH} = "$root:$ENV{PATH}";
|
||||
|
||||
# mknb.pm needs a management node to load, so lift the routine out and drive
|
||||
# the real code on its own.
|
||||
my ($routine) = $source =~ /(sub genesis_lzma_command \{.*?\n\}\n)/s;
|
||||
BAIL_OUT('could not extract genesis_lzma_command from mknb.pm') unless $routine;
|
||||
eval "package MknbCompressor; $routine 1;" or BAIL_OUT("could not evaluate: $@");
|
||||
write_text("$root/payload", "Genesis payload\n");
|
||||
is(system("cd '$root' && printf 'payload\\n' | cpio -o -H newc > archive.cpio"), 0,
|
||||
'builds an actual newc archive');
|
||||
my $archive = read_binary("$root/archive.cpio");
|
||||
like($archive, qr/^070701/, 'fixture is a newc archive');
|
||||
|
||||
sub command { return MknbCompressor::genesis_lzma_command(@_); }
|
||||
|
||||
# Debian and Ubuntu ship both names, and lzma is the one the plugin has always
|
||||
# used, so nothing changes on those systems.
|
||||
is( command( 1, 1 ), 'lzma -C crc32 -9', 'lzma is used when it is there' );
|
||||
|
||||
# Red Hat ships xz alone.
|
||||
is( command( 0, 1 ), 'xz --format=lzma -C crc32 -9',
|
||||
'xz stands in for lzma when only xz is there' );
|
||||
|
||||
# The gzip path below the caller handles a system with neither.
|
||||
is( command( 0, 0 ), undef, 'nothing is returned when neither program is there' );
|
||||
|
||||
# The container has to stay the one the file name promises. "xz" on its own
|
||||
# writes the xz container, which the file name does not describe and which a
|
||||
# reader of a .lzma file cannot open.
|
||||
my ($xz_form) = command( 0, 1 ) =~ /--format=(\S+)/;
|
||||
is( $xz_form, 'lzma', 'xz is asked for the lzma container, not its own' );
|
||||
|
||||
# The caller has to take the command from the routine, and the name of the
|
||||
# written file must not change with it.
|
||||
like( $source, qr/genesis_lzma_command\(-x "\/usr\/bin\/lzma", -x "\/usr\/bin\/xz"\)/,
|
||||
'the caller asks the routine which program to run' );
|
||||
like( $source, qr/cpio -o -H newc \| \$lzma_command > \$tftpdir\/xcat\/genesis\.fs\.\$arch\.lzma\.\$suffix/,
|
||||
'the chosen command writes the same file under the same suffix' );
|
||||
|
||||
# The fallback to gzip and the atomic rename both have to survive.
|
||||
like( $source, qr/falling back to gzip/, 'the gzip fallback is still reported' );
|
||||
like( $source, qr/move\("\$tftpdir\/xcat\/genesis\.fs\.\$arch\.lzma\.\$suffix"/,
|
||||
'the finished image is still renamed into place' );
|
||||
for my $case ([1, 1, 'lzma'], [1, 0, 'lzma'], [0, 1, 'xz']) {
|
||||
my ($lzma, $xz, $name) = @$case;
|
||||
subtest "$name with lzma=$lzma xz=$xz" => sub {
|
||||
my $command = xCAT_plugin::mknb::genesis_lzma_command($lzma, $xz);
|
||||
like($command, qr/^\Q$name\E /, 'selects the available compressor');
|
||||
is(system("$command < '$root/archive.cpio' > '$root/archive.lzma'"), 0,
|
||||
'selected command compresses the archive');
|
||||
is(system("xz --format=lzma -dc '$root/archive.lzma' > '$root/decoded.cpio'"), 0,
|
||||
'output has the promised LZMA container');
|
||||
is(read_binary("$root/decoded.cpio"), $archive, 'decompression preserves every archive byte');
|
||||
};
|
||||
}
|
||||
is(xCAT_plugin::mknb::genesis_lzma_command(0, 0), undef,
|
||||
'no LZMA command is selected when neither compressor is available');
|
||||
|
||||
done_testing();
|
||||
|
||||
Reference in New Issue
Block a user