2012-09-07 08:19:36 +00:00
# IBM(c) 2012 EPL license http://www.eclipse.org/legal/epl-v10.html
#-------------------------------------------------------
= head1
2012-10-08 08:40:30 +00:00
xCAT plugin to support Profiled nodes management
2012-09-07 08:19:36 +00:00
= cut
#-------------------------------------------------------
2012-10-08 08:40:30 +00:00
package xCAT_plugin::profilednodes ;
2012-09-07 08:19:36 +00:00
use strict ;
use warnings ;
2012-11-01 09:19:19 +00:00
use Getopt::Long qw( :config no_ignore_case ) ;
2012-11-05 15:00:12 +00:00
use Data::Dumper ;
2012-09-07 08:19:36 +00:00
require xCAT::Table ;
require xCAT::Utils ;
require xCAT::TableUtils ;
require xCAT::NetworkUtils ;
require xCAT::MsgUtils ;
2014-01-27 05:52:33 +00:00
require xCAT::CFMUtils ;
2012-10-08 08:40:30 +00:00
require xCAT::ProfiledNodeUtils ;
2012-09-07 08:19:36 +00:00
# Globals.
# These 2 global variables are for storing the parse result of hostinfo file.
2013-01-08 04:47:39 +00:00
# These 2 global varialbes are set in lib xCAT::ProfiledNodeUtils->parse_nodeinfo_file.
#%::profiledNodeAttrs;
#@::profiledNodeObjNames;
2012-09-07 08:19:36 +00:00
# All database records.
my % allhostnames ;
my % allbmcips ;
my % allmacs ;
2013-09-23 06:45:43 +00:00
my % allcecs ;
2014-08-26 06:11:31 +00:00
my % alllparids ;
2013-06-26 09:41:39 +00:00
my % allmacsupper ;
2012-09-07 08:19:36 +00:00
my % allips ;
my % allinstallips ;
my % allnicips ;
my % allracks ;
my % allchassis ;
2013-04-17 07:06:57 +00:00
my % allswitches ;
2013-05-23 07:59:27 +00:00
my % all_switchports ;
2013-04-17 07:06:57 +00:00
2014-06-13 06:34:28 +00:00
my @ switch_records ;
2012-12-13 02:00:48 +00:00
# The array of all chassis which is special CMM
my % allcmmchassis ;
2013-03-29 05:58:26 +00:00
my % allothernics ;
2012-09-07 08:19:36 +00:00
# Define parameters for xcat requests.
my $ request ;
my $ callback ;
my $ request_command ;
my $ command ;
my $ args ;
# Put arguments in a hash.
my % args_dict ;
2014-04-18 07:45:44 +00:00
my % general_arg ;
2012-09-07 08:19:36 +00:00
#-------------------------------------------------------
= head3 handled_commands
Return list of commands handled by this plugin
= cut
#-------------------------------------------------------
sub handled_commands {
return {
2012-10-08 08:40:30 +00:00
nodeimport = > 'profilednodes' ,
nodepurge = > 'profilednodes' ,
nodechprofile = > 'profilednodes' ,
2013-01-25 08:55:14 +00:00
noderegenips = > 'profilednodes' ,
2012-10-08 08:40:30 +00:00
noderefresh = > 'profilednodes' ,
nodediscoverstart = > 'profilednodes' ,
nodediscoverstop = > 'profilednodes' ,
nodediscoverls = > 'profilednodes' ,
2013-04-06 09:07:21 +00:00
#nodediscoverstatus => 'profilednodes',
2012-10-12 07:11:26 +00:00
nodeaddunmged = > 'profilednodes' ,
nodechmac = > 'profilednodes' ,
2012-10-08 08:40:30 +00:00
findme = > 'profilednodes' ,
2012-09-07 08:19:36 +00:00
} ;
}
#-------------------------------------------------------
= head3 process_request
Process the command . This is the main call .
= cut
#-------------------------------------------------------
sub process_request {
$ request = shift ;
$ callback = shift ;
2012-10-12 07:11:26 +00:00
#$::CALLBACK = $callback;
2012-09-07 08:19:36 +00:00
$ request_command = shift ;
$ command = $ request - > { command } - > [ 0 ] ;
$ args = $ request - > { arg } ;
2012-09-27 08:56:19 +00:00
2014-04-18 07:45:44 +00:00
my $ gereral_arg = get_general_args ( ) ;
2013-01-31 07:58:08 +00:00
# There is no need to acquire lock for command nodediscoverstatus, nodediscoverls and noderegenips.
2012-10-31 05:22:43 +00:00
if ( $ command eq "nodediscoverstatus" ) {
nodediscoverstatus ( ) ;
return ;
} elsif ( $ command eq "nodediscoverls" ) {
nodediscoverls ( ) ;
return ;
2013-01-31 07:58:08 +00:00
} elsif ( $ command eq "noderegenips" ) {
noderegenips ( ) ;
return ;
2012-10-31 05:22:43 +00:00
}
2012-09-27 08:56:19 +00:00
2014-04-18 07:45:44 +00:00
my $ non_block = 1 ;
2014-06-13 06:34:28 +00:00
if ( defined $ general_arg { 'blockmode' } ) {
if ( $ general_arg { 'blockmode' } == 1 ) {
$ non_block = 0 ;
}
2014-04-18 07:45:44 +00:00
}
my $ lock = xCAT::Utils - > acquire_lock ( "nodemgmt" , $ non_block ) ;
2012-10-22 09:37:09 +00:00
if ( ! $ lock ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Cannot acquire lock, another process is already running." ) ;
2012-09-27 08:56:19 +00:00
return ;
}
# These commands should make sure no discover is running.
2012-10-12 07:11:26 +00:00
if ( grep { $ _ eq $ command } ( "nodeimport" , "nodepurge" , "nodechprofile" , "nodeaddunmged" , "nodechmac" ) ) {
2012-10-08 08:40:30 +00:00
my $ discover_running = xCAT::ProfiledNodeUtils - > is_discover_started ( ) ;
2012-09-27 08:56:19 +00:00
if ( $ discover_running ) {
2013-01-15 01:56:16 +00:00
my % errormsg_dict = (
'nodeimport' = > 'import nodes' ,
'nodepurge' = > 'remove nodes' ,
'nodechprofile' = > 'change profiles' ,
'nodeaddunmged' = > 'add devices' ,
'nodechmac' = > 'change MAC address'
) ;
setrsp_errormsg ( "Cannot $errormsg_dict{$command} while node discovery is running." ) ;
2014-04-18 07:45:44 +00:00
xCAT::Utils - > release_lock ( $ lock , $ non_block ) ;
2012-09-27 08:56:19 +00:00
return ;
}
}
2012-09-07 08:19:36 +00:00
2012-10-08 08:40:30 +00:00
if ( $ command eq "nodeimport" ) {
2012-10-31 05:22:43 +00:00
nodeimport ( ) ;
2012-10-08 08:40:30 +00:00
} elsif ( $ command eq "nodepurge" ) {
nodepurge ( ) ;
} elsif ( $ command eq "nodechprofile" ) {
nodechprofile ( ) ;
} elsif ( $ command eq "noderefresh" ) {
noderefresh ( ) ;
} elsif ( $ command eq "nodediscoverstart" ) {
nodediscoverstart ( ) ;
} elsif ( $ command eq "nodediscoverstop" ) {
nodediscoverstop ( ) ;
2012-09-27 08:56:19 +00:00
} elsif ( $ command eq "findme" ) {
findme ( ) ;
2012-10-12 07:11:26 +00:00
} elsif ( $ command eq "nodeaddunmged" ) {
nodeaddunmged ( ) ;
} elsif ( $ command eq "nodechmac" ) {
nodechmac ( ) ;
2012-09-07 08:19:36 +00:00
}
2012-09-27 08:56:19 +00:00
2014-04-18 07:45:44 +00:00
xCAT::Utils - > release_lock ( $ lock , $ non_block ) ;
}
sub get_general_args
{
my ( $ help , $ ver , $ blockmode ) ;
% general_arg = ( ) ;
@ ARGV = ( ) ;
if ( $ args ) {
@ ARGV = @$ args ;
}
GetOptions (
'h|help' = > \ $ help ,
'v|version' = > \ $ ver ,
'b|block' = > \ $ blockmode ,
) ;
if ( $ help ) {
$ general_arg { 'help' } = 1 ;
}
if ( $ ver ) {
$ general_arg { 'version' } = 1 ;
}
if ( $ blockmode ) {
$ general_arg { 'blockmode' } = 1 ;
}
2012-09-07 08:19:36 +00:00
}
#-------------------------------------------------------
= head3 parse_args
Description : Parse arguments . We placed arguments into a directory % args_dict
Arguments : args - args of xCAT requests .
Returns : undef - parse succeed .
A string - parse arguments failed , the return value is error message .
= cut
#-----------------------------------------------------
sub parse_args {
2013-01-25 08:55:14 +00:00
% args_dict = ( ) ;
2012-11-01 09:19:19 +00:00
foreach my $ arg ( @ ARGV ) {
2012-09-07 08:19:36 +00:00
my @ argarray = split ( /=/ , $ arg ) ;
my $ arglen = @ argarray ;
if ( $ arglen > 2 ) {
2012-11-28 05:39:09 +00:00
return "Illegal argument $arg specified." ;
2012-09-07 08:19:36 +00:00
}
# translate the profile names into real group names in db.
2013-07-22 06:54:47 +00:00
if ( $ argarray [ 1 ] )
{
if ( $ argarray [ 0 ] eq "networkprofile" ) {
$ args_dict { $ argarray [ 0 ] } = "__NetworkProfile_" . $ argarray [ 1 ] ;
} elsif ( $ argarray [ 0 ] eq "imageprofile" ) {
$ args_dict { $ argarray [ 0 ] } = "__ImageProfile_" . $ argarray [ 1 ] ;
} elsif ( $ argarray [ 0 ] eq "hardwareprofile" ) {
$ args_dict { $ argarray [ 0 ] } = "__HardwareProfile_" . $ argarray [ 1 ] ;
} else {
$ args_dict { $ argarray [ 0 ] } = $ argarray [ 1 ] ;
}
2012-09-07 08:19:36 +00:00
}
}
return undef ;
}
2012-11-01 09:19:19 +00:00
sub validate_args {
my $ helpmsg = shift ;
my $ enabledparamsref = shift ;
my $ mandatoryparamsref = shift ;
2014-06-13 06:34:28 +00:00
if ( defined $ general_arg { 'help' } ) {
if ( $ general_arg { 'help' } == 1 ) {
my % process_help_commands = (
'nodediscoverstart' = > 1 ,
'nodediscoverstop' = > 1 ,
'nodediscoverls' = > 1 ,
'nodediscoverstatus' = > 1 ,
) ;
# do not process help message for these noddiscover* commands, cover them in seqdiscovery.pm
unless ( $ process_help_commands { $ command } == 1 ) {
setrsp_infostr ( $ helpmsg ) ;
return 0 ;
}
2014-04-18 07:45:44 +00:00
}
2012-11-01 09:19:19 +00:00
}
2013-04-01 10:32:07 +00:00
2012-11-01 09:19:19 +00:00
my $ parseret = parse_args ( ) ;
if ( $ parseret ) {
setrsp_errormsg ( $ parseret ) ;
return 0 ;
}
2013-04-06 09:07:21 +00:00
# If specified the nodrange= arg, we asume that the sequential discovery will be started
if ( defined $ args_dict { 'noderange' } ) {
# This is a sequential discovery request, just return to make sequential to handle it
return 0 ;
2012-11-01 09:19:19 +00:00
}
# Mandatory arguments.
my @ mandatoryparams = ( ) ;
if ( $ mandatoryparamsref ) {
@ mandatoryparams = @$ mandatoryparamsref ;
}
2013-04-12 08:08:17 +00:00
if ( @ mandatoryparams ) {
my $ profiledis ;
foreach ( @ mandatoryparams ) {
if ( exists ( $ args_dict { $ _ } ) ) {
# this is for profile discovery
$ profiledis = 1 ;
last ;
}
}
unless ( $ profiledis ) {
# Not see the nodrange and 'networkprofile', 'imageprofile', 'hostnameformat'
# return to make sequential discovery to display help message
return 0 ;
2013-04-06 09:07:21 +00:00
}
}
2012-11-01 09:19:19 +00:00
foreach ( @ mandatoryparams ) {
if ( ! exists ( $ args_dict { $ _ } ) ) {
2013-04-01 10:32:07 +00:00
setrsp_errormsg ( "For profile discovery, the $_ option must be specified." ) ;
setrsp_infostr ( $ helpmsg ) ;
2012-11-01 09:19:19 +00:00
return 0 ;
}
}
2013-04-06 09:07:21 +00:00
# Make sure the specified parameters are valid ones.
my @ enabledparams = ( ) ;
if ( $ enabledparamsref ) {
@ enabledparams = @$ enabledparamsref ;
}
foreach my $ argname ( keys % args_dict ) {
if ( ! grep { $ _ eq $ argname } @ enabledparams ) {
setrsp_errormsg ( "Illegal attribute $argname specified." ) ;
setrsp_infostr ( $ helpmsg ) ;
return 0 ;
}
}
2012-11-01 09:19:19 +00:00
return 1 ;
}
2012-09-07 08:19:36 +00:00
#-------------------------------------------------------
2012-10-08 08:40:30 +00:00
= head3 nodeimport
2012-09-07 08:19:36 +00:00
2012-09-11 06:14:50 +00:00
Description :
2012-10-08 08:40:30 +00:00
Create profiled nodes by importing hostinfo file .
This sub maps to request " nodeimport " , we need to call this command from CLI like following steps :
# ln -s /opt/xcat/bin/xcatclientnnr /opt/xcat/bin/nodeimport
# nodeimport file=/root/hostinfo.file networkprofile=network_cn imageprofile=rhel63_cn hardwareprofile=ipmi groups=group1,group2
2012-09-11 06:14:50 +00:00
The hostinfo file should be written like: ( MAC address is mandatory attribute )
# Auto generate hostname for this node entry.
__hostname__:
mac = 11 : 11 : 11 : 11 : 11 : 11
# Specified hostname node.
node01:
mac = 22 : 22 : 22 : 22 : 22 : 22
After this call finished , the compute node ' s info will be updated automatically in /etc/ hosts , dns config , dhcp config , TFTP config ...
2012-09-07 08:19:36 +00:00
= cut
#-------------------------------------------------------
2012-10-08 08:40:30 +00:00
sub nodeimport {
2012-09-07 08:19:36 +00:00
# Parse arges.
2012-10-12 07:11:26 +00:00
xCAT::MsgUtils - > message ( 'S' , "Import profiled nodes through hostinfo file." ) ;
2012-11-01 09:19:19 +00:00
my $ helpmsg = " nodeimport: create profiled nodes by importing hostinfo file .
Usage:
\ tnodeimport file = < hostinfo file > networkprofile = <networkprofile> imageprofile = <imageprofile> hostnameformat = <hostnameformat> [ hardwareprofile = <hardwareprofile> ] [ groups = <groups> ]
\ tnodeimport [ - h | - - help ]
\ tnodeimport { - v | - - version } " ;
2012-09-27 08:56:19 +00:00
my @ enabledparams = ( 'file' , 'groups' , 'networkprofile' , 'hardwareprofile' , 'imageprofile' , 'hostnameformat' ) ;
2012-11-01 09:19:19 +00:00
my @ mandatoryparams = ( 'file' , 'networkprofile' , 'imageprofile' , 'hostnameformat' ) ;
my $ ret = validate_args ( $ helpmsg , \ @ enabledparams , \ @ mandatoryparams ) ;
if ( ! $ ret ) {
return ;
2012-09-07 08:19:36 +00:00
}
2012-09-27 08:56:19 +00:00
if ( ! ( - e $ args_dict { 'file' } ) ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Node information file does not exist." ) ;
2012-09-07 08:19:36 +00:00
return ;
}
2012-10-29 08:59:14 +00:00
# validate hostnameformat:
my $ nameformattype = xCAT::ProfiledNodeUtils - > get_hostname_format_type ( $ args_dict { 'hostnameformat' } ) ;
if ( $ nameformattype eq "unknown" ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Invalid node name format: $args_dict{'hostnameformat'}" ) ;
2012-10-29 08:59:14 +00:00
return ;
}
2012-12-13 02:00:48 +00:00
# Validate if profile consistent
my $ imageprofile = $ args_dict { 'imageprofile' } ;
my $ networkprofile = $ args_dict { 'networkprofile' } ;
my $ hardwareprofile = $ args_dict { 'hardwareprofile' } ;
my ( $ returncode , $ errmsg ) = xCAT::ProfiledNodeUtils - > check_profile_consistent ( $ imageprofile , $ networkprofile , $ hardwareprofile ) ;
if ( not $ returncode ) {
setrsp_errormsg ( $ errmsg ) ;
return ;
}
2012-10-29 08:59:14 +00:00
2012-09-07 08:19:36 +00:00
# Get database records: all hostnames, all ips, all racks...
2012-10-12 07:11:26 +00:00
xCAT::MsgUtils - > message ( 'S' , "Getting database records." ) ;
2012-10-08 08:40:30 +00:00
my $ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'nodelist' , 'node' ) ;
2012-09-07 08:19:36 +00:00
% allhostnames = %$ recordsref ;
2012-10-08 08:40:30 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'ipmi' , 'bmc' ) ;
2012-09-07 08:19:36 +00:00
% allbmcips = %$ recordsref ;
2012-10-08 08:40:30 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'mac' , 'mac' ) ;
2012-09-07 08:19:36 +00:00
% allmacs = %$ recordsref ;
2012-12-13 02:00:48 +00:00
# Get all FSP ip address
$ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'ppc' , 'hcp' ) ;
my % allfspips = %$ recordsref ;
2013-04-17 07:06:57 +00:00
# Get all switches name
2013-08-07 05:40:05 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_db_switches ( ) ;
2013-04-17 07:06:57 +00:00
% allswitches = %$ recordsref ;
2013-05-23 07:59:27 +00:00
# Get all switches_switchport
$ recordsref = xCAT::ProfiledNodeUtils - > get_db_switchports ( ) ;
% all_switchports = %$ recordsref ;
2013-06-26 09:41:39 +00:00
# MAC records looks like: "01:02:03:04:05:0E!node5.01:02:03:05:0F!node6-eth1". We want to get the real mac addres.
2012-09-27 08:56:19 +00:00
foreach ( keys % allmacs ) {
my @ hostentries = split ( /\|/ , $ _ ) ;
foreach my $ hostandmac ( @ hostentries ) {
my ( $ macstr , $ machostname ) = split ( "!" , $ hostandmac ) ;
$ allmacs { $ macstr } = 0 ;
}
}
2013-08-05 07:11:45 +00:00
% allmacsupper = ( ) ;
2013-06-26 09:41:39 +00:00
foreach ( keys % allmacs ) {
$ allmacsupper { uc ( $ _ ) } = 0 ;
}
2012-10-08 08:40:30 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'hosts' , 'ip' ) ;
2012-09-07 08:19:36 +00:00
% allinstallips = %$ recordsref ;
$ recordsref = xCAT::NetworkUtils - > get_all_nicips ( 1 ) ;
% allips = %$ recordsref ;
# Merge all BMC IPs and install IPs into allips.
2012-12-13 02:00:48 +00:00
% allips = ( % allips , % allbmcips , % allinstallips , % allfspips ) ;
2012-09-07 08:19:36 +00:00
2013-09-23 06:45:43 +00:00
# Get all CEC names
$ recordsref = xCAT::ProfiledNodeUtils - > get_all_cecs ( 1 ) ;
% allcecs = %$ recordsref ;
2014-08-26 06:11:31 +00:00
# Get all LPAR ids
$ recordsref = xCAT::ProfiledNodeUtils - > get_all_lparids ( \ % allcecs ) ;
% alllparids = %$ recordsref ;
2013-09-23 06:45:43 +00:00
2012-09-27 08:56:19 +00:00
#TODO: can not use getallnode to get rack infos.
2012-10-12 07:11:26 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_all_rack ( 1 ) ;
% allracks = %$ recordsref ;
2012-10-08 08:40:30 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_all_chassis ( 1 ) ;
2012-09-27 08:56:19 +00:00
% allchassis = %$ recordsref ;
2012-12-13 02:00:48 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_all_chassis ( 1 , 'cmm' ) ;
% allcmmchassis = %$ recordsref ;
2012-09-07 08:19:36 +00:00
2014-06-13 06:34:28 +00:00
@ switch_records = ( ) ;
2012-09-07 08:19:36 +00:00
# Generate temporary hostnames for hosts entries in hostfile.
2012-10-12 07:11:26 +00:00
xCAT::MsgUtils - > message ( 'S' , "Generate temporary hostnames." ) ;
2012-09-07 08:19:36 +00:00
my ( $ retcode_read , $ retstr_read ) = read_and_generate_hostnames ( $ args_dict { 'file' } ) ;
if ( $ retcode_read != 0 ) {
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Failed to validate node information file." ) ;
2012-09-07 08:19:36 +00:00
setrsp_errormsg ( $ retstr_read ) ;
return ;
}
2013-01-08 04:47:39 +00:00
my ( $ parse_ret , $ parse_str ) = xCAT::ProfiledNodeUtils - > parse_nodeinfo_file ( $ retstr_read ) ;
if ( ! $ parse_ret ) {
setrsp_progress ( "Failed to validate node information file." ) ;
setrsp_errormsg ( $ parse_str ) ;
return ;
}
2012-09-07 08:19:36 +00:00
2013-04-17 07:06:57 +00:00
my $ mac_addr_mode = 0 ;
2013-04-28 05:49:39 +00:00
my $ switch_mode = 0 ;
2012-09-07 08:19:36 +00:00
# Parse and validate the hostinfo string. The real hostnames will be generated here.
2012-10-12 07:11:26 +00:00
xCAT::MsgUtils - > message ( 'S' , "Parsing hostinfo string and validate it." ) ;
2013-01-08 04:47:39 +00:00
my ( $ hostinfo_dict_ref , $ invalid_records_ref ) = validate_node_entries ( ) ;
2012-09-07 08:19:36 +00:00
my % hostinfo_dict = %$ hostinfo_dict_ref ;
my @ invalid_records = @$ invalid_records_ref ;
if ( @ invalid_records ) {
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Failed to validate node information file." ) ;
2012-09-07 08:19:36 +00:00
setrsp_invalidrecords ( \ @ invalid_records ) ;
return ;
}
unless ( % hostinfo_dict ) {
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Failed to validate node information file." ) ;
setrsp_errormsg ( "Cannot find node records in node information file." ) ;
2012-09-07 08:19:36 +00:00
return ;
}
2013-04-17 07:06:57 +00:00
# if user specified the switch, we need to add a new item into switch table
my @ nodelist = keys % hostinfo_dict ;
foreach my $ mynode ( @ nodelist )
{
if ( defined ( $ hostinfo_dict { $ mynode } { 'mac' } ) )
{
$ mac_addr_mode = 1 ;
}
2014-06-13 06:34:28 +00:00
if ( defined ( $ hostinfo_dict { $ mynode } { 'switches' } ) )
2013-04-28 05:49:39 +00:00
{
$ switch_mode = 1 ;
}
2014-06-13 06:34:28 +00:00
}
# cannot mix switch discovery with mac import
if ( ( $ mac_addr_mode == 1 ) && ( $ switch_mode == 1 ) )
{
setrsp_progress ( "Failed to validate node information file." ) ;
setrsp_errormsg ( "Cannot define mac import node in switch discovery hostinfo file." ) ;
return ;
2013-04-17 07:06:57 +00:00
}
2014-08-10 14:09:21 +00:00
# Get no mac address nodes when user only defined CEC in NIF for 7R2 support.
my @ nomacnodes = ( ) ;
foreach my $ nomacnode ( @ nodelist ) {
if ( defined ( $ hostinfo_dict { $ nomacnode } { 'cec' } ) &&
not ( defined ( $ hostinfo_dict { $ nomacnode } { 'mac' } ) ) &&
not ( defined ( $ hostinfo_dict { $ nomacnode } { 'switch' } ) ) ) {
push @ nomacnodes , $ nomacnode ;
}
}
2013-09-23 06:45:43 +00:00
# Create the full hostinfo dict.
2012-10-12 07:11:26 +00:00
xCAT::MsgUtils - > message ( 'S' , "Generating new hostinfo string." ) ;
2013-09-23 06:45:43 +00:00
my ( $ retcode_gen , $ retstr_gen ) = gen_new_hostinfo_dict ( \ % hostinfo_dict ) ;
2012-09-07 08:19:36 +00:00
unless ( $ retcode_gen ) {
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Failed to validate node information file." ) ;
2012-09-07 08:19:36 +00:00
setrsp_errormsg ( $ retstr_gen ) ;
return ;
}
2013-09-23 06:45:43 +00:00
# create hosts and then call nodemgmt for node management plugins.
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Importing nodes..." ) ;
setrsp_progress ( "Creating nodes..." ) ;
2012-10-22 09:37:09 +00:00
my $ warnstr = "" ;
2013-09-23 06:45:43 +00:00
if ( xCAT::DBobjUtils - > setobjdefs ( \ % hostinfo_dict ) != 0 ) {
2012-11-28 05:39:09 +00:00
$ warnstr = "Warning: failed to import some nodes." ;
2013-09-23 06:45:43 +00:00
setrsp_progress ( $ warnstr ) ;
2012-10-22 09:37:09 +00:00
}
2014-06-13 06:34:28 +00:00
# create switch, port, interface relationship.
if ( $ switch_mode ) {
#debug message.
my $ swstr = Dumper ( @ switch_records ) ;
xCAT::MsgUtils - > message ( 'S' , "node-switch-port-interface relationship: @switch_records" ) ;
my $ swtab1 = xCAT::Table - > new ( 'switch' , - create = > 1 , - autocommit = > 0 ) ;
for my $ key_n_value ( @ switch_records ) {
my $ keyref = ( @$ key_n_value ) [ 0 ] ;
my $ valueref = ( @$ key_n_value ) [ 1 ] ;
$ swtab1 - > setAttribs ( $ keyref , $ valueref ) ;
}
$ swtab1 - > commit ;
}
2014-04-17 07:56:59 +00:00
# setup node provisioning status.
xCAT::Utils - > runxcmd ( { command = > [ "updatenodestat" ] , node = > \ @ nodelist , arg = > [ 'defined' ] } , $ request_command , - 1 , 2 ) ;
2014-01-27 05:52:33 +00:00
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Configuring nodes..." ) ;
2013-09-23 06:45:43 +00:00
my $ retref = xCAT::Utils - > runxcmd ( { command = > [ "kitnodeadd" ] , node = > \ @ nodelist , sequential = > [ 1 ] , macflag = > [ $ mac_addr_mode ] } , $ request_command , 0 , 2 ) ;
my $ retstrref = parse_runxcmd_ret ( $ retref ) ;
2012-10-22 09:37:09 +00:00
if ( $ ::RUNCMD_RC != 0 ) {
2012-11-05 15:00:12 +00:00
$ warnstr . = "Warning: failed to run command kitnodeadd." ;
if ( $ retstrref - > [ 1 ] ) {
$ warnstr . = "Details: $retstrref->[1]" ;
}
2012-10-22 09:37:09 +00:00
}
2014-08-10 14:09:21 +00:00
# Use xcat command: getmacs <noderanges> -D to automatically get node mac address
# If some of nodes can not get mac address, then finally remove them with warning msg.
if ( @ nomacnodes ) {
# Sleep 10 seconds to ensure the basic node attributes are effected
sleep 10 ;
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "getmacs" ] , node = > \ @ nomacnodes , arg = > [ '-D' ] } , $ request_command , 0 , 2 ) ;
$ retstrref = parse_runxcmd_ret ( $ retref ) ;
if ( $ ::RUNCMD_RC != 0 ) {
$ warnstr . = "Warning: Can not discover MAC address by getmacs command for some node(s)." ;
}
# Parse the output of "getmacs <noderange> -D" to filter success and failed nodes.
my @ successnodes = ( ) ;
my @ failednodes = ( ) ;
my $ nodelistref = $ retref - > { 'node' } ;
my $ index = 0 ;
my $ name = '' ;
my $ contents = '' ;
if ( $ nodelistref ) {
foreach ( @$ nodelistref ) {
# Get node name.
if ( $ nodelistref - > [ $ index ] - > { 'name' } ) {
$ name = $ nodelistref - > [ $ index ] - > { 'name' } - > [ 0 ] ;
}
# Get node data contents.
if ( $ nodelistref - > [ $ index ] - > { 'data' } - > [ 0 ] - > { 'contents' } ) {
$ contents = $ nodelistref - > [ $ index ] - > { 'data' } - > [ 0 ] - > { 'contents' } - > [ 0 ] ;
}
# Get success and failed nodes list.
if ( defined ( $ name ) and $ contents =~ /[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}/ ) {
push @ successnodes , $ name ;
} else {
push @ failednodes , $ name ;
}
$ index + + ;
}
}
# Reconfigure the nodes that MAC address discovered by getmacs command
if ( @ successnodes ) {
$ mac_addr_mode = 1 ;
my $ retref = xCAT::Utils - > runxcmd ( { command = > [ "kitnodeadd" ] , node = > \ @ successnodes , sequential = > [ 1 ] , macflag = > [ $ mac_addr_mode ] } , $ request_command , 0 , 2 ) ;
my $ retstrref = parse_runxcmd_ret ( $ retref ) ;
if ( $ ::RUNCMD_RC != 0 ) {
$ warnstr . = "Warning: failed to run command kitnodeadd." ;
if ( $ retstrref - > [ 1 ] ) {
$ warnstr . = "Details: $retstrref->[1]" ;
}
}
}
# Remove these nodes that can not get mac address by xcat command: getmacs <noderange> -D.
if ( @ failednodes ) {
my $ nodermretref = xCAT::Utils - > runxcmd ( { command = > [ "noderm" ] , node = > \ @ failednodes } , $ request_command , 0 , 2 ) ;
my $ nodermretstrref = parse_runxcmd_ret ( $ nodermretref ) ;
if ( $ ::RUNCMD_RC != 0 ) {
$ warnstr . = "Warning: Cannot remove some of nodes that not MAC address discovered by getmacs command." ;
if ( $ nodermretstrref - > [ 1 ] ) {
$ warnstr . = "Details: $nodermretstrref->[1]" ;
}
}
}
# Push the success nodes to nodelist and remove the failed nodes from nodelist.
@ nodelist = xCAT::CFMUtils - > arrayops ( "U" , \ @ nodelist , \ @ successnodes ) ;
@ failednodes = xCAT::CFMUtils - > arrayops ( "I" , \ @ nodelist , \ @ failednodes ) ;
@ nodelist = xCAT::CFMUtils - > arrayops ( "D" , \ @ nodelist , \ @ failednodes ) ;
}
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Imported nodes." ) ;
2012-10-22 09:37:09 +00:00
#TODO: get the real nodelist here.
setrsp_success ( \ @ nodelist , $ warnstr ) ;
2012-09-07 08:19:36 +00:00
}
#-------------------------------------------------------
2012-10-08 08:40:30 +00:00
= head3 nodepurge
2012-09-07 08:19:36 +00:00
2012-10-08 08:40:30 +00:00
Description : Remove nodes . After nodes removed , their info in /etc/ hosts , dhcp , dns ... will be removed automatically .
2012-09-07 08:19:36 +00:00
Arguments : N / A
= cut
#-------------------------------------------------------
2012-10-08 08:40:30 +00:00
sub nodepurge {
2012-09-07 08:19:36 +00:00
my $ nodes = $ request - > { node } ;
2012-11-28 05:39:09 +00:00
my $ helpmsg = " nodepurge: Removes nodes from database and system configuration .
2012-11-01 09:19:19 +00:00
Usage:
\ tnodepurge <noderange>
\ tnodepurge [ - h | - - help ]
\ tnodepurge { - v | - - version } " ;
my $ ret = validate_args ( $ helpmsg ) ;
if ( ! $ ret ) {
return ;
}
2013-01-15 05:47:34 +00:00
if ( ! $ nodes ) {
setrsp_infostr ( $ helpmsg ) ;
return ;
}
xCAT::MsgUtils - > message ( 'S' , "Purging nodes." ) ;
# For remove nodes, we should call 'nodemgmt' in front of 'noderm'
setrsp_progress ( "Configuring nodes..." ) ;
2012-11-01 09:19:19 +00:00
2012-10-22 09:37:09 +00:00
my $ warnstr = "" ;
2012-12-28 03:35:07 +00:00
my $ retref = xCAT::Utils - > runxcmd ( { command = > [ "kitnoderemove" ] , node = > $ nodes , sequential = > [ 1 ] } , $ request_command , 0 , 2 ) ;
2012-11-05 15:00:12 +00:00
my $ retstrref = parse_runxcmd_ret ( $ retref ) ;
2012-10-22 09:37:09 +00:00
# runxcmd failed.
if ( $ ::RUNCMD_RC != 0 ) {
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Warning: failed to call kitnoderemove command." ) ;
$ warnstr . = "Warning: failed to call kitnoderemove command." ;
2012-11-05 15:00:12 +00:00
if ( $ retstrref - > [ 1 ] ) {
$ warnstr . = "Details: $retstrref->[1]" ;
}
2012-10-22 09:37:09 +00:00
}
2012-11-05 15:00:12 +00:00
2013-05-29 03:47:47 +00:00
setrsp_progress ( "Updating DNS entries" ) ;
2013-09-23 06:45:43 +00:00
$ retref = "" ;
2013-05-29 03:47:47 +00:00
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "makedns" ] , node = > $ nodes , arg = > [ '-d' ] } , $ request_command , 0 , 2 ) ;
setrsp_progress ( "Updating hosts entries" ) ;
2013-09-23 06:45:43 +00:00
$ retref = "" ;
2013-05-29 03:47:47 +00:00
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "makehosts" ] , node = > $ nodes , arg = > [ '-d' ] } , $ request_command , 0 , 2 ) ;
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Removing nodes..." ) ;
2013-09-23 06:45:43 +00:00
$ retref = "" ;
2012-12-17 09:25:37 +00:00
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "noderm" ] , node = > $ nodes } , $ request_command , 0 , 2 ) ;
2012-11-05 15:00:12 +00:00
$ retstrref = parse_runxcmd_ret ( $ retref ) ;
2012-10-22 09:37:09 +00:00
if ( $ ::RUNCMD_RC != 0 ) {
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Warning: Cannot remove all nodes. The noderm command failed to remove some of the nodes." ) ;
$ warnstr . = "Warning: Cannot remove all nodes. The noderm command failed to remove some of the nodes." ;
2012-11-05 15:00:12 +00:00
if ( $ retstrref - > [ 1 ] ) {
$ warnstr . = "Details: $retstrref->[1]" ;
}
2012-10-22 09:37:09 +00:00
}
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Removed all nodes." ) ;
2012-10-22 09:37:09 +00:00
setrsp_success ( $ nodes , $ warnstr ) ;
2012-09-07 08:19:36 +00:00
}
#-------------------------------------------------------
2012-10-08 08:40:30 +00:00
= head3 noderefresh
2012-09-07 08:19:36 +00:00
2012-10-08 08:40:30 +00:00
Description : Re - Call kit plugins for node management
Arguments : N / A
= cut
#------------------------------------------------------
sub noderefresh
{
my $ nodes = $ request - > { node } ;
2012-11-28 05:39:09 +00:00
my $ helpmsg = " noderefresh: Calls kit plugins for the nodes in the profile .
2012-11-01 09:19:19 +00:00
Usage:
\ tnoderefresh <noderange>
\ tnoderefresh [ - h | - - help ]
\ tnoderefresh { - v | - - version } " ;
2013-01-15 05:47:34 +00:00
if ( ! $ nodes ) {
setrsp_infostr ( $ helpmsg ) ;
return ;
}
2012-11-01 09:19:19 +00:00
my $ ret = validate_args ( $ helpmsg ) ;
if ( ! $ ret ) {
return ;
}
2012-12-28 03:35:07 +00:00
my $ retref = xCAT::Utils - > runxcmd ( { command = > [ "kitnoderefresh" ] , node = > $ nodes , sequential = > [ 1 ] } , $ request_command , 0 , 2 ) ;
2012-11-05 15:00:12 +00:00
my $ retstrref = parse_runxcmd_ret ( $ retref ) ;
2012-10-22 09:37:09 +00:00
# runxcmd failed.
if ( $ ::RUNCMD_RC != 0 ) {
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Warning: Failed to call kit commands." ) ;
2012-10-22 09:37:09 +00:00
}
2012-10-08 08:40:30 +00:00
setrsp_success ( $ nodes ) ;
}
#-------------------------------------------------------
= head3 nodechprofile
Description : Update node profiles: imageprofile , networkprofile and hardwareprofile .
2012-09-07 08:19:36 +00:00
Arguments : N / A
= cut
#-------------------------------------------------------
2012-10-08 08:40:30 +00:00
sub nodechprofile {
2012-09-07 08:19:36 +00:00
my $ nodes = $ request - > { node } ;
2012-11-01 09:19:19 +00:00
my $ helpmsg = " nodechprofile: Update node profiles for profiled nodes .
Usage:
\ tnodechprofile <noderange> [ networkprofile = <networkprofile> ] [ imageprofile = <imageprofile> ] [ hardwareprofile = <hardwareprofile> ]
\ tnodechprofile [ - h | - - help ]
\ tnodechprofile { - v | - - version } " ;
2013-01-15 05:47:34 +00:00
if ( ! $ nodes ) {
setrsp_infostr ( $ helpmsg ) ;
return ;
}
2012-11-01 09:19:19 +00:00
2012-09-07 08:19:36 +00:00
my @ enabledparams = ( 'networkprofile' , 'hardwareprofile' , 'imageprofile' ) ;
2012-11-01 09:19:19 +00:00
my $ ret = validate_args ( $ helpmsg , \ @ enabledparams ) ;
if ( ! $ ret ) {
return ;
2012-09-07 08:19:36 +00:00
}
2013-01-15 05:47:34 +00:00
xCAT::MsgUtils - > message ( 'S' , "Update nodes' profile settings." ) ;
2012-09-07 08:19:36 +00:00
# Get current templates for all nodes.
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Getting all node groups from the database..." ) ;
2012-09-07 08:19:36 +00:00
my % groupdict ;
my $ nodelstab = xCAT::Table - > new ( 'nodelist' ) ;
my $ nodeshashref = $ nodelstab - > getNodesAttribs ( $ nodes , [ 'groups' ] ) ;
my % updatenodeshash ;
2013-01-31 07:58:08 +00:00
my % nodeoldprofiles = ( ) ;
foreach ( @$ nodes ) {
2013-06-18 08:22:12 +00:00
my % nodecurrprofiles = ( ) ;
2013-01-31 07:58:08 +00:00
# Get each node's profiles.
my $ groupsstr = $ nodeshashref - > { $ _ } - > [ 0 ] - > { 'groups' } ;
unless ( $ groupsstr ) {
setrsp_errormsg ( "node $_ does not have any profiles, can not change its profiles." ) ;
return ;
}
my @ groups = split ( /,/ , $ groupsstr ) ;
foreach my $ group ( @ groups ) {
if ( $ group =~ /__ImageProfile/ ) {
$ nodecurrprofiles { 'imageprofile' } = $ group ;
} elsif ( $ group =~ /__NetworkProfile/ ) {
$ nodecurrprofiles { 'networkprofile' } = $ group ;
} elsif ( $ group =~ /__HardwareProfile/ ) {
$ nodecurrprofiles { 'hardwareprofile' } = $ group ;
} else {
$ nodecurrprofiles { 'groups' } . = $ group . "," ;
}
}
# initialize node old profiles.
unless ( % nodeoldprofiles ) {
$ nodeoldprofiles { 'imageprofile' } = $ nodecurrprofiles { 'imageprofile' } ;
$ nodeoldprofiles { 'networkprofile' } = $ nodecurrprofiles { 'networkprofile' } ;
$ nodeoldprofiles { 'hardwareprofile' } = $ nodecurrprofiles { 'hardwareprofile' } ;
}
# Make sure whether all nodes having same profiles.
if ( $ nodeoldprofiles { 'imageprofile' } ne $ nodecurrprofiles { 'imageprofile' } ) {
setrsp_errormsg ( "node $_ does not have same imageprofile with other nodes." ) ;
return ;
} elsif ( $ nodeoldprofiles { 'hardwareprofile' } ne $ nodecurrprofiles { 'hardwareprofile' } ) {
setrsp_errormsg ( "node $_ does not have same hardwareprofile with other nodes." ) ;
return ;
} elsif ( $ nodeoldprofiles { 'networkprofile' } ne $ nodecurrprofiles { 'networkprofile' } ) {
setrsp_errormsg ( "node $_ does not have same networkprofile with other nodes." ) ;
return ;
}
# Replace the old profiles name with new specified ones in args_dict
if ( $ nodecurrprofiles { 'groups' } ) {
$ updatenodeshash { $ _ } { 'groups' } = $ nodecurrprofiles { 'groups' } ;
}
2013-06-18 08:22:12 +00:00
}
2014-09-01 02:46:05 +00:00
#fix 241844 issue, use local variable to store args_dict value
my $ imageprofile = undef ;
my $ networkprofile = undef ;
my $ hardwareprofile = undef ;
if ( exists $ args_dict { 'imageprofile' } ) {
$ imageprofile = $ args_dict { 'imageprofile' } ;
}
if ( exists $ args_dict { 'networkprofile' } ) {
$ networkprofile = $ args_dict { 'networkprofile' } ;
}
if ( exists $ args_dict { 'hardwareprofile' } ) {
$ hardwareprofile = $ args_dict { 'hardwareprofile' } ;
}
2013-06-18 08:22:12 +00:00
# After checking, all nodes' profile should be same
# Get the new profile with specified ones in args_dict
my $ changeflag = 0 ;
my $ profile_groups ;
my $ profile_status ;
2014-09-01 02:46:05 +00:00
if ( $ networkprofile ) {
$ profile_groups . = $ networkprofile . "," ;
if ( $ networkprofile ne $ nodeoldprofiles { 'networkprofile' } ) {
2013-06-18 08:22:12 +00:00
$ changeflag = 1 ;
} else {
xCAT::MsgUtils - > message ( 'S' , "Specified networkprofile is same with current value, ignore." ) ;
2014-09-01 02:46:05 +00:00
$ networkprofile = undef ;
2013-01-31 07:58:08 +00:00
}
2013-06-18 08:22:12 +00:00
}
2014-09-01 02:46:05 +00:00
if ( $ hardwareprofile ) {
$ profile_groups . = $ hardwareprofile . "," ;
if ( $ hardwareprofile ne $ nodeoldprofiles { 'hardwareprofile' } ) {
2013-06-18 08:22:12 +00:00
$ profile_status = 'defined' ;
$ changeflag = 1 ;
} else {
xCAT::MsgUtils - > message ( 'S' , "Specified hardwareprofile is same with current value, ignore." ) ;
2014-09-01 02:46:05 +00:00
$ hardwareprofile = undef ;
2013-01-31 07:58:08 +00:00
}
2013-06-18 08:22:12 +00:00
}
2014-09-01 02:46:05 +00:00
if ( $ imageprofile ) {
$ profile_groups . = $ imageprofile . "," ;
if ( $ imageprofile ne $ nodeoldprofiles { 'imageprofile' } ) {
2013-06-18 08:22:12 +00:00
$ profile_status = 'defined' ;
$ changeflag = 1 ;
} else {
xCAT::MsgUtils - > message ( 'S' , "Specified imageprofile is same with current value, ignore." ) ;
2014-09-01 02:46:05 +00:00
$ imageprofile = undef ;
2012-09-07 08:19:36 +00:00
}
}
2013-06-18 08:22:12 +00:00
# make sure there are something changed, otherwise we should quit without any changes.
unless ( $ changeflag ) {
2014-06-18 05:38:05 +00:00
setrsp_infostr ( "Warning: no profile changes detect." ) ;
2013-06-18 08:22:12 +00:00
return ;
}
# Update nodes' attributes
foreach ( @$ nodes ) {
$ updatenodeshash { $ _ } { 'groups' } . = $ profile_groups ;
}
2012-09-07 08:19:36 +00:00
#update DataBase.
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Updating database records..." ) ;
2012-09-07 08:19:36 +00:00
my $ nodetab = xCAT::Table - > new ( 'nodelist' , - create = > 1 ) ;
$ nodetab - > setNodesAttribs ( \ % updatenodeshash ) ;
$ nodetab - > close ( ) ;
2013-01-31 07:58:08 +00:00
2014-04-17 07:56:59 +00:00
#update node's status:
if ( $ profile_status eq "defined" ) {
xCAT::Utils - > runxcmd ( { command = > [ "updatenodestat" ] , node = > $ nodes , arg = > [ 'defined' ] } , $ request_command , - 1 , 2 ) ;
}
2013-01-31 07:58:08 +00:00
my $ retref ;
my $ retstrref ;
2013-01-25 08:55:14 +00:00
2013-01-31 07:58:08 +00:00
# If network profile specified. Need re-generate IPs for all nodess again.
2014-08-12 09:31:24 +00:00
# As new design, ignore BMC/FSP NIC while reinstall nodes
2014-09-01 02:46:05 +00:00
if ( $ networkprofile ) {
my $ newNetProfileName = $ networkprofile ;
2014-05-29 06:30:09 +00:00
my $ oldNetProfileName = $ nodeoldprofiles { 'networkprofile' } ;
my $ newNicsRef = xCAT::ProfiledNodeUtils - > get_nodes_nic_attrs ( [ $ newNetProfileName ] ) - > { $ newNetProfileName } ;
my $ oldNicsRef = xCAT::ProfiledNodeUtils - > get_nodes_nic_attrs ( [ $ oldNetProfileName ] ) - > { $ oldNetProfileName } ;
my % updateNicsHash = ( ) ;
2014-08-20 07:33:29 +00:00
my % reserveNicsHash = ( ) ;
2014-05-29 06:30:09 +00:00
foreach my $ newNic ( keys %$ newNicsRef ) {
if ( $ newNicsRef - > { $ newNic } - > { 'type' } ne 'BMC' and $ newNicsRef - > { $ newNic } - > { 'type' } ne 'FSP' ) {
$ updateNicsHash { $ newNic } = 1 ;
}
}
2014-08-20 07:33:29 +00:00
# Add BMC/FSP as reserve NICs and not remove it form nics table
2014-05-29 06:30:09 +00:00
foreach my $ oldNic ( keys %$ oldNicsRef ) {
if ( $ oldNicsRef - > { $ oldNic } - > { 'type' } ne 'BMC' and $ oldNicsRef - > { $ oldNic } - > { 'type' } ne 'FSP' ) {
$ updateNicsHash { $ oldNic } = 1 ;
2014-08-20 07:33:29 +00:00
} else {
$ reserveNicsHash { $ oldNic } = 1 ;
2014-05-29 06:30:09 +00:00
}
}
my $ updateNics = join ( "," , keys % updateNicsHash ) ;
2014-08-20 07:33:29 +00:00
my $ reserveNics = join ( "," , keys % reserveNicsHash ) ;
2013-01-31 07:58:08 +00:00
setrsp_progress ( "Regenerate IP addresses for nodes..." ) ;
2013-09-23 06:45:43 +00:00
$ retref = "" ;
2014-08-20 07:33:29 +00:00
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "noderegenips" ] , node = > $ nodes , arg = > [ "nics=$updateNics" , "reservenics=$reserveNics" ] , sequential = > [ 1 ] } , $ request_command , 0 , 2 ) ;
2013-01-31 07:58:08 +00:00
$ retstrref = parse_runxcmd_ret ( $ retref ) ;
if ( $ ::RUNCMD_RC != 0 ) {
setrsp_progress ( "Warning: failed to generate IPs for nodes." ) ;
}
}
2014-08-12 09:31:24 +00:00
# Update node's chain table if we need to re-provisioning OS...
# We need to re-provision OS if:
# hardware profile changed or
# image profile changed or
# network profile changed.
2014-09-01 02:46:05 +00:00
if ( ( $ imageprofile ) or ( $ networkprofile ) or ( $ hardwareprofile ) ) {
2014-08-12 09:31:24 +00:00
my $ nodetypetab = xCAT::Table - > new ( 'nodetype' ) ;
my $ firstnode = $ nodes - > [ 0 ] ;
my $ profiles = xCAT::ProfiledNodeUtils - > get_nodes_profiles ( [ $ firstnode ] , 1 ) ;
unless ( $ profiles ) {
setrsp_errormsg ( "Can not get node profiles." ) ;
return ;
}
# If we have hardware changes, reconfigure everything including BMC.
my $ chainret = 0 ;
my $ chainstr = "" ;
2014-09-01 02:46:05 +00:00
if ( $ hardwareprofile ) {
2014-08-12 09:31:24 +00:00
( $ chainret , $ chainstr ) = xCAT::ProfiledNodeUtils - > gen_chain_for_profiles ( $ profiles - > { $ firstnode } , 1 ) ;
} else {
( $ chainret , $ chainstr ) = xCAT::ProfiledNodeUtils - > gen_chain_for_profiles ( $ profiles - > { $ firstnode } , 0 ) ;
}
if ( $ chainret != 0 ) {
setrsp_errormsg ( "Failed to generate chain string for nodes." ) ;
return ;
}
# DB update: chain table.
my % chainAttr = { } ;
foreach my $ node ( @$ nodes ) {
$ chainAttr { $ node } { 'chain' } = $ chainstr ;
2014-08-22 09:01:54 +00:00
$ chainAttr { $ node } { 'currchain' } = '' ;
2014-08-12 09:31:24 +00:00
}
my $ chaintab = xCAT::Table - > new ( 'chain' , - create = > 1 ) ;
$ chaintab - > setNodesAttribs ( \ % chainAttr ) ;
$ chaintab - > close ( ) ;
# Run node plugins to refresh node relateive configurations.
$ retref = { } ;
setrsp_progress ( "Updating DNS entries" ) ;
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "makedns" ] , node = > $ nodes , arg = > [ '-d' ] } , $ request_command , 0 , 2 ) ;
my $ retstrref = parse_runxcmd_ret ( $ retref ) ;
if ( $ ::RUNCMD_RC != 0 ) {
setrsp_progress ( "Warning: failed to call kit commands." ) ;
}
$ retref = { } ;
setrsp_progress ( "Updating hosts entries" ) ;
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "makehosts" ] , node = > $ nodes , arg = > [ '-d' ] } , $ request_command , 0 , 2 ) ;
$ retref = { } ;
$ retstrref = parse_runxcmd_ret ( $ retref ) ;
if ( $ ::RUNCMD_RC != 0 ) {
setrsp_progress ( "Warning: failed to call kit commands." ) ;
}
setrsp_progress ( "Re-creating nodes..." ) ;
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "kitnodeadd" ] , node = > $ nodes , macflag = > [ 1 ] } , $ request_command , 0 , 2 ) ;
$ retstrref = parse_runxcmd_ret ( $ retref ) ;
if ( $ ::RUNCMD_RC != 0 ) {
setrsp_progress ( "Warning: failed to call kit commands." ) ;
}
}
2013-01-25 08:55:14 +00:00
setrsp_progress ( "Updated the image/network/hardware profiles used by nodes." ) ;
setrsp_success ( $ nodes ) ;
}
#------------------------------------------------------
= head3 noderegenips
Description: Re - generate IPs automatically for specified nodes .
All these nodes must be in same networkprofile .
If no nics specified , then re - generate IP all nics in the networkprofile .
= cut
#-----------------------------------------------------
sub noderegenips
{
my $ nodes = $ request - > { node } ;
my $ helpmsg = " noderegenips: Regenerate nodes IP addresses .
Usage:
\ tnoderegenips <noderange> [ nics = <eth0,eth1...> ]
\ tnoderegenips [ - h | - - help ]
\ tnoderegenips { - v | - - version } " ;
if ( ! $ nodes ) {
setrsp_infostr ( $ helpmsg ) ;
return ;
}
2014-08-20 07:33:29 +00:00
my @ enabledparams = ( 'nics' , 'reservenics' ) ;
2013-01-25 08:55:14 +00:00
my $ ret = validate_args ( $ helpmsg , \ @ enabledparams ) ;
if ( ! $ ret ) {
return ;
}
my @ updateNics = ( ) ;
my @ removedNics = ( ) ;
2014-08-20 07:33:29 +00:00
my @ reserveNics = ( ) ;
2013-01-25 08:55:14 +00:00
my $ netProfileName = '' ;
my $ netProfileNicsRef ;
my % freeIPsHash = ( ) ;
# nicipsAttr and ipAttr are for storing node's nicips and ip attribute
my % nicipsAttr = ( ) ;
my % ipAttr = ( ) ;
my $ installnic = '' ;
xCAT::MsgUtils - > message ( 'S' , "Start running noderegenips." ) ;
#1. Validate all nodes have same network profile. networkprofile.
my $ nodesProfilesRef = xCAT::ProfiledNodeUtils - > get_nodes_profiles ( $ nodes ) ;
foreach my $ node ( keys %$ nodesProfilesRef ) {
unless ( $ nodesProfilesRef - > { $ node } - > { NetworkProfile } ) {
setrsp_errormsg ( "Node $node does not have a network profile." ) ;
return ;
}
unless ( $ netProfileName ) {
$ netProfileName = "__NetworkProfile_" . $ nodesProfilesRef - > { $ node } - > { NetworkProfile } ;
next ;
}
if ( "__NetworkProfile_" . $ nodesProfilesRef - > { $ node } - > { NetworkProfile } ne $ netProfileName ) {
setrsp_errormsg ( "Node $node has a different network profile with other nodes." ) ;
return ;
}
}
#2. Get network profile nics settings.
$ netProfileNicsRef = xCAT::ProfiledNodeUtils - > get_nodes_nic_attrs ( [ $ netProfileName ] ) ;
my $ nicsref = $ netProfileNicsRef - > { $ netProfileName } ;
my @ nicslist = keys %$ nicsref ;
2014-05-29 06:30:09 +00:00
2013-01-25 08:55:14 +00:00
#3. validate specified nics
if ( exists $ args_dict { 'nics' } ) {
@ updateNics = split ( "," , $ args_dict { 'nics' } ) ;
}
2014-08-20 07:33:29 +00:00
if ( exists $ args_dict { 'reservenics' } ) {
@ reserveNics = split ( "," , $ args_dict { 'reservenics' } ) ;
}
2013-01-25 08:55:14 +00:00
foreach ( @ updateNics ) {
unless ( $ netProfileNicsRef - > { $ netProfileName } - > { $ _ } ) {
# We want to remove this nic from these nodes.
push ( @ removedNics , $ _ ) ;
}
}
unless ( @ updateNics ) {
@ updateNics = @ nicslist ;
}
# get install nic for these nodes.
my $ restab = xCAT::Table - > new ( 'noderes' ) ;
my $ installnicattr = $ restab - > getNodeAttribs ( $ netProfileName , [ 'installnic' ] ) ;
$ installnic = $ installnicattr - > { 'installnic' } ;
#4. get all node's current database nics settings.
my $ nodesNicsRef = xCAT::ProfiledNodeUtils - > get_nodes_nic_attrs ( $ nodes ) ;
my $ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'ipmi' , 'bmc' ) ;
% allbmcips = %$ recordsref ;
$ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'hosts' , 'ip' ) ;
% allinstallips = %$ recordsref ;
$ recordsref = xCAT::NetworkUtils - > get_all_nicips ( 1 ) ;
% allips = %$ recordsref ;
$ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'ppc' , 'hcp' ) ;
my % allfspips = %$ recordsref ;
% allips = ( % allips , % allbmcips , % allinstallips , % allfspips ) ;
#5. free currently used IPs for all nodes.
foreach my $ node ( @$ nodes ) {
foreach my $ nicname ( @ updateNics ) {
my $ nicip = $ nodesNicsRef - > { $ node } - > { $ nicname } - > { "ip" } ;
if ( $ nicip ) {
delete ( $ allips { $ nicip } ) ;
}
}
}
#6. Generate new free IPs for each network.
my @ allknownips = keys % allips ;
2014-06-18 05:38:05 +00:00
my % netFreeIPsHash = ( ) ;
2013-01-25 08:55:14 +00:00
foreach my $ updnic ( @ updateNics ) {
#No need generate for removed nics.
unless ( grep { $ _ eq $ updnic } @ removedNics ) {
my $ netname = $ netProfileNicsRef - > { $ netProfileName } - > { $ updnic } - > { "network" } ;
2014-06-18 05:38:05 +00:00
if ( not exists $ netFreeIPsHash { $ netname } ) {
$ netFreeIPsHash { $ netname } = xCAT::ProfiledNodeUtils - > get_allocable_staticips_innet ( $ netname , \ @ allknownips ) ;
}
2014-06-25 00:59:01 +00:00
$ freeIPsHash { $ updnic } = $ netFreeIPsHash { $ netname } ;
2013-01-25 08:55:14 +00:00
}
}
#7. Assign new free IPs for nodes and generate nicips and hosts attribute.
2013-06-18 04:46:29 +00:00
my % bmcipsAttr = { } ;
my % fspipsAttr = { } ;
my $ provision_flag = 0 ;
my $ bmc_flag = 0 ;
my $ fsp_flag = 0 ;
2013-01-25 08:55:14 +00:00
foreach my $ node ( @$ nodes ) {
foreach my $ nicname ( @ nicslist ) {
# Remove records from nicips for removed nics.
if ( grep { $ _ eq $ nicname } @ removedNics ) {
next ;
}
unless ( grep { $ _ eq $ nicname } @ updateNics ) {
# if the nic not specified, just keep the old IP&NIC record in nics table.
my $ oldip = $ nodesNicsRef - > { $ node } - > { $ nicname } - > { "ip" } ;
2014-05-29 06:30:09 +00:00
if ( $ oldip ) {
$ nicipsAttr { $ node } { nicips } . = $ nicname . "!" . $ oldip . "," ;
}
2013-01-25 08:55:14 +00:00
} else {
my $ ipsref = $ freeIPsHash { $ nicname } ;
my $ nextip = shift @$ ipsref ;
unless ( $ nextip ) {
setrsp_errormsg ( "There are no more IP addresses available in the static network range for nic $nicname." ) ;
return ;
}
$ nicipsAttr { $ node } { nicips } . = $ nicname . "!" . $ nextip . "," ;
if ( $ installnic eq $ nicname ) {
2013-06-18 04:46:29 +00:00
$ provision_flag = 1 ;
2013-01-25 08:55:14 +00:00
$ ipAttr { $ node } { ip } = $ nextip ;
2013-06-18 04:46:29 +00:00
} elsif ( $ nicname eq 'bmc' ) {
$ bmc_flag = 1 ;
$ bmcipsAttr { $ node } { "bmc" } = $ nextip ;
} elsif ( $ nicname eq 'fsp' ) {
$ fsp_flag = 1 ;
$ fspipsAttr { $ node } { "hcp" } = $ nextip ;
2013-01-25 08:55:14 +00:00
}
2014-08-22 09:01:54 +00:00
}
2013-01-25 08:55:14 +00:00
}
2014-08-22 09:01:54 +00:00
2014-08-20 07:33:29 +00:00
# Add reserve nics
foreach my $ nicname ( @ reserveNics ) {
2014-09-15 07:55:01 +00:00
my $ count = index ( $ nicipsAttr { $ node } { nicips } , $ nicname ) ;
if ( $ count < 0 ) {
my $ oldip = $ nodesNicsRef - > { $ node } - > { $ nicname } - > { "ip" } ;
if ( $ oldip ) {
$ nicipsAttr { $ node } { nicips } . = $ nicname . "!" . $ oldip . "," ;
}
}
2014-08-20 07:33:29 +00:00
}
2013-01-25 08:55:14 +00:00
}
2014-05-29 06:30:09 +00:00
2013-01-25 08:55:14 +00:00
#8. Update database.
setrsp_progress ( "Updating database records..." ) ;
my $ nicstab = xCAT::Table - > new ( 'nics' , - create = > 1 ) ;
$ nicstab - > setNodesAttribs ( \ % nicipsAttr ) ;
$ nicstab - > close ( ) ;
2013-06-18 04:46:29 +00:00
# Update hosts table if provisioning NIC ip change
if ( $ provision_flag ) {
2013-01-25 08:55:14 +00:00
my $ hoststab = xCAT::Table - > new ( 'hosts' , - create = > 1 ) ;
$ hoststab - > setNodesAttribs ( \ % ipAttr ) ;
$ hoststab - > close ( ) ;
2013-06-18 04:46:29 +00:00
}
# Update ipmi table if bmc NIC ip change
if ( $ bmc_flag ) {
my $ ipmitab = xCAT::Table - > new ( 'ipmi' , - create = > 1 ) ;
$ ipmitab - > setNodesAttribs ( \ % bmcipsAttr ) ;
$ ipmitab - > close ( ) ;
}
# Update ppc table if fsp NIC ip change
if ( $ fsp_flag ) {
my $ ppctab = xCAT::Table - > new ( 'ppc' , - create = > 1 ) ;
$ ppctab - > setNodesAttribs ( \ % fspipsAttr ) ;
$ ppctab - > close ( ) ;
}
2013-01-25 08:55:14 +00:00
setrsp_progress ( "Re-generated node's IPs for specified nics." ) ;
2012-09-07 08:19:36 +00:00
setrsp_success ( $ nodes ) ;
}
2012-10-12 07:11:26 +00:00
#-------------------------------------------------------
= head3 nodeaddunmged
Description : Create a node with hostname and ip address specified .
This node will belong to group "__Unmanaged" .
Host file /etc/ hosts will be updated automatically .
Arguments : N / A
= cut
#-------------------------------------------------------
sub nodeaddunmged
{
xCAT::MsgUtils - > message ( "Adding a unmanaged node." ) ;
2012-11-28 05:39:09 +00:00
my $ helpmsg = " nodeaddunmged: Creates an unmanaged node specifying the node name and IP address
2012-11-01 09:19:19 +00:00
Usage:
\ tnodeaddunmged hostname <hostname> ip = <ip>
\ tnodeaddunmged [ - h | - - help ]
\ tnodeaddunmged { - v | - - version } " ;
2012-10-12 07:11:26 +00:00
my @ enabledparams = ( 'hostname' , 'ip' ) ;
2012-11-01 09:19:19 +00:00
my $ ret = validate_args ( $ helpmsg , \ @ enabledparams , \ @ enabledparams ) ;
if ( ! $ ret ) {
return ;
2012-10-12 07:11:26 +00:00
}
# validate the IP address
my $ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'ipmi' , 'bmc' ) ;
% allbmcips = %$ recordsref ;
$ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'hosts' , 'ip' ) ;
% allinstallips = %$ recordsref ;
$ recordsref = xCAT::NetworkUtils - > get_all_nicips ( 1 ) ;
% allips = %$ recordsref ;
% allips = ( % allips , % allbmcips , % allinstallips ) ;
if ( exists $ allips { $ args_dict { 'ip' } } ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "The specified IP address $args_dict{'ip'} already exists in the IP address database. You must use a different IP address." ) ;
2012-10-12 07:11:26 +00:00
return ;
2012-11-05 03:22:16 +00:00
} elsif ( ( xCAT::NetworkUtils - > validate_ip ( $ args_dict { 'ip' } ) ) [ 0 ] - > [ 0 ] ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "The specified IP address $args_dict{'ip'} is invalid. You must use a valid IP address." ) ;
2012-10-12 07:11:26 +00:00
return ;
}
# validate hostname.
$ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'nodelist' , 'node' ) ;
% allhostnames = %$ recordsref ;
if ( exists $ allhostnames { $ args_dict { 'hostname' } } ) {
2013-01-15 08:20:19 +00:00
setrsp_errormsg ( "The specified device name $args_dict{'hostname'} already exists. You must use a different device name." ) ;
2012-10-12 07:11:26 +00:00
return ;
}
2013-07-26 09:47:17 +00:00
if ( ! xCAT::NetworkUtils - > isValidHostname ( $ args_dict { 'hostname' } ) ) {
setrsp_errormsg ( "The specified device name $args_dict{'hostname'} is invalid. You must use a valid device name composed of 'a-z' '0-9'." ) ;
2012-10-12 07:11:26 +00:00
return ;
}
2012-11-19 08:56:16 +00:00
my % updatenodeshash = ( ) ;
$ updatenodeshash { $ args_dict { 'hostname' } } { 'ip' } = $ args_dict { 'ip' } ;
my $ hoststab = xCAT::Table - > new ( 'hosts' , - create = > 1 ) ;
$ hoststab - > setNodesAttribs ( \ % updatenodeshash ) ;
$ hoststab - > close ( ) ;
% updatenodeshash = ( ) ;
$ updatenodeshash { $ args_dict { 'hostname' } } { 'groups' } = "__Unmanaged" ;
my $ nodetab = xCAT::Table - > new ( 'nodelist' , - create = > 1 ) ;
$ nodetab - > setNodesAttribs ( \ % updatenodeshash ) ;
$ nodetab - > close ( ) ;
my $ retref = xCAT::Utils - > runxcmd ( { command = > [ "makehosts" ] , node = > [ $ args_dict { "hostname" } ] } , $ request_command , 0 , 2 ) ;
2012-11-05 15:00:12 +00:00
my $ retstrref = parse_runxcmd_ret ( $ retref ) ;
2012-10-22 09:37:09 +00:00
if ( $ ::RUNCMD_RC != 0 ) {
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Warning: failed to update /etc/hosts for unmanaged node." ) ;
2012-10-22 09:37:09 +00:00
}
2013-09-23 06:45:43 +00:00
$ retref = "" ;
2013-04-28 06:07:08 +00:00
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "makedns" ] , node = > [ $ args_dict { "hostname" } ] } , $ request_command , 0 , 2 ) ;
$ retstrref = parse_runxcmd_ret ( $ retref ) ;
if ( $ ::RUNCMD_RC != 0 ) {
setrsp_progress ( "Warning: failed to update dns for unmanaged node." ) ;
}
2012-11-28 05:39:09 +00:00
setrsp_infostr ( "Created unmanaged node." ) ;
2012-10-12 07:11:26 +00:00
}
#-------------------------------------------------------
= head3 nodechmac
Description : Change node 's provisioning NIC' s MAC address .
And then call kits plugins for nodes .
Arguments : N / A
= cut
#-------------------------------------------------------
sub nodechmac
{
xCAT::MsgUtils - > message ( "Replacing node's mac address." ) ;
2012-11-28 05:39:09 +00:00
my $ helpmsg = " nodechmac: updates the MAC address for a provisioning network interface .
2012-11-01 09:19:19 +00:00
Usage:
\ tnodechmac <node> mac = <mac>
\ tnodechmac [ - h | - - help ]
\ tnodechmac { - v | - - version } " ;
2012-10-12 07:11:26 +00:00
my @ enabledparams = ( 'mac' ) ;
2012-11-01 09:19:19 +00:00
my $ ret = validate_args ( $ helpmsg , \ @ enabledparams , \ @ enabledparams ) ;
if ( ! $ ret ) {
return ;
2012-10-12 07:11:26 +00:00
}
2012-11-01 09:19:19 +00:00
my $ nodelist = $ request - > { node } ;
my $ hostname = $ nodelist - > [ 0 ] ;
2014-09-15 09:32:28 +00:00
if ( "__NOMAC__" eq $ args_dict { "mac" } ) {
# Validate if node is bind on a switch
my $ switch_table = xCAT::Table - > new ( "switch" ) ;
my @ item = $ switch_table - > getAttribs ( { 'node' = > $ hostname } , 'switch' , 'port' ) ;
my $ item_num = @ item ;
my $ switch_valid = 0 ;
unless ( $ item [ 0 ] )
{
setrsp_errormsg ( "Failed to replace node <$hostname>. Switch information cannot be retrieved. Ensure that the switch is configured correctly." ) ;
return ;
} else {
foreach my $ switch_item ( @ item ) {
if ( $ switch_item - > { 'switch' } && $ switch_item - > { 'port' } ) {
$ switch_valid = 1 ;
}
}
}
unless ( $ switch_valid )
{
setrsp_errormsg ( "Failed to replace node <$hostname>. Switch information cannot be retrieved. Ensure that the switch is configured correctly." ) ;
return ;
}
} else {
#Validate MAC address
my $ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'mac' , 'mac' ) ;
% allmacs = %$ recordsref ;
foreach ( keys % allmacs ) {
my @ hostentries = split ( /\|/ , $ _ ) ;
foreach my $ hostandmac ( @ hostentries ) {
my ( $ macstr , $ machostname ) = split ( "!" , $ hostandmac ) ;
$ allmacs { $ macstr } = 0 ;
}
}
% allmacsupper = ( ) ;
foreach ( keys % allmacs ) {
$ allmacsupper { uc ( $ _ ) } = 0 ;
}
if ( exists $ allmacsupper { uc ( $ args_dict { "mac" } ) } ) {
setrsp_errormsg ( "The specified MAC address $args_dict{'mac'} already exists. You must use a different MAC address." ) ;
return ;
} elsif ( ! xCAT::NetworkUtils - > isValidMAC ( $ args_dict { 'mac' } ) ) {
setrsp_errormsg ( "The specified MAC address $args_dict{'mac'} is invalid. You must use a valid MAC address." ) ;
return ;
2012-10-12 07:11:26 +00:00
}
}
2014-08-12 09:31:24 +00:00
# re-create the chain record as updating mac may means for replacing a new brand hardware...
# Call Plugins.
my $ profiles = xCAT::ProfiledNodeUtils - > get_nodes_profiles ( [ $ hostname ] , 1 ) ;
unless ( $ profiles ) {
setrsp_errormsg ( "Can not get node profiles." ) ;
return ;
}
( my $ chainret , my $ chainstr ) = xCAT::ProfiledNodeUtils - > gen_chain_for_profiles ( $ profiles - > { $ hostname } , 1 ) ;
if ( $ chainret != 0 ) {
setrsp_errormsg ( "Failed to generate chain string for nodes." ) ;
return ;
}
2012-10-12 07:11:26 +00:00
# Update database records.
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Updating database..." ) ;
2014-08-12 09:31:24 +00:00
# MAC table
2014-09-15 09:32:28 +00:00
if ( "__NOMAC__" eq $ args_dict { "mac" } )
{
my $ mactab = xCAT::Table - > new ( 'mac' , - create = > 1 ) ;
my % keyhash ;
$ keyhash { 'node' } = $ hostname ;
$ mactab - > delEntries ( \ % keyhash ) ;
$ mactab - > commit ( ) ;
$ mactab - > close ( ) ;
} else {
my $ mactab = xCAT::Table - > new ( 'mac' , - create = > 1 ) ;
$ mactab - > setNodeAttribs ( $ hostname , { mac = > $ args_dict { 'mac' } } ) ;
$ mactab - > close ( ) ;
}
2012-10-12 07:11:26 +00:00
2014-08-12 09:31:24 +00:00
# DB update: chain table.
my $ chaintab = xCAT::Table - > new ( 'chain' , - create = > 1 ) ;
2014-08-22 09:01:54 +00:00
$ chaintab - > setNodeAttribs ( $ hostname , { chain = > $ chainstr , currchain = > '' } ) ;
2014-08-12 09:31:24 +00:00
$ chaintab - > close ( ) ;
# Run node plugins to refresh node relateive configurations.
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Configuring nodes..." ) ;
2014-08-12 09:31:24 +00:00
my $ retref = { } ;
setrsp_progress ( "Updating DNS entries" ) ;
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "makedns" ] , node = > [ $ hostname ] , arg = > [ '-d' ] } , $ request_command , 0 , 2 ) ;
2012-11-05 15:00:12 +00:00
my $ retstrref = parse_runxcmd_ret ( $ retref ) ;
2012-10-22 09:37:09 +00:00
if ( $ ::RUNCMD_RC != 0 ) {
2012-11-05 15:00:12 +00:00
setrsp_progress ( "Warning: failed to call kit commands." ) ;
2012-10-22 09:37:09 +00:00
}
2014-08-12 09:31:24 +00:00
$ retref = { } ;
setrsp_progress ( "Updating hosts entries" ) ;
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "makehosts" ] , node = > [ $ hostname ] , arg = > [ '-d' ] } , $ request_command , 0 , 2 ) ;
$ retref = { } ;
$ retstrref = parse_runxcmd_ret ( $ retref ) ;
if ( $ ::RUNCMD_RC != 0 ) {
setrsp_progress ( "Warning: failed to call kit commands." ) ;
}
2014-09-15 09:32:28 +00:00
if ( "__NOMAC__" eq $ args_dict { "mac" } )
{
setrsp_progress ( "Updating DHCP entries" ) ;
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "makedhcp" ] , node = > [ $ hostname ] , arg = > [ '-d' ] } , $ request_command , 0 , 2 ) ;
$ retref = { } ;
$ retstrref = parse_runxcmd_ret ( $ retref ) ;
if ( $ ::RUNCMD_RC != 0 ) {
setrsp_progress ( "Warning: failed to call kit commands." ) ;
}
}
2014-08-12 09:31:24 +00:00
setrsp_progress ( "Re-creating nodes..." ) ;
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "kitnodeadd" ] , node = > [ $ hostname ] , macflag = > [ 1 ] } , $ request_command , 0 , 2 ) ;
$ retstrref = parse_runxcmd_ret ( $ retref ) ;
if ( $ ::RUNCMD_RC != 0 ) {
setrsp_progress ( "Warning: failed to call kit commands." ) ;
}
2012-12-13 03:32:16 +00:00
# Update node's status.
setrsp_progress ( "Updating node status..." ) ;
2014-04-17 07:56:59 +00:00
xCAT::Utils - > runxcmd ( { command = > [ "updatenodestat" ] , node = > [ $ hostname ] , arg = > [ 'defined' ] } , $ request_command , - 1 , 2 ) ;
2012-12-13 03:32:16 +00:00
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Updated MAC address." ) ;
2012-10-12 07:11:26 +00:00
}
2012-09-07 08:19:36 +00:00
#-------------------------------------------------------
2012-10-08 08:40:30 +00:00
= head3 nodediscoverstart
2012-09-27 08:56:19 +00:00
2012-10-08 08:40:30 +00:00
Description : Start profiled nodes discovery . If already started , return a failure .
2012-09-27 08:56:19 +00:00
User should specify networkprofile , hardwareprofile ,
imageprofile , hostnameformat , rack , chassis , height and u so
that node ' s IP address will be generated automatcially
according to networkprofile , node ' s hardware settings will
be set according to hardware profile , node ' s os settings will
be set according to image profile , node ' s hostname will be
set according to hostnameformat and rank . And other node ' s
attribs will also be set according to rack , chassis , height and u .
Arguments : N / A
= cut
#-------------------------------------------------------
2012-10-08 08:40:30 +00:00
sub nodediscoverstart {
2012-10-12 07:11:26 +00:00
xCAT::MsgUtils - > message ( "Profiled nodes discovery started." ) ;
2012-11-01 09:19:19 +00:00
my $ helpmsg = " nodediscoverstart: Start profiled nodes discovery .
Usage:
\ tnodediscoverstart networkprofile = <networkprofile> imageprofile = <imageprofile> hostnameformat = <hostnameformat> [ hardwareprofile = <hardwareprofile> ] [ groups = <groups> ] [ rack = <rack> ] [ chassis = <chassis> ] [ height = <height> ] [ unit = <unit> ] [ rank = rank ]
\ tnodediscoverstart [ - h | - - help ]
\ tnodediscoverstart { - v | - - version }
" ;
2012-09-27 08:56:19 +00:00
2012-10-29 08:59:14 +00:00
my @ enabledparams = ( 'networkprofile' , 'hardwareprofile' , 'imageprofile' , 'hostnameformat' , 'rank' , 'rack' , 'chassis' , 'height' , 'unit' , 'groups' ) ;
2012-11-01 09:19:19 +00:00
my @ mandatoryparams = ( 'networkprofile' , 'imageprofile' , 'hostnameformat' ) ;
my $ ret = validate_args ( $ helpmsg , \ @ enabledparams , \ @ mandatoryparams ) ;
if ( ! $ ret ) {
return ;
2012-09-27 08:56:19 +00:00
}
2012-12-14 07:59:17 +00:00
my ( $ returncode , $ errmsg ) = xCAT::ProfiledNodeUtils - > check_profile_consistent ( $ args_dict { 'imageprofile' } , $ args_dict { 'networkprofile' } , $ args_dict { 'hardwareprofile' } ) ;
if ( not $ returncode ) {
setrsp_errormsg ( $ errmsg ) ;
return ;
}
2012-10-29 08:59:14 +00:00
# validate hostnameformat:
my $ nameformattype = xCAT::ProfiledNodeUtils - > get_hostname_format_type ( $ args_dict { 'hostnameformat' } ) ;
if ( $ nameformattype eq "unknown" ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Invalid node name format: $args_dict{'hostnameformat'}" ) ;
2012-10-29 08:59:14 +00:00
return ;
2012-12-14 07:59:17 +00:00
} elsif ( $ nameformattype eq 'rack' ) {
if ( ( ! exists $ args_dict { 'rack' } ) && ( ! exists $ args_dict { 'chassis' } ) ) {
setrsp_errormsg ( "Specify rack/chassis as node name format includes rack info." ) ;
return ;
}
2012-10-29 08:59:14 +00:00
}
2012-10-12 07:11:26 +00:00
my $ recordsref = xCAT::ProfiledNodeUtils - > get_all_rack ( 1 ) ;
% allracks = %$ recordsref ;
$ recordsref = xCAT::ProfiledNodeUtils - > get_all_chassis ( 1 ) ;
% allchassis = %$ recordsref ;
# check rack
if ( exists $ args_dict { 'rack' } ) {
if ( ! exists $ allracks { $ args_dict { 'rack' } } ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Specified rack $args_dict{'rack'} is not defined" ) ;
2012-10-12 07:11:26 +00:00
return ;
}
# rack must be specified with chassis or unit + height.
if ( exists $ args_dict { 'chassis' } ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Specified chassis cannot be used with rack." ) ;
2012-10-30 06:24:30 +00:00
return ;
2012-10-12 07:11:26 +00:00
} else {
# We set default value for height and u if rack specified
if ( ! exists $ args_dict { 'height' } ) { $ args_dict { 'height' } = 1 }
if ( ! exists $ args_dict { 'unit' } ) { $ args_dict { 'unit' } = 1 }
}
}
# chassis jdugement.
if ( exists $ args_dict { 'chassis' } ) {
if ( ! exists $ allchassis { $ args_dict { 'chassis' } } ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Specified chassis $args_dict{'chassis'} is not defined." ) ;
2012-10-12 07:11:26 +00:00
return ;
}
if ( exists $ args_dict { 'unit' } or exists $ args_dict { 'height' } ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Specified chassis cannot be used with unit or height." ) ;
2012-10-12 07:11:26 +00:00
return ;
}
}
# height and u must be valid numbers.
if ( exists $ args_dict { 'unit' } ) {
2012-10-30 06:24:30 +00:00
# unit must be specified together with rack.
if ( ! exists $ args_dict { 'rack' } ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Specified unit must also include specified rack" ) ;
2012-10-30 06:24:30 +00:00
return ;
}
2012-10-12 07:11:26 +00:00
# Not a valid number.
if ( ! ( $ args_dict { 'unit' } =~ /^\d+$/ ) ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Specified unit $args_dict{'u'} is invalid" ) ;
2012-10-12 07:11:26 +00:00
return ;
}
}
if ( exists $ args_dict { 'height' } ) {
2012-10-30 06:24:30 +00:00
# unit must be specified together with rack.
if ( ! exists $ args_dict { 'rack' } ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Specified height must include specified rack." ) ;
2012-10-30 06:24:30 +00:00
return ;
}
2012-10-12 07:11:26 +00:00
# Not a valid number.
if ( ! ( $ args_dict { 'height' } =~ /^\d+$/ ) ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Specified height $args_dict{'height'} is invalid." ) ;
2012-10-12 07:11:26 +00:00
return ;
}
}
2013-04-12 08:08:17 +00:00
# Check the running of sequential discovery
my @ PCMdiscover = xCAT::TableUtils - > get_site_attribute ( "__SEQDiscover" ) ;
if ( $ PCMdiscover [ 0 ] ) {
setrsp_errormsg ( "Profile Discovery cannot be run together with Sequential discovery." ) ;
return ;
}
2012-09-27 08:56:19 +00:00
# Read DB to confirm the discover is not started yet.
2012-10-24 07:14:11 +00:00
my $ discover_running = xCAT::ProfiledNodeUtils - > is_discover_started ( ) ;
if ( $ discover_running ) {
2012-10-08 08:40:30 +00:00
setrsp_errormsg ( "Profiled nodes discovery already started." ) ;
2012-09-27 08:56:19 +00:00
return ;
}
2012-10-29 08:59:14 +00:00
# Make sure provisioning network has a dynamic range.
my $ provnet = xCAT::ProfiledNodeUtils - > get_netprofile_provisionnet ( $ args_dict { networkprofile } ) ;
if ( ! $ provnet ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Provisioning network not defined for network profile." ) ;
2012-10-29 08:59:14 +00:00
return ;
}
my $ networkstab = xCAT::Table - > new ( "networks" ) ;
my $ netentry = ( $ networkstab - > getAllAttribsWhere ( "netname = '$provnet'" , 'ALL' ) ) [ 0 ] ;
if ( ! $ netentry - > { 'dynamicrange' } ) {
2012-11-28 05:39:09 +00:00
setrsp_errormsg ( "Dynamic IP address range not defined for provisioning network." ) ;
2012-10-29 08:59:14 +00:00
return ;
}
2012-09-27 08:56:19 +00:00
# save discover args into table site.
my $ valuestr = "" ;
foreach ( keys % args_dict ) {
if ( $ args_dict { $ _ } ) {
$ valuestr . = "$_:$args_dict{$_}," ;
}
}
my $ sitetab = xCAT::Table - > new ( 'site' , - create = > 1 ) ;
$ sitetab - > setAttribs ( { "key" = > "__PCMDiscover" } , { "value" = > "$valuestr" } ) ;
$ sitetab - > close ( ) ;
2012-10-12 07:11:26 +00:00
setrsp_infostr ( "Profiled node's discover started" ) ;
2012-09-27 08:56:19 +00:00
}
#-------------------------------------------------------
2012-10-08 08:40:30 +00:00
= head3 nodediscoverstop
2012-09-27 08:56:19 +00:00
2012-10-08 08:40:30 +00:00
Description : Stop profiled nodes auto discover . This action will remove the
2012-09-27 08:56:19 +00:00
dababase flags .
Arguments : N / A
= cut
#------------------------------------------------------
2012-10-08 08:40:30 +00:00
sub nodediscoverstop {
2012-11-01 09:19:19 +00:00
2012-11-28 05:39:09 +00:00
my $ helpmsg = " nodediscoverstop: stops node auto - discovery .
2012-11-01 09:19:19 +00:00
Usage:
\ tnodediscoverstop
\ tnodediscoverstop [ - h | - - help ]
\ tnodediscoverstop { - v | - - version } " ;
my $ ret = validate_args ( $ helpmsg ) ;
if ( ! $ ret ) {
return ;
}
2012-09-27 08:56:19 +00:00
# Read DB to confirm the discover is started.
2012-10-12 07:11:26 +00:00
xCAT::MsgUtils - > message ( "Stopping profiled node's discover." ) ;
2012-10-24 07:14:11 +00:00
my $ discover_running = xCAT::ProfiledNodeUtils - > is_discover_started ( ) ;
if ( ! $ discover_running ) {
2013-04-01 10:32:07 +00:00
# do nothing that make sequential discovery to handle the message
# setrsp_errormsg("Node discovery for all nodes using profiles is not started.");
2012-09-27 08:56:19 +00:00
return ;
}
# remove site table records: discover flag.
my $ sitetab = xCAT::Table - > new ( "site" ) ;
my % keyhash ;
$ keyhash { 'key' } = "__PCMDiscover" ;
$ sitetab - > delEntries ( \ % keyhash ) ;
$ sitetab - > commit ( ) ;
# Update node's attributes, remove from gruop "__PCMDiscover".
# we'll call rmdef so that node's groupinfo in table nodelist will be updated automatically.
my @ nodes = xCAT::NodeRange:: noderange ( '__PCMDiscover' ) ;
if ( @ nodes ) {
# There are some nodes discvoered.
2012-11-05 15:00:12 +00:00
my $ retref = xCAT::Utils - > runxcmd ( { command = > [ "rmdef" ] , arg = > [ "-t" , "group" , "-o" , "__PCMDiscover" ] } , $ request_command , 0 , 2 ) ;
2012-09-27 08:56:19 +00:00
}
2012-11-28 05:39:09 +00:00
setrsp_infostr ( "Node discovery for all nodes using profiles stopped." ) ;
2012-09-27 08:56:19 +00:00
}
2012-10-22 09:37:09 +00:00
#-------------------------------------------------------
= head3 nodediscoverstatus
2013-04-06 09:07:21 +00:00
Description : This function is obsoleted that the status will be displayed by sequential discovery
Detect whether Profiled nodes discovery is running or not .
2012-10-22 09:37:09 +00:00
Arguments : N / A
= cut
#-------------------------------------------------------
sub nodediscoverstatus {
2012-11-01 09:19:19 +00:00
2012-11-28 05:39:09 +00:00
my $ helpmsg = " nodediscoverstatus: detects if node discovery is running .
2012-11-01 09:19:19 +00:00
Usage:
\ tnodediscoverstatus
\ tnodediscoverstatus [ - h | - - help ]
\ tnodediscoverstatus { - v | - - version } " ;
my $ ret = validate_args ( $ helpmsg ) ;
if ( ! $ ret ) {
return ;
}
2012-10-22 09:37:09 +00:00
my $ discover_running = xCAT::ProfiledNodeUtils - > is_discover_started ( ) ;
if ( $ discover_running ) {
2012-11-28 05:39:09 +00:00
setrsp_progress ( "Node discovery for all nodes using profiles is running" ) ;
2012-10-22 09:37:09 +00:00
} else {
2013-04-01 10:32:07 +00:00
# do nothing that make sequential discovery to handle the message
# setrsp_progress("Node discovery for all nodes using profiles is not started");
2012-10-22 09:37:09 +00:00
}
}
2012-09-27 08:56:19 +00:00
#-------------------------------------------------------
2012-10-08 08:40:30 +00:00
= head3 nodediscoverls
2012-09-27 08:56:19 +00:00
2012-10-08 08:40:30 +00:00
Description : List all discovered profiled nodes .
2012-09-27 08:56:19 +00:00
Arguments : N / A
= cut
#-------------------------------------------------------
2012-10-08 08:40:30 +00:00
sub nodediscoverls {
2012-11-28 05:39:09 +00:00
my $ helpmsg = " nodediscoverls: lists all discovered nodes using profiles .
2012-11-01 09:19:19 +00:00
Usage:
\ tnodediscoverls
\ tnodediscoverls [ - h | - - help ]
\ tnodediscoverls { - v | - - version } " ;
my $ ret = validate_args ( $ helpmsg ) ;
if ( ! $ ret ) {
return ;
}
2012-09-27 08:56:19 +00:00
# Read DB to confirm the discover is started.
2012-10-24 07:14:11 +00:00
my $ discover_running = xCAT::ProfiledNodeUtils - > is_discover_started ( ) ;
if ( ! $ discover_running ) {
2013-04-01 10:32:07 +00:00
# do nothing that make sequential discovery to handle the message
# setrsp_errormsg("Node discovery process is not running.");
2012-09-27 08:56:19 +00:00
return ;
}
my @ nodes = xCAT::NodeRange:: noderange ( '__PCMDiscover' ) ;
my $ mactab = xCAT::Table - > new ( "mac" ) ;
my $ macsref = $ mactab - > getNodesAttribs ( \ @ nodes , [ 'mac' ] ) ;
my $ nodelisttab = xCAT::Table - > new ( "nodelist" ) ;
2014-04-17 07:56:59 +00:00
# Get node current provisioning status.
my $ provisionapp = "provision" ;
my $ provision_status = xCAT::TableUtils - > getAppStatus ( \ @ nodes , $ provisionapp ) ;
2012-09-27 08:56:19 +00:00
2012-10-08 08:40:30 +00:00
my $ rspentry ;
my $ i = 0 ;
2012-09-27 08:56:19 +00:00
foreach ( @ nodes ) {
if ( ! $ _ ) {
next ;
}
2012-10-22 09:37:09 +00:00
$ rspentry - > { node } - > [ $ i ] - > { "name" } = $ _ ;
2012-10-12 07:11:26 +00:00
# Only get the MAC address of provisioning NIC.
my @ hostentries = split ( /\|/ , $ macsref - > { $ _ } - > [ 0 ] - > { "mac" } ) ;
foreach my $ hostandmac ( @ hostentries ) {
if ( ! $ hostandmac ) {
next ;
}
if ( index ( $ hostandmac , "!" ) == - 1 ) {
2012-10-22 09:37:09 +00:00
$ rspentry - > { node } - > [ $ i ] - > { "mac" } = $ hostandmac ;
2012-10-12 07:11:26 +00:00
last ;
}
}
2012-09-27 08:56:19 +00:00
2014-04-17 07:56:59 +00:00
if ( $ provision_status - > { $ _ } ) {
$ rspentry - > { node } - > [ $ i ] - > { "status" } = $ provision_status - > { $ _ } ;
2012-09-27 08:56:19 +00:00
} else {
2012-10-22 09:37:09 +00:00
$ rspentry - > { node } - > [ $ i ] - > { "status" } = "defined" ;
2012-09-27 08:56:19 +00:00
}
2012-10-08 08:40:30 +00:00
$ i + + ;
2012-09-27 08:56:19 +00:00
}
2012-10-22 09:37:09 +00:00
$ callback - > ( $ rspentry ) ;
2012-09-27 08:56:19 +00:00
}
#-------------------------------------------------------
= head3 findme
Description : The default interface for node discovery .
We must implement this method so that
2012-10-08 08:40:30 +00:00
profiled nodes ' s findme request can be answered
while profiled nodes discovery is running .
2012-09-27 08:56:19 +00:00
Arguments : N / A
= cut
#-------------------------------------------------------
sub findme {
2013-01-25 08:55:14 +00:00
# re-initalize the global variable
% args_dict = ( ) ;
2012-09-27 08:56:19 +00:00
# Read DB to confirm the discover is started.
2013-01-25 08:55:14 +00:00
my $ sitetab = xCAT::Table - > new ( 'site' ) ;
2013-01-28 21:38:13 +00:00
my $ stabent = $ sitetab - > getAttribs ( { 'key' = > '__PCMDiscover' } , ( 'value' ) ) ;
my $ sitevaluesstr ;
if ( ref $ stabent ) {
$ sitevaluesstr = $ stabent - > { 'value' } ;
}
2013-01-25 08:55:14 +00:00
unless ( $ sitevaluesstr ) {
2013-04-01 10:32:07 +00:00
#setrsp_errormsg("Profiled nodes discovery not started yet.");
2012-09-27 08:56:19 +00:00
return ;
}
2013-04-01 10:32:07 +00:00
xCAT::MsgUtils - > message ( 'S' , "Profile Discovery: Start.\n" ) ;
2012-09-27 08:56:19 +00:00
# We store node profiles in site table, key is "__PCMDiscover"
2013-01-25 08:55:14 +00:00
my @ profilerecords = split ( ',' , $ sitevaluesstr ) ;
2012-09-27 08:56:19 +00:00
foreach ( @ profilerecords ) {
if ( $ _ ) {
my ( $ profilename , $ profilevalue ) = split ( ':' , $ _ ) ;
if ( $ profilename and $ profilevalue ) {
$ args_dict { $ profilename } = $ profilevalue ;
}
}
}
# Get database records: all hostnames, all ips, all racks...
# To improve performance, we should initalize a daemon later??
2012-10-08 08:40:30 +00:00
xCAT::MsgUtils - > message ( 'S' , "Getting database records.\n" ) ;
my $ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'nodelist' , 'node' ) ;
2012-09-27 08:56:19 +00:00
% allhostnames = %$ recordsref ;
2012-10-08 08:40:30 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'ipmi' , 'bmc' ) ;
2012-09-27 08:56:19 +00:00
% allbmcips = %$ recordsref ;
2012-10-08 08:40:30 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'mac' , 'mac' ) ;
2012-09-27 08:56:19 +00:00
% allmacs = %$ recordsref ;
foreach ( keys % allmacs ) {
my @ hostentries = split ( /\|/ , $ _ ) ;
foreach my $ hostandmac ( @ hostentries ) {
my ( $ macstr , $ machostname ) = split ( "!" , $ hostandmac ) ;
$ allmacs { $ macstr } = 0 ;
}
}
2013-08-05 07:11:45 +00:00
% allmacsupper = ( ) ;
2013-06-26 09:41:39 +00:00
foreach ( keys % allmacs ) {
$ allmacsupper { uc ( $ _ ) } = 0 ;
}
2012-10-08 08:40:30 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_allnode_singleattrib_hash ( 'hosts' , 'ip' ) ;
2012-09-27 08:56:19 +00:00
% allinstallips = %$ recordsref ;
$ recordsref = xCAT::NetworkUtils - > get_all_nicips ( 1 ) ;
% allips = %$ recordsref ;
# Merge all BMC IPs and install IPs into allips.
% allips = ( % allips , % allbmcips , % allinstallips ) ;
2012-10-12 07:11:26 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_all_rack ( 1 ) ;
% allracks = %$ recordsref ;
2012-10-08 08:40:30 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_all_chassis ( 1 ) ;
2012-09-27 08:56:19 +00:00
% allchassis = %$ recordsref ;
2012-12-24 06:39:26 +00:00
$ recordsref = xCAT::ProfiledNodeUtils - > get_all_chassis ( 1 , 'cmm' ) ;
% allcmmchassis = %$ recordsref ;
2012-09-27 08:56:19 +00:00
# Get discovered client IP and MAC
my $ ip = $ request - > { '_xcat_clientip' } ;
2012-10-08 08:40:30 +00:00
xCAT::MsgUtils - > message ( 'S' , "Profield nodes discover: _xcat_clientip is $ip.\n" ) ;
2012-09-27 08:56:19 +00:00
my $ mac = '' ;
2013-05-08 09:40:02 +00:00
my $ arptable ;
2013-05-10 13:29:23 +00:00
if ( - x "/usr/sbin/arp" ) {
2013-05-08 09:40:02 +00:00
$ arptable = `/usr/sbin/arp -n` ;
}
else {
$ arptable = `/sbin/arp -n` ;
}
2012-09-27 08:56:19 +00:00
my @ arpents = split /\n/ , $ arptable ;
foreach ( @ arpents ) {
if ( m/^($ip)\s+\S+\s+(\S+)\s/ ) {
$ mac = $ 2 ;
last ;
}
}
if ( ! $ mac ) {
2012-10-08 08:40:30 +00:00
setrsp_errormsg ( "Profiled nodes discover: Can not get mac address of this node." ) ;
2012-09-27 08:56:19 +00:00
return ;
}
2012-10-08 08:40:30 +00:00
xCAT::MsgUtils - > message ( 'S' , "Profiled nodes discover: mac is $mac.\n" ) ;
2013-06-26 09:41:39 +00:00
if ( exists $ allmacsupper { uc ( $ mac ) } ) {
2012-09-27 08:56:19 +00:00
setrsp_errormsg ( "Discovered MAC $mac already exists in database." ) ;
return ;
}
# Assign TMPHOSTS9999 as a temporary hostname, in parse_hsots_string,
# it will detect this and arrange a real hostname for it.
my $ raw_hostinfo_str = "TMPHOSTS9999:\n mac=$mac\n" ;
# Append rack, chassis, unit, height into host info string.
2012-10-12 07:11:26 +00:00
foreach my $ key ( 'rack' , 'chassis' , 'unit' , 'height' ) {
2012-09-27 08:56:19 +00:00
if ( exists ( $ args_dict { $ key } ) ) {
$ raw_hostinfo_str . = " $key=$args_dict{$key}\n" ;
}
}
2012-10-12 07:11:26 +00:00
if ( exists $ args_dict { 'unit' } and exists $ args_dict { 'height' } ) {
2012-10-08 08:40:30 +00:00
# increase start unit automatically.
2012-10-12 07:11:26 +00:00
$ args_dict { 'unit' } = $ args_dict { 'unit' } + $ args_dict { 'height' } ;
# save discover args into table site.
my $ valuestr = "" ;
foreach ( keys % args_dict ) {
if ( $ args_dict { $ _ } ) {
$ valuestr . = "$_:$args_dict{$_}," ;
}
}
2013-01-25 08:55:14 +00:00
$ sitetab = xCAT::Table - > new ( 'site' , - create = > 1 ) ;
2012-10-12 07:11:26 +00:00
$ sitetab - > setAttribs ( { "key" = > "__PCMDiscover" } , { "value" = > "$valuestr" } ) ;
$ sitetab - > close ( ) ;
2012-10-08 08:40:30 +00:00
}
2012-12-24 06:39:26 +00:00
# For auto discovering PureFlex (x) nodes, set slotid attribute by default.
if ( exists $ args_dict { 'chassis' } ) {
if ( exists $ allcmmchassis { $ args_dict { 'chassis' } } ) {
$ raw_hostinfo_str . = " slotid=1\n" ;
}
}
2012-10-08 08:40:30 +00:00
2013-01-08 04:47:39 +00:00
xCAT::ProfiledNodeUtils - > parse_nodeinfo_file ( $ raw_hostinfo_str ) ;
my ( $ hostinfo_dict_ref , $ invalid_records_ref ) = validate_node_entries ( ) ;
2012-09-27 08:56:19 +00:00
my % hostinfo_dict = %$ hostinfo_dict_ref ;
2013-09-23 06:45:43 +00:00
# Create the full hostinfo dict
2012-10-08 08:40:30 +00:00
xCAT::MsgUtils - > message ( 'S' , "Profiled nodes discover: Generating new hostinfo string.\n" ) ;
2013-09-23 06:45:43 +00:00
my ( $ retcode_gen , $ retstr_gen ) = gen_new_hostinfo_dict ( $ hostinfo_dict_ref ) ;
2012-09-27 08:56:19 +00:00
unless ( $ retcode_gen ) {
setrsp_errormsg ( $ retstr_gen ) ;
return ;
}
2013-09-23 06:45:43 +00:00
# Create hosts and then call nodemgmt for node management plugins.
xCAT::MsgUtils - > message ( 'S' , "Creating nodes...\n" ) ;
my $ warnstr ;
if ( xCAT::DBobjUtils - > setobjdefs ( \ % hostinfo_dict ) != 0 ) {
$ warnstr = "Warning: failed to import node." ;
setrsp_progress ( $ warnstr ) ;
2012-10-22 09:37:09 +00:00
}
2012-09-27 08:56:19 +00:00
my @ nodelist = keys % hostinfo_dict ;
2014-04-17 07:56:59 +00:00
# setup node provisioning status.
xCAT::Utils - > runxcmd ( { command = > [ "updatenodestat" ] , node = > \ @ nodelist , arg = > [ 'defined' ] } , $ request_command , - 1 , 2 ) ;
2012-09-27 08:56:19 +00:00
2014-03-20 10:34:41 +00:00
# call makehosts to get the IP by resolving the name
my $ retref = xCAT::Utils - > runxcmd ( { command = > [ "makehosts" ] , node = > \ @ nodelist , sequential = > [ 1 ] } , $ request_command , 0 , 2 ) ;
2012-09-27 08:56:19 +00:00
# call discover to notify client.
2012-10-08 08:40:30 +00:00
xCAT::MsgUtils - > message ( 'S' , "Call discovered request.\n" ) ;
2012-09-27 08:56:19 +00:00
$ request - > { "command" } = [ "discovered" ] ;
$ request - > { "node" } = \ @ nodelist ;
2013-04-01 10:32:07 +00:00
$ request - > { discoverymethod } = [ 'profile' ] ;
2014-03-20 10:34:41 +00:00
$ retref = "" ;
$ retref = xCAT::Utils - > runxcmd ( $ request , $ request_command , 0 , 2 ) ;
2013-09-23 06:45:43 +00:00
my $ retstrref = parse_runxcmd_ret ( $ retref ) ;
2012-09-27 08:56:19 +00:00
2012-10-26 02:30:03 +00:00
xCAT::MsgUtils - > message ( 'S' , "Call nodemgmt plugins.\n" ) ;
2013-09-23 06:45:43 +00:00
$ retref = "" ;
2012-12-28 03:35:07 +00:00
$ retref = xCAT::Utils - > runxcmd ( { command = > [ "kitnodeadd" ] , node = > \ @ nodelist , sequential = > [ 1 ] } , $ request_command , 0 , 2 ) ;
2012-11-05 15:00:12 +00:00
$ retstrref = parse_runxcmd_ret ( $ retref ) ;
2012-10-26 02:30:03 +00:00
2012-09-27 08:56:19 +00:00
# Set discovered flag.
my $ nodegroupstr = $ hostinfo_dict { $ nodelist [ 0 ] } { "groups" } ;
my $ nodelstab = xCAT::Table - > new ( 'nodelist' , - create = > 1 ) ;
$ nodelstab - > setNodeAttribs ( $ nodelist [ 0 ] , { groups = > $ nodegroupstr . ",__PCMDiscover" } ) ;
$ nodelstab - > close ( ) ;
}
#-------------------------------------------------------
2013-09-23 06:45:43 +00:00
= head3 gen_new_hostinfo_dict
2012-09-07 08:19:36 +00:00
2013-09-23 06:45:43 +00:00
Description : Generate full hostinfo dict
2012-09-07 08:19:36 +00:00
Arguments : hostinfo_dict_ref - The reference of hostinfo dict .
Returns : ( returnvalue , returnmsg )
2013-09-23 06:45:43 +00:00
returnvalue - 0 , stands for generate new hostinfo dict failed .
1 , stands for generate new hostinfo dict OK .
2012-09-07 08:19:36 +00:00
returnnmsg - error messages if generate failed .
2013-09-23 06:45:43 +00:00
- OK for success cases .
2012-09-07 08:19:36 +00:00
= cut
#-------------------------------------------------------
2013-09-23 06:45:43 +00:00
sub gen_new_hostinfo_dict {
2012-09-07 08:19:36 +00:00
my $ hostinfo_dict_ref = shift ;
my % hostinfo_dict = %$ hostinfo_dict_ref ;
# Get free ips list for all networks in network profile.
my @ allknownips = keys % allips ;
2012-10-22 09:37:09 +00:00
my $ netprofileattrsref = xCAT::ProfiledNodeUtils - > get_nodes_nic_attrs ( [ $ args_dict { 'networkprofile' } ] ) - > { $ args_dict { 'networkprofile' } } ;
2012-09-07 08:19:36 +00:00
my % netprofileattr = %$ netprofileattrsref ;
my % freeipshash ;
foreach ( keys % netprofileattr ) {
my $ netname = $ netprofileattr { $ _ } { 'network' } ;
if ( $ netname and ( ! exists $ freeipshash { $ netname } ) ) {
2012-10-08 08:40:30 +00:00
$ freeipshash { $ netname } = xCAT::ProfiledNodeUtils - > get_allocable_staticips_innet ( $ netname , \ @ allknownips ) ;
2012-09-07 08:19:36 +00:00
}
}
# Get networkprofile's installip
my $ noderestab = xCAT::Table - > new ( 'noderes' ) ;
my $ networkprofile = $ args_dict { 'networkprofile' } ;
my $ nodereshashref = $ noderestab - > getNodeAttribs ( $ networkprofile , [ 'installnic' ] ) ;
my % nodereshash = %$ nodereshashref ;
my $ installnic = $ nodereshash { 'installnic' } ;
# Get node's provisioning method
2012-10-08 08:40:30 +00:00
my $ provmethod = xCAT::ProfiledNodeUtils - > get_imageprofile_prov_method ( $ args_dict { 'imageprofile' } ) ;
2012-12-24 03:49:00 +00:00
2014-08-12 09:31:24 +00:00
# Generate node's chain.
my % nodeprofiles = ( 'NetworkProfile' = > $ args_dict { 'networkprofile' } ,
'ImageProfile' = > $ args_dict { 'imageprofile' } ) ;
if ( defined $ args_dict { 'hardwareprofile' } ) { $ nodeprofiles { 'HardwareProfile' } = $ args_dict { 'hardwareprofile' } }
( my $ errcode , my $ chainstr ) = xCAT::ProfiledNodeUtils - > gen_chain_for_profiles ( \ % nodeprofiles , 1 ) ;
if ( $ errcode != 0 ) {
return ( 0 , "Failed to generate chain for nodes." ) ;
}
2014-01-27 05:52:33 +00:00
# start to check windows nodes, product will indicate it is a windows node: win2k8r2.enterprise
my ( $ osvers , $ osprofile ) = xCAT::ProfiledNodeUtils - > get_imageprofile_prov_osvers ( $ provmethod ) ;
my $ product = undef ;
if ( $ osvers =~ /^win/ )
{
$ product = "$osvers.$osprofile" ;
}
2012-12-24 03:49:00 +00:00
# Check whether this is Power env.
my $ is_fsp = xCAT::ProfiledNodeUtils - > is_fsp_node ( $ args_dict { 'networkprofile' } ) ;
2013-06-05 10:34:59 +00:00
foreach my $ item ( sort ( keys % hostinfo_dict ) ) {
2013-09-23 06:45:43 +00:00
# Set Nodes's type:
$ hostinfo_dict { $ item } { "objtype" } = 'node' ;
2014-06-13 06:34:28 +00:00
# Setup switches hash as switch table is a special one:
# We can not set values in table switch through hostinfo_dict,
# but must do that through $swtab1->setAttribs.
if ( defined $ hostinfo_dict { $ item } { switches } ) {
my @ switchlist = split ( /,/ , $ hostinfo_dict { $ item } { switches } ) ;
foreach my $ spi ( @ switchlist ) {
if ( $ spi ) {
my @ spilist = split ( /!/ , $ spi ) ;
my % keyshash = ( ) ;
my % valueshash = ( ) ;
$ keyshash { 'node' } = $ item ;
2014-06-17 09:15:31 +00:00
$ valueshash { 'interface' } = $ spilist [ 0 ] ;
$ keyshash { 'switch' } = $ spilist [ 1 ] ;
$ keyshash { 'port' } = $ spilist [ 2 ] ;
2014-06-13 06:34:28 +00:00
push @ switch_records , [ \ % keyshash , \ % valueshash ] ;
}
}
delete ( $ hostinfo_dict { $ item } { switches } ) ;
}
2013-04-01 07:16:59 +00:00
# Generate IPs for other interfaces defined in MAC file.
2012-09-07 08:19:36 +00:00
my % ipshash ;
2013-04-01 07:16:59 +00:00
foreach ( keys % netprofileattr ) {
2013-03-29 05:58:26 +00:00
# Not generate IP if exists other nics
if ( exists $ allothernics { $ item } - > { $ _ } ) {
2013-06-04 05:46:55 +00:00
$ ipshash { $ _ } = $ allothernics { $ item } - > { $ _ } ;
2013-03-29 05:58:26 +00:00
}
2013-04-01 07:16:59 +00:00
}
# Generate IPs for not defined interfaces.
foreach ( keys % netprofileattr ) {
my $ netname = $ netprofileattr { $ _ } { 'network' } ;
my $ freeipsref ;
if ( $ netname ) {
$ freeipsref = $ freeipshash { $ netname } ;
}
2013-06-24 06:48:40 +00:00
# Not generate other nic's ip if it is defined in file
2013-04-01 07:16:59 +00:00
if ( exists $ allothernics { $ item } - > { $ _ } ) {
next ;
}
2013-06-24 06:48:40 +00:00
# Not generate install nic ip if it is defined in file
if ( $ _ eq $ installnic and exists $ hostinfo_dict { $ item } { "ip" } ) {
next ;
}
2013-03-29 05:58:26 +00:00
# If generated IP is already used, re-generate free ip
2012-09-07 08:19:36 +00:00
my $ nextip = shift @$ freeipsref ;
2013-03-29 05:58:26 +00:00
while ( exists $ allips { $ nextip } ) {
$ nextip = shift @$ freeipsref ;
}
2012-09-07 08:19:36 +00:00
if ( ! $ nextip ) {
2012-11-28 05:39:09 +00:00
return 0 , "There are no more IP addresses available in the static network range of network $netname for interface $_" ;
2012-09-07 08:19:36 +00:00
} else {
$ ipshash { $ _ } = $ nextip ;
$ allips { $ nextip } = 0 ;
2013-03-29 05:58:26 +00:00
}
2012-09-07 08:19:36 +00:00
}
2013-06-24 06:48:40 +00:00
# Apply generated install nic ip to node if it is not defined in file.
2012-09-07 08:19:36 +00:00
if ( ! exists $ hostinfo_dict { $ item } { "ip" } ) {
if ( exists $ ipshash { $ installnic } ) {
$ hostinfo_dict { $ item } { "ip" } = $ ipshash { $ installnic } ;
} else {
2012-11-28 05:39:09 +00:00
return 0 , "There are no more IP addresses available in the static network range for interface $installnic" ;
2012-09-07 08:19:36 +00:00
}
}
2013-01-09 09:17:27 +00:00
2013-01-15 08:20:19 +00:00
my $ nicips = $ installnic . "!" . $ hostinfo_dict { $ item } { "ip" } ;
2013-01-09 09:17:27 +00:00
foreach ( keys % ipshash ) {
if ( $ _ eq $ installnic ) { next ; }
2013-01-15 06:04:22 +00:00
$ nicips = "$_!$ipshash{$_},$nicips" ;
2013-01-09 09:17:27 +00:00
}
$ hostinfo_dict { $ item } { "nicips" } = $ nicips ;
2014-01-27 05:52:33 +00:00
#save for windows node
if ( defined ( $ product ) && exists ( $ hostinfo_dict { $ item } { "prodkey" } ) )
{
if ( defined ( $ hostinfo_dict { $ item } { "prodkey" } ) )
{
my $ rst = xCAT::ProfiledNodeUtils - > update_windows_prodkey ( $ item , $ product , $ hostinfo_dict { $ item } { "prodkey" } ) ;
if ( $ rst == 1 )
{
return 0 , "Test Store windows per-node key failed for node: $item" ;
}
}
}
2012-09-07 08:19:36 +00:00
$ hostinfo_dict { $ item } { "objtype" } = "node" ;
$ hostinfo_dict { $ item } { "groups" } = "__Managed" ;
if ( exists $ args_dict { 'networkprofile' } ) { $ hostinfo_dict { $ item } { "groups" } . = "," . $ args_dict { 'networkprofile' } }
if ( exists $ args_dict { 'imageprofile' } ) { $ hostinfo_dict { $ item } { "groups" } . = "," . $ args_dict { 'imageprofile' } }
if ( exists $ args_dict { 'hardwareprofile' } ) { $ hostinfo_dict { $ item } { "groups" } . = "," . $ args_dict { 'hardwareprofile' } }
2012-10-29 08:59:14 +00:00
if ( exists $ args_dict { 'groups' } ) { $ hostinfo_dict { $ item } { "groups" } . = "," . $ args_dict { 'groups' } }
2012-12-24 03:49:00 +00:00
# xCAT limitation: slotid attribute only for power, id is for x.
if ( ( exists $ hostinfo_dict { $ item } { "slotid" } ) && ( ! $ is_fsp ) ) {
$ hostinfo_dict { $ item } { "id" } = $ hostinfo_dict { $ item } { "slotid" } ;
delete ( $ hostinfo_dict { $ item } { "slotid" } ) ;
}
# generage mpa attribute for blades managed by CMM.
if ( exists $ hostinfo_dict { $ item } { "chassis" } ) {
my $ chassisname = $ hostinfo_dict { $ item } { "chassis" } ;
if ( exists $ allcmmchassis { $ chassisname } ) {
$ hostinfo_dict { $ item } { "mpa" } = $ chassisname ;
}
}
2013-09-23 06:45:43 +00:00
# generate CEC-based rack-mount Power nodes' attributes
# lparid is optional, if not set, set it to 1
if ( ( exists $ hostinfo_dict { $ item } { "cec" } ) && ( ! $ is_fsp ) ) {
$ hostinfo_dict { $ item } { "hcp" } = $ hostinfo_dict { $ item } { "cec" } ;
$ hostinfo_dict { $ item } { "parent" } = $ hostinfo_dict { $ item } { "cec" } ;
delete ( $ hostinfo_dict { $ item } { "cec" } ) ;
if ( exists $ hostinfo_dict { $ item } { "lparid" } ) {
$ hostinfo_dict { $ item } { "id" } = $ hostinfo_dict { $ item } { "lparid" } ;
delete ( $ hostinfo_dict { $ item } { "lparid" } ) ;
} else {
$ hostinfo_dict { $ item } { "id" } = 1 ;
}
$ hostinfo_dict { $ item } { "mgt" } = "fsp" ;
}
2012-09-07 08:19:36 +00:00
2013-06-20 04:01:22 +00:00
# get the chain attribute from hardwareprofile and insert it to node.
my $ chaintab = xCAT::Table - > new ( 'chain' ) ;
my $ hardwareprofile = $ args_dict { 'hardwareprofile' } ;
my $ chain = $ chaintab - > getNodeAttribs ( $ hardwareprofile , [ 'chain' ] ) ;
2014-08-12 09:31:24 +00:00
$ hostinfo_dict { $ item } { "chain" } = $ chainstr ;
2013-06-20 04:01:22 +00:00
2012-12-13 02:00:48 +00:00
if ( exists $ netprofileattr { "bmc" } ) { # Update BMC records.
2012-09-07 08:19:36 +00:00
$ hostinfo_dict { $ item } { "mgt" } = "ipmi" ;
if ( exists $ ipshash { "bmc" } ) {
$ hostinfo_dict { $ item } { "bmc" } = $ ipshash { "bmc" } ;
} else {
2012-11-28 05:39:09 +00:00
return 0 , "There are no more IP addresses available in the static network range for the BMC network." ;
2012-09-07 08:19:36 +00:00
}
2012-12-13 02:00:48 +00:00
} elsif ( exists $ netprofileattr { "fsp" } ) { # Update FSP records
$ hostinfo_dict { $ item } { "mgt" } = "fsp" ;
$ hostinfo_dict { $ item } { "mpa" } = $ hostinfo_dict { $ item } { "chassis" } ;
if ( exists $ ipshash { "fsp" } ) {
$ hostinfo_dict { $ item } { "hcp" } = $ ipshash { "fsp" } ;
} else {
return 0 , "No sufficient IP addresses for FSP" ;
}
2012-09-07 08:19:36 +00:00
}
}
2013-09-23 06:45:43 +00:00
return 1 , "OK" ;
2012-09-07 08:19:36 +00:00
}
#-------------------------------------------------------
= head3 read_and_generate_hostnames
Description : Read hostinfo file and generate temporary hostnames for no - hostname specified ones .
Arguments : hostfile - the location of hostinfo file .
Returns : ( returnvalue , returnmsg )
returnvalue - 0 , stands for a failed return
1 , stands for a success return
returnnmsg - error messages for failed return .
- the contents of the hostinfo string .
= cut
#-------------------------------------------------------
sub read_and_generate_hostnames {
my $ hostfile = shift ;
# Get 10000 temprary hostnames.
2012-10-08 08:40:30 +00:00
my $ freehostnamesref = xCAT::ProfiledNodeUtils - > gen_numric_hostnames ( "TMPHOSTS" , "" , 4 ) ;
2012-09-07 08:19:36 +00:00
# Auto generate hostnames for "__hostname__" entries.
open ( HOSTFILE , $ hostfile ) ;
my $ filecontent = join ( "" , <HOSTFILE> ) ;
2012-10-29 08:59:14 +00:00
# Convert windows txt file into unix format.
$ filecontent =~ s/\cM\cJ/\n/g ;
2012-09-07 08:19:36 +00:00
while ( ( index $ filecontent , "__hostname__:" ) >= 0 ) {
my $ nexthost = shift @$ freehostnamesref ;
# no more valid hostnames to assign.
if ( ! $ nexthost ) {
2012-11-28 05:39:09 +00:00
return 1 , "Failed to generate a node name. There are no more valid node names available." ;
2012-09-07 08:19:36 +00:00
}
# This hostname already specified in hostinfo file.
if ( ( index $ filecontent , "$nexthost:" ) >= 0 ) {
next ;
}
# This hostname should not in database.
if ( exists $ allhostnames { $ nexthost } ) {
next ;
}
$ filecontent =~ s/__hostname__/$nexthost/ ;
}
close ( HOSTFILE ) ;
return 0 , $ filecontent ;
}
#-------------------------------------------------------
2013-01-08 04:47:39 +00:00
= head3 validate_node_entries
2012-09-07 08:19:36 +00:00
2013-01-08 04:47:39 +00:00
Description : Validate the node entrie and generate proper attributes .
Arguments : N / A
2012-09-07 08:19:36 +00:00
Returns : ( hostinfo_dict , invalid_records )
hostinfo_dict - Reference of hostinfo dict . Key are hostnames and values is an attributes dict .
invalid_records - Reference of invalid records list .
= cut
#-------------------------------------------------------
2013-01-08 04:47:39 +00:00
sub validate_node_entries {
2012-09-07 08:19:36 +00:00
my % hostinfo_dict ;
my @ invalid_records ;
2012-09-27 08:56:19 +00:00
my $ nameformat = $ args_dict { 'hostnameformat' } ;
2012-09-07 08:19:36 +00:00
2012-10-08 08:40:30 +00:00
my $ nameformattype = xCAT::ProfiledNodeUtils - > get_hostname_format_type ( $ nameformat ) ;
2012-09-07 08:19:36 +00:00
my % freehostnames ;
# Record duplicated items.
2013-01-08 04:47:39 +00:00
# We should go through list @::profiledNodeObjNames first as %::profiledNodeAttrs is just a hash,
2012-09-07 08:19:36 +00:00
# it not tells whether there are some duplicated hostnames in the hostinfo string.
my % hostnamedict ;
2013-01-08 04:47:39 +00:00
foreach my $ hostname ( @ ::profiledNodeObjNames ) {
2012-09-07 08:19:36 +00:00
if ( exists $ hostnamedict { $ hostname } ) {
push @ invalid_records , [ $ hostname , "Duplicated hostname defined" ] ;
2014-08-20 08:55:10 +00:00
} elsif ( length ( $ hostname ) > 63 ) {
# As the rule of IDN encoding, the length of hostname should less than 64 characters.
push @ invalid_records , [ $ hostname , "The length of hostname is more than 63 characters" ] ;
2012-09-07 08:19:36 +00:00
} else {
$ hostnamedict { $ hostname } = 0 ;
}
}
# Verify each node entry.
2012-11-19 08:56:16 +00:00
my $ rank = 0 ;
if ( exists ( $ args_dict { 'rank' } ) ) {
$ rank = $ args_dict { 'rank' } ;
}
2013-03-29 05:58:26 +00:00
# Get all nics attribute in networkprofile
my $ networkprofile = $ args_dict { networkprofile } ;
my $ netprofileattrsref = xCAT::ProfiledNodeUtils - > get_nodes_nic_attrs ( [ $ networkprofile ] ) - > { $ networkprofile } ;
my % netprofileattr = %$ netprofileattrsref ;
# Get install nic and provision network
my $ noderestab = xCAT::Table - > new ( 'noderes' ) ;
my $ nodereshashref = $ noderestab - > getNodeAttribs ( $ networkprofile , [ 'installnic' ] ) ;
my % nodereshash = %$ nodereshashref ;
my $ installnic = $ nodereshash { 'installnic' } ;
my $ provnet = $ netprofileattr { $ installnic } { "network" } ;
$ noderestab - > close ( ) ;
# Get all nics' static range
my % freeipshash = ( ) ;
foreach ( keys % netprofileattr ) {
my $ netname = $ netprofileattr { $ _ } { 'network' } ;
if ( $ netname and ( ! exists $ freeipshash { $ netname } ) ) {
$ freeipshash { $ netname } = xCAT::ProfiledNodeUtils - > get_allocable_staticips_innet ( $ netname ) ;
}
}
my $ freeprovipsref = $ freeipshash { $ provnet } ;
2012-12-11 03:33:46 +00:00
2012-12-13 03:32:16 +00:00
# get all chassis's rack info.
my @ chassislist = keys % allchassis ;
my $ chassisrackref = xCAT::ProfiledNodeUtils - > get_racks_for_chassises ( \ @ chassislist ) ;
2013-01-25 08:55:14 +00:00
foreach my $ attr ( @ ::profiledNodeObjNames ) {
2013-01-08 04:47:39 +00:00
my $ errmsg = validate_node_entry ( $ attr , $ ::profiledNodeAttrs { $ attr } ) ;
2012-12-11 03:33:46 +00:00
# Check whether specified IP is in our prov network, static range.
2013-01-08 04:47:39 +00:00
if ( $ ::profiledNodeAttrs { $ attr } - > { 'ip' } ) {
unless ( grep { $ _ eq $ ::profiledNodeAttrs { $ attr } - > { 'ip' } } @$ freeprovipsref ) {
$ errmsg . = "Specified IP address $::profiledNodeAttrs{$attr}->{'ip'} not in static range of provision network $provnet" ;
2012-12-11 03:33:46 +00:00
}
}
2013-03-29 05:58:26 +00:00
# Check nicips
my $ nic_and_ips ;
if ( $ ::profiledNodeAttrs { $ attr } - > { 'nicips' } ) {
my ( $ ret , $ othernicsref , $ outputmsg ) = xCAT::ProfiledNodeUtils - > check_nicips ( $ installnic , $ netprofileattrsref , \ % freeipshash , $ ::profiledNodeAttrs { $ attr } - > { 'nicips' } ) ;
if ( $ ret ) {
$ errmsg . = $ outputmsg ;
} else {
$ nic_and_ips = $ othernicsref ;
}
delete $ ::profiledNodeAttrs { $ attr } - > { 'nicips' } ;
}
2012-12-13 03:32:16 +00:00
# Set rack info for blades too.
2013-01-08 04:47:39 +00:00
if ( $ ::profiledNodeAttrs { $ attr } - > { 'chassis' } ) {
$ ::profiledNodeAttrs { $ attr } - > { 'rack' } = $ chassisrackref - > { $ ::profiledNodeAttrs { $ attr } - > { 'chassis' } } ;
2012-12-13 03:32:16 +00:00
}
2012-09-07 08:19:36 +00:00
if ( $ errmsg ) {
2012-12-11 03:33:46 +00:00
if ( $ attr =~ /^TMPHOSTS/ ) {
2012-09-07 08:19:36 +00:00
push @ invalid_records , [ "__hostname__" , $ errmsg ] ;
} else {
2012-12-11 03:33:46 +00:00
push @ invalid_records , [ $ attr , $ errmsg ] ;
2012-09-07 08:19:36 +00:00
}
next ;
}
2013-03-29 05:58:26 +00:00
my $ definedhostname = "" ;
2012-09-07 08:19:36 +00:00
# We need generate hostnames for this entry.
2012-12-11 03:33:46 +00:00
if ( $ attr =~ /^TMPHOSTS/ )
2012-09-07 08:19:36 +00:00
{
# rack + numric hostname format, we must specify rack in node's definition.
my $ numricformat ;
# Need convert hostname format into numric format first.
if ( $ nameformattype eq "rack" ) {
2013-01-08 04:47:39 +00:00
if ( ! exists $ ::profiledNodeAttrs { $ attr } { "rack" } ) {
2012-11-28 05:39:09 +00:00
push @ invalid_records , [ "__hostname__" , "Rack information is not specified. You must enter the required rack information." ] ;
2012-09-07 08:19:36 +00:00
next ;
}
2013-01-08 04:47:39 +00:00
$ numricformat = xCAT::ProfiledNodeUtils - > rackformat_to_numricformat ( $ nameformat , $ ::profiledNodeAttrs { $ attr } { "rack" } ) ;
2012-12-11 03:33:46 +00:00
if ( ! $ numricformat ) {
2013-01-08 04:47:39 +00:00
push @ invalid_records , [ "__hostname__" , "The rack number of rack $::profiledNodeAttrs{$attr}{'rack'} does not match hostname format $nameformat" ] ;
2012-12-11 03:33:46 +00:00
}
2012-09-07 08:19:36 +00:00
} else {
# pure numric hostname format
$ numricformat = $ nameformat ;
}
# Generate hostnames based on numric hostname format.
2012-11-19 08:56:16 +00:00
my $ hostnamelistref ;
2012-09-07 08:19:36 +00:00
if ( ! exists $ freehostnames { $ numricformat } ) {
2012-11-19 08:56:16 +00:00
$ hostnamelistref = xCAT::ProfiledNodeUtils - > genhosts_with_numric_tmpl ( $ numricformat , $ rank , 10000 ) ;
$ rank = $ rank + 10000 ;
if ( ! @$ hostnamelistref ) {
push @ invalid_records , [ "__hostname__" , "Can not generate sufficient hostnames from hostname format." ] ;
last ;
} else {
$ freehostnames { $ numricformat } = $ hostnamelistref ;
2012-09-27 08:56:19 +00:00
}
2012-09-07 08:19:36 +00:00
}
2012-11-19 08:56:16 +00:00
$ hostnamelistref = $ freehostnames { $ numricformat } ;
2012-09-07 08:19:36 +00:00
my $ nexthostname = shift @$ hostnamelistref ;
2012-12-11 03:33:46 +00:00
while ( ( ! $ nexthostname ) || exists $ allhostnames { $ nexthostname } ) {
2012-11-19 08:56:16 +00:00
if ( ! @$ hostnamelistref ) {
$ hostnamelistref = xCAT::ProfiledNodeUtils - > genhosts_with_numric_tmpl ( $ numricformat , $ rank , 10000 ) ;
$ rank = $ rank + 10000 ;
if ( ! @$ hostnamelistref ) {
push @ invalid_records , [ "__hostname__" , "Can not generate sufficient hostnames from hostname format." ] ;
last ;
}
}
2012-09-07 08:19:36 +00:00
$ nexthostname = shift @$ hostnamelistref ;
}
2013-03-29 05:58:26 +00:00
$ definedhostname = $ nexthostname ;
2013-01-08 04:47:39 +00:00
$ hostinfo_dict { $ nexthostname } = $ ::profiledNodeAttrs { $ attr } ;
2012-09-07 08:19:36 +00:00
} else {
2013-03-29 05:58:26 +00:00
$ definedhostname = $ attr ;
2013-01-08 04:47:39 +00:00
$ hostinfo_dict { $ attr } = $ ::profiledNodeAttrs { $ attr } ;
2012-09-07 08:19:36 +00:00
}
2013-03-29 05:58:26 +00:00
if ( $ nic_and_ips ) {
$ allothernics { $ definedhostname } = $ nic_and_ips ;
}
2012-09-07 08:19:36 +00:00
}
2013-03-29 05:58:26 +00:00
2012-09-07 08:19:36 +00:00
return ( \ % hostinfo_dict , \ @ invalid_records ) ;
}
#-------------------------------------------------------
= head3 validate_node_entry
Description : Validate a node info hash .
Arguments : node_name - node hostname .
node_entry_ref - Reference of the node info hash .
Returns : errormsg
- undef : stands for no errror .
- valid string: stands for the error message of validation .
= cut
#-------------------------------------------------------
sub validate_node_entry {
my $ node_name = shift ;
my $ node_entry_ref = shift ;
my % node_entry = %$ node_entry_ref ;
2012-12-11 03:33:46 +00:00
my $ errmsg = "" ;
2012-09-07 08:19:36 +00:00
# duplicate hostname found in hostinfo file.
if ( exists $ allhostnames { $ node_name } ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "Node name $node_name already exists. You must use a new node name.\n" ;
2012-09-07 08:19:36 +00:00
}
2014-08-10 14:09:21 +00:00
# Must specify either MAC, CEC or switch + port.
2014-01-27 05:52:33 +00:00
if ( exists $ node_entry { "mac" } ||
2014-08-28 09:27:15 +00:00
exists $ node_entry { "switches" } ||
2014-08-10 14:09:21 +00:00
exists $ node_entry { "cec" } ) {
2012-09-07 08:19:36 +00:00
} else {
2014-08-28 09:27:15 +00:00
$ errmsg . = "MAC address, cec, switches is not specified. You must specify the MAC address, CEC name or switches.\n" ;
2012-09-07 08:19:36 +00:00
}
if ( ! xCAT::NetworkUtils - > isValidHostname ( $ node_name ) ) {
2013-01-17 06:40:33 +00:00
unless ( $ node_name =~ /^TMPHOSTS/ ) {
$ errmsg . = "Node name: $node_name is invalid. You must use a valid node name.\n" ;
}
2012-09-07 08:19:36 +00:00
}
2012-12-13 02:00:48 +00:00
# validate if node use FSP network
my $ is_fsp = xCAT::ProfiledNodeUtils - > is_fsp_node ( $ args_dict { 'networkprofile' } ) ;
2012-09-07 08:19:36 +00:00
# validate each single value.
foreach ( keys % node_entry ) {
if ( $ _ eq "mac" ) {
2013-06-26 09:41:39 +00:00
if ( exists $ allmacsupper { uc ( $ node_entry { $ _ } ) } ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "MAC address $node_entry{$_} already exists in the database or in the nodeinfo file. You must use a new MAC address.\n" ;
2012-09-07 08:19:36 +00:00
} elsif ( ! xCAT::NetworkUtils - > isValidMAC ( $ node_entry { $ _ } ) ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "MAC address $node_entry{$_} is invalid. You must use a valid MAC address.\n" ;
2012-09-07 08:19:36 +00:00
} else {
$ allmacs { $ node_entry { $ _ } } = 0 ;
2014-05-29 06:30:09 +00:00
$ allmacsupper { uc ( $ node_entry { $ _ } ) } = 0 ;
2012-09-07 08:19:36 +00:00
}
} elsif ( $ _ eq "ip" ) {
if ( exists $ allips { $ node_entry { $ _ } } ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "IP address $node_entry{$_} already exists in the database or in the nodeinfo file.\n" ;
2012-11-05 03:22:16 +00:00
} elsif ( ( xCAT::NetworkUtils - > validate_ip ( $ node_entry { $ _ } ) ) [ 0 ] - > [ 0 ] ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "IP address $node_entry{$_} is invalid. You must use a valid IP address.\n" ;
2012-09-07 08:19:36 +00:00
} else {
#push the IP into allips list.
$ allips { $ node_entry { $ _ } } = 0 ;
}
2014-01-27 05:52:33 +00:00
} elsif ( $ _ eq "prodkey" ) {
# Get node's provisioning os version
my $ osimagename = xCAT::ProfiledNodeUtils - > get_imageprofile_prov_method ( $ args_dict { 'imageprofile' } ) ;
my ( $ osvers , $ profile ) = xCAT::ProfiledNodeUtils - > get_imageprofile_prov_osvers ( $ osimagename ) ;
if ( ! ( $ osvers =~ /^win/ ) ) {
$ errmsg . = "Specified Windows per-node key to a non-windows node is not acceptable\n" ;
}
# it will handle windows pernode key
if ( ! ( $ node_entry { $ _ } =~ /\w{5}-\w{5}-\w{5}-\w{5}-\w{5}/ ) ) {
$ errmsg . = "Specified Windows per-node key $node_entry{$_} is not valid\n" ;
}
#Transfer to capital
$ node_entry { $ _ } = uc $ node_entry { $ _ } ;
2014-06-13 06:34:28 +00:00
} elsif ( $ _ eq "switches" ) {
# switches=switch1!1!eth0,switch2!2!eth1
my @ interfaceslist = ( ) ;
my @ switchlist = split ( /,/ , $ node_entry { $ _ } ) ;
foreach my $ spi ( @ switchlist ) {
if ( $ spi ) {
my @ spilist = split ( /!/ , $ spi ) ;
if ( @ spilist != 3 ) {
$ errmsg . = "Invalid 'switches' value $node_entry{$_} specified.\n" ;
next ;
}
2014-06-17 09:15:31 +00:00
if ( ! exists $ allswitches { $ spilist [ 1 ] } ) {
$ errmsg . = "Specified switch $spilist[1] is not defined\n" ;
2014-06-13 06:34:28 +00:00
}
# Not a valid number.
2014-06-17 09:15:31 +00:00
if ( ! ( $ spilist [ 2 ] =~ /^\d+$/ ) ) {
$ errmsg . = "Specified port $spilist[2] is invalid\n" ;
2014-06-13 06:34:28 +00:00
}
# now, we need to check "swith_switchport" string list to avoid duplicate config
2014-06-17 09:15:31 +00:00
my $ switch_port = $ spilist [ 1 ] . "_" . $ spilist [ 2 ] ;
2014-06-13 06:34:28 +00:00
if ( exists $ all_switchports { $ switch_port } ) {
2014-06-17 09:15:31 +00:00
$ errmsg . = "Specified switch $spilist[1] and port $spilist[2] already exists in the database or in the nodeinfo file. You must use a new switch port.\n" ;
2014-06-13 06:34:28 +00:00
} else {
# after checking, add this one into all_switchports
$ all_switchports { $ switch_port } = 0 ;
}
}
2013-05-23 07:59:27 +00:00
}
2012-09-07 08:19:36 +00:00
} elsif ( $ _ eq "rack" ) {
2012-10-30 06:24:30 +00:00
if ( ! exists $ allracks { $ node_entry { $ _ } } ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "Specified rack $node_entry{$_} is not defined\n" ;
2012-09-07 08:19:36 +00:00
}
2012-09-27 08:56:19 +00:00
# rack must be specified with chassis or unit + height.
if ( exists $ node_entry { "chassis" } ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "Specified rack cannot be used with chassis.\n" ;
2012-10-12 07:11:26 +00:00
} elsif ( exists $ node_entry { "height" } and exists $ node_entry { "unit" } ) {
2012-09-27 08:56:19 +00:00
} else {
2013-10-10 07:29:35 +00:00
$ errmsg . = "Specified rack must also specify the height and unit.\n" ;
2012-09-27 08:56:19 +00:00
}
2012-09-07 08:19:36 +00:00
} elsif ( $ _ eq "chassis" ) {
2012-10-30 06:24:30 +00:00
if ( ! exists $ allchassis { $ node_entry { $ _ } } ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "Specified chassis $node_entry{$_} is not defined\n" ;
2012-09-07 08:19:36 +00:00
}
2012-09-27 08:56:19 +00:00
# Chassis must not be specified with unit and height.
2012-10-12 07:11:26 +00:00
if ( exists $ node_entry { "height" } or exists $ node_entry { "unit" } ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "Specified chassis cannot be used with height or unit.\n" ;
2012-09-27 08:56:19 +00:00
}
2012-12-13 02:00:48 +00:00
# Check if this chassis is CMM. If it is, must specify slotid
if ( exists $ allcmmchassis { $ node_entry { $ _ } } ) {
if ( not exists $ node_entry { "slotid" } ) {
2013-01-22 01:56:13 +00:00
$ errmsg . = "Specified CMM Chassis must be used with slotid" ;
2012-12-13 02:00:48 +00:00
}
} else {
# If the specific chassis is not CMM chassis, but network is fsp
if ( $ is_fsp ) {
$ errmsg . = "Specified FSP network must be used with CMM chassis."
}
}
2012-10-12 07:11:26 +00:00
} elsif ( $ _ eq "unit" ) {
2012-10-30 06:24:30 +00:00
if ( ! exists $ node_entry { "rack" } ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "Specified unit must be used with rack.\n" ;
2012-10-30 06:24:30 +00:00
}
2012-09-07 08:19:36 +00:00
# Not a valid number.
if ( ! ( $ node_entry { $ _ } =~ /^\d+$/ ) ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "Specified unit $node_entry{$_} is invalid\n" ;
2012-09-07 08:19:36 +00:00
}
} elsif ( $ _ eq "height" ) {
2012-11-07 07:29:45 +00:00
if ( ! exists $ node_entry { "rack" } ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "Height must be used with rack\n" ;
2012-10-30 06:24:30 +00:00
}
2012-09-07 08:19:36 +00:00
# Not a valid number.
if ( ! ( $ node_entry { $ _ } =~ /^\d+$/ ) ) {
2012-12-11 03:33:46 +00:00
$ errmsg . = "Specified height $node_entry{$_} is invalid\n" ;
2012-09-07 08:19:36 +00:00
}
2012-12-13 02:00:48 +00:00
} elsif ( $ _ eq "slotid" ) {
if ( not exists $ node_entry { "chassis" } ) {
$ errmsg . = "Specified slotid must be used with chassis" ;
}
# Not a valid number.
if ( ! ( $ node_entry { $ _ } =~ /^[1-9]\d*$/ ) ) {
$ errmsg . = "Specified slotid $node_entry{$_} is invalid" ;
}
2013-09-23 06:45:43 +00:00
} elsif ( $ _ eq "lparid" ) {
if ( not exists $ node_entry { "cec" } ) {
$ errmsg . = "The lparid option must be used with the cec option.\n" ;
}
} elsif ( $ _ eq "cec" ) {
2014-08-26 06:11:31 +00:00
my $ cec_name = $ node_entry { "cec" } ;
my $ lpar_id = 1 ;
2013-09-23 06:45:43 +00:00
# Check the specified CEC is existing
if ( ! exists $ allcecs { $ node_entry { $ _ } } ) {
$ errmsg . = "The CEC name $node_entry{$_} that is specified in the node information file is not defined in the system.\n" ;
2014-08-26 06:11:31 +00:00
} elsif ( exists $ node_entry { "lparid" } ) {
$ lpar_id = $ node_entry { "lparid" } ;
2013-09-23 06:45:43 +00:00
}
2014-08-26 06:11:31 +00:00
if ( exists $ alllparids { $ cec_name } { $ lpar_id } ) {
$ errmsg . = "The CEC name $cec_name and LPAR id $lpar_id already exist in the database or in the nodeinfo file. You must use a new CEC name and LPAR id.\n" ;
} else {
$ alllparids { $ cec_name } { $ lpar_id } = 0 ;
}
2013-03-29 05:58:26 +00:00
} elsif ( $ _ eq "nicips" ) {
2013-06-04 05:46:55 +00:00
# Check Multi-Nic's ip
my $ othernics = $ node_entry { $ _ } ;
foreach my $ nic_ips ( split ( /,/ , $ othernics ) ) {
my @ nic_and_ips = ( ) ;
my $ nic = "" ;
my $ nic_ip = "" ;
if ( $ nic_ips =~ /!/ and $ nic_ips !~ /!$/ ) {
@ nic_and_ips = split ( /!/ , $ nic_ips ) ;
$ nic_ip = $ nic_and_ips [ 1 ] ;
2013-07-03 13:42:15 +00:00
if ( exists $ allips { $ nic_ip } ) {
2013-06-04 05:46:55 +00:00
$ errmsg . = "IP address $nic_ip already exists in the database or in the nodeinfo file.\n" ;
} elsif ( ( xCAT::NetworkUtils - > validate_ip ( $ nic_ip ) ) [ 0 ] - > [ 0 ] ) {
$ errmsg . = "IP address $nic_ip is invalid. You must use a valid IP address.\n" ;
} else {
#push the IP into allips list.
$ allips { $ nic_ip } = 0 ;
}
}
2013-06-26 09:41:39 +00:00
}
2012-09-07 08:19:36 +00:00
} else {
2012-12-11 03:33:46 +00:00
$ errmsg . = "Invalid attribute $_ specified\n" ;
2012-09-07 08:19:36 +00:00
}
}
# push hostinfo into global dicts.
$ allhostnames { $ node_name } = 0 ;
2012-12-11 03:33:46 +00:00
return $ errmsg ;
2012-09-07 08:19:36 +00:00
}
#-------------------------------------------------------
= head3 setrsp_invalidrecords
Description : Set response for processing invalid host records .
Arguments : recordsref - Refrence of invalid nodes list .
= cut
#-------------------------------------------------------
sub setrsp_invalidrecords
{
my $ recordsref = shift ;
my $ rsp ;
# The total number of invalid records.
2013-01-05 07:04:02 +00:00
$ rsp - > { error } = [ "Errors found in nodeinfo file" ] ;
$ rsp - > { errorcode } = [ 2 ] ;
$ rsp - > { invalid_records_num } - > [ 0 ] = scalar @$ recordsref ;
2012-09-07 08:19:36 +00:00
# We write details of invalid records into a file.
2012-10-08 08:40:30 +00:00
my ( $ fh , $ filename ) = xCAT::ProfiledNodeUtils - > get_output_filename ( ) ;
2012-09-07 08:19:36 +00:00
foreach ( @$ recordsref ) {
my @ erroritem = @$ _ ;
2012-12-11 03:33:46 +00:00
print $ fh "nodename $erroritem[0], error:\n$erroritem[1]\n" ;
2012-09-07 08:19:36 +00:00
}
close $ fh ;
2012-10-12 07:11:26 +00:00
#make it readable for http.
system ( "chmod +r $filename" ) ;
2012-09-07 08:19:36 +00:00
# Tells the URL of the details file.
2012-10-22 09:37:09 +00:00
xCAT::MsgUtils - > message ( 'S' , "Detailed response info placed in file: $filename\n" ) ;
2013-01-05 07:04:02 +00:00
$ rsp - > { details } = [ $ filename ] ;
2012-09-07 08:19:36 +00:00
$ callback - > ( $ rsp ) ;
}
#-------------------------------------------------------
= head3 setrsp_errormsg
Description : Set response for error messages .
Arguments : errormsg - Error messages .
= cut
#-------------------------------------------------------
sub setrsp_errormsg
{
my $ errormsg = shift ;
my $ rsp ;
xCAT::MsgUtils - > message ( 'S' , "$errormsg\n" ) ;
2013-01-05 07:04:02 +00:00
$ rsp - > { error } = [ $ errormsg ] ;
$ rsp - > { errorcode } = [ 1 ] ;
2012-09-07 08:19:36 +00:00
$ callback - > ( $ rsp ) ;
}
2012-09-27 08:56:19 +00:00
#-------------------------------------------------------
= head3 setrsp_infostr
Description : Set response for a info string .
Arguments : infostr - The info string ..
= cut
#-------------------------------------------------------
sub setrsp_infostr
{
my $ infostr = shift ;
my $ rsp ;
xCAT::MsgUtils - > message ( 'S' , "$infostr\n" ) ;
2013-01-05 07:04:02 +00:00
$ rsp - > { data } = [ $ infostr ] ;
2012-10-08 08:40:30 +00:00
$ callback - > ( $ rsp ) ;
}
#-------------------------------------------------------
= head3 setrsp_progress
Description : Set response for running progress
Arguments : progress: the progress string .
= cut
#-------------------------------------------------------
sub setrsp_progress
{
my $ progress = shift ;
my $ rsp ;
xCAT::MsgUtils - > message ( 'S' , "$progress" ) ;
2013-01-05 07:04:02 +00:00
$ rsp - > { info } = [ $ progress ] ;
2012-09-27 08:56:19 +00:00
$ callback - > ( $ rsp ) ;
}
2012-10-08 08:40:30 +00:00
2012-09-07 08:19:36 +00:00
#-------------------------------------------------------
= head3 setrsp_success
Description : Set response for successfully processed nodes .
Arguments : recordsref - Refrence of nodes list .
= cut
#-------------------------------------------------------
sub setrsp_success
{
my $ recordsref = shift ;
2012-10-22 09:37:09 +00:00
my $ warnstr = shift ;
2012-09-07 08:19:36 +00:00
my $ rsp ;
# The total number of success nodes.
2013-01-05 07:04:02 +00:00
$ rsp - > { success_nodes_num } - > [ 0 ] = scalar @$ recordsref ;
2012-10-08 08:40:30 +00:00
my ( $ fh , $ filename ) = xCAT::ProfiledNodeUtils - > get_output_filename ( ) ;
2012-09-07 08:19:36 +00:00
foreach ( @$ recordsref ) {
print $ fh "success: $_\n" ;
}
2012-10-22 09:37:09 +00:00
if ( $ warnstr ) {
print $ fh "There are some warnings:\n$warnstr\n" ;
}
2012-09-07 08:19:36 +00:00
close $ fh ;
2012-10-12 07:11:26 +00:00
#make it readable for http.
system ( "chmod +r $filename" ) ;
2012-09-07 08:19:36 +00:00
# Tells the URL of the details file.
2012-10-22 09:37:09 +00:00
xCAT::MsgUtils - > message ( 'S' , "Detailed response info placed in file: $filename\n" ) ;
2013-01-05 07:04:02 +00:00
$ rsp - > { details } = [ $ filename ] ;
2012-09-07 08:19:36 +00:00
$ callback - > ( $ rsp ) ;
}
2012-10-22 09:37:09 +00:00
#-----------------------------------------------------
2012-11-05 15:00:12 +00:00
= head3 parse_runxcmd_ret
2012-10-22 09:37:09 +00:00
2012-11-05 15:00:12 +00:00
Description : Get return of runxcmd and convert it into strings .
2012-10-22 09:37:09 +00:00
Arguments : The return reference of runxcmd
2012-11-05 15:00:12 +00:00
Return: : [ $ outstr , $ errstr ] , A reference of list , placing standard output and standard error message .
2012-10-22 09:37:09 +00:00
= cut
#-----------------------------------------------------
2012-11-05 15:00:12 +00:00
sub parse_runxcmd_ret
2012-10-22 09:37:09 +00:00
{
2012-11-05 15:00:12 +00:00
my $ retref = shift ;
my $ msglistref ;
my $ outstr = "" ;
my $ errstr = "" ;
if ( $ retref ) {
if ( $ retref - > { data } ) {
$ msglistref = $ retref - > { data } ;
$ outstr = Dumper ( @$ msglistref ) ;
xCAT::MsgUtils - > message ( 'S' , "Command standard output: $outstr" ) ;
}
if ( $ retref - > { error } ) {
$ msglistref = $ retref - > { error } ;
$ errstr = Dumper ( @$ msglistref ) ;
xCAT::MsgUtils - > message ( 'S' , "Command error output: $errstr" ) ;
2012-10-22 09:37:09 +00:00
}
}
2012-11-05 15:00:12 +00:00
return [ $ outstr , $ errstr ] ;
2012-10-22 09:37:09 +00:00
}
2012-09-07 08:19:36 +00:00
1 ;