2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-26 09:44:03 +00:00

feat(genesis): activate installed OpenEmbedded images

This commit is contained in:
Vinícius Ferrão
2026-08-24 20:14:32 -03:00
parent 735951fefe
commit 4457efbd1b
2 changed files with 91 additions and 28 deletions
+50 -18
View File
@@ -9,6 +9,8 @@ use File::Path;
use File::Copy;
my $GENESIS_EXPORT_MANIFEST = 'xcat-genesis.manifest';
my %GENESIS_ARCHITECTURES = map { $_ => 1 }
qw(x86 x86_64 ppc64 ppc64le armv7hf aarch64 riscv64);
sub handled_commands {
return {
@@ -38,6 +40,28 @@ sub _select_network_addresses {
return (\%legacy, \%selected);
}
sub _select_genesis_source {
my ($xcatroot, $requested_arch) = @_;
return unless defined($requested_arch);
my $arch = $requested_arch eq 'ppc64el' ? 'ppc64le' : $requested_arch;
return unless $GENESIS_ARCHITECTURES{$arch};
my $netboot = "$xcatroot/share/xcat/netboot";
my $openembedded = "$netboot/genesis-openembedded/$arch";
return ($openembedded, $arch, 'openembedded')
if -e $openembedded || -l $openembedded;
my $legacy_arch = $arch eq 'ppc64le' ? 'ppc64' : $arch;
my $legacy = "$netboot/genesis/$legacy_arch";
return ($legacy, $legacy_arch, 'legacy') if -e $legacy || -l $legacy;
my $classic = "$netboot/$legacy_arch";
return ($classic, $legacy_arch, 'classic') if -e $classic || -l $classic;
return;
}
sub _genesis_export_manifest_present {
my ($directory) = @_;
my $manifest = "$directory/$GENESIS_EXPORT_MANIFEST";
@@ -341,21 +365,25 @@ sub process_request {
}
my $tftpdir = xCAT::TableUtils->getTftpDir();
my $arch = $request->{arg}->[0];
if (!$arch) {
$callback->({ error => "Need to specify architecture (x86, x86_64 or ppc64)" }, { errorcode => [1] });
my $requested_arch = $request->{arg}->[0];
if (!$requested_arch) {
$callback->({ error => "Need to specify architecture (x86, x86_64, ppc64, ppc64le, armv7hf, aarch64 or riscv64)" }, { errorcode => [1] });
return;
} elsif ($arch eq "ppc64le" or $arch eq "ppc64el") {
$callback->({ data => "The arch:$arch is not supported, using \"ppc64\" instead" });
$arch = 'ppc64';
$request->{arg}->[0] = $arch;
}
my $genesis_dir = "$::XCATROOT/share/xcat/netboot/genesis/$arch";
unless (-d "$::XCATROOT/share/xcat/netboot/$arch" or -d $genesis_dir) {
$callback->({ error => "Unable to find directory $::XCATROOT/share/xcat/netboot/$arch or $::XCATROOT/share/xcat/netboot/genesis/$arch", errorcode => [1] });
my ($genesis_dir, $arch, $genesis_type) =
_select_genesis_source($::XCATROOT, $requested_arch);
unless (defined($genesis_dir) && -d $genesis_dir && !-l $genesis_dir) {
$callback->({ error => "Unable to find a Genesis image for architecture $requested_arch", errorcode => [1] });
return;
}
if ($requested_arch eq 'ppc64el') {
$callback->({ data => 'Using the canonical architecture name ppc64le' });
} elsif ($requested_arch eq 'ppc64le' && $arch eq 'ppc64') {
$callback->({ data => 'OpenEmbedded ppc64le is not installed, using the legacy ppc64 image' });
}
$request->{arg}->[0] = $arch;
my $configfileonly = $request->{arg}->[1];
if ($configfileonly and $configfileonly ne "-c" and $configfileonly ne "--configfileonly") {
$callback->({ error => "The option $configfileonly is not supported", errorcode => [1] });
@@ -364,7 +392,10 @@ sub process_request {
goto CREAT_CONF_FILE;
}
if (_prebuilt_genesis_requested($genesis_dir)) {
$callback->({ data => ["Installing exported Genesis image for $arch"] });
my $image_name = $genesis_type eq 'openembedded'
? 'OpenEmbedded Genesis'
: 'exported Genesis';
$callback->({ data => ["Installing $image_name image for $arch"] });
my ($installed_initrd, $install_error) =
_install_prebuilt_genesis($genesis_dir, $tftpdir, $arch);
if ($install_error) {
@@ -375,7 +406,8 @@ sub process_request {
$invisibletouch = 1;
goto CREAT_CONF_FILE;
}
if (_genesis_export_manifest_present($genesis_dir)) {
if ($genesis_type eq 'openembedded'
|| _genesis_export_manifest_present($genesis_dir)) {
$callback->({
error => ["Incomplete Genesis export: $genesis_dir"],
errorcode => [1],
@@ -441,19 +473,19 @@ sub process_request {
mkpath("$tftpdir/xcat");
}
my $rc;
if (-e "$::XCATROOT/share/xcat/netboot/genesis/$arch") {
$rc = system("shopt -s dotglob; GLOBIGNORE=\".:..\" cp -a $::XCATROOT/share/xcat/netboot/genesis/$arch/fs/* $tempdir");
$rc = system("cp -a $::XCATROOT/share/xcat/netboot/genesis/$arch/kernel $tftpdir/xcat/genesis.kernel.$arch");
if ($genesis_type eq 'legacy') {
$rc = system("shopt -s dotglob; GLOBIGNORE=\".:..\" cp -a $genesis_dir/fs/* $tempdir");
$rc = system("cp -a $genesis_dir/kernel $tftpdir/xcat/genesis.kernel.$arch");
$invisibletouch = 1;
} else {
$rc = system("cp -a $::XCATROOT/share/xcat/netboot/$arch/nbroot/* $tempdir");
$rc = system("cp -a $genesis_dir/nbroot/* $tempdir");
}
if ($rc) {
system("rm -rf $tempdir");
if ($invisibletouch) {
$callback->({ error => ["Failed to copy $::XCATROOT/share/xcat/netboot/genesis/$arch/fs contents"], errorcode => [1] });
$callback->({ error => ["Failed to copy $genesis_dir/fs contents"], errorcode => [1] });
} else {
$callback->({ error => ["Failed to copy $::XCATROOT/share/xcat/netboot/$arch/nbroot/ contents"], errorcode => [1] });
$callback->({ error => ["Failed to copy $genesis_dir/nbroot contents"], errorcode => [1] });
}
return;
}
+41 -10
View File
@@ -1991,10 +1991,36 @@ sub setupLinuxexports
=head3 mknb
Creates a network boot root image on Linux
Run mknb for each installed xCAT-genesis-scripts/xCAT-genesis-base architecture and place the result in /tftpboot
Run mknb for each installed Genesis architecture and place the result in /tftpboot
=cut
#-----------------------------------------------------------------------------
sub _installed_genesis_architectures
{
my ($xcatroot) = @_;
my @supported = qw(aarch64 armv7hf ppc64 ppc64le riscv64 x86 x86_64);
my %supported = map { $_ => 1 } @supported;
my %installed;
my $openembedded = "$xcatroot/share/xcat/netboot/genesis-openembedded";
if (opendir(my $dh, $openembedded)) {
while (my $entry = readdir($dh)) {
next unless $supported{$entry};
my $path = "$openembedded/$entry";
$installed{$entry} = 1 if -d $path && !-l $path;
}
closedir($dh);
}
my $legacy = "$xcatroot/share/xcat/netboot/genesis";
foreach my $arch (@supported) {
my $path = "$legacy/$arch";
$installed{$arch} = 1 if -d $path && !-l $path;
}
return grep { $installed{$_} } @supported;
}
sub mknb
{
# The xCAT-genesis-scripts.spec file touches /etc/xcat/genesis-scripts-updated or
@@ -2014,20 +2040,25 @@ sub mknb
xCAT::MsgUtils->message('I', "Running '$cmd', triggered by the installation/update of xCAT-genesis-base ...");
}
}
my @architectures = _installed_genesis_architectures($::XCATROOT);
my @openembedded = grep {
-d "$::XCATROOT/share/xcat/netboot/genesis-openembedded/$_"
} @architectures;
if (@openembedded) {
unless ($run_mknb) {
xCAT::MsgUtils->message('I', "Running '$cmd' for installed OpenEmbedded Genesis images ...");
}
$run_mknb = 1;
}
if ($run_mknb) {
foreach (qw(ppc64 x86_64)) {
my $genesis_base_pkg = "xCAT-genesis-base-$_";
if (system("rpm -q $genesis_base_pkg >/dev/null 2>&1") != 0) {
xCAT::MsgUtils->message('I', "Skipping '$cmd $_' because $genesis_base_pkg is not installed.");
next;
}
system("$cmd $_");
foreach my $arch (@architectures) {
system("$cmd $arch");
if ($? != 0) {
my $rc = $? >> 8;
xCAT::MsgUtils->message('E', "The 'mknb $_' command returned error code: $rc.");
xCAT::MsgUtils->message('E', "The 'mknb $arch' command returned error code: $rc.");
}
else {
xCAT::MsgUtils->message('I', "The 'mknb $_' command completed successfully.");
xCAT::MsgUtils->message('I', "The 'mknb $arch' command completed successfully.");
}
}
}