2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-05-23 01:02:48 +00:00

Merge pull request #4704 from xcat2/master

Merge master to 2.13 branch for 2.13.10 release(1)
This commit is contained in:
zet809
2018-01-23 17:32:42 +08:00
committed by GitHub
126 changed files with 3915 additions and 837 deletions
+6 -1
View File
@@ -8,7 +8,7 @@ Documentation
xCAT documentation is available at: http://xcat-docs.readthedocs.io/en/latest/
|docs_latest| |docs_2138| |docs_2137| |docs_2136| |docs_2135| |docs_2134| |docs_2133| |docs_2132| |docs_2131| |docs_2130| |docs_212|
|docs_latest| |docs_2139| |docs_2138| |docs_2137| |docs_2136| |docs_2135| |docs_2134| |docs_2133| |docs_2132| |docs_2131| |docs_2130| |docs_212|
Open Source License
-------------------
@@ -22,6 +22,11 @@ Developers
Developers and prospective contributors are encouraged to read the `Developers Guide <http://xcat-docs.readthedocs.io/en/latest/developers/>`_
In particular the `GitHub <http://xcat-docs.readthedocs.io/en/latest/developers/github/>`_ related subsection.
.. |docs_2139| image:: https://readthedocs.org/projects/xcat-docs/badge/?version=2.13.9
:alt: 2.13.9 documentation status
:scale: 100%
:target: http://xcat-docs.readthedocs.io/en/2.13.9/
.. |docs_2138| image:: https://readthedocs.org/projects/xcat-docs/badge/?version=2.13.8
:alt: 2.13.8 documentation status
:scale: 100%
+1 -1
View File
@@ -1 +1 @@
2.13.9
2.13.10
+2 -2
View File
@@ -213,7 +213,7 @@ then
for file in $packages
do
file_low=`echo $file | tr '[A-Z]' '[a-z]'`
if [ "$file" = "xCAT" -o "$file" = "xCAT-genesis-scripts" ]; then
if [ "$file" = "xCAT" -o "$file" = "xCAT-genesis-scripts" -o "$file" = "xCATsn" ]; then
target_archs="amd64 ppc64el"
else
target_archs="all"
@@ -250,7 +250,7 @@ then
# shipping bmcsetup and getipmi scripts as part of postscripts
files=("bmcsetup" "getipmi")
for f in "${files[@]}"; do
cp ${CURDIR}/../xCAT-genesis-scripts/bin/$f ${CURDIR}/postscripts/$f
cp ${CURDIR}/../xCAT-genesis-scripts/usr/bin/$f ${CURDIR}/postscripts/$f
sed -i "s/xcat.genesis.$f/$f/g" ${CURDIR}/postscripts/$f
done
fi
+109
View File
@@ -0,0 +1,109 @@
Collaborative PDU
=================
Collaborative PDU is also referred as Coral PDU, it controls power for compute Rack. User can access PDU via SSH and can use the **PduManager** command to configure and manage the PDU product.
Pre-Defined PDU Objects
-----------------------
A pre-defined PDU node object is required before running pdudiscover command. ::
mkdef coralpdu groups=pdu mgt=pdu nodetype=pdu (required)
all other attributes can be set by chdef command or pdudisocover command. ::
--switch required for pdudiscover command to do mapping
--switchport required for pdudiscover command to do mapping
--ip ip address of the pdu.
--mac can be filled in by pdudiscover command
--pdutype crpdu(for coral pdu) or irpdu(for infrastructure PDUs)
The following attributes need to be set in order to configure snmp with non-default values. ::
--community community string for coral pdu
--snmpversion snmp version number, required if configure snmpv3 for coral pdu
--snmpuser snmpv3 user name, required if configure snmpv3 for coral pdu
--authkey auth passphrase for snmpv3 configuration
--authtype auth protocol (MD5|SHA) for snmpv3 configuration
--privkey priv passphrase for snmpv3 configuration
--privtype priv protocol (AES|DES) for snmpv3 configuration
--seclevel security level (noAuthNoPriv|authNoPriv|authPriv) for snmpv3 configuration
Make sure to run makehosts after pre-defined PDU. ::
makehosts coralpdu
Configure PDUs
--------------
After pre-defining PDUs, user can use **pdudisocver --range ip_range --setup** to configure the PDUs, or following commands can be used:
* To configure passwordless of Coral PDU: ::
# rspconfig coralpdu sshcfg
* To change hostname of Coral PDU: ::
# rspconfig coralpdu hosname=f5pdu3
* To change ip address of PDU: ::
# rsconfig coralpdu ip=x.x.x.x netmaks=255.x.x.x
* To configure SNMP community string or snmpv3 of PDU (the attribute needs to pre-defined): ::
# rspconfig coralpdu snmpcfg
Remote Power Control of PDU
---------------------------
Use the rpower command to remotely power on and off PDU.
* To check power stat of PDU: ::
# rpower coralpdu stat
* To power off the PDU: ::
# rpower coralpdu off
* To power on the PDU: ::
# rpower coralpdu on
Coral PDUs have three relays, the following commands are for individual relay support of PDU:
* To check power stat of relay: ::
# rpower coralpdu relay=1 stat
* To power off the relay: ::
# rpower coralpdu relay=2 off
* To power on the relay: ::
# rpower coralpdu relay=3 on
Show Monitor Data
-----------------
Use the rvitals command to show realtime monitor data(input voltage, current, power) of PDU. ::
# rvitals coralpdu
Show manufacture information
-----------------------------
Use the rinv command to show MFR information of PDU ::
# rinv coralpdu
+5 -1
View File
@@ -1,10 +1,14 @@
PDUs
====
Power Distribution Units (PDUs) are devices that distribute power to servers in a frame. Intelligent PDUs have the capability of monitoring the amount of power that is being used by devices plugged into it.
Power Distribution Units (PDUs) are devices that distribute power to servers in a frame. They have the capability of monitoring the amount of power that is being used by devices plugged into it and cycle power to individual receptacles. xCAT can support two kinds of PDUs, infrastructure PDU (irpdu) and collaborative PDU (crpdu).
The Infrastructure rack PDUs are switched and monitored 1U PDU products which can connect up to nine C19 devices or up to 12 C13 devices and an additional three C13 peripheral devices to a signle dedicated power source. The Collaborative PDU is on the compute rack and has the 6x IEC 320-C13 receptacles that feed the rack switches. These two types of PDU have different design and implementation. xCAT has different code path to maintains PDU commands via **pdutype**.
.. toctree::
:maxdepth: 2
pdu.rst
irpdu.rst
crpdu.rst
+153
View File
@@ -0,0 +1,153 @@
Infrastructure PDU
==================
Users can access Infrastructure PDU via telnet and use the **IBM PDU Configuration Utility** to set up and configure the PDU. xCAT supports PDU commands for power management and monitoring through SNMP.
PDU Commands
------------
Administrators will need to know the exact mapping of the outlets to each server in the frame. xCAT cannot validate the physical cable is connected to the correct server.
Add a ``pdu`` attribute to the compute node definition in the form "PDU_Name:outlet": ::
#
# Compute server cn01 has two power supplies
# connected to outlet 6 and 7 on pdu=f5pdu3
#
chdef cn01 pdu=f5pdu3:6,f5pdu3:7
The following commands are supported against a compute node:
* Check the pdu status for a compute node: ::
# rpower cn01 pdustat
cn01: f5pdu3 outlet 6 is on
cn01: f5pdu3 outlet 7 is on
* Power off the PDU outlets for a compute node: ::
# rpower cn01 pduoff
cn01: f5pdu3 outlet 6 is off
cn01: f5pdu3 outlet 7 is off
* Power on the PDU outlets for a compute node: ::
# rpower cn01 pduon
cn01: f5pdu3 outlet 6 is on
cn01: f5pdu3 outlet 7 is on
* Power cycling the PDU outlets for a compute node: ::
# rpower cn01 pdureset
cn01: f5pdu3 outlet 6 is reset
cn01: f5pdu3 outlet 7 is reset
The following commands are supported against a PDU:
* Check the status of the full PDU: ::
# rpower f5pdu3 stat
f5pdu3: outlet 1 is on
f5pdu3: outlet 2 is on
f5pdu3: outlet 3 is on
f5pdu3: outlet 4 is on
f5pdu3: outlet 5 is on
f5pdu3: outlet 6 is off
f5pdu3: outlet 7 is off
f5pdu3: outlet 8 is on
f5pdu3: outlet 9 is on
f5pdu3: outlet 10 is on
f5pdu3: outlet 11 is on
f5pdu3: outlet 12 is on
* Power off the full PDU: ::
# rpower f5pdu3 off
f5pdu3: outlet 1 is off
f5pdu3: outlet 2 is off
f5pdu3: outlet 3 is off
f5pdu3: outlet 4 is off
f5pdu3: outlet 5 is off
f5pdu3: outlet 6 is off
f5pdu3: outlet 7 is off
f5pdu3: outlet 8 is off
f5pdu3: outlet 9 is off
f5pdu3: outlet 10 is off
f5pdu3: outlet 11 is off
f5pdu3: outlet 12 is off
* Power on the full PDU: ::
# rpower f5pdu3 on
f5pdu3: outlet 1 is on
f5pdu3: outlet 2 is on
f5pdu3: outlet 3 is on
f5pdu3: outlet 4 is on
f5pdu3: outlet 5 is on
f5pdu3: outlet 6 is on
f5pdu3: outlet 7 is on
f5pdu3: outlet 8 is on
f5pdu3: outlet 9 is on
f5pdu3: outlet 10 is on
f5pdu3: outlet 11 is on
f5pdu3: outlet 12 is on
* Power reset the full PDU: ::
# rpower f5pdu3 reset
f5pdu3: outlet 1 is reset
f5pdu3: outlet 2 is reset
f5pdu3: outlet 3 is reset
f5pdu3: outlet 4 is reset
f5pdu3: outlet 5 is reset
f5pdu3: outlet 6 is reset
f5pdu3: outlet 7 is reset
f5pdu3: outlet 8 is reset
f5pdu3: outlet 9 is reset
f5pdu3: outlet 10 is reset
f5pdu3: outlet 11 is reset
f5pdu3: outlet 12 is reset
* PDU inventory information: ::
# rinv f6pdu16
f6pdu16: PDU Software Version: "OPDP_sIBM_v01.3_2"
f6pdu16: PDU Machine Type: "1U"
f6pdu16: PDU Model Number: "dPDU4230"
f6pdu16: PDU Part Number: "46W1608"
f6pdu16: PDU Name: "IBM PDU"
f6pdu16: PDU Serial Number: "4571S9"
f6pdu16: PDU Description: "description"
* PDU and outlet power information: ::
# rvitals f6pdu15
f6pdu15: Voltage Warning: 0
f6pdu15: outlet 1 Current: 0 mA
f6pdu15: outlet 1 Max Capacity of the current: 16000 mA
f6pdu15: outlet 1 Current Threshold Warning: 9600 mA
f6pdu15: outlet 1 Current Threshold Critical: 12800 mA
f6pdu15: outlet 1 Last Power Reading: 0 Watts
f6pdu15: outlet 2 Current: 0 mA
f6pdu15: outlet 2 Max Capacity of the current: 16000 mA
f6pdu15: outlet 2 Current Threshold Warning: 9600 mA
f6pdu15: outlet 2 Current Threshold Critical: 12800 mA
f6pdu15: outlet 2 Last Power Reading: 0 Watts
f6pdu15: outlet 3 Current: 1130 mA
f6pdu15: outlet 3 Max Capacity of the current: 16000 mA
f6pdu15: outlet 3 Current Threshold Warning: 9600 mA
f6pdu15: outlet 3 Current Threshold Critical: 12800 mA
f6pdu15: outlet 3 Last Power Reading: 217 Wattsv
**Note:** For BMC based compute nodes, turning the PDU outlet power on does not automatically power on the compute side. Users will need to issue ``rpower <node> on`` to power on the compute side after the BMC boots.
+28 -129
View File
@@ -1,17 +1,39 @@
PDU
===
Discovering PDUs
================
xCAT provides basic remote management for each power outlet plugged into the PDUs using SNMP communication. This documentation will focus on configuration of the PDU and Node objects to allow xCAT to control power at the PDU outlet level.
xCAT provides `pdudiscover` command to discover the PDUs that are attached to the neighboring subnets on xCAT management node. ::
pdudiscover [<noderange>|--range ipranges] [-r|-x|-z] [-w] [-V|--verbose] [--setup]
xCAT uses snmp scan method to discover PDU. Make sure net-snmp-utils package is installed on xCAT MN in order to use snmpwalk command. ::
Options:
--range Specify one or more IP ranges. Each can be an ip address (10.1.2.3) or an ip range
(10.1.2.0/24). If the range is huge, for example, 192.168.1.1/8, the pdu
discover may take a very long time to scan. So the range should be exactly
specified. It accepts multiple formats. For example:
192.168.1.1/24, 40-41.1-2.3-4.1-100.
If the range is not specified, the command scans all the subnets that the active
network interfaces (eth0, eth1) are on where this command is issued.
-r Display Raw responses.
-x XML formatted output.
-z Stanza formatted output.
-w Writes output to xCAT database.
--setup Process switch-based pdu discovery and configure the PDUs(it included passwordless , change ip address from dhcp to static and snmp configuration). It required predefined PDU node definition with switch name and switch port attributes for mapping. (Notes: only support for crpdu for now for this options)
Define PDU Objects
------------------
#. Define pdu object ::
mkdef f5pdu3 groups=pdu ip=50.0.0.8 mgt=pdu nodetype=pdu
mkdef f5pdu3 groups=pdu ip=50.0.0.8 mgt=pdu nodetype=pdu pdutype=irpdu
#. Define switch attribute for pdu object which will be used for pdudiscover **--setup** options. ::
chdef f5pdu3 switch=mid08 switchport=3
#. Add hostname to /etc/hosts::
@@ -19,129 +41,6 @@ Define PDU Objects
#. Verify the SNMP command responds against the PDU: ::
snmpwalk -v1 -cpublic -mALL f5pdu3 .1.3.6.1.2.1.1
Define PDU Attribute
--------------------
Administrators will need to know the exact mapping of the outlets to each server in the frame. xCAT cannot validate the physical cable is connected to the correct server.
Add a ``pdu`` attribute to the compute node definition in the form "PDU_Name:outlet": ::
#
# Compute server cn01 has two power supplies
# connected to outlet 6 and 7 on pdu=f5pdu3
#
chdef cn01 pdu=f5pdu3:6,f5pdu3:7
Verify the setting: ``lsdef cn01 -i pdu``
PDU Commands
------------
The following commands are supported against a compute node:
* Check the pdu status for a compute node: ::
# rpower cn01 pdustat
cn01: f5pdu3 outlet 6 is on
cn01: f5pdu3 outlet 7 is on
* Power off the PDU outlets on a compute node: ::
# rpower cn01 pduoff
cn01: f5pdu3 outlet 6 is off
cn01: f5pdu3 outlet 7 is off
* Power on the PDU outlets on a compute node: ::
# rpower cn01 pduon
cn01: f5pdu3 outlet 6 is on
cn01: f5pdu3 outlet 7 is on
* Power cycling the PDU outlets on a compute node: ::
# rpower cn01 pdureset
cn01: f5pdu3 outlet 6 is reset
cn01: f5pdu3 outlet 7 is reset
The following commands are supported against a PDU:
* Check the status of the full PDU: ::
# rinv f5pdu3
f5pdu3: outlet 1 is on
f5pdu3: outlet 2 is on
f5pdu3: outlet 3 is on
f5pdu3: outlet 4 is on
f5pdu3: outlet 5 is on
f5pdu3: outlet 6 is off
f5pdu3: outlet 7 is off
f5pdu3: outlet 8 is on
f5pdu3: outlet 9 is on
f5pdu3: outlet 10 is on
f5pdu3: outlet 11 is on
f5pdu3: outlet 12 is on
* Power off the full PDU: ::
# rpower f5pdu3 off
f5pdu3: outlet 1 is off
f5pdu3: outlet 2 is off
f5pdu3: outlet 3 is off
f5pdu3: outlet 4 is off
f5pdu3: outlet 5 is off
f5pdu3: outlet 6 is off
f5pdu3: outlet 7 is off
f5pdu3: outlet 8 is off
f5pdu3: outlet 9 is off
f5pdu3: outlet 10 is off
f5pdu3: outlet 11 is off
f5pdu3: outlet 12 is off
* Power on the full PDU: ::
# rpower f5pdu3 on
f5pdu3: outlet 1 is on
f5pdu3: outlet 2 is on
f5pdu3: outlet 3 is on
f5pdu3: outlet 4 is on
f5pdu3: outlet 5 is on
f5pdu3: outlet 6 is on
f5pdu3: outlet 7 is on
f5pdu3: outlet 8 is on
f5pdu3: outlet 9 is on
f5pdu3: outlet 10 is on
f5pdu3: outlet 11 is on
f5pdu3: outlet 12 is on
* Power reset the full PDU: ::
# rpower f5pdu3 reset
f5pdu3: outlet 1 is reset
f5pdu3: outlet 2 is reset
f5pdu3: outlet 3 is reset
f5pdu3: outlet 4 is reset
f5pdu3: outlet 5 is reset
f5pdu3: outlet 6 is reset
f5pdu3: outlet 7 is reset
f5pdu3: outlet 8 is reset
f5pdu3: outlet 9 is reset
f5pdu3: outlet 10 is reset
f5pdu3: outlet 11 is reset
f5pdu3: outlet 12 is reset
**Note:** For BMC based compute nodes, turning the PDU outlet power on does not automatically power on the compute side. Users will need to issue ``rpower <node> on`` to power on the compute node after the BMC boots.
snmpwalk -v1 -cpublic -mALL f5pdu3 system
@@ -0,0 +1,93 @@
Configure routes
-----------------
There are 2 ways to configure OS route in xCAT:
* ``makeroutes``: command to add or delete routes on the management node or any given nodes.
* ``setroute``: script to replace/add the routes to the node, it can be used in postscripts/postbootscripts.
``makeroutes`` or ``setroute`` will modify OS temporary route, it also modifies persistent route in ``/etc/sysconfig/static-routes`` file.
Before using ``makeroutes`` or ``setroute`` to configure OS route, details of the routes data such as routename, subnet, net mask and gateway should be stored in ``routes`` table.
Configure ``routes`` table
``````````````````````````
#. Store default route data in ``routes`` table: ::
chdef -t route defaultroute net=default mask=255.0.0.0 gateway=10.0.0.101
#. Store additional route data in ``routes`` table: ::
chdef -t route 20net net=20.0.0.0 mask=255.0.0.0 gateway=0.0.0.0 ifname=eth1
#. Check data in ``routes`` table: ::
tabdump routes
#routename,net,mask,gateway,ifname,comments,disable
"30net","30.0.0.0","255.0.0.0","0.0.0.0","eth2",,
"20net","20.0.0.0","255.0.0.0","0.0.0.0","eth1",,
"defaultroute","default","255.0.0.0","10.0.0.101",,,
Use ``makeroutes`` to configure OS route on xCAT management node
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#. define the names of the routes to be setup on the management node in ``site`` table: ::
chdef -t site mnroutenames="defaultroute,20net"
lsdef -t site clustersite -i mnroutenames
Object name: clustersite
mnroutenames=defaultroute,20net
#. add all routes from the ``mnroutenames`` to the OS route table for the management node: ::
makeroutes
#. add route ``20net`` and ``30net`` to the OS route table for the management node: ::
makeroutes -r 20net,30net
#. delete route ``20net`` from the OS route table for the management node: ::
makeroutes -d -r 20net
Use ``makeroutes`` to configure OS route for compute node
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#. define the names of the routes to be setup on the compute node: ::
chdef -t cn1 routenames="defaultroute,20net"
#. add all routes from the ``routenames`` to the OS route table for the compute node: ::
makeroutes cn1
#. add route ``20net`` and ``30net`` to the OS route table for the compute node: ::
makeroutes cn1 -r 20net,30net
#. delete route ``20net`` from the OS route table for the compute node: ::
makeroutes cn1,cn2 -d -r 20net
Use ``setroute`` to configure OS route for compute node
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
#. define the names of the routes to be setup on the compute node: ::
chdef -t cn1 routenames="defaultroute,20net"
#. If adding ``setroute [replace | add]`` into the nodes postscripts list, ``setroute`` will be executed during OS deployment on compute node to replace/add routes from ``routenames``: ::
chdef cn1 -p postscripts="setroute replace"
#. Or if the compute node is already running, use ``updatenode`` command to run ``setroute [replace | add]`` postscript: ::
updatenode cn1 -P "setroute replace"
Check result
````````````
#. Use ``route`` command in xCAT management node to check OS route table.
#. Use ``xdsh cn1 route`` to check compute node OS route table.
@@ -0,0 +1 @@
.. include:: ../../../../common/deployment/network/cfg_routes.rst
@@ -8,3 +8,4 @@ This section describes how to configure network adapters with persistent configu
cfg_network_adapter.rst
cfg_second_adapter.rst
cfg_routes.rst
@@ -0,0 +1 @@
.. include:: ../../../../common/deployment/network/cfg_routes.rst
@@ -8,3 +8,4 @@ This section describes how to configure network adapters with persistent configu
cfg_network_adapter.rst
cfg_second_adapter.rst
cfg_routes.rst
@@ -19,10 +19,17 @@ Name
****************
\ **reventlog**\ \ *noderange*\ {\ *number-of-entries*\ [\ **-s**\ ]|\ **all [-s] | clear**\ }
\ **reventlog**\ \ *noderange*\ [\ *number-of-entries*\ [\ **-s**\ ]|\ **all [-s] | clear**\ ]
\ **reventlog**\ [\ **-h | -**\ **-help | -v | -**\ **-version**\ ]
OpenPOWER OpenBMC specific :
============================
\ **reventlog**\ \ *noderange*\ [\ **resolved=**\ {\ *id-list*\ |\ **LED**\ }]
*******************
\ **Description**\
@@ -64,6 +71,12 @@ logs are stored on each servers service processor.
\ **resolved=**\ {\ *id-list*\ |\ **LED**\ }
Mark event log entries as resolved. Use comma separated list of entry ids to specify individual entries. Use \ **LED**\ to mark as resolved all event log entries that contribute to LED fault.
\ **-h | -**\ **-help**\
Print help.
@@ -83,7 +96,7 @@ logs are stored on each servers service processor.
1.
1. List last 5 event log entries from node4 and node5
.. code-block:: perl
@@ -110,7 +123,7 @@ logs are stored on each servers service processor.
2.
2. Clear all event log entries from node4 and node5
.. code-block:: perl
@@ -129,6 +142,27 @@ logs are stored on each servers service processor.
3. Mark as resolved all event log entries from node4 that contribute to LED fault
.. code-block:: perl
reventlog node4 resolved=LED
Output is similar to:
.. code-block:: perl
Attempting to resolve the following log entries: LED...
node4: Resolved 51.
node4: Resolved 52.
node4: Resolved 58.
********
SEE ALSO
@@ -150,31 +150,19 @@ The command will update firmware for OpenPOWER BMC when given an OpenPOWER node
\ **-l|-**\ **-list**\ :
The list option will list out available firmware on the BMC. It provides an interface to display the ID of the various firmware levels.
.. code-block:: perl
The list option will list out available firmware on the BMC. It provides an interface to display the ID of the various firmware levels.
The (*) symbol indicates the active running firmware on the server.
The (+) symbol indicates the firmware that is pending and a reboot is required to set it to be the active running firmware level.
The (\*) symbol indicates the active running firmware on the server.
The (+) symbol indicates the firmware that is pending and a reboot is required to set it to be the active running firmware level.
\ **-u|-**\ **-upload**\ :
.. code-block:: perl
The upload option expects a .tar file as the input and will upload the file to the BMC. Use the list option to view the result.
The upload option expects a .tar file as the input and will upload the file to the BMC. Use the list option to view the result.
\ **-a|-**\ **-activate**\ :
.. code-block:: perl
The activate option expects either a .tar file or an ID as the input. If a .tar file is provided, it will upload and activate the firmware in a single step
The activate option expects either a .tar file or an ID as the input. If a .tar file is provided, it will upload and activate the firmware in a single step
To apply the firmware level, a reboot is required to BMC and HOST.
@@ -182,37 +170,14 @@ To apply the firmware level, a reboot is required to BMC and HOST.
\ **-d**\ :
.. code-block:: perl
This option steamlines the update, activate, reboot BMC and reboot HOST procedure. It expects a directory containing both BMC and PNOR .tar files. When BMC and PNOR tar files are provided, the command will upload and activate firmware. After BMC becomes activate, it will reboot BMC. If BMC state is Ready, the command will reboot the HOST. If BMC state is NotReady, the command will exit.
This option steamlines the update, activate, reboot BMC and reboot HOST procedure. It expects a directory containing both BMC and PNOR .tar files. When BMC and PNOR tar files are provided, the command will upload and activate firmware. After BMC becomes activate, it will reboot BMC. If BMC state is Ready, the command will reboot the HOST. If BMC state is NotReady, the command will exit.
\ **Note:**\ When using \ **-**\ **-no-host-reboot**\ , it will not reboot the host after BMC is reboot.
\ **-**\ **-delete**\ :
This delete option will delete update image from BMC. It expects an ID as the input.
.. code-block:: perl
This delete option will delete update image from BMC. It expects an ID as the input.
\ **-d**\ :
.. code-block:: perl
This option steamlines the update, activate, reboot BMC and reboot HOST procedure. It expects a directory containing both BMC and PNOR .tar files. When BMC and PNOR tar files are provided, the command will upload and activate firmware. After BMC becomes activate, it will reboot BMC. If BMC state is Ready, the command will reboot the HOST. If BMC state is NotReady, the command will exit.
\ **Note:**\ When using \ **--no-host-reboot**\, it will not reboot the host after BMC is reboot.
\ **-**\ **-delete**\ :
.. code-block:: perl
The delete option will delete update image from BMC. It expects an ID as the input.
***************
@@ -49,7 +49,7 @@ OpenBMC specific:
\ **rspconfig**\ \ *noderange*\ {\ **ipsrc | ip | netmask | gateway | hostname | vlan | sshcfg**\ }
\ **rspconfig**\ \ *noderange*\ \ **dump**\ [\ **-l | -**\ **-list**\ ] [\ **-g | -**\ **-generate**\ ] [\ **-c | -**\ **-clear**\ {\ *id*\ |\ **all**\ }] [\ **-d | -**\ **-download**\ \ *id*\ ]
\ **rspconfig**\ \ *noderange*\ \ **dump**\ [\ **-l | -**\ **-list**\ ] [\ **-g | -**\ **-generate**\ ] [\ **-c | -**\ **-clear**\ {\ *id*\ | \ **all**\ }] [\ **-d | -**\ **-download**\ {\ *id*\ | \ **all**\ }]
MPA specific:
@@ -449,7 +449,7 @@ OPTIONS
\ **-d**\ will download a single dump from the BMC to /var/log/xcat/dump on management or service node.
\ **-d**\ will download a single dump or all generated dumps from the BMC to /var/log/xcat/dump on management or service node.
@@ -67,7 +67,7 @@ OpenPOWER (OpenBMC) specific:
=============================
\ **rvitals**\ \ *noderange*\ [\ **temp | voltage | wattage | fanspeed | power | altitude | all**\ ]
\ **rvitals**\ \ *noderange*\ [\ **temp | voltage | wattage | fanspeed | power | leds | altitude | all**\ ]
@@ -50,7 +50,7 @@ nodelist Attributes:
\ **status**\
The current status of this node. This attribute will be set by xCAT software. Valid values: defined, booting, netbooting, booted, discovering, configuring, installing, alive, standingby, powering-off, unreachable. If blank, defined is assumed. The possible status change sequences are: For installation: defined->[discovering]->[configuring]->[standingby]->installing->booting->booted->[alive], For diskless deployment: defined->[discovering]->[configuring]->[standingby]->netbooting->booted->[alive], For booting: [alive/unreachable]->booting->[alive], For powering off: [alive]->powering-off->[unreachable], For monitoring: alive->unreachable. Discovering and configuring are for x Series discovery process. Alive and unreachable are set only when there is a monitoring plug-in start monitor the node status for xCAT. Note that the status values will not reflect the real node status if you change the state of the node from outside of xCAT (i.e. power off the node using HMC GUI).
The current status of this node. This attribute will be set by xCAT software. Valid values: defined, booting, netbooting, booted, discovering, configuring, installing, alive, standingby, powering-off, unreachable. If blank, defined is assumed. The possible status change sequences are: For installation: defined->[discovering]->[configuring]->[standingby]->installing->booting->[postbooting]->booted->[alive], For diskless deployment: defined->[discovering]->[configuring]->[standingby]->netbooting->[postbooting]->booted->[alive], For booting: [alive/unreachable]->booting->[postbooting]->booted->[alive], For powering off: [alive]->powering-off->[unreachable], For monitoring: alive->unreachable. Discovering and configuring are for x Series discovery process. Alive and unreachable are set only when there is a monitoring plug-in start monitor the node status for xCAT. Note that the status values will not reflect the real node status if you change the state of the node from outside of xCAT (i.e. power off the node using HMC GUI).
@@ -68,7 +68,7 @@ servicenode Attributes:
\ **conserver**\
Do we set up Conserver on this service node? Valid values:1 or 0. If 1, configures and starts conserver daemon. If 0, it does not change the current state of the service.
Do we set up console service on this service node? Valid values: 0, 1, or 2. If 0, it does not change the current state of the service. If 1, configures and starts conserver daemon. If 2, configures and starts goconserver daemon.
@@ -1131,7 +1131,7 @@ node Attributes:
\ **status**\ (nodelist.status)
The current status of this node. This attribute will be set by xCAT software. Valid values: defined, booting, netbooting, booted, discovering, configuring, installing, alive, standingby, powering-off, unreachable. If blank, defined is assumed. The possible status change sequences are: For installation: defined->[discovering]->[configuring]->[standingby]->installing->booting->booted->[alive], For diskless deployment: defined->[discovering]->[configuring]->[standingby]->netbooting->booted->[alive], For booting: [alive/unreachable]->booting->[alive], For powering off: [alive]->powering-off->[unreachable], For monitoring: alive->unreachable. Discovering and configuring are for x Series discovery process. Alive and unreachable are set only when there is a monitoring plug-in start monitor the node status for xCAT. Note that the status values will not reflect the real node status if you change the state of the node from outside of xCAT (i.e. power off the node using HMC GUI).
The current status of this node. This attribute will be set by xCAT software. Valid values: defined, booting, netbooting, booted, discovering, configuring, installing, alive, standingby, powering-off, unreachable. If blank, defined is assumed. The possible status change sequences are: For installation: defined->[discovering]->[configuring]->[standingby]->installing->booting->[postbooting]->booted->[alive], For diskless deployment: defined->[discovering]->[configuring]->[standingby]->netbooting->[postbooting]->booted->[alive], For booting: [alive/unreachable]->booting->[postbooting]->booted->[alive], For powering off: [alive]->powering-off->[unreachable], For monitoring: alive->unreachable. Discovering and configuring are for x Series discovery process. Alive and unreachable are set only when there is a monitoring plug-in start monitor the node status for xCAT. Note that the status values will not reflect the real node status if you change the state of the node from outside of xCAT (i.e. power off the node using HMC GUI).
@@ -0,0 +1,32 @@
2017-12-07 - OpenSSL Vulnerabilities
====================================
*Dec 07, 2017*, OpenSSL announced the following security advisories: https://www.openssl.org/news/secadv/20171207.txt
Advisory CVEs
-------------
* CVE-2017-3737 - **Read/write after SSL object in error state** (Severity: Moderate)
This issue does not affect OpenSSL 1.1.0.
OpenSSL 1.0.2 users should upgrade to 1.0.2n
* CVE-2017-3738 - **rsaz_1024_mul_avx2 overflow bug on x86_64** (Severity: Low)
Due to the low severity of this issue we are not issuing a new release of OpenSSL 1.1.0 at this time. The fix will be included in OpenSSL 1.1.0h when it becomes available. The fix is also available in commit e502cc86d in the OpenSSL git repository.
OpenSSL 1.0.2 users should upgrade to 1.0.2n
Please see the security bulletin above for patch, upgrade, or suggested work around information.
Action
------
xCAT uses OpenSSL for client-server communication but **does not** ship it.
It is highly recommended to keep your OpenSSL levels up-to-date with the indicated versions in the security bulletins to prevent any potential security threats. Obtain the updated software packages from your Operating system distribution channels.
+1
View File
@@ -5,6 +5,7 @@
:maxdepth: 1
20171212_tls.rst
20171207_openssl.rst
20170828_openssl.rst
20170216_openssl.rst
20170126_openssl.rst
Executable
+38
View File
@@ -0,0 +1,38 @@
#!/bin/bash
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
function makepythonrpm {
RPMNAME="$1"
SPEC_FILE="$RPMNAME.spec"
tar --exclude .svn -czvf $RPMROOT/SOURCES/$RPMNAME-${VER}.tar.gz $RPMNAME
rm -f $RPMROOT/SRPMS/$RPMNAME-$VER*rpm $RPMROOT/RPMS/noarch/$RPMNAME-$VER*rpm
echo "Building $RPMROOT/RPMS/noarch/$RPMNAME-$VER-snap*.noarch.rpm $EMBEDTXT..."
rpmbuild --quiet -ta $RPMROOT/SOURCES/$RPMNAME-${VER}.tar.gz --define "version $VER" $REL "$EASE"
if [ $? -eq 0 ]; then
exit 0
else
exit 1
fi
}
# Main code....
OSNAME=$(uname)
VER=`cat Version`
REL="--define"
EASE='usedate 1'
RPMROOT=/root/rpmbuild
mkdir -p $RPMROOT/SOURCES
rpmbuild --version > /dev/null
if [ $? -gt 0 ]; then
echo "Error: rpmbuild does not appear to be installed or working."
exit 2
fi
if [ -n "$1" -a "$1" = "xCAT-openbmc-py" ]; then
makepythonrpm $1
else
echo 'Usage: makepythonrpm xCAT-openbmc-py'
exit 1
fi
+1 -1
View File
@@ -126,7 +126,7 @@ function makexcat {
# shipping bmcsetup and getipmi scripts as part of postscripts
files=("bmcsetup" "getipmi")
for f in "${files[@]}"; do
cp "xCAT-genesis-scripts/bin/"$f ${RPMNAME}/postscripts/$f
cp "xCAT-genesis-scripts/usr/bin/"$f ${RPMNAME}/postscripts/$f
sed -i "s/xcat.genesis.$f/$f/g" ${RPMNAME}/postscripts/$f
done
cd `dirname $0`/$RPMNAME
+6 -3
View File
@@ -46,6 +46,7 @@ $::STATUS_INACTIVE = "unreachable";
$::STATUS_INSTALLING = "installing";
$::STATUS_INSTALLED = "installed";
$::STATUS_BOOTING = "booting";
$::STATUS_POSTBOOTING = "postbooting";
$::STATUS_NETBOOTING = "netbooting";
$::STATUS_BOOTED = "booted";
$::STATUS_POWERING_ON = "powering-on";
@@ -66,6 +67,7 @@ $::STATUS_BMCREADY = "bmcready";
$::STATUS_INSTALLING => 1,
$::STATUS_INSTALLED => 1,
$::STATUS_BOOTING => 1,
$::STATUS_POSTBOOTING => 1,
$::STATUS_NETBOOTING => 1,
$::STATUS_BOOTED => 1,
$::STATUS_POWERING_ON => 1,
@@ -86,15 +88,16 @@ $::STATUS_BMCREADY = "bmcready";
$::STATUS_SYNCED => 1,
);
#defined->[discovering]->[configuring]->[standingby]->installing->[installed]->booting->alive, defined->[discovering]->[configuring]-[standingby]->netbooting->booted->alive, alive/unreachable->booting->alive, powering-off->unreachable, alive->unreachable
#defined->[discovering]->[configuring]->[standingby]->installing->[installed]->booting->[postbooting]->booted->alive, defined->[discovering]->[configuring]-[standingby]->netbooting->[postbooting]->booted->alive, alive/unreachable->booting->alive, powering-off->unreachable, alive->unreachable
%::NEXT_NODESTAT_VAL = (
$::STATUS_DEFINED => { $::STATUS_DISCOVERING => 1, $::STATUS_INSTALLING => 1, $::STATUS_NETBOOTING => 1, $::STATUS_POWERING_OFF => 1, $::STATUS_POWERING_ON => 1, $::STATUS_BOOTING => 1, $::STATUS_CONFIGURING => 1 },
$::STATUS_DISCOVERING => { $::STATUS_INSTALLING => 1, $::STATUS_NETBOOTING => 1, $::STATUS_CONFIGURING => 1, $::STATUS_BOOTING => 1 },
$::STATUS_CONFIGURING => { $::STATUS_INSTALLING => 1, $::STATUS_NETBOOTING => 1, $::STATUS_STANDING_BY => 1 },
$::STATUS_INSTALLING => { $::STATUS_INSTALLED => 1, $::STATUS_BOOTING => 1 },
$::STATUS_INSTALLED => { $::STATUS_BOOTING => 1 },
$::STATUS_BOOTING => { $::STATUS_BOOTED => 1, $::STATUS_ACTIVE => 1, $::STATUS_INACTIVE => 1 },
$::STATUS_NETBOOTING => { $::STATUS_BOOTED => 1 },
$::STATUS_BOOTING => { $::STATUS_BOOTED => 1, $::STATUS_ACTIVE => 1, $::STATUS_INACTIVE => 1, $::STATUS_POSTBOOTING => 1 },
$::STATUS_POSTBOOTING => { $::STATUS_BOOTED => 1 },
$::STATUS_NETBOOTING => { $::STATUS_POSTBOOTING => 1, $::STATUS_BOOTED => 1 },
$::STATUS_BOOTED => { $::STATUS_ACTIVE => 1, $::STATUS_INACTIVE => 1 },
$::STATUS_ACTIVE => { $::STATUS_INACTIVE => 1, $::STATUS_DISCOVERING => 1, $::STATUS_CONFIGURING => 1, $::STATUS_INSTALLING => 1, $::STATUS_NETBOOTING => 1, $::STATUS_POWERING_OFF => 1, $::STATUS_POWERING_ON => 1 },
$::STATUS_INACTIVE => { $::STATUS_ACTIVE => 1, $::STATUS_DISCOVERING => 1, $::STATUS_CONFIGURING => 1, $::STATUS_INSTALLING => 1, $::STATUS_NETBOOTING => 1, $::STATUS_POWERING_OFF => 1, $::STATUS_POWERING_ON => 1 },
+1 -1
View File
@@ -510,7 +510,7 @@ sub refresh_table {
# if we are doing switch discovery and the node is not a switch, skip
# if we are NOT doing switch discovery, and the node is a switch, skip
my $ntype = $typehash->{$entry->{node}}->[0]->{nodetype};
if ( (($discover_switch) and ( $ntype ne "switch"))
if ( (($discover_switch) and ($ntype ne "switch") and ($ntype ne "pdu") )
or ( !($discover_switch) and ( $ntype eq "switch")) ){
xCAT::MsgUtils->trace(0, "d", "refresh_table: skip node=$entry->{node} switch=$entry->{switch} discover_switch=$discover_switch nodetype=$ntype\n");
next;
+4 -2
View File
@@ -624,7 +624,7 @@ passed as argument rather than by table value',
descriptions => {
node => 'The hostname of a node in the cluster.',
groups => "A comma-delimited list of groups this node is a member of. Group names are arbitrary, except all nodes should be part of the 'all' group. Internal group names are designated by using __<groupname>. For example, __Unmanaged, could be the internal name for a group of nodes that is not managed by xCAT. Admins should avoid using the __ characters when defining their groups.",
status => 'The current status of this node. This attribute will be set by xCAT software. Valid values: defined, booting, netbooting, booted, discovering, configuring, installing, alive, standingby, powering-off, unreachable. If blank, defined is assumed. The possible status change sequences are: For installation: defined->[discovering]->[configuring]->[standingby]->installing->booting->booted->[alive], For diskless deployment: defined->[discovering]->[configuring]->[standingby]->netbooting->booted->[alive], For booting: [alive/unreachable]->booting->[alive], For powering off: [alive]->powering-off->[unreachable], For monitoring: alive->unreachable. Discovering and configuring are for x Series discovery process. Alive and unreachable are set only when there is a monitoring plug-in start monitor the node status for xCAT. Note that the status values will not reflect the real node status if you change the state of the node from outside of xCAT (i.e. power off the node using HMC GUI).',
status => 'The current status of this node. This attribute will be set by xCAT software. Valid values: defined, booting, netbooting, booted, discovering, configuring, installing, alive, standingby, powering-off, unreachable. If blank, defined is assumed. The possible status change sequences are: For installation: defined->[discovering]->[configuring]->[standingby]->installing->booting->[postbooting]->booted->[alive], For diskless deployment: defined->[discovering]->[configuring]->[standingby]->netbooting->[postbooting]->booted->[alive], For booting: [alive/unreachable]->booting->[postbooting]->booted->[alive], For powering off: [alive]->powering-off->[unreachable], For monitoring: alive->unreachable. Discovering and configuring are for x Series discovery process. Alive and unreachable are set only when there is a monitoring plug-in start monitor the node status for xCAT. Note that the status values will not reflect the real node status if you change the state of the node from outside of xCAT (i.e. power off the node using HMC GUI).',
statustime => "The data and time when the status was updated.",
appstatus => "A comma-delimited list of application status. For example: 'sshd=up,ftp=down,ll=down'",
appstatustime => 'The date and time when appstatus was updated.',
@@ -962,7 +962,7 @@ passed as argument rather than by table value',
dhcpserver => 'Do we set up DHCP on this service node? Not supported on AIX. Valid values:1 or 0. If 1, runs makedhcp -n. If 0, it does not change the current state of the service. ',
tftpserver => 'Do we set up TFTP on this service node? Not supported on AIX. Valid values:1 or 0. If 1, configures and starts atftp. If 0, it does not change the current state of the service. ',
nfsserver => 'Do we set up file services (HTTP,FTP,or NFS) on this service node? For AIX will only setup NFS, not HTTP or FTP. Valid values:1 or 0.If 0, it does not change the current state of the service. ',
conserver => 'Do we set up Conserver on this service node? Valid values:1 or 0. If 1, configures and starts conserver daemon. If 0, it does not change the current state of the service.',
conserver => 'Do we set up console service on this service node? Valid values: 0, 1, or 2. If 0, it does not change the current state of the service. If 1, configures and starts conserver daemon. If 2, configures and starts goconserver daemon. ',
monserver => 'Is this a monitoring event collection point? Valid values: 1 or 0. If 0, it does not change the current state of the service.',
ldapserver => 'Do we set up ldap caching proxy on this service node? Not supported on AIX. Valid values:1 or 0. If 0, it does not change the current state of the service.',
ntpserver => 'Not used. Use setupntp postscript to setup a ntp server on this service node? Valid values:1 or 0. If 0, it does not change the current state of the service.',
@@ -1057,6 +1057,7 @@ passed as argument rather than by table value',
" requests it does not know to these servers. Note that the DNS servers on the\n" .
" service nodes will ignore this value and always be configured to forward \n" .
" to the management node.\n\n" .
" emptyzonesenable: (yes or no). This is to set empty-zones-enable value in named.conf options section. \n\n" .
" master: The hostname of the xCAT management node, as known by the nodes.\n\n" .
" nameservers: A comma delimited list of DNS servers that each node in the cluster should\n" .
" use. This value will end up in the nameserver settings of the\n" .
@@ -1151,6 +1152,7 @@ passed as argument rather than by table value',
" defserialflow: The default serial flow - currently only used by the mknb command.\n\n" .
" defserialport: The default serial port - currently only used by mknb.\n\n" .
" defserialspeed: The default serial speed - currently only used by mknb.\n\n" .
" disablenodesetwarning: Allow the legacy xCAT non-osimage style nodeset to execute.\n\n" .
" genmacprefix: When generating mac addresses automatically, use this manufacturing\n" .
" prefix (e.g. 00:11:aa)\n\n" .
" genpasswords: Automatically generate random passwords for BMCs when configuring\n" .
+3 -2
View File
@@ -83,13 +83,14 @@ my %usage = (
OpenPOWER (IPMI) specific:
rvitals noderange [temp|voltage|wattage|fanspeed|power|leds|chassis|all]
OpenPOWER (OpenBMC) specific:
rvitals noderange [temp|voltage|wattage|fanspeed|power|altitude|all]
rvitals noderange [temp|voltage|wattage|fanspeed|power|leds|altitude|all]
MIC specific:
rvitals noderange {thermal|all}
pdu specific:
rvitals noderange ",
"reventlog" =>
"Usage: reventlog <noderange> [all [-s]|clear|<number of entries to retrieve> [-s]] [-V|--verbose]
reventlog <noderange> [resolved={<id list>|LED}]
reventlog [-h|--help|-v|--version]",
"rinv" =>
"Usage:
@@ -146,7 +147,7 @@ my %usage = (
rspconfig <noderange> [userid=<userid> username=<username> password=<password>]
OpenBMC specific:
rspconfig <noderange> [ipsrc|ip|netmask|gateway|hostname|vlan]
rspconfig <noderange> dump [-l|--list] [-g|--generate] [-c|--clear {<id>|all}] [-d|--download <id>]
rspconfig <noderange> dump [-l|--list] [-g|--generate] [-c|--clear {<id>|all}] [-d|--download {<id>|all}]
iDataplex specific:
rspconfig <noderange> [thermprofile]
rspconfig <noderange> [thermprofile=<two digit number from chassis>]
+2
View File
@@ -42,6 +42,8 @@ our %global_switch_type = (
Cumulus => "onie",
cumulus => "onie",
Edgecore => "onie",
sLEN => "irpdu",
sIBM => "irpdu",
coral => "crpdu"
);
+2 -2
View File
@@ -218,8 +218,8 @@ sub install_xcat{
my @cmds = ("cd ./../../xcat-core && sudo ./mklocalrepo.sh",
"sudo chmod 777 /etc/apt/sources.list",
"sudo echo \"deb [arch=amd64] http://xcat.org/files/xcat/repos/apt/xcat-dep trusty main\" >> /etc/apt/sources.list",
"sudo echo \"deb [arch=ppc64el] http://xcat.org/files/xcat/repos/apt/xcat-dep trusty main\" >> /etc/apt/sources.list",
"sudo echo \"deb [arch=amd64] http://xcat.org/files/xcat/repos/apt/devel/xcat-dep trusty main\" >> /etc/apt/sources.list",
"sudo echo \"deb [arch=ppc64el] http://xcat.org/files/xcat/repos/apt/devel/xcat-dep trusty main\" >> /etc/apt/sources.list",
"sudo wget -q -O - \"http://xcat.org/files/xcat/repos/apt/apt.key\" | sudo apt-key add -",
"sudo apt-get -qq update");
my @output;
+2 -1
View File
@@ -149,7 +149,8 @@ elif [ $USE_GOCONSERVER == "1" ]; then
CONGO_SSL_CERT=$HOME/.xcat/client-cred.pem \
CONGO_SSL_CA_CERT=$HOME/.xcat/ca.pem \
CONGO_PORT=12430 \
CONGO_CLIENT_TYPE=xcat"
CONGO_CLIENT_TYPE=xcat \
CONGO_SSL_INSECURE=true"
if [ "$CONSERVER" == `hostname` ]; then
host=`hostname -s`
if [ $? -ne 0 ]; then
+24 -1
View File
@@ -4,10 +4,15 @@ B<reventlog> - retrieve or clear remote hardware event logs
=head1 B<Synopsis>
B<reventlog> I<noderange> {I<number-of-entries> [B<-s>]|B<all [-s]>|B<clear>}
B<reventlog> I<noderange> [I<number-of-entries> [B<-s>]|B<all [-s]>|B<clear>]
B<reventlog> [B<-h>|B<--help>|B<-v>|B<--version>]
=head2 OpenPOWER OpenBMC specific :
B<reventlog> I<noderange> [B<resolved=>{I<id-list>|B<LED>}]
=head1 B<Description>
B<reventlog> can display any number of remote hardware event log entries
@@ -34,6 +39,10 @@ To sort the entries from latest (always the last entry in event DB) to oldest (a
Clear event logs.
=item B<resolved=>{I<id-list>|B<LED>}
Mark event log entries as resolved. Use comma separated list of entry ids to specify individual entries. Use B<LED> to mark as resolved all event log entries that contribute to LED fault.
=item B<-h>|B<--help>
Print help.
@@ -50,6 +59,7 @@ Print version.
=over 2
=item 1.
List last 5 event log entries from node4 and node5
reventlog node4,node5 5
@@ -67,6 +77,7 @@ Output is similar to:
node5: SERVPROC I 09/06/00 15:21:29 System spn1 started a RS485 connection with us[00]
=item 2.
Clear all event log entries from node4 and node5
reventlog node4,node5 clear
@@ -75,6 +86,18 @@ Output is similar to:
node4: clear
node5: clear
=item 3.
Mark as resolved all event log entries from node4 that contribute to LED fault
reventlog node4 resolved=LED
Output is similar to:
Attempting to resolve the following log entries: LED...
node4: Resolved 51.
node4: Resolved 52.
node4: Resolved 58.
=back
=head1 SEE ALSO
+7 -7
View File
@@ -103,19 +103,19 @@ The command will update firmware for OpenPOWER BMC when given an OpenPOWER node
B<-l|--list>:
The list option will list out available firmware on the BMC. It provides an interface to display the ID of the various firmware levels.
The list option will list out available firmware on the BMC. It provides an interface to display the ID of the various firmware levels.
The (*) symbol indicates the active running firmware on the server.
The (*) symbol indicates the active running firmware on the server.
The (+) symbol indicates the firmware that is pending and a reboot is required to set it to be the active running firmware level.
The (+) symbol indicates the firmware that is pending and a reboot is required to set it to be the active running firmware level.
B<-u|--upload>:
The upload option expects a .tar file as the input and will upload the file to the BMC. Use the list option to view the result.
The upload option expects a .tar file as the input and will upload the file to the BMC. Use the list option to view the result.
B<-a|--activate>:
The activate option expects either a .tar file or an ID as the input. If a .tar file is provided, it will upload and activate the firmware in a single step
The activate option expects either a .tar file or an ID as the input. If a .tar file is provided, it will upload and activate the firmware in a single step
To apply the firmware level, a reboot is required to BMC and HOST.
@@ -123,13 +123,13 @@ B<Note:> When using B<rflash> in hierarchical environment, the .tar file must be
B<-d>:
This option steamlines the update, activate, reboot BMC and reboot HOST procedure. It expects a directory containing both BMC and PNOR .tar files. When BMC and PNOR tar files are provided, the command will upload and activate firmware. After BMC becomes activate, it will reboot BMC. If BMC state is Ready, the command will reboot the HOST. If BMC state is NotReady, the command will exit.
This option steamlines the update, activate, reboot BMC and reboot HOST procedure. It expects a directory containing both BMC and PNOR .tar files. When BMC and PNOR tar files are provided, the command will upload and activate firmware. After BMC becomes activate, it will reboot BMC. If BMC state is Ready, the command will reboot the HOST. If BMC state is NotReady, the command will exit.
B<Note:> When using B<--no-host-reboot>, it will not reboot the host after BMC is reboot.
B<--delete>:
This delete option will delete update image from BMC. It expects an ID as the input.
This delete option will delete update image from BMC. It expects an ID as the input.
=head1 B<Options>
+2 -2
View File
@@ -26,7 +26,7 @@ B<rspconfig> I<noderange> B<garp>=I<time>
B<rspconfig> I<noderange> {B<ipsrc>|B<ip>|B<netmask>|B<gateway>|B<hostname>|B<vlan>|B<sshcfg>}
B<rspconfig> I<noderange> B<dump> [B<-l>|B<--list>] [B<-g>|B<--generate>] [B<-c>|B<--clear> {I<id>|B<all>}] [B<-d>|B<--download> I<id>]
B<rspconfig> I<noderange> B<dump> [B<-l>|B<--list>] [B<-g>|B<--generate>] [B<-c>|B<--clear> {I<id> | B<all>}] [B<-d>|B<--download> {I<id> | B<all>}]
=head2 MPA specific:
@@ -342,7 +342,7 @@ B<-l> will list all the generated dumps on the BMC.
B<-g> will generate a new dump on the BMC. Dump generation can take a few minutes.
=item
B<-d> will download a single dump from the BMC to /var/log/xcat/dump on management or service node.
B<-d> will download a single dump or all generated dumps from the BMC to /var/log/xcat/dump on management or service node.
=back
+1 -1
View File
@@ -32,7 +32,7 @@ B<rvitals> I<noderange> [B<temp>|B<voltage>|B<wattage>|B<fanspeed>|B<power>|B<le
=head2 OpenPOWER (OpenBMC) specific:
B<rvitals> I<noderange> [B<temp>|B<voltage>|B<wattage>|B<fanspeed>|B<power>|B<altitude>|B<all>]
B<rvitals> I<noderange> [B<temp>|B<voltage>|B<wattage>|B<fanspeed>|B<power>|B<leds>|B<altitude>|B<all>]
=head1 B<Description>
+63
View File
@@ -0,0 +1,63 @@
#!/bin/bash
#
# This is a dirty script for convert an xCAT-genesis-base rpm package to
# a debian package.
#
# xCAT-genesis-base-x86_64-2.13.10-snap201801090246.noarch.rpm
RPM_PACKAGE="$1"
if [ -z "${RPM_PACKAGE}" ]
then
echo "Usage: ${0##*/} /path/to/xCAT-genesis-base.rpm"
exit 0
fi
set -x
[ -n "${RPM_PACKAGE}" ] || exit 1
[ -f "${RPM_PACKAGE}" ] || exit 1
umask 0022
EXTRACT_DIR="${RPM_PACKAGE##*/}"
EXTRACT_DIR="${EXTRACT_DIR%%-snap*}"
rm -rf "${EXTRACT_DIR}"
rm -rf "${EXTRACT_DIR}.orig"
alien -d -g -c -k "${RPM_PACKAGE}" || exit 1
PACKAGE_ARCH="${EXTRACT_DIR%-*}"
PACKAGE_ARCH="${PACKAGE_ARCH##*-}"
if [[ ${EXTRACT_DIR} =~ -x86_64- ]]
then
rm -rf "${EXTRACT_DIR//x86_64/amd64}"
mv "${EXTRACT_DIR}" "${EXTRACT_DIR//x86_64/amd64}"
EXTRACT_DIR="${EXTRACT_DIR//x86_64/amd64}"
sed -i -e 's/x86-64/amd64/g' "${EXTRACT_DIR}/debian/control"
sed -i -e 's/x86-64/amd64/g' "${EXTRACT_DIR}/debian/changelog"
fi
sed -i -e "/^Description:/i Breaks: xcat-genesis-scripts-${PACKAGE_ARCH//x86_64/amd64} (<< 2.13.10)" "${EXTRACT_DIR}/debian/control"
cat >"${EXTRACT_DIR}/debian/preinst" <<EOF
#!/bin/bash
[ -d /opt/xcat/share/xcat/netboot/genesis/${PACKAGE_ARCH}/fs/bin ] &&
rm -rf /opt/xcat/share/xcat/netboot/genesis/${PACKAGE_ARCH}/fs/bin
[ -d /opt/xcat/share/xcat/netboot/genesis/${PACKAGE_ARCH}/fs/sbin ] &&
rm -rf /opt/xcat/share/xcat/netboot/genesis/${PACKAGE_ARCH}/fs/sbin
[ -d /opt/xcat/share/xcat/netboot/genesis/${PACKAGE_ARCH}/fs/lib ] &&
rm -rf /opt/xcat/share/xcat/netboot/genesis/${PACKAGE_ARCH}/fs/lib
[ -d /opt/xcat/share/xcat/netboot/genesis/${PACKAGE_ARCH}/fs/lib64 ] &&
rm -rf /opt/xcat/share/xcat/netboot/genesis/${PACKAGE_ARCH}/fs/lib64
[ -d /opt/xcat/share/xcat/netboot/genesis/${PACKAGE_ARCH}/fs/var/run ] &&
rm -rf /opt/xcat/share/xcat/netboot/genesis/${PACKAGE_ARCH}/fs/var/run
exit 0
EOF
chmod 0755 "${EXTRACT_DIR}/debian/preinst"
( cd "${EXTRACT_DIR}" && debian/rules binary )
-1
View File
@@ -473,7 +473,6 @@ dracut_install /usr/share/zoneinfo/posix/Asia/Phnom_Penh
dracut_install /usr/share/zoneinfo/posix/Asia/Ulan_Bator
dracut_install /usr/share/zoneinfo/posix/Asia/Sakhalin
dracut_install /usr/share/zoneinfo/posix/MST7MDT
dracut_install /usr/share/zoneinfo/posix/Canada/East-Saskatchewan
dracut_install /usr/share/zoneinfo/posix/Canada/Atlantic
dracut_install /usr/share/zoneinfo/posix/Canada/Central
dracut_install /usr/share/zoneinfo/posix/Canada/Eastern
-1
View File
@@ -498,7 +498,6 @@ dracut_install /usr/share/zoneinfo/posix/Asia/Phnom_Penh
dracut_install /usr/share/zoneinfo/posix/Asia/Ulan_Bator
dracut_install /usr/share/zoneinfo/posix/Asia/Sakhalin
dracut_install /usr/share/zoneinfo/posix/MST7MDT
dracut_install /usr/share/zoneinfo/posix/Canada/East-Saskatchewan
dracut_install /usr/share/zoneinfo/posix/Canada/Atlantic
dracut_install /usr/share/zoneinfo/posix/Canada/Central
dracut_install /usr/share/zoneinfo/posix/Canada/Eastern
+1 -1
View File
@@ -29,7 +29,7 @@ Vendor: IBM Corp.
Summary: xCAT Genesis netboot image
URL: https://xcat.org/
Source1: xCAT-genesis-base-%{tarch}.tar.bz2
Conflicts: xCAT-genesis-scripts-%{tarch} < 1:2.13.9
Conflicts: xCAT-genesis-scripts-%{tarch} < 1:2.13.10
Buildroot: %{_localstatedir}/tmp/xCAT-genesis
BuildRequires: /usr/sbin/ntp-wait
@@ -33,7 +33,8 @@ rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/xcat/netboot/genesis/builder
cd $RPM_BUILD_ROOT/%{prefix}/share/xcat/netboot/genesis/builder
tar jxvf %{SOURCE1}
chmod +x $RPM_BUILD_ROOT/%{prefix}/share/xcat/netboot/genesis/builder/buildrpm
chmod 0755 $RPM_BUILD_ROOT/%{prefix}/share/xcat/netboot/genesis/builder/buildrpm
chmod 0755 $RPM_BUILD_ROOT/%{prefix}/share/xcat/netboot/genesis/builder/debuild-xcat-genesis-base
cd -
+18 -19
View File
@@ -1,3 +1,4 @@
#!/bin/bash
root=1
rootok=1
netroot=xcat
@@ -8,11 +9,13 @@ mkdir -p /etc/ssh
mkdir -p /var/tmp/
mkdir -p /var/empty/sshd
sed -i '/^root:x/d' /etc/passwd
echo root:x:0:0::/:/bin/bash >> /etc/passwd
echo sshd:x:30:30:SSH User:/var/empty/sshd:/sbin/nologin >> /etc/passwd
echo rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin >> /etc/passwd
echo rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin >> /etc/passwd
echo qemu:x:107:107:qemu user:/:/sbin/nologin >> /etc/passwd
cat >>/etc/passwd <<"__ENDL"
root:x:0:0::/:/bin/bash
sshd:x:30:30:SSH User:/var/empty/sshd:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
qemu:x:107:107:qemu user:/:/sbin/nologin
__ENDL
# Fedora 20 ppc64 uses /lib/dracut/hooks/initqueue/finished
# CentOS 7 probably uses /lib/dracut/hooks/initqueue/finished also
if [ -d "/initqueue-finished" ]; then
@@ -35,34 +38,30 @@ mkdir -p /var/lib/dhclient/
mkdir -p /var/log
ip link set lo up
echo '127.0.0.1 localhost' >> /etc/hosts
if grep console=ttyS /proc/cmdline > /dev/null; then
while :; do sleep 1; screen -x console < /dev/tty1 > /dev/tty1 2>&1; clear; done &
if grep -q console=ttyS /proc/cmdline; then
while :; do sleep 1; screen -S console -ln screen -x doxcat </dev/tty1 &>/dev/tty1; clear &>/dev/tty1 ; done &
fi
while :; do screen -ln < /dev/tty2 > /dev/tty2 2>&1; done &
while :; do screen -ln < /dev/tty2 &> /dev/tty2 ; done &
# The section below is just for System P LE hardware discovery
# Need to wait for NIC initialization
sleep 20
ARCH=`uname -m`
#For Openpower
if [ $ARCH = "ppc64le" ]; then
ARCH="ppc64"
fi
ARCH="$(uname -m)"
if [ $ARCH == 'ppc64' ]; then
if [[ ${ARCH} =~ ppc64 ]]; then
waittime=2
ALL_NICS=`ip link show | grep -v "^ " | awk '{print $2}' | sed -e 's/:$//' | grep -v lo`
ALL_NICS=$(ip link show | grep -v "^ " | awk '{print $2}' | sed -e 's/:$//' | grep -v lo)
for tmp in $ALL_NICS; do
tmp_data=`ip link show $tmp | grep -v "^ " | grep "UP"`
tmp_data="$(ip link show "$tmp" | grep -v "^ " | grep "UP")"
if [ "$tmp_data" == "" ]; then
ip link set $tmp up
ip link set "$tmp" up
fi
tmp_data="UP"
waittime=$(($waittime+1))
waittime=$((waittime+1))
done
# wait 2+number_of_nics seconds for all the LINKed NICs to be UP
sleep $waittime
fi
while :; do screen -L -ln doxcat; done
while :; do screen -dr doxcat || screen -S doxcat -L -ln doxcat; done
+1 -1
View File
@@ -7,7 +7,7 @@ Standards-Version: 3.9.4
Package: xcat-genesis-scripts-amd64
Architecture: all
Depends: xcat-genesis-base-amd64 (>=2.13.2)
Depends: xcat-genesis-base-amd64 (>= 2.13.10)
Conflicts: xcat-genesis-scripts, xcat-genesis-scripts-x86-64
Replaces: xcat-genesis-scripts, xcat-genesis-scripts-x86-64
Description: xCAT genesis
+1 -1
View File
@@ -7,7 +7,7 @@ Standards-Version: 3.9.4
Package: xcat-genesis-scripts-ppc64
Architecture: all
Depends: xcat-genesis-base-ppc64 (>=2.13.2)
Depends: xcat-genesis-base-ppc64 (>= 2.13.10)
Conflicts: xcat-genesis-scripts
Replaces: xcat-genesis-scripts
Description: xCAT genesis
+1 -2
View File
@@ -33,8 +33,7 @@ install:
dh_installdirs $(installdir)
dh_install -X".svn"
dh_install ./etc/ $(installtodir)
dh_install ./bin/ $(installtodir)
dh_install ./sbin/ $(installtodir)
dh_install ./usr/ $(installtodir)
dh_compress
dh_installdeb
dh_gencontrol
@@ -482,7 +482,12 @@ for user in $BMCUS; do
TRIES=0
# Enable the channel link for the specified user
while ! ipmitool -d $idev channel setaccess $LANCHAN $USERSLOT link=on; do
if [ "$IPMIMFG" == 343 -a "$XPROD" == 124 ]; then # For Intel S2600BP system boards
cmd="ipmitool -d $idev channel setaccess $LANCHAN $USERSLOT link=on ipmi=on"
else
cmd="ipmitool -d $idev channel setaccess $LANCHAN $USERSLOT link=on"
fi
while ! eval $cmd; do
sleep 1
let TRIES=TRIES+1
if [ $TRIES -gt $TIMEOUT ]; then break; fi
+26 -26
View File
@@ -29,7 +29,7 @@ Vendor: IBM Corp.
Summary: xCAT Genesis netboot image - Core content
URL: https://xcat.org/
Source1: xCAT-genesis-scripts.tar.bz2
Requires: xCAT-genesis-base-%{tarch} >= 2:2.13.2
Requires: xCAT-genesis-base-%{tarch} >= 2:2.13.10
Buildroot: %{_localstatedir}/tmp/xCAT-genesis
Packager: IBM Corp.
@@ -71,32 +71,32 @@ touch /etc/xcat/genesis-scripts-updated
%Files
%defattr(-,root,root)
#%dir %attr(-,root,root) %{rpminstallroot}
%{rpminstallroot}/bin/allowcred.awk
%{rpminstallroot}/bin/bmcsetup
%{rpminstallroot}/bin/raidcmd
%{rpminstallroot}/bin/raidutils
%{rpminstallroot}/bin/diskdiscover
%{rpminstallroot}/bin/configraid
%{rpminstallroot}/bin/dodiscovery
%{rpminstallroot}/bin/dosysclone
%{rpminstallroot}/bin/doxcat
%{rpminstallroot}/bin/getadapter
%{rpminstallroot}/bin/getcert
%{rpminstallroot}/bin/getdestiny
%{rpminstallroot}/bin/getipmi
%{rpminstallroot}/bin/ifup
%{rpminstallroot}/bin/minixcatd.awk
%{rpminstallroot}/bin/nextdestiny
%{rpminstallroot}/bin/remoteimmsetup
%{rpminstallroot}/bin/udpcat.awk
%{rpminstallroot}/bin/updateflag.awk
%{rpminstallroot}/bin/pseries_platform
%{rpminstallroot}/bin/update_flash
%{rpminstallroot}/bin/update_flash_nv
%{rpminstallroot}/bin/restart
%{rpminstallroot}/usr/bin/allowcred.awk
%{rpminstallroot}/usr/bin/bmcsetup
%{rpminstallroot}/usr/bin/raidcmd
%{rpminstallroot}/usr/bin/raidutils
%{rpminstallroot}/usr/bin/diskdiscover
%{rpminstallroot}/usr/bin/configraid
%{rpminstallroot}/usr/bin/dodiscovery
%{rpminstallroot}/usr/bin/dosysclone
%{rpminstallroot}/usr/bin/doxcat
%{rpminstallroot}/usr/bin/getadapter
%{rpminstallroot}/usr/bin/getcert
%{rpminstallroot}/usr/bin/getdestiny
%{rpminstallroot}/usr/bin/getipmi
%{rpminstallroot}/usr/bin/ifup
%{rpminstallroot}/usr/bin/minixcatd.awk
%{rpminstallroot}/usr/bin/nextdestiny
%{rpminstallroot}/usr/bin/remoteimmsetup
%{rpminstallroot}/usr/bin/udpcat.awk
%{rpminstallroot}/usr/bin/updateflag.awk
%{rpminstallroot}/usr/bin/pseries_platform
%{rpminstallroot}/usr/bin/update_flash
%{rpminstallroot}/usr/bin/update_flash_nv
%{rpminstallroot}/usr/bin/restart
%{rpminstallroot}/etc/init.d/functions
%{rpminstallroot}/etc/udev/rules.d/99-imm.rules
%{rpminstallroot}/etc/udev/rules.d/98-mlx.rules
%{rpminstallroot}/sbin/setupimmnic
%{rpminstallroot}/sbin/loadmlxeth
%{rpminstallroot}/usr/sbin/setupimmnic
%{rpminstallroot}/usr/sbin/loadmlxeth
%exclude %{rpminstallroot}/debian/*
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from __future__ import print_function
import argparse
import sys
from xcatagent import server
class AgentShell(object):
def get_base_parser(self):
parser = argparse.ArgumentParser(
prog='xcatagent',
add_help=False,
formatter_class=HelpFormatter,
)
parser.add_argument('-h', '--help',
action='store_true',
help=argparse.SUPPRESS,
)
parser.add_argument('--standalone',
help="Start xcat agent as a standalone service, "
"mostly work for test purpose. ",
action='store_true')
parser.add_argument('--sock',
help="The unix domain sock file to communicate "
"with the client",
default='/var/run/xcat/agent.sock',
type=str)
return parser
def do_help(self, args):
self.parser.print_help()
def main(self, argv):
self.parser = self.get_base_parser()
(options, args) = self.parser.parse_known_args(argv)
if options.help:
self.do_help(options)
return 0
s = server.Server(options.sock, options.standalone)
s.start()
class HelpFormatter(argparse.HelpFormatter):
def start_section(self, heading):
# Title-case the headings
heading = '%s%s' % (heading[0].upper(), heading[1:])
super(HelpFormatter, self).start_section(heading)
if __name__ == '__main__':
AgentShell().main(sys.argv[1:])
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# just for test
from __future__ import print_function
import argparse
import json
import os
import socket
import sys
from xcatagent import utils
class ClientShell(object):
def get_base_parser(self):
parser = argparse.ArgumentParser(
prog='agentclient',
add_help=False,
formatter_class=HelpFormatter,
)
parser.add_argument('-h', '--help',
action='store_true',
help=argparse.SUPPRESS,
)
parser.add_argument('--sock',
help="The unix domain sock file to communicate "
"with the server",
default='/var/run/xcat/agent.sock',
type=str)
return parser
def do_help(self, args):
self.parser.print_help()
def main(self, argv):
self.parser = self.get_base_parser()
(options, args) = self.parser.parse_known_args(argv)
if options.help:
self.do_help(options)
return 0
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
nodes = ['node1', 'node2']
nodeinfo = {'node1':{'bmc':'10.0.0.1', 'bmcip':'10.0.0.1', 'username':'root', 'password': 'xxxxxx'},
'node2':{'bmc':'10.0.0.2', 'bmcip':'10.0.0.2', 'username':'root', 'password': 'xxxxxx'}}
s.connect(options.sock)
req = {'module': 'openbmc',
'command': 'rpower',
'args': ['state'],
'cwd': os.getcwd(),
'nodes': nodes,
'nodeinfo': nodeinfo,
'envs': {'debugmode': 1}}
buf = json.dumps(req)
s.send(utils.int2bytes(len(buf)))
s.send(buf)
while True:
sz = s.recv(4)
if len(sz) == 0:
break
sz = utils.bytes2int(sz)
data = s.recv(sz)
print(data)
class HelpFormatter(argparse.HelpFormatter):
def start_section(self, heading):
# Title-case the headings
heading = '%s%s' % (heading[0].upper(), heading[1:])
super(HelpFormatter, self).start_section(heading)
if __name__ == '__main__':
ClientShell().main(sys.argv[1:])
@@ -0,0 +1,2 @@
from gevent import monkey
monkey.patch_all(thread=False)
@@ -0,0 +1,47 @@
from xcatagent import utils
import gevent
from gevent.pool import Pool
MODULE_MAP = {"openbmc": "OpenBMCManager"}
class BaseManager(object):
def __init__(self, messager, cwd):
self.messager = messager
self.cwd = cwd
@classmethod
def get_manager_func(self, name):
module_name = 'xcatagent.%s' % name
try:
__import__(module_name)
except ImportError:
return None
class_name = MODULE_MAP[name]
return utils.class_func(module_name, class_name)
def process_nodes_worker(self, name, classname, nodes, nodeinfo, command, args):
module_name = 'xcatagent.%s' % name
obj_func = utils.class_func(module_name, classname)
gevent_pool = Pool(1000)
for node in nodes:
obj = obj_func(self.messager, node, nodeinfo[node])
if not hasattr(obj, command):
self.messager.error('%s: command %s is not supported for %s' % (node, command, classname))
func = getattr(obj, command)
try:
gevent_pool.add( gevent.spawn(func, args) )
except Exception:
error = '%s: Internel Error occured in gevent' % node
self.messager.error(error)
gevent_pool.join()
class BaseDriver(object):
def __init__(self, messager):
self.messager = messager
@@ -0,0 +1,812 @@
from xcatagent import base
import os
import time
import sys
import gevent
import utils
import xcat_exception
import openbmc_rest
HTTP_PROTOCOL = "https://"
PROJECT_URL = "/xyz/openbmc_project"
RESULT_OK = 'ok'
RESULT_FAIL = 'fail'
DEBUGMODE = False
VERBOSE = False
all_nodes_result = {}
# global variables of rflash
RFLASH_OPTIONS = {
"-a" : "activate",
"--activate" : "activate",
"-c" : "check",
"--check" : "check",
"-d" : "direcory",
"--delete" : "delete",
"-l" : "list",
"--list" : "list",
"-u" : "upload",
"--upload" : "upload",
}
RFLASH_URLS = {
"activate" : {
"url" : PROJECT_URL + "/software/#ACTIVATE_ID#/attr/RequestedActivation",
"field" : "xyz.openbmc_project.Software.Activation.RequestedActivations.Active",
},
"delete" : {
"url" : PROJECT_URL + "/software/#DELETE_ID#/action/Delete",
"field" : [],
},
"upload" : {
"url" : "/upload/image/",
},
"priority" : {
"url" : PROJECT_URL + "/software/#PRIORITY_ID#/attr/Priority",
"field" : False,
}
}
XCAT_LOG_DIR = "/var/log/xcat"
XCAT_LOG_RFLASH_DIR = XCAT_LOG_DIR + "/rflash/"
# global variable of firmware information
FIRM_URL = PROJECT_URL + "/software/enumerate"
# global variables of rpower
POWER_SET_OPTIONS = ('on', 'off', 'bmcreboot', 'softoff')
POWER_GET_OPTIONS = ('bmcstate', 'state', 'stat', 'status')
RPOWER_URLS = {
"on" : {
"url" : PROJECT_URL + "/state/host0/attr/RequestedHostTransition",
"field" : "xyz.openbmc_project.State.Host.Transition.On",
},
"off" : {
"url" : PROJECT_URL + "/state/chassis0/attr/RequestedPowerTransition",
"field" : "xyz.openbmc_project.State.Chassis.Transition.Off",
},
"softoff" : {
"url" : PROJECT_URL + "/state/host0/attr/RequestedHostTransition",
"field" : "xyz.openbmc_project.State.Host.Transition.Off",
},
"bmcreboot" : {
"url" : PROJECT_URL + "/state/bmc0/attr/RequestedBMCTransition",
"field" : "xyz.openbmc_project.State.BMC.Transition.Reboot",
},
"state" : {
"url" : PROJECT_URL + "/state/enumerate",
},
}
RPOWER_STATE = {
"on" : "on",
"off" : "off",
"Off" : "off",
"softoff" : "softoff",
"boot" : "reset",
"reset" : "reset",
"bmcreboot" : "BMC reboot",
"Ready" : "BMC Ready",
"NotReady" : "BMC NotReady",
"chassison" : "on (Chassis)",
"Running" : "on",
"Quiesced" : "quiesced",
}
POWER_STATE_DB = {
"on" : "powering-on",
"off" : "powering-off",
"softoff" : "powering-off",
"boot" : "powering-on",
"reset" : "powering-on",
}
class OpenBMC(base.BaseDriver):
headers = {'Content-Type': 'application/json'}
def __init__(self, messager, name, node_info):
super(OpenBMC, self).__init__(messager)
self.node = name
for key, value in node_info.items():
setattr(self, key, value)
global DEBUGMODE
self.client = openbmc_rest.OpenBMCRest(name, messager, DEBUGMODE)
def _login(self):
""" Login
:raise: error message if failed
"""
url = HTTP_PROTOCOL + self.bmcip + '/login'
data = { "data": [ self.username, self.password ] }
self.client.request('POST', url, OpenBMC.headers, data, 'login')
return RESULT_OK
def _msg_process_rflash (self, msg, update_dict, checkv):
"""deal with msg during rflash
:param msg: the msg want to process
"""
if not checkv:
self.messager.info('%s: %s' % (self.node, msg))
elif VERBOSE:
self.messager.info('%s: %s' % (self.node, msg))
self.rflash_log_handle.writelines(msg + '\n')
self.rflash_log_handle.flush()
if update_dict:
utils.update2Ddict(update_dict, self.node, 'result', [msg])
def _firm_info(self, status):
"""List firmware information including additional
called by rflash check and rinv firm
:returns: firmware information
"""
firm_output = []
try:
(has_functional, firm_info) = self._get_firm_info(status)
except (xcat_exception.SelfServerException,
xcat_exception.SelfClientException) as e:
firm_output.append(e.message)
return firm_output
keys = firm_info.keys()
keys.sort()
for key in keys:
flag = ''
if 'is_functional' in firm_info[key]:
flag = '*'
elif ('Priority' in firm_info[key] and
firm_info[key]['Priority'] == '0'):
if not has_functional:
flag = '*'
else:
flag = '+'
if not flag and not VERBOSE:
continue
firm_output.append('%s Firmware Product: %s (%s)%s' %
(firm_info[key]['Purpose'],
firm_info[key]['Version'],
firm_info[key]['Activation'], flag))
if 'ExtendedVersion' in firm_info[key]:
extendeds = firm_info[key]['ExtendedVersion'].split(',')
extendeds.sort()
for extended in extendeds:
firm_output.append('%s Firmware Product: ' \
'-- additional info: %s' % \
(firm_info[key]['Purpose'], extended))
return firm_output
def _get_firm_info(self, status):
"""get firmware information
:param status: current status
:returns: firmware version information
"""
firm_info = {}
has_functional = False
url = HTTP_PROTOCOL + self.bmcip + FIRM_URL
response = self.client.request('GET', url, OpenBMC.headers, '', status)
functional_url = PROJECT_URL + '/software/functional'
for key in response['data']:
key_id = key.split('/')[-1]
if key_id == 'functional':
for endpoint in response['data'][key]['endpoints']:
purpose = response['data'][endpoint]['Purpose'].split('.')[-1]
key_sort = purpose + '-' + endpoint.split('/')[-1]
utils.update2Ddict(firm_info, key_sort, 'is_functional', True)
has_functional = True
if 'Version' in response['data'][key]:
purpose = response['data'][key]['Purpose'].split('.')[-1]
key_sort = purpose + '-' + key_id
if (functional_url in response['data'] and
key in response['data'][functional_url]['endpoints']):
utils.update2Ddict(firm_info, key_sort, 'is_functional', True)
utils.update2Ddict(firm_info, key_sort, 'Version',
response['data'][key]['Version'])
utils.update2Ddict(firm_info, key_sort, 'Purpose', purpose)
utils.update2Ddict(firm_info, key_sort, 'Activation',
response['data'][key]['Activation'].split('.')[-1])
if 'Priority' in response['data'][key]:
utils.update2Ddict(firm_info, key_sort, 'Priority',
str(response['data'][key]['Priority']))
if 'ExtendedVersion' in response['data'][key]:
utils.update2Ddict(firm_info, key_sort, 'ExtendedVersion',
response['data'][key]['ExtendedVersion'])
if 'Progress' in response['data'][key]:
utils.update2Ddict(firm_info, key_sort, 'Progress',
response['data'][key]['Progress'])
return (has_functional, firm_info)
def _get_firm_id(self, firm_list):
"""get firmware id
:param firm_list: the list of firmware versions
:return: result and info list
"""
firm_ids = []
url = HTTP_PROTOCOL + self.bmcip + FIRM_URL
for i in range(6):
try:
response = self.client.request('GET', url, OpenBMC.headers,
'', 'rflash_check_id')
except (xcat_exception.SelfServerException,
xcat_exception.SelfClientException) as e:
self._msg_process_rflash(e.message, all_nodes_result, False)
return (RESULT_FAIL, [])
for key in response['data']:
if 'Version' in response['data'][key]:
if response['data'][key]['Version'] in firm_list:
firm_id = key.split('/')[-1]
upload_msg = 'Firmware upload successful. ' \
'Attempting to activate firmware: ' \
'%s (ID: %s)' % \
(response['data'][key]['Version'], firm_id)
self._msg_process_rflash(upload_msg, {}, False)
firm_ids.append(firm_id)
firm_list.remove(response['data'][key]['Version'])
if firm_list:
for firm_ver in firm_list:
retry_msg = 'Could not find ID for firmware %s to '\
'activate, waiting %d seconds and retry...' \
% (firm_ver, 10)
self._msg_process_rflash(upload_msg, {}, True)
gevent.sleep( 10 )
else:
break
if firm_list:
for firm_ver in firm_list:
error = 'Could not find firmware %s after waiting %d seconds.' \
% (firm_ver, 10*6)
self._msg_process_rflash(upload_msg, {}, False)
error_list.append(error)
utils.update2Ddict(all_nodes_result, self.node, 'result', error_list)
return (RESULT_FAIL, [])
return (RESULT_OK, firm_ids)
def _check_id_status(self, firm_id_list):
"""check firm id status
:param firm_id_list: list of firm ids want to check
:return: result
"""
result = RESULT_OK
set_priority_ids = []
process_status = {}
failed_msg = []
for i in range(80):
try:
(has_functional, firm_info) = self._get_firm_info('rflash_check_status')
except (xcat_exception.SelfServerException,
xcat_exception.SelfClientException) as e:
self._msg_process_rflash(e.message, all_nodes_result, False)
return (RESULT_FAIL, set_priority_ids)
activation_num = 0
for key in firm_info:
firm_id = key.split('-')[-1]
if firm_id in firm_id_list:
activation_state = firm_info[key]['Activation']
firm_version = firm_info[key]['Version']
if activation_state == 'Failed':
activation_msg = 'Firmware %s activation failed.' % (firm_version)
self._msg_process_rflash(activation_msg, {}, False)
failed_msg.append(activation_msg)
result = RESULT_FAIL
firm_id_list.rempove(firm_id)
if activation_state == 'Active':
activation_msg = 'Firmware %s activation successful.' % (firm_version)
self._msg_process_rflash(activation_msg, {}, False)
firm_id_list.remove(firm_id)
priority = firm_info[key]['Priority']
if priority != '0':
set_priority_ids.append(firm_id)
if activation_state == 'Activating':
activating_progress_msg = 'Activating %s ... %s%%' \
% (firm_version, firm_info[key]['Progress'])
self._msg_process_rflash(activating_progress_msg, {}, True)
process_status[firm_id] = activating_progress_msg
if not firm_id_list:
break
gevent.sleep( 15 )
if firm_id_list:
result = RESULT_FAIL
for firm_id in firm_id_list:
if firm_id in process_status:
failed_msg.append('After %d seconds check the current status is %s' \
% (80*15, process_status[firm_id]))
if failed_msg:
utils.update2Ddict(all_nodes_result, self.node, 'result', [failed_msg])
return (result, set_priority_ids)
def _set_priority(self, priority_ids):
"""set firmware priority to 0
:param priority_ids: list of firmware ids
:return ok if success
:return error msg if failed
"""
for priority_id in priority_ids:
url = (HTTP_PROTOCOL + self.bmcip +
RFLASH_URLS['priority']['url'].replace('#PRIORITY_ID#', priority_id))
data = { "data": RFLASH_URLS['priority']['field'] }
try:
response = self.client.request('PUT', url, OpenBMC.headers,
data, 'rflash_set_priority')
except (xcat_exception.SelfServerException,
xcat_exception.SelfClientException) as e:
return e.message
return RESULT_OK
def _rflash_activate_id(self, activate_id):
"""rflash activate id
:param activate_id: the id want to activate
:raise: error message if failed
"""
url = (HTTP_PROTOCOL + self.bmcip +
RFLASH_URLS['activate']['url'].replace('#ACTIVATE_ID#', activate_id))
data = { "data": RFLASH_URLS['activate']['field'] }
try:
response = self.client.request('PUT', url, OpenBMC.headers,
data, 'rflash_activate')
except xcat_exception.SelfServerException as e:
return e.message
except xcat_exception.SelfClientException as e:
code = e.code
if code == 403:
return 'Error: Invalid ID provided to activate. ' \
'Use the -l option to view valid firmware IDs.'
return e.message
return RESULT_OK
def _rflash_activate(self, activate_arg):
"""ACTIVATE firmware
called by rflash activate
:param activate_arg: firmware tar ball or firmware id
:return: ok if success
:raise: error message if failed
"""
activate_id = activate_version = ''
if 'activate_id' in activate_arg:
activate_id = activate_arg['activate_id']
if 'update_file' in activate_arg:
result = self._rflash_upload(activate_arg['update_file'])
if result != RESULT_OK:
self._msg_process_rflash(result, all_nodes_result, False)
return
activate_version = activate_arg['activate_version']
(result, info) = self._get_firm_id([activate_version])
if result == RESULT_OK:
activate_id = info.pop(0)
else:
return
result = self._rflash_activate_id(activate_id)
if result != RESULT_OK:
self._msg_process_rflash(result, all_nodes_result, False)
return
else:
flash_started_msg = 'rflash %s started, please wait...' % activate_version
self._msg_process_rflash(flash_started_msg, {}, False)
firm_id_list = [activate_id]
(result, priority_ids) = self._check_id_status(firm_id_list)
if result == RESULT_OK:
utils.update2Ddict(all_nodes_result, self.node, 'result', 'OK')
if priority_ids:
self._set_priority(priority_ids)
def _rflash_delete(self, delete_id):
"""Delete firmware on OpenBMC
called by rflash delete
:param delete_id: firmware id want to delete
:returns: ok if success
:raise: error message if failed
"""
url = (HTTP_PROTOCOL + self.bmcip +
RFLASH_URLS['delete']['url'].replace('#DELETE_ID#', delete_id))
data = { "data": RFLASH_URLS['delete']['field'] }
try:
response = self.client.request('POST', url, OpenBMC.headers,
data, 'rflash_delete')
except xcat_exception.SelfServerException as e:
return e.message
except xcat_exception.SelfClientException as e:
code = e.code
if code == 404:
return 'Error: Invalid ID provided to delete. ' \
'Use the -l option to view valid firmware IDs.'
return e.message
return RESULT_OK
def _rflash_list(self):
"""List firmware information
called by rflash list
:returns: firmware version if success
:raise: error message if failed
"""
firm_output = []
try:
(has_functional, firm_info) = self._get_firm_info('rflash_list')
except (xcat_exception.SelfServerException,
xcat_exception.SelfClientException) as e:
firm_output.append(e.message)
return firm_output
firm_output.append('%-8s %-7s %-10s %-s' % ('ID', 'Purpose', 'State', 'Version'))
firm_output.append('-' * 55)
for key in firm_info:
status = firm_info[key]['Activation']
if 'is_functional' in firm_info[key]:
status += '(*)'
elif 'Priority' in firm_info[key] and firm_info[key]['Priority'] == '0':
if not has_functional:
status += '(*)'
else:
status += '(+)'
firm_output.append('%-8s %-7s %-10s %-s' % (key.split('-')[-1],
firm_info[key]['Purpose'], status, firm_info[key]['Version']))
return firm_output
def _rflash_upload(self, upload_file):
""" Upload *.tar file to OpenBMC server
:param upload_file: file to upload
"""
url = HTTP_PROTOCOL + self.bmcip + RFLASH_URLS['upload']['url']
headers = {'Content-Type': 'application/octet-stream'}
uploading_msg = 'Uploading %s ...' % upload_file
self._msg_process_rflash(uploading_msg, {}, True)
try:
self.client.request_upload('PUT', url, headers,
upload_file, 'rflash_upload')
except (xcat_exception.SelfServerException,
xcat_exception.SelfClientException) as e:
result = e.message
return result
return RESULT_OK
def _set_power_onoff(self, subcommand):
""" Set power on/off/softoff/bmcreboot
:param subcommand: subcommand for rpower
:returns: ok if success
:raise: error message if failed
"""
url = HTTP_PROTOCOL + self.bmcip + RPOWER_URLS[subcommand]['url']
data = { "data": RPOWER_URLS[subcommand]['field'] }
try:
response = self.client.request('PUT', url, OpenBMC.headers,
data, 'rpower_' + subcommand)
except (xcat_exception.SelfServerException,
xcat_exception.SelfClientException) as e:
if subcommand != 'bmcreboot':
result = e.message
return result
return RESULT_OK
def _get_power_state(self, subcommand):
""" Get power current state
:param subcommand: state/stat/status/bmcstate
:returns: current state if success
:raise: error message if failed
"""
result = ''
bmc_not_ready = 'NotReady'
url = HTTP_PROTOCOL + self.bmcip + RPOWER_URLS['state']['url']
try:
response = self.client.request('GET', url, OpenBMC.headers,
'', 'rpower_' + subcommand)
except xcat_exception.SelfServerException, e:
if subcommand == 'bmcstate':
result = bmc_not_ready
else:
result = e.message
except xcat_exception.SelfClientException, e:
result = e.message
if result:
return result
for key in response['data']:
key_type = key.split('/')[-1]
if key_type == 'bmc0':
bmc_current_state = response['data'][key]['CurrentBMCState'].split('.')[-1]
if key_type == 'chassis0':
chassis_current_state = response['data'][key]['CurrentPowerState'].split('.')[-1]
if key_type == 'host0':
host_current_state = response['data'][key]['CurrentHostState'].split('.')[-1]
if subcommand == 'bmcstate':
if bmc_current_state == 'Ready':
return bmc_current_state
else:
return bmc_not_ready
if chassis_current_state == 'Off':
return chassis_current_state
elif chassis_current_state == 'On':
if host_current_state == 'Off':
return 'chassison'
elif host_current_state == 'Quiesced':
return host_current_state
elif host_current_state == 'Running':
return host_current_state
else:
return 'Unexpected chassis state=' + host_current_state
else:
return 'Unexpected chassis state=' + chassis_current_state
def _rpower_boot(self):
"""Power boot
:returns: 'reset' if success
:raise: error message if failed
"""
result = self._set_power_onoff('off')
if result != RESULT_OK:
return result
self.messager.update_node_attributes('status', self.node, POWER_STATE_DB['off'])
start_timeStamp = int(time.time())
for i in range (0,30):
status = self._get_power_state('state')
if status in RPOWER_STATE and RPOWER_STATE[status] == 'off':
break
gevent.sleep( 2 )
end_timeStamp = int(time.time())
if status not in RPOWER_STATE or RPOWER_STATE[status] != 'off':
wait_time = str(end_timeStamp - start_timeStamp)
result = 'Error: Sent power-off command but state did not change ' \
'to off after waiting %s seconds. (State= %s).' % (wait_time, status)
return result
result = self._set_power_onoff('on')
return result
def rflash(self, args):
"""handle rflash command
:param args: subcommands and parameters for rflash
"""
subcommand = args[0]
if subcommand == 'activate' or subcommand == 'upload':
self.rflash_log_file = XCAT_LOG_RFLASH_DIR + '/' + self.node + '.log'
self.rflash_log_handle = open(self.rflash_log_file, 'a')
try:
result = self._login()
except (xcat_exception.SelfServerException,
xcat_exception.SelfClientException) as e:
result = e.message
if result != RESULT_OK:
self.messager.info('%s: %s'% (self.node,result))
if subcommand == 'activate' or subcommand == 'upload':
self.rflash_log_handle.writelines(result + '\n')
self.rflash_log_handle.flush()
if subcommand == 'activate':
utils.update2Ddict(all_nodes_result, self.node, 'result', [result])
return
if subcommand == 'activate':
activate_arg = args[1]
self._rflash_activate(activate_arg)
if subcommand == 'check':
firm_info = self._firm_info('rflash_check')
for i in firm_info:
result = '%s: %s' % (self.node, i)
self.messager.info(result)
if subcommand == 'delete':
firmware_id = args[1]
result = self._rflash_delete(firmware_id)
if result == RESULT_OK:
result = '%s: [%s] Firmware removed' % (self.node, firmware_id)
self.messager.info(result)
else:
result = '%s: %s' % (self.node, result)
self.messager.info(result)
if subcommand == 'list':
firm_info = self._rflash_list()
for i in firm_info:
result = '%s: %s' % (self.node, i)
self.messager.info(result)
if subcommand == 'upload':
upload_file = args[1]
result = self._rflash_upload(upload_file)
if result == RESULT_OK:
result = 'Firmware upload successful. Use -l option to list.'
self._msg_process_rflash(result, {}, False)
else:
self._msg_process_rflash(result, {}, False)
if subcommand == 'activate' or subcommand == 'upload':
self.rflash_log_handle.close()
def rpower(self, args):
"""handle rpower command
:param args: subcommands for rpower
"""
subcommand = args[0]
try:
result = self._login()
except xcat_exception.SelfServerException as e:
if subcommand == 'bmcstate':
result = '%s: %s' % (self.node, RPOWER_STATE['NotReady'])
else:
result = '%s: %s' % (self.node, e.message)
except xcat_exception.SelfClientException as e:
result = '%s: %s' % (self.node, e.message)
if result != RESULT_OK:
self.messager.info(result)
return
new_status = ''
if subcommand in POWER_SET_OPTIONS:
result = self._set_power_onoff(subcommand)
if result == RESULT_OK:
result = RPOWER_STATE[subcommand]
new_status = POWER_STATE_DB.get(subcommand, '')
if subcommand in POWER_GET_OPTIONS:
tmp_result = self._get_power_state(subcommand)
result = RPOWER_STATE.get(tmp_result, tmp_result)
if subcommand == 'boot':
result = self._rpower_boot()
if result == RESULT_OK:
result = RPOWER_STATE[subcommand]
new_status = POWER_STATE_DB.get(subcommand, '')
if subcommand == 'reset':
status = self._get_power_state('state')
if status == 'Off' or status == 'chassison':
result = RPOWER_STATE['Off']
else:
result = self._rpower_boot()
if result == RESULT_OK:
result = RPOWER_STATE[subcommand]
new_status = POWER_STATE_DB.get(subcommand, '')
message = '%s: %s' % (self.node, result)
self.messager.info(message)
if new_status:
self.messager.update_node_attributes('status', self.node, new_status)
class OpenBMCManager(base.BaseManager):
def __init__(self, messager, cwd, nodes, envs):
super(OpenBMCManager, self).__init__(messager, cwd)
self.nodes = nodes
global DEBUGMODE
DEBUGMODE = envs['debugmode']
def _get_full_path(self,file_path):
if type(self.cwd) == 'unicode':
dir_path = self.cwd
else:
dir_path = self.cwd[0]
return '%s/%s' % (dir_path,file_path)
def _check_verbose(self, args):
verbose_list = ('-V', '--verbose')
for i in verbose_list:
if i in args:
global VERBOSE
VERBOSE = True
args.remove(i)
def _summary(self, nodes_num, title):
if all_nodes_result:
success_num = failed_num = 0
failed_list = []
for key in all_nodes_result:
if all_nodes_result[key]['result'] == 'OK':
success_num += 1
else:
failed_num += 1
for errors in all_nodes_result[key]['result']:
for error in errors:
failed_list.append('%s: %s' % (key, error))
self.messager.info('-' * 55)
self.messager.info('%s complete: Total=%d Success=%d Failed=%d' % \
(title, nodes_num, success_num, failed_num))
if failed_list:
for i in failed_list:
self.messager.info(i)
self.messager.info('-' * 55)
def rflash(self, nodeinfo, args):
if not os.path.exists(XCAT_LOG_RFLASH_DIR):
os.makedirs(XCAT_LOG_RFLASH_DIR)
nodes_num = len(self.nodes)
self._check_verbose(args)
for key,value in RFLASH_OPTIONS.items():
if key in args:
args.remove(key)
args.insert(0, value)
break
upload_file = None
activate_arg = {}
args_num = len(args)
subcommand = args[0]
if (subcommand == 'upload' or subcommand == 'activate' or
(subcommand == 'check' and args_num > 1)):
arg_type = args[1].split('.')[-1]
if arg_type == 'tar':
upload_file = args[1]
if not os.path.isabs(upload_file):
upload_file = self._get_full_path(upload_file)
if (not os.access(upload_file, os.F_OK) or
not os.access(upload_file, os.R_OK)):
error = 'Error: Cannot access %s. Check the management ' \
'node and/or service nodes.' % upload_file
self.messager.error(error)
return
activate_arg['update_file'] = upload_file
else:
activate_arg['activate_id'] = args[1]
if (subcommand == 'check' or subcommand == 'activate') and upload_file:
grep_cmd = '/usr/bin/grep -a'
version_cmd = grep_cmd + ' ^version= ' + upload_file
purpose_cmd = grep_cmd + ' purpose= ' + upload_file
firmware_ver = os.popen(version_cmd).readlines()[0].split('=')[-1].strip()
purpose_ver = os.popen(purpose_cmd).readlines()[0].split('=')[-1].strip()
if subcommand == 'check':
self.messager.info('TAR %s Firmware Product Version: %s' \
% (purpose_ver,firmware_ver))
else:
activate_arg['activate_version'] = firmware_ver
activate_arg['purpose'] = purpose_ver.split('.')[-1]
if subcommand == 'activate':
args[1] = activate_arg
if subcommand == 'upload':
args[1] = upload_file
if subcommand == 'upload' or subcommand == 'activate' and upload_file:
self.messager.info('Attempting to upload %s, please wait...' % upload_file)
super(OpenBMCManager, self).process_nodes_worker('openbmc', 'OpenBMC',
self.nodes, nodeinfo, 'rflash', args)
self._summary(nodes_num, 'Firmware update')
def rpower(self, nodeinfo, args):
super(OpenBMCManager, self).process_nodes_worker('openbmc', 'OpenBMC',
self.nodes, nodeinfo, 'rpower', args)
@@ -0,0 +1,113 @@
#!/usr/bin/env python
import requests
import json
import time
import rest
import xcat_exception
class OpenBMCRest:
def __init__(self, name, messager, debugmode):
self.session = rest.RestSession()
self.name = name
self.messager = messager
self.debugmode = debugmode
def _print_record_log (self, log_string, status):
if self.debugmode :
localtime = time.asctime( time.localtime(time.time()) )
log = self.name + ': [openbmc_debug] ' + status + ' ' + log_string
self.messager.info(localtime + ' ' + log)
self.messager.syslog(log)
def _request_log (self, method, url, headers, data, files):
log_string = 'curl -k -c cjar -b cjar'
log_string += ' -X %s' % method
for key,value in headers.items():
header_data = key + ": " + value
log_string += ' -H "' + header_data + '"'
log_string += ' %s' % url
if data:
log_string += ' -d \'%s\'' % data
if files:
log_string += ' -T \'%s\'' % files
return log_string
def _response_check (self, response, response_dict, status):
if response.status_code != requests.codes.ok:
description = ''.join(response_dict['data']['description'])
error = 'Error: [%d] %s' % (response.status_code, description)
self._print_record_log(error, status)
code = response.status_code
raise xcat_exception.SelfClientException(error, code)
else:
self._print_record_log(response_dict['message'], status)
def request (self, method, url, headers, in_data, status):
data = log_data = ''
if in_data:
data = json.dumps(in_data)
log_data = data
if status == 'login':
in_data['data'][1] = 'xxxxxx'
log_data = json.dumps(in_data)
log_string = self._request_log(method, url, headers, log_data, '')
self._print_record_log(log_string, status)
try:
response = self.session.request(method, url, headers, data)
except xcat_exception.SelfServerException as e:
self._print_record_log(e.message, status)
raise xcat_exception.SelfServerException(e.message)
try:
response_dict = response.json()
except ValueError:
error = 'Error: Received wrong format response: %s' % response
self._print_record_log(error, status)
raise xcat_exception.SelfServerException(error)
self._response_check(response, response_dict, status)
return response_dict
def request_upload (self, method, url, headers, files, status):
for key,value in headers.items():
header_data = key + ': ' + value
request_cmd_log = 'curl -k -c cjar -b cjar -H "%s" -X %s -T %s %s -s' \
% (header_data, method, files, url)
log_string = self._request_log(method, url, headers, '', files)
self._print_record_log(log_string, status)
response = self.session.request_upload(method, url, header_data, files)
if not response:
error = 'Error: Did not receive response from OpenBMC after ' \
'running command form \'%s\'' % request_cmd_log
raise xcat_exception.SelfServerException(error)
try:
response_dict = json.loads(response)
except ValueError:
error = 'Error: Received wrong format response: %s: %s' % \
(request_cmd_log, response)
self._print_record_log(error, status)
raise xcat_exception.SelfServerException(error)
if response_dict['message'] != '200 OK':
error = 'Error: Failed to upload update file %s : %s-%s' % \
(files, response_dict['message'], \
''.join(response_dict['data']['description']))
self._print_record_log(error, status)
raise xcat_exception.SelfClientException(error, code)
self._print_record_log(response_dict['message'], status)
return
@@ -0,0 +1,41 @@
#!/usr/bin/env python
import requests
from gevent.subprocess import Popen, PIPE
import urllib3
urllib3.disable_warnings()
import xcat_exception
class RestSession :
def __init__(self):
self.session = requests.Session()
self.cookies = None
def request (self, method, url, headers, data):
try:
response = self.session.request(method, url,
data=data,
headers=headers,
verify=False,
timeout=30)
except requests.exceptions.ConnectionError:
raise xcat_exception.SelfServerException(
'Error: BMC did not respond. ' \
'Validate BMC configuration and retry the command.')
except requests.exceptions.Timeout:
raise xcat_exception.SelfServerException('Error: Timeout to connect to server')
if not self.cookies:
self.cookies = requests.utils.dict_from_cookiejar(self.session.cookies)
return response
def request_upload (self, method, url, headers, files):
request_cmd = 'curl -k -b sid=%s -H "%s" -X %s -T %s %s -s' % \
(self.cookies['sid'], headers, method, files, url)
sub = Popen(request_cmd, stdout=PIPE, shell=True)
response, err = sub.communicate()
return response
@@ -0,0 +1,123 @@
# -*- encoding: utf-8 -*-
from __future__ import print_function
import json
import sys
import os
import threading
import fcntl
import traceback
from gevent import socket
from gevent.server import StreamServer
from gevent.lock import BoundedSemaphore
from xcatagent import utils
from xcatagent import base as xcat_manager
MSG_TYPE = 'message'
DB_TYPE = 'db'
LOCK_FILE = '/var/lock/xcat/agent.lock'
class Messager(object):
def __init__(self, sock):
self.sock = sock
self.sem = BoundedSemaphore(1)
def _send(self, d):
buf = json.dumps(d)
self.sem.acquire()
self.sock.sendall(utils.int2bytes(len(buf)) + buf)
self.sem.release()
def info(self, msg):
d = {'type': MSG_TYPE, 'msg': {'type': 'info', 'data': msg}}
self._send(d)
def warn(self, msg):
d = {'type': MSG_TYPE, 'msg': {'type': 'warning', 'data': msg}}
self._send(d)
def error(self, msg):
d = {'type': MSG_TYPE, 'msg': {'type': 'error', 'data': msg}}
self._send(d)
def syslog(self, msg):
d = {'type': MSG_TYPE, 'msg': {'type': 'syslog', 'data': msg}}
self._send(d)
def update_node_attributes(self, attribute, node, data):
d = {'type': DB_TYPE, 'attribute': {'name': attribute, 'method': 'set', 'type': 'node', 'node': node, 'value': data}}
self._send(d)
class Server(object):
def __init__(self, address, standalone):
try:
os.unlink(address)
except OSError:
if os.path.exists(address):
raise
self.address = address
self.standalone = standalone
self.server = StreamServer(self._serve(), self._handle)
def _serve(self):
listener = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
listener.bind(self.address)
listener.listen(1)
return listener
def _handle(self, sock, address):
try:
messager = Messager(sock)
buf = sock.recv(4)
sz = utils.bytes2int(buf)
buf = utils.recv_all(sock, sz)
req = json.loads(buf)
if not 'command' in req:
messager.error("Could not find command")
return
if not 'module' in req:
messager.error("Please specify the request module")
return
if not 'cwd' in req:
messager.error("Please specify the cwd parameter")
return
manager_func = xcat_manager.BaseManager.get_manager_func(
req['module'])
if manager_func is None:
messager.error("Could not find manager for %s" % req['module'])
return
nodes = req.get("nodes", None)
manager = manager_func(messager, req['cwd'], nodes, req['envs'])
if not hasattr(manager, req['command']):
messager.error("command %s is not supported" % req['command'])
func = getattr(manager, req['command'])
# call the function in the specified manager
func(req['nodeinfo'], req['args'])
# after the method returns, the request should be handled
# completely, close the socket for client
if not self.standalone:
sock.close()
self.server.stop()
os._exit(0)
except Exception:
print(traceback.format_exc(), file=sys.stderr)
self.server.stop()
os._exit(1)
def keep_peer_alive(self):
def acquire():
fd = open(LOCK_FILE, "r+")
fcntl.flock(fd.fileno(), fcntl.LOCK_EX)
# if reach here, parent process may exit
print("xcat process exit unexpectedly.", file=sys.stderr)
self.server.stop()
os._exit(1)
t = threading.Thread(target=acquire)
t.start()
def start(self):
if not self.standalone:
self.keep_peer_alive()
self.server.serve_forever()
@@ -0,0 +1,49 @@
import struct
import sys
import inspect
def int2bytes(num):
return struct.pack('i', num)
def bytes2int(buf):
return struct.unpack('i', buf)[0]
def get_classes(module_name):
ret = []
for name, obj in inspect.getmembers(sys.modules[module_name]):
if inspect.isclass(obj):
ret.append(obj)
return ret
def class_func(module_name, class_name):
func = getattr(sys.modules[module_name], class_name)
return func
def recv_all(sock, size):
recv_size = 4096
buf_size = 0
buf_parts = []
while buf_size < size:
tmp_size = recv_size
left_size = size - buf_size
if left_size < recv_size:
tmp_size = left_size
buf_part = sock.recv(tmp_size)
buf_parts.append(buf_part)
buf_size += len(buf_part)
buf = ''.join(buf_parts)
return buf
def update2Ddict(updata_dict, key_a, key_b, value):
if key_a in updata_dict:
updata_dict[key_a].update({key_b: value})
else:
updata_dict.update({key_a: {key_b: value}})
@@ -0,0 +1,9 @@
#!/usr/bin/env python
class SelfServerException(Exception) :
pass
class SelfClientException(Exception) :
def __init__(self, message, code) :
super(Exception, self).__init__(message)
self.code = code
+54
View File
@@ -0,0 +1,54 @@
Summary: xCAT openbmc python
Name: xCAT-openbmc-py
Version: %{?version:%{version}}%{!?version:%(cat Version)}
Release: %{?release:%{release}}%{!?release:snap%(date +"%Y%m%d%H%M")}
Epoch: 1
License: EPL
Group: Applications/System
Source: xCAT-openbmc-py-%{version}.tar.gz
Packager: IBM Corp.
Vendor: IBM Corp.
Distribution: %{?_distribution:%{_distribution}}%{!?_distribution:%{_vendor}}
Prefix: /opt/xcat
BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root
%ifnos linux
AutoReqProv: no
%endif
BuildArch: noarch
Requires: xCAT-server, python-requests
%description
xCAT-openbmc-py provides openbmc related functions.
%prep
%setup -q -n xCAT-openbmc-py
%build
%install
rm -rf $RPM_BUILD_ROOT
install -d $RPM_BUILD_ROOT/%{prefix}/lib/python/agent
install -d $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/xcatagent
install -m755 lib/python/agent/*.py $RPM_BUILD_ROOT/%{prefix}/lib/python/agent
install -m644 lib/python/agent/xcatagent/*.py $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/xcatagent
%ifnos linux
rm -rf $RPM_BUILD_ROOT/%{prefix}/lib/python
%endif
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%{prefix}
%changelog
%pre
%post
%preun
+269
View File
@@ -15,8 +15,17 @@ use HTTP::Request;
use HTTP::Headers;
use LWP;
use JSON;
use File::Path;
use IO::Socket::SSL qw( SSL_VERIFY_PEER );
my $go_api_port = 12429;
my $go_cons_port = 12430;
use constant CONSOLE_LOG_DIR => "/var/log/consoles";
unless (-d CONSOLE_LOG_DIR) {
mkpath(CONSOLE_LOG_DIR, 0, 0755);
}
sub http_request {
my ($method, $url, $data) = @_;
my @user = getpwuid($>);
@@ -27,6 +36,7 @@ sub http_request {
SSL_cert_file => xCAT::Utils->getHomeDir() . "/.xcat/client-cred.pem",
SSL_ca_file => xCAT::Utils->getHomeDir() . "/.xcat/ca.pem",
SSL_use_cert => 1,
verify_hostname => 0,
SSL_verify_mode => SSL_VERIFY_PEER, }, );
my $header = HTTP::Headers->new('Content-Type' => 'application/json');
# $data = encode_json $data if defined($data);
@@ -105,4 +115,263 @@ sub create_nodes {
return $ret;
}
#-------------------------------------------------------------------------------
=head3 is_xcat_conf_ready
Check if the goconserver configuration file was generated by xcat
Returns:
1 - ready
0 - not ready
Globals:
none
Example:
my $ready=(xCAT::Goconserver::is_xcat_conf_ready()
Comments:
none
=cut
#-------------------------------------------------------------------------------
sub is_xcat_conf_ready {
my $file;
open $file, '<', "/etc/goconserver/server.conf";
my $line = <$file>;
close $file;
if ($line =~ /#generated by xcat/) {
return 1;
}
return 0;
}
#-------------------------------------------------------------------------------
=head3 is_goconserver_running
Check if the goconserver service is running
Returns:
1 - running
0 - not running
Globals:
none
Example:
my $running=(xCAT::Goconserver::is_goconserver_running()
Comments:
none
=cut
#-------------------------------------------------------------------------------
sub is_goconserver_running {
my $cmd = "ps axf | grep -v grep | grep \/usr\/bin\/goconserver";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
return 0;
}
return 1;
}
#-------------------------------------------------------------------------------
=head3 is_conserver_running
Check if the conserver service is running
Returns:
1 - running
0 - not running
Globals:
none
Example:
my $running=(xCAT::Goconserver::is_conserver_running()
Comments:
none
=cut
#-------------------------------------------------------------------------------
sub is_conserver_running {
# On ubuntu system 'service conserver status' can not get the correct status of conserver,
# use 'pidof conserver' like what we did in rcons.
my $cmd = "pidof conserver";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC == 0) {
return 1;
}
return 0;
}
#-------------------------------------------------------------------------------
=head3 build_conf
generate configuration file for goconserver
Returns:
none
Globals:
none
Example:
my $running=(xCAT::Goconserver::build_conf()
Comments:
none
=cut
#-------------------------------------------------------------------------------
sub build_conf {
my $config = "#generated by xcat ".xCAT::Utils->Version()."\n".
"global:\n".
" host: 0.0.0.0\n".
" ssl_key_file: /etc/xcat/cert/server-cred.pem\n".
" ssl_cert_file: /etc/xcat/cert/server-cred.pem\n".
" ssl_ca_cert_file: /etc/xcat/cert/ca.pem\n".
" logfile: /var/log/goconserver/server.log # the log for goconserver\n".
"api:\n".
" port: $go_api_port # the port for rest api\n".
"console:\n".
" datadir: /var/lib/goconserver/ # the data file to save the hosts\n".
" port: $go_cons_port # the port for console\n".
" log_timestamp: true # log the timestamp at the beginning of line\n".
" reconnect_interval: 10 # retry interval in second if console could not be connected\n".
" logger: # multiple logger targets could be specified\n".
" file: # file logger, valid fields: name,logdir. Accept array in yaml format\n".
" - name: default # the identity name customized by user\n".
" logdir: ".CONSOLE_LOG_DIR." # default log directory of xcat\n".
" # - name: goconserver \n".
" # logdir: /var/log/goconserver/nodes \n".
" # tcp: # valied fields: name, host, port, timeout, ssl_key_file, ssl_cert_file, ssl_ca_cert_file, ssl_insecure\n".
" # - name: logstash \n".
" # host: 127.0.0.1 \n".
" # port: 9653 \n".
" # timeout: 3 # default 3 second\n".
" # - name: filebeat \n".
" # host: <hostname or ip> \n".
" # port: <port> \n".
" # udp: # valid fiedls: name, host, port, timeout\n".
" # - name: rsyslog \n".
" # host: \n".
" # port: \n".
" # timeout: # default 3 second\n";
my $file;
my $ret = open ($file, '>', '/etc/goconserver/server.conf');
if ($ret == 0) {
xCAT::MsgUtils->message("S", "Could not open file /etc/goconserver/server.conf");
return 1;
}
print $file $config;
close $file;
return 0;
}
#-------------------------------------------------------------------------------
=head3 start_service
start goconserver service
Returns:
none
Globals:
none
Example:
my $running=(xCAT::Goconserver::start_service()
Comments:
none
=cut
#-------------------------------------------------------------------------------
sub start_service {
my $cmd = "service goconserver start";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("S", "Could not start goconserver service.");
return 1;
}
return 0;
}
#-------------------------------------------------------------------------------
=head3 stop_service
stop goconserver service
Returns:
none
Globals:
none
Example:
my $ret=(xCAT::Goconserver::stop_service()
Comments:
none
=cut
#-------------------------------------------------------------------------------
sub stop_service {
my $cmd = "service goconserver stop";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("S", "Could not stop goconserver service.");
return 1;
}
return 0;
}
#-------------------------------------------------------------------------------
=head3 stop_conserver_service
stop conserver service
Returns:
none
Globals:
none
Example:
my $ret=(xCAT::Goconserver::stop_conserver_service()
Comments:
none
=cut
#-------------------------------------------------------------------------------
sub stop_conserver_service {
my $cmd = "service conserver stop";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("S", "Could not stop conserver service.");
return 1;
}
return 0;
}
#-------------------------------------------------------------------------------
=head3 restart_service
restart goconserver service
Returns:
none
Globals:
none
Example:
my $ret=(xCAT::Goconserver::restart_service()
Comments:
none
=cut
#-------------------------------------------------------------------------------
sub restart_service {
my $cmd = "service goconserver restart";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("S", "Could not restart goconserver service.");
return 1;
}
return 0;
}
sub get_api_port {
return $go_api_port;
}
1;
+173
View File
@@ -16,6 +16,21 @@ use HTTP::Request;
use HTTP::Headers;
use HTTP::Cookies;
use Data::Dumper;
use Time::HiRes qw(sleep time);
use JSON;
use File::Path;
use Fcntl ":flock";
use IO::Socket::UNIX qw( SOCK_STREAM );
use xCAT_monitoring::monitorctrl;
my $LOCK_DIR = "/var/lock/xcat/";
my $LOCK_PATH = "/var/lock/xcat/agent.lock";
my $AGENT_SOCK_PATH = "/var/run/xcat/agent.sock";
my $PYTHON_LOG_PATH = "/var/log/xcat/agent.log";
my $PYTHON_AGENT_FILE = "/opt/xcat/lib/python/agent/agent.py";
my $MSG_TYPE = "message";
my $DB_TYPE = "db";
my $lock_fd;
my $header = HTTP::Headers->new('Content-Type' => 'application/json');
@@ -43,4 +58,162 @@ sub send_request {
return $id;
}
# if lock is released unexpectedly, python side would aware of the error after
# getting this lock
sub acquire_lock {
mkpath($LOCK_DIR);
# always create a new lock file
unlink($LOCK_PATH);
open($lock_fd, ">>", $LOCK_PATH) or return undef;
flock($lock_fd, LOCK_EX) or return undef;
return $lock_fd;
}
sub start_python_agent {
if (! -e $PYTHON_AGENT_FILE) {
xCAT::MsgUtils->message("S", "'$PYTHON_AGENT_FILE' does not exist");
return undef;
}
if (!defined(acquire_lock())) {
xCAT::MsgUtils->message("S", "Error: Faild to require lock");
return undef;
}
my $fd;
open($fd, '>', $AGENT_SOCK_PATH) && close($fd);
my $pid = fork;
if (!defined $pid) {
xCAT::MsgUtils->message("S", "Error: Unable to fork process");
return undef;
}
$SIG{CHLD} = 'DEFAULT';
if (!$pid) {
# child
open($fd, ">>", $PYTHON_LOG_PATH) && close($fd);
open(STDOUT, '>>', $PYTHON_LOG_PATH) or die("open: $!");
open(STDERR, '>>&', \*STDOUT) or die("open: $!");
my $ret = exec ($PYTHON_AGENT_FILE);
if (!defined($ret)) {
xCAT::MsgUtils->message("S", "Error: Failed to start python agent");
exit(1);
}
}
return $pid;
}
sub handle_message {
my ($data, $callback) = @_;
if($data->{type} eq $MSG_TYPE) {
my $msg = $data->{msg};
if ($msg->{type} eq 'info') {
xCAT::MsgUtils->message("I", { data => [$msg->{data}] }, $callback);
} elsif ($msg->{type} eq 'warning') {
xCAT::MsgUtils->message("W", { data => [$msg->{data}] }, $callback);
} elsif ($msg->{type} eq 'error'){
xCAT::MsgUtils->message("E", { data => [$msg->{data}] }, $callback);
} elsif ($msg->{type} eq 'syslog'){
xCAT::MsgUtils->message("S", $msg->{data});
}
} elsif ($data->{type} eq $DB_TYPE) {
my $attribute = $data->{attribute};
if ($attribute->{name} eq 'status' and $attribute->{method} eq 'set' and $attribute->{type} eq 'node') {
my %new_status = ($attribute->{value} => [$attribute->{node}]);
xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%new_status, 1)
}
}
}
sub submit_agent_request {
my ($pid, $req, $nodeinfo, $callback) = @_;
my $sock;
my $retry = 0;
while($retry < 30) {
$sock = IO::Socket::UNIX->new(Peer => $AGENT_SOCK_PATH, Type => SOCK_STREAM, Timeout => 10, Blocking => 1);
if (!defined($sock)) {
sleep(0.1);
} else {
last;
}
$retry++;
}
if (!defined($sock)) {
xCAT::MsgUtils->message("E", { data => ["Failed to connect to the agent"] }, $callback);
kill('TERM', $pid);
return;
}
my $xcatdebugmode = 0;
if ($::XCATSITEVALS{xcatdebugmode}) { $xcatdebugmode = $::XCATSITEVALS{xcatdebugmode} }
my %env_hash = ();
$env_hash{debugmode} = $xcatdebugmode;
my ($data, $sz, $ret, $buf);
$data->{module} = 'openbmc';
$data->{command} = $req->{command}->[0];
$data->{args} = $req->{arg};
$data->{cwd} = $req->{cwd};
$data->{nodes} = $req->{node};
$data->{nodeinfo} = $nodeinfo;
$data->{envs} = \%env_hash;
$buf = encode_json($data);
$sz = pack('i', length($buf));
# send length of data first
$ret = $sock->send($sz);
if (!$ret) {
xCAT::MsgUtils->message("E", { data => ["Failed to send message to the agent"] }, $callback);
$sock->close();
kill('TERM', $pid);
return;
}
# send data
$ret = $sock->send($buf);
if (!$ret) {
xCAT::MsgUtils->message("E", { data => ["Failed to send message to the agent"] }, $callback);
$sock->close();
kill('TERM', $pid);
return;
}
while(1) {
$ret = $sock->recv($buf, 4);
if (!$ret) {
last;
}
# receive the length of data
$sz = unpack('i', $buf);
# read data with length is $sz
$ret = $sock->recv($buf, $sz);
if (!$ret) {
xCAT::MsgUtils->message("E", { data => ["receive data from python agent unexpectedly"] }, $callback);
last;
}
$data = decode_json($buf);
handle_message($data, $callback);
}
# no message received, the socket on the agent side should be closed.
$sock->close();
}
sub wait_agent {
my ($pid, $callback) = @_;
waitpid($pid, 0);
if ($? >> 8 != 0) {
xCAT::MsgUtils->message("E", { data => ["python agent exited unexpectedly"] }, $callback);
}
}
sub is_openbmc_python {
my $environment = shift;
$environment = shift if (($environment) && ($environment =~ /OPENBMC/));
# If XCAT_OPENBMC_PYTHON is YES, will run openbmc2.pm. If not, run openbmc.pm
if (ref($environment) eq 'ARRAY' and ref($environment->[0]->{XCAT_OPENBMC_PYTHON}) eq 'ARRAY') {
$::OPENBMC_PYTHON = $environment->[0]->{XCAT_OPENBMC_PYTHON}->[0];
} elsif (ref($environment) eq 'ARRAY') {
$::OPENBMC_PYTHON = $environment->[0]->{XCAT_OPENBMC_PYTHON};
} else {
$::OPENBMC_PYTHON = $environment->{XCAT_OPENBMC_PYTHON};
}
if (defined($::OPENBMC_PYTHON) and $::OPENBMC_PYTHON eq "YES") {
return 1;
}
return 0;
}
1;
+3 -1
View File
@@ -61,6 +61,8 @@ sub validate {
my $peerhostorg = shift;
my $deferredmsgargs = shift;
my @filtered_cmds = qw( getdestiny getbladecons getipmicons getopenbmccons getcons);
# now check the policy table if user can run the command
my $policytable = xCAT::Table->new('policy');
unless ($policytable) {
@@ -192,7 +194,7 @@ sub validate {
$status = "Denied";
$rc = 0;
}
if (($request->{command}->[0] ne "getdestiny") && ($request->{command}->[0] ne "getbladecons") && ($request->{command}->[0] ne "getipmicons") && ($request->{command}->[0] ne "getopenbmccons")) {
if (! grep { /$request->{command}->[0]/ } @filtered_cmds) {
# set username authenticated to run command
# if from Trusted host, use input username, else set from creds
+60 -6
View File
@@ -152,6 +152,9 @@ sub init_plugin
$rc = xCAT::Utils->setupAIXconserver();
}
} elsif ($servicelist->{"conserver"} == 2)
{
&setup_GOCONS();
}
if (($servicelist->{"nameserver"} == 1) || ($servicelist->{"nameserver"} == 2))
{
@@ -488,15 +491,17 @@ sub setup_CONS
{
my ($nodename) = @_;
my $rc = 0;
my $cmdref;
if (-x "/usr/bin/goconserver") {
my $cmd = "ps axf | grep -v grep | grep \/usr\/bin\/goconserver";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC == 0) {
xCAT::MsgUtils->message("S", "INFO: goconserver was started, do nothing for conserver.");
return 0;
require xCAT::Goconserver;
if (xCAT::Goconserver::is_goconserver_running()) {
$rc = xCAT::Goconserver::stop_service();
if($rc) {
xCAT::MsgUtils->message("S", "Error: Failed to stop goconserver service.");
return 1;
}
}
}
my $cmdref;
$cmdref->{command}->[0] = "makeconservercf";
$cmdref->{arg}->[0] = "-l";
$cmdref->{cwd}->[0] = "/opt/xcat/sbin";
@@ -538,6 +543,55 @@ sub setup_CONS
#-----------------------------------------------------------------------------
=head3 setup_GOCONS
Sets up goconserver
=cut
#-----------------------------------------------------------------------------
sub setup_GOCONS
{
my ($running, $ready, $ret);
unless (-x "/usr/bin/goconserver") {
xCAT::MsgUtils->message("S", "Error: goconserver is not installed.");
return 1;
}
require xCAT::Goconserver;
# if goconserver is installed, check the status of conserver service.
if (xCAT::Goconserver::is_conserver_running()) {
xCAT::MsgUtils->message("S", "conserver is started, stopping it.");
$ret = xCAT::Goconserver::stop_conserver_service();
if ($ret) {
xCAT::MsgUtils->message("S", "Error: failed to stop conserver service.");
return 1;
}
}
$running = xCAT::Goconserver::is_goconserver_running();
$ready = xCAT::Goconserver::is_xcat_conf_ready();
if ( $running && $ready ) {
# Already started by xcat
return 0;
}
# user could customize the configuration, do not rewrite the configuration if this file has been
# generated by xcat
if (!$ready) {
$ret = xCAT::Goconserver::build_conf();
if ($ret) {
xCAT::MsgUtils->message("S", "Error: failed to create configuration file for goconserver.");
return 1;
}
}
$ret = xCAT::Goconserver::restart_service();
if ($ret) {
xCAT::MsgUtils->message("S", "Error: failed to start goconserver service.");
return 1;
}
return 0;
}
#-----------------------------------------------------------------------------
=head3 setup_DHCP
Sets up DHCP services
+2 -3
View File
@@ -203,9 +203,8 @@ sub process_request {
my $cb = shift;
if ($req->{command}->[0] eq "makeconservercf") {
if (-x "/usr/bin/goconserver") {
my $cmd = "ps axf | grep -v grep | grep \/usr\/bin\/goconserver";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC == 0) {
require xCAT::Goconserver;
if (xCAT::Goconserver::is_goconserver_running()) {
my $rsp->{data}->[0] = "goconserver is started, please stop it at first.";
xCAT::MsgUtils->message("E", $rsp, $cb);
return;
+31 -26
View File
@@ -86,9 +86,10 @@ sub process_request
# do your processing here
# return info
my $origclient = $client;
if ($client) { ($client) = noderange($client) }
unless ($client) { #Not able to do host authentication, abort
xCAT::MsgUtils->trace(0, "E", "Received getcredentials from $origclient, which couldn't be correlated to a node (domain mismatch?)");
return;
}
my $credcheck;
@@ -97,9 +98,11 @@ sub process_request
} elsif ($request->{'callback_https_port'} and $request->{'callback_https_port'}->[0] and $request->{'callback_https_port'}->[0] < 1024) {
$credcheck = [ 1, $request->{'callback_https_port'}->[0] ];
} else {
xCAT::MsgUtils->trace(0, 'E', "Received malformed getcredentials requesting, ignore it.");
return;
}
unless (ok_with_node($client, $credcheck)) {
xCAT::MsgUtils->trace(0, 'E', "The node ($client) is not ready, ignore it.");
return;
}
@@ -131,10 +134,10 @@ sub process_request
my ($rootkeyparm, $zonename) = split(/:/, $parm);
if ($zonename) {
$parm = $rootkeyparm; # take the zone off
`logger -t xcat -p local4.info "credentials: The node is asking for zone:$zonename sshkeys ."`;
xCAT::MsgUtils->trace(0, 'I', "credentials: The node ($client) is asking for sshkeys of zone: $zonename.");
$sshrootkeydir = xCAT::Zone->getzonekeydir($zonename);
if ($sshrootkeydir == 1) { # error return
`logger -t xcat -p local4.info "credentials: The node is asking for zone:$zonename sshkeys and the $zonename is not defined."`;
xCAT::MsgUtils->trace(0, 'W', "credentials: The zone: $zonename is not defined.");
} else {
$foundkeys = 1; # don't want to read the zone data twice
}
@@ -144,85 +147,85 @@ sub process_request
if ($parm =~ /ssh_root_key/) {
unless (-r "$sshrootkeydir/id_rsa") {
push @{ $rsp->{'error'} }, "Unable to read root's private ssh key";
`logger -t xcat -p local4.info "credentials: Unable to read root's private ssh key"`;
xCAT::MsgUtils->trace(0, 'E', "credentials: Unable to read root's private ssh key");
next;
}
`logger -t xcat -p local4.info "credentials: sending $parm"`;
xCAT::MsgUtils->trace(0, 'I', "credentials: sending $parm to $client");
$tfilename = "$sshrootkeydir/id_rsa";
`logger -t xcat -p local4.info "credentials: The ssh root private key is in $tfilename."`;
xCAT::MsgUtils->trace(0, 'I', "credentials: The root's private ssh key is in $tfilename.");
} elsif ($parm =~ /ssh_root_pub_key/) {
unless (-r "$sshrootkeydir/id_rsa.pub") {
push @{ $rsp->{'error'} }, "Unable to read root's public ssh key";
`logger -t xcat -p local4.info "credentials: Unable to read root's public ssh key"`;
xCAT::MsgUtils->trace(0, 'E', "credentials: Unable to read root's public ssh key");
next;
}
`logger -t xcat -p local4.info "credentials: sending $parm"`;
xCAT::MsgUtils->trace(0, 'I', "credentials: sending $parm to $client");
$tfilename = "$sshrootkeydir/id_rsa.pub";
`logger -t xcat -p local4.info "credentials: The ssh root public key is in $tfilename."`;
xCAT::MsgUtils->trace(0, 'I', "credentials: The root's public ssh key is in $tfilename.");
} elsif ($parm =~ /xcat_server_cred/) {
unless (-r "/etc/xcat/cert/server-cred.pem") {
push @{ $rsp->{'error'} }, "Unable to read xcat_server_cred";
`logger -t xcat -p local4.info "credentials: Unable to read xcat_server_cred"`;
xCAT::MsgUtils->trace(0, 'E', "credentials: Unable to read xcat_server_cred");
next;
}
`logger -t xcat -p local4.info "credentials: sending $parm"`;
xCAT::MsgUtils->trace(0, 'I', "credentials: sending $parm to $client");
$tfilename = "/etc/xcat/cert/server-cred.pem";
} elsif (($parm =~ /xcat_client_cred/) or ($parm =~ /xcat_root_cred/)) {
unless (-r "$root/.xcat/client-cred.pem") {
push @{ $rsp->{'error'} }, "Unable to read xcat_client_cred or xcat_root_cred";
`logger -t xcat -p local4.info "credentials: Unable to read xcat_client_cred or xcat_root_cred"`;
xCAT::MsgUtils->trace(0, 'E', "credentials: Unable to read xcat_client_cred or xcat_root_cred");
next;
}
`logger -t xcat -p local4.info "credentials: sending $parm"`;
xCAT::MsgUtils->trace(0, 'I', "credentials: sending $parm to $client");
$tfilename = "$root/.xcat/client-cred.pem";
} elsif ($parm =~ /ssh_dsa_hostkey/) {
`logger -t xcat -p local4.info "credentials: sending $parm"`;
xCAT::MsgUtils->trace(0, 'I', "credentials: sending $parm to $client");
if (-r "/etc/xcat/hostkeys/$client/ssh_host_dsa_key") {
$tfilename = "/etc/xcat/hostkeys/$client/ssh_host_dsa_key";
} elsif (-r "/etc/xcat/hostkeys/ssh_host_dsa_key") {
$tfilename = "/etc/xcat/hostkeys/ssh_host_dsa_key";
} else {
push @{ $rsp->{'error'} }, "Unable to read private DSA key from /etc/xcat/hostkeys";
`logger -t xcat -p local4.info "credentials: Unable to read private DSA key"`;
xCAT::MsgUtils->trace(0, 'E', "credentials: Unable to read private DSA key");
next;
}
} elsif ($parm =~ /ssh_rsa_hostkey/) {
`logger -t xcat -p local4.info "credentials: sending $parm"`;
xCAT::MsgUtils->trace(0, 'I', "credentials: sending $parm to $client");
if (-r "/etc/xcat/hostkeys/$client/ssh_host_rsa_key") {
$tfilename = "/etc/xcat/hostkeys/$client/ssh_host_rsa_key";
} elsif (-r "/etc/xcat/hostkeys/ssh_host_rsa_key") {
$tfilename = "/etc/xcat/hostkeys/ssh_host_rsa_key";
} else {
push @{ $rsp->{'error'} }, "Unable to read private RSA key from /etc/xcat/hostkeys";
`logger -t xcat -p local4.info "credentials: Unable to read private RSA key"`;
xCAT::MsgUtils->trace(0, 'E', "credentials: Unable to read private RSA key");
next;
}
} elsif ($parm =~ /ssh_ecdsa_hostkey/) {
`logger -t xcat -p local4.info "credentials: sending $parm"`;
xCAT::MsgUtils->trace(0, 'I', "credentials: sending $parm to $client");
if (-r "/etc/xcat/hostkeys/$client/ssh_host_ecdsa_key") {
$tfilename = "/etc/xcat/hostkeys/$client/ssh_host_ecdsa_key";
} elsif (-r "/etc/xcat/hostkeys/ssh_host_ecdsa_key") {
$tfilename = "/etc/xcat/hostkeys/ssh_host_ecdsa_key";
} else {
push @{ $rsp->{'error'} }, "Unable to read private ECDSA key from /etc/xcat/hostkeys";
`logger -t xcat -p local4.info "credentials: Unable to read private ECDSA key"`;
xCAT::MsgUtils->trace(0, 'E', "credentials: Unable to read private ECDSA key");
next;
}
} elsif ($parm =~ /xcat_cfgloc/) {
`logger -t xcat -p local4.info "credentials: sending $parm"`;
xCAT::MsgUtils->trace(0, 'I', "credentials: sending $parm to $client");
unless (-r "/etc/xcat/cfgloc") {
push @{ $rsp->{'error'} }, "Unable to read /etc/xcat/cfgloc ";
`logger -t xcat -p local4.info "credentials: Unable to read /etc/xcat/cfgloc"`;
xCAT::MsgUtils->trace(0, 'E', "credentials: Unable to read /etc/xcat/cfgloc");
next;
}
$tfilename = "/etc/xcat/cfgloc";
} elsif ($parm =~ /krb5_keytab/) { #TODO: MUST RELAY TO MASTER
`logger -t xcat -p local4.info "credentials: sending $parm"`;
xCAT::MsgUtils->trace(0, 'I', "credentials: sending $parm to $client");
my $princsuffix = $request->{'_xcat_clientfqdn'}->[0];
$ENV{KRB5CCNAME} = "/tmp/xcat/krb5cc_xcat_$$";
system('kinit -S kadmin/admin -k -t /etc/xcat/krb5_pass xcat/admin');
@@ -248,7 +251,7 @@ sub process_request
unlink "/tmp/xcat/keytab.$$";
next;
} elsif ($parm =~ /x509cert/) {
`logger -t xcat -p local4.info "credentials: sending $parm"`;
xCAT::MsgUtils->trace(0, 'I', "credentials: sending $parm to $client");
my $csr = $request->{'csr'}->[0];
my $csrfile;
my $oldumask = umask 0077;
@@ -289,7 +292,8 @@ sub process_request
chomp;
my ($type, $expiry, $revoke, $serial, $fname, $subject) = split /\t/;
if ($type eq 'V' and $subject =~ /CN=$client\z/) { #we already have a valid certificate, new request replaces it, revoke old
print "The time of replacing is at hand for $client\n";
#print "The time of replacing is at hand for $client\n";
xCAT::MsgUtils->trace(0, 'I', "credentials: The time of replacing is at hand for $client");
system("openssl ca -config /etc/xcat/ca/openssl.cnf -revoke /etc/xcat/ca/certs/$serial.pem");
}
}
@@ -304,15 +308,16 @@ sub process_request
my $certcontents = join('', @certdata);
push @{ $rsp->{'data'} }, { content => [$certcontents], desc => [$parm] };
} elsif ($parm =~ /xcat_dockerhost_cert/) {
`logger -t xcat -p local4.info "credentials: sending $parm"`;
xCAT::MsgUtils->trace(0, 'I', "credentials: sending $parm to $client");
unless (-r "/etc/xcatdockerca/cert/dockerhost-cert.pem") {
push @{ $rsp->{'error'} }, "Unable to read /etc/xcatdockerca/cert/dockerhost-cert.pem ";
`logger -t xcat -p local4.info "credentials: Unable to read /etc/xcatdockerca/cert/dockerhost-cert.pem"`;
xCAT::MsgUtils->trace(0, 'E', "credentials: Unable to read /etc/xcatdockerca/cert/dockerhost-cert.pem");
next;
}
$tfilename = "/etc/xcatdockerca/cert/dockerhost-cert.pem";
} else {
xCAT::MsgUtils->trace(0, 'W', "credentials: Not supported type: $parm");
next;
}
+23 -2
View File
@@ -587,6 +587,18 @@ sub process_request {
$ctx->{forwarders} = \@forwarders;
}
my @options = xCAT::TableUtils->get_site_attribute("emptyzonesenable");
my $empty_zones = $options[0];
if (defined($empty_zones)) {
if ($empty_zones =~ /^yes$|^no$/) {
$ctx->{empty_zones_enable} = $empty_zones;
} else {
my $rsp;
push @{ $rsp->{data} }, "emptyzonesenable from xCAT site table should be yes or no.";
xCAT::MsgUtils->message("E", $rsp, $callback);
return;
}
}
my @slave_ips;
my $dns_slaves = get_dns_slave();
if (scalar @$dns_slaves) {
@@ -1098,6 +1110,8 @@ sub update_namedconf {
push @newnamed, "\t\t" . $_ . ";\n";
}
push @newnamed, "\t};\n";
} elsif ($ctx->{empty_zones_enable} and $line =~ /empty-zones-enable/) {
push @newnamed, "\tempty-zones-enable " . $ctx->{empty_zones_enable} . ";\n";
} elsif ($ctx->{slaves} and $line =~ /allow-transfer \{/) {
push @newnamed, "\tallow-transfer \{\n";
$skip = 1;
@@ -1237,6 +1251,10 @@ sub update_namedconf {
push @newnamed, "\t};\n";
}
if ($ctx->{empty_zones_enable}){
push @newnamed, "\tempty-zones-enable " . $ctx->{empty_zones_enable} . ";\n";
}
if ($slave) {
push @newnamed, "\tallow-transfer { any; };\n";
} else {
@@ -1281,10 +1299,13 @@ sub update_namedconf {
my @includes = split /[ ,]/, $site_entry;
foreach (@includes) {
if (defined($_)) {
push @newnamed, "include \"$_\";\n";
my $line = "include \"$_\";\n";
unless (grep{/$line/} @newnamed) {
push @newnamed, "include \"$_\";\n";
}
}
}
push @newnamed, "\n";
}
}
unless ($slave) {
@@ -64,7 +64,8 @@ sub process_request
unless ($request->{'_xcat_clienthost'}->[0]) {
#ERROR? malformed request
return; #nothing to do here...
xCAT::MsgUtils->trace(0, 'E', "Received malformed getpostscript requesting, ignore it.");
return;
}
$client = $request->{'_xcat_clienthost'}->[0];
}
@@ -72,7 +73,7 @@ sub process_request
my $origclient = $client;
if ($client) { ($client) = noderange($client) }
unless ($client) { #Not able to do identify the host in question
xCAT::MsgUtils->message("S", "Received getpostscript from $origclient, which couldn't be correlated to a node (domain mismatch?)");
xCAT::MsgUtils->trace(0, "E", "Received getpostscript from $origclient, which couldn't be correlated to a node (domain mismatch?)");
return;
}
my $state;
@@ -88,18 +89,18 @@ sub process_request
my $notmpfiles;
my $nofiles;
# If not version=2, then we return the mypostscript file in an array.
# If not version=2, then we return the mypostscript file in an array.
if ($version != 2) {
$notmpfiles = 1; # no tmp files and no files
$nofiles = 1; # do not create /tftpboot/mypostscript/mypostscript.<nodename>
@scriptcontents = xCAT::Postage::makescript([$client], $state, $callback, $notmpfiles, $nofiles);
`logger -t xcat -p local4.info "getpostscript: sending data"`;
xCAT::MsgUtils->trace(0, "I", "getpostscript: Sending scripts data to $client...");
$rsp->{data} = \@scriptcontents;
$callback->($rsp);
} else { # version 2, make files, do not return array
# make the mypostscript.<nodename> file
# or the mypostscript.<nodename>.tmp file if precreatemypostscripts=0
# xcatdsklspost will wget the file
# make the mypostscript.<nodename> file
# or the mypostscript.<nodename>.tmp file if precreatemypostscripts=0
# xcatdsklspost will wget the file
$notmpfiles = 0;
$nofiles = 0;
xCAT::Postage::makescript([$client], $state, $callback, $notmpfiles, $nofiles);
+34 -89
View File
@@ -17,8 +17,6 @@ use Data::Dumper;
my $isSN;
my $host;
my $go_api_port = 12429;
my $go_cons_port = 12430;
my $bmc_cons_port = "2200";
my $usage_string =" makegocons [-V|--verbose] [-d|--delete] noderange
-h|--help Display this usage statement.
@@ -56,8 +54,6 @@ sub preprocess_request {
#$Getopt::Long::pass_through=1;
if (!GetOptions(
'c|conserver' => \$::CONSERVER,
'l|local' => \$::LOCAL,
'h|help' => \$::HELP,
'D|debug' => \$::DEBUG,
'v|version' => \$::VERSION,
@@ -75,19 +71,6 @@ sub preprocess_request {
$request = {};
return;
}
if ($::LOCAL) {
if ($noderange && @$noderange > 0) {
$::callback->({ data => "Invalid option -l or --local when there are nodes specified." });
$request = {};
return;
}
}
if ($::CONSERVER && $::LOCAL) {
$::callback->({ data => "Can not specify -l or --local together with -c or --conserver." });
$request = {};
return;
}
# get site master
my $master = xCAT::TableUtils->get_site_Master();
@@ -122,42 +105,14 @@ sub preprocess_request {
push @nodes, $_->{node};
}
#send all nodes to the MN
if (!$isSN && !$::CONSERVER) { #If -c flag is set, do not add the all nodes to the management node
if ($::VERBOSE) {
my $rsp;
$rsp->{data}->[0] = "Setting the nodes into goconserver on the management node";
xCAT::MsgUtils->message("I", $rsp, $::callback);
}
my $reqcopy = {%$request};
$reqcopy->{'_xcatdest'} = $master;
$reqcopy->{_xcatpreprocessed}->[0] = 1;
$reqcopy->{'_allnodes'} = $allnodes; # the original command comes with nodes or not
if ($allnodes == 1) { @nodes = (); }
$reqcopy->{node} = \@nodes;
push @requests, $reqcopy;
if ($::LOCAL) { return \@requests; }
}
# send to conserver hosts
foreach my $cons (keys %cons_hash) {
#print "cons=$cons\n";
my $doit = 0;
if ($isSN) {
if (exists($iphash{$cons})) { $doit = 1; }
} else {
if (!exists($iphash{$cons}) || $::CONSERVER) { $doit = 1; }
}
if ($doit) {
my $reqcopy = {%$request};
$reqcopy->{'_xcatdest'} = $cons;
$reqcopy->{_xcatpreprocessed}->[0] = 1;
$reqcopy->{'_allnodes'} = [$allnodes]; # the original command comes with nodes or not
$reqcopy->{node} = $cons_hash{$cons}{nodes};
push @requests, $reqcopy;
} #end if
foreach my $host (keys %cons_hash) {
my $reqcopy = {%$request};
$reqcopy->{'_xcatdest'} = $host;
$reqcopy->{_xcatpreprocessed}->[0] = 1;
$reqcopy->{'_allnodes'} = [$allnodes]; # the original command comes with nodes or not
$reqcopy->{node} = $cons_hash{$host}{nodes};
push @requests, $reqcopy;
} #end foreach
if ($::DEBUG) {
@@ -308,54 +263,44 @@ sub gen_request_data {
return $data;
}
sub start_goconserver {
my $rsp;
my ($rsp, $running, $ready, $ret);
unless (-x "/usr/bin/goconserver") {
$rsp->{data}->[0] = "goconserver is not installed.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
return 1;
}
# As conserver is always installed, we check the existence of goconserver at first.
# if goconserver is installed, check the status of conserver service.
my $cmd = "ps axf | grep -v grep | grep \/usr\/sbin\/conserver";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC == 0) {
if (xCAT::Goconserver::is_conserver_running()) {
$rsp->{data}->[0] = "conserver is started, please stop it at first.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
return 1;
}
$cmd = "ps axf | grep -v grep | grep \/usr\/bin\/goconserver";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0) {
my $config= "global:\n".
" host: 0.0.0.0\n".
" ssl_key_file: /etc/xcat/cert/server-key.pem\n".
" ssl_cert_file: /etc/xcat/cert/server-cert.pem\n".
" ssl_ca_cert_file: /etc/xcat/cert/ca.pem\n".
" logfile: /var/log/goconserver/server.log\n".
"api:\n".
" port: $go_api_port\n".
"console:\n".
" port: $go_cons_port\n";
my $file;
my $ret = open ($file, '>', '/etc/goconserver/server.conf');
if ($ret == 0) {
$rsp->{data}->[0] = "Could not open file /etc/goconserver/server.conf.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
return 1;
}
print $file $config;
close $file;
my $cmd = "service goconserver start";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0) {
$rsp->{data}->[0] = "Could not start goconserver service.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
return 1;
}
sleep(3);
$running = xCAT::Goconserver::is_goconserver_running();
$ready = xCAT::Goconserver::is_xcat_conf_ready();
if ( $running && $ready ) {
# Already started by xcat
return 0;
}
# user could customize the configuration, do not rewrite the configuration if this file has been
# generated by xcat
if (!$ready) {
$ret = xCAT::Goconserver::build_conf();
if ($ret) {
$rsp->{data}->[0] = "Failed to create configuration file for goconserver.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
return 1;
}
}
$ret = xCAT::Goconserver::restart_service();
if ($ret) {
$rsp->{data}->[0] = "Failed to start goconserver service.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
return 1;
}
$rsp->{data}->[0] = "Starting goconserver service ...";
xCAT::MsgUtils->message("I", $rsp, $::callback);
sleep(3);
return 0;
}
@@ -406,7 +351,7 @@ sub makegocons {
xCAT::SvrUtils::sendmsg([ 1, "Could not generate the request data" ], $::callback);
return 1;
}
my $api_url = "https://$host:$go_api_port";
my $api_url = "https://$host:". xCAT::Goconserver::get_api_port();
$ret = xCAT::Goconserver::delete_nodes($api_url, $data, $delmode, $::callback);
if ($delmode) {
return $ret;
+10 -10
View File
@@ -2427,9 +2427,9 @@ sub rflash {
my $c_id = ${ $sessdata->{component_ids} }[$i];
my $version = $firmware_version{$c_id};
my $format_string = $comp_string{$c_id};
my $format_ver = sprintf("%3d.%02x %02X%02X%02X%02X",
$version->[0], $version->[1], $version->[2],
$version->[3], $version->[4], $version->[5]);
my $format_ver = sprintf("%3d.%02x.%d",
$version->[0], $version->[1],
$version->[5]*0x1000000 +$version->[4]*0x10000+ $version->[3]*0x100+$version->[2]);
$msg = $msg . $sessdata->{node} . ": " .
"Node firmware version for $format_string component: $format_ver";
if ($i != scalar(@{ $sessdata->{component_ids} }) - 1) {
@@ -4696,7 +4696,7 @@ sub parseboard {
my $macdata = $boardinf{extra}->[6]->{value};
my $macstring = "1";
my $macprefix;
while ($macdata and $macstring !~ /00:00:00:00:00:00/ and not ref $global_sessdata->{currmacs}) {
while ($macdata and ref $macdata and $macstring !~ /00:00:00:00:00:00/ and not ref $global_sessdata->{currmacs}) {
my @currmac = splice @$macdata, 0, 6;
unless ((scalar @currmac) == 6) {
last;
@@ -8747,16 +8747,16 @@ sub hpm_action_version {
return -1;
}
my $version = $hpm_data_hash{1}{action_version};
my $ver = sprintf("%3d.%02x %02X%02X%02X%02X", $version->[0], $version->[1], $version->[2],
$version->[3], $version->[4], $version->[5]);
my $ver = sprintf("%3d.%02x.%d", $version->[0], $version->[1],
$version->[5]*0x1000000+$version->[4]*0x10000+$version->[3]*0x100+$version->[2]);
$callback->({ data => "HPM firmware version for BOOT component:$ver" });
$version = $hpm_data_hash{2}{action_version};
$ver = sprintf("%3d.%02x %02X%02X%02X%02X", $version->[0], $version->[1], $version->[2],
$version->[3], $version->[4], $version->[5]);
$ver = sprintf("%3d.%02x.%d", $version->[0], $version->[1],
$version->[5]*0x1000000+$version->[4]*0x10000+$version->[3]*0x100+$version->[2]);
$callback->({ data => "HPM firmware version for APP component:$ver" });
$version = $hpm_data_hash{4}{action_version};
$ver = sprintf("%3d.%02x %02X%02X%02X%02X", $version->[0], $version->[1], $version->[2],
$version->[3], $version->[4], $version->[5]);
$ver = sprintf("%3d.%02x.%d", $version->[0], $version->[1],
$version->[5]*0x1000000+$version->[4]*0x10000+$version->[3]*0x100+$version->[2]);
$callback->({ data => "HPM firmware version for BIOS component:$ver" });
}
+2 -3
View File
@@ -620,7 +620,7 @@ sub mods_in_rpm {
rmtree($tmp_path);
return; }
} else {
if (system("cd $tmp_path; rpm2cpio $krpm | cpio -idum *.ko > /dev/null 2>&1 ; cd - > /dev/null 2>&1")) {
if (system("cd $tmp_path; rpm2cpio $krpm | cpio -idum > /dev/null 2>&1 ; cd - > /dev/null 2>&1")) {
my $rsp;
push @{ $rsp->{data} }, "Unable to extract files from the rpm $krpm.";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
@@ -636,7 +636,7 @@ sub mods_in_rpm {
return;
}
my @ko_files = `find $tmp_path -name *.ko`;
my @ko_files = `find $tmp_path -regextype posix-egrep -regex ".*/*\.ko(\.xz)?"`;
foreach my $ko (@ko_files) {
my %mod;
chomp($ko);
@@ -650,7 +650,6 @@ sub mods_in_rpm {
$mod{description} = $desc;
push(@modlist, \%mod);
}
rmtree($tmp_path);
return @modlist;
+456 -99
View File
@@ -60,7 +60,7 @@ $::RSETBOOT_URL_PATH = "boot";
$::UPLOAD_AND_ACTIVATE = 0;
$::UPLOAD_ACTIVATE_STREAM = 0;
$::RFLASH_STREAM_NO_HOST_REBOOT = 0;
$::TAR_FILE_PATH = "";
$::NO_ATTRIBUTES_RETURNED = "No attributes returned from the BMC.";
$::UPLOAD_WAIT_ATTEMPT = 6;
@@ -76,6 +76,7 @@ $::BMC_CHECK_INTERVAL = 15;
$::RSPCONFIG_DUMP_INTERVAL = 15;
$::RSPCONFIG_DUMP_MAX_RETRY = 20;
$::RSPCONFIG_DUMP_WAIT_TOTALTIME = int($::RSPCONFIG_DUMP_INTERVAL*$::RSPCONFIG_DUMP_MAX_RETRY);
$::RSPCONFIG_DUMP_DOWNLOAD_ALL_REQUESTED = 0;
$::RSPCONFIG_WAIT_VLAN_DONE = 15;
$::RSPCONFIG_WAIT_IP_DONE = 3;
$::RSPCONFIG_DUMP_CMD_TIME = 0;
@@ -93,6 +94,11 @@ unless (-d $::XCAT_LOG_DUMP_DIR) {
mkpath($::XCAT_LOG_DUMP_DIR);
}
# Common logging messages:
my $usage_errormsg = "Usage error.";
my $reventlog_no_id_resolved_errormsg = "Provide a comma separated list of IDs to be resolved. Example: 'resolved=x,y,z'";
sub unsupported {
my $callback = shift;
if (defined($::OPENBMC_DEVEL) && ($::OPENBMC_DEVEL eq "YES")) {
@@ -144,6 +150,7 @@ my $http_protocol="https";
my $openbmc_url = "/org/openbmc";
my $openbmc_project_url = "/xyz/openbmc_project";
$::SOFTWARE_URL = "$openbmc_project_url/software";
$::LOGGING_URL = "$openbmc_project_url/logging/entry/#ENTRY_ID#/attr/Resolved";
#-------------------------------------------------------
# The hash table to store method and url for request,
@@ -197,6 +204,17 @@ my %status_info = (
REVENTLOG_CLEAR_RESPONSE => {
process => \&reventlog_response,
},
REVENTLOG_RESOLVED_REQUEST => {
method => "PUT",
init_url => "$::LOGGING_URL",
data => "1",
},
REVENTLOG_RESOLVED_RESPONSE => {
process => \&reventlog_response,
},
REVENTLOG_RESOLVED_RESPONSE_LED => {
process => \&reventlog_response,
},
RFLASH_LIST_REQUEST => {
method => "GET",
@@ -449,6 +467,14 @@ my %status_info = (
RSPCONFIG_SSHCFG_RESPONSE => {
process => \&rspconfig_sshcfg_response,
},
RSPCONFIG_CLEAR_GARD_REQUEST => {
method => "POST",
init_url => "/org/open_power/control/gard/action/Reset",
data => "[]",
},
RSPCONFIG_CLEAR_GARD_RESPONSE => {
process => \&rspconfig_response,
},
RSPCONFIG_DUMP_LIST_REQUEST => {
method => "GET",
init_url => "$openbmc_project_url/dump/enumerate",
@@ -487,6 +513,9 @@ my %status_info = (
RSPCONFIG_DUMP_DOWNLOAD_RESPONSE => {
process => \&rspconfig_dump_response,
},
RSPCONFIG_DUMP_DOWNLOAD_ALL_RESPONSE => {
process => \&rspconfig_dump_response,
},
RVITALS_REQUEST => {
method => "GET",
init_url => "$openbmc_project_url/sensors/enumerate",
@@ -494,6 +523,13 @@ my %status_info = (
RVITALS_RESPONSE => {
process => \&rvitals_response,
},
RVITALS_LEDS_REQUEST => {
method => "GET",
init_url => "$openbmc_project_url/led/physical/enumerate",
},
RVITALS_LEDS_RESPONSE => {
process => \&rvitals_response,
},
RSPCONFIG_API_CONFIG_ON_REQUEST => {
method => "PUT",
init_url => "$openbmc_project_url",
@@ -510,6 +546,14 @@ my %status_info = (
RSPCONFIG_API_CONFIG_OFF_RESPONSE => {
process => \&rspconfig_api_config_response,
},
RSPCONFIG_API_CONFIG_ATTR_REQUEST => {
method => "PUT",
init_url => "$openbmc_project_url",
data => "false",
},
RSPCONFIG_API_CONFIG_ATTR_RESPONSE => {
process => \&rspconfig_api_config_response,
},
RSPCONFIG_API_CONFIG_QUERY_REQUEST => {
method => "GET",
init_url => "$openbmc_project_url",
@@ -523,6 +567,7 @@ my %status_info = (
# For example: rspconfig <subcommand>
# rspconfig <subcommand>=0
# rspconfig <subcommand>=1
# rspconfig <subcommand>=<attr_value>
#
#
my %api_config_info = (
@@ -530,17 +575,34 @@ my %api_config_info = (
command => "rspconfig",
url => "/control/host0/auto_reboot",
attr_url => "AutoReboot",
display_name => "AutoReboot",
display_name => "BMC AutoReboot",
type => "boolean",
subcommand => "autoreboot",
},
RSPCONFIG_POWERSUPPLY_REDUNDENCY => {
RSPCONFIG_POWERSUPPLY_REDUNDANCY => {
command => "rspconfig",
url => "/sensors/chassis/PowerSupplyRedundancy",
attr_url => "PowerSupplyRedundency",
display_name => "PowerSupplyRedundency",
type => "boolean",
subcommand => "powersupplyredundency",
attr_url => "value",
display_name => "BMC PowerSupplyRedundancy",
type => "attribute",
subcommand => "powersupplyredundancy",
attr_value => {
enabled => "Enabled",
disabled => "Disabled",
},
},
RSPCONFIG_POWERRESTORE_POLICY => {
command => "rspconfig",
url => "/control/host0/power_restore_policy",
attr_url => "PowerRestorePolicy",
display_name => "BMC PowerRestorePolicy",
type => "attribute",
subcommand => "powerrestorepolicy",
attr_value => {
restore => "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
always_on => "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
always_off => "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
},
},
);
@@ -647,6 +709,11 @@ sub preprocess_request {
}
##############################################
if (xCAT::OPENBMC->is_openbmc_python($request->{environment})) {
$request = {};
return;
}
$callback = shift;
if ($::XCATSITEVALS{xcatdebugmode}) { $xcatdebugmode = $::XCATSITEVALS{xcatdebugmode} }
@@ -660,7 +727,7 @@ sub preprocess_request {
my $extrargs = $request->{arg};
my @exargs = ($request->{arg});
my @requests;
$::cwd = $request->{cwd}->[0];
if (ref($extrargs)) {
@exargs = @$extrargs;
}
@@ -1013,6 +1080,9 @@ sub parse_args {
my $option_s;
GetOptions( 's' => \$option_s );
return ([ 1, "The -s option is not supported for OpenBMC." ]) if ($option_s);
if ( "resolved" ~~ @ARGV) {
return ([ 1, "$usage_errormsg $reventlog_no_id_resolved_errormsg" ]);
}
return ([ 1, "Only one option is supported at the same time for $command" ]);
} elsif (scalar(@ARGV) == 0 and $command =~ /rpower|rspconfig|rflash/) {
@@ -1043,7 +1113,23 @@ sub parse_args {
}
} elsif ($command eq "reventlog") {
$subcommand = "all" if (!defined($ARGV[0]));
unless ($subcommand =~ /^\d$|^\d+$|^all$|^clear$/) {
if ($subcommand =~ /^(\w+)=(.*)/) {
my $key = $1;
my $value = $2;
if (not $value) {
return ([ 1, "$usage_errormsg $reventlog_no_id_resolved_errormsg" ]);
}
my $nodes_num = @$noderange;
if (@$noderange > 1) {
return ([ 1, "Resolving faults over a xCAT noderange is not recommended." ]);
}
xCAT::SvrUtils::sendmsg("Attempting to resolve the following log entries: $value...", $callback);
} elsif ($subcommand !~ /^\d$|^\d+$|^all$|^clear$/) {
if ($subcommand =~ "resolved") {
return ([ 1, "$usage_errormsg $reventlog_no_id_resolved_errormsg" ]);
}
return ([ 1, "Unsupported command: $command $subcommand" ]);
}
} elsif ($command eq "rspconfig") {
@@ -1096,12 +1182,19 @@ sub parse_args {
} elsif ($subcommand =~ /^sshcfg$/) {
return ([ 1, "Configure sshcfg must be issued without other options." ]) if ($num_subcommand > 1);
$setorget = ""; # SSH Keys are copied using a RShellAPI, not REST API
} elsif ($subcommand eq "gard") {
my $option = "";
$option = $ARGV[1] if (defined $ARGV[1]);
return ([ 1, "Clear GARD cannot be issued with other options." ]) if ($num_subcommand > 2);
return ([ 1, "Invalid parameter for $command $subcommand $option" ]) if ($option !~ /^-c$|^--clear$/);
$setorget = "";
return;
} elsif ($subcommand eq "dump") {
my $option = "";
$option = $ARGV[1] if (defined $ARGV[1]);
if ($option =~ /^-d$|^--download$/) {
return ([ 1, "No dump file ID specified" ]) unless ($ARGV[2]);
return ([ 1, "Invalid parameter for $command $option $ARGV[2]" ]) if ($ARGV[2] !~ /^\d*$/);
return ([ 1, "Invalid parameter for $command $option $ARGV[2]" ]) if ($ARGV[2] !~ /^\d*$/ and $ARGV[2] ne "all");
} elsif ($option =~ /^-c$|^--clear$/) {
return ([ 1, "No dump file ID specified. To clear all, specify 'all'." ]) unless ($ARGV[2]);
return ([ 1, "Invalid parameter for $command $option $ARGV[2]" ]) if ($ARGV[2] !~ /^\d*$/ and $ARGV[2] ne "all");
@@ -1124,7 +1217,7 @@ sub parse_args {
}
} elsif ($command eq "rvitals") {
$subcommand = "all" if (!defined($ARGV[0]));
unless ($subcommand =~ /^temp$|^voltage$|^wattage$|^fanspeed$|^power$|^altitude$|^all$/) {
unless ($subcommand =~ /^leds$|^temp$|^voltage$|^wattage$|^fanspeed$|^power$|^altitude$|^all$/) {
return ([ 1, "Unsupported command: $command $subcommand" ]);
}
} elsif ($command eq "rflash") {
@@ -1161,17 +1254,24 @@ sub parse_args {
}
}
}
elsif ($opt =~ /.*\//) {
elsif ($opt =~ /^\//) {
$filepath_passed = 1;
push (@tarball_path, $opt);
}
else {
push (@flash_arguments, $opt);
$invalid_options .= $opt . " ";
my $tmppath = xCAT::Utils->full_path($opt, $::cwd);
if (opendir(TDIR, $tmppath)) {
$filepath_passed = 1;
push (@tarball_path, $tmppath);
close(TDIR);
} else {
push (@flash_arguments, $opt);
$invalid_options .= $opt . " ";
}
}
}
# show options parsed in bypass mode
print "DEBUG filename=$filename_passed, updateid=$updateid_passed, options=$option_flag, invalid=$invalid_options rflash_arguments=@flash_arguments\n";
print "DEBUG filename=$filename_passed, updateid=$updateid_passed, options=$option_flag, tar_file_path=@tarball_path, invalid=$invalid_options rflash_arguments=@flash_arguments\n";
if ($option_flag =~ tr{ }{ } > 0) {
unless ($verbose or $option_flag =~/^-d --no-host-reboot$/) {
@@ -1180,7 +1280,10 @@ sub parse_args {
}
if (scalar @flash_arguments > 1) {
if ($filename_passed and $option_flag !~ /^-d$/) {
if (($option_flag =~ /^-a$|^--activate$|^--delete$/) or ($filename_passed and $option_flag !~ /^-d$/)) {
# Handles:
# - Multiple options not supported to activate/delete at the same time
# - Filename passed in and option is not -d for directory
return ([1, "More than one firmware specified is not supported."]);
} elsif ($option_flag =~ /^-d$/) {
return ([1, "More than one directory specified is not supported."]);
@@ -1199,7 +1302,12 @@ sub parse_args {
if ($updateid_passed) {
# Updateid was passed, check flags allowed with update id
if ($option_flag !~ /^--delete$|^-a$|^--activate$/) {
return ([ 1, "Invalid option specified when an update id is provided: $option_flag" ]);
my $optional_help_msg = "";
if ($option_flag == "-d") {
# For this special case, -d was changed to pass in a directory.
$optional_help_msg = "Did you mean --delete?"
}
return ([ 1, "Invalid option specified when an update id is provided: $option_flag. $optional_help_msg" ]);
}
my $action = "activate";
if ($option_flag =~ /^--delete$/) {
@@ -1216,8 +1324,10 @@ sub parse_args {
}
if (!opendir(DIR, $tarball_path[0])) {
return ([1, "Can't open directory : $tarball_path[0]"]);
} else {
$::TAR_FILE_PATH = $tarball_path[0];
closedir(DIR);
}
closedir(DIR);
} elsif ($option_flag =~ /^-c$|^--check$|^-u$|^--upload$|^-a$|^--activate$/) {
return ([ 1, "Invalid firmware specified with $option_flag" ]);
} else {
@@ -1399,6 +1509,16 @@ sub parse_command_status {
if ($subcommand eq "clear") {
$next_status{LOGIN_RESPONSE} = "REVENTLOG_CLEAR_REQUEST";
$next_status{REVENTLOG_CLEAR_REQUEST} = "REVENTLOG_CLEAR_RESPONSE";
} elsif ($subcommand =~ /resolved=LED/) {
$next_status{LOGIN_RESPONSE} = "REVENTLOG_REQUEST";
$next_status{REVENTLOG_REQUEST} = "REVENTLOG_RESOLVED_RESPONSE_LED";
} elsif ($subcommand =~ /resolved=(.+)/) {
$next_status{LOGIN_RESPONSE} = "REVENTLOG_RESOLVED_REQUEST";
$next_status{REVENTLOG_RESOLVED_REQUEST} = "REVENTLOG_RESOLVED_RESPONSE";
my @entries = split(",", $1);
my $init_entry = shift @entries;
$status_info{REVENTLOG_RESOLVED_REQUEST}{init_url} =~ s/#ENTRY_ID#/$init_entry/g;
push @{ $status_info{REVENTLOG_RESOLVED_RESPONSE}{remain_entries} }, @entries;
} else {
$next_status{LOGIN_RESPONSE} = "REVENTLOG_REQUEST";
$next_status{REVENTLOG_REQUEST} = "REVENTLOG_RESPONSE";
@@ -1429,18 +1549,25 @@ sub parse_command_status {
my $subcommand_key = $1;
my $subcommand_value = $2;
if ($subcommand_value eq "1") {
if (($subcommand_value eq "1") && ($api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{type} eq "boolean")) {
# Setup chain for subcommand=1
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_API_CONFIG_ON_REQUEST";
$status_info{RSPCONFIG_API_CONFIG_ON_REQUEST}{init_url} = $status_info{RSPCONFIG_API_CONFIG_ON_REQUEST}{init_url} . $api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{url} . "/attr/" . $api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{attr_url};
$next_status{RSPCONFIG_API_CONFIG_ON_REQUEST} = "RSPCONFIG_API_CONFIG_ON_RESPONSE";
}
elsif ($subcommand_value eq "0") {
elsif (($subcommand_value eq "0") && ($api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{type} eq "boolean")) {
# Setup chain for subcommand=0
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_API_CONFIG_OFF_REQUEST";
$status_info{RSPCONFIG_API_CONFIG_OFF_REQUEST}{init_url} = $status_info{RSPCONFIG_API_CONFIG_OFF_REQUEST}{init_url} . $api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{url} . "/attr/" . $api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{attr_url};
$next_status{RSPCONFIG_API_CONFIG_OFF_REQUEST} = "RSPCONFIG_API_CONFIG_OFF_RESPONSE";
}
elsif (($api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{type} eq "attribute") && (exists $api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{attr_value}{$subcommand_value})) {
# Setup chain for subcommand=<attribute key>
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_API_CONFIG_ATTR_REQUEST";
$status_info{RSPCONFIG_API_CONFIG_ATTR_REQUEST}{init_url} = $status_info{RSPCONFIG_API_CONFIG_ATTR_REQUEST}{init_url} . $api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{url} . "/attr/" . $api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{attr_url};
$status_info{RSPCONFIG_API_CONFIG_ATTR_REQUEST}{data} = $api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{attr_value}{$subcommand_value};
$next_status{RSPCONFIG_API_CONFIG_ATTR_REQUEST} = "RSPCONFIG_API_CONFIG_ATTR_RESPONSE";
}
else {
# Everything else is invalid
xCAT::SvrUtils::sendmsg([1, "Invalid value $subcommand_value for 'rspconfig $subcommand_key=$subcommand_value' command"], $callback);
@@ -1524,10 +1651,19 @@ sub parse_command_status {
return 1;
}
$::RSPCONFIG_DUMP_CMD_TIME = time(); #Save time of rspcommand start to use in the dump filename
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_DOWNLOAD_REQUEST";
$next_status{RSPCONFIG_DUMP_DOWNLOAD_REQUEST} = "RSPCONFIG_DUMP_DOWNLOAD_RESPONSE";
$status_info{RSPCONFIG_DUMP_DOWNLOAD_REQUEST}{init_url} =~ s/#ID#/$$subcommands[2]/g;
$status_info{RSPCONFIG_DUMP_DOWNLOAD_REQUEST}{argv} = $$subcommands[2];
if ($$subcommands[2] eq "all") {
# if "download all" was passed in
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_LIST_REQUEST";
$next_status{RSPCONFIG_DUMP_LIST_REQUEST} = "RSPCONFIG_DUMP_LIST_RESPONSE";
$next_status{RSPCONFIG_DUMP_LIST_RESPONSE} = "RSPCONFIG_DUMP_DOWNLOAD_ALL_RESPONSE";
xCAT::SvrUtils::sendmsg("Downloading all dumps...", $callback);
$::RSPCONFIG_DUMP_DOWNLOAD_ALL_REQUESTED = 1; # Set flag to download all dumps
} else {
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_DOWNLOAD_REQUEST";
$next_status{RSPCONFIG_DUMP_DOWNLOAD_REQUEST} = "RSPCONFIG_DUMP_DOWNLOAD_RESPONSE";
$status_info{RSPCONFIG_DUMP_DOWNLOAD_REQUEST}{init_url} =~ s/#ID#/$$subcommands[2]/g;
$status_info{RSPCONFIG_DUMP_DOWNLOAD_REQUEST}{argv} = $$subcommands[2];
}
} else {
# this section handles the dump support where no options are given and xCAT will
# # handle the creation, waiting, and download of the dump across a given noderange
@@ -1546,6 +1682,10 @@ sub parse_command_status {
$next_status{RSPCONFIG_DUMP_DOWNLOAD_REQUEST} = "RSPCONFIG_DUMP_DOWNLOAD_RESPONSE";
}
return 0;
} elsif ($subcommand eq "gard") {
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_CLEAR_GARD_REQUEST";
$next_status{RSPCONFIG_CLEAR_GARD_REQUEST} = "RSPCONFIG_CLEAR_GARD_RESPONSE";
return 0;
}
if ($subcommand =~ /^admin_passwd=(.+),(.+)/) {
@@ -1622,9 +1762,15 @@ sub parse_command_status {
$subcommand = "all";
}
$next_status{LOGIN_RESPONSE} = "RVITALS_REQUEST";
$next_status{RVITALS_REQUEST} = "RVITALS_RESPONSE";
$status_info{RVITALS_RESPONSE}{argv} = "$subcommand";
if ($subcommand eq "leds") {
$next_status{LOGIN_RESPONSE} = "RVITALS_LEDS_REQUEST";
$next_status{RVITALS_LEDS_REQUEST} = "RVITALS_LEDS_RESPONSE";
$status_info{RVITALS_LEDS_RESPONSE}{argv} = "$subcommand";
} else {
$next_status{LOGIN_RESPONSE} = "RVITALS_REQUEST";
$next_status{RVITALS_REQUEST} = "RVITALS_RESPONSE";
$status_info{RVITALS_RESPONSE}{argv} = "$subcommand";
}
}
if ($command eq "rflash") {
@@ -1722,13 +1868,13 @@ sub parse_command_status {
# Display firmware version of the specified .tar file
xCAT::SvrUtils::sendmsg("TAR $purpose_value Firmware Product Version\: $version_value", $callback);
}
} elsif (opendir(DIR, $update_file)) {
} elsif (opendir(DIR, $::TAR_FILE_PATH)) {
my @tar_files = readdir(DIR);
foreach my $file (@tar_files) {
if ($file !~ /.*\.tar$/) {
next;
} else {
my $full_path_file = $update_file."/".$file;
my $full_path_file = $::TAR_FILE_PATH."/".$file;
$full_path_file=~s/\/\//\//g;
my $firmware_version_in_file = `$grep_cmd $version_tag $full_path_file`;
my $purpose_version_in_file = `$grep_cmd $purpose_tag $full_path_file`;
@@ -1854,7 +2000,6 @@ sub parse_command_status {
$next_status{RFLASH_UPDATE_CHECK_STATE_REQUEST} = "RFLASH_UPDATE_CHECK_STATE_RESPONSE";
$next_status{RFLASH_SET_PRIORITY_REQUEST} = "RFLASH_SET_PRIORITY_RESPONSE";
$next_status{RFLASH_SET_PRIORITY_RESPONSE} = "RFLASH_UPDATE_CHECK_STATE_REQUEST";
$next_status{RFLASH_UPDATE_CHECK_STATE_REQUEST} = "RFLASH_UPDATE_CHECK_STATE_RESPONSE";
$next_status{RFLASH_UPDATE_CHECK_STATE_RESPONSE} = "RPOWER_BMCREBOOT_REQUEST";
$next_status{RPOWER_BMCREBOOT_REQUEST} = "RPOWER_RESET_RESPONSE";
$status_info{RPOWER_RESET_RESPONSE}{argv} = "bmcreboot";
@@ -1970,7 +2115,7 @@ sub parse_node_info {
next;
}
unless($node_info{$node}{bmcip}) {
xCAT::SvrUtils::sendmsg("Error: Unable to resolve ip address for bmc: $node_info{$node}{bmc}", $callback, $node);
xCAT::SvrUtils::sendmsg("Error: Unable to resolved ip address for bmc: $node_info{$node}{bmc}", $callback, $node);
delete $node_info{$node};
$rst = 1;
next;
@@ -2124,21 +2269,24 @@ sub deal_with_response {
$wait_node_num--;
return;
}
if (defined $status_info{RPOWER_BMC_STATUS_RESPONSE}{argv} and $status_info{RPOWER_BMC_STATUS_RESPONSE}{argv} =~ /bmcstate$/) {
if ($node_info{$node}{cur_status} eq "RPOWER_BMC_STATUS_RESPONSE" and defined $status_info{RPOWER_BMC_STATUS_RESPONSE}{argv} and $status_info{RPOWER_BMC_STATUS_RESPONSE}{argv} =~ /bmcstate$/) {
retry_check_times($node, "RPOWER_BMC_STATUS_REQUEST", "bmc_conn_check_times", $::BMC_CHECK_INTERVAL, $response->status_line);
return;
}
}
if ($response->status_line eq $::RESPONSE_SERVICE_UNAVAILABLE) {
$error = $::RESPONSE_SERVICE_UNAVAILABLE;
} elsif ($response->status_line eq $::RESPONSE_METHOD_NOT_ALLOWED) {
# Special processing for file upload. At this point we do not know how to
# form a proper file upload request. It always fails with "Method not allowed" error.
# If that happens, just assume it worked.
# TODO remove this block when proper request can be generated
$status_info{ $node_info{$node}{cur_status} }->{process}->($node, $response);
return;
if ($node_info{$node}{cur_status} eq "REVENTLOG_RESOLVED_RESPONSE") {
$error = "Could not find ID specified.";
} else {
# Special processing for file upload. At this point we do not know how to
# form a proper file upload request. It always fails with "Method not allowed" error.
# If that happens, just assume it worked.
# TODO remove this block when proper request can be generated
$status_info{ $node_info{$node}{cur_status} }->{process}->($node, $response);
return;
}
} elsif ($response->status_line eq $::RESPONSE_SERVICE_TIMEOUT) {
if ($node_info{$node}{cur_status} eq "RPOWER_RESET_RESPONSE" and defined $status_info{RPOWER_RESET_RESPONSE}{argv} and $status_info{RPOWER_RESET_RESPONSE}{argv} =~ /bmcreboot$/) {
my $infomsg = "BMC $::POWER_STATE_REBOOT";
@@ -2163,7 +2311,16 @@ sub deal_with_response {
} elsif ($node_info{$node}{cur_status} eq "RSETBOOT_ENABLE_RESPONSE" ) {
# If 403 is received setting boot method, API endpoint changed in 1738 FW, inform the user of work around.
$error = "Invalid endpoint used to set boot method. If running firmware < ibm-v1.99.10-0-r7, 'export XCAT_OPENBMC_FIRMWARE=1736' and retry.";
} else {
} elsif ($node_info{$node}{cur_status} eq "REVENTLOG_RESOLVED_RESPONSE") {
my $cur_url;
if ($node_info{$node}{cur_url}) {
$cur_url = $node_info{$node}{cur_url};
} else {
$cur_url = $status_info{REVENTLOG_RESOLVED_REQUEST}{init_url};
}
my $log_id = (split ('/', $cur_url))[5];
$error = "Invalid ID=$log_id provided to be resolved. [$::RESPONSE_FORBIDDEN]";
} else{
$error = "$::RESPONSE_FORBIDDEN - Requested endpoint does not exists and may indicate function is not yet supported by OpenBMC firmware.";
}
# Handle 404
@@ -2795,7 +2952,67 @@ sub reventlog_response {
if ($node_info{$node}{cur_status} eq "REVENTLOG_CLEAR_RESPONSE") {
if ($response_info->{'message'} eq $::RESPONSE_OK) {
xCAT::SvrUtils::sendmsg("clear", $callback, $node);
xCAT::SvrUtils::sendmsg("Logs cleared", $callback, $node);
}
} elsif ($node_info{$node}{cur_status} eq "REVENTLOG_RESOLVED_RESPONSE") {
my $cur_url;
if ($node_info{$node}{cur_url}) {
$cur_url = $node_info{$node}{cur_url};
if ($node_info{$node}{bak_url}) {
$node_info{$node}{cur_url} = shift @{ $node_info{$node}{bak_url} };
} else {
$node_info{$node}{cur_url} = "";
}
} else {
$cur_url = $status_info{REVENTLOG_RESOLVED_REQUEST}{init_url};
}
if ($response_info->{'message'} eq $::RESPONSE_OK) {
my $log_id = (split ('/', $cur_url))[5];
xCAT::SvrUtils::sendmsg("Resolved $log_id.", $callback, $node);
}
if ($status_info{REVENTLOG_RESOLVED_RESPONSE}{remain_entries} and !$node_info{$node}{remain_entries}) {
foreach my $entry (@{ $status_info{REVENTLOG_RESOLVED_RESPONSE}{remain_entries} }) {
my $tmp_url = $::LOGGING_URL;
$tmp_url =~ s/#ENTRY_ID#/$entry/g;
push @{ $node_info{$node}{bak_url} }, $tmp_url;
}
$node_info{$node}{cur_url} = shift @{ $node_info{$node}{bak_url} };
$node_info{$node}{remain_entries} = $status_info{REVENTLOG_RESOLVED_RESPONSE}{remain_entries};
}
if ($node_info{$node}{cur_url}) {
$next_status{"REVENTLOG_RESOLVED_RESPONSE"} = "REVENTLOG_RESOLVED_REQUEST";
} else {
# Break out of this loop if there are no more IDs to resolve
$wait_node_num--;
return;
}
} elsif ($node_info{$node}{cur_status} eq "REVENTLOG_RESOLVED_RESPONSE_LED") {
# Scan all event log entries and build an array of all that have callout data
my @entries;
foreach my $key_url (keys %{$response_info->{data}}) {
my %content = %{ ${ $response_info->{data} }{$key_url} };
next unless ($content{Id});
my $event_msg = is_callout_event_data(\%content);
push(@entries, $event_msg) if ($event_msg); # Add array entry of log event id
}
# If some entries with callout data, send them off to be resolved
if (scalar(@entries) > 0) {
$next_status{"REVENTLOG_RESOLVED_RESPONSE_LED"} = "REVENTLOG_RESOLVED_REQUEST";
$next_status{"REVENTLOG_RESOLVED_REQUEST"} = "REVENTLOG_RESOLVED_RESPONSE";
my $init_entry = shift @entries;
$status_info{REVENTLOG_RESOLVED_REQUEST}{init_url} =~ s/#ENTRY_ID#/$init_entry/g;
push @{ $status_info{REVENTLOG_RESOLVED_RESPONSE}{remain_entries} }, @entries;
}
else {
# Return if there are no entries with callout data
xCAT::SvrUtils::sendmsg("There are no event log entries contributing to LED fault", $callback, $node);
$wait_node_num--;
return;
}
} else {
my $entry_string = $status_info{REVENTLOG_RESPONSE}{argv};
@@ -2832,6 +3049,33 @@ sub reventlog_response {
#-------------------------------------------------------
=head3 is_callout_event_data
Parse reventlog data and return entry ID if it has
CALLOUT data
Input:
$content: data for single entry
=cut
#-------------------------------------------------------
sub is_callout_event_data {
my $content = shift;
my $id_num = $$content{Id};
if ($$content{Message}) {
if (defined $$content{AdditionalData} and $$content{AdditionalData}) {
foreach my $addition (@{ $$content{AdditionalData} }) {
if ($addition =~ /CALLOUT/) {
return $id_num;
}
}
}
}
return "";
}
#-------------------------------------------------------
=head3 parse_event_data
Parse reventlog data
@@ -2844,6 +3088,7 @@ sub reventlog_response {
sub parse_event_data {
my $content = shift;
my $content_info = "";
my $LED_tag = " [LED]"; # Indicate that the entry contributes to LED fault
my $timestamp = $$content{Timestamp};
my $id_num = $$content{Id};
@@ -2852,7 +3097,7 @@ sub parse_event_data {
$mon += 1;
$year += 1900;
my $UTC_time = sprintf ("%02d/%02d/%04d %02d:%02d:%02d", $mon, $mday, $year, $hour, $min, $sec);
my $messgae = $$content{Message};
my $message = $$content{Message};
my $callout;
my $msg_pid;
my $i2c_device;
@@ -2886,21 +3131,22 @@ sub parse_event_data {
}
}
$messgae .= "||$callout" if ($callout);
$message .= "||$callout" if ($callout);
if (ref($event_mapping) eq "HASH") {
if ($event_mapping->{$messgae}) {
my $event_type = $event_mapping->{$messgae}{EventType};
my $event_message = $event_mapping->{$messgae}{Message};
my $severity = $event_mapping->{$messgae}{Severity};
my $affect = $event_mapping->{$messgae}{AffectedSubsystem};
if ($event_mapping->{$message}) {
my $event_type = $event_mapping->{$message}{EventType};
my $event_message = $event_mapping->{$message}{Message};
my $severity = $event_mapping->{$message}{Severity};
my $affect = $event_mapping->{$message}{AffectedSubsystem};
$content_info = "$UTC_time [$id_num]: $event_type, ($severity) $event_message (AffectedSubsystem: $affect, PID: $msg_pid), Resolved: $$content{Resolved}";
} else {
$content_info = "$UTC_time [$id_num]: Not found in policy table: $messgae (PID: $msg_pid), Resolved: $$content{Resolved}";
$content_info = "$UTC_time [$id_num]: Not found in policy table: $message (PID: $msg_pid), Resolved: $$content{Resolved}";
}
} else {
$content_info = "$UTC_time [$id_num]: $messgae (PID: $msg_pid), Resolved: $$content{Resolved}";
$content_info = "$UTC_time [$id_num]: $message (PID: $msg_pid), Resolved: $$content{Resolved}";
}
$content_info .= $LED_tag if ($callout);
}
return $content_info;
@@ -3209,6 +3455,12 @@ sub rspconfig_response {
return;
}
if ($node_info{$node}{cur_status} eq "RSPCONFIG_CLEAR_GARD_RESPONSE") {
if ($response_info->{'message'} eq $::RESPONSE_OK) {
xCAT::SvrUtils::sendmsg("GARD cleared", $callback, $node);
}
}
if ($next_status{ $node_info{$node}{cur_status} }) {
if ($node_info{$node}{cur_status} eq "RSPCONFIG_CHECK_RESPONSE") {
$node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }{$origin_type};
@@ -3265,6 +3517,14 @@ sub rspconfig_api_config_response {
xCAT::SvrUtils::sendmsg("Error unsetting RSPCONFIG_API_CONFIG_OFF_RESPONSE", $callback, $node);
}
}
elsif ($node_info{$node}{cur_status} eq "RSPCONFIG_API_CONFIG_ATTR_RESPONSE") {
if ($response_info->{'message'} eq $::RESPONSE_OK) {
xCAT::SvrUtils::sendmsg("BMC Setting ". $api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{display_name} . "...", $callback, $node);
}
else {
xCAT::SvrUtils::sendmsg("Error unsetting RSPCONFIG_API_CONFIG_OFF_RESPONSE", $callback, $node);
}
}
elsif ($node_info{$node}{cur_status} eq "RSPCONFIG_API_CONFIG_QUERY_RESPONSE") {
if ($response_info->{'message'} eq $::RESPONSE_OK) {
foreach my $key_url (keys %{$response_info->{data}}) {
@@ -3274,11 +3534,21 @@ sub rspconfig_api_config_response {
last;
}
}
if (scalar($value) >= 0) {
if (($value eq "0") || ($value eq "1")) {
# If 0 or 1 display as a boolean value
xCAT::SvrUtils::sendmsg($api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{display_name} . ": $value", $callback, $node);
}
else {
xCAT::SvrUtils::sendmsg("Unable to query value for " . $api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{attr_url}, $callback, $node);
# If not a boolean value, display the last component of the attribute
# For example "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"
# will be displayed as "Restore"
my @attr_value = split('\.', $value);
if (@attr_value[-1]) {
xCAT::SvrUtils::sendmsg($api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{display_name} . ": @attr_value[-1]", $callback, $node);
}
else {
xCAT::SvrUtils::sendmsg("Unable to query value for " . $api_config_info{$::RSPCONFIG_CONFIGURED_API_KEY}{attr_url}, $callback, $node);
}
}
}
else {
@@ -3427,12 +3697,22 @@ sub rspconfig_dump_response {
$year += 1900;
my $UTC_time = sprintf ("%02d/%02d/%04d %02d:%02d:%02d", $mon, $mday, $year, $hour, $min, $sec);
$dump_info{$id} = "[$id] Generated: $UTC_time, Size: $content{Size}";
if ($::RSPCONFIG_DUMP_DOWNLOAD_ALL_REQUESTED) {
# Save dump info for later, when dump download all
$node_info{$node}{dump_info}{$id} = "[$id] Generated: $UTC_time, Size: $content{Size}";
}
}
}
xCAT::SvrUtils::sendmsg("$::NO_ATTRIBUTES_RETURNED", $callback, $node) if (!%dump_info and $node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_LIST_RESPONSE");
foreach my $key ( sort { $a <=> $b } keys %dump_info) {
xCAT::MsgUtils->message("I", { data => ["$node: $dump_info{$key}"] }, $callback) if ($dump_info{$key});
# If processing the "download all" request, do not print anything now.
# Download function dump_download_process() will be
# printing the output for each downloaded dump
unless ($::RSPCONFIG_DUMP_DOWNLOAD_ALL_REQUESTED) {
foreach my $key ( sort { $a <=> $b } keys %dump_info) {
xCAT::MsgUtils->message("I", { data => ["$node: $dump_info{$key}"] }, $callback) if ($dump_info{$key});
}
}
if (!$gen_check and $node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_CHECK_RESPONSE") {
@@ -3453,6 +3733,9 @@ sub rspconfig_dump_response {
}
}
}
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_DOWNLOAD_ALL_RESPONSE") {
&dump_download_all_process($node);
}
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_DOWNLOAD_REQUEST") {
my $child = xCAT::Utils->xfork;
@@ -3555,7 +3838,12 @@ sub dump_download_process {
return 1;
}
if ($h->{message} eq $::RESPONSE_OK) {
xCAT::SvrUtils::sendmsg("Dump $dump_id generated. Downloading to $file_name", $callback, $node);
if ($::RSPCONFIG_DUMP_DOWNLOAD_ALL_REQUESTED) {
# Slightly different message if downloading dumps as part of "download all" processing
xCAT::SvrUtils::sendmsg("Downloading dump $dump_id to $file_name", $callback, $node);
} else {
xCAT::SvrUtils::sendmsg("Dump $dump_id generated. Downloading to $file_name", $callback, $node);
}
my $curl_dwld_result = `$curl_dwld_cmd -s`;
if (!$curl_dwld_result) {
if ($xcatdebugmode) {
@@ -3584,6 +3872,27 @@ sub dump_download_process {
#-------------------------------------------------------
=head3 dump_download_all_process
Process to download all dumps
Input:
$node: nodename of current response
=cut
#-------------------------------------------------------
sub dump_download_all_process {
my $node = shift;
# Call dump_download_process for each dump id in the list
foreach my $dump_id (keys %{$node_info{$node}{dump_info}}) {
$node_info{$node}{dump_id} = $dump_id;
&dump_download_process($node);
}
}
#-------------------------------------------------------
=head3 rvitals_response
Deal with response of rvitals command
@@ -3600,53 +3909,95 @@ sub rvitals_response {
my $response_info = decode_json $response->content;
my $grep_string = $status_info{RVITALS_RESPONSE}{argv};
my $grep_string;
if ($node_info{$node}{cur_status} =~ "RVITALS_LEDS_RESPONSE") {
$grep_string = $status_info{RVITALS_LEDS_RESPONSE}{argv};
} else {
$grep_string = $status_info{RVITALS_RESPONSE}{argv};
}
my $src;
my $content_info;
my @sorted_output;
my %leds = ();
foreach my $key_url (keys %{$response_info->{data}}) {
my %content = %{ ${ $response_info->{data} }{$key_url} };
#
# Skip over attributes that are not asked to be printed
#
if ($grep_string =~ "temp") {
unless ( $content{Unit} =~ "DegreesC") { next; }
}
if ($grep_string =~ "voltage") {
unless ( $content{Unit} =~ "Volts") { next; }
}
if ($grep_string =~ "wattage") {
unless ( $content{Unit} =~ "Watts") { next; }
}
if ($grep_string =~ "fanspeed") {
unless ( $content{Unit} =~ "RPMS") { next; }
}
if ($grep_string =~ "power") {
unless ( $content{Unit} =~ "Amperes" || $content{Unit} =~ "Joules" || $content{Unit} =~ "Watts" ) { next; }
}
if ($grep_string =~ "altitude") {
unless ( $content{Unit} =~ "Meters" ) { next; }
}
my $label = (split(/\//, $key_url))[ -1 ];
# replace underscore with space, uppercase the first letter
$label =~ s/_/ /g;
$label =~ s/\b(\w)/\U$1/g;
#
# Calculate the adjusted value based on the scale attribute
#
my $calc_value = $content{Value};
if ( $content{Scale} != 0 ) {
$calc_value = ($content{Value} * (10 ** $content{Scale}));
}
my $calc_value = undef;
$content_info = $label . ": " . $calc_value . " " . $sensor_units{ $content{Unit} };
push (@sorted_output, $content_info); #Save output in array
if ($node_info{$node}{cur_status} =~ "RVITALS_LEDS_RESPONSE") {
# Print out Led info
$calc_value = (split(/\./, $content{State}))[-1];
$content_info = $label . ": " . $calc_value ;
if ($key_url =~ "fan0") { $leds{fan0} = $calc_value; }
if ($key_url =~ "fan1") { $leds{fan1} = $calc_value; }
if ($key_url =~ "fan2") { $leds{fan2} = $calc_value; }
if ($key_url =~ "fan3") { $leds{fan3} = $calc_value; }
if ($key_url =~ "front_id") { $leds{front_id} = $calc_value; }
if ($key_url =~ "front_fault") { $leds{front_fault} = $calc_value; }
if ($key_url =~ "front_power") { $leds{front_power} = $calc_value; }
if ($key_url =~ "rear_id") { $leds{rear_id} = $calc_value; }
if ($key_url =~ "rear_fault") { $leds{rear_fault} = $calc_value; }
if ($key_url =~ "rear_power") { $leds{rear_power} = $calc_value; }
} else {
# print out Sensor info
#
# Skip over attributes that are not asked to be printed
#
if ($grep_string =~ "temp") {
unless ( $content{Unit} =~ "DegreesC") { next; }
}
if ($grep_string =~ "voltage") {
unless ( $content{Unit} =~ "Volts") { next; }
}
if ($grep_string =~ "wattage") {
unless ( $content{Unit} =~ "Watts") { next; }
}
if ($grep_string =~ "fanspeed") {
unless ( $content{Unit} =~ "RPMS") { next; }
}
if ($grep_string =~ "power") {
unless ( $content{Unit} =~ "Amperes" || $content{Unit} =~ "Joules" || $content{Unit} =~ "Watts" ) { next; }
}
if ($grep_string =~ "altitude") {
unless ( $content{Unit} =~ "Meters" ) { next; }
}
#
# Calculate the adjusted value based on the scale attribute
#
$calc_value = $content{Value};
if ( $content{Scale} != 0 ) {
$calc_value = ($content{Value} * (10 ** $content{Scale}));
}
$content_info = $label . ": " . $calc_value . " " . $sensor_units{ $content{Unit} };
push (@sorted_output, $content_info); #Save output in array
}
}
if ($node_info{$node}{cur_status} =~ "RVITALS_LEDS_RESPONSE") {
$content_info = "Front . . . . . : Power:$leds{front_power} Fault:$leds{front_fault} Identify:$leds{front_id}";
push (@sorted_output, $content_info);
$content_info = "Rear . . . . . : Power:$leds{rear_power} Fault:$leds{rear_fault} Identify:$leds{rear_id}";
push (@sorted_output, $content_info);
# Fans
if ($leds{fan0} =~ "Off" and $leds{fan1} =~ "Off" and $leds{fan2} eq "Off" and $leds{fan3} eq "Off") {
$content_info = "Front Fans . . : No LEDs On";
} else {
$content_info = "Front Fans . . : fan0:$leds{fan0} fan1:$leds{fan1} fan2:$leds{fan2} fan3:$leds{fan3}";
}
push (@sorted_output, $content_info);
}
# If sorted array has any contents, sort it and print it
if (scalar @sorted_output > 0) {
# Sort the output, alpha, then numeric
@@ -3787,8 +4138,15 @@ sub rflash_response {
}
}
}
if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_ACTIVATE_RESPONSE" or $node_info{$node}{cur_status} eq "RFLASH_UPDATE_HOST_ACTIVATE_RESPONSE") {
my $flash_started_msg = "rflash started, please wait...";
if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_ACTIVATE_RESPONSE") {
my $flash_started_msg = "rflash $::UPLOAD_FILE_VERSION started, please wait...";
if ($::VERBOSE) {
xCAT::SvrUtils::sendmsg("$flash_started_msg", $callback, $node);
}
print RFLASH_LOG_FILE_HANDLE "$flash_started_msg\n";
}
if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_HOST_ACTIVATE_RESPONSE") {
my $flash_started_msg = "rflash $::UPLOAD_PNOR_VERSION started, please wait...";
if ($::VERBOSE) {
xCAT::SvrUtils::sendmsg("$flash_started_msg", $callback, $node);
}
@@ -4018,7 +4376,7 @@ sub rflash_upload {
my $content_login = '{ "data": [ "' . $node_info{$node}{username} .'", "' . $node_info{$node}{password} . '" ] }';
my $content_logout = '{ "data": [ ] }';
my $cjar_id = "/tmp/_xcat_cjar.$node";
my @curl_upload_cmds;
my %curl_upload_cmds;
# curl commands
my $curl_login_cmd = "curl -c $cjar_id -k -H 'Content-Type: application/json' -X POST $request_url/login -d '" . $content_login . "'";
my $curl_logout_cmd = "curl -b $cjar_id -k -H 'Content-Type: application/json' -X POST $request_url/logout -d '" . $content_logout . "'";
@@ -4026,7 +4384,7 @@ sub rflash_upload {
if (%fw_tar_files) {
foreach my $key (keys %fw_tar_files) {
my $curl_upload_cmd = "curl -b $cjar_id -k -H 'Content-Type: application/octet-stream' -X PUT -T " . $key . " $request_url/upload/image/";
push(@curl_upload_cmds, $curl_upload_cmd);
$curl_upload_cmds{$key}=$curl_upload_cmd;
}
}
@@ -4052,9 +4410,10 @@ sub rflash_upload {
return 1;
}
if ($h->{message} eq $::RESPONSE_OK) {
foreach my $upload_cmd(@curl_upload_cmds){
if(%curl_upload_cmds){
while((my $file,my $version)=each(%fw_tar_files)){
my $uploading_msg = "Uploading $file ...";
my $upload_cmd = $curl_upload_cmds{$file};
# Login successfull, upload the file
if ($::VERBOSE) {
xCAT::SvrUtils::sendmsg("$uploading_msg", $callback, $node);
@@ -4141,10 +4500,8 @@ sub is_valid_config_api {
$subcommand_value = $2;
}
foreach my $config_subcommand (keys %api_config_info) {
foreach my $config_attribute (keys %{ $api_config_info{$config_subcommand} }) {
if ($subcommand_key eq $api_config_info{$config_subcommand}{subcommand}) {
return $config_subcommand;
}
if ($subcommand_key eq $api_config_info{$config_subcommand}{subcommand}) {
return $config_subcommand;
}
}
return -1;
+271
View File
@@ -0,0 +1,271 @@
#!/usr/bin/perl
### IBM(c) 2017 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT_plugin::openbmc2;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use strict;
use warnings "all";
use JSON;
use Getopt::Long;
use xCAT::Utils;
use xCAT::Usage;
use xCAT::SvrUtils;
use xCAT::OPENBMC;
#-------------------------------------------------------
=head3 handled_commands
Return list of commands handled by this plugin
=cut
#-------------------------------------------------------
sub handled_commands {
return {
rflash => 'nodehm:mgt=openbmc',
rpower => 'nodehm:mgt=openbmc',
};
}
my %node_info = ();
my $callback;
#-------------------------------------------------------
=head3 preprocess_request
preprocess the command
=cut
#-------------------------------------------------------
sub preprocess_request {
my $request = shift;
$callback = shift;
if (!xCAT::OPENBMC->is_openbmc_python($request->{environment})) {
$request = {};
return;
}
my $command = $request->{command}->[0];
my $noderange = $request->{node};
my $extrargs = $request->{arg};
my @exargs = ($request->{arg});
my @requests;
if (ref($extrargs)) {
@exargs = @$extrargs;
}
my $usage_string = xCAT::Usage->parseCommand($command, @exargs);
if ($usage_string) {
$callback->({ data => [$usage_string] });
$request = {};
return;
}
my $parse_result = parse_args($command, $extrargs, $noderange);
if (ref($parse_result) eq 'ARRAY') {
my $error_data;
foreach my $node (@$noderange) {
$error_data .= "\n" if ($error_data);
$error_data .= "$node: Error: " . "$parse_result->[1]";
}
$callback->({ errorcode => [$parse_result->[0]], data => [$error_data] });
$request = {};
return;
}
my $sn = xCAT::ServiceNodeUtils->get_ServiceNode($noderange, "xcat", "MN");
foreach my $snkey (keys %$sn) {
my $reqcopy = {%$request};
$reqcopy->{node} = $sn->{$snkey};
$reqcopy->{'_xcatdest'} = $snkey;
$reqcopy->{_xcatpreprocessed}->[0] = 1;
push @requests, $reqcopy;
}
return \@requests;
}
#-------------------------------------------------------
=head3 process_request
Process the command
=cut
#-------------------------------------------------------
sub process_request {
my $request = shift;
$callback = shift;
my $noderange = $request->{node};
my $check = parse_node_info($noderange);
$callback->({ errorcode => [$check] }) if ($check);
return unless(%node_info);
my $pid = xCAT::OPENBMC::start_python_agent();
if (!defined($pid)) {
xCAT::MsgUtils->message("E", { data => ["Failed to start python agent"] }, $callback);
return;
}
xCAT::OPENBMC::submit_agent_request($pid, $request, \%node_info, $callback);
xCAT::OPENBMC::wait_agent($pid, $callback);
}
#-------------------------------------------------------
=head3 parse_args
Parse the command line options and operands
=cut
#-------------------------------------------------------
sub parse_args {
my $command = shift;
my $extrargs = shift;
my $noderange = shift;
my $subcommand = undef;
if (scalar(@ARGV) >= 2 and ($command =~ /rpower/)) {
return ([ 1, "Only one option is supported at the same time for $command" ]);
} elsif (scalar(@ARGV) == 0 and $command =~ /rpower|rflash/) {
return ([ 1, "No option specified for $command" ]);
} else {
$subcommand = $ARGV[0];
}
if ($command eq "rflash") {
my $verbose;
my ($activate, $check, $delete, $directory, $list, $upload) = (0) x 6;
my $no_host_reboot;
GetOptions(
'a|activate' => \$activate,
'c|check' => \$check,
'delete' => \$delete,
'd' => \$directory,
'l|list' => \$list,
'u|upload' => \$upload,
'V|verbose' => \$verbose,
'no-host-reboot' => \$no_host_reboot,
);
my $option_num = $activate+$check+$delete+$directory+$list+$upload;
if ($option_num >= 2) {
return ([ 1, "Multiple options are not supported."]);
} elsif ($option_num == 0) {
return ([ 1, "No options specified."]);
}
if ($activate or $check or $delete or $upload) {
return ([ 1, "More than one firmware specified is not supported."]) if ($#ARGV >= 1);
if ($check) {
return ([ 1, "Invalid firmware specified with '-c|--check'."]) if (@ARGV and ($ARGV[0] !~ /.*\.tar$/i or $#ARGV >= 1));
}
if ($activate or $delete or $upload) {
my $option = "-a|--activate";
if ($upload) {
$option = "-u|--upload";
} elsif ($delete) {
$option = "--delete"
}
return ([ 1, "Invalid firmware specified with '$option'"]) if (!@ARGV);
my $param = $ARGV[0];
return ([ 1, "Invalid firmware specified with '$option': $param"]) if (($delete and $param !~ /^[[:xdigit:]]+$/i)
or ($activate and $param !~ /^[[:xdigit:]]+$/i and $param !~ /.*\.tar$/i) or ($upload and $param !~ /.*\.tar$/i));
}
}
if ($directory) {
return ([ 1, "Unsupported command: $command '-d'" ]);
return ([ 1, "More than one directory specified is not supported."]) if ($#ARGV >= 1);
return ([ 1, "Invalid option specified with '-d'."]) if (!@ARGV);
}
if ($list) {
return ([ 1, "Invalid option specified with '-l|--list'."]) if (@ARGV);
}
} elsif ($command eq "rpower") {
unless ($subcommand =~ /^on$|^off$|^softoff$|^reset$|^boot$|^bmcreboot$|^bmcstate$|^status$|^stat$|^state$/) {
return ([ 1, "Unsupported command: $command $subcommand" ]);
}
} else {
return ([ 1, "Unsupported command: $command" ]);
}
}
#-------------------------------------------------------
=head3 parse_node_info
Parse the node information: bmc, bmcip, username, password
=cut
#-------------------------------------------------------
sub parse_node_info {
my $noderange = shift;
my $rst = 0;
my $passwd_table = xCAT::Table->new('passwd');
my $passwd_hash = $passwd_table->getAttribs({ 'key' => 'openbmc' }, qw(username password));
my $openbmc_table = xCAT::Table->new('openbmc');
my $openbmc_hash = $openbmc_table->getNodesAttribs(\@$noderange, ['bmc', 'username', 'password']);
foreach my $node (@$noderange) {
if (defined($openbmc_hash->{$node}->[0])) {
if ($openbmc_hash->{$node}->[0]->{'bmc'}) {
$node_info{$node}{bmc} = $openbmc_hash->{$node}->[0]->{'bmc'};
$node_info{$node}{bmcip} = xCAT::NetworkUtils::getNodeIPaddress($openbmc_hash->{$node}->[0]->{'bmc'});
}
unless($node_info{$node}{bmc}) {
xCAT::SvrUtils::sendmsg("Error: Unable to get attribute bmc", $callback, $node);
delete $node_info{$node};
$rst = 1;
next;
}
unless($node_info{$node}{bmcip}) {
xCAT::SvrUtils::sendmsg("Error: Unable to resolve ip address for bmc: $node_info{$node}{bmc}", $callback, $node);
delete $node_info{$node};
$rst = 1;
next;
}
if ($openbmc_hash->{$node}->[0]->{'username'}) {
$node_info{$node}{username} = $openbmc_hash->{$node}->[0]->{'username'};
} elsif ($passwd_hash and $passwd_hash->{username}) {
$node_info{$node}{username} = $passwd_hash->{username};
} else {
xCAT::SvrUtils::sendmsg("Error: Unable to get attribute username", $callback, $node);
delete $node_info{$node};
$rst = 1;
next;
}
if ($openbmc_hash->{$node}->[0]->{'password'}) {
$node_info{$node}{password} = $openbmc_hash->{$node}->[0]->{'password'};
} elsif ($passwd_hash and $passwd_hash->{password}) {
$node_info{$node}{password} = $passwd_hash->{password};
} else {
xCAT::SvrUtils::sendmsg("Error: Unable to get attribute password", $callback, $node);
delete $node_info{$node};
$rst = 1;
next;
}
} else {
xCAT::SvrUtils::sendmsg("Error: Unable to get information from openbmc table", $callback, $node);
$rst = 1;
next;
}
}
return $rst;
}
1;
+105 -2
View File
@@ -251,6 +251,8 @@ sub fill_outletCount {
my $count = $session->get("$outletoid");
if ($count) {
$pdutab->setNodeAttribs($pdu, {outlet => $count});
} else {
xCAT::SvrUtils::sendmsg("Invalid Outlet number ", $callback,$pdu);
}
return $count;
@@ -913,7 +915,7 @@ sub showMFR {
foreach my $pdu (@$noderange) {
unless ($pduhash->{$pdu}->[0]->{pdutype} eq "crpdu") {
xCAT::SvrUtils::sendmsg("This command only supports CONSTELLATION PDU with pdutype=crpdu", $callback,$pdu);
rinv_for_irpdu($pdu, $callback);
next;
}
@@ -942,6 +944,55 @@ sub showMFR {
}
}
sub rinv_for_irpdu
{
my $pdu = shift;
my $callback = shift;
my $output;
my $session = connectTopdu($pdu,$callback);
if (!$session) {
$callback->({ errorcode => [1],error => "Couldn't connect to $pdu"});
next;
}
#ibmPduSoftwareVersion
$output = $session->get(".1.3.6.1.4.1.2.6.223.7.3.0");
if ($output) {
xCAT::SvrUtils::sendmsg("PDU Software Version: $output", $callback,$pdu);
}
#ibmPduMachineType
$output = $session->get(".1.3.6.1.4.1.2.6.223.7.4.0");
if ($output) {
xCAT::SvrUtils::sendmsg("PDU Machine Type: $output", $callback,$pdu);
}
#ibmPduModelNumber
$output = $session->get(".1.3.6.1.4.1.2.6.223.7.5.0");
if ($output) {
xCAT::SvrUtils::sendmsg("PDU Model Number: $output", $callback,$pdu);
}
#ibmPduPartNumber
$output = $session->get(".1.3.6.1.4.1.2.6.223.7.6.0");
if ($output) {
xCAT::SvrUtils::sendmsg("PDU Part Number: $output", $callback,$pdu);
}
#ibmPduName
$output = $session->get(".1.3.6.1.4.1.2.6.223.7.7.0");
if ($output) {
xCAT::SvrUtils::sendmsg("PDU Name: $output", $callback,$pdu);
}
#ibmPduSerialNumber
$output = $session->get(".1.3.6.1.4.1.2.6.223.7.9.0");
if ($output) {
xCAT::SvrUtils::sendmsg("PDU Serial Number: $output", $callback,$pdu);
}
#ibmPduDescription
$output = $session->get(".1.3.6.1.4.1.2.6.223.7.10.0");
if ($output) {
xCAT::SvrUtils::sendmsg("PDU Description: $output", $callback,$pdu);
}
}
#-------------------------------------------------------
@@ -971,7 +1022,18 @@ sub showMonitorData {
foreach my $pdu (@$noderange) {
unless ($pduhash->{$pdu}->[0]->{pdutype} eq "crpdu") {
xCAT::SvrUtils::sendmsg("This command only supports CONSTELLATION PDU with pdutype=crpdu", $callback,$pdu);
my $session = connectTopdu($pdu,$callback);
if (!$session) {
$callback->({ errorcode => [1],error => "Couldn't connect to $pdu"});
next;
}
my $count = $pduhash->{$pdu}->[0]->{outlet};
unless ($count) {
$count = fill_outletCount($session, $pdu, $callback);
}
if ($count > 0) {
rvitals_for_irpdu($pdu, $count, $session, $callback);
}
next;
}
@@ -1000,6 +1062,47 @@ sub showMonitorData {
}
}
sub rvitals_for_irpdu
{
my $pdu = shift;
my $count = shift;
my $session = shift;
my $callback = shift;
my $output;
#ibmPduVoltageWarning: (voltageNormal(0),voltageOutOfRange(1))
my $voltagewarning = ".1.3.6.1.4.1.2.6.223.0.1.1.7.0";
$output = $session->get("$voltagewarning");
xCAT::SvrUtils::sendmsg("Voltage Warning: $output", $callback,$pdu);
# get power info for each outlet
# starts oid .2.6.223.8.2.2.1.7 to .2.6.223.8.2.2.1.14
#ibmPduOutletCurrent
my $outletcurrent = ".1.3.6.1.4.1.2.6.223.8.2.2.1.7";
#ibmPduOutletMaxCapacity
my $outletmaxcap = ".1.3.6.1.4.1.2.6.223.8.2.2.1.8";
#ibmPduOutletCurrentThresholdWarning
my $currentthrewarning = ".1.3.6.1.4.1.2.6.223.8.2.2.1.9";
#ibmPduOutletCurrentThresholdCritical
my $currentthrecrit = ".1.3.6.1.4.1.2.6.223.8.2.2.1.10";
#ibmPduOutletLastPowerReading
my $lastpowerreading = ".1.3.6.1.4.1.2.6.223.8.2.2.1.13";
for (my $outlet = 1; $outlet <= $count; $outlet++) {
$output = $session->get("$outletcurrent.$outlet");
xCAT::SvrUtils::sendmsg("outlet $outlet Current: $output mA", $callback,$pdu);
$output = $session->get("$outletmaxcap.$outlet");
xCAT::SvrUtils::sendmsg("outlet $outlet Max Capacity of the current: $output mA", $callback,$pdu);
$output = $session->get("$currentthrewarning.$outlet");
xCAT::SvrUtils::sendmsg("outlet $outlet Current Threshold Warning: $output mA", $callback,$pdu);
$output = $session->get("$currentthrecrit.$outlet");
xCAT::SvrUtils::sendmsg("outlet $outlet Current Threshold Critical: $output mA", $callback,$pdu);
$output = $session->get("$lastpowerreading.$outlet");
xCAT::SvrUtils::sendmsg("outlet $outlet Last Power Reading: $output Watts", $callback,$pdu);
}
}
#-------------------------------------------------------
=head3 relaystat
+28 -22
View File
@@ -434,6 +434,7 @@ sub process_request {
}
if (exists($globalopt{setup})) {
send_msg(\%request, 0, "Configure $device ....");
switchsetup($predefineswitch, \%request, $sub_req);
}
@@ -1151,7 +1152,7 @@ sub get_switchtype {
return $xCAT::data::switchinfo::global_switch_type{$key};
} else {
if (exists($globalopt{pdu})) {
return "irpdu";
return "crpdu";
}
return $key;
}
@@ -1397,8 +1398,8 @@ sub matchPredefineSwitch {
}
my $stype = get_switchtype($vendor);
if (exists($globalopt{pdu})) {
$stype="pdu";
if (exists($globalopt{pdu}) and !stype ) {
$stype="crpdu";
}
send_msg($request, 0, "$device discovered and matched: $dswitch to $node" );
@@ -1432,34 +1433,39 @@ sub switchsetup {
my $request = shift;
my $sub_req = shift;
if (exists($globalopt{pdu})) {
my $mytype = "pdu";
my $nodetab = xCAT::Table->new('hosts');
my $nodehash = $nodetab->getNodesAttribs(\@{${nodes_to_config}->{$mytype}},['ip','otherinterfaces']);
# get netmask from network table
my $nettab = xCAT::Table->new("networks");
my @nets;
if ($nettab) {
@nets = $nettab->getAllAttribs('net','mask');
}
foreach my $pdu(@{${nodes_to_config}->{$mytype}}) {
my $cmd = "rspconfig $pdu sshcfg";
xCAT::Utils->runcmd($cmd, 0);
my $ip = $nodehash->{$pdu}->[0]->{ip};
my $mask;
foreach my $net (@nets) {
if (xCAT::NetworkUtils::isInSameSubnet( $net->{'net'}, $ip, $net->{'mask'}, 0)) {
$mask=$net->{'mask'};
foreach my $mytype (keys %$nodes_to_config) {
if ( $mytype eq "irpdu" ) {
send_msg($request, 0, "the setup options for irpdu is not support yet\n");
} elsif ( $mytype eq "crpdu" ) {
my $nodetab = xCAT::Table->new('hosts');
my $nodehash = $nodetab->getNodesAttribs(\@{${nodes_to_config}->{$mytype}},['ip','otherinterfaces']);
foreach my $pdu(@{${nodes_to_config}->{$mytype}}) {
my $cmd = "rspconfig $pdu sshcfg";
xCAT::Utils->runcmd($cmd, 0);
my $ip = $nodehash->{$pdu}->[0]->{ip};
my $mask;
foreach my $net (@nets) {
if (xCAT::NetworkUtils::isInSameSubnet( $net->{'net'}, $ip, $net->{'mask'}, 0)) {
$mask=$net->{'mask'};
}
}
$cmd = "rspconfig $pdu hostname=$pdu ip=$ip netmask=$mask";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC == 0) {
xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$pdu,"ip=$ip","otherinterfaces="] }, $sub_req, 0, 1);
} else {
send_msg($request, 0, "Failed to run rspconfig command to set ip/netmask\n");
}
}
}
$cmd = "rspconfig $pdu hostname=$pdu ip=$ip netmask=$mask";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC == 0) {
xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$pdu,"ip=$ip","otherinterfaces="] }, $sub_req, 0, 1);
} else {
send_msg($request, 0, "Failed to run rspconfig command to set ip/netmask\n");
send_msg($request, 0, "the pdu type $mytype is not support\n");
}
}
return;
}
+30 -23
View File
@@ -179,6 +179,7 @@ my $xcatdir;
my $sitetab;
my $retries = 0;
xCAT::MsgUtils->trace(0, 'I', 'xcatd is going to start...');
# The database initialization may take some time in the system boot scenario
# wait for a while for the database initialization
while (!($sitetab = xCAT::Table->new('site')) && $retries < 200)
@@ -188,13 +189,13 @@ while (!($sitetab = xCAT::Table->new('site')) && $retries < 200)
$retries++;
}
unless ($sitetab) {
xCAT::MsgUtils->message("S", "ERROR: Unable to open basic site table for configuration");
xCAT::MsgUtils->message("SE", "ERROR: Unable to open basic site table for configuration");
die;
}
my ($tmp) = $sitetab->getAttribs({ 'key' => 'xcatdport' }, 'value');
unless ($tmp) {
xCAT::MsgUtils->message("S", "ERROR:Need xcatdport defined in site table, try chtab key=xcatdport site.value=3001");
xCAT::MsgUtils->message("SE", "ERROR: Need xcatdport defined in site table, try chtab key=xcatdport site.value=3001");
die;
}
$port = $tmp->{value};
@@ -376,7 +377,7 @@ sub do_installm_service {
}
unless ($socket) {
xCAT::MsgUtils->message("S", "xcatd unable to open install monitor services on $sport");
xCAT::MsgUtils->message("SE", "xcatd unable to open install monitor services on $sport");
die;
}
@@ -401,6 +402,8 @@ sub do_installm_service {
}
}
}
my $conn_peer_addr = $conn->peerhost();
xCAT::MsgUtils->trace(0, "I", "xcatd received a connection request from $conn_peer_addr");
my $client_name;
my $client_aliases;
@@ -411,11 +414,12 @@ sub do_installm_service {
} else {
($client_name, $client_aliases) = gethostbyaddr($conn->peeraddr, AF_INET);
}
unless ($client_name) {
my $addrfamily=sockaddr_family(getpeername($conn));
my $myaddr=Socket::inet_ntop($addrfamily,$conn->peeraddr);
xCAT::MsgUtils->message("S", "xcatd received a connection request from unknown host with ip address $myaddr, please check whether the reverse name resolution works correctly. The connection request will be ignored");
print "xcatd received a connection request from unknown host with ip address $myaddr, please check whether the reverse name resolution works correctly. The connection request will be ignored\n";
my $addrfamily=sockaddr_family(getpeername($conn));
my $myaddr=Socket::inet_ntop($addrfamily,$conn->peeraddr);
xCAT::MsgUtils->message("SE", "xcatd received a connection request from unknown host with ip address $myaddr, please check whether the reverse name resolution works correctly. The connection request will be ignored");
#print "xcatd received a connection request from unknown host with ip address $myaddr, please check whether the reverse name resolution works correctly. The connection request will be ignored\n";
close($conn);
next;
}
@@ -447,8 +451,8 @@ sub do_installm_service {
$validclient = 1;
last;
} else {
xCAT::MsgUtils->message("S", "xcatd received a connection request from $client, which can not be found in xCAT nodelist table. The connection request will be ignored");
print "xcatd received a connection request from $client, which can not be found in xCAT nodelist table. The connection request will be ignored\n";
xCAT::MsgUtils->message("SE", "xcatd received a connection request from $client, which can not be found in xCAT nodelist table. The connection request will be ignored");
#print "xcatd received a connection request from $client, which can not be found in xCAT nodelist table. The connection request will be ignored\n";
}
}
@@ -475,6 +479,7 @@ sub do_installm_service {
# node should be blocked, race condition may occur otherwise
#my $pid=xCAT::Utils->xfork();
#unless ($pid) { # fork off the nodeset and potential slowness
xCAT::MsgUtils->trace(0, "I", "xcatd: triggering \'nodeset $node next\'...");
plugin_command(\%request, undef, \&build_response);
#exit(0);
@@ -563,7 +568,7 @@ sub do_installm_service {
# remove the BASECUST_REMOVAL line from /tftpboot/hostname.info file
my $myfile = "/tftpboot/$text" . ".info";
`/usr/bin/cat $myfile | /usr/bin/sed "/BASECUST_REMOVAL/d">/tmp/$text.nimtmp`;
`/usr/bin/cat $myfile | /usr/bin/sed "/BASECUST_REMOVAL/d">/tmp/$text.nimtmp`;
`/usr/bin/mv /tmp/$text.nimtmp $myfile`;
close($conn);
}
@@ -573,9 +578,10 @@ sub do_installm_service {
};
if ($@) {
if ($@ =~ /XCATTIMEOUT/) {
xCAT::MsgUtils->message("S", "xcatd installmonitor timed out talking to $node");
xCAT::MsgUtils->message("S", "xcatd: install monitor timed out talking to $node");
} else {
xCAT::MsgUtils->message("S", "xcatd: possible BUG encountered by xCAT install monitor service: " . $@);
close($conn);
}
}
}
@@ -668,13 +674,13 @@ sub do_discovery_process {
}
sub do_udp_service { # This function opens up a UDP port
# It will do similar to the standard service, except:
# -Obviously, unencrypted and messages are not guaranteed
# -For that reason, more often than not plugins designed with
# -this method will not expect to have a callback
# Also, this throttles to handle one message at a time, so no forking either
# Explicitly, to handle whatever operations nodes periodically send during discover state
# Could be used for heartbeating and such as desired
# It will do similar to the standard service, except:
# -Obviously, unencrypted and messages are not guaranteed
# -For that reason, more often than not plugins designed with
# -this method will not expect to have a callback
# Also, this throttles to handle one message at a time, so no forking either
# Explicitly, to handle whatever operations nodes periodically send during discover state
# Could be used for heartbeating and such as desired
my %args = @_;
my $discoctl = $args{discoctl};
$dispatch_requests = 0;
@@ -730,7 +736,7 @@ sub do_udp_service { # This function opens up a UDP port
openlog("xcat", '', 'local4');
unless ($socket) {
xCAT::MsgUtils->message("S", "xCAT UDP service unable to open port $port: $!");
xCAT::MsgUtils->message("SE", "xCAT UDP service unable to open port $port: $!");
closelog();
die "Unable to start UDP on $port";
}
@@ -756,7 +762,7 @@ sub do_udp_service { # This function opens up a UDP port
my $tcclients; # hash reference to store traffic control requests
while (1) {
unless ($actualpid == $$) { # This really should be impossible now...
xCAT::MsgUtils->message("S", "xcatd: Something absolutely ludicrous happpened, xCAT developers think this message is impossible to see, post if you see it, fork bomb averted");
xCAT::MsgUtils->message("SE", "xcatd: Something absolutely ludicrous happpened, xCAT developers think this message is impossible to see, post if you see it, fork bomb averted");
exit(1);
}
until ($select->can_read(5)) { # Wait for data
@@ -928,7 +934,7 @@ if (defined $pid_init) {
exit(0);
}
} else {
print "Unable to branch the initialization portion, will use more memory\n";
xCAT::MsgUtils->message("SW", "WARN: Unable to branch the plugins initialization portion, will use more memory");
scan_plugins();
}
@@ -1870,7 +1876,7 @@ sub plugin_command {
$$progname = $oldprogname;
}; # REMOVEEVALFORDEBUG
if ($@) { # We are still alive, should be alive, but yet we have an error. This means we are in the case of 'do_request' or something similar. Forward up the death since our communication channel is intact..
xCAT::MsgUtils->message("S", "$@");
xCAT::MsgUtils->trace(0, "E", "$@");
die $@;
}
} else {
@@ -2012,7 +2018,8 @@ sub plugin_command {
$callback->({ error => [$error], errorcode => [1] });
xexit(0); # Die like we should have done
} elsif ($@) { # We are still alive, should be alive, but yet we have an error. This means we are in the case of 'do_request' or something similar. Forward up the death since our communication channel is intact..
xCAT::MsgUtils->message("S", "$@");
xCAT::MsgUtils->trace(0, "E", "$@");
$$progname = $oldprogname;
die $@;
}
} else {
@@ -38,15 +38,18 @@ EOF
chmod 0755 /tmp/updateflag
cd /tmp
log_label="xcat.deployment"
msgutil_r "$MASTER_IP" "info" "Executing post.xcat to prepare for firstbooting ..." "/var/log/xcat/xcat.log" "$log_label"
RAND=$(perl -e 'print int(rand(50)). "\n"')
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "sleep $RAND" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "sleep $RAND" "/var/log/xcat/xcat.log" "$log_label"
fi
sleep $RAND
# Stop if no openssl to help the next bit
if [ ! -x /usr/bin/openssl ]; then
msgutil_r "$MASTER_IP" "debug" "/usr/bin/openssl does not exist, halt ..." "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "error" "/usr/bin/openssl does not exist, halt ..." "/var/log/xcat/xcat.log" "$log_label"
/tmp/updateflag $MASTER $XCATIPORT "installstatus failed"
sleep 36500d
fi
@@ -72,33 +75,27 @@ else
fi
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "/opt/xcat/xcatinfo generated" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "/opt/xcat/xcatinfo generated" "/var/log/xcat/xcat.log" "$log_label"
fi
# download the postscripts
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "trying to download postscripts from http://$MASTER_IP$INSTALLDIR/postscripts/" "/var/log/xcat/xcat.log"
fi
msgutil_r "$MASTER_IP" "info" "trying to download postscripts from $MASTER_IP..." "/var/log/xcat/xcat.log" "$log_label"
# Stop if no wget to help the next bit
if [ ! -x /usr/bin/wget ]; then
msgutil_r "$MASTER_IP" "debug" "/usr/bin/wget does not exist, halt ..." "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "error" "/usr/bin/wget does not exist, halt ..." "/var/log/xcat/xcat.log" "$log_label"
/tmp/updateflag $MASTER $XCATIPORT "installstatus failed"
sleep 36500d
fi
wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -e robots=off -nH --cut-dirs=2 --reject "index.html*" --no-parent -t 20 -T 60 http://$MASTER_IP$INSTALLDIR/postscripts/ -P /xcatpost
if [ "$?" != "0" ]; then
msgutil_r "$MASTER_IP" "debug" "failed to download postscripts from http://$MASTER_IP$INSTALLDIR/postscripts/, halt ..." "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "error" "failed to download postscripts from http://$MASTER_IP$INSTALLDIR/postscripts/, halt ..." "/var/log/xcat/xcat.log" "$log_label"
/tmp/updateflag $MASTER $XCATIPORT "installstatus failed"
sleep 36500d
fi
chmod -R +x `find /xcatpost/ -maxdepth 1 -print | grep -E -v '^(/xcatpost/|/xcatpost/_xcat|/xcatpost/_ssh|/xcatpost/ca|/xcatpost/hostkeys)$'`
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "postscripts downloaded successfully" "/var/log/xcat/xcat.log"
fi
msgutil_r "$MASTER_IP" "info" "postscripts downloaded successfully" "/var/log/xcat/xcat.log" "$log_label"
# get the precreated mypostscript file
if [ -x /xcatpost/mypostscript ]; then
@@ -106,14 +103,12 @@ if [ -x /xcatpost/mypostscript ]; then
fi
export NODE=#TABLE:nodelist:THISNODE:node#
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "trying to download precreated mypostscript file http://$MASTER_IP$TFTPDIR/mypostscripts/mypostscript.$NODE" "/var/log/xcat/xcat.log"
fi
msgutil_r "$MASTER_IP" "info" "trying to get mypostscript from $MASTER_IP..." "/var/log/xcat/xcat.log" "$log_label"
wget -N --waitretry=10 --random-wait --retry-connrefused -t 20 -T 60 http://$MASTER_IP$TFTPDIR/mypostscripts/mypostscript.$NODE -P /xcatpost 2> /tmp/wget.log
if [ "$?" = "0" ]; then
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "precreated mypostscript downloaded successfully" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "precreated mypostscript downloaded successfully" "/var/log/xcat/xcat.log" "$log_label"
fi
mv /xcatpost/mypostscript.$NODE /xcatpost/mypostscript
chmod 700 /xcatpost/mypostscript
@@ -127,14 +122,14 @@ export XCATSERVER
# If mypostscript doesn't exist, we will get it through getpostscript.awk
if [ ! -x /xcatpost/mypostscript ]; then
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "failed to download precreated mypostscript, trying to generate with getpostscript.awk" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "no pre-generated mypostscript.<nodename>, trying to get it with getpostscript.awk..." "/var/log/xcat/xcat.log" "$log_label"
fi
# To support the postscripts in the subdirectories under /install/postscripts
# chmod +x /xcatpost/*
# Stop if no getpostscript.awk to help the next bit
if [ ! -x /xcatpost/getpostscript.awk ]; then
msgutil_r "$MASTER_IP" "debug" "/xcatpost/getpostscript.awk does not exist, halt ..." "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "error" "/xcatpost/getpostscript.awk does not exist, halt ..." "/var/log/xcat/xcat.log" "$log_label"
/tmp/updateflag $MASTER $XCATIPORT "installstatus failed"
sleep 36500d
fi
@@ -203,7 +198,7 @@ run_ps () {
fi
if [ -f \$1 ]; then
msgutil_r \"\$MASTER_IP\" \"info\" "\"\`date\` Running \$scriptype: \$1\"" \"\$logfile\"
msgutil_r \"\$MASTER_IP\" \"info\" "\"Running \$scriptype: \$1\"" \"\$logfile\" \"xcat.mypostscript\"
if [ \"\$XCATDEBUGMODE\" = \"1\" ] || [ \"\$XCATDEBUGMODE\" = \"2\" ]; then
local compt=\$(file \$1)
local reg=\"shell script\"
@@ -222,9 +217,9 @@ run_ps () {
if [ \"\$ret_local\" -ne \"0\" ]; then
return_value=\$ret_local
fi
msgutil_r \"\$MASTER_IP\" \"info\" "\"\`date\` \$scriptype \$1 return with \$ret_local\"" \"\$logfile\"
msgutil_r \"\$MASTER_IP\" \"info\" "\"\$scriptype \$1 return with \$ret_local\"" \"\$logfile\" \"xcat.mypostscript\"
else
msgutil_r \"\$MASTER_IP\" \"info\" "\"\`date\` \$scriptype \$1 does NOT exist.\"" \"\$logfile\"
msgutil_r \"\$MASTER_IP\" \"error\" "\"\$scriptype \$1 does NOT exist.\"" \"\$logfile\" \"xcat.mypostscript\"
return_value=-1
fi
@@ -242,12 +237,12 @@ fi
chmod +x /xcatpost/mypostscript
if [ ! -x /xcatpost/mypostscript ]; then
msgutil_r "$MASTER_IP" "debug" "generate mypostscript file failure, halt ..." "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "error" "failed to generate mypostscript file, halt ..." "/var/log/xcat/xcat.log" "$log_label"
/tmp/updateflag $MASTER $XCATIPORT "installstatus failed"
sleep 36500d
else
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "generate mypostscript file successfully" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "generate mypostscript file successfully" "/var/log/xcat/xcat.log" "$log_label"
fi
fi
@@ -258,12 +253,10 @@ echo "$TMP" > /xcatpost/mypostscript.post
chmod 755 /xcatpost/mypostscript.post
if [ ! -x /xcatpost/mypostscript.post ]; then
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "failed to generate /xcatpost/mypostscript.post" "/var/log/xcat/xcat.log"
fi
msgutil_r "$MASTER_IP" "error" "failed to generate /xcatpost/mypostscript.post" "/var/log/xcat/xcat.log" "$log_label"
else
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "/xcatpost/mypostscript.post generated" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "generate mypostscript.post file successfully" "/var/log/xcat/xcat.log" "$log_label"
fi
fi
@@ -280,11 +273,15 @@ if [ $hassystemd -eq 1 ] ; then
cat >/etc/systemd/system/xcatpostinit1.service <<'EOF'
#INCLUDE:/install/postscripts/xcatpostinit1.service#
EOF
msgutil_r "$MASTER_IP" "debug" "/etc/systemd/system/xcatpostinit1.service generated" "/var/log/xcat/xcat.log"
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "/etc/systemd/system/xcatpostinit1.service generated" "/var/log/xcat/xcat.log" "$log_label"
fi
ln -s /etc/systemd/system/xcatpostinit1.service /etc/systemd/system/multi-user.target.wants/xcatpostinit1.service
msgutil_r "$MASTER_IP" "debug" "xcatpostinit1.service enabled" "/var/log/xcat/xcat.log"
ln -s /etc/systemd/system/xcatpostinit1.service /etc/systemd/system/multi-user.target.wants/xcatpostinit1.service
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "xcatpostinit1.service enabled" "/var/log/xcat/xcat.log" "$log_label"
fi
cat >/opt/xcat/xcatpostinit1 << 'EOF'
#INCLUDE:/install/postscripts/xcatpostinit1.install#
EOF
@@ -296,12 +293,10 @@ EOF
chmod 755 /etc/init.d/xcatpostinit1
if [ ! -x /etc/init.d/xcatpostinit1 ]; then
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "failed to generate /etc/init.d/xcatpostinit1" "/var/log/xcat/xcat.log"
fi
msgutil_r "$MASTER_IP" "error" "failed to generate /etc/init.d/xcatpostinit1" "/var/log/xcat/xcat.log" "$log_label"
else
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "/etc/init.d/xcatpostinit1 generated" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "/etc/init.d/xcatpostinit1 generated" "/var/log/xcat/xcat.log" "$log_label"
fi
fi
@@ -326,7 +321,7 @@ EOF
#chkconfig --add xcatpostinit1
chkconfig xcatpostinit1 on
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "service xcatpostinit1 enabled" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "service xcatpostinit1 enabled" "/var/log/xcat/xcat.log" "$log_label"
fi
fi
fi
@@ -345,13 +340,13 @@ if [[ $OSVER == ubuntu* ]]; then
update-rc.d -f xcatpostinit1 remove
fi
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "update-rc.d -f xcatpostinit1 remove" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "update-rc.d -f xcatpostinit1 remove" "/var/log/xcat/xcat.log" "xcat.xcatinstallpost"
fi
else
if [[ ! "$RUNBOOTSCRIPTS" =~ ^(1|yes|y)$ ]] && [[ ! "$NODESTATUS" =~ ^(1|yes|y)$ ]]; then
chkconfig xcatpostinit1 off
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "service xcatpostinit1 disabled" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "service xcatpostinit1 disabled" "/var/log/xcat/xcat.log" "xcat.xcatinstallpost"
fi
fi
@@ -361,12 +356,10 @@ EOF
chmod 755 /opt/xcat/xcatinstallpost
if [ ! -x /opt/xcat/xcatinstallpost ]; then
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "failed to generate /opt/xcat/xcatinstallpost" "/var/log/xcat/xcat.log"
fi
msgutil_r "$MASTER_IP" "error" "failed to generate /opt/xcat/xcatinstallpost" "/var/log/xcat/xcat.log" "$log_label"
else
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "/opt/xcat/xcatinstallpost generated" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "/opt/xcat/xcatinstallpost generated" "/var/log/xcat/xcat.log" "$log_label"
fi
fi
@@ -378,12 +371,10 @@ EOF
chmod 755 /opt/xcat/xcatdsklspost
if [ ! -x /opt/xcat/xcatdsklspost ]; then
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "failed to generate /opt/xcat/xcatdsklspost" "/var/log/xcat/xcat.log"
fi
msgutil_r "$MASTER_IP" "error" "failed to generate /opt/xcat/xcatdsklspost" "/var/log/xcat/xcat.log" "$log_label"
else
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "/opt/xcat/xcatdsklspost generated" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "/opt/xcat/xcatdsklspost generated" "/var/log/xcat/xcat.log" "$log_label"
fi
fi
@@ -415,11 +406,11 @@ export CONSOLEPORT=#TABLEBLANKOKAY:nodehm:THISNODE:serialport#
#WRITEREPO#
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "info" "running mypostscript" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "info" "running mypostscript" "/var/log/xcat/xcat.log" "$log_label"
fi
/xcatpost/mypostscript
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "info" "mypostscript returned" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "info" "mypostscript returned" "/var/log/xcat/xcat.log" "$log_label"
fi
@@ -482,14 +473,12 @@ else
[ -f /boot/grub/grub.conf ] && sed -i 's/^serial/#serial/' /boot/grub/grub.conf
[ -f /boot/grub/grub.conf ] && sed -i 's/^terminal/#terminal/' /boot/grub/grub.conf
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "debug" "/boot/grub/grub.conf updated" "/var/log/xcat/xcat.log"
msgutil_r "$MASTER_IP" "debug" "/boot/grub/grub.conf updated" "/var/log/xcat/xcat.log" "$log_label"
fi
fi
if [ "$XCATDEBUGMODE" = "1" ] || [ "$XCATDEBUGMODE" = "2" ]; then
msgutil_r "$MASTER_IP" "info" "finished node installation, reporting status..." "/var/log/xcat/xcat.log"
fi
msgutil_r "$MASTER_IP" "info" "finished firstboot preparation, sending request to $MASTER:3002 for changing status..." "/var/log/xcat/xcat.log" "$log_label"
#the following command should always be run to prevent infinite installation loops
updateflag.awk $MASTER 3002
@@ -3,24 +3,29 @@ declare -F msgutil_r &>/dev/null || function msgutil_r {
local msgtype=$2
local msgstr=$3
local logfile=$4
local logtag=$5
if [ -z "$msgtype" ]; then
msgtype="debug"
fi
if [ -z "$logtag" ]; then
logtag="xcat"
fi
if [ -n "$logserver" ];then
logger -n $logserver -t xcat -p local4.$msgtype "$msgstr"
logger -n $logserver -t $logtag -p local4.$msgtype "$msgstr"
if [ "$?" != "0" ];then
exec 3<>/dev/udp/$logserver/514 >/dev/null;logger -s -t xcat -p local4.$msgtype "$msgstr" 2>&3
exec 3<>/dev/udp/$logserver/514 >/dev/null;logger -s -t $logtag -p local4.$msgtype "$msgstr" 2>&3
if [ "$?" != "0" ];then
logger -s -t xcat -p local4.$msgtype "$msgstr" 2>&1|nc $logserver 514 >/dev/null 2>&1
logger -s -t $logtag -p local4.$msgtype "$msgstr" 2>&1|nc $logserver 514 >/dev/null 2>&1
if [ "$?" != "0" ];then
logger -t xcat -p local4.$msgtype "$msgstr"
logger -t $logtag -p local4.$msgtype "$msgstr"
fi
fi
fi
else
logger -t xcat -p local4.$msgtype "$msgstr"
logger -t $logtag -p local4.$msgtype "$msgstr"
fi
if [ -n "$logfile" ]; then
local logdir="$(dirname $logfile)"
@@ -29,7 +34,7 @@ declare -F msgutil_r &>/dev/null || function msgutil_r {
touch "$logfile"
fi
echo "$msgstr" >> $logfile
echo "$(date) [$msgtype]: $logtag: $msgstr" >> $logfile
fi
}
@@ -1,5 +1,5 @@
#!/bin/sh
log_label="xcat.dracut_033"
log_label="xcat.deployment"
NEWROOT=$3
RWDIR=.statelite
@@ -11,7 +11,6 @@ STATEMNT="$(getarg STATEMNT=)"
rootlimit="$(getarg rootlimit=)"
xcatdebugmode="$(getarg xcatdebugmode=)"
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "in dracut, executing xcatroot..."
getarg nonodestatus
NODESTATUS=$?
@@ -21,10 +20,13 @@ if [ $? -ne 0 ]; then
XCATIPORT="3002"
fi
[ "$xcatdebugmode" = "1" -o "$xcatdebugmode" = "2" ] && SYSLOGHOST="" || SYSLOGHOST="-n $MASTER"
logger $SYSLOGHOST -t $log_label -p local4.info "Executing xcatroot to prepare for netbooting (dracut_33)..."
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "MASTER=$MASTER XCATIPORT=$XCATIPORT NODESTATUS=$NODESTATUS"
if [ "$NODESTATUS" != "0" ]; then
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "Reporting installstatus=netbooting..."
logger $SYSLOGHOST -t $log_label -p local4.info "Sending request to $MASTER:$XCATIPORT for changing status to netbooting..."
/tmp/updateflag $MASTER $XCATIPORT "installstatus netbooting"
fi
@@ -32,14 +34,16 @@ fi
imgurl="$(getarg imgurl=)";
if [ ! -z "$imgurl" ]; then
if [ xhttp = x${imgurl%%:*} ]; then
logger $SYSLOGHOST -t $log_label -p local4.info "Downloading rootfs image from $imgurl..."
NFS=0
FILENAME=${imgurl##*/}
while [ ! -r "$FILENAME" ]; do
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "Downloading $imgurl..."
echo Getting $imgurl...
if ! wget -nv $imgurl; then
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "Downloading $imgurl FAILED, retrying..."
logger $SYSLOGHOST -t $log_label -p local4.error "Downloading $imgurl FAILED, retrying..."
rm -f $FILENAME
echo Failed to get the image, waiting for next retrying...
sleep 27
fi
done
@@ -53,6 +57,7 @@ if [ ! -z "$imgurl" ]; then
SERVER=${SERVER%%/*}
SERVER=${SERVER%:}
ROOTDIR=/${ROOTDIR#*/}
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "SERVER=$SERVER ROOTDIR=$ROOTDIR"
fi
fi
#echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug
@@ -70,7 +75,7 @@ if [ -r /rootimg.sfs ]; then
mount --move /ro $NEWROOT/ro
mount --move /rw $NEWROOT/rw
elif [ -r /rootimg.cpio.gz ] || [ -r /rootimg.cpio.xz ]; then
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "Downloaded rootimg.cpio.[gz/xz]...Setting up RAM-root tmpfs."
logger $SYSLOGHOST -t $log_label -p local4.info "Setting up RAM-root tmpfs on downloaded rootimg.cpio.[gz/xz]..."
echo Setting up RAM-root tmpfs.
if [ -z $rootlimit ];then
mount -t tmpfs -o mode=755 rootfs $NEWROOT
@@ -98,7 +103,7 @@ elif [ -r /rootimg.cpio.gz ] || [ -r /rootimg.cpio.xz ]; then
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "Done extracting the root filesystem..."
echo "Done extracting the root filesystem..."
elif [ -r /rootimg.tar.gz ] || [ -r /rootimg.tar.xz ]; then
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "Downloaded rootimg.tar.[gz/xz]...Setting up RAM-root tmpfs."
logger $SYSLOGHOST -t $log_label -p local4.info "Setting up RAM-root tmpfs on downloaded rootimg.tar.[gz/xz]..."
echo Setting up RAM-root tmpfs.
if [ -z $rootlimit ];then
mount -t tmpfs -o mode=755 rootfs $NEWROOT
@@ -121,11 +126,13 @@ elif [ -r /rootimg.tar.gz ] || [ -r /rootimg.tar.xz ]; then
fi
fi
$NEWROOT/etc/init.d/localdisk
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "Done extracting the root filesystem."
echo "Done extracting the root filesystem."
msg="Done extracting the root filesystem."
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "$msg"
echo "$msg"
elif [ -r /rootimg-statelite.gz ]; then
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "Setting up RAM-root tmpfs for statelite mode."
echo Setting up RAM-root tmpfs for statelite mode.
msg="Setting up RAM-root tmpfs for statelite mode."
logger $SYSLOGHOST -t $log_label -p local4.info "$msg"
echo "$msg"
if [ -z $rootlimit];then
mount -t tmpfs -o mode=755 rootfs $NEWROOT
@@ -134,17 +141,22 @@ elif [ -r /rootimg-statelite.gz ]; then
fi
cd $NEWROOT
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "Extracting the root filesystem..."
echo "Extracting root filesystem..."
msg="Extracting root filesystem..."
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "$msg"
echo "$msg"
if [ -x /bin/cpio ]; then
gzip -cd /rootimg-statelite.gz |/bin/cpio -idum
else
gzip -cd /rootimg-statelite.gz |cpio -idum
fi
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "Done extracting the root filesystem."
echo "Done extracting the root filesystem."
msg="Done extracting the root filesystem."
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "$msg"
echo "$msg"
# then, the statelite staffs will be processed
echo Setting up Statelite
msg="Setting up Statelite..."
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "$msg"
echo "$msg"
modprobe nfs
MAXTRIES=7
ITER=0
@@ -194,8 +206,8 @@ elif [ -r /rootimg-statelite.gz ]; then
if [ "$ITER" == "$MAXTRIES" ]; then
echo "You are dead, rpower $ME boot to play again."
echo "Possible problems:
1. $SNAPSHOTSERVER is not exporting $SNAPSHOTROOT ?
2. Is DNS set up? Maybe that's why I can't mount $SNAPSHOTSERVER."
1. $SNAPSHOTSERVER is not exporting $SNAPSHOTROOT ?
2. Is DNS set up? Maybe that's why I can't mount $SNAPSHOTSERVER."
/bin/sh
exit
fi
@@ -249,8 +261,9 @@ elif [ -r /rootimg-statelite.gz ]; then
mount -n --bind /sys $NEWROOT/sys
else
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "Failed to download image, panic in 5..."
echo -n Failed to download image, panic in 5...
msg="Failed to download image, panic in 5..."
logger $SYSLOGHOST -t $log_label -p local4.error "$msg"
echo -n "$msg"
for i in 4 3 2 1 0; do
/bin/sleep 1
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "$i..."
@@ -342,7 +355,7 @@ if [ -d "$NEWROOT/etc/sysconfig" -a ! -e "$NEWROOT/etc/sysconfig/selinux" ]; the
echo "SELINUX=disabled" >> "$NEWROOT/etc/sysconfig/selinux"
fi
[ "$xcatdebugmode" > "0" ] && logger -t $log_label -p local4.debug "exiting xcatroot..."
logger $SYSLOGHOST -t $log_label -p local4.info "Exiting xcatroot..."
# inject new exit_if_exists
echo 'settle_exit_if_exists="--exit-if-exists=/dev/root"; rm "$job"' > $hookdir/initqueue/xcat.sh
# force udevsettle to break
+2 -2
View File
@@ -7,8 +7,8 @@ RewriteCond %{HTTPS} !=on
RewriteRule ^/?xcatws/(.*) https://%{SERVER_NAME}/xcatws/$1 [R,L]
RewriteRule ^/?xcatwsv2/(.*) https://%{SERVER_NAME}/xcatwsv2/$1 [R,L]
<Files (xcatws.cgi|zvmxcatws.cgi)>
<FilesMatch "^(xcatws.cgi|zvmxcatws.cgi)$">
Order allow,deny
Allow from all
</Files>
</FilesMatch>

Some files were not shown because too many files have changed in this diff Show More