#!/usr/bin/env perl # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; } use lib "$::XCATROOT/lib/perl"; use File::Basename; #use Data::Dumper; use Getopt::Long; require xCAT::MsgUtils; require xCAT::DSHCLI; #require xCAT::Client; # delay the require of this until we know if -K was specified, because of XCATBYPASS mode my $bname = basename($0); #----------------------------------------------------------------------------- =head1 xdsh/xdcp This program is the client interface for xdsh/xdcp. xdsh/xdcp command This is the interface to for xdsh/xdsp The command can run in client/server mode (default) or in bypass mode where it does not use the xcat daemon xcatd. Bypass mode is useful, when executing the command on the Management Server and in particular if you want to run as a non-root id. Call parse_args to verify mode (client/server or bypass) and whether to use Env Variables Build hash and submit request See man page for options =cut #----------------------------------------------------------------------------- # Main # report unsupported dsh exports &check_invalid_exports; my $cmdref; my $arg; my @SaveARGV = @ARGV; $cmdref->{command}->[0] = $bname; # save my command name my $arg = shift(@SaveARGV); if ($arg =~ /^-/) # no noderange { push @{$cmdref->{arg}}, $arg; foreach (@SAVEARGV) { push(@{$cmdref->{arg}}, $_); } @ARGV = @{$cmdref->{arg}}; # save just the argument to parse } else { $cmdref->{noderange}->[0] = $arg; # save noderange @ARGV = @SaveARGV; # noderange removed for parsing } # check for help, bypass, other client flags if ($bname eq "xdsh") { &parse_args_xdsh; } else { # xdcp &parse_args_xdcp; } foreach (@SaveARGV) { push(@{$cmdref->{arg}}, $_); } # add environment variables, if they have not already been assigned with # command line flags if (!($::NODE_RSH)) { if ($ENV{'DSH_NODE_RSH'}) { push(@{$cmdref->{env}}, "DSH_NODE_RSH=$ENV{'DSH_NODE_RSH'}"); } } if (!($::NODE_OPTS)) { if ($ENV{'DSH_NODE_OPTS'}) { push(@{$cmdref->{env}}, "DSH_NODE_OPTS=$ENV{'DSH_NODE_OPTS'}"); } } if (!($::FANOUT)) { if ($ENV{'DSH_FANOUT'}) { push(@{$cmdref->{env}}, "DSH_FANOUT=$ENV{'DSH_FANOUT'}"); } } if (!($::TIMEOUT)) { if ($ENV{'DSH_TIMEOUT'}) { push(@{$cmdref->{env}}, "DSH_TIMEOUT=$ENV{'DSH_TIMEOUT'}"); } } if (!($::CONTEXT_SET)) { if ($ENV{'DSH_CONTEXT'}) { push(@{$cmdref->{env}}, "DSH_CONTEXT=$ENV{'DSH_CONTEXT'}"); } } require xCAT::Client; xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response); exit $xCAT::Client::EXITCODE; #----------------------------------------------------------------------------- =head3 parse_args_xdsh Parses for dsh input Check if the command ask for help and display usage Need to check only for the -X flag Need to check -B flag to determine mode =cut #----------------------------------------------------------------------------- sub parse_args_xdsh { Getopt::Long::Configure("posix_default"); Getopt::Long::Configure("no_gnu_compat"); Getopt::Long::Configure("bundling"); my %options = (); if ( !GetOptions( 'e|execute' => \$options{'execute'}, 'f|fanout=i' => \$options{'fanout'}, 'h|help' => \$options{'help'}, 'l|user=s' => \$options{'user'}, 'm|monitor' => \$options{'monitor'}, 'o|node-options=s' => \$options{'node-options'}, 'q|show-config' => \$options{'show-config'}, 'r|node-rsh=s' => \$options{'node-rsh'}, 's|stream' => \$options{'streaming'}, 't|timeout=i' => \$options{'timeout'}, 'v|verify' => \$options{'verify'}, 'z|exit-status' => \$options{'exit-status'}, 'B|bypass' => \$options{'bypass'}, 'C|context=s' => \$options{'context'}, 'E|environment=s' => \$options{'environment'}, 'I|ignore-sig|ignoresig=s' => \$options{'ignore-signal'}, 'K|keysetup' => \$options{'ssh-setup'}, 'L|no-locale' => \$options{'no-locale'}, 'Q|silent' => \$options{'silent'}, 'S|syntax=s' => \$options{'syntax'}, 'T|trace' => \$options{'trace'}, 'V|version' => \$options{'version'}, 'command-name|commandName=s' => \$options{'command-name'}, 'command-description|commandDescription=s' => \$options{'command-description'}, 'X:s' => \$options{'ignore_env'} ) ) { xCAT::DSHCLI->usage_dsh; exit 1; } if ($options{'help'}) { xCAT::DSHCLI->usage_dsh; exit 0; } if ($options{'bypass'} || $options{'ssh-setup'}) # must force bypass mode for -K, so it can prompt user for node pw { $ENV{XCATBYPASS} = "yes"; # bypass xcatd } if ($options{'version'}) { xCAT::MsgUtils->message("I", "Version 2.0\n"); exit 0; } if ($options{'node-rsh'}) # if set on command line, use it { $::NODE_RSH = 1; } if ($options{'node-opts'}) # if set on command line, use it { $::NODE_OPTS = 1; } if ($options{'fanout'}) # if set on command line, use it { $::FANOUT = 1; } if ($options{'timeout'}) # if set on command line, use it { $::TIMEOUT = 1; } if ($options{'context'}) # if a context is specified, use it { $::CONTEXT_SET = 1; } if (defined $options{'ignore_env'}) { xCAT::DSHCLI->ignoreEnv($options{'ignore_env'}); } } #----------------------------------------------------------------------------- =head3 parse_args_xdcp Parses for dcp input Check if the command ask for help and display usage Need to check -X flag to determine how to set Environment Variables Need to check -B flag to determine mode =cut #----------------------------------------------------------------------------- sub parse_args_xdcp { my %options = (); Getopt::Long::Configure("posix_default"); Getopt::Long::Configure("no_gnu_compat"); Getopt::Long::Configure("bundling"); if ( !GetOptions( 'f|fanout=i' => \$options{'fanout'}, 'h|help' => \$options{'help'}, 'l|user=s' => \$options{'user'}, 'n|nodes=s' => \$options{'nodes'}, 'o|node-options=s' => \$options{'node-options'}, 'q|show-config' => \$options{'show-config'}, 'p|preserve' => \$options{'preserve'}, 'r|c|node-rcp=s' => \$options{'node-rcp'}, 's' => \$options{'rsync'}, 't|timeout=i' => \$options{'timeout'}, 'v|verify' => \$options{'verify'}, 'B|bypass' => \$options{'bypass'}, 'C|context=s' => \$options{'context'}, 'Q|silent' => \$options{'silent'}, 'P|pull' => \$options{'pull'}, 'R|recursive' => \$options{'recursive'}, 'T|trace' => \$options{'trace'}, 'V|version' => \$options{'version'}, 'X:s' => \$options{'ignore_env'} ) ) { xCAT::DSHCLI->usage_dcp; exit 1; } if ($options{'help'}) { xCAT::DSHCLI->usage_dcp; exit 0; } if ($options{'version'}) { xCAT::MsgUtils->message("I", "Version 2.0"); exit 0; } if ($::BYPASS) { $ENV{XCATBYPASS} = "yes"; # bypass xcatd } } #----------------------------------------------------------------------------- =head3 check_invalid_exports Check for unsupported dsh exports and warns =cut #----------------------------------------------------------------------------- sub check_invalid_exports { ## # Check for unsupported Environment Variables # DSH_DEVICE_LIST, DSH_DEVICE_OPTS, DSH_DEVICE_RCP,DSH_DEVICE_RSH, # DSH_NODEGROUP_PATH # For support Env Variables tell them to use the command line flag ## if ($ENV{'DSH_LIST'}) # if file of nodes input { xCAT::MsgUtils->message( "I", "DSH_LIST is set but is not supported. It will be ignored.\n" ); } if ($ENV{'DSH_NODE_LIST'}) { xCAT::MsgUtils->message( "I", "DSH_NODE_LIST is set but is not supported. It will be ignored.\n" ); } if ($ENV{'WCOLL'}) { xCAT::MsgUtils->message("I", "WCOLL is set but is not supported. It will be ignored.\n"); } if ($ENV{'DSH_DEVICE_LIST'}) { xCAT::MsgUtils->message( "I", "DSH_DEVICE_LIST is set but is not supported. It will be ignored.\n" ); } if ($ENV{'DSH_DEVICE_OPTS'}) { xCAT::MsgUtils->message( "I", "DSH_DEVICE_OPTS is set but is not supported. It will be ignored.\n" ); } if ($ENV{'DSH_DEVICE_RCP'}) { xCAT::MsgUtils->message( "I", "DSH_DEVICE_RCP is set but is not supported. It will be ignored.\n" ); } if ($ENV{'DSH_DEVICE_RSH'}) { xCAT::MsgUtils->message( "I", "DSH_DEVICE_RSH is set but is not supported. It will be ignored.\n" ); } if ($ENV{'DSH_NODEGROUP_PATH'}) { xCAT::MsgUtils->message( "I", "DSH_NODEGROUP_PATH is set but is not supported. It will be ignored.\n" ); } if ($ENV{'RSYNC_RSH'}) { xCAT::MsgUtils->message("I", " RSYNC_RSH is set but is not supported. It will be ignored.\n"); } if ($ENV{'DSH_REPORT'}) { xCAT::MsgUtils->message("I", " DSH_REPORT is set but is not supported. It will be ignored.\n"); } }