mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-08-18 17:20:19 +00:00
Merge branch 'master' of github.com:xcat2/xcat-core into codeLatest
This commit is contained in:
@@ -224,7 +224,7 @@ Using the mypostscript template
|
||||
Using the mypostscript template
|
||||
'''''''''''''''''''''''''''''''
|
||||
|
||||
xCAT provides a way for the admin to customize the information that will be provide to the postscripts/postbootscripts when they run on the node. This is done by editing the mypostscript.tmpl file. The attributes that are provided in the shipped mypostscript.tmpl file should not be removed. They are needed by the default xCAT postscripts.
|
||||
xCAT provides a way for the admin to customize the information that will be provided to the postscripts/postbootscripts when they run on the node. This is done by editing the mypostscript.tmpl file. The attributes that are provided in the shipped mypostscript.tmpl file should not be removed. They are needed by the default xCAT postscripts.
|
||||
|
||||
The mypostscript.tmpl, is shipped in the /opt/xcat/share/xcat/mypostscript directory.
|
||||
|
||||
@@ -233,9 +233,9 @@ If the admin customizes the mypostscript.tmpl, they should copy the mypostscript
|
||||
site table precreatemypostscripts attribute
|
||||
'''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
If the site table precreatemypostscripts attribute is set to 1 or yes, it will instruct xcat at nodeset and updatenode time to query the db once for all of the nodes passed into the command and create the mypostscript file for each node and put them in a directory in $TFTPDIR(for example /tftpboot). The created mypostscript.<nodename>. file in the /tftpboot/mypostscripts directory will not be regenerated unless another nodeset or updatenode command is run to that node. This should be used when the system definition has stabilized. It saves time on the updatenode or reboot by not regenerating the mypostscript file.
|
||||
If the site table precreatemypostscripts attribute is set to 1 or yes, it will instruct xCAT at nodeset and updatenode time to query the db once for all of the nodes passed into the command and create the mypostscript file for each node and put them in a directory in $TFTPDIR(for example /tftpboot). The created mypostscript.<nodename>. file in the /tftpboot/mypostscripts directory will not be regenerated unless another nodeset or updatenode command is run to that node. This should be used when the system definition has stabilized. It saves time on the updatenode or reboot by not regenerating the mypostscript file.
|
||||
|
||||
If the precreatemyposcripts attribute is yes, and a database change is made or xcat code is upgraded, then you should run a new nodeset or updatenode to regenerate the /tftpboot/mypostscript/mypostscript.<nodename>. file to pick up the latest database setting. The default for precreatemypostscripts is no/0.
|
||||
If the precreatemyposcripts attribute is yes, and a database change is made or xCAT code is upgraded, then you should run a new nodeset or updatenode to regenerate the /tftpboot/mypostscript/mypostscript.<nodename>. file to pick up the latest database setting. The default for precreatemypostscripts is no/0.
|
||||
|
||||
When you run nodeset or updatenode, it will search the **/install/postscripts/mypostscript.tmpl** first. If the **/install/postscripts/mypostscript.tmpl** exists, it will use that template to generate the mypostscript for each node. Otherwise, it will use **/opt/xcat/share/xcat/mypostscript/mypostscript.tmpl**.
|
||||
|
||||
@@ -245,7 +245,8 @@ Content of the template for mypostscript
|
||||
|
||||
**The attributes that are defined in the shipped mypostscript.tmpl file** should not be removed. The xCAT default postscripts rely on that information to run successfully. **The following will explain the entries in the mypostscript.tmpl file**.
|
||||
|
||||
The SITE_TABLE_ALL_ATTRIBS_EXPORT line in the file directs the code to export all attributes defined in the site table. Note the attributes are not always defined exactly as in the site table to avoid conflict with other table attributes of the same name. For example, the site table master attribute is named SITEMASTER in the generated mypostscript file. ::
|
||||
The SITE_TABLE_ALL_ATTRIBS_EXPORT line in the file directs the code to export all attributes defined in the site table.
|
||||
Note: the attributes are not always defined exactly as in the site table to avoid conflict with other table attributes of the same name. For example, the site table master attribute is named SITEMASTER in the generated mypostscript file. ::
|
||||
|
||||
#SITE_TABLE_ALL_ATTRIBS_EXPORT#
|
||||
|
||||
@@ -404,7 +405,7 @@ Kinds of variables in the template
|
||||
|
||||
VARNAME=#TABLE:tablename:$NODE:attribute#
|
||||
|
||||
For example, to get the new updatstatus attribute from the nodelist table: ::
|
||||
For example, to get the new updatestatus attribute from the nodelist table: ::
|
||||
|
||||
UPDATESTATUS=#TABLE:nodelist:$NODE:updatestatus#
|
||||
export UPDATESTATUS
|
||||
|
@@ -446,6 +446,7 @@ sub sshcfg {
|
||||
#####################################
|
||||
if ( !defined( $mode )) {
|
||||
my ($keytype, $key_string) = split /\ /, $sshkey;
|
||||
chomp($key_string);
|
||||
xCAT::MsgUtils->verbose_message($request, "rspconfig :check sshcfg for user:$logon on node:$server.");
|
||||
my $result = xCAT::PPCcli::send_cmd( $exp, "cat $auth" );
|
||||
my $Rc = shift(@$result);
|
||||
@@ -461,6 +462,7 @@ sub sshcfg {
|
||||
#################################
|
||||
foreach ( @$result ) {
|
||||
my ($tmp1, $tmp2) = split /\ /, $_;
|
||||
chomp($tmp2);
|
||||
if ( "$tmp2" eq "$key_string" ) {
|
||||
return( [[$server,"enabled",SUCCESS]] );
|
||||
}
|
||||
|
@@ -87,6 +87,7 @@ require Exporter;
|
||||
"1359576195.413831" => "rhelhpc6.4",#x86_64, RHEL ComputeNode
|
||||
"1384196516.465862" => "rhelhpc6.5",#x86_64, RHEL ComputeNode
|
||||
"1411733344.599861" => "rhelhpc6.6",#x86_64, RHEL ComputeNode
|
||||
"1435823078.264564" => "rhelhpc6.7",#x86_64, RHEL ComputeNode
|
||||
"1399449226.140088" => "rhelhpc7.0",#x86_64, RHEL ComputeNode
|
||||
"1194015916.783841" => "fedora8",
|
||||
"1194015385.299901" => "fedora8",
|
||||
|
@@ -36,6 +36,7 @@ my $iem_support;
|
||||
my $vpdhash;
|
||||
my %allerrornodes=();
|
||||
my $global_sessdata;
|
||||
my %child_pids;
|
||||
|
||||
my $IPMIXCAT = "/opt/xcat/bin/ipmitool-xcat";
|
||||
my $NON_BLOCK = 1;
|
||||
@@ -1574,12 +1575,12 @@ sub calc_ipmitool_version {
|
||||
# 0 when no response from bmc
|
||||
#----------------------------------------------------------------#
|
||||
sub check_bmc_status_with_ipmitool {
|
||||
my $pre_cmd = shift;
|
||||
my $interval = shift;
|
||||
my $retry = shift;
|
||||
my $count = 0;
|
||||
my $cmd = $pre_cmd." power status";
|
||||
while ($count < $retry) {
|
||||
my $pre_cmd = shift;
|
||||
my $interval = shift;
|
||||
my $retry = shift;
|
||||
my $count = 0;
|
||||
my $cmd = $pre_cmd." power status";
|
||||
while ($count < $retry) {
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
sleep($interval);
|
||||
@@ -1640,7 +1641,6 @@ sub do_firmware_update {
|
||||
$callback,$sessdata->{node},%allerrornodes);
|
||||
return -1;
|
||||
}
|
||||
|
||||
# step 2 reset cold
|
||||
$cmd = $pre_cmd." mc reset cold";
|
||||
$output = xCAT::Utils->runcmd($cmd, -1);
|
||||
@@ -1694,14 +1694,22 @@ sub rflash {
|
||||
if ($sessdata->{subcommand} eq 'check') {
|
||||
my %firmware_version;
|
||||
check_firmware_version($sessdata, \%firmware_version);
|
||||
foreach my $c_id (@{$sessdata->{component_ids}}) {
|
||||
my $msg="";
|
||||
my $i;
|
||||
for ($i = 0; $i < scalar(@{$sessdata->{component_ids}}); $i++) {
|
||||
my $c_id = ${$sessdata->{component_ids}}[$i];
|
||||
my $version = $firmware_version{$c_id};
|
||||
my $format_ver = sprintf("%3d.%02x %02X%02X%02X%02X", $version->[0], $version->[1], $version->[2],
|
||||
my $format_ver = sprintf("%3d.%02x %02X%02X%02X%02X",
|
||||
$version->[0], $version->[1], $version->[2],
|
||||
$version->[3], $version->[4], $version->[5]);
|
||||
xCAT::SvrUtils::sendmsg("Node firmware version for component $c_id: $format_ver",
|
||||
$callback,$sessdata->{node},%allerrornodes);
|
||||
$msg = $msg.$sessdata->{node}.": ".
|
||||
"Node firmware version for component $c_id: $format_ver";
|
||||
if ( $i != scalar(@{$sessdata->{component_ids}}) -1 ) {
|
||||
$msg = $msg."\n";
|
||||
}
|
||||
|
||||
}
|
||||
$callback->({data=>$msg});
|
||||
return;
|
||||
}
|
||||
return do_firmware_update($sessdata);
|
||||
@@ -1718,20 +1726,74 @@ sub rflash {
|
||||
}
|
||||
}
|
||||
|
||||
sub start_rflash_thread {
|
||||
#----------------------------------------------------------------#
|
||||
# Running rflash procedure in a child process
|
||||
# Note (chenglch) If the parent process abort unexpectedly, the
|
||||
# child process can not be terminated by xcat.
|
||||
#----------------------------------------------------------------#
|
||||
sub do_rflash_process {
|
||||
my $node = shift;
|
||||
# NOTE (chenglch): Actually if multiple client or rest api works on the same node,
|
||||
# the bmc of the node may not be protected while rflash is running. As xcat may not
|
||||
# support lock on node level, just require a lock for rflash command for specific node.
|
||||
my $lock = xCAT::Utils->acquire_lock("rflash_$node", $NON_BLOCK);
|
||||
if (! $lock){
|
||||
xCAT::SvrUtils::sendmsg ([1,"rflash is running on $node, please retry after a while"],
|
||||
my $pid = xCAT::Utils->xfork;
|
||||
if ( !defined($pid) ) {
|
||||
xCAT::SvrUtils::sendmsg ([1,"Fork rflash process Error."],
|
||||
$callback,$node,%allerrornodes);
|
||||
return;
|
||||
}
|
||||
donode($node, @_);
|
||||
while (xCAT::IPMI->waitforrsp()) { yield };
|
||||
xCAT::Utils->release_lock($lock, $NON_BLOCK);
|
||||
# child
|
||||
elsif ( $pid == 0 ) {
|
||||
$SIG{CHLD} = $SIG{INT} = $SIG{TERM} = "DEFAULT";
|
||||
# NOTE (chenglch): Actually if multiple client or rest api works on the same node,
|
||||
# the bmc of the node may not be protected while rflash is running. As xcat may not
|
||||
# support lock on node level, just require a lock for rflash command for specific node.
|
||||
my $lock = xCAT::Utils->acquire_lock("rflash_$node", $NON_BLOCK);
|
||||
if (! $lock){
|
||||
xCAT::SvrUtils::sendmsg ([1,"rflash is running on $node, please retry after a while"],
|
||||
$callback,$node,%allerrornodes);
|
||||
exit(1);
|
||||
}
|
||||
donode($node, @_);
|
||||
while (xCAT::IPMI->waitforrsp()) { yield };
|
||||
xCAT::Utils->release_lock($lock, $NON_BLOCK);
|
||||
exit(0);
|
||||
}
|
||||
# parent
|
||||
else {
|
||||
$child_pids{$pid} = $node;
|
||||
}
|
||||
return $pid;
|
||||
}
|
||||
|
||||
sub start_rflash_processes {
|
||||
my $donargs_ptr = shift;
|
||||
my @donargs = @{$donargs_ptr};
|
||||
my $ipmitimeout = shift;
|
||||
my $ipmitrys = shift;
|
||||
my $command = shift;
|
||||
my %namedargs=@_;
|
||||
my $extra=$namedargs{-args};
|
||||
my @exargs=@$extra;
|
||||
|
||||
$SIG{INT} = $SIG{TERM} = sub {
|
||||
foreach ( keys %child_pids ) {
|
||||
kill 2, $_;
|
||||
}
|
||||
exit 0;
|
||||
};
|
||||
$SIG{CHLD} = sub {
|
||||
my $cpid;
|
||||
while ( ( $cpid = waitpid( -1, WNOHANG ) ) > 0 ) {
|
||||
if ( $child_pids{$cpid} ) {
|
||||
delete $child_pids{$cpid};
|
||||
}
|
||||
}
|
||||
};
|
||||
foreach (@donargs) {
|
||||
do_rflash_process( $_->[0],$_->[1],$_->[2],$_->[3],$_->[4],
|
||||
$ipmitimeout,$ipmitrys,$command,-args=>\@exargs);
|
||||
}
|
||||
while ( ( scalar( keys %child_pids ) ) > 0 ) {
|
||||
yield;
|
||||
}
|
||||
}
|
||||
|
||||
sub fpc_firmup_config {
|
||||
@@ -7544,6 +7606,8 @@ sub process_request {
|
||||
if ($request->{command}->[0] eq "rflash") {
|
||||
my %args_hash;
|
||||
if (!defined($extrargs)) {
|
||||
$callback->({error=>"No option or hpm file is provided.",
|
||||
errorcode=>1});
|
||||
return;
|
||||
}
|
||||
foreach my $opt (@$extrargs) {
|
||||
@@ -7561,10 +7625,6 @@ sub process_request {
|
||||
return;
|
||||
}
|
||||
$args_hash{hpm} = $opt;
|
||||
} else {
|
||||
$callback->({error=>"Error command: Option $opt is not supported.",
|
||||
errorcode=>1});
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (exists($args_hash{hpm})){
|
||||
@@ -7634,21 +7694,10 @@ sub process_request {
|
||||
}
|
||||
}
|
||||
|
||||
my $children = 0;
|
||||
my $sub_fds = new IO::Select;
|
||||
# NOTE (chenglch) rflash for one node need about 5-10 minutes. There is no need to rflash node
|
||||
# one by one, so parallel thread is used here.
|
||||
# one by one, fork a process for each node.
|
||||
if ($command eq 'rflash') {
|
||||
my %thread_group;
|
||||
# TODO (chenglch) the size of the noderange maybe very large, so many thread is created here.
|
||||
# Thread pool or limit size is needed.
|
||||
foreach (@donargs) {
|
||||
$thread_group{$_->[0]} = threads->new(\&start_rflash_thread, $_->[0],$_->[1],$_->[2],$_->[3],$_->[4],
|
||||
$ipmitimeout,$ipmitrys,$command,-args=>\@exargs);
|
||||
}
|
||||
foreach (@donargs) {
|
||||
$thread_group{$_->[0]}->join();
|
||||
}
|
||||
start_rflash_processes(\@donargs, $ipmitimeout,$ipmitrys,$command,-args=>\@exargs);
|
||||
}
|
||||
else {
|
||||
foreach (@donargs) {
|
||||
@@ -7664,34 +7713,6 @@ sub process_request {
|
||||
}
|
||||
}
|
||||
while (xCAT::IPMI->waitforrsp()) { yield };
|
||||
if (keys %needbladeinv) {
|
||||
#ok, we have some inventory data that, for now, suggests blade plugin to getdata from blade plugin
|
||||
# my @bladenodes = keys %needbladeinv;
|
||||
# $request->{arg}=['mac'];
|
||||
# $request->{node}=\@bladenodes;
|
||||
# require xCAT_plugin::blade;
|
||||
# xCAT_plugin::blade::process_request($request,$callback);
|
||||
}
|
||||
####return;
|
||||
####while ($sub_fds->count > 0 and $children > 0) {
|
||||
#### my $handlednodes={};
|
||||
#### forward_data($callback,$sub_fds,$handlednodes);
|
||||
#### #update the node status to the nodelist.status table
|
||||
#### if ($check) {
|
||||
#### updateNodeStatus($handlednodes, \@allerrornodes);
|
||||
#### }
|
||||
####}
|
||||
####
|
||||
#####Make sure they get drained, this probably is overkill but shouldn't hurt
|
||||
####my $rc=1;
|
||||
####while ( $rc>0 ) {
|
||||
#### my $handlednodes={};
|
||||
#### $rc=forward_data($callback,$sub_fds,$handlednodes);
|
||||
#### #update the node status to the nodelist.status table
|
||||
#### if ($check) {
|
||||
#### updateNodeStatus($handlednodes, \@allerrornodes);
|
||||
#### }
|
||||
####}
|
||||
|
||||
if ($check) {
|
||||
#print "allerrornodes=@allerrornodes\n";
|
||||
|
Reference in New Issue
Block a user