2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-05-05 16:49:08 +00:00

Merge pull request #7533 from VersatusHPC/fix/opensuse-leap-support

feat: add openSUSE Leap 15 and SLES 15 provisioning support
This commit is contained in:
Markus Hilger
2026-05-04 17:20:59 +02:00
committed by GitHub
22 changed files with 897 additions and 83 deletions

View File

@@ -53,6 +53,37 @@ MStatus()
return $RVAL
}
SUSESuccess()
{
rc_failed 0
rc_status -v
}
SUSEFailure()
{
rc_failed 1
rc_status -v
}
SUSEWarning()
{
rc_failed 0
rc_status -v
}
IsSUSEFamily()
{
[ -f /etc/SuSE-release ] && return 0
[ -r /etc/os-release ] || return 1
. /etc/os-release
case " $ID $ID_LIKE " in
*"sles"*|*"sled"*|*"suse"*|*"opensuse"*) return 0 ;;
esac
return 1
}
if [ -f /etc/init.d/functions ]; then
# EL8-
. /etc/init.d/functions
@@ -76,6 +107,18 @@ elif [ -f /lib/lsb/init-functions ]; then
LOG_SUCCESS=log_success_msg
LOG_FAILURE=log_failure_msg
LOG_WARNING=log_warning_msg
elif IsSUSEFamily && [ -f /etc/rc.status ]; then
# Use SUSE's native SysV status helpers when Red Hat/Debian helpers are absent.
. /etc/rc.status
type rc_reset >/dev/null 2>&1 && type rc_failed >/dev/null 2>&1 && type rc_status >/dev/null 2>&1 || {
echo "Error, SUSE status helper functions are unavailable"
exit 1
}
rc_reset
STATUS=MStatus
LOG_SUCCESS=SUSESuccess
LOG_FAILURE=SUSEFailure
LOG_WARNING=SUSEWarning
else
echo "Error, don't know how to start on this platform"
exit 1
@@ -159,6 +202,3 @@ start)
;;
esac

View File

@@ -503,9 +503,31 @@ sub get_os_search_list {
}
push(@list, join('.', @word));
# openSUSE Leap 15.x uses the same AutoYaST asset layout as SLES 15.
# Do not extend this to Leap 16 without validating its installer path.
if ($baseos =~ /^(leap15)(?:\..*)?$/) {
push(@list, "sle15");
}
return @list;
}
sub _profile_file_matches {
my ($filename, $osver, $shortosver, $genos, $arch) = @_;
# osver and arch specific, for example compute.sle15.x86_64.pkglist
if ($filename =~ /[^\.]*\.([^\.]*)\.([^\.]*)\./) {
return (($1 eq $osver || $1 eq $shortosver || $1 eq $genos) && $2 eq $arch);
}
# osver or arch specific, for example compute.sle15.pkglist
if ($filename =~ /[^\.]*\.([^\.]*)\./) {
return ($1 eq $osver || $1 eq $shortosver || $1 eq $genos || $1 eq $arch);
}
return 1;
}
sub get_file_name {
my ($searchpath, $extension, $profile, $os, $arch, $genos) = @_;
@@ -581,6 +603,7 @@ sub get_postinstall_file_name {
my $profile = shift;
my $os = shift;
my $arch = shift;
my $genos = shift;
my $extension = "postinstall";
my $dotpos = rindex($os, ".");
my $osbase = substr($os, 0, $dotpos);
@@ -637,6 +660,13 @@ sub get_postinstall_file_name {
}
}
if (($genos) && (-x "$searchpath/$profile.$genos.$arch.$extension")) {
return "$searchpath/$profile.$genos.$arch.$extension";
}
if (($genos) && (-x "$searchpath/$profile.$genos.$extension")) {
return "$searchpath/$profile.$genos.$extension";
}
if (-x "$searchpath/$profile.$arch.$extension") {
return "$searchpath/$profile.$arch.$extension";
}
@@ -689,7 +719,7 @@ sub update_tables_with_templates
$osver = shift;
}
my $shortosver = $osver;
$shortosver =~ s/\..*//;
$shortosver =~ s/\..*//; # for major-version assets, for example leap15.6 -> leap15
my $arch = shift; #like ppc64, x86, x86_64
my $ospkgdir = shift;
my $osdistroname = shift;
@@ -707,6 +737,8 @@ sub update_tables_with_templates
$osname = "hyperv";
$ostype = "Windows";
$imagetype = "windows";
} elsif ($osver =~ /^leap15/) {
$osname = "sles";
} else {
until (-r "$::XCATROOT/share/xcat/install/$osname/" or not $osname) {
chop($osname);
@@ -729,7 +761,11 @@ sub update_tables_with_templates
$genos = "subiquity";
}
}
} elsif ($osver =~ /^leap15/) {
$genos = "sle15";
}
# For Leap, let get_os_search_list prefer leap15 assets before the sle15 fallback.
my $file_lookup_genos = ($osver =~ /^leap15/) ? undef : $genos;
#print "osver=$osver, arch=$arch, osname=$osname, genos=$genos\n";
my $installroot = xCAT::TableUtils->getInstallDir();
@@ -755,12 +791,10 @@ sub update_tables_with_templates
foreach (@tmplfiles) {
my $tmpf = basename($_);
#skip template files for other OS or architecture suffixes
next unless _profile_file_matches($tmpf, $osver, $shortosver, $genos, $arch);
#get the profile name out of the file, TODO: this does not work if the profile name contains the '.'
if ($tmpf =~ /[^\.]*\.([^\.]*)\.([^\.]*)\./) { # osver *and* arch specific, make sure they match
unless (($1 eq $osver or $1 eq $shortosver) and $2 eq $arch) { next; }
} elsif ($tmpf =~ /[^\.]*\.([^\.]*)\./) { #osver *or* arch specific, make sure one matches
unless ($1 eq $osver or $1 eq $shortosver or $2 eq $arch) { next; }
}
$tmpf =~ /^([^\.]*)\..*$/;
$tmpf = $1;
@@ -771,12 +805,10 @@ sub update_tables_with_templates
foreach (@tmplfiles) {
my $tmpf = basename($_);
#skip template files for other OS or architecture suffixes
next unless _profile_file_matches($tmpf, $osver, $shortosver, $genos, $arch);
#get the profile name out of the file, TODO: this does not work if the profile name contains the '.'
if ($tmpf =~ /[^\.]*\.([^\.]*)\.([^\.]*)\./) { # osver *and* arch specific, make sure they match
unless (($1 eq $osver or $1 eq $shortosver) and $2 eq $arch) { next; }
} elsif ($tmpf =~ /[^\.]*\.([^\.]*)\./) { #osver *or* arch specific, make sure one matches
unless ($1 eq $osver or $1 eq $shortosver or $1 eq $arch) { next; }
}
$tmpf =~ /^([^\.]*)\..*$/;
$tmpf = $1;
$profiles{$tmpf} = 1;
@@ -797,20 +829,20 @@ sub update_tables_with_templates
#print "profile=$profile\n";
#get template file
my $tmplfile = get_tmpl_file_name($cuspath, $profile, $osver, $arch, $genos);
if (!$tmplfile) { $tmplfile = get_tmpl_file_name($defpath, $profile, $osver, $arch, $genos); }
my $tmplfile = get_tmpl_file_name($cuspath, $profile, $osver, $arch, $file_lookup_genos);
if (!$tmplfile) { $tmplfile = get_tmpl_file_name($defpath, $profile, $osver, $arch, $file_lookup_genos); }
if (!$tmplfile) { next; }
#get otherpkgs.pkglist file
my $otherpkgsfile = get_otherpkgs_pkglist_file_name($cuspath, $profile, $osver, $arch);
if (!$otherpkgsfile) { $otherpkgsfile = get_otherpkgs_pkglist_file_name($defpath, $profile, $osver, $arch); }
my $otherpkgsfile = get_otherpkgs_pkglist_file_name($cuspath, $profile, $osver, $arch, $file_lookup_genos);
if (!$otherpkgsfile) { $otherpkgsfile = get_otherpkgs_pkglist_file_name($defpath, $profile, $osver, $arch, $file_lookup_genos); }
#get synclist file
my $synclistfile = xCAT::SvrUtils->getsynclistfile(undef, $osver, $arch, $profile, "netboot");
#get the pkglist file
my $pkglistfile = get_pkglist_file_name($cuspath, $profile, $osver, $arch);
if (!$pkglistfile) { $pkglistfile = get_pkglist_file_name($defpath, $profile, $osver, $arch, $genos); }
my $pkglistfile = get_pkglist_file_name($cuspath, $profile, $osver, $arch, $file_lookup_genos);
if (!$pkglistfile) { $pkglistfile = get_pkglist_file_name($defpath, $profile, $osver, $arch, $file_lookup_genos); }
#now update the db
if (!$osimagetab) {
@@ -928,6 +960,8 @@ sub update_tables_with_mgt_image
$osname = "hyperv";
$ostype = "Windows";
$imagetype = "windows";
} elsif ($osver =~ /^leap15/) {
$osname = "sles";
} else {
until (-r "$::XCATROOT/share/xcat/install/$osname/" or not $osname) {
chop($osname);
@@ -1131,6 +1165,8 @@ sub update_tables_with_diskless_image
my $mode = shift;
my $ospkgdir = shift;
my $osdistroname = shift;
my $shortosver = $osver;
$shortosver =~ s/\..*//; # for major-version assets, for example leap15.6 -> leap15
my $provm = "netboot";
if ($mode) { $provm = $mode; }
@@ -1142,6 +1178,8 @@ sub update_tables_with_diskless_image
$osname = "windows";
$ostype = "Windows";
$imagetype = "windows";
} elsif ($osver =~ /^leap15/) {
$osname = "sles";
} else {
until (-r "$::XCATROOT/share/xcat/netboot/$osname/" or not $osname) {
chop($osname);
@@ -1156,7 +1194,11 @@ sub update_tables_with_diskless_image
$genos =~ s/\..*//;
if ($genos =~ /rh.*s(\d*)/) {
$genos = "rhels$1";
} elsif ($osver =~ /^leap15/) {
$genos = "sle15";
}
# For Leap, let get_os_search_list prefer leap15 assets before the sle15 fallback.
my $file_lookup_genos = ($osver =~ /^leap15/) ? undef : $genos;
#print "osver=$osver, arch=$arch, osname=$osname, genos=$genos, profile=$profile\n";
my $installroot = xCAT::TableUtils->getInstallDir();
@@ -1186,6 +1228,9 @@ sub update_tables_with_diskless_image
foreach (@tmplfiles) {
my $tmpf = basename($_);
#skip pkglist files for other OS or architecture suffixes
next unless _profile_file_matches($tmpf, $osver, $shortosver, $genos, $arch);
#get the profile name out of the file, TODO: this does not work if the profile name contains the '.'
$tmpf =~ /^([^\.]*)\..*$/;
$tmpf = $1;
@@ -1195,6 +1240,9 @@ sub update_tables_with_diskless_image
foreach (@tmplfiles) {
my $tmpf = basename($_);
#skip pkglist files for other OS or architecture suffixes
next unless _profile_file_matches($tmpf, $osver, $shortosver, $genos, $arch);
#get the profile name out of the file, TODO: this does not work if the profile name contains the '.'
$tmpf =~ /^([^\.]*)\..*$/;
$tmpf = $1;
@@ -1204,26 +1252,26 @@ sub update_tables_with_diskless_image
foreach my $profile (keys %profiles) {
#get the pkglist file
my $pkglistfile = get_pkglist_file_name($cuspath, $profile, $osver, $arch);
if (!$pkglistfile) { $pkglistfile = get_pkglist_file_name($defpath, $profile, $osver, $arch); }
my $pkglistfile = get_pkglist_file_name($cuspath, $profile, $osver, $arch, $file_lookup_genos);
if (!$pkglistfile) { $pkglistfile = get_pkglist_file_name($defpath, $profile, $osver, $arch, $file_lookup_genos); }
#print "pkglistfile=$pkglistfile\n";
if (!$pkglistfile) { next; }
#get otherpkgs.pkglist file
my $otherpkgsfile = get_otherpkgs_pkglist_file_name($cuspath, $profile, $osver, $arch);
if (!$otherpkgsfile) { $otherpkgsfile = get_otherpkgs_pkglist_file_name($defpath, $profile, $osver, $arch); }
my $otherpkgsfile = get_otherpkgs_pkglist_file_name($cuspath, $profile, $osver, $arch, $file_lookup_genos);
if (!$otherpkgsfile) { $otherpkgsfile = get_otherpkgs_pkglist_file_name($defpath, $profile, $osver, $arch, $file_lookup_genos); }
#get synclist file
my $synclistfile = xCAT::SvrUtils->getsynclistfile(undef, $osver, $arch, $profile, "netboot");
#get the exlist file
my $exlistfile = get_exlist_file_name($cuspath, $profile, $osver, $arch);
if (!$exlistfile) { $exlistfile = get_exlist_file_name($defpath, $profile, $osver, $arch); }
my $exlistfile = get_exlist_file_name($cuspath, $profile, $osver, $arch, $file_lookup_genos);
if (!$exlistfile) { $exlistfile = get_exlist_file_name($defpath, $profile, $osver, $arch, $file_lookup_genos); }
#get postinstall script file name
my $postfile = get_postinstall_file_name($cuspath, $profile, $osver, $arch);
if (!$postfile) { $postfile = get_postinstall_file_name($defpath, $profile, $osver, $arch); }
my $postfile = get_postinstall_file_name($cuspath, $profile, $osver, $arch, $genos);
if (!$postfile) { $postfile = get_postinstall_file_name($defpath, $profile, $osver, $arch, $genos); }
#now update the db

View File

@@ -326,7 +326,7 @@ sub subvars {
$writerepo .="$repo_in_post\n";
$writerepo .="EOF\n";
}
} elsif ($platform =~ /^(sles|suse)/) {
} elsif ($platform =~ /^(sles|suse|leap15)/) {
my $http = "http://#TABLE:noderes:\$NODE:nfsserver#$httpportsuffix/$pkgdir";
$source .= " <listentry>
<media_url>$http</media_url>
@@ -341,18 +341,8 @@ sub subvars {
opendir(DIR,$pkgdir);
my @subpkgdir=grep(!/\.\.?$|^media.1$/, readdir DIR);
foreach my $subdir (@subpkgdir){
my $product_name;
my $product_dir;
$product_dir=$subdir;
if($subdir =~ /^Module-/){
$product_name="sle-".lc($subdir);
}elsif($subdir =~ /^Product-SUSE-Manager-Server|^Product-SLES_SAP|^Product-SLED/){
# Skip product directories that are not "SLES", causes conflict on SLE15.2
next;
}elsif($subdir =~ /^Product-/){
$subdir=~s/Product-//;
$product_name=$subdir;
}
my $product_name = _sle15_install_product_name($subdir);
my $product_dir = $subdir;
if (defined($product_name) && defined($product_dir)){
$source .="<listentry>\n$space12<media_url>http://XCATNEXTSERVERHOOK$httpportsuffix$pkgdir</media_url>\n$space12<product>$product_name</product>\n$space12<product_dir>/$product_dir</product_dir>\n$space12</listentry>\n$space10";
}
@@ -2003,6 +1993,29 @@ sub getNM_GW()
return (undef, undef);
}
sub _sle15_install_product_name {
my ($subdir) = @_;
if ($subdir =~ /^Module-SAP-/) {
return;
}
if ($subdir =~ /^Module-/) {
return "sle-" . lc($subdir);
}
if ($subdir =~ /^Product-SUSE-Manager-Server|^Product-SLES_SAP|^Product-SLED/) {
# Skip product directories that are not generic SLES; these can conflict with SLE 15 installs.
return;
}
if ($subdir =~ /^Product-(.+)$/) {
return $1;
}
return;
}
1;

View File

@@ -1410,6 +1410,14 @@ sub stop_TFTP
return 0;
}
sub in_tftpd_is_atftpd
{
return 0 unless -x "/usr/sbin/in.tftpd";
my $help = `/usr/sbin/in.tftpd --help 2>&1`;
return ($help =~ /--daemon/ && $help =~ /--group/ && $help =~ /--logfile/) ? 1 : 0;
}
#-----------------------------------------------------------------------------
#
#=head3 enable_TFTP
@@ -1465,6 +1473,8 @@ sub enable_TFTP
my $startcmd = "/usr/sbin/in.tftpd $v4only -v -l -s $tftpdir -m /etc/tftpmapfile4xcat.conf";
if ($tftpflags) {
$startcmd = "/usr/sbin/in.tftpd $v4only $tftpflags";
} elsif (in_tftpd_is_atftpd()) {
$startcmd = "/usr/sbin/in.tftpd --daemon --user nobody --group nogroup $tftpdir";
}
if ( -x "/usr/sbin/in.tftpd") {

View File

@@ -1641,11 +1641,8 @@ sub process_request
}
else
{
my @nsrnoutput = split /\n/, `/bin/netstat -rn`;
splice @nsrnoutput, 0, 2;
foreach (@nsrnoutput) { #scan netstat
my @parts = split /\s+/;
push @nrn, $parts[0] . ":" . $parts[7] . ":" . $parts[2] . ":" . $parts[3];
foreach my $route (local_ipv4_routes()) {
push @nrn, join(':', @{$route});
}
my @ip6routes = `ip -6 route`;
foreach (@ip6routes) {
@@ -1734,10 +1731,7 @@ sub process_request
# For SLES11+ and RHEL7+ Operating system releases, the
# dhcpd/dhcpd6 configuration is stored in the same file
my $os_ver = $os;
$os_ver =~ s/[^0-9.^0-9]//g;
if (($os =~ /sles/i && $os_ver >= 11) ||
($os =~ /rhels?/i && $os_ver >= 7)) {
if (dhcpd_sysconfig_uses_interface_key($os)) {
$dhcpd_key = "DHCPD_INTERFACE";
if ($usingipv6 and $dhcpver eq "dhcpd6") {
@@ -1805,10 +1799,7 @@ sub process_request
if ($usingipv6) {
# sles11.3 and rhels7 has dhcpd and dhcpd6 config in the dhcp file
my $os_ver = $os;
$os_ver =~ s/[^0-9.^0-9]//g;
if (($os =~ /sles/i && $os_ver >= 11) ||
($os =~ /rhels?/i && $os_ver >= 7)) {
if (dhcpd_sysconfig_uses_interface_key($os)) {
if ($missingfiles{dhcpd}) {
$callback->({ error => ["The file /etc/sysconfig/dhcpd doesn't exist, check the dhcp server"] });
}
@@ -2612,6 +2603,17 @@ sub kea_apply_ddns_behavior
$intent->{'ddns-update-on-renew'} = JSON::true;
}
sub dhcpd_sysconfig_uses_interface_key
{
my $os = shift || "";
my $os_ver = $os;
$os_ver =~ s/[^0-9.^0-9]//g;
return 1 if $os =~ /(sles|opensuse[-_]?leap|leap)/i && $os_ver >= 11;
return 1 if $os =~ /rhels?/i && $os_ver >= 7;
return 0;
}
sub kea_ddns_enabled
{
return defined($::XCATSITEVALS{dnshandler}) && $::XCATSITEVALS{dnshandler} =~ /ddns/ ? 1 : 0;
@@ -2643,6 +2645,24 @@ sub kea_ipv4_routes
my @vnets = @_;
my @routes;
push @routes, local_ipv4_routes();
foreach (@vnets) {
my $n = $_->{net};
my $if = $_->{mgtifname};
my $nm = $_->{mask};
if ($if =~ /!remote!/ and $n !~ /:/) {
push @routes, [ $n, $if, $nm, '' ];
}
}
return @routes;
}
sub local_ipv4_routes
{
my @routes;
my $ipcmd = kea_command_path('ip');
if ($ipcmd) {
my @route_output = split /\n/, `$ipcmd -4 route show 2>/dev/null`;
@@ -2667,15 +2687,6 @@ sub kea_ipv4_routes
}
}
foreach (@vnets) {
my $n = $_->{net};
my $if = $_->{mgtifname};
my $nm = $_->{mask};
if ($if =~ /!remote!/ and $n !~ /:/) {
push @routes, [ $n, $if, $nm, '' ];
}
}
return @routes;
}

View File

@@ -285,6 +285,10 @@ sub process_request {
if ($osfamily =~ /sles/ && $osfamily =~ /sp/) {
$osfamily = "sles";
}
# openSUSE Leap 15.x reuses the existing SLES diskless image scripts.
if ($osver =~ /^leap15/) {
$osfamily = "sles";
}
$osfamily =~ s/ //g;

View File

@@ -217,8 +217,12 @@ sub process_request {
}
my $distname = $osver;
until (-r "$::XCATROOT/share/xcat/netboot/$distname/" or not $distname) {
chop($distname);
if ($osver =~ /^leap15/) {
$distname = "sles";
} else {
until (-r "$::XCATROOT/share/xcat/netboot/$distname/" or not $distname) {
chop($distname);
}
}
unless ($distname) {
$callback->({ error => ["Unable to find $::XCATROOT/share/xcat/netboot directory for $osver"], errorcode => [1] });
@@ -326,7 +330,11 @@ sub process_request {
if (-e "$rootimg_dir/usr/lib/dracut/modules.d/97xcat/install") {
xCAT::Utils->runcmd("mv $rootimg_dir/usr/lib/dracut/modules.d/97xcat/install $rootimg_dir/.statebackup/install", 0, 1);
}
xCAT::Utils->runcmd("cp /opt/xcat/share/xcat/netboot/rh/dracut_033/install.netboot $rootimg_dir/usr/lib/dracut/modules.d/97xcat/install", 0, 1);
my $dracut_install = "$::XCATROOT/share/xcat/netboot/$distname/dracut_033/install.netboot";
if (!-r $dracut_install) {
$dracut_install = "$::XCATROOT/share/xcat/netboot/rh/dracut_033/install.netboot";
}
xCAT::Utils->runcmd("cp $dracut_install $rootimg_dir/usr/lib/dracut/modules.d/97xcat/install", 0, 1);
# timedatectl requires /etc/localtime link to the zoneinfo in /usr/share/zoneinfo

View File

@@ -37,10 +37,10 @@ sub handled_commands
{
return {
copycd => "sles",
mknetboot => "nodetype:os=(sle.*)|(suse.*)",
mkinstall => "nodetype:os=(sle.*)|(suse.*)",
mkstatelite => "nodetype:os=(sle.*)",
mksysclone => "nodetype:os=(sle.*)|(suse.*)"
mknetboot => "nodetype:os=(sle.*)|(suse.*)|(leap15.*)",
mkinstall => "nodetype:os=(sle.*)|(suse.*)|(leap15.*)",
mkstatelite => "nodetype:os=(sle.*)|(leap15.*)",
mksysclone => "nodetype:os=(sle.*)|(suse.*)|(leap15.*)"
};
}
@@ -297,7 +297,7 @@ sub mknetboot
# TODO: should get the $pkgdir value from the linuximage table
$pkgdir = "$installroot/$osver/$arch";
} elsif ($osver =~ /suse.*/) {
} elsif ($osver =~ /suse.*/ or $osver =~ /leap15.*/) {
$platform = "sles";
}
@@ -875,6 +875,8 @@ sub mkinstall
$plat = "sle";
} elsif ($os =~ /suse.*/) {
$plat = "suse";
} elsif ($os =~ /leap15.*/) {
$plat = "sles";
} else {
$plat = "foobar";
print "You should never get here! Programmer error!";
@@ -1103,6 +1105,9 @@ sub mkinstall
. " install=$httpmethod://"
. $netserver . ":" . $httpport
. "$httpprefix/1";
if ($os =~ /^leap15/) {
$kcmdline .= " self_update=0";
}
my $installnic;
my $primarynic;
@@ -1566,6 +1571,78 @@ sub using_dracut
}
}
sub _opensuse_leap_distname
{
my $version = shift;
return unless defined $version;
return unless $version =~ /^(15(?:\.\d+)?)/;
return "leap$1";
}
sub _detect_opensuse_leap_treeinfo
{
my $mntpath = shift;
my $treeinfo = "$mntpath/.treeinfo";
return unless -r $treeinfo;
my %section;
my $section = "";
open(my $fh, "<", $treeinfo) or return;
while (my $line = <$fh>) {
chomp($line);
if ($line =~ /^\s*\[([^\]]+)\]\s*$/) {
$section = $1;
next;
}
next unless $line =~ /^\s*([^=\s]+)\s*=\s*(.*?)\s*$/;
$section{$section}{$1} = $2;
}
close($fh);
my $name = $section{release}{name} || $section{general}{family} || $section{general}{name};
return unless defined $name and $name =~ /openSUSE\s+Leap/i;
my $distname = _opensuse_leap_distname($section{release}{version} || $section{general}{version});
return unless $distname;
return ($distname, $section{general}{arch});
}
sub _detect_opensuse_leap_media
{
my ($media, $products) = @_;
$media = "" unless defined $media;
$products = "" unless defined $products;
return unless "$media\n$products" =~ /openSUSE[-\s]+Leap/i;
my $version;
if ($products =~ /openSUSE[-\s]+Leap\s+(\d+(?:\.\d+)?)/i) {
$version = $1;
} elsif ($media =~ /openSUSE[-\s]+Leap[-\s]+(\d+(?:\.\d+)?)/i) {
$version = $1;
}
my $distname = _opensuse_leap_distname($version);
return unless $distname;
my $arch;
if ("$media\n$products" =~ /(x86_64|ppc64le|ppc64el|s390x|aarch64)/) {
$arch = $1;
}
return ($distname, $arch);
}
sub _copycd_distname_supported
{
my $distname = shift;
return 1 unless $distname;
return 1 if $distname =~ /^(?:sle|suse)/;
return 1 if $distname =~ /^leap15(?:\..*)?$/;
return;
}
sub copycd
{
my $request = shift;
@@ -1621,10 +1698,10 @@ sub copycd
$path =~ s,//*,/,g;
}
if ($distname and $distname !~ /^sle|^suse/)
if (!_copycd_distname_supported($distname))
{
#If they say to call it something other than SLES or SUSE, give up?
# If they say to call it something other than SLE, SUSE, or Leap, give up.
return;
}
@@ -1632,7 +1709,16 @@ sub copycd
my $discnumber;
my $darch;
my $linktwo = 0;
if (-r $mntpath . "/content")
my ($opensuse_distname, $opensuse_arch) = _detect_opensuse_leap_treeinfo($mntpath);
if ($opensuse_distname) {
$detdistname = $opensuse_distname;
$distname = $opensuse_distname unless $distname;
$darch = $opensuse_arch if $opensuse_arch;
$discnumber = 1;
}
if (!$discnumber and -r $mntpath . "/content")
{
my $dinfo;
open($dinfo, $mntpath . "/content");
@@ -1743,16 +1829,30 @@ sub copycd
}
closedir($dirh);
} elsif (-r $mntpath . "/media.1/media") {
} elsif (!$discnumber and -r $mntpath . "/media.1/media") {
my $dinfo;
open($dinfo, $mntpath . "/media.1/media");
my $dsc = <$dinfo>;
close($dinfo);
my $prod = "";
if (-r "$mntpath/media.1/products") {
open(my $prod_fh, "<", "$mntpath/media.1/products");
local $/;
$prod = <$prod_fh>;
close($prod_fh);
}
if ($dsc =~ /x86_64/) {
$darch = "x86_64";
} elsif ($dsc =~ /ppc64le/) {
$darch = "ppc64le" ;
}
if ($dsc =~ /Installer/ and $dsc =~ /SLE-15/) {
my ($opensuse_media_distname, $opensuse_media_arch) = _detect_opensuse_leap_media($dsc, $prod);
if ($opensuse_media_distname) {
$discnumber = 1;
$detdistname = $opensuse_media_distname;
$distname = $opensuse_media_distname unless $distname;
$darch = $opensuse_media_arch if $opensuse_media_arch;
} elsif ($dsc =~ /Installer/ and $dsc =~ /SLE-15/) {
$discnumber = 1;
unless ($distname) {
if ($dsc =~ /SLE-15-SP(\d)/) {

View File

@@ -42,6 +42,10 @@ echo "DHCLIENT_PRIMARY_DEVICE=yes" >> ifcfg-$PRINIC
fi
perl -pi -e 's/^FIREWALL="yes"/FIREWALL="no"/' /etc/sysconfig/network/config
if command -v systemctl >/dev/null 2>&1 && systemctl list-unit-files firewalld.service >/dev/null 2>&1; then
systemctl stop firewalld.service >/dev/null 2>&1 || true
systemctl disable firewalld.service >/dev/null 2>&1 || true
fi
service network restart
RAND=$(perl -e 'print int(rand(50)). "\n"')

View File

@@ -0,0 +1,12 @@
@base
iputils
vim
openssl
rsync
net-tools
rsyslog
nfs-client
wget
openssh
zypper
chrony

View File

@@ -0,0 +1,90 @@
<?xml version="1.0"?>
<!DOCTYPE profile>
<profile xmlns="http://www.suse.com/1.0/yast2ns" xmlns:config="http://www.suse.com/1.0/configns">
<bootloader>
<global>
<activate>true</activate>
<append>#XCATVAR:PERSKCMDLINE#</append>
</global>
</bootloader>
<general>
<mode>
<confirm config:type="boolean">false</confirm>
<final_reboot config:type="boolean">false</final_reboot>
</mode>
<self_update config:type="boolean">false</self_update>
<signature-handling>
<accept_non_trusted_gpg_key config:type="boolean">true</accept_non_trusted_gpg_key>
<accept_unknown_gpg_key config:type="boolean">true</accept_unknown_gpg_key>
<accept_unsigned_file config:type="boolean">true</accept_unsigned_file>
<accept_verification_failed config:type="boolean">true</accept_verification_failed>
</signature-handling>
</general>
<timezone>
<hwclock>UTC</hwclock>
<timezone>#TABLE:site:key=timezone:value#</timezone>
</timezone>
<keyboard>
<keymap>english-us</keymap>
</keyboard>
<language>
<language>en_US</language>
</language>
<partitioning config:type="list">
<!-- XCAT-PARTITION-START -->
<drive>
<device>XCATPARTITIONHOOK</device>
<initialize config:type="boolean">true</initialize>
<use>all</use>
</drive>
<!-- XCAT-PARTITION-END -->
</partitioning>
<add-on>
<add_on_products config:type="list">
#INSTALL_SOURCES#
</add_on_products>
</add-on>
<software>
<products config:type="list">
<product>Leap</product>
</products>
<do_online_update config:type="boolean">false</do_online_update>
<patterns config:type="list">
#INCLUDE_DEFAULT_PTRNLIST_S#
</patterns>
<packages config:type="list">
#INCLUDE_DEFAULT_PKGLIST_S#
</packages>
</software>
<users config:type="list">
<user>
<username>root</username>
<user_password>#CRYPT:passwd:key=system,username=root:password#</user_password>
<encrypted config:type="boolean">true</encrypted>
<forename/>
<surname/>
</user>
</users>
<networking>
<dns>
<dhcp_hostname config:type="boolean">true</dhcp_hostname>
<hostname>linux</hostname>
</dns>
<interfaces config:type="list">
<interface>
<bootproto>dhcp</bootproto>
<device>eth0</device>
<startmode>onboot</startmode>
</interface>
</interfaces>
<keep_install_network config:type="boolean">true</keep_install_network>
<routing>
<ipv4_forward config:type="boolean">false</ipv4_forward>
</routing>
</networking>
<scripts>
#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.sle#
#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/chroot.sles#
#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/post.sle#
</scripts>
</profile>

View File

@@ -0,0 +1,15 @@
@base
@x11
openssl
iputils
chrony
rsync
rsyslog
net-tools
vsftpd
perl-IO-Tty
perl-SNMP
perl-Net-DNS
mariadb-client
vim
wget

View File

@@ -0,0 +1,90 @@
<?xml version="1.0"?>
<!DOCTYPE profile>
<profile xmlns="http://www.suse.com/1.0/yast2ns" xmlns:config="http://www.suse.com/1.0/configns">
<bootloader>
<global>
<activate>true</activate>
<append>#XCATVAR:PERSKCMDLINE#</append>
</global>
</bootloader>
<general>
<mode>
<confirm config:type="boolean">false</confirm>
<final_reboot config:type="boolean">false</final_reboot>
</mode>
<self_update config:type="boolean">false</self_update>
<signature-handling>
<accept_non_trusted_gpg_key config:type="boolean">true</accept_non_trusted_gpg_key>
<accept_unknown_gpg_key config:type="boolean">true</accept_unknown_gpg_key>
<accept_unsigned_file config:type="boolean">true</accept_unsigned_file>
<accept_verification_failed config:type="boolean">true</accept_verification_failed>
</signature-handling>
</general>
<timezone>
<hwclock>UTC</hwclock>
<timezone>#TABLE:site:key=timezone:value#</timezone>
</timezone>
<keyboard>
<keymap>english-us</keymap>
</keyboard>
<language>
<language>en_US</language>
</language>
<partitioning config:type="list">
<!-- XCAT-PARTITION-START -->
<drive>
<device>XCATPARTITIONHOOK</device>
<initialize config:type="boolean">true</initialize>
<use>all</use>
</drive>
<!-- XCAT-PARTITION-END -->
</partitioning>
<add-on>
<add_on_products config:type="list">
#INSTALL_SOURCES#
</add_on_products>
</add-on>
<software>
<products config:type="list">
<product>Leap</product>
</products>
<do_online_update config:type="boolean">false</do_online_update>
<patterns config:type="list">
#INCLUDE_DEFAULT_PTRNLIST_S#
</patterns>
<packages config:type="list">
#INCLUDE_DEFAULT_PKGLIST_S#
</packages>
</software>
<users config:type="list">
<user>
<username>root</username>
<user_password>#CRYPT:passwd:key=system,username=root:password#</user_password>
<encrypted config:type="boolean">true</encrypted>
<forename/>
<surname/>
</user>
</users>
<networking>
<dns>
<dhcp_hostname config:type="boolean">true</dhcp_hostname>
<hostname>linux</hostname>
</dns>
<interfaces config:type="list">
<interface>
<bootproto>dhcp</bootproto>
<device>eth0</device>
<startmode>onboot</startmode>
</interface>
</interfaces>
<keep_install_network config:type="boolean">true</keep_install_network>
<routing>
<ipv4_forward config:type="boolean">false</ipv4_forward>
</routing>
</networking>
<scripts>
#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.sle#
#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/chroot.sles#
#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/post.sle#
</scripts>
</profile>

View File

@@ -50,16 +50,24 @@ sub get_profile_def_filename {
}
my $osbase = substr($osver, 0, $dotpos);
my $fallbackos;
if ($osver =~ /^leap15/) {
$fallbackos = "sle15";
}
if (-r "$base/$profile.$osver.$arch.$ext") {
return "$base/$profile.$osver.$arch.$ext";
} elsif (-r "$base/$profile.$osbase.$arch.$ext") {
return "$base/$profile.$osbase.$arch.$ext";
} elsif ($fallbackos && -r "$base/$profile.$fallbackos.$arch.$ext") {
return "$base/$profile.$fallbackos.$arch.$ext";
} elsif (-r "$base/$profile.$arch.$ext") {
return "$base/$profile.$arch.$ext";
} elsif (-r "$base/$profile.$osver.$ext") {
return "$base/$profile.$osver.$ext";
} elsif (-r "$base/$profile.$osbase.$ext") {
return "$base/$profile.$osbase.$ext";
} elsif ($fallbackos && -r "$base/$profile.$fallbackos.$ext") {
return "$base/$profile.$fallbackos.$ext";
} elsif (-r "$base/$profile.$ext") {
return "$base/$profile.$ext";
}

View File

@@ -0,0 +1,49 @@
aaa_base
coreutils
bash
dbus-1
wicked
device-mapper
dracut
nfs-kernel-server
keyutils
lvm2
openssl
dhcp-client
openssh
procps
psmisc
wget
sysconfig
rsyslog
vim
rsync
timezone
bc
chrony
gzip
e2fsprogs
parted
xfsprogs
binutils
tar
open-iscsi
curl
btrfsprogs
cryptsetup
dmraid
mdadm
multipath-tools
gpg2
which
cifs-utils
util-linux-systemd
systemd
udev
kernel-default
kernel-firmware-all
adaptec-firmware
xz
net-tools
rsyslog
iputils

View File

@@ -0,0 +1,14 @@
#!/bin/sh
installroot=$1
arch=$3
profile=$4
cat <<END >"$installroot/etc/fstab"
proc /proc proc rw 0 0
sysfs /sys sysfs rw 0 0
devpts /dev/pts devpts rw,gid=5,mode=620 0 0
${profile}_${arch} / tmpfs rw 0 1
none /tmp tmpfs defaults,size=10m 0 2
none /var/tmp tmpfs defaults,size=10m 0 2
END

View File

@@ -24,6 +24,7 @@ ntp
gzip
e2fsprogs
parted
xfsprogs
binutils
tar
open-iscsi

View File

@@ -1,7 +1,7 @@
#!/bin/sh
echo $drivers
dracut_install wget tar cpio gzip modprobe touch echo cut wc xz
dracut_install grep ifconfig ip hostname awk egrep grep dirname expr
dracut_install grep ip hostname awk egrep grep dirname expr
dracut_install mount.nfs
dracut_install parted mke2fs bc mkswap swapon chmod mkfs mkfs.ext4 mkfs.xfs xfs_db
inst "$moddir/xcat-updateflag" "/tmp/updateflag"

View File

@@ -1,7 +1,7 @@
#!/bin/sh
echo $drivers
dracut_install wget cpio gzip modprobe wc touch echo cut
dracut_install grep ifconfig ip hostname awk egrep grep dirname expr logger
dracut_install grep ip hostname awk egrep grep dirname expr logger
dracut_install parted mke2fs bc mkswap swapon chmod mkfs mkfs.ext4 mkfs.xfs xfs_db
inst "$moddir/xcat-updateflag" "/tmp/updateflag"
inst_hook pre-mount 5 "$moddir/xcat-premount.sh"

View File

@@ -909,7 +909,9 @@ unless (-l "$rootimg_dir/var/lib/dhcpcd") {
}
#keyctl moved to /bin for newer release
system("cd $rootimg_dir/usr/bin/; ln -s ../../bin/keyctl $rootimg_dir/usr/bin/keyctl");
unless (-e "$rootimg_dir/usr/bin/keyctl") {
system("cd $rootimg_dir/usr/bin/; ln -s ../../bin/keyctl $rootimg_dir/usr/bin/keyctl");
}
# which is different from the Redhat family
@@ -933,10 +935,15 @@ if (@new_order) {
}
# add drivers for local disk support
push @ndrivers, ("ext3.ko", "ext4.ko", "virtio_pci.ko", "virtio_blk.ko", "libata.ko", "scsi_mod.ko", "scsi_dh.ko", "ahci.ko", "megaraid_sas.ko", "sd_mod.ko");
push @ndrivers, ("ext3.ko", "ext4.ko", "virtio_pci.ko", "virtio_blk.ko", "libata.ko", "scsi_mod.ko", "ahci.ko", "megaraid_sas.ko", "sd_mod.ko");
if (glob("$rootimg_dir/lib/modules/$kernelver/kernel/drivers/scsi/device_handler/scsi_dh.ko*")) {
push @ndrivers, "scsi_dh.ko";
}
if ($osver_host >= 12) {
push @ndrivers, ("ibmvscsi.ko");
if ($arch =~ /ppc/) {
push @ndrivers, ("ibmvscsi.ko");
}
} else { # for sles11 or lower
push @ndrivers, ("ibmvscsic.ko", "ata_piix.ko", "pcieport.ko");
}
@@ -2124,9 +2131,17 @@ sub generic_post { # This function is meant to leave the image in a state approx
foreach my $service (@services) {
my $cmd = "chroot $rootimg_dir ";
if (-r "$rootimg_dir/etc/init.d/$service") {
if ((-r "$rootimg_dir/etc/init.d/$service") && (-x "$rootimg_dir/sbin/insserv")) {
$cmd = $cmd . "insserv -f $service";
system("$cmd");
} elsif (($service eq "network") && (-r "$rootimg_dir/usr/lib/systemd/system/wicked.service")) {
$cmd = $cmd . "systemctl enable wicked.service";
system("$cmd");
} elsif (-r "$rootimg_dir/usr/lib/systemd/system/$service.service") {
$cmd = $cmd . "systemctl enable $service.service";
system("$cmd");
} elsif (-r "$rootimg_dir/etc/init.d/$service") {
print "[genimage] skipping $service init script enablement because insserv is unavailable\n";
}
else {
$cmd = $cmd . "systemctl enable $service.service";
@@ -2490,4 +2505,3 @@ sub usage {
print " genimage -i eth0 -n tg3,bnx2 -o sles11 -p compute --permission 777\n";
return 0;
}

View File

@@ -1,10 +1,12 @@
use strict;
use warnings;
## no critic (Modules::RequireFilenameMatchesPackage, TestingAndDebugging::ProhibitNoStrict, TestingAndDebugging::ProhibitNoWarnings)
no warnings 'once';
use FindBin;
use lib "$FindBin::Bin/../../perl-xCAT";
use File::Temp qw(tempdir);
use Test::More;
BEGIN {
@@ -81,6 +83,72 @@ my %network_entry = (
tftpserver => '<xcatmaster>',
);
ok(xCAT_plugin::dhcp::dhcpd_sysconfig_uses_interface_key('opensuse-leap15.6'), 'openSUSE Leap head node uses SUSE dhcpd interface key');
ok(xCAT_plugin::dhcp::dhcpd_sysconfig_uses_interface_key('leap15.6'), 'Leap head node osver uses SUSE dhcpd interface key');
ok(!xCAT_plugin::dhcp::dhcpd_sysconfig_uses_interface_key('opensuse-tumbleweed'), 'generic openSUSE names do not enable Leap-specific dhcpd handling');
{
my $tmpdir = tempdir(CLEANUP => 1);
my $fake_ip = "$tmpdir/ip";
open(my $ip_fh, '>', $fake_ip) or die "Cannot write fake ip command: $!";
print {$ip_fh} "#!/bin/sh\n";
print {$ip_fh} "cat <<'EOF'\n";
print {$ip_fh} "default via 192.168.1.1 dev eth1 proto dhcp\n";
print {$ip_fh} "10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.1\n";
print {$ip_fh} "192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.20\n";
print {$ip_fh} "EOF\n";
close($ip_fh);
chmod 0755, $fake_ip;
no warnings 'redefine';
local *xCAT_plugin::dhcp::kea_command_path = sub {
my ($command) = @_;
return $fake_ip if $command eq 'ip';
return;
};
is_deeply(
[ xCAT_plugin::dhcp::local_ipv4_routes() ],
[
[ '0.0.0.0', 'eth1', '0.0.0.0', 'G' ],
[ '10.0.0.0', 'eth0', '255.255.255.0', '' ],
[ '192.168.1.0', 'eth1', '255.255.255.0', '' ],
],
'local IPv4 route detection prefers ip route output'
);
}
{
my $tmpdir = tempdir(CLEANUP => 1);
my $fake_netstat = "$tmpdir/netstat";
open(my $netstat_fh, '>', $fake_netstat) or die "Cannot write fake netstat command: $!";
print {$netstat_fh} "#!/bin/sh\n";
print {$netstat_fh} "cat <<'EOF'\n";
print {$netstat_fh} "Kernel IP routing table\n";
print {$netstat_fh} "Destination Gateway Genmask Flags MSS Window irtt Iface\n";
print {$netstat_fh} "0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth1\n";
print {$netstat_fh} "10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0\n";
print {$netstat_fh} "EOF\n";
close($netstat_fh);
chmod 0755, $fake_netstat;
no warnings 'redefine';
local *xCAT_plugin::dhcp::kea_command_path = sub {
my ($command) = @_;
return $fake_netstat if $command eq 'netstat';
return;
};
is_deeply(
[ xCAT_plugin::dhcp::local_ipv4_routes() ],
[
[ '0.0.0.0', 'eth1', '0.0.0.0', 'UG' ],
[ '10.0.0.0', 'eth0', '255.255.255.0', 'U' ],
],
'local IPv4 route detection falls back to netstat output'
);
}
{
no warnings 'redefine';
local *xCAT_plugin::dhcp::kea_ipv4_routes = sub {

View File

@@ -0,0 +1,215 @@
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
use File::Temp qw(tempdir);
use FindBin;
use Cwd qw(realpath);
use lib "$FindBin::Bin/../../perl-xCAT";
use lib "$FindBin::Bin/../../xCAT-server/lib/perl";
use lib "$FindBin::Bin/../../xCAT-server/lib/xcat/plugins";
use lib "$FindBin::Bin/../../xCAT-server/share/xcat/netboot/imgutils";
require sles;
use xCAT::SvrUtils;
use xCAT::Template;
use imgutils;
my $leap_compute_template_path = "$FindBin::Bin/../../xCAT-server/share/xcat/install/sles/compute.leap15.tmpl";
open(my $leap_compute_template_fh, '<', $leap_compute_template_path) or die "Cannot read Leap compute template: $!";
my $leap_compute_template = do { local $/; <$leap_compute_template_fh> };
close($leap_compute_template_fh);
like($leap_compute_template, qr/<product>Leap<\/product>/, 'Leap install template selects Leap base product');
like($leap_compute_template, qr/<self_update config:type="boolean">false<\/self_update>/, 'Leap install template disables installer self-update');
like($leap_compute_template, qr/<do_online_update config:type="boolean">false<\/do_online_update>/, 'Leap install template disables online update');
my $leap_compute_pkglist_path = "$FindBin::Bin/../../xCAT-server/share/xcat/install/sles/compute.leap15.pkglist";
open(my $leap_compute_pkglist_fh, '<', $leap_compute_pkglist_path) or die "Cannot read Leap compute pkglist: $!";
my $leap_compute_pkglist = do { local $/; <$leap_compute_pkglist_fh> };
close($leap_compute_pkglist_fh);
like($leap_compute_pkglist, qr/^\@base$/m, 'Leap compute install pkglist requests a non-empty base pattern');
unlike($leap_compute_pkglist, qr/^(?:insserv-compat|net-tools-deprecated|ntp)$/m, 'Leap compute install pkglist avoids unavailable SLE package names');
my $sle15_netboot_pkglist_path = "$FindBin::Bin/../../xCAT-server/share/xcat/netboot/sles/compute.sle15.pkglist";
open(my $sle15_netboot_pkglist_fh, '<', $sle15_netboot_pkglist_path) or die "Cannot read SLE 15 netboot pkglist: $!";
my $sle15_netboot_pkglist = do { local $/; <$sle15_netboot_pkglist_fh> };
close($sle15_netboot_pkglist_fh);
like($sle15_netboot_pkglist, qr/^xfsprogs$/m, 'SLE 15 netboot pkglist includes xfs tools required by the xCAT dracut module');
is(xCAT::Template::_sle15_install_product_name('Product-SLES'), 'SLES', 'SLE 15 install source keeps the generic SLES product');
is(xCAT::Template::_sle15_install_product_name('Module-Basesystem'), 'sle-module-basesystem', 'SLE 15 install source keeps regular modules');
is(xCAT::Template::_sle15_install_product_name('Module-SAP-Applications'), undef, 'SLE 15 install source skips SAP application module');
is(xCAT::Template::_sle15_install_product_name('Module-SAP-Business-One'), undef, 'SLE 15 install source skips SAP Business One module');
is(xCAT::Template::_sle15_install_product_name('Product-SLES_SAP'), undef, 'SLE 15 install source skips SAP product media');
my $sle_post_common_path = "$FindBin::Bin/../../xCAT-server/share/xcat/install/scripts/post.sles.common";
open(my $sle_post_common_fh, '<', $sle_post_common_path) or die "Cannot read SLE post-install script: $!";
my $sle_post_common = do { local $/; <$sle_post_common_fh> };
close($sle_post_common_fh);
like($sle_post_common, qr/systemctl stop firewalld\.service/, 'SLE post-install script stops firewalld on systemd releases');
like($sle_post_common, qr/systemctl disable firewalld\.service/, 'SLE post-install script disables firewalld after stateful install');
my $tmpdir = tempdir(CLEANUP => 1);
open(my $treeinfo, '>', "$tmpdir/.treeinfo") or die "Cannot write .treeinfo: $!";
print {$treeinfo} <<'EOF';
[release]
name = openSUSE Leap
version = 15.6
[general]
arch = x86_64
family = openSUSE Leap
name = openSUSE Leap 15.6
version = 15.6
platforms = x86_64,xen
[images-x86_64]
kernel = boot/x86_64/loader/linux
initrd = boot/x86_64/loader/initrd
EOF
close($treeinfo);
my ($tree_dist, $tree_arch) = xCAT_plugin::sles::_detect_opensuse_leap_treeinfo($tmpdir);
is($tree_dist, 'leap15.6', 'detects openSUSE Leap distname from .treeinfo');
is($tree_arch, 'x86_64', 'detects openSUSE Leap arch from .treeinfo');
my $media = <<'EOF';
openSUSE - openSUSE-Leap-15.6-NET-x86_64-Build710.3-Media
openSUSE-Leap-15.6-NET-x86_64-Build710.3
1
EOF
my $products = "/ openSUSE-Leap 15.6-1\n";
my ($media_dist, $media_arch) = xCAT_plugin::sles::_detect_opensuse_leap_media($media, $products);
is($media_dist, 'leap15.6', 'detects openSUSE Leap distname from media files');
is($media_arch, 'x86_64', 'detects openSUSE Leap arch from media files');
my ($unsupported_dist) = xCAT_plugin::sles::_detect_opensuse_leap_media(
"openSUSE - openSUSE-Leap-16.0-NET-x86_64-Media\n",
"/ openSUSE-Leap 16.0-1\n"
);
is($unsupported_dist, undef, 'does not detect unvalidated openSUSE Leap 16 media as supported');
ok(xCAT_plugin::sles::_copycd_distname_supported('leap15.6'), 'copycd accepts explicit Leap distname override');
ok(!xCAT_plugin::sles::_copycd_distname_supported('leap16.0'), 'copycd rejects unvalidated Leap 16 distname override');
ok(!xCAT_plugin::sles::_copycd_distname_supported('opensuse15.6'), 'copycd does not accept generic openSUSE distname override');
my %commands = %{ xCAT_plugin::sles->handled_commands };
like($commands{mkinstall}, qr/leap15\.\*/, 'mkinstall handles openSUSE Leap 15 nodes');
like($commands{mknetboot}, qr/leap15\.\*/, 'mknetboot handles openSUSE Leap 15 nodes');
like($commands{mkstatelite}, qr/leap15\.\*/, 'mkstatelite handles openSUSE Leap 15 nodes');
my @os_search = xCAT::SvrUtils::get_os_search_list('leap15.6');
is_deeply(
\@os_search,
[qw(leap15.6 leap15.5 leap15.4 leap15.3 leap15.2 leap15.1 leap15.0 leap15 sle15)],
'openSUSE Leap 15.x searches exact, minor, major, then SLE 15 fallback'
);
my @unsupported_os_search = xCAT::SvrUtils::get_os_search_list('leap16.0');
unlike(
join(' ', @unsupported_os_search),
qr/\bsle16\b/,
'openSUSE Leap 16 does not silently use an unvalidated SLE 16 fallback'
);
my $install_dir = tempdir(CLEANUP => 1);
open(my $tmpl, '>', "$install_dir/compute.leap15.tmpl") or die "Cannot write openSUSE template: $!";
print {$tmpl} "opensuse template\n";
close($tmpl);
open(my $compute_fallback_tmpl, '>', "$install_dir/compute.sle15.tmpl") or die "Cannot write compute SLE template: $!";
print {$compute_fallback_tmpl} "sles template\n";
close($compute_fallback_tmpl);
open(my $fallback_tmpl, '>', "$install_dir/service.sle15.tmpl") or die "Cannot write SLE template: $!";
print {$fallback_tmpl} "sles template\n";
close($fallback_tmpl);
open(my $install_pkglist, '>', "$install_dir/compute.leap15.pkglist") or die "Cannot write openSUSE install pkglist: $!";
print {$install_pkglist} "chrony\n";
close($install_pkglist);
open(my $install_fallback_pkglist, '>', "$install_dir/service.sle15.pkglist") or die "Cannot write SLE install pkglist: $!";
print {$install_fallback_pkglist} "ntp\n";
close($install_fallback_pkglist);
is(
xCAT::SvrUtils::get_tmpl_file_name($install_dir, 'compute', 'leap15.6', 'x86_64'),
"$install_dir/compute.leap15.tmpl",
'openSUSE template lookup prefers leap15 over SLE 15'
);
is(
xCAT::SvrUtils::get_tmpl_file_name($install_dir, 'service', 'leap15.6', 'x86_64'),
"$install_dir/service.sle15.tmpl",
'openSUSE template lookup can fall back to SLE 15'
);
is(
xCAT::SvrUtils::get_pkglist_file_name($install_dir, 'compute', 'leap15.6', 'x86_64'),
"$install_dir/compute.leap15.pkglist",
'openSUSE install pkglist lookup prefers leap15 over SLE 15'
);
is(
xCAT::SvrUtils::get_pkglist_file_name($install_dir, 'service', 'leap15.6', 'x86_64'),
"$install_dir/service.sle15.pkglist",
'openSUSE install pkglist lookup can fall back to SLE 15'
);
my $table_netboot_dir = tempdir(CLEANUP => 1);
open(my $table_opensuse_pkglist, '>', "$table_netboot_dir/compute.leap15.pkglist") or die "Cannot write openSUSE table pkglist: $!";
print {$table_opensuse_pkglist} "zypper\n";
close($table_opensuse_pkglist);
open(my $table_pkglist, '>', "$table_netboot_dir/compute.sle15.pkglist") or die "Cannot write table pkglist: $!";
print {$table_pkglist} "aaa_base\n";
close($table_pkglist);
open(my $table_exlist, '>', "$table_netboot_dir/compute.sle15.exlist") or die "Cannot write table exlist: $!";
print {$table_exlist} "/tmp\n";
close($table_exlist);
open(my $table_postinstall, '>', "$table_netboot_dir/compute.sle15.postinstall") or die "Cannot write table postinstall: $!";
print {$table_postinstall} "#!/bin/sh\n";
close($table_postinstall);
chmod 0755, "$table_netboot_dir/compute.sle15.postinstall";
is(
xCAT::SvrUtils::get_pkglist_file_name($table_netboot_dir, 'compute', 'leap15.6', 'x86_64'),
"$table_netboot_dir/compute.leap15.pkglist",
'openSUSE diskless table lookup prefers leap15 pkglist over SLE 15'
);
unlink "$table_netboot_dir/compute.leap15.pkglist";
is(
xCAT::SvrUtils::get_pkglist_file_name($table_netboot_dir, 'compute', 'leap15.6', 'x86_64', 'sle15'),
"$table_netboot_dir/compute.sle15.pkglist",
'openSUSE diskless table lookup can fall back to SLE 15 pkglist'
);
is(
xCAT::SvrUtils::get_exlist_file_name($table_netboot_dir, 'compute', 'leap15.6', 'x86_64', 'sle15'),
"$table_netboot_dir/compute.sle15.exlist",
'openSUSE diskless table lookup can fall back to SLE 15 exlist'
);
is(
xCAT::SvrUtils::get_postinstall_file_name($table_netboot_dir, 'compute', 'leap15.6', 'x86_64', 'sle15'),
"$table_netboot_dir/compute.sle15.postinstall",
'openSUSE diskless table lookup can fall back to SLE 15 postinstall'
);
my $netboot_dir = tempdir(CLEANUP => 1);
open(my $opensuse_pkglist, '>', "$netboot_dir/compute.leap15.pkglist") or die "Cannot write openSUSE pkglist: $!";
print {$opensuse_pkglist} "zypper\n";
close($opensuse_pkglist);
open(my $pkglist, '>', "$netboot_dir/compute.sle15.pkglist") or die "Cannot write SLE pkglist: $!";
print {$pkglist} "aaa_base\n";
close($pkglist);
my $real_netboot_dir = realpath($netboot_dir) || $netboot_dir;
is(
imgutils::get_profile_def_filename('leap15.6', 'compute', 'x86_64', $netboot_dir, 'pkglist'),
"$real_netboot_dir/compute.leap15.pkglist",
'openSUSE diskless profile lookup prefers leap15 pkglist over SLE 15'
);
unlink "$netboot_dir/compute.leap15.pkglist";
is(
imgutils::get_profile_def_filename('leap15.6', 'compute', 'x86_64', $netboot_dir, 'pkglist'),
"$real_netboot_dir/compute.sle15.pkglist",
'openSUSE diskless profile lookup falls back to SLE 15 pkglist'
);
done_testing();