rollupdate - add support for translatenames
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@10012 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
parent
9bace51802
commit
d29f467806
@ -20,6 +20,10 @@ require Data::Dumper;
|
||||
require Getopt::Long;
|
||||
require xCAT::MsgUtils;
|
||||
require File::Path;
|
||||
use Text::Balanced qw(extract_bracketed);
|
||||
use Safe;
|
||||
my $evalcpt = new Safe;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
@ -559,6 +563,7 @@ sub rollupdate {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Build and submit scheduler jobs
|
||||
#
|
||||
@ -643,6 +648,15 @@ sub ll_jobs {
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Translate xCAT names to LL names
|
||||
$::XLATED = {};
|
||||
if (defined($::FILEATTRS{translatenames}[0])) {
|
||||
foreach my $xlate_stanza( @{ $::FILEATTRS{'translatenames'} } ) {
|
||||
translate_names($xlate_stanza);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Create LL floating resources for mutual exclusion support
|
||||
# and max_updates
|
||||
if (&create_LL_mutex_resources($updategroup,$::updateall) > 0) {
|
||||
@ -774,16 +788,22 @@ sub ll_jobs {
|
||||
my ( $nodelist, $machinelist );
|
||||
my $machinecount = 0;
|
||||
foreach my $node ( @{ $updategroup->{$ugname} } ) {
|
||||
if ( defined( $machines{$node} )
|
||||
&& ( $machines{$node}{'mstatus'} eq "1" ) ) {
|
||||
$machinelist .= " $machines{$node}{'mname'}";
|
||||
my $xlated_node;
|
||||
if ( defined ($::XLATED{$node}) ){
|
||||
$xlated_node = $::XLATED{$node};
|
||||
} else {
|
||||
$xlated_node = $node;
|
||||
}
|
||||
if ( defined( $machines{$xlated_node} )
|
||||
&& ( $machines{$xlated_node}{'mstatus'} eq "1" ) ) {
|
||||
$machinelist .= " $machines{$xlated_node}{'mname'}";
|
||||
$machinecount++;
|
||||
$nodelist .= ",$node";
|
||||
} elsif ( $run_if_down eq 'yes' ) {
|
||||
if ( defined( $machines{$node} ) ) {
|
||||
if ( defined( $machines{$xlated_node} ) ) {
|
||||
# llmkres -D will allow reserving down nodes as long
|
||||
# as they are present in the machine list
|
||||
$machinelist .= " $machines{$node}{'mname'}";
|
||||
$machinelist .= " $machines{$xlated_node}{'mname'}";
|
||||
$machinecount++;
|
||||
}
|
||||
$nodelist .= ",$node";
|
||||
@ -833,6 +853,11 @@ sub ll_jobs {
|
||||
if (defined($::FILEATTRS{bringuptimeout}[0])){
|
||||
push (@ugdflines, "bringuptimeout=$::FILEATTRS{bringuptimeout}[0]\n");
|
||||
}
|
||||
if (defined($::FILEATTRS{translatenames}[0])){
|
||||
foreach my $xlate_stanza( @{ $::FILEATTRS{'translatenames'} } ) {
|
||||
push (@ugdflines, "translatenames=$xlate_stanza\n");
|
||||
}
|
||||
}
|
||||
if (defined($::FILEATTRS{skipshutdown}[0])){
|
||||
push (@ugdflines, "skipshutdown=$::FILEATTRS{skipshutdown}[0]\n");
|
||||
}
|
||||
@ -884,7 +909,8 @@ sub ll_jobs {
|
||||
}
|
||||
|
||||
# Build reservation callback script
|
||||
my @rcblines;
|
||||
|
||||
my @rcblines;
|
||||
my $rcbcmd = $::FILEATTRS{'reservationcallback'}[0];
|
||||
if (!defined($rcbcmd)){ $rcbcmd = "$::XCATROOT/bin/runrollupdate"; }
|
||||
push (@rcblines, "#!/bin/sh \n");
|
||||
@ -953,6 +979,7 @@ sub ll_jobs {
|
||||
if ( $jcline =~ /Feature/ ) {
|
||||
$jcline =~ s/\"\s+/\"/g;
|
||||
$jcline =~ s/\s+\"/\"/g;
|
||||
$jcline =~ s/\=\"/\= \"/g;
|
||||
}
|
||||
if ($lastcount) {
|
||||
$jcline2 = $jcline;
|
||||
@ -1191,6 +1218,117 @@ sub check_policy {
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head3 translate_names
|
||||
|
||||
Translate xCAT node names to scheduler names as requested by the user
|
||||
|
||||
Arguments: $instructions - translation instructions of the form:
|
||||
<xcat_noderange>:/<pattern>/<replacement>/
|
||||
OR
|
||||
<xcat_noderange>:|<pattern>|<replacement>|
|
||||
Returns:
|
||||
Globals:
|
||||
hash: $::XLATED{$node}=$xlated_name
|
||||
AND $::XLATED{$xlated_name}=$node
|
||||
to allow easy lookup in either direction
|
||||
Error:
|
||||
Example:
|
||||
|
||||
Comments:
|
||||
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# This is a utility function to create a number out of a string, useful for things like round robin algorithms on unnumbered nodes
|
||||
sub mknum {
|
||||
my $string = shift;
|
||||
my $number=0;
|
||||
foreach (unpack("C*",$string)) { #do big endian, then it would make 'fred' and 'free' be one number apart
|
||||
$number += $_;
|
||||
}
|
||||
return $number;
|
||||
}
|
||||
$evalcpt->share('&mknum');
|
||||
$evalcpt->permit('require');
|
||||
|
||||
sub translate_names{
|
||||
my $instructions = shift;
|
||||
|
||||
my ($nr,$regexps) = split( /\:/, $instructions );
|
||||
my @xCATnodes = xCAT::NodeRange::noderange($nr);
|
||||
|
||||
foreach my $xCATnode (@xCATnodes) {
|
||||
my $xlated_node = $xCATnode;
|
||||
my $datum = $regexps;
|
||||
# The following is based on code copied from Table::getNodeAttribs
|
||||
if ($datum =~ /^\/[^\/]*\/[^\/]*\/$/)
|
||||
{
|
||||
my $exp = substr($datum, 1);
|
||||
chop $exp;
|
||||
my @parts = split('/', $exp, 2);
|
||||
$xlated_node =~ s/$parts[0]/$parts[1]/;
|
||||
$datum = $xlated_node;
|
||||
}
|
||||
elsif ($datum =~ /^\|.*\|.*\|$/)
|
||||
{
|
||||
#Perform arithmetic and only arithmetic operations in bracketed issues on the right.
|
||||
#Tricky part: don't allow potentially dangerous code, only eval if
|
||||
#to-be-evaled expression is only made up of ()\d+-/%$
|
||||
#Futher paranoia? use Safe module to make sure I'm good
|
||||
my $exp = substr($datum, 1);
|
||||
chop $exp;
|
||||
my @parts = split('\|', $exp, 2);
|
||||
my $curr;
|
||||
my $next;
|
||||
my $prev;
|
||||
my $retval = $parts[1];
|
||||
($curr, $next, $prev) =
|
||||
extract_bracketed($retval, '()', qr/[^()]*/);
|
||||
|
||||
unless($curr) { #If there were no paramaters to save, treat this one like a plain regex
|
||||
undef $@; #extract_bracketed would have set $@ if it didn't return, undef $@
|
||||
$retval = $xlated_node;
|
||||
$retval =~ s/$parts[0]/$parts[1]/;
|
||||
$datum = $retval;
|
||||
unless ($datum =~ /^$/) { # ignore blank translations
|
||||
$xlated_node=$datum;
|
||||
}
|
||||
next; #skip the redundancy that follows otherwise
|
||||
}
|
||||
while ($curr)
|
||||
{
|
||||
|
||||
#my $next = $comps[0];
|
||||
my $value = $xlated_node;
|
||||
$value =~ s/$parts[0]/$curr/;
|
||||
# $value = $evalcpt->reval('use integer;'.$value);
|
||||
$value = $evalcpt->reval($value);
|
||||
$retval = $prev . $value . $next;
|
||||
#use text::balanced extract_bracketed to parse each atom, make sure nothing but arith operators, parens, and numbers are in it to guard against code execution
|
||||
($curr, $next, $prev) =
|
||||
extract_bracketed($retval, '()', qr/[^()]*/);
|
||||
}
|
||||
undef $@;
|
||||
#At this point, $retval is the expression after being arithmetically contemplated, a generated regex, and therefore
|
||||
#must be applied in total
|
||||
my $answval = $xlated_node;
|
||||
$answval =~ s/$parts[0]/$retval/;
|
||||
$datum = $answval; #$retval;
|
||||
}
|
||||
unless ($datum =~ /^$/) {
|
||||
$::XLATED{$xCATnode}=$datum;
|
||||
$::XLATED{$datum}=$xCATnode;
|
||||
}
|
||||
|
||||
}
|
||||
# print Dumper($::XLATED);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head3 set_LL_feature
|
||||
@ -1788,9 +1926,15 @@ sub runrollupdate {
|
||||
($::DATAATTRS{skipshutdown}[0] eq "1") ) ) {
|
||||
$skipshutdown = 1;
|
||||
}
|
||||
$::XLATED = {};
|
||||
if (defined($::DATAATTRS{translatenames}[0])) {
|
||||
foreach my $xlate_stanza( @{ $::DATAATTRS{'translatenames'} } ) {
|
||||
translate_names($xlate_stanza);
|
||||
}
|
||||
}
|
||||
|
||||
# make sure nodes are in correct state
|
||||
my $hostlist = &get_hostlist;
|
||||
my $hostlist = &get_hostlist();
|
||||
if (! $hostlist ) {
|
||||
if ($::VERBOSE) {
|
||||
open (RULOG, ">>$::LOGDIR/$::LOGFILE");
|
||||
@ -1804,7 +1948,7 @@ sub runrollupdate {
|
||||
}
|
||||
|
||||
my $nltab = xCAT::Table->new('nodelist');
|
||||
my @nodes = split( /\,/, $hostlist );
|
||||
my @nodes = split( /\,/, $hostlist );
|
||||
my $appstatus=xCAT::Utils->getAppStatus(\@nodes,"RollingUpdate");
|
||||
foreach my $node (@nodes) {
|
||||
unless ( defined($appstatus->{$node})
|
||||
@ -2054,16 +2198,25 @@ sub runrollupdate {
|
||||
my $totalwait = 0;
|
||||
my %ll_res;
|
||||
while ($not_done && $totalwait < ($statustimeout * 60)) {
|
||||
my @query_bootnodes;
|
||||
foreach my $bn (keys %ll_res) {
|
||||
if ( ! ($ll_res{$bn}{removed}) ) {
|
||||
push (@query_bootnodes,$bn);
|
||||
}
|
||||
}
|
||||
if ( ! @query_bootnodes ) {
|
||||
@query_bootnodes = @bootnodes;
|
||||
}
|
||||
if ($::VERBOSE) {
|
||||
open (RULOG, ">>$::LOGDIR/$::LOGFILE");
|
||||
print RULOG localtime()." $::ug_name: Checking ".join(",",@bootnodes)." xCAT database $statusattr for value $statusval \n";
|
||||
print RULOG localtime()." $::ug_name: Checking ".join(",",@query_bootnodes)." xCAT database $statusattr for value $statusval \n";
|
||||
close (RULOG);
|
||||
}
|
||||
my $nltab_stats =
|
||||
$nltab->getNodesAttribs( \@bootnodes, [ 'node', $statusattr ] );
|
||||
%ll_res = ();
|
||||
$nltab->getNodesAttribs( \@query_bootnodes, [ 'node', $statusattr ] );
|
||||
# %ll_res = ();
|
||||
$not_done = 0;
|
||||
foreach my $bn (@bootnodes) {
|
||||
foreach my $bn (@query_bootnodes) {
|
||||
if ( $nltab_stats->{$bn}->[0]->{$statusattr} !~ /$statusval/ ) {
|
||||
$ll_res{$bn}{not_done}=1;
|
||||
$not_done = 1;
|
||||
@ -2075,9 +2228,14 @@ sub runrollupdate {
|
||||
($::ll_reservation_id)){
|
||||
my @remove_res;
|
||||
foreach my $bn (keys %ll_res) {
|
||||
if ($ll_res{$bn}{remove} && ! $ll_res{$bn}{removed} ){
|
||||
push (@remove_res,$bn);
|
||||
if (($ll_res{$bn}{remove}) && (! $ll_res{$bn}{removed}) ){
|
||||
if ( defined($::XLATED{$bn}) ) {
|
||||
push (@remove_res,$::XLATED{$bn});
|
||||
} else {
|
||||
push (@remove_res,$bn);
|
||||
}
|
||||
$ll_res{$bn}{removed} = 1;
|
||||
$ll_res{$bn}{not_done} = 0;
|
||||
}
|
||||
}
|
||||
if (@remove_res) {
|
||||
@ -2086,8 +2244,12 @@ sub runrollupdate {
|
||||
}
|
||||
}
|
||||
if ($not_done) {
|
||||
sleep(20);
|
||||
$totalwait += 20;
|
||||
if ($::TEST) {
|
||||
$not_done = 0;
|
||||
} else {
|
||||
sleep(20);
|
||||
$totalwait += 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($not_done) {
|
||||
@ -2109,10 +2271,19 @@ sub runrollupdate {
|
||||
push (@error_nodes,$bn);
|
||||
}
|
||||
}
|
||||
open (RULOG, ">>$::LOGDIR/$::LOGFILE");
|
||||
print RULOG "\n";
|
||||
print RULOG localtime()." ERROR: bringuptimeout exceeded for the following nodes: \n";
|
||||
print RULOG join(",",@error_nodes);
|
||||
print RULOG "\n";
|
||||
xCAT::Utils->setAppStatus(\@error_nodes,"RollingUpdate","ERROR_bringuptimeout_exceeded");
|
||||
if ( defined($remaining_nodes[0]) ) {
|
||||
if ( @remaining_nodes ) {
|
||||
print RULOG localtime()." ERROR: bringuptimeout exceeded for some nodes in a preceding bringuporder. The following nodes will not be powered on: \n";
|
||||
print RULOG join(",",@remaining_nodes);
|
||||
print RULOG "\n";
|
||||
xCAT::Utils->setAppStatus(\@remaining_nodes,"RollingUpdate","ERROR_bringuptimeout_exceeded_for_previous_node");
|
||||
}
|
||||
close (RULOG);
|
||||
}
|
||||
last;
|
||||
}
|
||||
@ -2237,7 +2408,16 @@ sub get_hostlist {
|
||||
print RULOG localtime()." Hostlist: $status_fields[22] \n";
|
||||
close (RULOG);
|
||||
}
|
||||
return $status_fields[22];
|
||||
my $return_list;
|
||||
foreach my $machine (split( /\,/, $status_fields[22])) {
|
||||
if ( defined($::XLATED{$machine}) ) {
|
||||
$return_list = $return_list.','.$::XLATED{$machine};
|
||||
} else {
|
||||
$return_list = $return_list.','.$machine;
|
||||
}
|
||||
}
|
||||
$return_list =~ s/^,//;
|
||||
return $return_list;
|
||||
}
|
||||
|
||||
|
||||
@ -2609,8 +2789,10 @@ sub llreconfig {
|
||||
my $runlocal=0;
|
||||
foreach my $m (@llms) {
|
||||
my ($sm,$rest) = split(/\./,$m);
|
||||
my $xlated_sm = $sm;
|
||||
if ( defined ($::XLATED{$sm}) ) { $xlated_sm = $::XLATED{$sm}; }
|
||||
if (xCAT::Utils->thishostisnot($m)) {
|
||||
push(@llnodes, $sm) unless $have{$sm}++;
|
||||
push(@llnodes, $xlated_sm) unless $have{$sm}++;
|
||||
} else {
|
||||
$runlocal=1;
|
||||
}
|
||||
@ -2634,7 +2816,7 @@ sub llreconfig {
|
||||
if ( scalar(@llnodes) > 0 ) {
|
||||
if ($::VERBOSE) {
|
||||
open (RULOG, ">>$::LOGDIR/$::LOGFILE");
|
||||
print RULOG localtime()." Running command \'xdsh $llcms $llrms $cmd\'\n";
|
||||
print RULOG localtime()." Running command \'xdsh ".join(',',@llnodes)." $cmd\'\n";
|
||||
close (RULOG);
|
||||
}
|
||||
if ($::TEST) {
|
||||
|
@ -122,6 +122,23 @@ mutex_count=2
|
||||
# nodegroup_mutex=block2IO
|
||||
# nodegroup_mutex=block3IO
|
||||
|
||||
# translatenames:
|
||||
# If your scheduler will be using names for nodes that are different from
|
||||
# xCAT node names (e.g. the scheduler is using a different administrative
|
||||
# network), you will need to tell xCAT how to translate from xCAT node names
|
||||
# to the node names registered with your scheduler.
|
||||
#
|
||||
# Syntax:
|
||||
# translatenames=<xCAT_noderange>:/<pattern>/<replacement>/
|
||||
# where <pattern> and <replacement> are perl regular expressions to
|
||||
# be performed on the node names in <xCAT_noderange>.
|
||||
# See the xcatdb man page for more details on using regular expressions.
|
||||
# Multiple translatenames statements are allowed. If an xCAT nodename
|
||||
# exists in more than one xCAT_noderange, the last translated value
|
||||
# will be used.
|
||||
#translatenames=service:|bb(\d+)s(\d+)|bb($1)sn($2)|
|
||||
#translatenames=compute:/\z/-hf2/
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -68,6 +68,24 @@ updateall_nodes=compute
|
||||
updateall_nodecount=3
|
||||
|
||||
|
||||
# translatenames:
|
||||
# If your scheduler will be using names for nodes that are different from
|
||||
# xCAT node names (e.g. the scheduler is using a different administrative
|
||||
# network), you will need to tell xCAT how to translate from xCAT node names
|
||||
# to the node names registered with your scheduler.
|
||||
#
|
||||
# Syntax:
|
||||
# translatenames=<xCAT_noderange>:/<pattern>/<replacement>/
|
||||
# where <pattern> and <replacement> are perl regular expressions to
|
||||
# be performed on the node names in <xCAT_noderange>.
|
||||
# See the xcatdb man page for more details on using regular expressions.
|
||||
# Multiple translatenames statements are allowed. If an xCAT nodename
|
||||
# exists in more than one xCAT_noderange, the last translated value
|
||||
# will be used.
|
||||
#translatenames=service:|bb(\d+)s(\d+)|bb($1)sn($2)|
|
||||
#translatenames=compute:/\z/-hf2/
|
||||
|
||||
|
||||
|
||||
# Scheduler Feature values
|
||||
# Node feature values that will be changed in the scheduler during the
|
||||
|
@ -91,6 +91,23 @@ updategroup=ns11(c4lpar211-c4lpar214)
|
||||
#mutex=block2a,block2b,block2c
|
||||
#mutex=block3a,block3b,block3c
|
||||
|
||||
# translatenames:
|
||||
# If your scheduler will be using names for nodes that are different from
|
||||
# xCAT node names (e.g. the scheduler is using a different administrative
|
||||
# network), you will need to tell xCAT how to translate from xCAT node names
|
||||
# to the node names registered with your scheduler.
|
||||
#
|
||||
# Syntax:
|
||||
# translatenames=<xCAT_noderange>:/<pattern>/<replacement>/
|
||||
# where <pattern> and <replacement> are perl regular expressions to
|
||||
# be performed on the node names in <xCAT_noderange>.
|
||||
# See the xcatdb man page for more details on using regular expressions.
|
||||
# Multiple translatenames statements are allowed. If an xCAT nodename
|
||||
# exists in more than one xCAT_noderange, the last translated value
|
||||
# will be used.
|
||||
#translatenames=service:|bb(\d+)s(\d+)|bb($1)sn($2)|
|
||||
#translatenames=compute:/\z/-hf2/
|
||||
|
||||
|
||||
|
||||
# maxupdates: Maximum number of updategroups that can be updated at one time
|
||||
|
Loading…
Reference in New Issue
Block a user