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:
+6
-1
@@ -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%
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
+93
@@ -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 node’s 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.
|
||||
+1
@@ -0,0 +1 @@
|
||||
.. include:: ../../../../common/deployment/network/cfg_routes.rst
|
||||
+1
@@ -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
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
.. include:: ../../../../common/deployment/network/cfg_routes.rst
|
||||
+1
@@ -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.
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
:maxdepth: 1
|
||||
|
||||
20171212_tls.rst
|
||||
20171207_openssl.rst
|
||||
20170828_openssl.rst
|
||||
20170216_openssl.rst
|
||||
20170126_openssl.rst
|
||||
|
||||
Executable
+38
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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" .
|
||||
|
||||
@@ -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>]
|
||||
|
||||
@@ -42,6 +42,8 @@ our %global_switch_type = (
|
||||
Cumulus => "onie",
|
||||
cumulus => "onie",
|
||||
Edgecore => "onie",
|
||||
sLEN => "irpdu",
|
||||
sIBM => "irpdu",
|
||||
coral => "crpdu"
|
||||
);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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 )
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 -
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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/*
|
||||
|
||||
Executable
+52
@@ -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:])
|
||||
Executable
+76
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Executable → Regular
+23
-2
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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" });
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user