2010-06-28 21:25:56 +00:00
# IBM(c) 2010 EPL license http://www.eclipse.org/legal/epl-v10.html
#-------------------------------------------------------
= head1
2010-12-15 18:21:36 +00:00
xCAT plugin package to handle the snmove command
2010-06-28 21:25:56 +00:00
= cut
#-------------------------------------------------------
package xCAT_plugin::snmove ;
2010-12-15 18:21:36 +00:00
2010-06-28 21:25:56 +00:00
BEGIN
{
2010-12-15 18:21:36 +00:00
$ ::XCATROOT = $ ENV { 'XCATROOT' } ? $ ENV { 'XCATROOT' } : '/opt/xcat' ;
2010-06-28 21:25:56 +00:00
}
use lib "$::XCATROOT/lib/perl" ;
use strict ;
use xCAT::Table ;
use xCAT::Utils ;
use xCAT::NetworkUtils ;
use xCAT::MsgUtils ;
use Getopt::Long ;
use xCAT::NodeRange ;
2011-04-12 20:27:22 +00:00
#use Data::Dumper;
2010-06-28 21:25:56 +00:00
1 ;
#-------------------------------------------------------
= head3 handled_commands
Return list of commands handled by this plugin
= cut
#-------------------------------------------------------
sub handled_commands
{
2010-12-15 18:21:36 +00:00
return { snmove = > "snmove" , } ;
2010-06-28 21:25:56 +00:00
}
#-------------------------------------------------------
= head3 preprocess_request
Preprocess the command
= cut
#-------------------------------------------------------
sub preprocess_request
{
my $ request = shift ;
my $ callback = shift ;
my $ sub_req = shift ;
2010-12-15 18:21:36 +00:00
my $ command = $ request - > { command } - > [ 0 ] ;
my $ args = $ request - > { arg } ;
2010-06-28 21:25:56 +00:00
2010-12-15 18:21:36 +00:00
#if already preprocessed, go straight to process_request
if ( ( defined ( $ request - > { _xcatpreprocessed } ) )
2010-06-28 21:25:56 +00:00
&& ( $ request - > { _xcatpreprocessed } - > [ 0 ] == 1 ) )
{
return [ $ request ] ;
}
2010-12-15 18:21:36 +00:00
# let process_request handle it
2010-06-28 21:25:56 +00:00
my $ reqcopy = { %$ request } ;
$ reqcopy - > { _xcatpreprocessed } - > [ 0 ] = 1 ;
return [ $ reqcopy ] ;
}
#-------------------------------------------------------
= head3 process_request
Process the command
= cut
#-------------------------------------------------------
sub process_request
{
my $ request = shift ;
my $ callback = shift ;
my $ sub_req = shift ;
my $ command = $ request - > { command } - > [ 0 ] ;
my $ args = $ request - > { arg } ;
2010-12-15 18:21:36 +00:00
my $ error = 0 ;
2010-06-28 21:25:56 +00:00
# parse the options
2010-12-15 18:21:36 +00:00
@ ARGV = ( ) ;
if ( $ args )
{
@ ARGV = @ { $ args } ;
2010-06-28 21:25:56 +00:00
}
Getopt::Long:: Configure ( "bundling" ) ;
Getopt::Long:: Configure ( "no_pass_through" ) ;
2010-12-15 18:21:36 +00:00
if (
! GetOptions (
2011-04-12 20:27:22 +00:00
'h|help' = > \ $ ::HELP ,
'v|version' = > \ $ ::VERSION ,
's|source=s' = > \ $ ::SN1 , # source SN akb MN
'S|sourcen=s' = > \ $ ::SN1N , # source SN akb node
'd|dest=s' = > \ $ ::SN2 , # dest SN akb MN
'D|destn=s' = > \ $ ::SN2N , # dest SN akb node
'P|postscripts=s' = > \ $ ::POST , # postscripts to be run
'i|ignorenodes' = > \ $ ::IGNORE ,
'V|verbose' = > \ $ ::VERBOSE ,
2010-12-15 18:21:36 +00:00
)
)
2010-06-28 21:25:56 +00:00
{
2010-12-15 18:21:36 +00:00
& usage ( $ callback ) ;
return 1 ;
2010-06-28 21:25:56 +00:00
}
2010-12-15 18:21:36 +00:00
2010-06-28 21:25:56 +00:00
# display the usage if -h or --help is specified
2010-12-15 18:21:36 +00:00
if ( $ ::HELP )
{
& usage ( $ callback ) ;
return 0 ;
2010-06-28 21:25:56 +00:00
}
# display the version statement if -v or --verison is specified
if ( $ ::VERSION )
{
2010-12-15 18:21:36 +00:00
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = xCAT::Utils - > Version ( ) ;
$ callback - > ( $ rsp ) ;
return 0 ;
2010-06-28 21:25:56 +00:00
}
2011-04-12 20:27:22 +00:00
if ( ( $ ::IGNORE ) && ( $ ::POST ) ) {
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "-P and -i flags cannot be specified at the same time.\n" ;
$ callback - > ( $ rsp ) ;
return 1 ;
}
2010-12-15 18:21:36 +00:00
if ( @ ARGV > 1 )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Too many paramters.\n" ;
$ callback - > ( $ rsp ) ;
& usage ( $ callback ) ;
return 1 ;
2010-06-28 21:25:56 +00:00
}
2011-01-06 16:05:00 +00:00
if ( ( @ ARGV == 0 ) && ( ! $ ::SN1 ) )
2010-12-15 18:21:36 +00:00
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] =
"A node range or the source service node must be specified.\n" ;
$ callback - > ( $ rsp ) ;
& usage ( $ callback ) ;
return 1 ;
2010-06-28 21:25:56 +00:00
}
2010-12-15 18:21:36 +00:00
#
# get the list of nodes
# - either from the command line or by checking which nodes are
# managed by the servicenode (SN1)
#
my @ nodes = ( ) ;
if ( @ ARGV == 1 )
{
my $ nr = $ ARGV [ 0 ] ;
@ nodes = noderange ( $ nr ) ;
if ( nodesmissed )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] =
"Invalid nodes in noderange:" . join ( ',' , nodesmissed ) ;
$ callback - > ( $ rsp ) ;
return 1 ;
}
}
else
{
# get all the nodes that use SN1 as the primary service nodes
my $ pn_hash = xCAT::Utils - > getSNandNodes ( ) ;
foreach my $ snlist ( keys %$ pn_hash )
{
2011-01-06 16:05:00 +00:00
if ( ( $ snlist =~ /^$::SN1$/ ) || ( $ snlist =~ /^$::SN1\,/ ) )
2010-12-15 18:21:36 +00:00
{
push ( @ nodes , @ { $ pn_hash - > { $ snlist } } ) ;
}
}
2010-06-28 21:25:56 +00:00
}
2011-08-08 17:13:25 +00:00
#
# make sure all the nodes are resolvable
#
foreach my $ n ( @ nodes )
{
my $ packed_ip = xCAT::NetworkUtils - > getipaddr ( $ n ) ;
if ( ! $ packed_ip )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Could not resolve node \'$n\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
}
2011-04-12 20:27:22 +00:00
#
# get the node object definitions
#
my % objtype ;
my % nodehash ;
foreach my $ o ( @ nodes )
{
$ objtype { $ o } = 'node' ;
}
2010-06-28 21:25:56 +00:00
2011-04-12 20:27:22 +00:00
my % nhash = xCAT::DBobjUtils - > getobjdefs ( \ % objtype , $ callback ) ;
if ( ! ( % nhash ) )
{
my $ rsp ;
push @ { $ rsp - > { data } } , "Could not get xCAT object definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
2010-12-15 18:21:36 +00:00
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Changing the service node for the following nodes: \n @nodes\n" ;
$ callback - > ( $ rsp ) ;
2011-04-12 20:27:22 +00:00
#
# get the nimtype for AIX nodes (diskless or standalone)
#
my % nimtype ;
if ( xCAT::Utils - > isAIX ( ) )
{
# need to check the nimimage table to find the nimtype
my $ nimtab = xCAT::Table - > new ( 'nimimage' , - create = > 1 ) ;
if ( $ nimtab )
2010-12-15 18:21:36 +00:00
{
2011-04-12 20:27:22 +00:00
foreach my $ node ( @ nodes )
{
my $ provmethod = $ nhash { $ node } { 'provmethod' } ;
# get the nimtype
my $ ref = $ nimtab - > getAttribs ( { imagename = > $ provmethod } , 'nimtype' ) ;
if ( $ ref )
2010-12-15 18:21:36 +00:00
{
2011-04-12 20:27:22 +00:00
$ nimtype { $ node } = $ ref - > { 'nimtype' } ;
2010-12-15 18:21:36 +00:00
}
2011-04-12 20:27:22 +00:00
}
2010-12-15 18:21:36 +00:00
}
2011-04-12 20:27:22 +00:00
}
#
# get the backup sn for each node
#
my @ servlist ; # list of new service nodes
my % newsn ;
my $ nodehash ;
if ( $ ::SN2 ) { # we have the backup for each node from cmd line
foreach my $ n ( @ nodes ) {
$ newsn { $ n } = $ ::SN2 ;
2010-12-15 18:21:36 +00:00
}
2011-04-12 20:27:22 +00:00
push ( @ servlist , $ ::SN2 ) ;
} else {
# check the 2nd value of the servicenode attr
foreach my $ node ( @ nodes )
{
if ( $ nhash { $ node } { 'servicenode' } ) {
my @ sn = split ( ',' , $ nhash { $ node } { 'servicenode' } ) ;
if ( ( scalar ( @ sn ) > 2 ) && ( xCAT::Utils - > isAIX ( ) ) ) {
my $ rsp = { } ;
$ rsp - > { error } - > [ 0 ] =
"The service node attribute cannot have more than two values." ;
$ callback - > ( $ rsp ) ;
2010-12-15 18:21:36 +00:00
}
2011-04-12 20:27:22 +00:00
if ( $ sn [ 1 ] ) {
$ newsn { $ node } = $ sn [ 1 ] ;
if ( ! grep ( /^$sn[1]$/ , @ servlist ) ) {
push ( @ servlist , $ sn [ 1 ] ) ;
}
2010-12-15 18:21:36 +00:00
}
2011-04-12 20:27:22 +00:00
}
if ( ! $ newsn { $ node } ) {
my $ rsp = { } ;
$ rsp - > { error } - > [ 0 ] =
"Could not determine a backup service node for node $node." ;
$ callback - > ( $ rsp ) ;
$ error + + ;
}
}
}
2010-12-15 18:21:36 +00:00
2011-04-12 20:27:22 +00:00
if ( $ error ) {
return 1 ;
}
2010-12-15 18:21:36 +00:00
2011-04-12 20:27:22 +00:00
#
# get the new xcatmaster for each node
#
my % newxcatmaster ;
if ( $ ::SN2N ) { # we have the xcatmaster for each node from cmd line
foreach my $ n ( @ nodes ) {
$ newxcatmaster { $ n } = $ ::SN2N ;
}
} else {
# try to calculate the xcatmaster value for each node
# get all the interfaces from each SN
# $sni{$SN}= list of ip
my $ s = & getSNinterfaces ( \ @ servlist , $ callback , $ sub_req ) ;
my % sni = %$ s ;
# get the network info for each node
# $nethash{nodename}{networks attr name} = value
my % nethash = xCAT::DBobjUtils - > getNetwkInfo ( \ @ nodes ) ;
2011-04-14 19:34:11 +00:00
#print Dumper(%nethash);
2011-04-12 20:27:22 +00:00
# determine the xcatmaster value for the new SN
2010-12-15 18:21:36 +00:00
foreach my $ node ( @ nodes )
{
2011-04-12 20:27:22 +00:00
# get the node ip
# or use getNodeIPaddress
my $ nodeIP = xCAT::NetworkUtils - > getipaddr ( $ node ) ;
chomp $ nodeIP ;
# get the new SN for the node
my $ mySN = $ newsn { $ node } ;
# check each interface on the service node
foreach my $ IP ( @ { $ sni { $ mySN } } ) {
# if IP is in nodes subnet then thats the xcatmaster
if ( xCAT::NetworkUtils - > ishostinsubnet ( $ IP , $ nethash { $ node } { mask } , $ nethash { $ node } { net } ) ) {
# get the short hostname
my $ xcatmaster = xCAT::NetworkUtils - > gethostname ( $ IP ) ;
$ xcatmaster =~ s/\..*// ;
# add the value to the hash
$ newxcatmaster { $ node } = $ xcatmaster ;
last ;
2010-06-28 21:25:56 +00:00
}
2011-04-12 20:27:22 +00:00
}
if ( ! $ newxcatmaster { $ node } ) {
my $ rsp = { } ;
$ rsp - > { error } - > [ 0 ] =
"Could not determine an xcatmaster value for node $node." ;
$ callback - > ( $ rsp ) ;
$ error + + ;
}
}
}
2010-12-15 18:21:36 +00:00
2011-04-12 20:27:22 +00:00
if ( $ error ) {
return 1 ;
}
#
# reset the node attribute values
#
my % sn_hash ;
my $ old_node_hash = { } ;
foreach my $ node ( @ nodes )
{
my $ sn1 ;
my $ sn1n ;
my $ sn1n_ip ;
# get current xcatmaster
if ( $ ::SN1N ) { # use command line value
$ sn1n = $ ::SN1N ;
}
elsif ( $ nhash { $ node } { 'xcatmaster' } ) { # use xcatmaster attr
$ sn1n = $ nhash { $ node } { 'xcatmaster' } ;
}
if ( $ sn1n ) {
my @ ret = xCAT::Utils:: toIP ( $ sn1n ) ;
if ( $ ret [ 0 ] - > [ 0 ] == 0 ) {
$ sn1n_ip = $ ret [ 0 ] - > [ 1 ] ;
}
}
2011-01-06 16:05:00 +00:00
2011-04-12 20:27:22 +00:00
# get the servicenode values
my @ sn_a ;
my $ snlist = $ nhash { $ node } { 'servicenode' } ;
@ sn_a = split ( ',' , $ snlist ) ;
# get current servicenode
if ( $ ::SN1 )
{
# current SN from the command line
$ sn1 = $ ::SN1 ;
}
2010-12-15 18:21:36 +00:00
else
2011-04-12 20:27:22 +00:00
{
# current SN from node attribute
$ sn1 = $ sn_a [ 0 ] ;
}
# switch the servicenode attr list
my @ sn_temp = grep ( ! /^$newsn{$node}$/ , @ sn_a ) ;
unshift ( @ sn_temp , $ newsn { $ node } ) ;
my $ t = join ( ',' , @ sn_temp ) ;
$ sn_hash { $ node } { objtype } = 'node' ;
# set servicenode and xcatmaster attr
$ sn_hash { $ node } { 'servicenode' } = $ t ;
$ sn_hash { $ node } { 'xcatmaster' } = $ newxcatmaster { $ node } ;
$ old_node_hash - > { $ node } - > { 'oldsn' } = $ sn1 ;
$ old_node_hash - > { $ node } - > { 'oldmaster' } = $ sn1n ;
# set tftpserver
my $ tftp = $ nhash { $ node } { 'tftpserver' } ;
if ( $ tftp ) {
if ( $ sn1n && ( $ tftp eq $ sn1n ) )
{
$ sn_hash { $ node } { 'tftpserver' } = $ newxcatmaster { $ node } ;
} elsif ( $ sn1n_ip && ( $ tftp eq $ sn1n_ip ) ) {
$ sn_hash { $ node } { 'tftpserver' } = $ newxcatmaster { $ node } ;
}
}
# set nfsserver
my $ nfs = $ nhash { $ node } { 'nfsserver' } ;
#print "nfs=$nfs, sn1n=$sn1n, sn1n_ip=$sn1n_ip\n";
if ( $ nfs ) {
if ( $ sn1n && ( $ nfs eq $ sn1n ) )
{
$ sn_hash { $ node } { 'nfsserver' } = $ newxcatmaster { $ node } ;
} elsif ( $ sn1n_ip && ( $ nfs eq $ sn1n_ip ) ) {
$ sn_hash { $ node } { 'nfsserver' } = $ newxcatmaster { $ node } ;
}
}
#set monserver ( = "servicenode,xcatmaster" )
my $ mon = $ nhash { $ node } { 'monserver' } ;
if ( $ mon ) # if it is currently set
{
my @ tmp_a = split ( ',' , $ mon ) ;
if ( scalar ( @ tmp_a ) < 2 ) # it must have two values
{
my $ rsp ;
push @ { $ rsp - > { data } } , "The current value of the monserver attribute is not valid. It will not be reset.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
} else {
# if the first value is the current service node then change it
if ( $ tmp_a [ 0 ] eq $ sn1 )
2010-12-15 18:21:36 +00:00
{
2011-04-12 20:27:22 +00:00
$ sn_hash { $ node } { 'monserver' } = "$newsn{$node},$newxcatmaster{$node}" ;
2010-12-15 18:21:36 +00:00
}
2011-04-12 20:27:22 +00:00
}
2010-06-28 21:25:56 +00:00
}
2011-04-12 20:27:22 +00:00
}
2010-12-15 18:21:36 +00:00
my $ rsp ;
2011-04-12 20:27:22 +00:00
push @ { $ rsp - > { data } } , "Setting new values in the xCAT database.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
if ( keys ( % sn_hash ) > 0 )
{
# update the node definition
if ( xCAT::DBobjUtils - > setobjdefs ( \ % sn_hash ) != 0 )
2010-12-15 18:21:36 +00:00
{
2011-04-12 20:27:22 +00:00
my $ rsp ;
push @ { $ rsp - > { data } } , "Could not update xCAT node definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error + + ;
2010-12-15 18:21:36 +00:00
}
2011-04-12 20:27:22 +00:00
}
#
2010-12-15 18:21:36 +00:00
# handle conserver
2011-04-12 20:27:22 +00:00
#
2010-12-15 18:21:36 +00:00
my % sn_hash1 ;
2011-04-12 20:27:22 +00:00
foreach my $ node ( @ nodes )
{
if ( ( $ nhash { $ node } { 'conserver' } ) and ( $ nhash { $ node } { 'conserver' } eq $ old_node_hash - > { $ node } - > { 'oldsn' } ) ) {
$ sn_hash1 { $ node } { 'conserver' } = $ newsn { $ node } ;
$ sn_hash1 { $ node } { objtype } = 'node' ;
2010-06-28 21:25:56 +00:00
}
2011-04-12 20:27:22 +00:00
}
# update the node definition
if ( keys ( % sn_hash1 ) > 0 )
{
if ( xCAT::DBobjUtils - > setobjdefs ( \ % sn_hash1 ) != 0 )
2010-12-15 18:21:36 +00:00
{
2011-04-12 20:27:22 +00:00
my $ rsp ;
push @ { $ rsp - > { data } } , "Could not update xCAT node definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error + + ;
2010-06-28 21:25:56 +00:00
}
2011-04-12 20:27:22 +00:00
}
# run makeconservercf
2010-12-15 18:21:36 +00:00
my @ nodes_con = keys ( % sn_hash1 ) ;
if ( @ nodes_con > 0 )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Running makeconservercf " . join ( ',' , @ nodes_con ) ;
$ callback - > ( $ rsp ) ;
2011-04-12 20:27:22 +00:00
2010-12-15 18:21:36 +00:00
my $ ret =
2011-04-12 20:27:22 +00:00
xCAT::Utils - > runxcmd (
{
command = > [ 'makeconservercf' ] ,
node = > \ @ nodes_con ,
} ,
$ sub_req , 0 , 1
) ;
2010-12-15 18:21:36 +00:00
$ callback - > ( { data = > $ ret } ) ;
2010-06-28 21:25:56 +00:00
}
2011-04-12 20:27:22 +00:00
#
# Run niminit on AIX diskful nodes
#
if ( ! $ ::IGNORE ) # unless the user does not want us to touch the node
{
if ( xCAT::Utils - > isAIX ( ) )
2010-12-15 18:21:36 +00:00
{
2011-04-12 20:27:22 +00:00
#if the node is aix and the type is standalone
foreach my $ node ( @ nodes )
{
# if this is a standalone node then run niminit
if ( ( $ nimtype { $ node } ) && ( $ nimtype { $ node } eq 'standalone' ) ) {
my $ nimcmd = qq~/usr/sbin/niminit -a name=$node -a master=$newsn{$node} >/dev/null 2>&1~ ;
my $ out = xCAT::InstUtils - > xcmd ( $ callback , $ sub_req , "xdsh" , $ node , $ nimcmd , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp ;
push @ { $ rsp - > { data } } , "Could not run niminit on node $node.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
$ error + + ;
}
2010-06-28 21:25:56 +00:00
}
2011-04-12 20:27:22 +00:00
}
2010-06-28 21:25:56 +00:00
}
2011-04-12 20:27:22 +00:00
}
# for Linux system only
2010-12-15 18:21:36 +00:00
if ( xCAT::Utils - > isLinux ( ) )
{
#tftp, dhcp and nfs (site.disjointdhcps should be set to 1)
2011-04-12 20:27:22 +00:00
# get a list of nodes for each provmethod
2010-12-15 18:21:36 +00:00
my % nodeset_hash ;
foreach my $ node ( @ nodes )
{
2011-04-12 20:27:22 +00:00
my $ provmethod = $ nhash { $ node } { 'provmethod' } ;
if ( $ provmethod )
{
if ( ! grep ( /^$node$/ , @ { $ nodeset_hash { $ provmethod } } ) ) {
push ( @ { $ nodeset_hash { $ provmethod } } , $ node ) ;
}
2010-12-15 18:21:36 +00:00
}
}
2011-04-12 20:27:22 +00:00
# run the nodeset command
2010-12-15 18:21:36 +00:00
foreach my $ provmethod ( keys ( % nodeset_hash ) )
{
2011-04-12 20:27:22 +00:00
# need a node list to send to nodeset
my @ nodeset_nodes = @ { $ nodeset_hash { $ provmethod } } ;
if ( ( $ provmethod eq 'netboot' ) || ( $ provmethod eq 'install' ) || ( $ provmethod eq 'statelite' ) )
2010-12-15 18:21:36 +00:00
{
my $ ret =
2011-04-12 20:27:22 +00:00
xCAT::Utils - > runxcmd (
{
command = > [ 'nodeset' ] ,
node = > \ @ nodeset_nodes ,
arg = > [ $ provmethod ] ,
} ,
$ sub_req , 0 , 1
) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp ;
push @ { $ rsp - > { data } } , "Could not run the nodeset command.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
$ error + + ;
}
2010-12-15 18:21:36 +00:00
}
else
{
2011-04-12 20:27:22 +00:00
my $ ret = xCAT::Utils - > runxcmd ( { command = > [ 'nodeset' ] , node = > \ @ nodeset_nodes , arg = > [ "osimage=$provmethod" ] , } , $ sub_req , 0 , 1 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp ;
push @ { $ rsp - > { data } } , "Could not run the nodeset command.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
$ error + + ;
}
2010-12-15 18:21:36 +00:00
}
}
2011-04-12 20:27:22 +00:00
} # end - for Linux system only
#
# for both AIX and Linux systems
#
2011-04-14 19:34:11 +00:00
# setup the default gateway if the network.gateway=xcatmaster for the node
my % nethash ;
my % ipmap = ( ) ;
my % gwhash = ( ) ;
my $ nwtab = xCAT::Table - > new ( "networks" ) ;
if ( $ nwtab ) {
my @ tmp1 = $ nwtab - > getAllAttribs ( ( 'net' , 'mask' , 'gateway' , 'mgtifname' ) ) ;
if ( @ tmp1 && ( @ tmp1 > 0 ) ) {
foreach my $ nwitem ( @ tmp1 ) {
my $ gw = $ nwitem - > { 'gateway' } ;
if ( ! $ gw ) {
next ;
}
chomp $ gw ;
if ( $ gw ne '<xcatmaster>' ) {
next ;
}
#now only handle the networks that has <xcatmaster> as the gateway
my $ NM = $ nwitem - > { 'mask' } ;
my $ net = $ nwitem - > { 'net' } ;
my $ ifname = $ nwitem - > { 'mgtifname' } ;
chomp $ NM ;
chomp $ net ;
chomp $ ifname ;
#print "NM=$NM, net=$net, ifname=$ifname, nodes=@nodes\n";
# for each node - get the network info
foreach my $ node ( @ nodes )
{
# get, check, split the node IP
my $ IP = xCAT::NetworkUtils - > getipaddr ( $ node ) ;
chomp $ IP ;
# check the entries of the networks table
# - if the bitwise AND of the IP and the netmask gives you
# the "net" name then that is the entry you want.
if ( xCAT::NetworkUtils - > ishostinsubnet ( $ IP , $ NM , $ net ) )
{
my $ newmaster = $ newxcatmaster { $ node } ;
my $ newmasterIP ;
if ( exists ( $ ipmap { $ newmaster } ) ) {
$ newmasterIP = $ ipmap { $ newmaster } ;
} else {
$ newmasterIP = xCAT::NetworkUtils - > getipaddr ( $ newmaster ) ;
chomp ( $ newmasterIP ) ;
$ ipmap { $ newmaster } = $ newmasterIP ;
}
$ nethash { $ node } { 'gateway' } = $ newmasterIP ;
$ nethash { $ node } { 'net' } = $ net ;
$ nethash { $ node } { 'mask' } = $ NM ;
$ nethash { $ node } { 'mgtifname' } = $ ifname ;
if ( $ newmasterIP ) {
if ( exists ( $ gwhash { $ newmasterIP } ) ) {
my $ pa = $ gwhash { $ newmasterIP } ;
push ( @$ pa , $ node ) ;
} else {
$ gwhash { $ newmasterIP } = [ $ node ] ;
}
}
}
}
}
}
}
if ( keys ( % gwhash ) > 0 ) {
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Setting up the default routes on the nodes." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
}
foreach my $ gw ( keys % gwhash ) {
my $ cmd = "route add default gw" ; #this is temporary,TODO, set perminant route on the nodes.
if ( xCAT::Utils - > isAIX ( ) ) {
$ cmd = "route add default" ;
}
my $ ret =
xCAT::Utils - > runxcmd (
{
command = > [ 'xdsh' ] ,
node = > $ gwhash { $ gw } ,
arg = > [ "-v" , "$cmd $gw" ] ,
} ,
$ sub_req , - 1 , 1
) ;
if ( $ ::RUNCMD_RC != 0 )
{
$ error + + ;
}
my $ rsp ;
$ rsp - > { data } = $ ret ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
}
2010-12-15 18:21:36 +00:00
# run postscripts to take care of syslog, ntp, and mkresolvconf
2011-04-12 20:27:22 +00:00
# - if they are included in the postscripts table
2010-12-15 18:21:36 +00:00
if ( ! $ ::IGNORE ) # unless the user does not want us to touch the node
{
2011-04-12 20:27:22 +00:00
# get all the postscripts that should be run for the nodes
2010-12-15 18:21:36 +00:00
my $ pstab = xCAT::Table - > new ( 'postscripts' , - create = > 1 ) ;
my $ nodeposhash = { } ;
if ( $ pstab )
{
$ nodeposhash =
2011-04-12 20:27:22 +00:00
$ pstab - > getNodesAttribs ( \ @ nodes ,
[ 'postscripts' , 'postbootscripts' ] ) ;
2010-12-15 18:21:36 +00:00
}
else
{
my $ rsp = { } ;
$ rsp - > { error } - > [ 0 ] = "Cannot open postscripts table.\n" ;
$ callback - > ( $ rsp ) ;
return 1 ;
}
2011-04-12 20:27:22 +00:00
2010-12-15 18:21:36 +00:00
my $ et =
2011-04-12 20:27:22 +00:00
$ pstab - > getAttribs ( { node = > "xcatdefaults" } ,
'postscripts' , 'postbootscripts' ) ;
2010-12-15 18:21:36 +00:00
my $ defscripts = "" ;
my $ defbootscripts = "" ;
if ( $ et )
{
$ defscripts = $ et - > { 'postscripts' } ;
$ defbootscripts = $ et - > { 'postbootscripts' } ;
}
2011-04-12 20:27:22 +00:00
my $ user_posts ;
if ( $ ::POST ) {
$ user_posts = $ ::POST ;
}
2010-12-15 18:21:36 +00:00
my $ pos_hash = { } ;
foreach my $ node ( @ nodes )
{
2011-04-12 20:27:22 +00:00
2010-12-15 18:21:36 +00:00
foreach my $ rec ( @ { $ nodeposhash - > { $ node } } )
{
my $ scripts ;
if ( $ rec )
{
$ scripts = join ( ',' ,
$ defscripts ,
2011-04-12 20:27:22 +00:00
$ rec - > { 'postscripts' } ,
2010-12-15 18:21:36 +00:00
$ defbootscripts ,
2011-04-12 20:27:22 +00:00
$ rec - > { 'postbootscripts' } ) ;
2010-12-15 18:21:36 +00:00
}
else
{
$ scripts = join ( ',' , $ defscripts , $ defbootscripts ) ;
}
my @ tmp_a = split ( ',' , $ scripts ) ;
2011-08-08 17:13:25 +00:00
2011-04-12 20:27:22 +00:00
# xCAT's default scripts to be run: syslog, setupntp, and mkresolvconf
my @ valid_scripts = ( "syslog" , "setupntp" , "mkresolvconf" ) ;
2010-12-15 18:21:36 +00:00
my $ scripts1 = "" ;
2011-04-12 20:27:22 +00:00
if ( ( $ user_posts ) && ( $ user_posts eq "all" ) ) {
$ scripts1 = $ scripts ; #run all the postscripts defined in the postscripts table
} else {
foreach my $ s ( @ valid_scripts ) {
# if it was included in the original list then run it
if ( grep ( /^$s$/ , @ tmp_a ) )
{
if ( $ scripts1 ) {
$ scripts1 = "$scripts1,$s" ;
}
else
{
$ scripts1 = $ s ;
}
}
}
2010-12-15 18:21:36 +00:00
2011-04-12 20:27:22 +00:00
#append the user given scripts
if ( $ user_posts ) {
if ( $ scripts1 ) {
$ scripts1 = "$scripts1,$user_posts" ;
}
else
{
$ scripts1 = $ user_posts ;
}
}
}
2011-08-08 17:13:25 +00:00
2010-12-15 18:21:36 +00:00
if ( $ scripts1 )
{
2011-04-12 20:27:22 +00:00
if ( exists ( $ pos_hash - > { $ scripts1 } ) )
2010-12-15 18:21:36 +00:00
{
my $ pa = $ pos_hash - > { $ scripts1 } ;
push ( @$ pa , $ node ) ;
}
else
{
$ pos_hash - > { $ scripts1 } = [ $ node ] ;
}
}
}
}
2011-04-12 20:27:22 +00:00
#print Dumper($pos_hash);
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Running postscripts on the nodes." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
2010-12-15 18:21:36 +00:00
foreach my $ scripts ( keys ( %$ pos_hash ) )
{
2011-08-08 17:13:25 +00:00
2010-12-15 18:21:36 +00:00
my $ pos_nodes = $ pos_hash - > { $ scripts } ;
2011-08-08 17:13:25 +00:00
2010-12-15 18:21:36 +00:00
my $ ret =
2011-04-12 20:27:22 +00:00
xCAT::Utils - > runxcmd (
{
command = > [ 'updatenode' ] ,
node = > $ pos_nodes ,
arg = > [ "-P" , "$scripts" , "-s" ] ,
} ,
$ sub_req , - 1 , 1
) ;
if ( $ ::RUNCMD_RC != 0 )
{
$ error + + ;
2011-08-08 17:13:25 +00:00
2011-04-12 20:27:22 +00:00
}
my $ rsp ;
$ rsp - > { data } = $ ret ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
2010-12-15 18:21:36 +00:00
}
} # end -for both AIX and Linux systems
2011-04-12 20:27:22 +00:00
my $ retcode = 0 ;
2010-12-15 18:21:36 +00:00
if ( $ error )
2011-04-12 20:27:22 +00:00
{
#my $rsp;
#push @{$rsp->{data}}, "One or more errors occurred while attempting to switch nodes to a new service node.\n";
#xCAT::MsgUtils->message("E", $rsp, $callback);
$ retcode = 1 ;
}
#else
#{
# my $rsp;
# push @{$rsp->{data}}, "The nodes were successfully moved to the new service node.\n";
# xCAT::MsgUtils->message("I", $rsp, $callback);
#}
return $ retcode ;
2011-04-14 19:34:11 +00:00
}
2010-06-28 21:25:56 +00:00
2010-12-15 18:21:36 +00:00
#----------------------------------------------------------------------------
2010-06-28 21:25:56 +00:00
2010-12-15 18:21:36 +00:00
= head3 getSNinterfaces
2010-06-28 21:25:56 +00:00
2010-12-15 18:21:36 +00:00
Get a list of ip addresses for each service node in a list
2010-06-28 21:25:56 +00:00
2010-12-15 18:21:36 +00:00
Arguments:
list of servcie nodes
Returns:
1 - could not get list of ips
0 - ok
Globals:
none
Error:
none
Example:
my $ sni = xCAT::InstUtils - > getSNinterfaces ( \ @ servlist ) ;
Comments:
none
= cut
#-----------------------------------------------------------------------------
sub getSNinterfaces
{
#my ($class, $list, $callback, $subreq) = @_;
my ( $ list , $ callback , $ subreq ) = @ _ ;
my @ snlist = @$ list ;
my % SNinterfaces ;
# get all the possible IPs for the node I'm running on
my $ ifcmd ;
if ( xCAT::Utils - > isAIX ( ) )
{
$ ifcmd = "/usr/sbin/ifconfig -a " ;
}
else
{
$ ifcmd = "/sbin/ip addr " ;
}
foreach my $ sn ( @ snlist ) {
my $ SNIP ;
my $ result = xCAT::InstUtils - > xcmd ( $ callback , $ subreq , "xdsh" , $ sn , $ ifcmd , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
2011-04-12 20:27:22 +00:00
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] =
"Could not get IP addresses from service node $sn.\n" ;
$ callback - > ( $ rsp ) ;
next ;
2010-12-15 18:21:36 +00:00
}
foreach my $ int ( split ( /\n/ , $ result ) )
{
if ( ! grep ( /inet/ , $ int ) )
{
# only want line with "inet"
next ;
}
$ int =~ s/$sn:\s+// ; # skip hostname from xdsh output
my @ elems = split ( /\s+/ , $ int ) ;
if ( xCAT::Utils - > isLinux ( ) )
{
if ( $ elems [ 0 ] eq 'inet6' )
{
#Linux IPv6 TODO, do not return IPv6 networks on
# Linux for now
next ;
}
( $ SNIP , my $ mask ) = split /\// , $ elems [ 1 ] ;
}
else
{
# for AIX
if ( $ elems [ 0 ] eq 'inet6' )
{
$ SNIP = $ elems [ 1 ] ;
$ SNIP =~ s/\/.*// ; # ipv6 address 4000::99/64
$ SNIP =~ s/\%.*// ; # ipv6 address ::1%1/128
}
else
{
$ SNIP = $ elems [ 1 ] ;
}
}
chomp $ SNIP ;
push ( @ { $ SNinterfaces { $ sn } } , $ SNIP ) ;
}
}
return \ % SNinterfaces ;
2010-06-28 21:25:56 +00:00
}
2010-12-15 18:21:36 +00:00
#-----------------------------------------------------------------------------
sub usage
{
my $ cb = shift ;
my $ rsp = { } ;
push @ { $ rsp - > { data } } ,
"\nsnmove - Move xCAT compute nodes from one xCAT service node to a \nbackup service node." ;
push @ { $ rsp - > { data } } , "\nUsage: " ;
push @ { $ rsp - > { data } } , "\tsnmove -h" ;
push @ { $ rsp - > { data } } , "or" ;
push @ { $ rsp - > { data } } , "\tsnmove -v" ;
push @ { $ rsp - > { data } } , "or" ;
push @ { $ rsp - > { data } } ,
2011-04-12 20:27:22 +00:00
"\tsnmove noderange [-d sn2] [-D sn2n] [-i | -P scripts|all]" ;
2010-12-15 18:21:36 +00:00
push @ { $ rsp - > { data } } , "or" ;
push @ { $ rsp - > { data } } ,
2011-04-12 20:27:22 +00:00
"\tsnmove -s sn1 [-S sn1n] [-d sn2] [-D sn2n] [-i | -P scripts|all]" ;
2010-12-15 18:21:36 +00:00
push @ { $ rsp - > { data } } , "\n" ;
push @ { $ rsp - > { data } } , "\nWhere:" ;
push @ { $ rsp - > { data } } ,
"\tsn1 is the hostname of the source service node as known by (facing) the management node." ;
push @ { $ rsp - > { data } } ,
"\tsn1n is the hostname of the source service node as known by (facing) the nodes." ;
push @ { $ rsp - > { data } } ,
"\tsn2 is the hostname of the destination service node as known by (facing) the management node." ;
push @ { $ rsp - > { data } } ,
"\tsn2n is the hostname of the destination service node as known by (facing) the nodes." ;
2011-04-12 20:27:22 +00:00
push @ { $ rsp - > { data } } ,
"\tscripts is a comma separated list of postscripts to be run on the nodes. 'all' means all the scripts defined in the postscripts table for each node are to be run." ;
2010-12-15 18:21:36 +00:00
$ cb - > ( $ rsp ) ;
return 0 ;
}
2010-06-28 21:25:56 +00:00
2011-04-14 19:34:11 +00:00