diff --git a/xCAT-server/lib/xcat/plugins/zone.pm b/xCAT-server/lib/xcat/plugins/zone.pm index fcbb6809a..669003a59 100644 --- a/xCAT-server/lib/xcat/plugins/zone.pm +++ b/xCAT-server/lib/xcat/plugins/zone.pm @@ -95,13 +95,22 @@ sub process_request my $args = $request->{arg}; @ARGV = @{$args}; # get arguments - my %options = (); - $Getopt::Long::ignorecase = 0; + # Get the zonename if it is in the input + my @SaveARGV = @ARGV; + my $zonename = @SaveARGV[0]; # here is the zonename, if there is one + if ($zonename) { # take zonename off the argument list so it will parse correctly + my $tmp = shift(@SaveARGV); + @ARGV = @SaveARGV; + } + Getopt::Long::Configure("posix_default"); + Getopt::Long::Configure("no_gnu_compat"); Getopt::Long::Configure("bundling"); + my %options = (); if ( !GetOptions( - 'a|noderange=s' => \$options{'noderange'}, + 'a|noderange=s' => \$options{'addnoderange'}, + 'r|noderange=s' => \$options{'rmnoderange'}, 'defaultzone|defaultzone' => \$options{'defaultzone'}, 'g|assigngrp' => \$options{'assigngroup'}, 'f|force' => \$options{'force'}, @@ -132,14 +141,14 @@ sub process_request exit 0; } # test to see if the zonename was input - if (scalar(@ARGV) == 0) { + if (!$zonename) { my $rsp = {}; $rsp->{error}->[0] = - "zonename not specified, see man page for syntax."; + "zonename not specified, it is required for this command."; xCAT::MsgUtils->message("E", $rsp, $callback); exit 1; } else { - $request->{zonename} = $ARGV[0]; + $request->{zonename} = $zonename; } # if -s entered must be yes/1 or no/0 if ($options{'sshbetweennodes'}) { @@ -166,12 +175,40 @@ sub process_request $rsp->{info}->[0] = "The site table sshbetweennodes attribute is set to $entries[0]. It is not used when zones are defined. To get rid of this warning, remove the site table sshbetweennodes attribute."; xCAT::MsgUtils->message("I", $rsp, $callback); - } - # save input noderange - if ($options{'noderange'}) { + } + # -a and -r flags cannot be used together + if (($options{'addnoderange'}) && ($options{'rmnoderange'})) { + my $rsp = {}; + $rsp->{error}->[0] = + "You may not use the -a flag to add nodes and the -r flag to remove nodes on one command."; + xCAT::MsgUtils->message("E", $rsp, $callback); + exit 1; + + } + # save input noderange to add nodes + if ($options{'addnoderange'}) { # check to see if Management Node is in the noderange, if so error - $request->{noderange}->[0] = $options{'noderange'}; + $request->{noderange}->[0] = $options{'addnoderange'}; + my @nodes = xCAT::NodeRange::noderange($request->{noderange}->[0]); + my @mname = xCAT::Utils->noderangecontainsMn(@nodes); + if (@mname) + { # MN in the nodelist + my $nodes=join(',', @mname); + my $rsp = {}; + $rsp->{error}->[0] = + "You must not run $command and include the management node: $nodes."; + xCAT::MsgUtils->message("E", $rsp, $callback, 1); + exit 1; + } + + + } + # save input noderange to remove nodes + if ($options{'rmnoderange'}) { + + # check to see if Management Node is in the noderange, if so error + $request->{noderange}->[0] = $options{'rmnoderange'}; my @nodes = xCAT::NodeRange::noderange($request->{noderange}->[0]); my @mname = xCAT::Utils->noderangecontainsMn(@nodes); if (@mname) @@ -243,13 +280,21 @@ sub mkzone return 1; } # test for -g, if no noderange this is an error - if (( ! defined($$options{'noderange'})) && ($$options{'assigngroup'})) { + if (( ! defined($$options{'addnoderange'})) && ($$options{'assigngroup'})) { my $rsp = {}; $rsp->{error}->[0] = " The -g flag requires a noderange ( -a)."; xCAT::MsgUtils->message("E", $rsp, $callback); return 1; } + # test for -r, not valid + if ($$options{'rmnoderange'}) { + my $rsp = {}; + $rsp->{error}->[0] = + " The -r flag Is not valid for mkzone. Use chzone."; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } # check to see if the input zone already exists if (xCAT::Zone->iszonedefined($request->{zonename})) { my $rsp = {}; @@ -265,10 +310,13 @@ sub mkzone $keydir .= "/.ssh"; - # update the zone table - $rc=updatezonetable($request, $callback,$options,$keydir); + # add new zones to the zone table + $rc=addtozonetable($request, $callback,$options,$keydir); if ($rc == 0) { # zone table setup is ok - $rc=addnodestozone($request, $callback,$options,$keydir); + # test for a noderange, if(-a) not supplied nothing to do + if (defined($$options{'addnoderange'})) { + $rc=addnodestozone($request, $callback,$options,$keydir); + } if ($rc == 0) { # zone table setup is ok # generate root ssh keys $rc=gensshkeys($request, $callback,$options,$keydir); @@ -287,6 +335,10 @@ sub mkzone =head3 Parses and runs chzone + Input + request + callback + Input arguments from the GetOpts =cut @@ -295,14 +347,73 @@ sub mkzone sub chzone { my ($request, $callback,$options,$keydir) = @_; + my $rc=0; + # Create default path to generated ssh keys + # keydir comes in set to /etc/xcat/sshkeys + $keydir .= $request->{zonename}; + $keydir .= "/.ssh"; + my $zonename=$request->{zonename}; + # already checked but lets do it again, need a zonename + if (!($request->{zonename})) { + + my $rsp = {}; + $rsp->{error}->[0] = + "zonename not specified The zonename is required."; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + # see if they asked to do anything + if ((!($$options{'sshkeypath'})) && (!($$options{'gensshkeys'})) && + (!( $$options{'addnoderange'})) && (!( $$options{'rmnoderange'})) && + (!($$options{'assigngroup'} )) && (!($$options{'sshbetweennodes'}))) { + my $rsp = {}; + $rsp->{info}->[0] = + "chzone was run but nothing to do."; + xCAT::MsgUtils->message("I", $rsp, $callback); + return 0; + } + # get the zone ssh key directory. We don't have a good zone without it. + my $sshrootkeydir = xCAT::Zone->getzonekeydir($zonename); + if ($sshrootkeydir == 1) { # error return + #if we have been requested to regenerated the ssh keys continue + if (($$options{'sshkeypath'}) || ($$options{'gensshkeys'})) { + my $rsp = {}; + $rsp->{info}->[0] = + " sshkeydir attribute not defined for $zonename. The zone sshkeydir will be regenerated."; + xCAT::MsgUtils->message("I", $rsp, $callback); + } else { # sshkeydir is missing and they did not request to regenerate, that is an error + my $rsp = {}; + $rsp->{error}->[0] = + " sshkeydir attribute not defined for $zonename. The zone sshkeydir must be regenerated. Rerun this command with -k or -K options"; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + } else { # we got a sshkeydir from the database, use it + $keydir=$sshrootkeydir; + } + # do we regenerate keys (-k or -K) + if (($$options{'sshkeypath'}) || ($$options{'gensshkeys'})) { + $rc=gensshkeys($request, $callback,$options,$keydir); + if ($rc != 0) { + return 1; + } + } + + # update the zone table + $rc=updatezonetable($request, $callback,$options,$keydir); + if ($rc == 0) { # zone table setup is ok + # update the nodelist table + if (defined($$options{'addnoderange'})) { + $rc=addnodestozone($request, $callback,$options,$keydir); + } else { # note -a and -r are not allowed on one chzone + if (defined($$options{'rmnoderange'})) { + $rc=rmnodesfromzone($request, $callback,$options,$keydir); + } + } + } - # my $rsp = {}; - - #xCAT::MsgUtils->message("I", $rsp, $callback); - - return 0; - + return $rc; } #------------------------------------------------------- @@ -411,7 +522,7 @@ sub rmzone $tab->delEntries({zonename=>$zonename}); # remove zonename and possibly group name (-g flag) from any nodes defined in this zone - my $rc=rmnodesfromzone($request, $callback,$options); + my $rc=rmnodesfromzone($request, $callback,$options,"ALL"); return $rc; @@ -518,7 +629,7 @@ sub gensshkeys #------------------------------------------------------- =head3 - updatezonetable + addtozonetable Add the new zone to the zone table, check if already there and error - use either chzone or -f to override default @@ -527,7 +638,7 @@ sub gensshkeys =cut #------------------------------------------------------- -sub updatezonetable +sub addtozonetable { my ($request, $callback,$options,$keydir) = @_; my $rc=0; @@ -601,6 +712,73 @@ sub updatezonetable } #------------------------------------------------------- +=head3 + updatezonetable + change the zones in the zone table + + + +=cut + +#------------------------------------------------------- +sub updatezonetable +{ + my ($request, $callback,$options,$keydir) = @_; + my $rc=0; + my $zoneentry; + my $tab = xCAT::Table->new("zone"); + if($tab) { + + # now add the users changes + my %tb_cols; + # generated keys ( -k or -K) + if (($$options{'sshkeypath'}) || ($$options{'gensshkeys'})) { + $tb_cols{sshkeydir} = $keydir; # key directory + } + # set sshbetweennodes attribute from -s flag + if ( $$options{'sshbetweennodes'}) { + $tb_cols{sshbetweennodes} = $$options{'sshbetweennodes'}; + } + my $zonename=$request->{zonename}; + # if --defaultzone + if ( $$options{'defaultzone'}) { # set the default + # check to see if a default already defined + my $curdefaultzone = xCAT::Zone->getdefaultzone($callback); + if (!(defined ($curdefaultzone))) { # no default defined + $tb_cols{defaultzone} ="yes"; + } else { # already a default + if ($$options{'force'}) { # force the default + $tb_cols{defaultzone} ="yes"; + $tab->setAttribs({zonename => $zonename}, \%tb_cols); + # now change the old default zone to not be the default + my %tb1_cols; + $tb1_cols{defaultzone} ="no"; + $tab->setAttribs({zonename => $curdefaultzone}, \%tb1_cols); + $tab->commit(); + $tab->close(); + } else { # no force this is an error + my $rsp = {}; + $rsp->{error}->[0] = + " Failure setting default zone. The defaultzone $curdefaultzone already exists. Use the -f flag if you want to override the current default zone."; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + } + } + } else { + my $rsp = {}; + $rsp->{error}->[0] = + " Failure opening the zone table."; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + + return $rc; + +} +#------------------------------------------------------- + =head3 addnodestozone Add the new zonename attribute to any nodes in the noderange ( if a noderange specified) @@ -615,15 +793,17 @@ sub addnodestozone { my ($request, $callback,$options,$keydir) = @_; my $rc=0; - # test for a noderange, if not supplied nothing to do - if ( ! defined($$options{'noderange'})) { - return 0; - } my $zonename=$request->{zonename}; - # there is a node range. update the nodelist table # if -g add zonename group also - my $group=$$options{'noderange'}; my @nodes = xCAT::NodeRange::noderange($request->{noderange}->[0]); + # check to see if noderange expanded + if (!(scalar @nodes)) { + my $rsp = {}; + $rsp->{error}->[0] = + " The noderange $request->{noderange}->[0] is not valid. The nodes are not defined."; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } my $tab = xCAT::Table->new("nodelist"); if ($tab) { @@ -651,9 +831,11 @@ sub addnodestozone =head3 rmnodesfromzone - removes the zonename from all nodes with their zonename the input zone + removes the zonename from all nodes with their zonename the input zone or + the noderange supplied on the -r flag if -g, removes zonename group from all nodes defined with their zonename the input zone. - + Note if $ALL is input it removes all nodes from the zone, + otherwise $request->{noderange} points to the noderange =cut @@ -661,13 +843,26 @@ sub addnodestozone #------------------------------------------------------- sub rmnodesfromzone { - my ($request, $callback,$options) = @_; + my ($request, $callback,$options,$ALL) = @_; my $zonename=$request->{zonename}; my $tab = xCAT::Table->new("nodelist"); if ($tab) { # read all the nodes with zonename - my @nodes = xCAT::Zone->getnodesinzone($callback,$zonename); + my @nodes; + if ($ALL) { # do all nodes + @nodes = xCAT::Zone->getnodesinzone($callback,$zonename); + } else { # the nodes in the noderange ( -r ) + @nodes = xCAT::NodeRange::noderange($request->{noderange}->[0]); + # check to see if noderange expanded + if (!(scalar @nodes)) { + my $rsp = {}; + $rsp->{error}->[0] = + " The noderange $request->{noderange}->[0] is not valid. The nodes are not defined."; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + } # if -g then remove the zonename group attribute on each node if ($$options{'assigngroup'}){ foreach my $node (@nodes) {