From d2bb5a7290e7939eaec36ac46c069861d538a5ef Mon Sep 17 00:00:00 2001 From: bybai Date: Tue, 3 Apr 2018 05:33:47 -0400 Subject: [PATCH 01/10] add xCAT REST API for nodels --- xCAT-server/xCAT-wsapi/xcatws.cgi | 66 +++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/xCAT-server/xCAT-wsapi/xcatws.cgi b/xCAT-server/xCAT-wsapi/xcatws.cgi index 5fbea07ca..2dad37a46 100755 --- a/xCAT-server/xCAT-wsapi/xcatws.cgi +++ b/xCAT-server/xCAT-wsapi/xcatws.cgi @@ -138,6 +138,18 @@ my %URIdef = ( outhdler => \&actionout, }, }, + nodels => { + desc => "[URI:/nodes/{noderange}/nodels}] - Lists the nodes", + matcher => '^/nodes/[^/]*/nodels$', + GET => { + desc => "Lists the nodes.", + usage => "||An object which includes multiple entries like: : nodels|", + example => "|Get the running status for node node1|GET|/nodes/node1/nodels|", + cmd => "nodels", + fhandler => \&actionhdl, + outhdler => \&nodelsout, + }, + }, nodehost => { desc => "[URI:/nodes/{noderange}/host] - The mapping of ip and hostname for the node {noderange}", matcher => '^/nodes/[^/]*/host$', @@ -1755,6 +1767,56 @@ sub defout_remove_appended_info { } } +#handle output of nodels command +#input data like: +#$VAR1 = [ +# { +# 'xcatdsource' => [ +# 'bybc0602' +# ], +# 'node' => [ +# { +# 'name' => [ +# 'node1' +# ] +# }, +# { +# 'name' => [ +# 'node2' +# ] +# }, +# { +# 'name' => [ +# 'node3' +# ] +# } +# ] +# } +# ]; + +#TO: +#------------ +# [ +# 'node1', +# 'node2', +# 'node3' +# ]; +sub nodelsout { + my $data = shift; + my $json; + foreach my $d (@$data) { + my $jsonnode; + my $lines = $d->{node}; + foreach my $l (@$lines) { + + push(@{$json}, $l->{name}[0]); + + } + } + if ($json) { + addPageContent($JSON->encode($json), 1); + } +} sub localresout { my $data = shift; @@ -2060,6 +2122,10 @@ sub actionhdl { } else { error("Missed Action.", $STATUS_NOT_FOUND); } + } elsif ($params->{'resourcename'} eq "nodels") { + if (isGET()) { + + } } elsif ($params->{'resourcename'} =~ /(energy|energyattr)/) { if (isGET()) { if ($params->{'resourcename'} eq "energy") { From 94cd47a0018c614eb72a3b6d7bdd5173d823a805 Mon Sep 17 00:00:00 2001 From: XuWei Date: Mon, 9 Apr 2018 22:30:03 -0400 Subject: [PATCH 02/10] support rinv/rvitals run with Verbose option only --- xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py b/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py index c7cf2a85c..af445c481 100644 --- a/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py +++ b/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py @@ -217,8 +217,8 @@ class OpenBMCManager(base.BaseManager): def rinv(self, nodesinfo, args): # 1, parse agrs - if not args: - args = ['all'] + if not args or (len(args) == 1 and args[0] in ['-V', '--verbose']): + args.append('all') rinv_usage = """ Usage: @@ -385,8 +385,8 @@ class OpenBMCManager(base.BaseManager): def rvitals(self, nodesinfo, args): # 1, parse agrs - if not args: - args = ['all'] + if not args or (len(args) == 1 and args[0] in ['-V', '--verbose']): + args.append('all') rvitals_usage = """ Usage: From e8eb7d55f9a60485a6a8c8bc3ac87d9c852c7497 Mon Sep 17 00:00:00 2001 From: bybai Date: Mon, 9 Apr 2018 23:10:59 -0400 Subject: [PATCH 03/10] add nodels doc --- .../restapi_resource/restapi_reference.rst | 235 ++++++++++-------- 1 file changed, 132 insertions(+), 103 deletions(-) diff --git a/docs/source/advanced/restapi/restapi_resource/restapi_reference.rst b/docs/source/advanced/restapi/restapi_resource/restapi_reference.rst index d2cf1f937..d8b74d00d 100644 --- a/docs/source/advanced/restapi/restapi_resource/restapi_reference.rst +++ b/docs/source/advanced/restapi/restapi_resource/restapi_reference.rst @@ -15,10 +15,10 @@ POST - Create a token. **Example:** -Acquire a token for user 'root'. :: +Aquire a token for user 'root'. :: - #curl -X POST -k 'https://127.0.0.1/xcatws/tokens?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"userName":"root","userPW":"cluster"}' + curl -X POST -k 'https://127.0.0.1/xcatws/tokens?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"userName":"root","userPW":"cluster"}' { "token":{ "id":"a6e89b59-2b23-429a-b3fe-d16807dd19eb", @@ -52,7 +52,7 @@ Refer to the man page: :doc:`lsdef ` + +**Returns:** + +* Json format: An array of node names. + +**Example:** + +Get the node names from xCAT database. :: + + + curl -X GET -k 'https://127.0.0.1/xcatws/nodes/node[1-3]/nodels?userName=root&userPW=cluster&pretty=1' + [ + "node1", + "node2", + "node3", + ] + [URI:/nodes/{noderange}/subnodes] - The sub-nodes resources for the node {noderange} ------------------------------------------------------------------------------------ @@ -301,7 +322,7 @@ Refer to the man page: :doc:`rscan ` Get all the inventory attributes for node1. :: - #curl -X GET -k 'https://127.0.0.1/xcatws/nodes/node1/inventory?userName=root&userPW=cluster&pretty=1' + curl -X GET -k 'https://127.0.0.1/xcatws/nodes/node1/inventory?userName=root&userPW=cluster&pretty=1' { "node1":{ "DIMM 21 ":"8GB PC3-12800 (1600 MT/s) ECC RDIMM", @@ -673,7 +694,7 @@ Refer to the man page: :doc:`rinv ` Get the 'model' inventory attribute for node1. :: - #curl -X GET -k 'https://127.0.0.1/xcatws/nodes/node1/inventory/model?userName=root&userPW=cluster&pretty=1' + curl -X GET -k 'https://127.0.0.1/xcatws/nodes/node1/inventory/model?userName=root&userPW=cluster&pretty=1' { "node1":{ "System Description":"System x3650 M4", @@ -698,7 +719,7 @@ Refer to the man page: :doc:`reventlog ` Run the 'date' command on the node2. :: - #curl -X POST -k 'https://127.0.0.1/xcatws/nodes/node2/nodeshell?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"command":["date","ls"]}' + curl -X POST -k 'https://127.0.0.1/xcatws/nodes/node2/nodeshell?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"command":["date","ls"]}' { "node2":[ " Wed Apr 3 08:30:26 CST 2013", @@ -925,7 +946,7 @@ Refer to the man page: :doc:`xdcp ` Copy files /tmp/f1 and /tmp/f2 from xCAT MN to the node2:/tmp. :: - #curl -X POST -k 'https://127.0.0.1/xcatws/nodes/node2/nodecopy?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"src":["/tmp/f1","/tmp/f2"],"target":"/tmp"}' + curl -X POST -k 'https://127.0.0.1/xcatws/nodes/node2/nodecopy?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"src":["/tmp/f1","/tmp/f2"],"target":"/tmp"}' no output for succeeded copy. [URI:/nodes/{noderange}/vm] - The virtualization node {noderange}. @@ -953,20 +974,20 @@ Refer to the man page: :doc:`chvm ` Set memory to 3000MB. :: - #curl -X PUT -k 'https://127.0.0.1/xcatws/nodes/node1/vm?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"memorysize":"3000"}' + curl -X PUT -k 'https://127.0.0.1/xcatws/nodes/node1/vm?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"memorysize":"3000"}' **Example2:** Add a new 20G disk. :: - #curl -X PUT -k 'https://127.0.0.1/xcatws/nodes/node1/vm?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"adddisk":"20G"}' + curl -X PUT -k 'https://127.0.0.1/xcatws/nodes/node1/vm?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"adddisk":"20G"}' **Example3:** Purge the disk 'hdb'. :: - #curl -X PUT -k 'https://127.0.0.1/xcatws/nodes/node1/vm?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"purgedisk":"hdb"}' + curl -X PUT -k 'https://127.0.0.1/xcatws/nodes/node1/vm?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"purgedisk":"hdb"}' POST - Create the vm node {noderange}. `````````````````````````````````````` @@ -988,8 +1009,8 @@ Refer to the man page: :doc:`mkvm ` Create the vm node1 with a 30G disk, 2048M memory and 2 cpus. :: - #curl -X POST -k 'https://127.0.0.1/xcatws/nodes/node1/vm?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"disksize":"30G","memorysize":"2048","cpucount":"2"}' + curl -X POST -k 'https://127.0.0.1/xcatws/nodes/node1/vm?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"disksize":"30G","memorysize":"2048","cpucount":"2"}' DELETE - Remove the vm node {noderange}. ```````````````````````````````````````` @@ -1009,8 +1030,8 @@ Refer to the man page: :doc:`rmvm ` Remove the vm node1 by force and purge the disk. :: - #curl -X DELETE -k 'https://127.0.0.1/xcatws/nodes/node1/vm?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"force":"yes","purge":"yes"}' + curl -X DELETE -k 'https://127.0.0.1/xcatws/nodes/node1/vm?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"force":"yes","purge":"yes"}' [URI:/nodes/{noderange}/vmclone] - The clone resource for the virtual node {noderange}. --------------------------------------------------------------------------------------- @@ -1038,7 +1059,7 @@ Refer to the man page: :doc:`clonevm ` Generates a stateless image based on the specified osimage :: - #curl -X POST -k 'https://127.0.0.1/xcatws/osimages/sles11.2-x86_64-install-compute/instance?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"action":"gen"}' + curl -X POST -k 'https://127.0.0.1/xcatws/osimages/sles11.2-x86_64-install-compute/instance?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"action":"gen"}' **Example2:** Packs the stateless image from the chroot file system based on the specified osimage :: - #curl -X POST -k 'https://127.0.0.1/xcatws/osimages/sles11.2-x86_64-install-compute/instance?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"action":"pack"}' + curl -X POST -k 'https://127.0.0.1/xcatws/osimages/sles11.2-x86_64-install-compute/instance?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"action":"pack"}' **Example3:** Exports an xCAT image based on the specified osimage :: - #curl -X POST -k 'https://127.0.0.1/xcatws/osimages/sles11.2-x86_64-install-compute/instance?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"action":"export"}' + curl -X POST -k 'https://127.0.0.1/xcatws/osimages/sles11.2-x86_64-install-compute/instance?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"action":"export"}' DELETE - Delete the stateless or statelite image instance for the osimage {imgname} from the file system ```````````````````````````````````````````````````````````````````````````````````````````````````````` @@ -1290,8 +1312,8 @@ Refer to the man page: :doc:`rmimage ", @@ -1391,8 +1414,8 @@ Refer to the man page: :doc:`chdef Date: Mon, 9 Apr 2018 23:11:25 -0400 Subject: [PATCH 04/10] add nodels resource --- xCAT-server/xCAT-wsapi/genrestapidoc.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xCAT-server/xCAT-wsapi/genrestapidoc.pm b/xCAT-server/xCAT-wsapi/genrestapidoc.pm index 280cff9ca..eb01e9019 100755 --- a/xCAT-server/xCAT-wsapi/genrestapidoc.pm +++ b/xCAT-server/xCAT-wsapi/genrestapidoc.pm @@ -13,7 +13,7 @@ my @apigroups = ( groupname => 'nodes', header => "Node Resources", desc => "The URI list which can be used to create, query, change and manage node objects.", - resources => [ 'allnode', 'nodeallattr', 'nodeattr', 'nodehost', 'nodedns', 'nodedhcp', 'nodestat', 'subnodes', + resources => [ 'allnode', 'nodeallattr', 'nodeattr', 'nodehost', 'nodedns', 'nodedhcp', 'nodestat', 'nodels', 'subnodes', 'power', 'energy', 'energyattr', 'serviceprocessor', 'nextboot', 'bootstate', 'vitals', 'vitalsattr', 'inventory', 'inventoryattr', 'eventlog', 'beacon', 'updating', 'filesyncing', 'software_maintenance', 'postscript', 'nodeshell', 'nodecopy', @@ -181,9 +181,9 @@ sub make_rst_format { my ($uri, $data); if ($parts[3] =~ /\s+/) { ($uri, $data) = split(/ /, $parts[3]); - print "\n #curl -X $parts[2] -k \'https://127.0.0.1/xcatws$uri$postfix\' -H Content-Type:application/json --data \'$data\'\n"; + print "\n curl -X $parts[2] -k \'https://127.0.0.1/xcatws$uri$postfix\' -H Content-Type:application/json --data \'$data\'\n"; } else { - print "\n #curl -X $parts[2] -k \'https://127.0.0.1/xcatws$parts[3]$postfix\'\n"; + print "\n curl -X $parts[2] -k \'https://127.0.0.1/xcatws$parts[3]$postfix\'\n"; } if ($parts[4]) { From 9c7d9847ffd9efbc9e21cd95e507642c51d6eb25 Mon Sep 17 00:00:00 2001 From: bybai Date: Mon, 9 Apr 2018 23:13:01 -0400 Subject: [PATCH 05/10] clean up word typo --- xCAT-server/xCAT-wsapi/xcatws.cgi | 64 +++++++++++++++---------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/xCAT-server/xCAT-wsapi/xcatws.cgi b/xCAT-server/xCAT-wsapi/xcatws.cgi index 2dad37a46..099a905bd 100755 --- a/xCAT-server/xCAT-wsapi/xcatws.cgi +++ b/xCAT-server/xCAT-wsapi/xcatws.cgi @@ -42,7 +42,7 @@ use IO::Socket::SSL; my %usagemsg = ( objreturn => "Json format: An object which includes multiple \' : {att:value, attr:value ...}\' pairs.", objchparam => "Json format: An object which includes multiple \'att:value\' pairs.", - non_getreturn => "No output when execution is successfull. Otherwise output the error information in the Standard Error Format: {error:[msg1,msg2...],errocode:errornum}." + non_getreturn => "No output when execution is successful. Otherwise output the error information in the Standard Error Format: {error:[msg1,msg2...],errocode:errornum}." ); # ver(1.0): Use array type instread of string split by '|' or ',' @@ -72,16 +72,16 @@ my %URIdef = ( desc => "[URI:/nodes/{noderange}] - The node resource", matcher => '^/nodes/[^/]*$', GET => { - desc => "Get all the attibutes for the node {noderange}.", + desc => "Get all the attributes for the node {noderange}.", desc1 => "The keyword ALLRESOURCES can be used as {noderange} which means to get node attributes for all the nodes.", usage => "||$usagemsg{objreturn}|", - example => "|Get all the attibutes for node \'node1\'.|GET|/nodes/node1|{\n \"node1\":{\n \"profile\":\"compute\",\n \"netboot\":\"xnba\",\n \"arch\":\"x86_64\",\n \"mgt\":\"ipmi\",\n \"groups\":\"all\",\n ...\n }\n}|", + example => "|Get all the attributes for node \'node1\'.|GET|/nodes/node1|{\n \"node1\":{\n \"profile\":\"compute\",\n \"netboot\":\"xnba\",\n \"arch\":\"x86_64\",\n \"mgt\":\"ipmi\",\n \"groups\":\"all\",\n ...\n }\n}|", cmd => "lsdef", fhandler => \&defhdl, outhdler => \&defout, }, PUT => { - desc => "Change the attibutes for the node {noderange}.", + desc => "Change the attributes for the node {noderange}.", usage => "|$usagemsg{objchparam} DataBody: {attr1:v1,att2:v2,...}.|$usagemsg{non_getreturn}|", example => "|Change the attributes mgt=dfm and netboot=yaboot.|PUT|/nodes/node1 {\"mgt\":\"dfm\",\"netboot\":\"yaboot\"}||", cmd => "chdef", @@ -139,12 +139,12 @@ my %URIdef = ( }, }, nodels => { - desc => "[URI:/nodes/{noderange}/nodels}] - Lists the nodes", + desc => "[URI:/nodes/{noderange}/nodels}] - Lists the nodes, noderange cannot start with /", matcher => '^/nodes/[^/]*/nodels$', GET => { desc => "Lists the nodes.", - usage => "||An object which includes multiple entries like: : nodels|", - example => "|Get the running status for node node1|GET|/nodes/node1/nodels|", + usage => "||Json format: An array of node names.|", + example => "|Get the node names from xCAT database.|GET|/nodes/node[1-3]/nodels|[\n \"node1\",\n \"node2\",\n \"node3\",\n]|", cmd => "nodels", fhandler => \&actionhdl, outhdler => \&nodelsout, @@ -363,7 +363,7 @@ my %URIdef = ( desc => "[URI:/nodes/{noderange}/vitals] - The vitals resources for the node {noderange}", matcher => '^/nodes/[^/]*/vitals$', GET => { - desc => "Get all the vitals attibutes.", + desc => "Get all the vitals attributes.", usage => "||$usagemsg{objreturn}|", example => "|Get all the vitails attributes for the node1.|GET|/nodes/node1/vitals|{\n \"node1\":{\n \"SysBrd Fault\":\"0\",\n \"CPUs\":\"0\",\n \"Fan 4A Tach\":\"3330 RPM\",\n \"Drive 15\":\"0\",\n \"SysBrd Vol Fault\":\"0\",\n \"nvDIMM Flash\":\"0\",\n \"Progress\":\"0\"\n ...\n }\n}|", cmd => "rvitals", @@ -376,7 +376,7 @@ my %URIdef = ( desc => "[URI:/nodes/{noderange}/vitals/{temp|voltage|wattage|fanspeed|power|leds...}] - The specific vital attributes for the node {noderange}", matcher => '^/nodes/[^/]*/vitals/\S+$', GET => { - desc => "Get the specific vitals attibutes.", + desc => "Get the specific vitals attributes.", usage => "||$usagemsg{objreturn}|", example => "|Get the \'fanspeed\' vitals attribute.|GET|/nodes/node1/vitals/fanspeed|{\n \"node1\":{\n \"Fan 1A Tach\":\"3219 RPM\",\n \"Fan 4B Tach\":\"2688 RPM\",\n \"Fan 3B Tach\":\"2560 RPM\",\n \"Fan 4A Tach\":\"3330 RPM\",\n \"Fan 2A Tach\":\"3293 RPM\",\n \"Fan 1B Tach\":\"2592 RPM\",\n \"Fan 3A Tach\":\"3182 RPM\",\n \"Fan 2B Tach\":\"2592 RPM\"\n }\n}|", cmd => "rvitals", @@ -388,7 +388,7 @@ my %URIdef = ( desc => "[URI:/nodes/{noderange}/inventory] - The inventory attributes for the node {noderange}", matcher => '^/nodes/[^/]*/inventory$', GET => { - desc => "Get all the inventory attibutes.", + desc => "Get all the inventory attributes.", usage => "||$usagemsg{objreturn}|", example => "|Get all the inventory attributes for node1.|GET|/nodes/node1/inventory|{\n \"node1\":{\n \"DIMM 21 \":\"8GB PC3-12800 (1600 MT/s) ECC RDIMM\",\n \"DIMM 1 Manufacturer\":\"Hyundai Electronics\",\n \"Power Supply 2 Board FRU Number\":\"94Y8105\",\n \"DIMM 9 Model\":\"HMT31GR7EFR4C-PB\",\n \"DIMM 8 Manufacture Location\":\"01\",\n \"DIMM 13 Manufacturer\":\"Hyundai Electronics\",\n \"DASD Backplane 4\":\"Not Present\",\n ...\n }\n}|", cmd => "rinv", @@ -400,7 +400,7 @@ my %URIdef = ( desc => "[URI:/nodes/{noderange}/inventory/{pci|model...}] - The specific inventory attributes for the node {noderange}", matcher => '^/nodes/[^/]*/inventory/\S+$', GET => { - desc => "Get the specific inventory attibutes.", + desc => "Get the specific inventory attributes.", usage => "||$usagemsg{objreturn}|", example => "|Get the \'model\' inventory attribute for node1.|GET|/nodes/node1/inventory/model|{\n \"node1\":{\n \"System Description\":\"System x3650 M4\",\n \"System Model/MTM\":\"7915C2A\"\n }\n}|", cmd => "rinv", @@ -644,15 +644,15 @@ my %URIdef = ( desc => "[URI:/groups/{groupname}] - The group resource", matcher => '^/groups/[^/]*$', GET => { - desc => "Get all the attibutes for the group {groupname}.", + desc => "Get all the attributes for the group {groupname}.", usage => "||$usagemsg{objreturn}|", - example => "|Get all the attibutes for group \'all\'.|GET|/groups/all|{\n \"all\":{\n \"members\":\"zxnode2,nodexxx,node1,node4\"\n }\n}|", + example => "|Get all the attributes for group \'all\'.|GET|/groups/all|{\n \"all\":{\n \"members\":\"zxnode2,nodexxx,node1,node4\"\n }\n}|", cmd => "lsdef", fhandler => \&defhdl, outhdler => \&defout, }, PUT => { - desc => "Change the attibutes for the group {groupname}.", + desc => "Change the attributes for the group {groupname}.", usage => "|$usagemsg{objchparam} DataBody: {attr1:v1,att2:v2,...}.|$usagemsg{non_getreturn}|", example => "|Change the attributes mgt=dfm and netboot=yaboot.|PUT|/groups/all {\"mgt\":\"dfm\",\"netboot\":\"yaboot\"}||", cmd => "chdef", @@ -842,16 +842,16 @@ my %URIdef = ( desc => "[URI:/networks/{netname}] - The network resource", matcher => '^\/networks\/[^\/]*$', GET => { - desc => "Get all the attibutes for the network {netname}.", + desc => "Get all the attributes for the network {netname}.", desc1 => "The keyword ALLRESOURCES can be used as {netname} which means to get network attributes for all the networks.", usage => "||$usagemsg{objreturn}|", - example => "|Get all the attibutes for network \'network1\'.|GET|/networks/network1|{\n \"network1\":{\n \"gateway\":\"\",\n \"mask\":\"255.255.255.0\",\n \"mgtifname\":\"eth2\",\n \"net\":\"10.0.0.0\",\n \"tftpserver\":\"10.0.0.119\",\n ...\n }\n}|", + example => "|Get all the attributes for network \'network1\'.|GET|/networks/network1|{\n \"network1\":{\n \"gateway\":\"\",\n \"mask\":\"255.255.255.0\",\n \"mgtifname\":\"eth2\",\n \"net\":\"10.0.0.0\",\n \"tftpserver\":\"10.0.0.119\",\n ...\n }\n}|", cmd => "lsdef", fhandler => \&defhdl, outhdler => \&defout, }, PUT => { - desc => "Change the attibutes for the network {netname}.", + desc => "Change the attributes for the network {netname}.", usage => "|$usagemsg{objchparam} DataBody: {attr1:v1,att2:v2,...}.|$usagemsg{non_getreturn}|", example => "|Change the attributes mgtifname=eth0 and net=10.1.0.0.|PUT|/networks/network1 {\"mgtifname\":\"eth0\",\"net\":\"10.1.0.0\"}||", cmd => "chdef", @@ -931,7 +931,7 @@ my %URIdef = ( desc => "[URI:/osimages/{imgname}] - The osimage resource", matcher => '^\/osimages\/[^\/]*$', GET => { - desc => "Get all the attibutes for the osimage {imgname}.", + desc => "Get all the attributes for the osimage {imgname}.", desc1 => "The keyword ALLRESOURCES can be used as {imgname} which means to get image attributes for all the osimages.", usage => "||$usagemsg{objreturn}|", example => "|Get the attributes for the specified osimage.|GET|/osimages/sles11.2-x86_64-install-compute|{\n \"sles11.2-x86_64-install-compute\":{\n \"provmethod\":\"install\",\n \"profile\":\"compute\",\n \"template\":\"/opt/xcat/share/xcat/install/sles/compute.sles11.tmpl\",\n \"pkglist\":\"/opt/xcat/share/xcat/install/sles/compute.sles11.pkglist\",\n \"osvers\":\"sles11.2\",\n \"osarch\":\"x86_64\",\n \"osname\":\"Linux\",\n \"imagetype\":\"linux\",\n \"otherpkgdir\":\"/install/post/otherpkgs/sles11.2/x86_64\",\n \"osdistroname\":\"sles11.2-x86_64\",\n \"pkgdir\":\"/install/sles11.2/x86_64\"\n }\n}|", @@ -949,7 +949,7 @@ my %URIdef = ( outhdler => \&noout, }, PUT => { - desc => "Change the attibutes for the osimage {imgname}.", + desc => "Change the attributes for the osimage {imgname}.", usage => "|$usagemsg{objchparam} DataBody: {attr1:v1,attr2:v2...}|$usagemsg{non_getreturn}|", example => "|Change the 'osvers' and 'osarch' attributes for the osiamge.|PUT|/osimages/sles11.2-ppc64-install-compute/ {\"osvers\":\"sles11.3\",\"osarch\":\"x86_64\"}||", cmd => "chdef", @@ -980,7 +980,7 @@ my %URIdef = ( # TD, the implementation may need to be change. PUT_backup => { - desc => "Change the attibutes for the osimage {imgname}.", + desc => "Change the attributes for the osimage {imgname}.", usage => "|$usagemsg{objchparam} DataBody: {attr1:v1,attr2:v2...}|$usagemsg{non_getreturn}|", example => "|Change the 'osvers' and 'osarch' attributes for the osiamge.|PUT|/osimages/sles11.2-ppc64-install-compute/attrs/osvers;osarch {\"osvers\":\"sles11.3\",\"osarch\":\"x86_64\"}||", cmd => "chdef", @@ -1032,7 +1032,7 @@ my %URIdef = ( desc => "[URI:/policy/{policy_priority}] - The policy resource", matcher => '^\/policy\/[^\/]*$', GET => { - desc => "Get all the attibutes for a policy {policy_priority}.", + desc => "Get all the attributes for a policy {policy_priority}.", desc1 => "It will display all the policy attributes for one policy resource.", desc2 => "The keyword ALLRESOURCES can be used as {policy_priority} which means to get policy attributes for all the policies.", usage => "||$usagemsg{objreturn}|", @@ -1042,7 +1042,7 @@ my %URIdef = ( outhdler => \&defout, }, PUT => { - desc => "Change the attibutes for the policy {policy_priority}.", + desc => "Change the attributes for the policy {policy_priority}.", desc1 => "It will change one or more attributes for a policy.", usage => "|$usagemsg{objchparam} DataBody: {attr1:v1,att2:v2,...}.|$usagemsg{non_getreturn}|", example => "|Set the name attribute for policy 3.|PUT|/policy/3 {\"name\":\"root\"}||", @@ -1156,7 +1156,7 @@ my %URIdef = ( desc1 => "For a large number of nodes, this API call can be faster than using the corresponding nodes resource. The disadvantage is that you need to know the table names the attributes are stored in.", matcher => '^/tables/[^/]+/nodes/[^/]+$', GET => { - desc => "Get attibutes of tables for a noderange.", + desc => "Get attributes of tables for a noderange.", usage => "||An object containing each table. Within each table object is an array of node objects containing the attributes.|", example1 => qq(|Get all the columns from table nodetype for node1 and node2.|GET|/tables/nodetype/nodes/node1,node2|{\n \"nodetype\":[\n {\n \"provmethod\":\"rhels6.4-x86_64-install-compute\",\n \"profile\":\"compute\",\n \"arch\":\"x86_64\",\n \"name\":\"node1\",\n \"os\":\"rhels6.4\"\n },\n {\n \"provmethod\":\"rhels6.3-x86_64-install-compute\",\n \"profile\":\"compute\",\n \"arch\":\"x86_64\",\n \"name\":\"node2\",\n \"os\":\"rhels6.3\"\n }\n ]\n}|), example2 => qq(|Get all the columns from tables nodetype and noderes for node1 and node2.|GET|/tables/nodetype,noderes/nodes/node1,node2|{\n \"noderes\":[\n {\n \"installnic\":\"mac\",\n \"netboot\":\"xnba\",\n \"name\":\"node1\",\n \"nfsserver\":\"192.168.1.15\"\n },\n {\n \"installnic\":\"mac\",\n \"netboot\":\"pxe\",\n \"name\":\"node2\",\n \"proxydhcp\":\"no\"\n }\n ],\n \"nodetype\":[\n {\n \"provmethod\":\"rhels6.4-x86_64-install-compute\",\n \"profile\":\"compute\",\n \"arch\":\"x86_64\",\n \"name\":\"node1\",\n \"os\":\"rhels6.4\"\n },\n {\n \"provmethod\":\"rhels6.3-x86_64-install-compute\",\n \"profile\":\"compute\",\n \"arch\":\"x86_64\",\n \"name\":\"node2\",\n \"os\":\"rhels6.3\"\n }\n ]\n}|), @@ -1164,7 +1164,7 @@ my %URIdef = ( outhdler => \&tableout, }, PUT => { - desc => "Change the node table attibutes for {noderange}.", + desc => "Change the node table attributes for {noderange}.", usage => "|A hash of table names and attribute objects. DataBody: {table1:{attr1:v1,att2:v2,...}}.|$usagemsg{non_getreturn}|", example => '|Change the nodetype.arch and noderes.netboot attributes for nodes node1,node2.|PUT|/tables/nodetype,noderes/nodes/node1,node2 {"nodetype":{"arch":"x86_64"},"noderes":{"netboot":"xnba"}}||', fhandler => \&tablenodeputhdl, @@ -1176,14 +1176,14 @@ my %URIdef = ( desc1 => "For a large number of nodes, this API call can be faster than using the corresponding nodes resource. The disadvantage is that you need to know the table names the attributes are stored in.", matcher => '^/tables/[^/]+/nodes/[^/]+/[^/]+$', GET => { - desc => "Get table attibutes for a noderange.", + desc => "Get table attributes for a noderange.", usage => "||An object containing each table. Within each table object is an array of node objects containing the attributes.|", example => qq(|Get OS and ARCH attributes from nodetype table for node1 and node2.|GET|/tables/nodetype/nodes/node1,node2/os,arch|{\n \"nodetype\":[\n {\n \"arch\":\"x86_64\",\n \"name\":\"node1\",\n \"os\":\"rhels6.4\"\n },\n {\n \"arch\":\"x86_64\",\n \"name\":\"node2\",\n \"os\":\"rhels6.3\"\n }\n ]\n}|), fhandler => \&tablenodehdl, outhdler => \&tableout, }, PUT_backup => { - desc => "[URI:/tables/nodes/{noderange}] - Change the node table attibutes for the {noderange}.", + desc => "[URI:/tables/nodes/{noderange}] - Change the node table attributes for the {noderange}.", usage => "|A hash of table names and attribute objects. DataBody: {table1:{attr1:v1,att2:v2,...}}.|$usagemsg{non_getreturn}|", example => '|Change the nodehm.mgmt and noderes.netboot attributes for nodes node1-node5.|PUT|/tables/nodes/node1-node5 {"nodehm":{"mgmt":"ipmi"},"noderes":{"netboot":"xnba"}}||', fhandler => \&tablenodeputhdl, @@ -1208,14 +1208,14 @@ my %URIdef = ( desc2 => "{keys} should be the name=value pairs which are used to search table. e.g. {keys} should be [net=192.168.1.0,mask=255.255.255.0] for networks table query since the net and mask are the keys of networks table.", matcher => '^/tables/[^/]+/rows/[^/]+$', GET => { - desc => "Get attibutes for rows from non-node tables.", + desc => "Get attributes for rows from non-node tables.", usage => "||An object containing each table. Within each table object is an array of row objects containing the attributes.|", example => qq(|Get row which net=192.168.1.0,mask=255.255.255.0 from networks table.|GET|/tables/networks/rows/net=192.168.1.0,mask=255.255.255.0|{\n \"networks\":[\n {\n \"mgtifname\":\"eth0\",\n \"netname\":\"192_168_1_0-255_255_255_0\",\n \"tftpserver\":\"192.168.1.15\",\n \"gateway\":\"192.168.1.100\",\n \"staticrangeincrement\":\"1\",\n \"net\":\"192.168.1.0\",\n \"mask\":\"255.255.255.0\"\n }\n ]\n}|), fhandler => \&tablerowhdl, outhdler => \&tableout, }, PUT => { - desc => "Change the non-node table attibutes for the row that matches the {keys}.", + desc => "Change the non-node table attributes for the row that matches the {keys}.", usage => "|A hash of attribute names and values. DataBody: {attr1:v1,att2:v2,...}.|$usagemsg{non_getreturn}|", example => '|Create a route row in the routes table.|PUT|/tables/routes/rows/routename=privnet {"net":"10.0.1.0","mask":"255.255.255.0","gateway":"10.0.1.254","ifname":"eth1"}||', fhandler => \&tablerowputhdl, @@ -1234,7 +1234,7 @@ my %URIdef = ( desc1 => "Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, polciy, etc.", matcher => '^/tables/[^/]+/rows/[^/]+/[^/]+$', GET => { - desc => "Get specific attibutes for rows from non-node tables.", + desc => "Get specific attributes for rows from non-node tables.", usage => "||An object containing each table. Within each table object is an array of row objects containing the attributes.|", example => qq(|Get attributes mgtifname and tftpserver which net=192.168.1.0,mask=255.255.255.0 from networks table.|GET|/tables/networks/rows/net=192.168.1.0,mask=255.255.255.0/mgtifname,tftpserver|{\n \"networks\":[\n {\n \"mgtifname\":\"eth0\",\n \"tftpserver\":\"192.168.1.15\"\n }\n ]\n}|), fhandler => \&tablerowhdl, @@ -1291,7 +1291,7 @@ my %URIdef = ( GET => { desc => "Show attributes of a node template.", usage => "||$usagemsg{objreturn}|", - example => "|GET all the attibutes of node template \'x86_64kvmguest-template\'.|GET|/templates/node {\"options\":{\"--template\":\"x86_64kvmguest-template\"}} |{\n \"arch\":{\n \"x86_64\":\"compute\",\n \"bmc\":\"MANDATORY:The hostname or ip address of the BMC adapater\",\n \bmcpassword\":\"MANDATORY:the password of the BMC\",\n \"mgt\":\"ipmi\",\n \"groups\":\"all\",\n ...\n }\n}", + example => "|GET all the attributes of node template \'x86_64kvmguest-template\'.|GET|/templates/node {\"options\":{\"--template\":\"x86_64kvmguest-template\"}} |{\n \"arch\":{\n \"x86_64\":\"compute\",\n \"bmc\":\"MANDATORY:The hostname or ip address of the BMC adapater\",\n \bmcpassword\":\"MANDATORY:the password of the BMC\",\n \"mgt\":\"ipmi\",\n \"groups\":\"all\",\n ...\n }\n}", cmd => "lsdef", fhandler => \&defhdl, outhdler => \&defout, @@ -2894,7 +2894,7 @@ sub tablenodeputhdl { my $params = shift; # from the %URIdef: - # desc => "[URI:/tables/nodes/{noderange}] - Change the table attibutes for the {noderange}.", + # desc => "[URI:/tables/nodes/{noderange}] - Change the table attributes for the {noderange}.", # usage => "|An array of table objects. Each table object contains the table name and an object of attribute values. DataBody: {table1:{attr1:v1,att2:v2,...}}.|$usagemsg{non_getreturn}|", # example => '|Change the nodehm.mgmt and noderes.netboot attributes for nodes node1-node5.|PUT|/tables/nodes/node1-node5 {"nodehm":{"mgmt":"ipmi"},"noderes":{"netboot":"xnba"}}||', @@ -2961,7 +2961,7 @@ sub tablerowputhdl { my $params = shift; # from %URIdef: - # desc => "[URI:/tables/{table}/rows/{keys}] - Change the non-node table attibutes for the row that matches the {keys}.", + # desc => "[URI:/tables/{table}/rows/{keys}] - Change the non-node table attributes for the row that matches the {keys}.", # usage => "|A hash of attribute names and values. DataBody: {attr1:v1,att2:v2,...}.|$usagemsg{non_getreturn}|", # example => '|Creat a route row in the routes table.|PUT|/tables/routes/rows/routename=privnet {"net":"10.0.1.0","mask":"255.255.255.0","gateway":"10.0.1.254","ifname":"eth1"}||', From bd6718999b12808b57b2d339e9e0127c45d2d70a Mon Sep 17 00:00:00 2001 From: XuWei Date: Tue, 10 Apr 2018 21:55:04 -0400 Subject: [PATCH 06/10] modify return code of rspconfig hostname error --- xCAT-server/lib/xcat/plugins/openbmc.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xCAT-server/lib/xcat/plugins/openbmc.pm b/xCAT-server/lib/xcat/plugins/openbmc.pm index d5671b12b..f576e20a5 100644 --- a/xCAT-server/lib/xcat/plugins/openbmc.pm +++ b/xCAT-server/lib/xcat/plugins/openbmc.pm @@ -983,7 +983,7 @@ sub process_request { if ($next_status{LOGIN_RESPONSE} eq "RSPCONFIG_SET_HOSTNAME_REQUEST" and $status_info{RSPCONFIG_SET_HOSTNAME_REQUEST}{data} =~ /^\*$/) { if ($node_info{$node}{bmc} =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { my $info_msg = "Invalid OpenBMC Hostname $node_info{$node}{bmc}, can't set to OpenBMC"; - xCAT::SvrUtils::sendmsg($info_msg, $callback, $node); + xCAT::SvrUtils::sendmsg([1, $info_msg], $callback, $node); $wait_node_num--; next; } From 4d567525367427fae18ad5272fc61b206103bc4f Mon Sep 17 00:00:00 2001 From: hu-weihua Date: Tue, 10 Apr 2018 22:29:31 -0400 Subject: [PATCH 07/10] change test case of rspconfit to satisfy the latest code --- xCAT-test/autotest/testcase/rspconfig/cases0 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xCAT-test/autotest/testcase/rspconfig/cases0 b/xCAT-test/autotest/testcase/rspconfig/cases0 index 1054e48fa..97494f030 100644 --- a/xCAT-test/autotest/testcase/rspconfig/cases0 +++ b/xCAT-test/autotest/testcase/rspconfig/cases0 @@ -256,7 +256,7 @@ hcp:openbmc cmd:lsdef $$CN -i bmc -c check:rc == 0 cmd:rspconfig $$CN hostname=* -check:rc == 0 +check:rc != 0 check:output =~ Invalid OpenBMC Hostname cmd:ssh __GETNODEATTR(f6u03,bmc)__ "hostname" end From fe249bfb70106e0db310db05b8dee9728369199c Mon Sep 17 00:00:00 2001 From: cxhong Date: Wed, 11 Apr 2018 02:03:56 -0400 Subject: [PATCH 08/10] Print out error msg for xcatprobe switch_macmap command if switch passwordless is not enabled (#5064) * Print out error msg for xcatprobe switch_mac command if switch passwordless is not enabled. * Modified msg only if in the collect_mac_info case --- perl-xCAT/xCAT/MacMap.pm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/perl-xCAT/xCAT/MacMap.pm b/perl-xCAT/xCAT/MacMap.pm index 2a1931397..1c8668411 100644 --- a/perl-xCAT/xCAT/MacMap.pm +++ b/perl-xCAT/xCAT/MacMap.pm @@ -356,7 +356,7 @@ sub dump_mac_info { $ret{$switch}->{ErrorStr} = $self->{macinfo}->{$switch}->{ErrorStr}; # To show the error message that the username/password related error is for SNMP only - if ($ret{$switch}->{ErrorStr} =~ /user\s*name|password/i) { + if ($ret{$switch}->{ErrorStr} =~ /user\s*name|password$/i) { $ret{$switch}->{ErrorStr} .= " through SNMP"; } } else { @@ -729,6 +729,11 @@ sub refresh_switch { my @res=xCAT::Utils->runcmd("ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no $switch 'bridge fdb show|grep -i -v permanent|tr A-Z a-z 2>/dev/null' 2>/dev/null",-1); if ($::RUNCMD_RC) { xCAT::MsgUtils->message("S", "Failed to get mac table with ssh to $switch, fall back to snmp! To obtain mac table with ssh, please make sure the passwordless root ssh to $switch is available"); + if ($self->{collect_mac_info}) { + my $errmsg = "Failed to get MAC table from $switch. Make sure passwordless SSH to the switch is enabled."; + $self->{macinfo}->{$switch}->{ErrorStr} = $errmsg; + return; + } }else{ foreach (@res){ if($_ =~ m/^([0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}) dev swp([0-9]+) vlan ([0-9]+) .*/){ From fc4bbd33fe0c2800b3e06f9eebdef76cec3dc12e Mon Sep 17 00:00:00 2001 From: Bin Xu Date: Wed, 11 Apr 2018 14:19:35 +0800 Subject: [PATCH 09/10] Fix the issue for stateless node in debug mode, /dev/log is not available (#5086) (#4929) - use imjournal to make rsyslogd work well with journald --- .../netboot/rh/dracut_033/patch/syslog/module-setup.sh | 2 +- .../netboot/rh/dracut_033/patch/syslog/rsyslogd-start.sh | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/xCAT-server/share/xcat/netboot/rh/dracut_033/patch/syslog/module-setup.sh b/xCAT-server/share/xcat/netboot/rh/dracut_033/patch/syslog/module-setup.sh index 386a3a40b..ba8ed94cf 100755 --- a/xCAT-server/share/xcat/netboot/rh/dracut_033/patch/syslog/module-setup.sh +++ b/xCAT-server/share/xcat/netboot/rh/dracut_033/patch/syslog/module-setup.sh @@ -16,7 +16,7 @@ install() { local _installs if type -P rsyslogd >/dev/null; then _installs="rsyslogd" - inst_libdir_file rsyslog/lmnet.so rsyslog/imklog.so rsyslog/imuxsock.so + inst_libdir_file rsyslog/lmnet.so rsyslog/imklog.so rsyslog/imuxsock.so rsyslog/imjournal.so elif type -P syslogd >/dev/null; then _installs="syslogd" elif type -P syslog-ng >/dev/null; then diff --git a/xCAT-server/share/xcat/netboot/rh/dracut_033/patch/syslog/rsyslogd-start.sh b/xCAT-server/share/xcat/netboot/rh/dracut_033/patch/syslog/rsyslogd-start.sh index 9589af436..b0a3e6a94 100755 --- a/xCAT-server/share/xcat/netboot/rh/dracut_033/patch/syslog/rsyslogd-start.sh +++ b/xCAT-server/share/xcat/netboot/rh/dracut_033/patch/syslog/rsyslogd-start.sh @@ -21,7 +21,12 @@ rsyslog_config() { # echo "${filter} @${server}" # done - + # In dracut 33, default rsyslogd configuration does not use journald. Then when + # rsyslog in debug mode, it causes `/dev/log` is not available after switch_root (#4929) + echo "\$ModLoad imjournal" + echo "\$OmitLocalLogging on" + echo "\$IMJournalStateFile imjournal.state" + if [ -n "$filters" ];then confline="${filters}"; else From 17ce243cf6c28e78b1b7e5fe1c392de6fe398fad Mon Sep 17 00:00:00 2001 From: XuWei Date: Wed, 11 Apr 2018 04:20:29 -0400 Subject: [PATCH 10/10] fix typo error of rspconfig powersupplyredundancy --- xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py index a33714129..0401928b3 100644 --- a/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py @@ -198,7 +198,7 @@ RSPCONFIG_APIS = { 'get_data': [], 'display_name': "BMC PowerSupplyRedundancy", 'attr_values': { - 'disabled': ["Disables"], + 'disabled': ["Disabled"], 'enabled': ["Enabled"], }, },