mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-05-05 16:49:08 +00:00
Merge pull request #7529 from VersatusHPC/fix/ubuntu-2604-support
Add Ubuntu 26.04 provisioning support
This commit is contained in:
@@ -104,8 +104,8 @@ for package in ${packages[@]}; do
|
||||
fi
|
||||
done
|
||||
|
||||
# Supported distributions
|
||||
dists="saucy trusty utopic xenial bionic focal jammy"
|
||||
# Supported distributions. Set DISTS="jammy noble resolute" to limit local validation builds.
|
||||
dists="${DISTS:-saucy trusty utopic xenial bionic focal jammy noble resolute}"
|
||||
|
||||
c_flag= # xcat-core (trunk-delvel) path
|
||||
d_flag= # xcat-dep (trunk) path
|
||||
|
||||
@@ -122,6 +122,13 @@ The following matrix is the default live validation gate for DHCP backend work.
|
||||
- ``makedhcp -n``; ``kea-dhcp4 -t``; reservation add/query/delete;
|
||||
xNBA shell boot; compute-image boot artifact handoff through kernel,
|
||||
initrd, and root image when image validation is in scope
|
||||
* - Ubuntu 26.04 LTS
|
||||
- ``x86_64``
|
||||
- ``Kea``
|
||||
- ``xNBA shell`` and compute-image handoff
|
||||
- ``makedhcp -n``; ``kea-dhcp4 -t``; reservation add/query/delete;
|
||||
xNBA shell boot; stateful subiquity and stateless compute-image handoff
|
||||
through kernel, initrd, and root image when image validation is in scope
|
||||
|
||||
Kea Boot and Reservation Regression Matrix
|
||||
------------------------------------------
|
||||
@@ -212,18 +219,20 @@ paths.
|
||||
- ``POWER GRUB handoff``
|
||||
- DHCP offer; boot file handoff; POWER boot-path correctness; Genesis
|
||||
shell when Genesis payload validation is in scope
|
||||
* - Ubuntu 26.04 LTS
|
||||
- ``ppc64le``
|
||||
- ``Kea``
|
||||
- ``POWER GRUB handoff``
|
||||
- package installation on ``ppc64el``; DHCP offer; boot file handoff;
|
||||
POWER boot-path correctness; Genesis shell when live validation is in
|
||||
scope
|
||||
|
||||
Current Lab Baseline
|
||||
--------------------
|
||||
|
||||
The current KVM validation hosts are:
|
||||
|
||||
* ``rome01.local.versatushpc.com.br`` for ``x86_64``
|
||||
* ``power.local.versatushpc.com.br`` for ``ppc64le``
|
||||
|
||||
Validation access should use the ``builder`` account and the
|
||||
``id_ed25519_reposync`` SSH key. Avoid relying on ad-hoc root login or
|
||||
one-off cloud-init keys when recording repeatable validation procedure.
|
||||
KVM validation should cover both ``x86_64`` and ``ppc64le`` hosts. Record the
|
||||
repeatable lab access method privately with the validation run instead of
|
||||
embedding site-specific hostnames or credentials in this repository.
|
||||
|
||||
Full Ubuntu 24.04 ``x86_64`` stateless KVM validation required Ubuntu
|
||||
``genimage`` fixes for early BOOTIF handling and a lean initrd driver set.
|
||||
@@ -240,14 +249,14 @@ rendering.
|
||||
|
||||
Current exceptions:
|
||||
|
||||
* Ubuntu 22.04 LTS ISC OMAPI/``omshell`` host reservation updates are blocked by
|
||||
xCAT3 issue ``#11``. The failure reproduces on upstream ``master`` and is not
|
||||
caused by the Kea backend work. ``site.dhcpbackend=auto`` therefore selects
|
||||
Kea for Ubuntu 22.04 and newer releases; live Ubuntu 22.04 Kea validation
|
||||
remains a follow-up matrix row.
|
||||
* Ubuntu 22.04 LTS ISC OMAPI/``omshell`` host reservation updates are
|
||||
unreliable on current upstream code and are not caused by the Kea backend
|
||||
work. ``site.dhcpbackend=auto`` therefore selects Kea for Ubuntu 22.04 and
|
||||
newer releases; live Ubuntu 22.04 Kea validation remains a follow-up matrix
|
||||
row.
|
||||
* Ubuntu ``ppc64le`` package installation is missing required boot packages such
|
||||
as ``goconserver``, ``grub2-xcat``, and ``xcat-genesis-base-ppc64``. This is
|
||||
tracked by xCAT3 issue ``#13`` and is separate from Kea DHCP behavior.
|
||||
tracked separately and is not a Kea DHCP behavior issue.
|
||||
|
||||
Current PR Validation Snapshot
|
||||
------------------------------
|
||||
@@ -319,8 +328,7 @@ backend scope described above.
|
||||
- Raw DHCP fixture on the KVM provisioning bridge sent option 93
|
||||
``0x0010`` from the reserved outside-pool node MAC and received lease
|
||||
``10.241.10.22`` with boot file ``xcat/xnba.efi``; no
|
||||
``ALLOC_FAIL_NO_POOLS`` was observed. xCAT3 issue ``#17`` is closed as
|
||||
completed.
|
||||
``ALLOC_FAIL_NO_POOLS`` was observed.
|
||||
* - Ubuntu 24.04 LTS
|
||||
- ``x86_64``
|
||||
- ``Kea 2.4.1``
|
||||
@@ -339,9 +347,9 @@ backend scope described above.
|
||||
``genesis.kernel.ppc64`` and ``genesis.fs.ppc64.gz`` reached xCAT
|
||||
``shell`` state after replacing the broken ``grub2-xcat 1.0-3`` ppc
|
||||
GRUB core/module tree with the coherent
|
||||
``2.02-0.76.el7.1.snap201905160255`` tree. The remaining xCAT3 issue
|
||||
``#16`` follow-up is package provenance for ``grub2-xcat``, not DHCP or
|
||||
Genesis payload behavior.
|
||||
``2.02-0.76.el7.1.snap201905160255`` tree. The remaining follow-up is
|
||||
package provenance for ``grub2-xcat``, not DHCP or Genesis payload
|
||||
behavior.
|
||||
* - Ubuntu 24.04 LTS
|
||||
- ``ppc64le``
|
||||
- ``Kea 2.4.1``
|
||||
@@ -354,24 +362,28 @@ backend scope described above.
|
||||
Ubuntu LTS KVM Validation Snapshot
|
||||
----------------------------------
|
||||
|
||||
As of April 29, 2026, the Ubuntu LTS KVM validation for the Ubuntu
|
||||
As of May 1, 2026, the Ubuntu LTS KVM validation for the Ubuntu
|
||||
provisioning restoration work has the following result:
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 14 10 10 12 12 42
|
||||
:widths: 14 9 9 12 12 12 12 30
|
||||
|
||||
* - Platform
|
||||
- Arch
|
||||
- Backend
|
||||
- BIOS
|
||||
- UEFI
|
||||
- BIOS Stateless
|
||||
- BIOS Stateful
|
||||
- UEFI Stateless
|
||||
- UEFI Stateful
|
||||
- Notes
|
||||
* - Ubuntu 18.04 LTS
|
||||
- ``x86_64``
|
||||
- ``ISC``
|
||||
- Pass
|
||||
- Pass
|
||||
- Pass
|
||||
- Pass
|
||||
- Stateless and stateful compute boots passed against an Ubuntu 18.04
|
||||
headnode. The 18.04 debian-installer initrd did not include
|
||||
``virtio_blk`` in this KVM environment, so stateful VMs used
|
||||
@@ -384,6 +396,8 @@ provisioning restoration work has the following result:
|
||||
- ``ISC``
|
||||
- Pass
|
||||
- Pass
|
||||
- Pass
|
||||
- Pass
|
||||
- Stateless and stateful compute boots passed. Stateful validation used a
|
||||
manual static reservation workaround for the known forced-ISC OMAPI
|
||||
issue.
|
||||
@@ -392,6 +406,8 @@ provisioning restoration work has the following result:
|
||||
- ``Kea``
|
||||
- Pass
|
||||
- Pass
|
||||
- Pass
|
||||
- Pass
|
||||
- Stateless and stateful compute boots passed. Kea 2.0.2 configuration
|
||||
validation with ``kea-dhcp4 -t`` passed on the Ubuntu 22.04 headnode.
|
||||
``makedns -n`` starts ``bind9`` successfully, and the DHCP section of
|
||||
@@ -401,40 +417,30 @@ provisioning restoration work has the following result:
|
||||
- ``Kea``
|
||||
- Pass
|
||||
- Pass
|
||||
- Pass
|
||||
- Pass
|
||||
- Stateless and stateful compute boots passed. Kea 2.4.1 configuration
|
||||
validation with ``kea-dhcp4 -t`` passed on the Ubuntu 24.04 headnode.
|
||||
``makedns -n`` starts ``bind9`` successfully, and the DHCP section of
|
||||
``xcatprobe xcatmn`` passed on consecutive runs. UEFI validation used
|
||||
OVMF Secure Boot disabled.
|
||||
|
||||
Skipped Rows
|
||||
------------
|
||||
|
||||
The following rows are intentionally not counted in the current PR acceptance
|
||||
table:
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 18 10 12 60
|
||||
|
||||
* - Platform
|
||||
- Arch
|
||||
- Backend
|
||||
- Reason
|
||||
* - Ubuntu 22.04 LTS
|
||||
* - Ubuntu 26.04 LTS
|
||||
- ``x86_64``
|
||||
- ``Kea``
|
||||
- Skipped in this PR. Unit coverage now pins Ubuntu 22.04 to Kea by
|
||||
default because ISC OMAPI/``omshell`` is blocked by xCAT3 issue ``#11``;
|
||||
live KVM validation remains a follow-up row.
|
||||
* - Ubuntu 22.04 LTS
|
||||
- ``ppc64le``
|
||||
- ``Kea``
|
||||
- Skipped for the same Ubuntu 22.04 Kea follow-up validation reason as the
|
||||
``x86_64`` row.
|
||||
- Pass
|
||||
- Pass
|
||||
- Pass
|
||||
- Pass
|
||||
- Stateless and stateful compute boots passed against an Ubuntu 26.04
|
||||
headnode. Kea 3.0.3 configuration validation with ``kea-dhcp4 -t``
|
||||
passed. Stateless BIOS and UEFI nodes reached ``sshd`` after the
|
||||
netboot image was repacked with the recursive postscript download fix;
|
||||
stateful BIOS and UEFI nodes completed Subiquity install and booted from
|
||||
disk. Kea logs showed no ``ALLOC_FAIL_NO_POOLS``. UEFI validation used
|
||||
OVMF Secure Boot disabled.
|
||||
|
||||
External Follow-up Tracking
|
||||
---------------------------
|
||||
Follow-up Tracking
|
||||
------------------
|
||||
|
||||
These issues are outside the DHCP acceptance result but must be referenced when
|
||||
reporting this validation run:
|
||||
@@ -446,12 +452,12 @@ reporting this validation run:
|
||||
* - Issue
|
||||
- Area
|
||||
- Impact
|
||||
* - xCAT3 ``#13``
|
||||
* - Ubuntu ``ppc64le`` packages
|
||||
- Ubuntu ``ppc64le`` packages
|
||||
- Missing ``goconserver``, ``grub2-xcat``, and
|
||||
``xcat-genesis-base-ppc64`` block clean Ubuntu ppc64le package
|
||||
installation.
|
||||
* - xCAT3 ``#16``
|
||||
* - ``ppc64le`` GRUB package
|
||||
- ``ppc64le`` GRUB package
|
||||
- EL10 ppc64le fails with ``grub2-xcat 1.0-3`` because its POWER GRUB
|
||||
core/module tree cannot load the ppc64le Genesis kernel. The live row is
|
||||
|
||||
@@ -310,7 +310,7 @@ Backend selection tests:
|
||||
* ``auto`` uses ISC on EL9
|
||||
* ``auto`` uses ISC on Ubuntu 20.04
|
||||
* ``auto`` uses Kea on EL10
|
||||
* ``auto`` uses Kea on Ubuntu 22.04 and Ubuntu 24.04
|
||||
* ``auto`` uses Kea on Ubuntu 22.04 and newer
|
||||
* forced ``kea`` works on EL9 when Kea packages are installed
|
||||
* forced unavailable backend fails clearly
|
||||
|
||||
@@ -323,6 +323,7 @@ Integration matrix:
|
||||
* Ubuntu 20.04 plus ISC
|
||||
* Ubuntu 22.04 plus Kea
|
||||
* Ubuntu 24.04 plus Kea
|
||||
* Ubuntu 26.04 plus Kea
|
||||
|
||||
Semantic parity tests:
|
||||
|
||||
@@ -348,21 +349,18 @@ Test Infrastructure
|
||||
-------------------
|
||||
|
||||
Existing container-based EL8, EL9, and EL10 tests should be extended for backend
|
||||
coverage. The libvirt/KVM infrastructure on ``rome01.local.versatushpc.com.br``
|
||||
can be used for network and PXE smoke tests that are difficult to validate in
|
||||
ordinary containers.
|
||||
coverage. Libvirt/KVM infrastructure can be used for network and PXE smoke
|
||||
tests that are difficult to validate in ordinary containers.
|
||||
|
||||
Open test infrastructure details to confirm:
|
||||
|
||||
* SSH access method and user for ``rome01.local.versatushpc.com.br``
|
||||
* available base images for EL9, EL10, Ubuntu 18.04, Ubuntu 20.04, Ubuntu
|
||||
22.04, and Ubuntu 24.04
|
||||
22.04, Ubuntu 24.04, and Ubuntu 26.04
|
||||
* libvirt network names and whether isolated DHCP test networks are already
|
||||
available
|
||||
* whether nested or privileged test guests can run DHCP client and PXE tests
|
||||
* cleanup expectations for temporary VMs, networks, and storage volumes
|
||||
* the ``builder`` account and ``id_ed25519_reposync`` SSH key are available for
|
||||
repeatable validation access
|
||||
* repeatable validation access method and credentials
|
||||
|
||||
Manual Validation Snapshot
|
||||
--------------------------
|
||||
|
||||
@@ -154,19 +154,19 @@ sub render_ctrl_agent_config {
|
||||
my %sockets = (
|
||||
dhcp4 => {
|
||||
'socket-type' => 'unix',
|
||||
'socket-name' => $intent->{'dhcp4-socket'} || '/var/run/kea/kea4-ctrl-socket',
|
||||
'socket-name' => $intent->{'dhcp4-socket'} || $self->_kea_control_socket('kea4-ctrl-socket'),
|
||||
},
|
||||
);
|
||||
if ( $intent->{dhcp6} || $intent->{'dhcp6-socket'} ) {
|
||||
$sockets{dhcp6} = {
|
||||
'socket-type' => 'unix',
|
||||
'socket-name' => $intent->{'dhcp6-socket'} || '/var/run/kea/kea6-ctrl-socket',
|
||||
'socket-name' => $intent->{'dhcp6-socket'} || $self->_kea_control_socket('kea6-ctrl-socket'),
|
||||
};
|
||||
}
|
||||
if ( $intent->{ddns} || $intent->{'ddns-socket'} ) {
|
||||
$sockets{d2} = {
|
||||
'socket-type' => 'unix',
|
||||
'socket-name' => $intent->{'ddns-socket'} || '/var/run/kea/kea-ddns-ctrl-socket',
|
||||
'socket-name' => $intent->{'ddns-socket'} || $self->_kea_control_socket('kea-ddns-ctrl-socket'),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ sub load_dhcp4_config {
|
||||
my $content = <$fh>;
|
||||
close($fh);
|
||||
|
||||
my $json = eval { decode_json( _strip_json_comments($content) ) };
|
||||
my $json = eval { _decode_kea_json($content) };
|
||||
return { error => "Unable to parse $path as JSON: $@" } if $@;
|
||||
|
||||
$json->{Dhcp4}{subnet4} ||= [];
|
||||
@@ -236,7 +236,7 @@ sub load_dhcp6_config {
|
||||
my $content = <$fh>;
|
||||
close($fh);
|
||||
|
||||
my $json = eval { decode_json( _strip_json_comments($content) ) };
|
||||
my $json = eval { _decode_kea_json($content) };
|
||||
return { error => "Unable to parse $path as JSON: $@" } if $@;
|
||||
|
||||
$json->{Dhcp6}{subnet6} ||= [];
|
||||
@@ -334,6 +334,15 @@ sub encode_config {
|
||||
return JSON->new->canonical->pretty->encode($config);
|
||||
}
|
||||
|
||||
sub _decode_kea_json {
|
||||
my ($content) = @_;
|
||||
|
||||
# Kea accepts JSON with C/C++ comments and trailing commas. JSON->relaxed
|
||||
# is backend-dependent, so normalize these Kea extensions explicitly before
|
||||
# handing the content to the strict decoder.
|
||||
return decode_json( _strip_json_trailing_commas( _strip_json_comments($content) ) );
|
||||
}
|
||||
|
||||
sub _strip_json_comments {
|
||||
my ($content) = @_;
|
||||
|
||||
@@ -387,6 +396,48 @@ sub _strip_json_comments {
|
||||
return $out;
|
||||
}
|
||||
|
||||
sub _strip_json_trailing_commas {
|
||||
my ($content) = @_;
|
||||
|
||||
my $out = '';
|
||||
my $in_string = 0;
|
||||
my $escaped = 0;
|
||||
my $length = length($content);
|
||||
|
||||
for ( my $idx = 0; $idx < $length; $idx++ ) {
|
||||
my $char = substr( $content, $idx, 1 );
|
||||
|
||||
if ($in_string) {
|
||||
$out .= $char;
|
||||
if ($escaped) {
|
||||
$escaped = 0;
|
||||
} elsif ($char eq '\\') {
|
||||
$escaped = 1;
|
||||
} elsif ($char eq '"') {
|
||||
$in_string = 0;
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
if ($char eq '"') {
|
||||
$in_string = 1;
|
||||
$out .= $char;
|
||||
next;
|
||||
}
|
||||
|
||||
if ($char eq ',') {
|
||||
my $lookahead = $idx + 1;
|
||||
$lookahead++ while $lookahead < $length && substr( $content, $lookahead, 1 ) =~ /\s/;
|
||||
my $next = $lookahead < $length ? substr( $content, $lookahead, 1 ) : '';
|
||||
next if $next eq '}' || $next eq ']';
|
||||
}
|
||||
|
||||
$out .= $char;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
sub write_ctrl_agent_config {
|
||||
my ( $self, $intent, %opts ) = @_;
|
||||
|
||||
@@ -425,7 +476,17 @@ sub _validate_config_with {
|
||||
my $kea = _command_path($command);
|
||||
return { error => "Unable to validate $label configuration: $command was not found." } unless $kea;
|
||||
|
||||
my $cmd = "$kea -t " . _shell_quote($path) . " 2>&1";
|
||||
my $prefix = '';
|
||||
if ( $> == 0 ) {
|
||||
my $kea_user = _kea_user();
|
||||
my $runuser = _command_path('runuser');
|
||||
# Validate as the daemon user when possible so root does not hide
|
||||
# packaged Kea runtime-directory or config-readability failures.
|
||||
$prefix = _shell_quote($runuser) . ' -u ' . _shell_quote($kea_user) . ' -- '
|
||||
if $kea_user && $runuser;
|
||||
}
|
||||
|
||||
my $cmd = $prefix . _shell_quote($kea) . " -t " . _shell_quote($path) . " 2>&1";
|
||||
my $output = `$cmd`;
|
||||
my $rc = $? >> 8;
|
||||
return { error => "$label configuration validation failed: $output" } if $rc != 0;
|
||||
@@ -918,6 +979,15 @@ sub _kea_group {
|
||||
return;
|
||||
}
|
||||
|
||||
sub _kea_user {
|
||||
foreach my $user ( 'kea', '_kea' ) {
|
||||
my @entry = getpwnam($user);
|
||||
return $entry[0] if @entry;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub _kea_service {
|
||||
my ( $self, $service ) = @_;
|
||||
|
||||
@@ -953,6 +1023,28 @@ sub _systemd_unit_dirs {
|
||||
];
|
||||
}
|
||||
|
||||
sub _kea_socket_dir {
|
||||
my ($self) = @_;
|
||||
|
||||
return $self->{kea_socket_dir} if defined $self->{kea_socket_dir};
|
||||
|
||||
# Kea validates Control Agent sockets against its packaged runtime
|
||||
# directory, and newer packages reject /var/run/kea even when it resolves
|
||||
# to /run/kea. Keep the legacy path as the unknown-state fallback for
|
||||
# older Kea builds that validate before the runtime directory exists.
|
||||
foreach my $dir ( @{ $self->{kea_socket_dirs} || [ '/run/kea', '/var/run/kea' ] } ) {
|
||||
return $dir if -d $dir;
|
||||
}
|
||||
|
||||
return '/var/run/kea';
|
||||
}
|
||||
|
||||
sub _kea_control_socket {
|
||||
my ( $self, $socket_name ) = @_;
|
||||
|
||||
return $self->_kea_socket_dir() . "/$socket_name";
|
||||
}
|
||||
|
||||
sub _command_path {
|
||||
my ($command) = @_;
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ my $key;
|
||||
my $field;
|
||||
my $idir;
|
||||
my $node;
|
||||
my $master;
|
||||
my $httpportsuffix;
|
||||
my %loggedrealms;
|
||||
my $lastmachinepassdata;
|
||||
my $localadminenabled; #indicate whether Windows template has local logins enabled or not
|
||||
@@ -86,7 +88,7 @@ sub subvars {
|
||||
## 1, the "xcatmaster" attribute of the node
|
||||
## 2, the ip address of the mn/sn facing the compute node
|
||||
## 3, the site.master
|
||||
my $master;
|
||||
$master = undef;
|
||||
|
||||
#the "xcatmaster" attribute of the node
|
||||
if ($tmpl_hash->{'xcatmaster'}) {
|
||||
@@ -146,7 +148,7 @@ sub subvars {
|
||||
}
|
||||
$ENV{HTTPPORT} = $httpport;
|
||||
|
||||
my $httpportsuffix=":$httpport";
|
||||
$httpportsuffix=":$httpport";
|
||||
#replace the env with the right value so that correct include files can be found
|
||||
$inc =~ s/#ENV:([^#]+)#/envvar($1)/eg;
|
||||
my $res;
|
||||
@@ -364,6 +366,7 @@ sub subvars {
|
||||
$inc =~ s/#INSTALL_SOURCES_IN_PRE#/$source_in_pre/g;
|
||||
if (("ubuntu" eq $platform) || ("debian" eq $platform)) {
|
||||
$inc =~ s/#INCLUDE_OSIMAGE_PKGDIR#/$pkgdirs[-1]/;
|
||||
$inc =~ s/#UBUNTU_SUBIQUITY_APT_CONFIG#/ubuntu_subiquity_apt_config($media_dir)/eg;
|
||||
}
|
||||
$inc =~ s/#WRITEREPO#/$writerepo/g;
|
||||
}
|
||||
@@ -376,8 +379,10 @@ sub subvars {
|
||||
$inc =~ s/#INCLUDE_NOP:([^#^\n]+)#/includefile($1,1,0)/eg;
|
||||
$inc =~ s/#XCATVAR:([^#]+)#/envvar($1)/eg;
|
||||
$inc =~ s/#ENV:([^#]+)#/envvar($1)/eg;
|
||||
$inc =~ s/#UBUNTU_SUBIQUITY_APT_CONFIG#/ubuntu_subiquity_apt_config($media_dir)/eg;
|
||||
$inc =~ s/#MACHINEPASSWORD#/machinepassword()/eg;
|
||||
$inc =~ s/#CRYPT:([^:]+):([^:]+):([^#]+)#/crydb($1,$2,$3)/eg;
|
||||
$inc =~ s/#CRYPTORLOCKED:([^:]+):([^:]+):([^#]+)#/crydb_or_locked($1,$2,$3)/eg;
|
||||
$inc =~ s/#COMMAND:([^#]+)#/command($1)/eg;
|
||||
$inc =~ s/#KICKSTARTNET#/kickstartnetwork()/eg;
|
||||
$inc =~ s/#MIRRORSPEC#/mirrorspec()/eg;
|
||||
@@ -1647,6 +1652,158 @@ sub crydb
|
||||
return xCAT::PasswordUtils::crypt_system_password($table, $kp, \@fields);
|
||||
}
|
||||
|
||||
sub crydb_or_locked
|
||||
{
|
||||
my ( $table, $key, $field ) = @_;
|
||||
my $crypted = crydb( $table, $key, $field );
|
||||
return $crypted if defined($crypted) && length($crypted);
|
||||
return '*';
|
||||
}
|
||||
|
||||
sub ubuntu_subiquity_apt_config
|
||||
{
|
||||
my ($media_dir) = @_;
|
||||
my $use_deb822 = ubuntu_subiquity_uses_deb822_sources($media_dir);
|
||||
my @otherpkg_sources = ubuntu_subiquity_otherpkg_sources();
|
||||
|
||||
my @lines = (
|
||||
' apt:',
|
||||
' preserve_sources_list: false',
|
||||
' fallback: offline-install',
|
||||
' geoip: false',
|
||||
' disable_suites:',
|
||||
' - updates',
|
||||
' - backports',
|
||||
' - security',
|
||||
);
|
||||
|
||||
if ($use_deb822) {
|
||||
if (ubuntu_subiquity_uses_generated_cdrom_source($media_dir)) {
|
||||
# Ubuntu 26.04 and newer Subiquity overlays provide cdrom.sources.
|
||||
# Rendering a second file:///cdrom source triggers apt option conflicts.
|
||||
# Curtin still requires a valid Deb822 template, so write an inactive source.
|
||||
push @lines, ' sources_list: |';
|
||||
push @lines, ' Types: deb';
|
||||
push @lines, ' URIs: http://xcat.invalid/disabled';
|
||||
push @lines, ' Suites: $RELEASE';
|
||||
push @lines, ' Components: main';
|
||||
push @lines, ' Enabled: no';
|
||||
} else {
|
||||
push @lines, ' sources_list: |';
|
||||
push @lines, ' Types: deb';
|
||||
push @lines, ' URIs: file:///cdrom';
|
||||
push @lines, ' Suites: $RELEASE';
|
||||
push @lines, ' Components: main universe restricted multiverse';
|
||||
push @lines, ' Check-Date: no';
|
||||
}
|
||||
|
||||
foreach my $source (@otherpkg_sources) {
|
||||
push @lines, '';
|
||||
push @lines, ' Types: deb';
|
||||
push @lines, " URIs: $source";
|
||||
push @lines, ' Suites: ./';
|
||||
push @lines, ' Components:';
|
||||
push @lines, ' Trusted: yes';
|
||||
}
|
||||
} else {
|
||||
push @lines, ' mirror-selection:';
|
||||
push @lines, ' primary:';
|
||||
push @lines, ' - uri: file:/cdrom';
|
||||
|
||||
if (@otherpkg_sources) {
|
||||
push @lines, ' sources:';
|
||||
my $index = 0;
|
||||
foreach my $source (@otherpkg_sources) {
|
||||
push @lines, " xcat-otherpkgs-$index.list:";
|
||||
push @lines, qq( source: "deb [trusted=yes] $source ./");
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return join( "\n", @lines );
|
||||
}
|
||||
|
||||
sub ubuntu_subiquity_otherpkg_sources
|
||||
{
|
||||
my $nodetype_tab = xCAT::Table->new('nodetype');
|
||||
return unless $nodetype_tab;
|
||||
|
||||
my $nodetype_ent = $nodetype_tab->getNodeAttribs( $node, ['provmethod'] );
|
||||
return unless $nodetype_ent && $nodetype_ent->{provmethod};
|
||||
|
||||
my $linuximage_tab = xCAT::Table->new('linuximage');
|
||||
return unless $linuximage_tab;
|
||||
|
||||
my $linuximage_ent = $linuximage_tab->getAttribs( { imagename => $nodetype_ent->{provmethod} }, 'otherpkgdir' );
|
||||
return unless $linuximage_ent && $linuximage_ent->{otherpkgdir};
|
||||
|
||||
my @sources;
|
||||
foreach my $otherpkgdir ( split( /,/, $linuximage_ent->{otherpkgdir} ) ) {
|
||||
$otherpkgdir =~ s/^\s+|\s+$//g;
|
||||
next unless $otherpkgdir;
|
||||
next if $otherpkgdir !~ m{^https?://} && !ubuntu_subiquity_local_apt_repo($otherpkgdir);
|
||||
|
||||
my $uri = ubuntu_subiquity_pkgdir_uri($otherpkgdir);
|
||||
push @sources, $uri;
|
||||
}
|
||||
|
||||
return @sources;
|
||||
}
|
||||
|
||||
sub ubuntu_subiquity_uses_deb822_sources
|
||||
{
|
||||
my ($media_dir) = @_;
|
||||
my $release = ubuntu_subiquity_release($media_dir);
|
||||
|
||||
return 1 if $release =~ m{ubuntu([2-9][4-9]|[3-9][0-9])\.\d+};
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub ubuntu_subiquity_uses_generated_cdrom_source
|
||||
{
|
||||
my ($media_dir) = @_;
|
||||
my $release = ubuntu_subiquity_release($media_dir);
|
||||
|
||||
return 1 if $release =~ m{ubuntu([2-9][6-9]|[3-9][0-9])\.\d+};
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub ubuntu_subiquity_release
|
||||
{
|
||||
my ($media_dir) = @_;
|
||||
my $release = $media_dir || '';
|
||||
|
||||
if ( !$release ) {
|
||||
my $nodetype_tab = xCAT::Table->new('nodetype');
|
||||
my $nodetype_ent = $nodetype_tab ? $nodetype_tab->getNodeAttribs( $node, ['os'] ) : undef;
|
||||
$release = $nodetype_ent->{os} if $nodetype_ent && $nodetype_ent->{os};
|
||||
}
|
||||
|
||||
return $release;
|
||||
}
|
||||
|
||||
sub ubuntu_subiquity_local_apt_repo
|
||||
{
|
||||
my ($path) = @_;
|
||||
return 0 unless $path && -d $path;
|
||||
return 1 if ( -f "$path/Packages" || -f "$path/Packages.gz" ) && -f "$path/Release";
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub ubuntu_subiquity_pkgdir_uri
|
||||
{
|
||||
my ($path) = @_;
|
||||
$path ||= '/install';
|
||||
$path =~ s/\s+$//;
|
||||
$path =~ s{/+$}{};
|
||||
|
||||
return $path if $path =~ m{^https?://};
|
||||
|
||||
$path = "/$path" if $path !~ m{^/};
|
||||
return "http://$master$httpportsuffix$path";
|
||||
}
|
||||
|
||||
sub tabdb
|
||||
{
|
||||
my $table = shift;
|
||||
|
||||
@@ -100,7 +100,10 @@ if [ ! -x /usr/bin/wget ]; then
|
||||
sleep 36500d
|
||||
fi
|
||||
|
||||
wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -e robots=off -nH --cut-dirs=2 --reject "index.html*" --no-parent -t 20 -T 60 http://${MASTER_IP}:${HTTPPORT}${INSTALLDIR}/postscripts/ -P /xcatpost 2> /tmp/wget.log
|
||||
# These dispatcher scripts are not needed by the legacy post.xcat path. Newer
|
||||
# wget parses HTML-looking regex strings inside downloaded scripts and fails the
|
||||
# whole recursive download on bogus URLs.
|
||||
wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -e robots=off -nH --cut-dirs=2 --reject "index.html*,post.xcat.ng,post.xcat.rhels10" --no-parent -t 20 -T 60 http://${MASTER_IP}:${HTTPPORT}${INSTALLDIR}/postscripts/ -P /xcatpost 2> /tmp/wget.log
|
||||
if [ "$?" != "0" ]; then
|
||||
msgutil_r "$MASTER_IP" "error" "failed to download postscripts from http://$MASTER_IP$INSTALLDIR/postscripts/,check /tmp/wget.log on the node, halt ..." "/var/log/xcat/xcat.log" "$log_label"
|
||||
/tmp/updateflag $MASTER $XCATIPORT "installstatus failed"
|
||||
|
||||
@@ -10,13 +10,14 @@ systemctl stop syslog.socket
|
||||
systemctl stop rsyslog
|
||||
# however, lets make sure . . .
|
||||
[ -e /var/run/rsyslogd.pid ] && kill -TERM $(cat /var/run/rsyslogd.pid)
|
||||
# bare minimum rsyslog.conf to support UDP forwarding
|
||||
cat <<EOF > /tmp/rsyslog.conf
|
||||
# bare minimum rsyslog.conf to support UDP forwarding. Newer Ubuntu releases
|
||||
# run rsyslog under AppArmor and do not allow a config file from /tmp.
|
||||
cat <<EOF > /etc/rsyslog.conf
|
||||
module(load="imuxsock")
|
||||
module(load="imklog" permitnonkernelfacility="on")
|
||||
*.* @#XCATVAR:XCATMASTER#
|
||||
EOF
|
||||
rsyslogd -f /tmp/rsyslog.conf
|
||||
rsyslogd -f /etc/rsyslog.conf
|
||||
log_label="xcat.deployment"
|
||||
logger -t $log_label -p "info" "============deployment starting============"
|
||||
logger -t $log_label -p "info" "Running preseeding early_command Installation script..."
|
||||
|
||||
@@ -12,13 +12,7 @@ autoinstall:
|
||||
allow-pw: true
|
||||
authorized-keys: []
|
||||
install-server: true
|
||||
apt:
|
||||
fallback: offline-install
|
||||
geoip: false
|
||||
disable_suites:
|
||||
- updates
|
||||
- backports
|
||||
- security
|
||||
#UBUNTU_SUBIQUITY_APT_CONFIG#
|
||||
kernel:
|
||||
package: linux-generic
|
||||
user-data:
|
||||
@@ -28,13 +22,20 @@ autoinstall:
|
||||
package_upgrade: false
|
||||
timezone: #TABLE:site:key=timezone:value#
|
||||
chpasswd:
|
||||
list: |
|
||||
root:#CRYPT:passwd:key=system,username=root:password#
|
||||
list:
|
||||
- "root:#CRYPTORLOCKED:passwd:key=system,username=root:password#"
|
||||
expire: false
|
||||
packages:
|
||||
- openssh-server
|
||||
- openssh-client
|
||||
- wget
|
||||
- vim
|
||||
- rsync
|
||||
- busybox-static
|
||||
- gawk
|
||||
- bind9-dnsutils
|
||||
- chrony
|
||||
- gpg
|
||||
early-commands:
|
||||
- |
|
||||
exec >/tmp/pre-install.log 2>&1
|
||||
@@ -90,4 +91,4 @@ autoinstall:
|
||||
curtin in-target --target /target /root/post.script;
|
||||
} >>/target/var/log/xcat/xcat.log 2>&1'
|
||||
error-commands:
|
||||
- tar -c --transform='s/^/#HOSTNAME#-logs\//' /var/crash /var/log/installer /tmp/pre-install.log /autoinstall.yaml 2>/dev/null |nc -l 8080
|
||||
- tar -c --ignore-failed-read --transform='s/^/#HOSTNAME#-logs\//' /var/crash /var/log/installer /tmp/pre-install.log /autoinstall.yaml 2>/dev/null |nc -l 8080
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
bash
|
||||
nfs-common
|
||||
openssl
|
||||
isc-dhcp-client
|
||||
libc-bin
|
||||
openssh-server
|
||||
openssh-client
|
||||
wget
|
||||
vim
|
||||
rsync
|
||||
busybox-static
|
||||
gawk
|
||||
bind9-dnsutils
|
||||
chrony
|
||||
gpg
|
||||
@@ -0,0 +1 @@
|
||||
compute.ubuntu26.04.ppc64el.pkglist
|
||||
@@ -0,0 +1,15 @@
|
||||
bash
|
||||
nfs-common
|
||||
openssl
|
||||
isc-dhcp-client
|
||||
libc-bin
|
||||
openssh-server
|
||||
openssh-client
|
||||
wget
|
||||
vim
|
||||
rsync
|
||||
busybox-static
|
||||
gawk
|
||||
bind9-dnsutils
|
||||
chrony
|
||||
gpg
|
||||
@@ -0,0 +1,20 @@
|
||||
bash
|
||||
ifupdown
|
||||
nfs-common
|
||||
openssl
|
||||
isc-dhcp-client
|
||||
libc-bin
|
||||
linux-image-generic
|
||||
openssh-server
|
||||
openssh-client
|
||||
wget
|
||||
vim
|
||||
rsync
|
||||
busybox-static
|
||||
gawk
|
||||
bind9-dnsutils
|
||||
tar
|
||||
gzip
|
||||
xz-utils
|
||||
cpio
|
||||
chrony
|
||||
@@ -0,0 +1 @@
|
||||
compute.ubuntu26.04.ppc64el.pkglist
|
||||
@@ -0,0 +1,18 @@
|
||||
bash
|
||||
nfs-common
|
||||
openssl
|
||||
isc-dhcp-client
|
||||
libc-bin
|
||||
linux-image-generic
|
||||
openssh-server
|
||||
openssh-client
|
||||
wget
|
||||
rsync
|
||||
busybox-static
|
||||
gawk
|
||||
bind9-dnsutils
|
||||
tar
|
||||
gzip
|
||||
xz-utils
|
||||
cpio
|
||||
chrony
|
||||
@@ -273,7 +273,7 @@ unless ($onlyinitrd) {
|
||||
open($aptconfig, ">", "/tmp/genimage.$$.apt.list");
|
||||
my $repnum = 0;
|
||||
foreach $tmpsrcdir (@aptdirs) {
|
||||
print $aptconfig "deb file://$tmpsrcdir main stable\n\n";
|
||||
print $aptconfig "deb [trusted=yes] file://$tmpsrcdir main stable\n\n";
|
||||
$repnum += 1;
|
||||
}
|
||||
$repnum -= 1;
|
||||
@@ -357,14 +357,18 @@ unless ($onlyinitrd) {
|
||||
open($aptconfig, ">", "$rootimg_dir/etc/apt/sources.list");
|
||||
|
||||
if ($srcdir) {
|
||||
print $aptconfig "deb http://$masternode:$httpport$srcdir $dist main restricted universe\n";
|
||||
print $aptconfig "deb [trusted=yes] http://$masternode:$httpport$srcdir $dist main restricted universe\n";
|
||||
}
|
||||
|
||||
foreach (@pkgdir_internet) {
|
||||
print $aptconfig "deb $_\n";
|
||||
}
|
||||
foreach (@pkgdir_local) {
|
||||
print $aptconfig "deb $_\n";
|
||||
if (/^(http:\/\/\S+)\s+(\S.*)$/) {
|
||||
print $aptconfig "deb [trusted=yes] $1 $2\n";
|
||||
} else {
|
||||
print $aptconfig "deb $_\n";
|
||||
}
|
||||
}
|
||||
|
||||
close($aptconfig);
|
||||
@@ -1254,10 +1258,10 @@ for i in `cat /proc/cmdline`; do
|
||||
done
|
||||
|
||||
if [ -z "\$IFACE" ]; then
|
||||
if iface_exists "\$BOOTIF"; then
|
||||
IFACE=\$BOOTIF
|
||||
elif iface_exists "\$NETDEV"; then
|
||||
if iface_exists "\$NETDEV"; then
|
||||
IFACE=\$NETDEV
|
||||
elif iface_exists "\$BOOTIF"; then
|
||||
IFACE=\$BOOTIF
|
||||
elif iface_exists "\$PRINIC"; then
|
||||
IFACE=\$PRINIC
|
||||
else
|
||||
|
||||
@@ -209,6 +209,16 @@ is( $reservation_policy_config->{Dhcp4}{'reservations-in-subnet'}, JSON::false,
|
||||
is( $reservation_policy_config->{Dhcp4}{'reservations-out-of-pool'}, JSON::false, 'reservation out-of-pool policy can be overridden' );
|
||||
is( $reservation_policy_config->{Dhcp4}{'match-client-id'}, JSON::true, 'client-id lease matching policy can be overridden' );
|
||||
|
||||
my $client_id_policy_json = $backend->render_dhcp4_config(
|
||||
{
|
||||
interfaces => ['eth0'],
|
||||
match_client_id => 1,
|
||||
subnets => [],
|
||||
}
|
||||
);
|
||||
my $client_id_policy_config = decode_json($client_id_policy_json);
|
||||
is( $client_id_policy_config->{Dhcp4}{'match-client-id'}, JSON::true, 'DHCPv4 client-id matching can be explicitly restored' );
|
||||
|
||||
my $comment_dir = tempdir(CLEANUP => 1);
|
||||
my $commented_config = "$comment_dir/kea-dhcp4.conf";
|
||||
my $commented_content = <<'COMMENTED_JSON';
|
||||
@@ -220,9 +230,21 @@ my $commented_content = <<'COMMENTED_JSON';
|
||||
{
|
||||
"id": 1,
|
||||
"subnet": "10.20.0.0/24",
|
||||
"pools": [] // Keep URLs such as "http://server/path" intact.
|
||||
"pools": [], // Keep URLs such as "http://server/path" intact.
|
||||
}
|
||||
]
|
||||
],
|
||||
"loggers": [
|
||||
{
|
||||
"name": "kea-dhcp4",
|
||||
"output-options": [
|
||||
{
|
||||
"output": "stdout",
|
||||
"pattern": "%-5p %m\n",
|
||||
// "flush": false
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
COMMENTED_JSON
|
||||
@@ -374,6 +396,27 @@ is( $ddns_config->{DhcpDdns}{'forward-ddns'}{'ddns-domains'}[0]{name}, 'cluster.
|
||||
my $ctrl_agent_config = decode_json($backend->render_ctrl_agent_config({ 'http-port' => '8000' }));
|
||||
is( $ctrl_agent_config->{'Control-agent'}{'http-port'}, 8000, 'Control Agent HTTP port is numeric' );
|
||||
|
||||
my $runtime_socket_dir = "$unit_dir/run/kea";
|
||||
mkdir "$unit_dir/run" or die "Unable to create $unit_dir/run: $!";
|
||||
mkdir $runtime_socket_dir or die "Unable to create $runtime_socket_dir: $!";
|
||||
|
||||
my $runtime_socket_backend = xCAT::DHCP::Backend::Kea->new( kea_socket_dirs => [ $runtime_socket_dir, "$unit_dir/var/run/kea" ] );
|
||||
my $runtime_socket_config = decode_json($runtime_socket_backend->render_ctrl_agent_config({}));
|
||||
is( $runtime_socket_config->{'Control-agent'}{'control-sockets'}{dhcp4}{'socket-name'}, "$runtime_socket_dir/kea4-ctrl-socket", 'Control Agent socket uses the detected runtime directory' );
|
||||
|
||||
my $legacy_socket_backend = xCAT::DHCP::Backend::Kea->new( kea_socket_dirs => [] );
|
||||
my $legacy_socket_config = decode_json($legacy_socket_backend->render_ctrl_agent_config({}));
|
||||
is( $legacy_socket_config->{'Control-agent'}{'control-sockets'}{dhcp4}{'socket-name'}, '/var/run/kea/kea4-ctrl-socket', 'Control Agent socket falls back to the legacy runtime path when no runtime directory exists' );
|
||||
|
||||
my $socket_backend = xCAT::DHCP::Backend::Kea->new( kea_socket_dir => '/run/kea' );
|
||||
my $ctrl_agent_socket_config = decode_json($socket_backend->render_ctrl_agent_config({ dhcp6 => 1, ddns => 1 }));
|
||||
is( $ctrl_agent_socket_config->{'Control-agent'}{'control-sockets'}{dhcp4}{'socket-name'}, '/run/kea/kea4-ctrl-socket', 'Control Agent DHCPv4 socket uses the detected Kea socket directory' );
|
||||
is( $ctrl_agent_socket_config->{'Control-agent'}{'control-sockets'}{dhcp6}{'socket-name'}, '/run/kea/kea6-ctrl-socket', 'Control Agent DHCPv6 socket uses the detected Kea socket directory' );
|
||||
is( $ctrl_agent_socket_config->{'Control-agent'}{'control-sockets'}{d2}{'socket-name'}, '/run/kea/kea-ddns-ctrl-socket', 'Control Agent DDNS socket uses the detected Kea socket directory' );
|
||||
|
||||
my $explicit_socket_config = decode_json($socket_backend->render_ctrl_agent_config({ 'dhcp4-socket' => '/tmp/kea4.sock' }));
|
||||
is( $explicit_socket_config->{'Control-agent'}{'control-sockets'}{dhcp4}{'socket-name'}, '/tmp/kea4.sock', 'explicit Control Agent socket path overrides the default' );
|
||||
|
||||
my @commands;
|
||||
my $ca_backend = xCAT::DHCP::Backend::Kea->new(
|
||||
control_agent_handler => sub {
|
||||
|
||||
48
xCAT-test/unit/post_xcat_download_policy.t
Normal file
48
xCAT-test/unit/post_xcat_download_policy.t
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use File::Spec;
|
||||
use Test::More;
|
||||
|
||||
my $repo_root = File::Spec->catdir( $FindBin::Bin, '..', '..' );
|
||||
my %scripts = (
|
||||
'legacy install post.xcat' => File::Spec->catfile(
|
||||
$repo_root,
|
||||
'xCAT-server/share/xcat/install/scripts/post.xcat'
|
||||
),
|
||||
'legacy netboot xcatdsklspost' => File::Spec->catfile(
|
||||
$repo_root,
|
||||
'xCAT/postscripts/xcatdsklspost'
|
||||
),
|
||||
);
|
||||
|
||||
foreach my $path ( values %scripts ) {
|
||||
plan skip_all => "$path not found" unless -r $path;
|
||||
}
|
||||
|
||||
foreach my $name ( sort keys %scripts ) {
|
||||
my $path = $scripts{$name};
|
||||
open( my $fh, '<', $path ) or die "Unable to read $path: $!";
|
||||
my $script = do { local $/; <$fh> };
|
||||
close($fh);
|
||||
|
||||
like(
|
||||
$script,
|
||||
qr/--reject\s+"index\.html\*,post\.xcat\.ng,post\.xcat\.rhels10"/,
|
||||
"$name recursive wget ignores dispatcher scripts that contain literal HTML-link regexes"
|
||||
);
|
||||
like(
|
||||
$script,
|
||||
qr/Newer\s+(?:#\s+)?wget\s+parses\s+HTML-looking\s+regex\s+strings/s,
|
||||
"$name download policy documents why dispatcher scripts are excluded"
|
||||
);
|
||||
unlike(
|
||||
$script,
|
||||
qr/<a\s+href=/i,
|
||||
"$name comments do not contain HTML links that wget can recurse into"
|
||||
);
|
||||
}
|
||||
|
||||
done_testing();
|
||||
91
xCAT-test/unit/ubuntu_2604_pkglist.t
Normal file
91
xCAT-test/unit/ubuntu_2604_pkglist.t
Normal file
@@ -0,0 +1,91 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use File::Spec;
|
||||
use Test::More;
|
||||
|
||||
my $repo_root = File::Spec->catdir( $FindBin::Bin, '..', '..' );
|
||||
|
||||
my @pkglist_files = qw(
|
||||
xCAT-server/share/xcat/install/ubuntu/compute.ubuntu26.04.ppc64el.pkglist
|
||||
xCAT-server/share/xcat/install/ubuntu/compute.ubuntu26.04.x86_64.pkglist
|
||||
xCAT-server/share/xcat/netboot/ubuntu/compute.ubuntu26.04.ppc64el.pkglist
|
||||
xCAT-server/share/xcat/netboot/ubuntu/compute.ubuntu26.04.x86_64.pkglist
|
||||
);
|
||||
|
||||
foreach my $file (@pkglist_files) {
|
||||
my $path = File::Spec->catfile( $repo_root, $file );
|
||||
ok( -r $path, "$file exists" );
|
||||
|
||||
open( my $fh, '<', $path ) or die "Unable to read $path: $!";
|
||||
my @packages = grep { /\S/ && !/^\s*#/ } map { chomp; $_ } <$fh>;
|
||||
close($fh);
|
||||
|
||||
my %packages = map { $_ => 1 } @packages;
|
||||
ok( $packages{'bind9-dnsutils'}, "$file uses bind9-dnsutils" );
|
||||
ok( $packages{'chrony'}, "$file uses chrony" );
|
||||
ok( !$packages{'dnsutils'}, "$file avoids removed dnsutils package" );
|
||||
ok( !$packages{'ntp'}, "$file avoids removed ntp package" );
|
||||
ok( !$packages{'ntpdate'}, "$file avoids removed ntpdate package" );
|
||||
}
|
||||
|
||||
foreach my $file (qw(
|
||||
xCAT-server/share/xcat/install/ubuntu/compute.ubuntu26.04.ppc64le.pkglist
|
||||
xCAT-server/share/xcat/netboot/ubuntu/compute.ubuntu26.04.ppc64le.pkglist
|
||||
)) {
|
||||
my $path = File::Spec->catfile( $repo_root, $file );
|
||||
ok( -l $path, "$file aliases ppc64le to ppc64el" );
|
||||
}
|
||||
|
||||
my $subiquity_template = File::Spec->catfile(
|
||||
$repo_root,
|
||||
'xCAT-server/share/xcat/install/ubuntu/compute.subiquity.tmpl'
|
||||
);
|
||||
open( my $tmpl_fh, '<', $subiquity_template ) or die "Unable to read $subiquity_template: $!";
|
||||
my $template = do { local $/; <$tmpl_fh> };
|
||||
close($tmpl_fh);
|
||||
|
||||
like( $template, qr/\n\s+- bind9-dnsutils\n/, 'subiquity template uses bind9-dnsutils' );
|
||||
unlike( $template, qr/\n\s+- dnsutils\n/, 'subiquity template avoids removed dnsutils package' );
|
||||
like( $template, qr/\n\s+- "root:#CRYPTORLOCKED:passwd:key=system,username=root:password#"\n/, 'subiquity uses a locked root password marker when unset' );
|
||||
like( $template, qr/#UBUNTU_SUBIQUITY_APT_CONFIG#/, 'subiquity apt configuration is rendered from osimage package sources' );
|
||||
like( $template, qr/package_update: false/, 'subiquity install does not require online package update' );
|
||||
like( $template, qr/package_upgrade: false/, 'subiquity install does not require online package upgrade' );
|
||||
|
||||
my $template_module = File::Spec->catfile( $repo_root, 'xCAT-server/lib/perl/xCAT/Template.pm' );
|
||||
open( my $module_fh, '<', $template_module ) or die "Unable to read $template_module: $!";
|
||||
my $module = do { local $/; <$module_fh> };
|
||||
close($module_fh);
|
||||
|
||||
like( $module, qr/URIs: http:\/\/xcat\.invalid\/disabled.*Enabled: no/s, 'subiquity renderer disables duplicate archive sources when Subiquity provides cdrom.sources' );
|
||||
like( $module, qr/sources_list: \|/, 'subiquity renderer owns Deb822 install media sources when Subiquity does not provide cdrom.sources' );
|
||||
like( $module, qr/URIs: file:\/\/\/cdrom/, 'subiquity renderer can use the mounted install media as the primary mirror' );
|
||||
like( $module, qr/Check-Date: no/, 'subiquity renderer avoids cdrom Check-Date conflicts' );
|
||||
like( $module, qr/fallback: offline-install/, 'subiquity renderer can complete without external apt mirrors' );
|
||||
like( $module, qr/geoip: false/, 'subiquity renderer does not require external geoip lookup' );
|
||||
like( $module, qr/- updates.*- backports.*- security/s, 'subiquity renderer disables online update suites' );
|
||||
like( $module, qr/mirror-selection:/, 'subiquity renderer keeps classic mirror-selection fallback for older Ubuntu releases' );
|
||||
like( $module, qr/Types: deb.*URIs: \$source.*Suites: \.\/.*Components:.*Trusted: yes/s, 'subiquity renderer includes trusted local xCAT otherpkgdir repositories in Deb822 sources_list' );
|
||||
like( $module, qr/deb \[trusted=yes\] \$source \.\/"/, 'subiquity renderer keeps classic source-list fallback for older Ubuntu releases' );
|
||||
like( $module, qr/-f "\$path\/Release"/, 'subiquity renderer requires indexed otherpkgdir repositories' );
|
||||
|
||||
my $subiquity_pre = File::Spec->catfile(
|
||||
$repo_root,
|
||||
'xCAT-server/share/xcat/install/scripts/pre.ubuntu.subiquity'
|
||||
);
|
||||
open( my $pre_fh, '<', $subiquity_pre ) or die "Unable to read $subiquity_pre: $!";
|
||||
my $pre = do { local $/; <$pre_fh> };
|
||||
close($pre_fh);
|
||||
|
||||
like( $pre, qr/id: efi-part\s+type: partition\s+device: disk-detected\s+size: 512M\s+flag: boot\s+number: 1\s+preserve: false\s+grub_device: true/s, 'subiquity UEFI storage marks the EFI partition as grub device' );
|
||||
like( $pre, qr/id: efi-part-fs\s+type: format\s+fstype: fat32\s+volume: efi-part/s, 'subiquity UEFI storage formats ESP as fat32' );
|
||||
|
||||
my $repo_builder = File::Spec->catfile( $repo_root, 'build-ubunturepo' );
|
||||
open( my $builder_fh, '<', $repo_builder ) or die "Unable to read $repo_builder: $!";
|
||||
my $builder = do { local $/; <$builder_fh> };
|
||||
close($builder_fh);
|
||||
|
||||
like( $builder, qr/dists="\$\{DISTS:-[^"]*\bresolute\b[^"]*\}"/, 'Ubuntu repo builder includes resolute by default' );
|
||||
|
||||
done_testing();
|
||||
@@ -18,11 +18,11 @@ like($tmpl, qr/version:\s*1/, 'template has version: 1');
|
||||
unlike($tmpl, qr/^\s*identity:/m, 'template must not have identity section (use user-data instead)');
|
||||
like($tmpl, qr/kernel:/, 'template has kernel section');
|
||||
like($tmpl, qr/package:\s*linux-generic/, 'template specifies linux-generic kernel');
|
||||
like($tmpl, qr/apt:/, 'template has apt section');
|
||||
like($tmpl, qr/fallback:\s*offline-install/, 'template uses offline-install fallback');
|
||||
like($tmpl, qr/#UBUNTU_SUBIQUITY_APT_CONFIG#/, 'template renders apt section from osimage context');
|
||||
unlike($tmpl, qr/^\s*apt:/m, 'template does not carry a static apt section');
|
||||
unlike($tmpl, qr/WARN: no partitionfile/, 'template does not silently fall back when xCAT pre-script fails');
|
||||
unlike($tmpl, qr/INSTALL_DISK=""/, 'template does not guess an install disk in early-commands');
|
||||
like($tmpl, qr/geoip:\s*false/, 'template disables geoip');
|
||||
unlike($tmpl, qr/geoip:\s*true/, 'template does not enable geoip');
|
||||
|
||||
like($tmpl, qr/ssh:/, 'template has ssh section');
|
||||
like($tmpl, qr/install-server:\s*true/, 'template enables ssh install-server');
|
||||
@@ -57,10 +57,9 @@ unlike($tmpl, qr/wget .*?\|\| true/, 'xCAT control artifact downloads are not ma
|
||||
unlike($tmpl, qr/if \[ -x \/tmp\/getinstdisk \]/, 'getinstdisk not checked with -x');
|
||||
unlike($tmpl, qr/if \[ -x \/tmp\/pre\.sh \]/, 'pre.sh not checked with -x');
|
||||
|
||||
# Regression: disable_suites must be release-independent (no noble-*, jammy-*, etc.)
|
||||
unlike($tmpl, qr/noble-|jammy-|focal-/, 'disable_suites uses release-independent names');
|
||||
like($tmpl, qr/- updates/, 'disable_suites includes updates');
|
||||
like($tmpl, qr/- backports/, 'disable_suites includes backports');
|
||||
like($tmpl, qr/- security/, 'disable_suites includes security');
|
||||
# Regression: apt configuration is generated by Template.pm so release-specific
|
||||
# Subiquity behavior can be handled without cloning this template per release.
|
||||
unlike($tmpl, qr/noble-|jammy-|focal-/, 'template avoids release-specific apt suite names');
|
||||
like($tmpl, qr/#UBUNTU_SUBIQUITY_APT_CONFIG#/, 'template keeps dynamic apt renderer marker');
|
||||
|
||||
done_testing();
|
||||
|
||||
@@ -108,7 +108,10 @@ download_postscripts()
|
||||
rm -rf "$xcatpost"
|
||||
fi
|
||||
|
||||
export LANG=C; wget -l inf -nH -N -r --waitretry=10 --random-wait -e robots=off -T 60 -nH --cut-dirs=2 --reject "index.html*" --no-parent http://$server$INSTALLDIR/postscripts/ -P /$xcatpost 2> /tmp/wget.log
|
||||
# These dispatcher scripts are not needed by the legacy netboot post
|
||||
# path. Newer wget parses HTML-looking regex strings inside downloaded
|
||||
# scripts and fails the whole recursive download on bogus URLs.
|
||||
export LANG=C; wget -l inf -nH -N -r --waitretry=10 --random-wait -e robots=off -T 60 -nH --cut-dirs=2 --reject "index.html*,post.xcat.ng,post.xcat.rhels10" --no-parent http://$server$INSTALLDIR/postscripts/ -P /$xcatpost 2> /tmp/wget.log
|
||||
rc=$?
|
||||
if [ $rc -eq 0 ]; then
|
||||
# return from wget was 0 but some OS do not return errors, so we
|
||||
|
||||
Reference in New Issue
Block a user