From 73a2e73c44674e6474d47bcf199df87f18a83035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Tue, 18 Aug 2026 14:12:12 -0300 Subject: [PATCH] fix(NodeRange): add a nofile option that rejects the ^ file operator The ^ operator in a noderange names a file, and noderange() reads it. Add a nofile option. When nofile is set, noderange() does not open the file. It records that a ^file atom was present, so a caller can fail closed even when the range also holds plain nodes. file_operator_rejected() reports this. noderange() also expands site.excludenodes through a nested call. That range is trusted site data. Expand it without nofile and keep the request's rejection state across the call. A configured exclusion cannot clear the flag, and a ^file in site.excludenodes cannot set it. The default behavior does not change. Forward the option through extnoderange(). --- perl-xCAT/xCAT/NodeRange.pm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/perl-xCAT/xCAT/NodeRange.pm b/perl-xCAT/xCAT/NodeRange.pm index fad97cd24..7ec69971b 100644 --- a/perl-xCAT/xCAT/NodeRange.pm +++ b/perl-xCAT/xCAT/NodeRange.pm @@ -11,6 +11,7 @@ our @EXPORT = qw(noderange nodesmissed); our @EXPORT_OK = qw(extnoderange abbreviate_noderange); my $missingnodes = []; +my $filerejected = 0; my $nodelist; #=xCAT::Table->new('nodelist',-create =>1); my $grptab; @@ -72,6 +73,10 @@ sub nodesmissed { return @$missingnodes; } +sub file_operator_rejected { + return $filerejected; +} + sub reset_db { #workaround, something seems to be trying to use a corrupted reference to grptab @@ -521,7 +526,7 @@ sub extnoderange { #An extended noderange function. Needed by the GUI as the mo } my $return; $retaincache = 1; - $return->{node} = [ noderange($range, $verify) ]; + $return->{node} = [ noderange($range, $verify, 1, nofile => $namedopts->{nofile}) ]; if ($namedopts->{intersectinggroups}) { my %grouphash = (); my $nlent; @@ -626,6 +631,7 @@ sub noderange { my %options = @_; # additional options unless ($options{keepmissing}) { $missingnodes = []; + $filerejected = 0; } unless ($nodelist) { @@ -679,6 +685,7 @@ sub noderange { if ($atom =~ /^\^(.*)$/) { # get a list of nodes from a file my $nrfile = $1; + if ($options{nofile}) { $filerejected = 1; next; } open(my $nrf, '<', $nrfile) or next; while (<$nrf>) { my $line = $_; @@ -724,7 +731,11 @@ sub noderange { my $badnoderange = 0; my @badnodes = (); if ($::XCATSITEVALS{excludenodes}) { - @badnodes = noderange($::XCATSITEVALS{excludenodes}, 1, 0, %options); + my $request_filerejected = $filerejected; + my %exclude_options = %options; + delete $exclude_options{nofile}; + @badnodes = noderange($::XCATSITEVALS{excludenodes}, 1, 0, %exclude_options); + $filerejected = $request_filerejected; foreach my $bnode (@badnodes) { if (!$delnodes{$bnode}) { $delnodes{$bnode} = 1;