2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-10-02 17:02:17 +00:00
Files
xcat-core/xCAT-test/unit/syslog_openeuler_chroot.t
T
2026-09-15 00:33:39 -03:00

117 lines
5.8 KiB
Perl

#!/usr/bin/env perl
use strict;
use warnings;
use Cwd qw(abs_path);
use File::Copy qw(copy);
use File::Path qw(make_path);
use File::Temp qw(tempdir);
use FindBin;
use Test::More;
plan skip_all => 'requires Linux root and mount/network namespaces' unless $^O eq 'linux' && $> == 0;
plan skip_all => 'namespaces unavailable' if system('unshare -mn -- true >/dev/null 2>&1');
plan skip_all => 'requires native rsyslogd, systemctl, systemd-detect-virt and chroot'
if system('command -v rsyslogd systemctl systemd-detect-virt chroot >/dev/null');
my $source = $ENV{XCAT_SYSLOG_SOURCE_ROOT} || abs_path("$FindBin::Bin/../..");
my $tmp = tempdir(DIR => '/var/tmp', CLEANUP => !$ENV{XCAT_SYSLOG_KEEP});
diag("fixtures: $tmp") if $ENV{XCAT_SYSLOG_KEEP};
make_path("$tmp/bin");
sub write_file {
my ($path, $text) = @_;
open(my $fh, '>', $path) or die "$path: $!";
print {$fh} $text;
close($fh) or die "$path: $!";
}
sub read_file {
my ($path) = @_;
return '' unless -f $path;
open(my $fh, '<', $path) or die "$path: $!";
local $/;
return <$fh> // '';
}
for my $name (qw(syslog xcatlib.sh)) {
copy("$source/xCAT/postscripts/$name", "$tmp/bin/$name") or die $!;
}
write_file("$tmp/bin/systemctl", <<'SH');
#!/bin/bash
printf '%s\n' "$*" >> "/evidence/services-$XCAT_SYSLOG_PHASE.log"
/usr/bin/systemctl "$@" > "/evidence/systemctl-$XCAT_SYSLOG_PHASE.log" 2>&1
rc=$?
echo "$rc" > "/evidence/systemctl-$XCAT_SYSLOG_PHASE.rc"
cat "/evidence/systemctl-$XCAT_SYSLOG_PHASE.log"
exit "$rc"
SH
write_file("$tmp/bin/logger", <<'SH');
#!/bin/bash
printf '%s\n' "$*" >> /evidence/logger.log
SH
write_file("$tmp/bin/run", <<'SH');
#!/bin/bash
set -eu
mount --make-rprivate /
root="$XCAT_SYSLOG_FIXTURE/root"
for path in usr bin sbin lib lib64; do
[ -d "/$path" ] || continue
mount --bind "/$path" "$root/$path"
mount -o remount,bind,ro "$root/$path"
done
mount --bind "$XCAT_SYSLOG_BIN" "$root/postscripts"
mount -o remount,bind,ro "$root/postscripts"
mount --bind "$XCAT_SYSLOG_FIXTURE/evidence" "$root/evidence"
mount -t proc -o ro proc "$root/proc"
mount -t tmpfs -o mode=755,nosuid tmpfs "$root/dev"
touch "$root/dev/null"
mount --bind /dev/null "$root/dev/null"
set +e
chroot "$root" /usr/bin/systemd-detect-virt --quiet --chroot > "$XCAT_SYSLOG_FIXTURE/evidence/detect.log" 2>&1
echo "$?" > "$XCAT_SYSLOG_FIXTURE/evidence/detect.rc"
chroot "$root" /usr/bin/env PATH=/postscripts:/usr/sbin:/usr/bin:/sbin:/bin XCAT_SYSLOG_PHASE=baseline \
/bin/bash -c '. /postscripts/xcatlib.sh; restartservice syslog' > "$XCAT_SYSLOG_FIXTURE/evidence/helper.log" 2>&1
echo "$?" > "$XCAT_SYSLOG_FIXTURE/evidence/helper.rc"
for pass in 1 2; do
chroot "$root" /usr/bin/env PATH=/postscripts:/usr/sbin:/usr/bin:/sbin:/bin XCAT_SYSLOG_PHASE=postscript \
/bin/bash /postscripts/syslog > "$XCAT_SYSLOG_FIXTURE/evidence/postscript-$pass.log" 2>&1
rc=$?
echo "$rc" > "$XCAT_SYSLOG_FIXTURE/evidence/postscript-$pass.rc"
[ "$rc" -eq 0 ] || break
done
chroot "$root" /usr/sbin/rsyslogd -N1 -f /etc/rsyslog.conf > "$XCAT_SYSLOG_FIXTURE/evidence/parser.log" 2>&1
echo "$?" > "$XCAT_SYSLOG_FIXTURE/evidence/parser.rc"
exit 0
SH
chmod 0755, "$tmp/bin/$_" for qw(systemctl logger run);
my $minimal = "global(workDirectory=\"/var/lib/rsyslog\")\ninclude(file=\"/etc/rsyslog.d/*.conf\" mode=\"optional\")\n*.info /var/log/messages\n";
for my $case (['mn', 0], ['snlocal', 0], ['snforward', 0], ['cn', 0], ['mn', 1], ['cn', 1]) {
my ($role, $invalid) = @$case;
my $name = "$role " . ($invalid ? 'invalid' : 'valid') . ' native chroot';
my $fixture = "$tmp/$role-$invalid";
make_path("$fixture/evidence", map { "$fixture/root/$_" }
qw(usr bin sbin lib lib64 postscripts evidence proc dev run tmp etc/rsyslog.d var/log var/lib/rsyslog));
copy('/etc/ld.so.cache', "$fixture/root/etc/ld.so.cache") or die $!;
write_file("$fixture/root/etc/os-release", "ID=openEuler\n");
write_file("$fixture/root/etc/xCATMN", '') if $role eq 'mn';
write_file("$fixture/root/etc/rsyslog.conf", $minimal . ($invalid ? "invalid_rsyslog_directive()\n" : ''));
local %ENV = (%ENV, XCAT_SYSLOG_FIXTURE => $fixture, XCAT_SYSLOG_BIN => "$tmp/bin",
OSVER => ($ENV{XCAT_SYSLOG_OSVER} || 'openeuler24.03'), NTYPE => ($role =~ /^sn/ ? 'service' : 'compute'),
SVLOGLOCAL => ($role eq 'snlocal' ? 1 : 0), MASTER => '127.0.0.1:1514', SYSLOG => '');
is(system('unshare', '-mn', '--', "$tmp/bin/run"), 0, "$name: isolated driver completed");
my $evidence = "$fixture/evidence";
is(read_file("$evidence/detect.rc"), "0\n", "$name: native helper detects the actual chroot");
is(read_file("$evidence/systemctl-baseline.rc"), "0\n", "$name: actual systemctl defers successfully");
like(read_file("$evidence/systemctl-baseline.log"), qr/Running in chroot,\s*ignoring/i,
"$name: native systemctl identifies service deferral");
is(read_file("$evidence/helper.rc"), "1\n", "$name: shared restart helper retains its existing contract");
is(read_file("$evidence/services-postscript.log"), '', "$name: postscript does not attempt service activation");
if ($invalid) {
isnt(read_file("$evidence/postscript-1.rc"), "0\n", "$name: parser failure reaches the postscript exit");
isnt(read_file("$evidence/parser.rc"), "0\n", "$name: actual native parser rejects the configuration");
is(read_file("$evidence/logger.log"), '', "$name: no success log follows invalid configuration");
} else {
is(read_file("$evidence/postscript-1.rc"), "0\n", "$name: configuration completes successfully");
is(read_file("$evidence/postscript-2.rc"), "0\n", "$name: repeated configuration succeeds");
is(read_file("$evidence/parser.rc"), "0\n", "$name: actual native parser accepts the result");
like(read_file("$evidence/logger.log"), qr/rsyslog version 8 setup/, "$name: completed configuration is logged");
}
}
done_testing();