2011-08-05 11:34:53 +00:00
2007-10-26 22:44:33 +00:00
#-------------------------------------------------------
2008-02-18 15:57:25 +00:00
= head1
2007-10-26 22:44:33 +00:00
xCAT plugin package to handle xdsh
Supported command:
xdsh - > dsh
xdcp - > dcp
= cut
#-------------------------------------------------------
package xCAT_plugin::xdsh ;
2008-07-18 12:04:28 +00:00
use strict ;
2009-07-07 11:38:53 +00:00
use Storable qw( dclone ) ;
2009-09-21 13:09:26 +00:00
use File::Basename ;
use File::Path ;
2010-05-14 16:23:19 +00:00
use POSIX ;
2008-04-07 19:25:44 +00:00
require xCAT::Table ;
2007-10-26 22:44:33 +00:00
2008-04-07 19:25:44 +00:00
require xCAT::Utils ;
2007-10-26 22:44:33 +00:00
2008-04-07 19:25:44 +00:00
require xCAT::MsgUtils ;
2007-12-12 13:24:36 +00:00
use Getopt::Long ;
require xCAT::DSHCLI ;
2007-10-26 22:44:33 +00:00
1 ;
#-------------------------------------------------------
2008-02-18 15:57:25 +00:00
= head3 handled_commands
2007-10-26 22:44:33 +00:00
Return list of commands handled by this plugin
= cut
#-------------------------------------------------------
sub handled_commands
{
return {
xdsh = > "xdsh" ,
xdcp = > "xdsh"
} ;
}
2008-03-10 18:25:22 +00:00
#-------------------------------------------------------
= head3 preprocess_request
Check and setup for hierarchy
= cut
#-------------------------------------------------------
2008-03-31 18:17:00 +00:00
sub preprocess_request
{
2009-12-04 14:48:50 +00:00
my $ req = shift ;
my $ cb = shift ;
my $ sub_req = shift ;
2008-03-31 18:17:00 +00:00
my % sn ;
2008-07-18 12:04:28 +00:00
my $ sn ;
2009-12-04 14:48:50 +00:00
my $ rc = 0 ;
2009-07-22 13:36:13 +00:00
2009-03-16 13:24:16 +00:00
#if already preprocessed, go straight to request
2009-12-04 14:48:50 +00:00
if ( ( defined ( $ req - > { _xcatpreprocessed } ) )
&& ( $ req - > { _xcatpreprocessed } - > [ 0 ] == 1 ) )
{
return [ $ req ] ;
}
my $ command = $ req - > { command } - > [ 0 ] ; # xdsh vs xdcp
2008-10-17 16:04:13 +00:00
my $ nodes = $ req - > { node } ;
my $ service = "xcat" ;
2008-07-18 12:04:28 +00:00
my @ requests ;
2009-12-04 14:48:50 +00:00
$ ::tmpsyncsnfile = "/tmp/xcatrf.tmp" ;
$ ::RUNCMD_RC = 0 ;
@ ::good_SN ;
@ ::bad_SN ;
my $ syncsn = 0 ; # sync service node only if 1
2009-06-25 18:17:53 +00:00
# read the environment variables for rsync setup
2010-05-14 16:23:19 +00:00
# and xdsh -e command
2009-05-19 14:59:17 +00:00
foreach my $ envar ( @ { $ req - > { env } } )
{
my ( $ var , $ value ) = split ( /=/ , $ envar , 2 ) ;
2009-07-22 13:36:13 +00:00
if ( $ var eq "RSYNCSNONLY" )
2009-06-04 12:21:10 +00:00
{ # syncing SN, will change noderange to list of SN
2009-07-22 13:36:13 +00:00
# we are only syncing the service node ( -s flag)
2009-06-04 12:21:10 +00:00
$ syncsn = 1 ;
2009-05-25 12:27:48 +00:00
}
2009-06-04 12:21:10 +00:00
if ( $ var eq "DSH_RSYNC_FILE" ) # from -F flag
{ # if hierarchy,need to copy file to the SN
2009-12-04 14:48:50 +00:00
$ ::syncsnfile = $ value ; # in the new /tmp/xcatrf.tmp
2009-05-19 14:59:17 +00:00
}
2009-12-04 14:48:50 +00:00
if ( $ var eq "DCP_PULL" ) # from -P flag
{
$ ::dcppull = 1 ; # TBD handle pull hierarchy
2009-09-23 11:44:08 +00:00
}
2010-05-14 16:23:19 +00:00
if ( $ var eq "DSHEXECUTE" ) # from xdsh -e flag
{
2010-05-14 17:18:42 +00:00
$ ::dshexecutecmd = $ value ; # Handle hierarchy
my @ cmd = split ( / / , $ value ) ; # split off args, if any
$ ::dshexecute = $ cmd [ 0 ] ; # This is the executable file
2010-05-14 16:23:19 +00:00
}
2009-05-19 14:59:17 +00:00
}
2008-03-31 18:17:00 +00:00
2009-12-04 14:48:50 +00:00
# there are nodes in the xdsh command, not xdsh to an image
2008-10-17 16:04:13 +00:00
if ( $ nodes )
{
2009-12-04 14:48:50 +00:00
# find service nodes for requested nodes
# build an individual request for each service node
# find out the names for the Management Node
my @ MNnodeinfo = xCAT::Utils - > determinehostname ;
my $ MNnodename = pop @ MNnodeinfo ; # hostname
my @ MNnodeipaddr = @ MNnodeinfo ; # ipaddresses
$ ::mnname = $ MNnodeipaddr [ 0 ] ;
$ ::SNpath ; # syncfile path on the service node
2008-10-17 16:04:13 +00:00
$ sn = xCAT::Utils - > get_ServiceNode ( $ nodes , $ service , "MN" ) ;
2009-09-21 13:09:26 +00:00
my @ snodes ;
my @ snoderange ;
2009-06-25 18:17:53 +00:00
2009-09-21 13:09:26 +00:00
# check to see if service nodes and not just the MN
2011-08-05 11:34:53 +00:00
# if just MN or I am on a Service Node, then no hierarchy to deal with
if ( ! ( xCAT::Utils - > isServiceNode ( ) ) ) { # not on a servicenode
if ( $ sn )
{
2009-09-21 13:09:26 +00:00
foreach my $ snkey ( keys %$ sn )
{
if ( ! grep ( /$snkey/ , @ MNnodeipaddr ) )
2009-12-04 14:48:50 +00:00
{ # if not the MN
2009-09-21 13:09:26 +00:00
push @ snodes , $ snkey ;
$ snoderange [ 0 ] . = "$snkey," ;
2009-12-04 14:48:50 +00:00
chop $ snoderange [ 0 ] ;
2009-09-21 13:09:26 +00:00
}
}
2011-08-05 11:34:53 +00:00
}
2009-12-04 14:48:50 +00:00
}
2009-06-25 18:17:53 +00:00
2010-05-14 16:23:19 +00:00
# if servicenodes and (if xdcp and not pull function or xdsh -e)
2009-12-04 14:48:50 +00:00
# send command to service nodes first and process errors
# return an array of good service nodes
#
2010-05-14 16:23:19 +00:00
my $ synfiledir ;
2009-12-04 14:48:50 +00:00
if ( @ snodes ) # service nodes
{
2010-05-14 16:23:19 +00:00
# if xdcp and not pull function or xdsh -e
if ( ( ( $ command eq "xdcp" ) && ( $ ::dcppull == 0 ) ) or ( $ ::dshexecute ) )
2009-05-25 12:27:48 +00:00
{
2009-09-21 13:09:26 +00:00
# get the directory on the servicenode to put the files in
my @ syndir = xCAT::Utils - > get_site_attribute ( "SNsyncfiledir" ) ;
if ( $ syndir [ 0 ] )
{
$ synfiledir = $ syndir [ 0 ] ;
2009-06-25 18:17:53 +00:00
}
2009-09-21 13:09:26 +00:00
else
{
2009-12-04 14:48:50 +00:00
$ synfiledir = "/var/xcat/syncfiles" ; # default
}
2009-09-21 13:09:26 +00:00
2009-12-04 14:48:50 +00:00
# setup the service node with the files to xdcp to the
# compute nodes
2010-05-14 16:23:19 +00:00
if ( $ command eq "xdcp" ) {
$ rc =
& process_servicenodes_xdcp ( $ req , $ cb , $ sub_req , \ @ snodes ,
2009-12-04 14:48:50 +00:00
\ @ snoderange , $ synfiledir ) ;
2009-09-21 13:09:26 +00:00
2010-05-14 16:23:19 +00:00
# fatal error need to stop
if ( $ rc != 0 )
{
return ;
}
} else { # xdsh -e
$ rc =
& process_servicenodes_xdsh ( $ req , $ cb , $ sub_req , \ @ snodes ,
\ @ snoderange , $ synfiledir ) ;
# fatal error need to stop
if ( $ rc != 0 )
{
return ;
}
2009-09-21 13:09:26 +00:00
}
2009-05-25 12:27:48 +00:00
}
2009-12-04 14:48:50 +00:00
else
2010-05-14 16:23:19 +00:00
{ # command is xdsh ( not -e) or xdcp pull
2009-12-04 14:48:50 +00:00
@ ::good_SN = @ snodes ; # all good service nodes for now
}
2009-06-04 12:21:10 +00:00
2009-12-04 14:48:50 +00:00
}
else
{ # no servicenodes, no hierarchy
# process here on the MN
& process_request ( $ req , $ cb , $ sub_req ) ;
return ;
}
# if hierarchical work still to do
# Note there may still be a mix of nodes that are service from
# the MN and nodes that are serviced from the SN, for example
# a dsh to a list of servicenodes and nodes in the noderange.
if ( $ syncsn == 0 ) # not just syncing (-s) the service nodes
# taken care of in process_servicenodes
{
2009-07-22 13:36:13 +00:00
foreach my $ snkey ( keys %$ sn )
{
2009-06-04 12:21:10 +00:00
2009-12-04 14:48:50 +00:00
# if it is not being service by the MN
2009-07-22 13:36:13 +00:00
if ( ! grep ( /$snkey/ , @ MNnodeipaddr ) )
2009-12-04 14:48:50 +00:00
{
# if it is a good SN, one ready to service the nodes
if ( grep ( /$snkey/ , @ ::good_SN ) )
2009-06-04 12:21:10 +00:00
{
2010-05-14 16:23:19 +00:00
my $ noderequests =
& process_nodes ( $ req , $ sn , $ snkey , $ synfiledir ) ;
2009-12-04 14:48:50 +00:00
push @ requests , $ noderequests ; # build request queue
2009-09-21 13:09:26 +00:00
}
2009-06-04 12:21:10 +00:00
}
2009-12-04 14:48:50 +00:00
else # serviced by the MN, then
{ # just run normal dsh dcp
2009-07-22 13:36:13 +00:00
my $ reqcopy = { %$ req } ;
$ reqcopy - > { node } = $ sn - > { $ snkey } ;
$ reqcopy - > { '_xcatdest' } = $ snkey ;
$ reqcopy - > { _xcatpreprocessed } - > [ 0 ] = 1 ;
push @ requests , $ reqcopy ;
}
} # end foreach
2009-12-04 14:48:50 +00:00
} # end syncing nodes
2008-10-17 16:04:13 +00:00
}
2009-12-04 14:48:50 +00:00
else # no nodes on the command
{ # running on local image
2008-10-17 16:04:13 +00:00
return [ $ req ] ;
2008-03-31 18:17:00 +00:00
}
return \ @ requests ;
}
2008-03-10 18:25:22 +00:00
2007-10-26 22:44:33 +00:00
#-------------------------------------------------------
2010-05-14 16:23:19 +00:00
= head3 process_servicenodes_xdcp
2009-12-04 14:48:50 +00:00
Build the xdcp command to send to the service nodes first
Return an array of servicenodes that do not have errors
Returns error code:
if = 0 , good return continue to process the
nodes .
if = 1 , global error need to quit
= cut
#-------------------------------------------------------
2010-05-14 16:23:19 +00:00
sub process_servicenodes_xdcp
2009-12-04 14:48:50 +00:00
{
my $ req = shift ;
my $ callback = shift ;
my $ sub_req = shift ;
my $ sn = shift ;
my $ snrange = shift ;
my $ synfiledir = shift ;
my @ snodes = @$ sn ;
my @ snoderange = @$ snrange ;
my $ args ;
$ ::RUNCMD_RC = 0 ;
my $ cmd = $ req - > { command } - > [ 0 ] ;
# if xdcp -F command (input $syncsnfile) and service nodes first need
# to be rsync to the
# $synfiledir directory
if ( $ ::syncsnfile )
{
if ( ! - f $ ::syncsnfile )
{ # syncfile does not exist, quit
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "File:$::syncsnfile does not exist." ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback , 1 ) ;
return ( 1 ) ; # process no service nodes
}
2010-05-14 16:23:19 +00:00
# xdcp rsync each of the files contained in the -F syncfile to
# the service node first to the site.SNsyncfiledir directory
2009-12-04 14:48:50 +00:00
#change noderange to the service nodes
# sync each one and check for error
# if error do not add to good_SN array, add to bad_SN
foreach my $ node ( @ snodes )
{
# run the command to each servicenode
# xdcp <sn> -s -F <syncfile>
my @ sn = ( ) ;
2011-01-05 15:29:59 +00:00
# handle multiple servicenodes for one node
my @ sn_list = split ',' , $ node ;
foreach my $ snode ( @ sn_list ) {
push @ sn , $ snode ;
}
2009-12-04 14:48:50 +00:00
# don't use runxcmd, because can go straight to process_request,
# these are all service nodes. Also servicenode is taken from
# the noderes table and may not be the same name as in the nodelist
# table, for example may be an ip address.
# here on the MN
my $ addreq ;
$ addreq - > { '_xcatdest' } = $ ::mnname ;
$ addreq - > { node } = \ @ sn ;
$ addreq - > { noderange } = \ @ sn ;
$ addreq - > { arg } - > [ 0 ] = "-s" ;
$ addreq - > { arg } - > [ 1 ] = "-F" ;
$ addreq - > { arg } - > [ 2 ] = $ ::syncsnfile ;
$ addreq - > { command } - > [ 0 ] = $ cmd ;
$ addreq - > { cwd } - > [ 0 ] = $ req - > { cwd } - > [ 0 ] ;
$ addreq - > { env } = $ req - > { env } ;
& process_request ( $ addreq , $ callback , $ sub_req ) ;
if ( $ ::FAILED_NODES == 0 )
{
push @ ::good_SN , $ node ;
}
else
{
push @ ::bad_SN , $ node ;
}
} # end foreach good servicenode
# for all the service nodes that are still good
# need to xdcp rsync file( -F input)
# to the service node to the /tmp/xcatrf.tmp file
my @ good_SN2 = @ ::good_SN ;
@ ::good_SN = ( ) ;
foreach my $ node ( @ good_SN2 )
{
my @ sn = ( ) ;
push @ sn , $ node ;
# run the command to each good servicenode
# xdcp <sn> <syncfile> <tmp/xcatrf.tmp>
my $ addreq ;
$ addreq - > { '_xcatdest' } = $ ::mnname ;
$ addreq - > { node } = \ @ sn ;
$ addreq - > { noderange } = \ @ sn ;
$ addreq - > { arg } - > [ 0 ] = "$::syncsnfile" ;
$ addreq - > { arg } - > [ 1 ] = "$::tmpsyncsnfile" ;
$ addreq - > { command } - > [ 0 ] = $ cmd ;
$ addreq - > { cwd } - > [ 0 ] = $ req - > { cwd } - > [ 0 ] ;
$ addreq - > { env } = $ req - > { env } ;
& process_request ( $ addreq , $ callback , $ sub_req ) ;
if ( $ ::FAILED_NODES == 0 )
{
push @ ::good_SN , $ node ;
}
else
{
push @ ::bad_SN , $ node ;
}
} # end foreach good service node
} # end xdcp -F
else
{
# if other xdcp commands, and not pull function
# mk the directory on the SN to hold the files
# to be sent to the SN.
# build a command to update the service nodes
# change the destination to the tmp location on
# the service node
# hierarchical support for pull (TBD)
#make the needed directory on the service node
# create new directory for path on Service Node
# xdsh <sn> mkdir -p $SNdir
my $ frompath = $ req - > { arg } - > [ - 2 ] ;
$ ::SNpath = $ synfiledir ;
$ ::SNpath . = $ frompath ;
my $ SNdir ;
$ SNdir = dirname ( $ ::SNpath ) ; # get directory
foreach my $ node ( @ snodes )
{
my @ sn = ( ) ;
2011-01-05 15:29:59 +00:00
# handle multiple servicenodes for one node
my @ sn_list = split ',' , $ node ;
foreach my $ snode ( @ sn_list ) {
push @ sn , $ snode ;
}
2009-12-04 14:48:50 +00:00
# run the command to each servicenode
# to make the directory under the temporary
# SNsyncfiledir to hold the files that will be
# sent to the service nodes
# xdsh <sn> mkdir -p <SNsyncfiledir>/$::SNpath
my $ addreq ;
$ addreq - > { '_xcatdest' } = $ ::mnname ;
$ addreq - > { node } = \ @ sn ;
$ addreq - > { noderange } = \ @ sn ;
$ addreq - > { arg } - > [ 0 ] = "mkdir " ;
$ addreq - > { arg } - > [ 1 ] = "-p " ;
$ addreq - > { arg } - > [ 2 ] = $ SNdir ;
$ addreq - > { command } - > [ 0 ] = 'xdsh' ;
$ addreq - > { cwd } - > [ 0 ] = $ req - > { cwd } - > [ 0 ] ;
$ addreq - > { env } = $ req - > { env } ;
& process_request ( $ addreq , $ callback , $ sub_req ) ;
if ( $ ::FAILED_NODES == 0 )
{
push @ ::good_SN , $ node ;
}
else
{
push @ ::bad_SN , $ node ;
}
} # end foreach good servicenode
# now xdcp file to the service node to the new
# tmp path
# for all the service nodes that are still good
my @ good_SN2 = @ ::good_SN ;
@ ::good_SN = ( ) ;
foreach my $ node ( @ good_SN2 )
{
my @ sn ;
push @ sn , $ node ;
# copy the file to each good servicenode
# xdcp <sn> <file> <SNsyncfiledir/../file>
my $ addreq = dclone ( $ req ) ; # get original request
$ addreq - > { arg } - > [ - 1 ] = $ SNdir ; # change to tmppath on servicenode
$ addreq - > { '_xcatdest' } = $ ::mnname ;
$ addreq - > { node } = \ @ sn ;
$ addreq - > { noderange } = \ @ sn ;
& process_request ( $ addreq , $ callback , $ sub_req ) ;
if ( $ ::FAILED_NODES == 0 )
{
push @ ::good_SN , $ node ;
}
else
{
push @ ::bad_SN , $ node ;
}
} # end foreach good service node
}
# report bad service nodes]
if ( @ ::bad_SN )
{
my $ rsp = { } ;
my $ badnodes ;
foreach my $ badnode ( @ ::bad_SN )
{
$ badnodes . = $ badnode ;
$ badnodes . = ", " ;
}
chop $ badnodes ;
my $ msg =
2010-06-09 18:15:16 +00:00
"\nThe following servicenodes: $badnodes have errors and cannot be updated\n Until the error is fixed, xdcp will not work to nodes serviced by these service nodes." ;
2009-12-04 14:48:50 +00:00
$ rsp - > { data } - > [ 0 ] = $ msg ;
xCAT::MsgUtils - > message ( "D" , $ rsp , $ callback ) ;
}
return ( 0 ) ;
}
2010-05-14 16:23:19 +00:00
#-------------------------------------------------------
= head3 process_servicenodes_xdsh
Build the xdsh command to send the - e file
The executable must be copied into /var/xc at / syncfiles , and then
the command modified so that the xdsh running on the SN will cp the file
from /var/xc at /syncfiles to the compute node / tmp directory and run it .
Return an array of servicenodes that do not have errors
Returns error code:
if = 0 , good return continue to process the
nodes .
if = 1 , global error need to quit
= cut
#-------------------------------------------------------
sub process_servicenodes_xdsh
{
my $ req = shift ;
my $ callback = shift ;
my $ sub_req = shift ;
my $ sn = shift ;
my $ snrange = shift ;
my $ synfiledir = shift ;
my @ snodes = @$ sn ;
my @ snoderange = @$ snrange ;
my $ args ;
$ ::RUNCMD_RC = 0 ;
my $ cmd = $ req - > { command } - > [ 0 ] ;
# if xdsh -e <executable> command, service nodes first need
# to be rsync with the executable file to the $synfiledir
if ( $ ::dshexecute )
{
if ( ! - f $ ::dshexecute )
{ # -e file does not exist, quit
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "File:$::dshexecute does not exist." ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback , 1 ) ;
return ( 1 ) ; # process no service nodes
}
# xdcp the executable from the xdsh -e to the service node first
# change noderange to the service nodes
# sync to each SN and check for error
# if error do not add to good_SN array, add to bad_SN
# build a tmp syncfile with
# $::dshexecute -> $synfiledir . $::dshexecute
my $ tmpsyncfile = POSIX:: tmpnam . ".dsh" ;
my $ destination = $ synfiledir . $ ::dshexecute ;
open ( TMPFILE , "> $tmpsyncfile" )
or die "can not open file $tmpsyncfile" ;
print TMPFILE "$::dshexecute -> $destination\n" ;
close TMPFILE ;
chmod 0755 , $ tmpsyncfile ;
foreach my $ node ( @ snodes )
{
# sync the file to the SN /var/xcat/syncfiles directory
# (site.SNsyncfiledir)
# xdcp <sn> -s -F <tmpsyncfile>
my @ sn = ( ) ;
2011-01-05 15:29:59 +00:00
# handle multiple servicenodes for one node
my @ sn_list = split ',' , $ node ;
foreach my $ snode ( @ sn_list ) {
push @ sn , $ snode ;
}
2010-05-14 16:23:19 +00:00
# don't use runxcmd, because can go straight to process_request,
# these are all service nodes. Also servicenode is taken from
# the noderes table and may not be the same name as in the nodelist
# table, for example may be an ip address.
# here on the MN
my $ addreq ;
$ addreq - > { '_xcatdest' } = $ ::mnname ;
$ addreq - > { node } = \ @ sn ;
$ addreq - > { noderange } = \ @ sn ;
$ addreq - > { arg } - > [ 0 ] = "-s" ;
$ addreq - > { arg } - > [ 1 ] = "-F" ;
$ addreq - > { arg } - > [ 2 ] = $ tmpsyncfile ;
$ addreq - > { command } - > [ 0 ] = "xdcp" ;
$ addreq - > { cwd } - > [ 0 ] = $ req - > { cwd } - > [ 0 ] ;
$ addreq - > { env } = $ req - > { env } ;
& process_request ( $ addreq , $ callback , $ sub_req ) ;
if ( $ ::FAILED_NODES == 0 )
{
push @ ::good_SN , $ node ;
}
else
{
push @ ::bad_SN , $ node ;
}
} # end foreach good servicenode
# remove the tmp syncfile
`/bin/rm $tmpsyncfile` ;
} # end xdsh -E
# report bad service nodes]
if ( @ ::bad_SN )
{
my $ rsp = { } ;
my $ badnodes ;
foreach my $ badnode ( @ ::bad_SN )
{
$ badnodes . = $ badnode ;
$ badnodes . = ", " ;
}
chop $ badnodes ;
my $ msg =
"\nThe following servicenodes: $badnodes have errors and cannot be updated\n Until the error is fixed, xdsh -e will not work to nodes serviced by these service nodes. Run xdsh <servicenode,...> -c , to clean up the xdcp servicenode directory, and run the command again." ;
$ rsp - > { data } - > [ 0 ] = $ msg ;
xCAT::MsgUtils - > message ( "D" , $ rsp , $ callback ) ;
}
return ( 0 ) ;
}
2009-12-04 14:48:50 +00:00
#-------------------------------------------------------
= head3 process_nodes
Build the request to send to the nodes , serviced by SN
Return the request
= cut
#-------------------------------------------------------
sub process_nodes
{
my $ req = shift ;
my $ sn = shift ;
my $ snkey = shift ;
2010-05-14 16:23:19 +00:00
my $ synfiledir = shift ;
2009-12-04 14:48:50 +00:00
my $ command = $ req - > { command } - > [ 0 ] ;
my @ requests ;
2010-05-14 16:23:19 +00:00
# if the xdcp -F option to sync the nodes
2009-12-04 14:48:50 +00:00
# then for a Node
# change the command to use the -F /tmp/xcatrf.tmp
# because that is where the file was put on the SN
#
my $ newSNreq = dclone ( $ req ) ;
if ( $ ::syncsnfile ) # -F option
{
my $ args = $ newSNreq - > { arg } ;
my $ i = 0 ;
foreach my $ argument ( @$ args )
{
# find the -F and change the name of the
# file in the next array entry to the tmp file
if ( $ argument eq "-F" )
{
$ i + + ;
$ newSNreq - > { arg } - > [ $ i ] = $ ::tmpsyncsnfile ;
last ;
}
$ i + + ;
}
}
2010-05-14 16:23:19 +00:00
2009-12-04 14:48:50 +00:00
else
{ # if other dcp command, change from directory
# to be the site.SNsyncfiledir
# directory on the service node
# if not pull (-P) pullfunction
# xdsh and xdcp pull just use the input request
if ( ( $ command eq "xdcp" ) && ( $ ::dcppull == 0 ) )
{
2012-06-28 15:51:50 +00:00
# have to change each file path and add the SNsynfiledir
# except the last entry which is the destination on the computenode
my $ args = $ newSNreq - > { arg } ;
my $ arraysize = @$ args ;
my $ i = 0 ;
2012-07-02 12:57:24 +00:00
foreach my $ sarg ( @$ args ) {
2012-06-28 15:51:50 +00:00
if ( $ arraysize > 1 ) {
2012-07-02 12:57:24 +00:00
if ( ( $ sarg !~ /^-/ ) && ( $ sarg !~ /^\// ) ) { # just a flag, skip
my $ tmpfile = $ synfiledir ;
$ tmpfile . = $ newSNreq - > { arg } - > [ $ i ] ;
$ newSNreq - > { arg } - > [ $ i ] = $ tmpfile ;
$ arraysize - - ;
$ i + + ;
}
2012-06-28 15:51:50 +00:00
} else {
last ;
}
}
2010-05-14 16:23:19 +00:00
} else { # if xdsh -e
if ( $ ::dshexecute ) { # put in new path from SN directory
my $ destination = $ synfiledir . $ ::dshexecute ;
my $ args = $ newSNreq - > { arg } ;
my $ i = 0 ;
foreach my $ argument ( @$ args )
{
# find the -e and change the name of the
# file in the next array entry to SN offset
if ( $ argument eq "-e" )
{
$ i + + ;
$ newSNreq - > { arg } - > [ $ i ] = $ destination ;
last ;
}
$ i + + ;
}
} # end if dshexecute
}
2009-12-04 14:48:50 +00:00
}
$ newSNreq - > { node } = $ sn - > { $ snkey } ;
$ newSNreq - > { '_xcatdest' } = $ snkey ;
$ newSNreq - > { _xcatpreprocessed } - > [ 0 ] = 1 ;
#push @requests, $newSNreq;
return $ newSNreq ;
}
#-------------------------------------------------------
2008-02-18 15:57:25 +00:00
= head3 process_request
2007-10-26 22:44:33 +00:00
Process the command
= cut
#-------------------------------------------------------
sub process_request
{
my $ request = shift ;
my $ callback = shift ;
2009-12-04 14:48:50 +00:00
my $ sub_req = shift ;
2011-01-18 15:39:55 +00:00
$ ::SUBREQ = $ sub_req ;
2009-12-04 14:48:50 +00:00
my $ nodes = $ request - > { node } ;
my $ command = $ request - > { command } - > [ 0 ] ;
my $ args = $ request - > { arg } ;
my $ envs = $ request - > { env } ;
my $ rsp = { } ;
2008-02-18 15:57:25 +00:00
# get the Environment Variables and set them in the current environment
2008-03-31 18:17:00 +00:00
foreach my $ envar ( @ { $ request - > { env } } )
{
my ( $ var , $ value ) = split ( /=/ , $ envar , 2 ) ;
$ ENV { $ var } = $ value ;
2007-12-12 13:24:36 +00:00
}
2010-03-15 15:50:16 +00:00
# if request->{username} exists, set DSH_FROM_USERID to it
# override input, this is what was authenticated
if ( ( $ request - > { username } ) && defined ( $ request - > { username } - > [ 0 ] ) ) {
$ ENV { DSH_FROM_USERID } = $ request - > { username } - > [ 0 ] ;
}
2007-12-12 13:24:36 +00:00
if ( $ command eq "xdsh" )
{
xdsh ( $ nodes , $ args , $ callback , $ command , $ request - > { noderange } - > [ 0 ] ) ;
2007-10-26 22:44:33 +00:00
}
else
{
2007-12-12 13:24:36 +00:00
if ( $ command eq "xdcp" )
2007-10-26 22:44:33 +00:00
{
2007-12-12 13:24:36 +00:00
xdcp ( $ nodes , $ args , $ callback , $ command ,
$ request - > { noderange } - > [ 0 ] ) ;
2007-10-26 22:44:33 +00:00
}
else
2007-12-12 13:24:36 +00:00
{
2008-10-17 16:04:13 +00:00
my $ rsp = { } ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 0 ] =
2008-02-18 15:57:25 +00:00
"Unknown command $command. Cannot process the command." ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback , 1 ) ;
return ;
2007-10-26 22:44:33 +00:00
}
}
}
#-------------------------------------------------------
2008-02-18 15:57:25 +00:00
= head3 xdsh
2007-10-26 22:44:33 +00:00
2008-02-18 15:57:25 +00:00
Parses Builds and runs the dsh
2007-10-26 22:44:33 +00:00
= cut
#-------------------------------------------------------
sub xdsh
{
2007-12-12 13:24:36 +00:00
my ( $ nodes , $ args , $ callback , $ command , $ noderange ) = @ _ ;
2008-03-31 18:17:00 +00:00
2009-12-04 14:48:50 +00:00
$ ::FAILED_NODES = 0 ;
2009-11-10 15:57:05 +00:00
# parse dsh input, will return $::NUMBER_NODES_FAILED
2008-07-18 12:04:28 +00:00
my @ local_results =
2007-12-12 13:24:36 +00:00
xCAT::DSHCLI - > parse_and_run_dsh ( $ nodes , $ args , $ callback ,
$ command , $ noderange ) ;
2009-12-04 14:48:50 +00:00
my $ maxlines = 10000 ;
my $ arraylen = @ local_results ;
my $ rsp = { } ;
my $ i = 0 ;
2009-10-22 13:53:49 +00:00
my $ j ;
2009-12-04 14:48:50 +00:00
while ( $ i < $ arraylen )
{
for ( $ j = 0 ; $ j < $ maxlines ; $ j + + )
{
if ( $ i > $ arraylen )
{
last ;
}
else
{
$ rsp - > { data } - > [ $ j ] = $ local_results [ $ i ] ; # send max lines
}
$ i + + ;
}
xCAT::MsgUtils - > message ( "D" , $ rsp , $ callback ) ;
2009-10-22 13:53:49 +00:00
}
2009-12-04 14:48:50 +00:00
2009-11-10 15:57:05 +00:00
# set return code
$ rsp = { } ;
2009-12-04 14:48:50 +00:00
$ rsp - > { errorcode } = $ ::FAILED_NODES ;
2009-11-10 15:57:05 +00:00
$ callback - > ( $ rsp ) ;
2009-12-04 14:48:50 +00:00
return ;
2007-12-12 13:24:36 +00:00
}
#-------------------------------------------------------
2008-02-18 15:57:25 +00:00
= head3 xdcp
2007-12-12 13:24:36 +00:00
2008-02-18 15:57:25 +00:00
Parses , Builds and runs the dcp command
2007-12-12 13:24:36 +00:00
= cut
#-------------------------------------------------------
sub xdcp
{
my ( $ nodes , $ args , $ callback , $ command , $ noderange ) = @ _ ;
2008-03-31 18:17:00 +00:00
2009-12-04 14:48:50 +00:00
$ ::FAILED_NODES = 0 ;
2008-03-10 18:25:22 +00:00
#`touch /tmp/lissadebug`;
2007-12-12 13:24:36 +00:00
# parse dcp input
2008-07-18 12:04:28 +00:00
my @ local_results =
2007-12-12 13:24:36 +00:00
xCAT::DSHCLI - > parse_and_run_dcp ( $ nodes , $ args , $ callback ,
$ command , $ noderange ) ;
2008-10-17 16:04:13 +00:00
my $ rsp = { } ;
my $ i = 0 ;
2007-12-12 13:24:36 +00:00
## process return data
2009-12-04 14:48:50 +00:00
if ( @ local_results )
2007-10-26 22:44:33 +00:00
{
2009-12-04 14:48:50 +00:00
foreach my $ line ( @ local_results )
{
$ rsp - > { data } - > [ $ i ] = $ line ;
$ i + + ;
}
2007-10-26 22:44:33 +00:00
2009-12-04 14:48:50 +00:00
xCAT::MsgUtils - > message ( "D" , $ rsp , $ callback ) ;
}
2009-06-25 18:17:53 +00:00
if ( - e "/tmp/xcatrf.tmp" )
{ # used tmp file for -F option
#`rm /tmp/xcatrf.tmp`;
2009-06-04 12:21:10 +00:00
}
2009-12-04 14:48:50 +00:00
# set return code
$ rsp = { } ;
$ rsp - > { errorcode } = $ ::FAILED_NODES ;
$ callback - > ( $ rsp ) ;
2008-02-18 15:57:25 +00:00
return ;
2007-10-26 22:44:33 +00:00
}