From 1fa9d1f6fc717be873d0d6b602b575621deed4e4 Mon Sep 17 00:00:00 2001 From: Daniel Hilst <392820+dhilst@users.noreply.github.com> Date: Tue, 29 Sep 2026 18:19:19 -0300 Subject: [PATCH 1/2] test(xcat-core): nodepurge leaves the autoinstall directory of an Ubuntu node nodepurge removes the autoinstall configuration of each node it deletes. The cleanup loop was inline in the nodepurge sub of profilednodes.pm, which no test can load, so the loop moves to xCAT::ProfiledNodeUtils->remove_node_config_files with its behaviour unchanged. nodepurge_autoinst_cleanup.t drives that routine against a scratch directory. It fails here: the Subiquity node keeps its directory, and the preseed file and the .pre and .post scripts are removed. Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com> --- perl-xCAT/xCAT/ProfiledNodeUtils.pm | 26 ++++++++++++ xCAT-server/lib/xcat/plugins/profilednodes.pm | 14 +------ xCAT-test/unit/nodepurge_autoinst_cleanup.t | 40 +++++++++++++++++++ 3 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 xCAT-test/unit/nodepurge_autoinst_cleanup.t diff --git a/perl-xCAT/xCAT/ProfiledNodeUtils.pm b/perl-xCAT/xCAT/ProfiledNodeUtils.pm index 4c634072d..5926cab22 100644 --- a/perl-xCAT/xCAT/ProfiledNodeUtils.pm +++ b/perl-xCAT/xCAT/ProfiledNodeUtils.pm @@ -1585,3 +1585,29 @@ sub cal_netboot { return 0; } } + +#------------------------------------------------------------------------------- + +=head3 remove_node_config_files + Description : Remove the autoinstall configuration of each node in a list. + Arguments : $config_dir - the autoinstall directory, normally /install/autoinst + $nodes - reference to the list of node names + Returns : N/A + Example : + xCAT::ProfiledNodeUtils->remove_node_config_files("/install/autoinst", \@nodes); +=cut + +#------------------------------------------------------------------------------- +sub remove_node_config_files { + my $class = shift; + my $config_dir = shift; + my $nodes = shift; + + foreach my $one_node (@$nodes) { + foreach my $suffix ("", ".pre", ".post") { + my $path = "$config_dir/$one_node$suffix"; + next unless (-e $path); + unlink $path; + } + } +} diff --git a/xCAT-server/lib/xcat/plugins/profilednodes.pm b/xCAT-server/lib/xcat/plugins/profilednodes.pm index 1f4a6d159..c60b5fe37 100644 --- a/xCAT-server/lib/xcat/plugins/profilednodes.pm +++ b/xCAT-server/lib/xcat/plugins/profilednodes.pm @@ -735,20 +735,8 @@ Usage: $warnstr .= "Details: $retstrref->[1]"; } } - # For each node in the noderange remove its configureation files in $config_dir, if file exists setrsp_progress("Removing configuration files..."); - my $config_dir = "/install/autoinst/"; - foreach my $one_node (@$nodes) { - if ( -e "$config_dir/$one_node") { - unlink "$config_dir/$one_node"; - } - if ( -e "$config_dir/$one_node.post") { - unlink "$config_dir/$one_node.post"; - } - if ( -e "$config_dir/$one_node.pre") { - unlink "$config_dir/$one_node.pre"; - } - } + xCAT::ProfiledNodeUtils->remove_node_config_files("/install/autoinst", $nodes); setrsp_progress("Removed all nodes."); setrsp_success($nodes, $warnstr); } diff --git a/xCAT-test/unit/nodepurge_autoinst_cleanup.t b/xCAT-test/unit/nodepurge_autoinst_cleanup.t new file mode 100644 index 000000000..19093fc03 --- /dev/null +++ b/xCAT-test/unit/nodepurge_autoinst_cleanup.t @@ -0,0 +1,40 @@ +#!/usr/bin/env perl +use strict; +use warnings; + +use File::Path qw(mkpath); +use File::Slurper qw(write_text); +use File::Temp qw(tempdir); +use FindBin; +use Test::More; + +use lib "$FindBin::Bin/../../perl-xCAT"; +use xCAT::ProfiledNodeUtils; + +# nodepurge deletes the autoinstall configuration of each node it removes. mkinstall writes that +# configuration as a directory for a Subiquity node and as a plain file for preseed and kickstart, +# so the cleanup must remove both shapes. + +my $dir = tempdir(CLEANUP => 1); + +# A Subiquity node: cloud-init files in a directory named after the node. +mkpath("$dir/subiquitynode"); +write_text("$dir/subiquitynode/$_", "x\n") for qw(meta-data user-data vendor-data); + +# A preseed node: a plain file, with its .pre and .post scripts. +write_text("$dir/$_", "x\n") for qw(preseednode preseednode.pre preseednode.post); + +# othernode is not in the node list, so the routine must leave it alone. +write_text("$dir/othernode", "x\n"); + +# neverinstalled has no configuration at all, so the routine must not die on it. +xCAT::ProfiledNodeUtils->remove_node_config_files( + $dir, ['subiquitynode', 'preseednode', 'neverinstalled']); + +ok(!-e "$dir/subiquitynode", 'the autoinstall directory of a Subiquity node is removed'); +ok(!-e "$dir/preseednode", 'the autoinstall file of a preseed node is removed'); +ok(!-e "$dir/preseednode.pre", 'the .pre script of a preseed node is removed'); +ok(!-e "$dir/preseednode.post", 'the .post script of a preseed node is removed'); +ok(-e "$dir/othernode", 'a node outside the node list keeps its configuration'); + +done_testing(); From 4b73175670c4595914bbc267c7a6808b2c1e15d5 Mon Sep 17 00:00:00 2001 From: Daniel Hilst <392820+dhilst@users.noreply.github.com> Date: Tue, 29 Sep 2026 18:19:32 -0300 Subject: [PATCH 2/2] fix(xcat-core): nodepurge leaves the autoinstall directory of an Ubuntu node After nodepurge removes a Subiquity node, /install/autoinst/ is still on disk with meta-data, user-data and vendor-data in it. user-data carries the root password hash of a node that no longer exists. remove_node_config_files removed each path with unlink. unlink cannot remove a directory, and mkinstall in debian.pm calls mkpath for a Subiquity node, so the node configuration is a directory there and a plain file on the preseed and kickstart paths. The routine now removes a directory with rmtree. nodepurge_autoinst_cleanup.t fails without this change and passes with it. Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com> --- perl-xCAT/xCAT/ProfiledNodeUtils.pm | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/perl-xCAT/xCAT/ProfiledNodeUtils.pm b/perl-xCAT/xCAT/ProfiledNodeUtils.pm index 5926cab22..9b063e776 100644 --- a/perl-xCAT/xCAT/ProfiledNodeUtils.pm +++ b/perl-xCAT/xCAT/ProfiledNodeUtils.pm @@ -4,7 +4,7 @@ package xCAT::ProfiledNodeUtils; use strict; use warnings; use Socket; -use File::Path qw/mkpath/; +use File::Path qw/mkpath rmtree/; use File::Temp qw/tempfile/; use Fcntl qw(:flock); require xCAT::Table; @@ -1607,7 +1607,14 @@ sub remove_node_config_files { foreach my $suffix ("", ".pre", ".post") { my $path = "$config_dir/$one_node$suffix"; next unless (-e $path); - unlink $path; + + # mkinstall writes a directory here for a Subiquity node, with meta-data, + # user-data and vendor-data in it. unlink cannot remove a directory. + if (-d $path) { + rmtree($path); + } else { + unlink $path; + } } } }