diff --git a/README.rst b/README.rst
index a8377c82e..6d1848fbf 100644
--- a/README.rst
+++ b/README.rst
@@ -8,7 +8,7 @@ Documentation
xCAT documentation is available at: http://xcat-docs.readthedocs.io/en/latest/
-|docs_latest| |docs_2137| |docs_2136| |docs_2135| |docs_2134| |docs_2133| |docs_2132| |docs_2131| |docs_2130| |docs_212|
+|docs_latest| |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 `_
In particular the `GitHub `_ related subsection.
+.. |docs_2138| image:: https://readthedocs.org/projects/xcat-docs/badge/?version=2.13.8
+ :alt: 2.13.8 documentation status
+ :scale: 100%
+ :target: http://xcat-docs.readthedocs.io/en/2.13.8/
+
.. |docs_2137| image:: https://readthedocs.org/projects/xcat-docs/badge/?version=2.13.7
:alt: 2.13.7 documentation status
:scale: 100%
diff --git a/Version b/Version
index c38dd67f3..6ad4f1e46 100644
--- a/Version
+++ b/Version
@@ -1 +1 @@
-2.13.8
+2.13.9
diff --git a/docs/source/QA/index.rst b/docs/source/QA/index.rst
new file mode 100644
index 000000000..00069abdd
--- /dev/null
+++ b/docs/source/QA/index.rst
@@ -0,0 +1,7 @@
+Q/A list
+========
+
+.. toctree::
+ :maxdepth: 2
+
+ makehosts_qa.rst
diff --git a/docs/source/QA/makehosts_qa.rst b/docs/source/QA/makehosts_qa.rst
new file mode 100644
index 000000000..f0c425b87
--- /dev/null
+++ b/docs/source/QA/makehosts_qa.rst
@@ -0,0 +1,132 @@
+DNS,hostname and alias Q/A list
+-------------------------------
+
+Q: When there are multiple NICs, how to generate ``/etc/hosts`` records?
+````````````````````````````````````````````````````````````````````````
+
+When there are multiple NICs, and you want to use ``confignetwork`` to configure these NICs, suggest to use ``hosts`` table to configure installnic and use ``nics`` table to configure secondary NICs. You can refer to the following best practice example to generate ``/etc/hosts`` records.
+
+**Best practice example**:
+
+ * There are 2 networks in different domains: ``mgtnetwork`` and ``pubnetwork``
+ * ``mgtnetwork`` is xCAT management network
+ * There are 2 adapters in system node1: ``eth0`` and ``eth1``
+ * Add installnic ``eth0`` ``10.5.106.101`` record in ``/etc/hosts``, its alias is ``mgtnic``
+ * hostnames ``node1-pub`` and ``node1.public.com`` are for nic ``eth1``, ip is ``192.168.30.101``
+
+**Steps**:
+
+ #. Add networks entry in ``networks`` table: ::
+
+ chdef -t network mgtnetwork net=10.0.0.0 mask=255.0.0.0 domain=cluster.com
+ chdef -t network pubnetwork net=192.168.30.0 mask=255.255.255.0 domain=public.com
+
+ #. Create ``node1`` with installnic ip ``10.5.106.101``, its alias is ``mgtnic``: ::
+
+ chdef node1 ip=10.5.106.101 hostnames=mgtnic groups=all
+
+ #. Configure ``eth1`` in ``nics`` table: ::
+
+ chdef node1 nicips.eth1=192.168.30.101 nichostnamesuffixes.eth1=-pub nicaliases.eth1=node1.public.com nictypes.eth1=Ethernet nicnetworks.eth1=pubnetwork
+
+ #. Check ``node1`` definition: ::
+
+ lsdef node1
+ Object name: node1
+ groups=all
+ ip=10.5.106.101
+ hostnames=mgtnic
+ nicaliases.eth1=node1.public.com
+ nichostnamesuffixes.eth1=-pub
+ nicips.eth1=192.168.30.101
+ nicnetworks.eth1=pubnetwork
+ nictypes.eth1=Ethernet
+ postbootscripts=otherpkgs
+ postscripts=syslog,remoteshell,syncfiles
+
+ #. Execute ``makehosts -n`` to generate ``/etc/hosts`` records: ::
+
+ makehosts -n
+
+ #. Check results in ``/etc/hosts``: ::
+
+ 10.5.106.101 node1 node1.cluster.com mgtnic
+ 192.168.30.101 node1-pub node1.public.com
+
+ #. Edit ``/etc/resolv.conf``, xCAT management node ip like ``10.5.106.2`` is nameserver: ::
+
+ search cluster.com public.com
+ nameserver 10.5.106.2
+
+ #. Execute ``makedns -n`` to configure DNS
+
+Q: How to configure aliases?
+````````````````````````````
+
+There are 3 methods to configure aliases:
+
+#. Use ``hostnames`` in ``hosts`` table to configure aliases for the installnic.
+#. If you want to use script ``confignetwork`` to configure secondary NICs, suggest to use ``aliases`` in ``nics`` table to configure aliases, you can refer to :doc:`Configure Aliases <../guides/admin-guides/manage_clusters/common/deployment/network/cfg_network_aliases>`
+#. If you want to generate aliases records in ``/etc/hosts`` for secondary NICs, and don't want to use script ``confignetwork`` to configure these NICs, suggest to use ``otherinterfaces`` in ``hosts`` table to configure aliases. You can refer to following example:
+
+ * If you want to add ``node1-hd`` ``20.1.1.1`` in ``hosts`` table, and don't use ``confignetwork`` to configure it, you can add ``otherinterfaces`` like this: ::
+
+ chdef node1 otherinterfaces="node1-hd:20.1.1.1"
+
+ * After executing ``makehosts -n``, you can get records in ``/etc/hosts`` like following: ::
+
+ 20.1.1.1 node1-hd
+
+**Note**: If suffixes or aliases for the same IP are configured in both ``hosts`` table and ``nics`` table, will cause conflicts. ``makehosts`` will use values from ``nics`` table. The values from ``nics`` table will over-write that from ``hosts`` table to create ``/etc/hosts`` records.
+
+Q: How to handle the same short hostname in different domains?
+``````````````````````````````````````````````````````````````
+
+You can follow the best practice example.
+
+**Best practice example**:
+
+ * There are 2 networks in different domains: ``mgtnetwork`` and ``pubnetwork``
+ * ``mgtnetwork`` is xCAT management network
+ * Generate 2 records with the same hostname in ``/etc/hosts``, like: ::
+
+ 10.5.106.101 node1.cluster.com
+ 192.168.20.101 node1.public.com
+
+ * Nameserver is xCAT management node IP
+
+**Steps**:
+
+ #. Add networks entry in ``networks`` table: ::
+
+ chdef -t network mgtnetwork net=10.0.0.0 mask=255.0.0.0 domain=cluster.com
+ chdef -t network pubnetwork net=192.168.30.0 mask=255.255.255.0 domain=public.com
+
+ #. Create ``node1`` with ``ip=10.5.106.101``, xCAT can manage and install this node: ::
+
+ chdef node1 ip=10.5.106.101 groups=all
+
+ #. Create ``node1-pub`` with ``ip=192.168.30.101``, this node is only used to generate ``/etc/hosts`` records for public network, can use ``_unmanaged`` group name to label it: ::
+
+ chdef node1-pub ip=192.168.30.101 hostnames=node1.public.com groups=_unmanaged
+
+ #. Execute ``makehosts -n`` to generate ``/etc/hosts`` records: ::
+
+ makehosts -n
+
+ #. Check results in ``/etc/hosts``: ::
+
+ 10.5.106.101 node1 node1.cluster.com
+ 192.168.30.101 node1-pub node1.public.com
+
+ #. Edit ``/etc/resolv.conf``, for example, xCAT management node IP is 10.5.106.2 : ::
+
+ search cluster.com public.com
+ nameserver 10.5.106.2
+
+ #. Execute ``makedns -n`` to configure DNS
+
+Q: When to use ``hosts`` table and ``nics`` table?
+``````````````````````````````````````````````````
+
+``hosts`` table is used to store IP addresses and hostnames of nodes. ``makehosts`` use these data to create ``/etc/hosts`` records. ``nics`` table is used to stores secondary NICs details. Some scripts like ``confignetwork`` use data from ``nics`` table to configure secondary NICs. ``makehosts`` also use these data to create ``/etc/hosts`` records for each NIC.
diff --git a/docs/source/advanced/index.rst b/docs/source/advanced/index.rst
index 8c84eb6ac..820e899d8 100755
--- a/docs/source/advanced/index.rst
+++ b/docs/source/advanced/index.rst
@@ -23,6 +23,5 @@ Advanced Topics
restapi/index.rst
security/index.rst
softlayer/index.rst
- switches/index.rst
sysclone/index.rst
zones/index.rst
diff --git a/docs/source/advanced/networks/index.rst b/docs/source/advanced/networks/index.rst
index cd29cd51f..83fe4c232 100644
--- a/docs/source/advanced/networks/index.rst
+++ b/docs/source/advanced/networks/index.rst
@@ -1,5 +1,5 @@
-Networks
-========
+Networking
+==========
.. toctree::
:maxdepth: 2
diff --git a/docs/source/advanced/networks/onie_switches/os_cumulus/install.rst b/docs/source/advanced/networks/onie_switches/os_cumulus/install.rst
index 8915d02af..b10dd9a79 100644
--- a/docs/source/advanced/networks/onie_switches/os_cumulus/install.rst
+++ b/docs/source/advanced/networks/onie_switches/os_cumulus/install.rst
@@ -12,12 +12,16 @@ xCAT provides support for detecting and installing the Cumulus Linux OS into ONI
The mac address of the switch management port is required for xCAT to configure the DHCP information and send over the OS to install on the switch.
- **[small clusters]** If you know the mac address of the management port on the switch, create the pre-defined switch definition providing the mac address. ::
+ **Small Clusters**
+
+ If you know the mac address of the management port on the switch, create the pre-defined switch definition providing the mac address. ::
mkdef frame01sw1 --template onieswitch arch=armv71 \
ip=192.168.1.1 mac="aa:bb:cc:dd:ee:ff"
- **[large clusters]** xCAT's :doc:`switchdiscover ` command can be used to discover the mac address and fill in the predefined switch definitions based on the switch/switchport mapping.
+ **Large Clusters**
+
+ xCAT's :doc:`switchdiscover ` command can be used to discover the mac address and fill in the predefined switch definitions based on the switch/switchport mapping.
#. Define all the switch objects providing the switch/switchport mapping: ::
diff --git a/docs/source/advanced/networks/onie_switches/os_cumulus/manage.rst b/docs/source/advanced/networks/onie_switches/os_cumulus/manage.rst
index 512c4b1f4..b2976f56a 100644
--- a/docs/source/advanced/networks/onie_switches/os_cumulus/manage.rst
+++ b/docs/source/advanced/networks/onie_switches/os_cumulus/manage.rst
@@ -4,7 +4,19 @@ Switch Management
Switch Port and VLAN Configuration
----------------------------------
-xCAT expects the configuration for the front-panel ports to be located at ``/etc/network/interfaces.d/xCAT.intf`` on the switch. The ``configinterface`` postscript can download an interface configuration file from the management node. Place the configuration file in the directory ``/install/custom/sw_os/cumulus/interface/`` on the management node. It will first look for a file named the same as the switch's hostname, followed by the name of each group, followed by the word 'default'. If the postscript cannot find a configuration file on the management node, it will set all the ports on the switch to be part of VLAN 1. See the Cumulus Networks documentation for more information regarding advanced networking configuration. ::
+xCAT places the front-panel port configuration in ``/etc/network/interfaces.d/xCAT.intf``.
+
+The ``configinterface`` postscript can be used to pull switch interface configuration from the xCAT Management Node (MN) to the switch. Place the switch specific confguration files in the following directory on the MN: ``/install/custom/sw_os/cumulus/interface/``.
+
+xCAT will look for files in the above directory in the following order:
+
+ 1. file name that matches the switch hostname
+ 2. file name that matches the switch group name
+ 3. file name that has the word 'default'
+
+ Note: If the postscript cannot find a configuration file on the MN, it will set all ports on the switch to be part of VLAN 1.
+
+Execute the script using the following command: ::
updatenode -P configinterface
@@ -12,9 +24,11 @@ xCAT expects the configuration for the front-panel ports to be located at ``/etc
Re-install OS
-------------
-There may be occasions where a re-install of the OS is required. Assuming the files are available on the xCAT management node, the following commands will invoke the install process:
+There may be occasions where a re-install of the Cumulus Linux OS is required. The following commands can be used to invoke the install:
-* **[use xCAT]** ``xdsh`` can be used to invoke the reinstall of the OS: ::
+**Note:** Assumption that the Cumulus Linux files are on the xCAT MN in the correct place.
+
+* **Using xCAT**, ``xdsh`` can invoke the reinstall of the OS: ::
# to clear out all the previous configuration, use the -k option (optional)
xdsh "/usr/cumulus/bin/onie-select -k
@@ -22,7 +36,7 @@ There may be occasions where a re-install of the OS is required. Assuming the
# to invoke the reinstall of the OS
xdsh "/usr/cumulus/bin/onie-select -i -f;reboot"
-* **[manually]** Log into the Cumulus OS switch and run the following commands: ::
+* **Manually**, log into the switch and run the following commands: ::
sudo onie-select -i
sudo reboot
diff --git a/docs/source/advanced/networks/onie_switches/os_cumulus/upgrade.rst b/docs/source/advanced/networks/onie_switches/os_cumulus/upgrade.rst
index da079129c..ff125998e 100644
--- a/docs/source/advanced/networks/onie_switches/os_cumulus/upgrade.rst
+++ b/docs/source/advanced/networks/onie_switches/os_cumulus/upgrade.rst
@@ -1,62 +1,79 @@
-Cumulus OS upgrade
+Cumulus OS Upgrade
==================
-The Cumulus OS on the ONIE switches can be upgraded in 2 ways:
+The Cumulus OS on the ONIE switches can be upgraded using one of the following methods:
-* Upgrade only the changed packages, using ``apt-get update`` and ``apt-get upgrade``. If the ONIE switches has internet access, this is the preferred method, otherwise, you need to build up a local cumulus mirror in the cluster.
+Full Install
+------------
- Since in a typical cluster setup, the switches usually do not have internet access, you can create a local mirror on the server which has internet access and can be reached from the switches, the steps are ::
+Perform a full install from the ``.bin`` file of the new Cumulus Linux OS version, using ONIE.
+
+**Note:** Make sure you back up all your data and configuration files as the binary install will erase all previous configuration.
- mkdir -p /install/mirror/cumulus
- cd /install/mirror/cumulus
- #the wget might take a long time, it will be better if you can set up
- #a cron job to sync the local mirror with upstream
- wget -m --no-parent http://repo3.cumulusnetworks.com/repo/
-
- then compose a ``sources.list`` file on MN like this(take 172.21.253.37 as ip address of the local mirror server) ::
+#. Place the binary image under ``/install`` on the xCAT MN node.
- #cat /tmp/sources.list
- deb http://172.21.253.37/install/mirror/cumulus/repo3.cumulusnetworks.com/repo CumulusLinux-3 cumulus upstream
- deb-src http://172.21.253.37/install/mirror/cumulus/repo3.cumulusnetworks.com/repo CumulusLinux-3 cumulus upstream
-
- deb http://172.21.253.37/install/mirror/cumulus/repo3.cumulusnetworks.com/repo CumulusLinux-3-security-updates cumulus upstream
- deb-src http://172.21.253.37/install/mirror/cumulus/repo3.cumulusnetworks.com/repo CumulusLinux-3-security-updates cumulus upstream
-
- deb http://172.21.253.37/install/mirror/cumulus/repo3.cumulusnetworks.com/repo CumulusLinux-3-updates cumulus upstream
- deb-src http://172.21.253.37/install/mirror/cumulus/repo3.cumulusnetworks.com/repo CumulusLinux-3-updates cumulus upstream
-
- distribute the ``sources.list`` file to the switches to upgrade with ``xdcp``, take "switch1" as an example here ::
-
- xdcp switch1 /tmp/sources.list /etc/apt/sources.list
-
- then invoke ``apt-get update`` and ``apt-get install`` on the switches to start package upgrade, a reboot might be needed after upgrading ::
-
- xdsh switch1 'apt-get update && apt-get upgrade && reboot'
-
- check the `/etc/os-release` file to make sure the Cumulus OS has been upgraded ::
-
- cat /etc/os-release
-
-
-
-* Performe a binary (full image) install of the new version, using ONIE. If you expect to upgrade between major versions or if you have the binary image to upgrade to, this way is the recommended one. Make sure to backup your data and configuration files because binary install will erase all the configuration and data on the switch.
-
- The steps to perform a binary (full image) install of the new version are:
-
- 1) place the binary image "cumulus-linux-3.4.1.bin" under ``/install`` directory on MN("172.21.253.37") ::
+ In this example, IP=172.21.253.37 is the IP on the Management Node. ::
mkdir -p /install/onie/
cp cumulus-linux-3.4.1.bin /install/onie/
- 2) invoke the upgrade on switches with ``xdsh`` ::
+#. Invoke the upgrade on the switches using :doc:`xdsh `: ::
- xdsh switch1 "/usr/cumulus/bin/onie-install -a -f -i http://172.21.253.37/install/onie/cumulus-linux-3.4.1.bin && reboot"
+ xdsh switch1 "/usr/cumulus/bin/onie-install -a -f -i \
+ http://172.21.253.37/install/onie/cumulus-linux-3.4.1.bin && reboot"
- The full upgrade process might cost 30 min, you can ping the switch with ``ping switch1`` to check whether it finishes upgrade.
-
- 3) After upgrading, the license should be installed, see :ref:`Activate the License ` for detailed steps.
+ **Note:** The full upgrade process may run 30 minutes or longer.
+
+#. After upgrading, the license should be installed, see :ref:`Activate the License ` for details.
+
+#. Restore your data and configuration files on the switch.
+
+
+
+Update Changed Packages
+-----------------------
+
+This is the preferred method for upgrading the switch OS for incremental OS updates.
+
+Create Local Mirror
+```````````````````
+
+If the switches do not have access to the public Internet, you can create a local mirror of the Cumulus Linux repo.
+
+#. Create a local mirror on the Management Node: ::
- 4) Restore your data and configuration files on the switch.
+ mkdir -p /install/mirror/cumulus
+ cd /install/mirror/cumulus
+ wget -m --no-parent http://repo3.cumulusnetworks.com/repo/
+
+#. Create a ``sources.list`` file to point to the local repo on the Management node. In this example, IP=172.21.253.37 is the IP on the Management Node. ::
+
+ # cat /tmp/sources.list
+ deb http://172.21.253.37/install/mirror/cumulus/repo3.cumulusnetworks.com/repo CumulusLinux-3 cumulus upstream
+ deb-src http://172.21.253.37/install/mirror/cumulus/repo3.cumulusnetworks.com/repo CumulusLinux-3 cumulus upstream
+
+ deb http://172.21.253.37/install/mirror/cumulus/repo3.cumulusnetworks.com/repo CumulusLinux-3-security-updates cumulus upstream
+ deb-src http://172.21.253.37/install/mirror/cumulus/repo3.cumulusnetworks.com/repo CumulusLinux-3-security-updates cumulus upstream
+
+ deb http://172.21.253.37/install/mirror/cumulus/repo3.cumulusnetworks.com/repo CumulusLinux-3-updates cumulus upstream
+ deb-src http://172.21.253.37/install/mirror/cumulus/repo3.cumulusnetworks.com/repo CumulusLinux-3-updates cumulus upstream
+
+
+#. Distribute the ``sources.list`` file to your switches using :doc:`xdcp `. ::
+
+ xdcp switch1 /tmp/sources.list /etc/apt/sources.list
+
+Invoke the Update
+`````````````````
+
+#. Use xCAT :doc:`xdsh ` to invoke the update: ::
+
+ #
+ # A reboot may be needed after the upgrade
+ #
+ xdsh switch1 'apt-get update && apt-get upgrade && reboot'
+
+#. Check in ``/etc/os-release`` file to verify that the OS has been upgraded.
diff --git a/docs/source/advanced/security/index.rst b/docs/source/advanced/security/index.rst
index 5fdc56f08..790979759 100644
--- a/docs/source/advanced/security/index.rst
+++ b/docs/source/advanced/security/index.rst
@@ -6,4 +6,5 @@ The security of a system covers a wide range of elements, from the security of s
.. toctree::
:maxdepth: 2
- security
+ ssl_config.rst
+ security.rst
diff --git a/docs/source/advanced/security/ssl_config.rst b/docs/source/advanced/security/ssl_config.rst
new file mode 100644
index 000000000..3ea6f360b
--- /dev/null
+++ b/docs/source/advanced/security/ssl_config.rst
@@ -0,0 +1,56 @@
+OpenSSL Configuration
+=====================
+
+xCAT does not ship OpenSSL RPMS nor does it statically link to any OpenSSL libraries. Communication between the xCAT client and daemon utilizes OpenSSL and the administrator can configure SSL_version and SSL_cipher that should be used by xCAT daemons.
+
+The configuration is stored in the xCAT site table using the ``site.xcatsslversion`` and ``site.xcatsslciphers`` variables.
+
+Configuration
+-------------
+
+By default, xCAT ships with ``TLSv1`` configured. The current highest SSL version that can be supported is ``TLSv1.2``.
+
+* For rhels7.x and sles12.x and higher: ::
+
+ chtab key=xcatsslversion site.value=TLSv12
+
+* For ubuntu 14.x and higher: ::
+
+ chtab key=xcatsslversion site.value=TLSv1_2
+
+* For AIX 7.1.3.x: ::
+
+ chtab key=xcatsslversion site.value=TLSv1_2
+
+
+If running > ``TLSv1``, it is possible to disable insecure ciphers. Here's an example of one possible configuration: ::
+
+ "xcatsslciphers","kDH:kEDH:kRSA:!SSLv3:!SSLv2:!aNULL:!eNULL:!MEDIUM:!LOW:!MD5:!EXPORT:!CAMELLIA:!ECDH",,
+
+After making any changes to these configuration values, ``xcatd`` must be restarted: ::
+
+ service restart xcatd
+
+
+If any mistakes have been made and communiation is lost to xCAT, use ``XCATBYPASS`` to fix/remove the bad configuration: ::
+
+ XCATBYPASS=1 tabedit site
+
+
+Validation
+----------
+
+Use the ``openssl`` command to validate the SSL configuration is valid and expected.
+
+* To check whether TLSv1 is supported by xcatd: ::
+
+ openssl s_client -connect 127.0.0.1:3001 -tls1
+
+* To check if SSLv3 is disabled on ``xcatd``: ::
+
+ openssl s_client -connect localhost:3001 -ssl3
+
+ You should get a reponse similar to: ::
+
+ 70367087597568:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1259:SSL alert number 40
+ 70367087597568:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:598:
diff --git a/docs/source/advanced/switches/ethernet_switches.rst b/docs/source/advanced/switches/ethernet_switches.rst
deleted file mode 100644
index 1c9a8d361..000000000
--- a/docs/source/advanced/switches/ethernet_switches.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Ethernet Switches
-=================
diff --git a/docs/source/advanced/switches/index.rst b/docs/source/advanced/switches/index.rst
deleted file mode 100644
index 74d3b9cf9..000000000
--- a/docs/source/advanced/switches/index.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-Switch Management
-=================
-
-.. toctree::
- :maxdepth: 2
-
- ethernet_switches.rst
diff --git a/docs/source/guides/admin-guides/references/man1/bmcdiscover.1.rst b/docs/source/guides/admin-guides/references/man1/bmcdiscover.1.rst
index 6fde20bb8..b341c4d92 100644
--- a/docs/source/guides/admin-guides/references/man1/bmcdiscover.1.rst
+++ b/docs/source/guides/admin-guides/references/man1/bmcdiscover.1.rst
@@ -25,10 +25,6 @@ SYNOPSIS
\ **bmcdiscover**\ [\ **-**\ **-sn**\ \ *SN_nodename*\ ] [\ **-s**\ \ *scan_method*\ ] [\ **-u**\ \ *bmc_user*\ ] [\ **-p**\ \ *bmc_passwd*\ ] [\ **-z**\ ] [\ **-w**\ ] \ **-**\ **-range**\ \ *ip_ranges*\
-\ **bmcdiscover**\ \ **-u**\ \ *bmc_user*\ \ **-p**\ \ *bmc_passwd*\ \ **-i**\ \ *bmc_ip*\ \ **-**\ **-check**\
-
-\ **bmcdiscover**\ [\ **-u**\ \ *bmc_user*\ ] [\ **-p**\ \ *bmc_passwd*\ ] \ **-i**\ \ *bmc_ip*\ \ **-**\ **-ipsource**\
-
***********
DESCRIPTION
@@ -98,18 +94,6 @@ OPTIONS
-\ **-**\ **-check**\
-
- Check BMC administrator User/Password.
-
-
-
-\ **-**\ **-ipsource**\
-
- Display the BMC IP configuration.
-
-
-
\ **-h|-**\ **-help**\
Display usage message
@@ -187,22 +171,6 @@ Output is similar to:
bmcdiscover -s nmap --range "10.4.22-23.100-254" -w -z
-5. To check if the username or password is correct against the BMC:
-
-
-.. code-block:: perl
-
- bmcdiscover -i 10.4.23.254 -u USERID -p PASSW0RD --check
-
-
-6. Get BMC IP Address source, DHCP Address or static Address
-
-
-.. code-block:: perl
-
- bmcdiscover -i 10.4.23.254 -u USERID -p PASSW0RD --ipsource
-
-
********
SEE ALSO
diff --git a/docs/source/guides/admin-guides/references/man1/rflash.1.rst b/docs/source/guides/admin-guides/references/man1/rflash.1.rst
index 12833968e..097c35655 100644
--- a/docs/source/guides/admin-guides/references/man1/rflash.1.rst
+++ b/docs/source/guides/admin-guides/references/man1/rflash.1.rst
@@ -63,7 +63,9 @@ OpenPOWER OpenBMC specific :
\ **rflash**\ \ *noderange*\ \ *tar_file_path*\ {[\ **-c | -**\ **-check**\ ] | [\ **-a | -**\ **-activate**\ ] | [\ **-u | -**\ **-upload**\ ]}
-\ **rflash**\ \ *noderange*\ \ *image_id*\ {[\ **-a | -**\ **-activate**\ ] | [\ **-d | -**\ **-delete**\ ]}
+\ **rflash**\ \ *noderange*\ \ *tar_file_directory*\ [\ **-d**\] [\ **--no-host-reboot**\]
+
+\ **rflash**\ \ *noderange*\ \ *image_id*\ {[\ **-a | -**\ **-activate**\ ] | [\ **-**\ **-delete**\ ]}
@@ -135,18 +137,65 @@ OpenPOWER specific (using IPMI):
================================
-The command will update firmware for OpenPOWER BMC when given an OpenPOWER node and either the hpm formatted file path or path to a data directory.
+The command will update firmware for OpenPOWER BMC when given an OpenPOWER node with \ *mgt=ipmi*\ and either the hpm formatted file path or path to a data directory.
+
\ **Note:**\ When using \ **rflash**\ in hierarchical environment, the hpm file or data directory must be accessible from Service Nodes.
-OpenPOWER OpenBMC specific:
-===========================
+OpenPOWER specific (using OpenBMC):
+===================================
-The command will update firmware for OpenPOWER OpenBMC when given an OpenPOWER node and either an update .tar file or an uploaded image id.
+The command will update firmware for OpenPOWER BMC when given an OpenPOWER node with \ *mgt=openbmc*\ and either an update .tar file or an uploaded image id.
+
+\ **-l|-**\ **-list**\ :
+
+
+.. 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.
+
+
+\ **-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.
+
+
+\ **-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
+
+
+To apply the firmware level, a reboot is required to BMC and HOST.
+
\ **Note:**\ When using \ **rflash**\ in hierarchical environment, the .tar file must be accessible from Service Nodes.
+\ **-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.
+
***************
\ **Options**\
@@ -232,7 +281,7 @@ The command will update firmware for OpenPOWER OpenBMC when given an OpenPOWER n
-\ **-d|-**\ **-delete**\
+\ **-**\ **-delete**\
Delete update image from BMC
@@ -325,7 +374,7 @@ The command will update firmware for OpenPOWER OpenBMC when given an OpenPOWER n
-6. To update the firmware on IBM Power S822LC for Big Data machine specify the node name and the file path of the data directory containing pUpdate utility and BMC and/or PNOR update files:
+6. To update the firmware on IBM Power S822LC for Big Data machine specify the node name and the file path of the data directory containing pUpdate utility, both BMC and PNOR update files:
.. code-block:: perl
diff --git a/docs/source/guides/admin-guides/references/man1/rmdef.1.rst b/docs/source/guides/admin-guides/references/man1/rmdef.1.rst
index 3655a78b5..221319ff5 100644
--- a/docs/source/guides/admin-guides/references/man1/rmdef.1.rst
+++ b/docs/source/guides/admin-guides/references/man1/rmdef.1.rst
@@ -90,7 +90,7 @@ OPTIONS
\ **-C|-**\ **-cleanup**\
- Perform additional cleanup by running \ **nodeset offline**\ on the objects specified in the \ *noderange*\ .
+ Perform additional cleanup by running \ **nodeset offline**\ and \ **makeconservercf -d**\ on the objects specified in the \ *noderange*\ .
diff --git a/docs/source/guides/admin-guides/references/man1/rspconfig.1.rst b/docs/source/guides/admin-guides/references/man1/rspconfig.1.rst
index dab879fa5..b6956de5d 100644
--- a/docs/source/guides/admin-guides/references/man1/rspconfig.1.rst
+++ b/docs/source/guides/admin-guides/references/man1/rspconfig.1.rst
@@ -49,6 +49,8 @@ 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*\ ]
+
MPA specific:
=============
@@ -430,6 +432,29 @@ OPTIONS
+\ **dump**\
+
+ Manage OpenBMC system dumps. If no sub-option is provided, will generate, wait, and download the dump.
+
+
+ \ **-c**\ will clear a single specified dump, or use 'all' to clear all dumps on the BMC.
+
+
+
+ \ **-l**\ will list all the generated dumps on the BMC.
+
+
+
+ \ **-g**\ will generate a new dump on the BMC. Dump generation can take a few minutes.
+
+
+
+ \ **-d**\ will download a single dump from the BMC to /var/log/xcat/dump on management or service node.
+
+
+
+
+
\ **network**\ ={[\ *ip*\ ],[\ *host*\ ],[\ *gateway*\ ],[\ *netmask*\ ]|\*}
For MPA: get or set the MPA network parameters. If '\*' is specified, all parameters are read from the xCAT database.
@@ -1230,6 +1255,48 @@ EXAMPLES
+31. To list BMC dumps available for download:
+
+
+ .. code-block:: perl
+
+ rspconfig p9euh02 dump -l
+
+
+ Output is similar to:
+
+
+ .. code-block:: perl
+
+ p9euh02: [1] Generated: 09/06/2017 14:31:49, Size: 4528
+ p9euh02: [2] Generated: 09/06/2017 14:31:55, Size: 4516
+ p9euh02: [3] Generated: 09/06/2017 14:32:01, Size: 4236
+ p9euh02: [4] Generated: 09/06/2017 14:32:07, Size: 4248
+ p9euh02: [5] Generated: 09/06/2017 14:32:11, Size: 4268
+
+
+
+
+32. To generate and download BMC dump:
+
+
+ .. code-block:: perl
+
+ rspconfig p9euh02 dump
+
+
+ Output is similar to:
+
+
+ .. code-block:: perl
+
+ Capturing BMC Diagnostic information, this will take some time...
+ p9euh02: Dump requested. Target ID is 6, waiting for BMC to generate...
+ p9euh02: Dump 6 generated. Downloading to /var/log/xcat/dump/20171211-0951_p9euh02_dump_6.tar.xz
+
+
+
+
********
SEE ALSO
diff --git a/docs/source/guides/admin-guides/references/man5/linuximage.5.rst b/docs/source/guides/admin-guides/references/man5/linuximage.5.rst
index 1ecae0842..532eafc1b 100644
--- a/docs/source/guides/admin-guides/references/man5/linuximage.5.rst
+++ b/docs/source/guides/admin-guides/references/man5/linuximage.5.rst
@@ -80,7 +80,7 @@ linuximage Attributes:
\ **otherpkgdir**\
- The base directory where the non-distro packages are stored. Only 1 local directory supported at present.
+ The base directory and urls of internet repos from which the non-distro packages are retrived. Only 1 local directory is supported at present. The entries should be delimited with comma ",". Currently, the internet repos are only supported on Ubuntu and Redhat.
diff --git a/docs/source/guides/admin-guides/references/man5/servicenode.5.rst b/docs/source/guides/admin-guides/references/man5/servicenode.5.rst
index 3da4820e5..e202132f4 100644
--- a/docs/source/guides/admin-guides/references/man5/servicenode.5.rst
+++ b/docs/source/guides/admin-guides/references/man5/servicenode.5.rst
@@ -44,67 +44,67 @@ servicenode Attributes:
\ **nameserver**\
- Do we set up DNS on this service node? Valid values: 2, 1, no or 0. If 2, creates named.conf as dns slave, using the management node as dns master, and starts named. If 1, creates named.conf file with forwarding to the management node and starts named. If no or 0, it does not change the current state of the service.
+ Do we set up DNS on this service node? Valid values: 2, 1, or 0. If 2, creates named.conf as dns slave, using the management node as dns master, and starts named. If 1, creates named.conf file with forwarding to the management node and starts named. If 0, it does not change the current state of the service.
\ **dhcpserver**\
- Do we set up DHCP on this service node? Not supported on AIX. Valid values:yes or 1, no or 0. If yes, runs makedhcp -n. If no or 0, it does not change the current state of the service.
+ 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:yes or 1, no or 0. If yes, configures and starts atftp. If no or 0, it does not change the current state of the service.
+ 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:yes or 1, no or 0.If no or 0, it does not change the current state of the service.
+ 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:yes or 1, no or 0. If yes, configures and starts conserver daemon. If no or 0, it does not change the current state of the service.
+ 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.
\ **monserver**\
- Is this a monitoring event collection point? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ 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:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ 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:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ 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.
\ **ftpserver**\
- Do we set up a ftp server on this service node? Not supported on AIX Valid values:yes or 1, no or 0. If yes, configure and start vsftpd. (You must manually install vsftpd on the service nodes before this.) If no or 0, it does not change the current state of the service. xCAT is not using ftp for compute nodes provisioning or any other xCAT features, so this attribute can be set to 0 if the ftp service will not be used for other purposes
+ Do we set up a ftp server on this service node? Not supported on AIX Valid values:1 or 0. If 1, configure and start vsftpd. (You must manually install vsftpd on the service nodes before this.) If 0, it does not change the current state of the service. xCAT is not using ftp for compute nodes provisioning or any other xCAT features, so this attribute can be set to 0 if the ftp service will not be used for other purposes
\ **nimserver**\
- Not used. Do we set up a NIM server on this service node? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ Not used. Do we set up a NIM server on this service node? Valid values:1 or 0. If 0, it does not change the current state of the service.
\ **ipforward**\
- Do we set up ip forwarding on this service node? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ Do we set up ip forwarding on this service node? Valid values:1 or 0. If 0, it does not change the current state of the service.
@@ -116,7 +116,7 @@ servicenode Attributes:
\ **proxydhcp**\
- Do we set up proxydhcp service on this node? valid values: yes or 1, no or 0. If yes, the proxydhcp daemon will be enabled on this node.
+ Do we set up proxydhcp service on this node? valid values: 1 or 0. If 1, the proxydhcp daemon will be enabled on this node.
diff --git a/docs/source/guides/admin-guides/references/man7/group.7.rst b/docs/source/guides/admin-guides/references/man7/group.7.rst
index a90adca50..0995bf85c 100644
--- a/docs/source/guides/admin-guides/references/man7/group.7.rst
+++ b/docs/source/guides/admin-guides/references/man7/group.7.rst
@@ -947,67 +947,67 @@ group Attributes:
\ **setupconserver**\ (servicenode.conserver)
- Do we set up Conserver on this service node? Valid values:yes or 1, no or 0. If yes, configures and starts conserver daemon. If no or 0, it does not change the current state of the service.
+ 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.
\ **setupdhcp**\ (servicenode.dhcpserver)
- Do we set up DHCP on this service node? Not supported on AIX. Valid values:yes or 1, no or 0. If yes, runs makedhcp -n. If no or 0, it does not change the current state of the service.
+ 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.
\ **setupftp**\ (servicenode.ftpserver)
- Do we set up a ftp server on this service node? Not supported on AIX Valid values:yes or 1, no or 0. If yes, configure and start vsftpd. (You must manually install vsftpd on the service nodes before this.) If no or 0, it does not change the current state of the service. xCAT is not using ftp for compute nodes provisioning or any other xCAT features, so this attribute can be set to 0 if the ftp service will not be used for other purposes
+ Do we set up a ftp server on this service node? Not supported on AIX Valid values:1 or 0. If 1, configure and start vsftpd. (You must manually install vsftpd on the service nodes before this.) If 0, it does not change the current state of the service. xCAT is not using ftp for compute nodes provisioning or any other xCAT features, so this attribute can be set to 0 if the ftp service will not be used for other purposes
\ **setupipforward**\ (servicenode.ipforward)
- Do we set up ip forwarding on this service node? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ Do we set up ip forwarding on this service node? Valid values:1 or 0. If 0, it does not change the current state of the service.
\ **setupldap**\ (servicenode.ldapserver)
- Do we set up ldap caching proxy on this service node? Not supported on AIX. Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ 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.
\ **setupnameserver**\ (servicenode.nameserver)
- Do we set up DNS on this service node? Valid values: 2, 1, no or 0. If 2, creates named.conf as dns slave, using the management node as dns master, and starts named. If 1, creates named.conf file with forwarding to the management node and starts named. If no or 0, it does not change the current state of the service.
+ Do we set up DNS on this service node? Valid values: 2, 1, or 0. If 2, creates named.conf as dns slave, using the management node as dns master, and starts named. If 1, creates named.conf file with forwarding to the management node and starts named. If 0, it does not change the current state of the service.
\ **setupnfs**\ (servicenode.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:yes or 1, no or 0.If no or 0, it does not change the current state of the service.
+ 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.
\ **setupnim**\ (servicenode.nimserver)
- Not used. Do we set up a NIM server on this service node? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ Not used. Do we set up a NIM server on this service node? Valid values:1 or 0. If 0, it does not change the current state of the service.
\ **setupntp**\ (servicenode.ntpserver)
- Not used. Use setupntp postscript to setup a ntp server on this service node? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ 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.
\ **setupproxydhcp**\ (servicenode.proxydhcp)
- Do we set up proxydhcp service on this node? valid values: yes or 1, no or 0. If yes, the proxydhcp daemon will be enabled on this node.
+ Do we set up proxydhcp service on this node? valid values: 1 or 0. If 1, the proxydhcp daemon will be enabled on this node.
\ **setuptftp**\ (servicenode.tftpserver)
- Do we set up TFTP on this service node? Not supported on AIX. Valid values:yes or 1, no or 0. If yes, configures and starts atftp. If no or 0, it does not change the current state of the service.
+ 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.
diff --git a/docs/source/guides/admin-guides/references/man7/node.7.rst b/docs/source/guides/admin-guides/references/man7/node.7.rst
index 02b84092a..060e5fc74 100644
--- a/docs/source/guides/admin-guides/references/man7/node.7.rst
+++ b/docs/source/guides/admin-guides/references/man7/node.7.rst
@@ -959,67 +959,67 @@ node Attributes:
\ **setupconserver**\ (servicenode.conserver)
- Do we set up Conserver on this service node? Valid values:yes or 1, no or 0. If yes, configures and starts conserver daemon. If no or 0, it does not change the current state of the service.
+ 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.
\ **setupdhcp**\ (servicenode.dhcpserver)
- Do we set up DHCP on this service node? Not supported on AIX. Valid values:yes or 1, no or 0. If yes, runs makedhcp -n. If no or 0, it does not change the current state of the service.
+ 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.
\ **setupftp**\ (servicenode.ftpserver)
- Do we set up a ftp server on this service node? Not supported on AIX Valid values:yes or 1, no or 0. If yes, configure and start vsftpd. (You must manually install vsftpd on the service nodes before this.) If no or 0, it does not change the current state of the service. xCAT is not using ftp for compute nodes provisioning or any other xCAT features, so this attribute can be set to 0 if the ftp service will not be used for other purposes
+ Do we set up a ftp server on this service node? Not supported on AIX Valid values:1 or 0. If 1, configure and start vsftpd. (You must manually install vsftpd on the service nodes before this.) If 0, it does not change the current state of the service. xCAT is not using ftp for compute nodes provisioning or any other xCAT features, so this attribute can be set to 0 if the ftp service will not be used for other purposes
\ **setupipforward**\ (servicenode.ipforward)
- Do we set up ip forwarding on this service node? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ Do we set up ip forwarding on this service node? Valid values:1 or 0. If 0, it does not change the current state of the service.
\ **setupldap**\ (servicenode.ldapserver)
- Do we set up ldap caching proxy on this service node? Not supported on AIX. Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ 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.
\ **setupnameserver**\ (servicenode.nameserver)
- Do we set up DNS on this service node? Valid values: 2, 1, no or 0. If 2, creates named.conf as dns slave, using the management node as dns master, and starts named. If 1, creates named.conf file with forwarding to the management node and starts named. If no or 0, it does not change the current state of the service.
+ Do we set up DNS on this service node? Valid values: 2, 1, or 0. If 2, creates named.conf as dns slave, using the management node as dns master, and starts named. If 1, creates named.conf file with forwarding to the management node and starts named. If 0, it does not change the current state of the service.
\ **setupnfs**\ (servicenode.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:yes or 1, no or 0.If no or 0, it does not change the current state of the service.
+ 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.
\ **setupnim**\ (servicenode.nimserver)
- Not used. Do we set up a NIM server on this service node? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ Not used. Do we set up a NIM server on this service node? Valid values:1 or 0. If 0, it does not change the current state of the service.
\ **setupntp**\ (servicenode.ntpserver)
- Not used. Use setupntp postscript to setup a ntp server on this service node? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.
+ 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.
\ **setupproxydhcp**\ (servicenode.proxydhcp)
- Do we set up proxydhcp service on this node? valid values: yes or 1, no or 0. If yes, the proxydhcp daemon will be enabled on this node.
+ Do we set up proxydhcp service on this node? valid values: 1 or 0. If 1, the proxydhcp daemon will be enabled on this node.
\ **setuptftp**\ (servicenode.tftpserver)
- Do we set up TFTP on this service node? Not supported on AIX. Valid values:yes or 1, no or 0. If yes, configures and starts atftp. If no or 0, it does not change the current state of the service.
+ 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.
diff --git a/docs/source/guides/admin-guides/references/man7/osimage.7.rst b/docs/source/guides/admin-guides/references/man7/osimage.7.rst
index d8b2c77ce..8e2faea1f 100644
--- a/docs/source/guides/admin-guides/references/man7/osimage.7.rst
+++ b/docs/source/guides/admin-guides/references/man7/osimage.7.rst
@@ -255,7 +255,7 @@ osimage Attributes:
\ **otherpkgdir**\ (linuximage.otherpkgdir)
- The base directory where the non-distro packages are stored. Only 1 local directory supported at present.
+ The base directory and urls of internet repos from which the non-distro packages are retrived. Only 1 local directory is supported at present. The entries should be delimited with comma ",". Currently, the internet repos are only supported on Ubuntu and Redhat.
diff --git a/docs/source/guides/admin-guides/references/man8/makeconservercf.8.rst b/docs/source/guides/admin-guides/references/man8/makeconservercf.8.rst
index 19ae43ea6..249be78f4 100644
--- a/docs/source/guides/admin-guides/references/man8/makeconservercf.8.rst
+++ b/docs/source/guides/admin-guides/references/man8/makeconservercf.8.rst
@@ -21,6 +21,8 @@ SYNOPSIS
\ **makeconservercf**\ [\ **-V|-**\ **-verbose**\ ] [\ **-d|-**\ **-delete**\ ] [\ *noderange*\ ]
+\ **makeconservercf**\ [\ **-V|-**\ **-verbose**\ ] [\ **-C|-**\ **-cleanup**\ ]
+
\ **makeconservercf**\ [\ **-V|-**\ **-verbose**\ ] [\ **-l|-**\ **-local**\ ] [\ *noderange*\ ]
\ **makeconservercf**\ [\ **-V|-**\ **-verbose**\ ] [\ **-c|-**\ **-conserver**\ ] [\ *noderange*\ ]
@@ -42,6 +44,8 @@ does not have nodehm.cons set, it will not be written to the file.
If \ **-d**\ is specified, \ **makeconservercf**\ will remove specified nodes from /etc/conserver.cf file. If \ *noderange*\ is not specified, all xCAT nodes will be removed from /etc/conserver.cf file.
+If \ **-C|-**\ **-cleanup**\ is specified, \ **makeconservercf**\ will remove console configuration entries from /etc/conserver.cf for the nodes whose definitions have been removed from xCATdb. \ **Don't**\ specify any noderange.
+
In the case of a hierarchical cluster (i.e. one with service nodes) \ **makeconservercf**\ will determine
which nodes will have their consoles accessed from the management node and which from a service node
(based on the nodehm.conserver attribute). The /etc/conserver.cf file will be created accordingly on
@@ -60,6 +64,12 @@ OPTIONS
+\ **-C|-**\ **-cleanup**\
+
+ Remove the entries for the nodes whose definitions have been removed from xCAT db.
+
+
+
\ **-c|-**\ **-conserver**\
Only set up the conserver on the conserver host. If no conserver host
diff --git a/docs/source/guides/admin-guides/references/man8/makegocons.8.rst b/docs/source/guides/admin-guides/references/man8/makegocons.8.rst
new file mode 100644
index 000000000..76eb7a5fc
--- /dev/null
+++ b/docs/source/guides/admin-guides/references/man8/makegocons.8.rst
@@ -0,0 +1,151 @@
+
+############
+makegocons.8
+############
+
+.. highlight:: perl
+
+
+****
+NAME
+****
+
+
+\ **makegocons**\ - Register or unregister the node in the goconserver service
+
+
+********
+SYNOPSIS
+********
+
+
+\ **makegocons**\ [\ **-V|-**\ **-verbose**\ ] [\ **-d|-**\ **-delete**\ ] [\ *noderange*\ ]
+
+\ **makeconservercf**\ [\ **-h|-**\ **-help|-v|-**\ **-version**\ ]
+
+
+***********
+DESCRIPTION
+***********
+
+
+The \ **makegocons**\ command will start the goconserver service if it is not started, then
+send the REST request to create or delete the session resource in the goconserver service. The session
+information including the session command or ssh connection parameters (for openbmc) is generated by xcat
+based on the records in the related tables (e.g. nodehm, ipmi, ppc, openbmc).
+
+By default \ **makegocons**\ will register the session for all of the nodes in xcat.
+
+If a \ *noderange*\ is specified, only the session in the specified scope will be affected, goconserver
+service will not be restarted and the other session will not be disconnected. This is the advantage
+of goconserver over the conserver service with \ **makeconservercf**\ .
+
+If \ **-d**\ is specified, \ **makegocons**\ will remove the session in the goconserver service.
+
+In the case of a hierarchical cluster (i.e. one with service nodes) \ **makegocons**\ will determine
+which nodes will have their consoles accessed from the management node and which from a service node
+(based on the nodehm.conserver attribute).
+
+For openbmc which uses ssh as the terminal session connection method, goconserver can help save the system
+resources as goconserver could handle the ssh connection within goroutine which is more light-weighted than the command process.
+
+\ **Note:**\ goconserver is an experimental feature, it will not be installed with xcat and will only support the systemd based systems.
+Download and setup the rpm or deb package manually. Release link:
+
+
+.. code-block:: perl
+
+ https://github.com/chenglch/goconserver/releases
+
+
+
+*******
+OPTIONS
+*******
+
+
+
+\ **-d|-**\ **-delete**\
+
+ Delete rather than add or refresh the nodes specified as a noderange.
+
+
+
+\ **-v|-**\ **-version**\
+
+ Display version.
+
+
+
+\ **-V|-**\ **-verbose**\
+
+ Verbose mode.
+
+
+
+\ **-h|-**\ **-help**\
+
+ Display usage message.
+
+
+
+
+************
+RETURN VALUE
+************
+
+
+
+0. The command completed successfully.
+
+
+
+1. An error has occurred.
+
+
+
+
+********
+EXAMPLES
+********
+
+
+
+1. To create goconserver configuration for all the nodes.
+
+
+ .. code-block:: perl
+
+ makegocons
+
+
+
+
+2. To create goconserver configuration for nodes node01-node10.
+
+
+ .. code-block:: perl
+
+ makegocons node01-node10
+
+
+
+
+3. To remove goconserver configuration for node01.
+
+
+ .. code-block:: perl
+
+ makegocons -d node01
+
+
+
+
+
+********
+SEE ALSO
+********
+
+
+rcons(1)|rcons.1
+
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 0afdb7281..32ec86a95 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -32,6 +32,7 @@ Table of Contents
guides/install-guides/index.rst
guides/admin-guides/index.rst
advanced/index.rst
+ QA/index.rst
references/index.rst
troubleshooting/index.rst
developers/index.rst
diff --git a/docs/source/references/coral/cluster_mgmt/firmware/index.rst b/docs/source/references/coral/cluster_mgmt/firmware/index.rst
new file mode 100644
index 000000000..1d105d896
--- /dev/null
+++ b/docs/source/references/coral/cluster_mgmt/firmware/index.rst
@@ -0,0 +1,8 @@
+Power9 Firmware Update
+======================
+
+.. toctree::
+ :maxdepth: 2
+
+ ipmi.rst
+ openbmc.rst
diff --git a/docs/source/references/coral/cluster_mgmt/firmware/ipmi.rst b/docs/source/references/coral/cluster_mgmt/firmware/ipmi.rst
new file mode 100644
index 000000000..877294a5a
--- /dev/null
+++ b/docs/source/references/coral/cluster_mgmt/firmware/ipmi.rst
@@ -0,0 +1,40 @@
+IPMI Firmware Update
+====================
+
+The process for updating firmware on the IBM Power9 Server (Boston) is documented below.
+
+
+Collect the required files
+--------------------------
+
+Collect the following files and put them into a directory on the Management Node.
+
+ * pUpdate
+ * pnor
+ * bmc
+
+If running ``rflash`` in Hierarchy, the firmware files/directory must be accessible on the Service Nodes.
+
+Flash Firmware
+--------------
+
+Using xCAT ``rflash`` command, specify the directory containing the files with the ``-d`` option. ::
+
+ rflash -d /path-to-directory/
+
+The ``pUpdate`` utility is leveraged in doing the firmware update against the target node and will do the following:
+
+ * power off the host
+ * flash bmc and reboot
+ * flash pnor
+ * power on the host
+
+Monitor the progress for the nodes by looking at the files under ``/var/log/xcat/rflash/``.
+
+Validatation
+------------
+
+Use the ``rinv`` command to validate firmware level: ::
+
+ rinv firm | xcoll
+
diff --git a/docs/source/references/coral/cluster_mgmt/firmware/openbmc.rst b/docs/source/references/coral/cluster_mgmt/firmware/openbmc.rst
new file mode 100644
index 000000000..49caae6bf
--- /dev/null
+++ b/docs/source/references/coral/cluster_mgmt/firmware/openbmc.rst
@@ -0,0 +1,79 @@
+OpenBMC Firmware Update
+=======================
+
+The process of updating firmware on the OpenBMC managed servers is documented below.
+
+The sequence of events that must happen is the following:
+
+ * Power off the Host
+ * Update and Activate PNOR
+ * Update and Activate BMC
+ * Reboot the BMC (applies BMC)
+ * Power on the Host (applies PNOR)
+
+**Note:** xCAT is working on streamlining this process to reduce the flexibility of the above steps at the convenience of the Administrator to handle the necessary reboots. See `Issue #4245 `_
+
+
+
+Power off Host
+--------------
+
+Use the rpower command to power off the host: ::
+
+ rpower off
+
+Update and Activate PNOR Firmware
+---------------------------------
+
+Use the rflash command to upload and activate the PNOR firmware: ::
+
+ rflash -a /path/to/witherspoon.pnor.squashfs.tar
+
+If running ``rflash`` in Hierarchy, the firmware files must be accessible on the Service Nodes.
+
+**Note:** The ``-a`` option does an upload and activate in one step, after firmware is activated, use the ``rflash -l`` to view. The ``rflash`` command shows ``(*)`` as the active firmware and ``(+)`` on the firmware that requires reboot to become effective.
+
+Update and Activate BMC Firmware
+--------------------------------
+
+Use the rflash command to upload and activate the PNOR firmware: ::
+
+ rflash -a /path/to/obmc-phosphor-image-witherspoon.ubi.mtd.tar
+
+If running ``rflash`` in Hierarchy, the firmware files must be accessible on the Service Nodes.
+
+**Note:** The ``-a`` option does an upload and activate in one step, after firmware is activated, use the ``rflash -l`` to view. The ``rflash`` command shows ``(*)`` as the active firmware and ``(+)`` on the firmware that requires reboot to become effective.
+
+Reboot the BMC
+--------------
+
+Use the ``rpower`` command to reboot the BMC: ::
+
+ rpower bmcreboot
+
+The BMC will take 2-5 minutes to reboot, check the status using: ``rpower bmcstate`` and wait for ``BMCReady`` to be returned.
+
+**Known Issue:** On reboot, the first call to the BMC after reboot, xCAT will return ``Error: BMC did not respond within 10 seconds, retry the command.``. Please retry.
+
+
+Power on Host
+-------------
+
+User the ``rpower`` command to power on the Host: ::
+
+ rpower on
+
+
+Validation
+----------
+
+Use one of the following commands to validate firmware levels are in sync:
+
+* Use the ``rinv`` command to validate firmware level: ::
+
+ rinv firm -V | grep -i ibm | grep "\*" | xcoll
+
+* Use the ``rflash`` command to validate the firmware level: ::
+
+ rflash -l | grep "\*" | xcoll
+
diff --git a/docs/source/references/coral/cluster_mgmt/index.rst b/docs/source/references/coral/cluster_mgmt/index.rst
new file mode 100644
index 000000000..20b2bbcb8
--- /dev/null
+++ b/docs/source/references/coral/cluster_mgmt/index.rst
@@ -0,0 +1,7 @@
+Cluster Management
+==================
+
+.. toctree::
+ :maxdepth: 2
+
+ firmware/index.rst
diff --git a/docs/source/references/coral/index.rst b/docs/source/references/coral/index.rst
index 4639e3360..58de81eac 100644
--- a/docs/source/references/coral/index.rst
+++ b/docs/source/references/coral/index.rst
@@ -7,6 +7,7 @@ CORAL stands for Collaboration of Oak Ridge, Argonne, and Livermore and is solut
.. toctree::
:maxdepth: 2
+ cluster_mgmt/index.rst
known_issues/index.rst
.. mn/index.rst
.. discovery/index.rst
diff --git a/docs/source/references/coral/known_issues/index.rst b/docs/source/references/coral/known_issues/index.rst
index 359cd90de..63e9126be 100644
--- a/docs/source/references/coral/known_issues/index.rst
+++ b/docs/source/references/coral/known_issues/index.rst
@@ -5,3 +5,4 @@ Known Issues
:maxdepth: 2
genesis_base.rst
+ openbmc/index.rst
diff --git a/docs/source/references/coral/known_issues/openbmc/2_13_8.rst b/docs/source/references/coral/known_issues/openbmc/2_13_8.rst
new file mode 100644
index 000000000..d5502f9be
--- /dev/null
+++ b/docs/source/references/coral/known_issues/openbmc/2_13_8.rst
@@ -0,0 +1,7 @@
+#4264 - rpower command intermittently reports 503: Service Unavailable Error
+============================================================================
+
+Issue `#4264 `_
+
+In attempt to improve the performance of the REST calls to OpenBMC and reduce the time spent in a timeout, we fail too soon here before the BMC has a chance to respond.
+
diff --git a/docs/source/references/coral/known_issues/openbmc/SW402273.rst b/docs/source/references/coral/known_issues/openbmc/SW402273.rst
new file mode 100644
index 000000000..b1a07e688
--- /dev/null
+++ b/docs/source/references/coral/known_issues/openbmc/SW402273.rst
@@ -0,0 +1,17 @@
+SW402273 - Unable to tell the firmware level that is actually running on the node via REST
+==========================================================================================
+
+* **Issue:** `SW402273 `_
+* **Reported:** 1738B (ibm-v1.99.10-0-r7)
+* **Fixed:** 1740B (ibm-v1.99.10-0-r13)
+
+**Issue:**
+
+Until 1740B firmware (> ibm-v1.99.10-0-r13), there's no method provided by OpenBMC to indicate the active running firmware on the node. Until the BMC is rebooted or the HOST is rebooted, the Active firmware may or may not really be running.
+
+If you are running a version that prints the following message from ``rflash``: ::
+
+ cn01: WARNING, The current firmware is unable to detect running firmware version.
+
+Please update the BMC to a version higher than ibm-v1.99.10-0-r13.
+
diff --git a/docs/source/references/coral/known_issues/openbmc/SW404161.rst b/docs/source/references/coral/known_issues/openbmc/SW404161.rst
new file mode 100644
index 000000000..e955fdeab
--- /dev/null
+++ b/docs/source/references/coral/known_issues/openbmc/SW404161.rst
@@ -0,0 +1,26 @@
+SW404161 - Firmware do not self extract tar, causing rflash cannot find ID to activate
+======================================================================================
+
+* **Issue:** `SW404161 `_
+* **Reported:** 1738A (ibm-v1.99.10-0-r7)
+* **Fixed:** 1742D (ibm-v1.99.10-0-113-r10)
+
+**Issue:**
+
+Firmware is not extracted and could not be found by rflash to activate ::
+
+ [root@c650mnp03 ~]# rflash c650f07p27 obmc-phosphor-image-witherspoon.ubi.mtd.tar -a
+ c650f07p27: Uploading /root/obmc-phosphor-image-witherspoon.ubi.mtd.tar ...
+ c650f07p27: Firmware upload successful. Attempting to activate firmware: ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d
+ c650f07p27: Could not find ID for firmware ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d to activate, waiting 10 seconds and retry...
+ c650f07p27: Could not find ID for firmware ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d to activate, waiting 10 seconds and retry...
+ c650f07p27: Could not find ID for firmware ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d to activate, waiting 10 seconds and retry...
+ c650f07p27: Could not find ID for firmware ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d to activate, waiting 10 seconds and retry...
+ c650f07p27: Could not find ID for firmware ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d to activate, waiting 10 seconds and retry...
+ c650f07p27: Could not find ID for firmware ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d to activate, waiting 10 seconds and retry...
+ c650f07p27: Error: Could not find firmware ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d after waiting 60 seconds.
+
+**Work-around:** Use one of the following methods:
+
+* Reboot the BMC before flashing firmware: ``rpower <> bmcreboot``
+* ssh into bmc and run: ``systemctl restart xyz.openbmc_project.Software.Version.service``
diff --git a/docs/source/references/coral/known_issues/openbmc/SW406771.rst b/docs/source/references/coral/known_issues/openbmc/SW406771.rst
new file mode 100644
index 000000000..145844d86
--- /dev/null
+++ b/docs/source/references/coral/known_issues/openbmc/SW406771.rst
@@ -0,0 +1,84 @@
+SW406771 - Duplicate FW ID or 2 BMC firmware active at the same time
+====================================================================
+
+* **Issue:** `SW407037 `_
+* **Reported:** 1740A (ibm-v1.99.10-0-r11-0-g9c65260)
+* **Fixed:** 1742 or higher
+
+**Issue:**
+
+At some point after 1740A firmware, ``ibm-v1.99.10-0-r11-0-g9c65260``, the hashing algorithm to create the ID on the BMC was chagned by the Firmware team. This allows for the same firmware to potentially have two different IDs resulting in two active running BMC firmware.
+
+
+**Work-around**
+
+Upgrade from 1740A
+------------------
+
+If you are running 1740A, you will need to get two BMC firmware levels from your IBM representative.
+
+This example will cover flashing from 1740A to 1742D, using 1742C as the recovery flash level.
+
+#. Identify the issue where the IDs are not using the correct hash ::
+
+ mid05tor12cn13: ID Purpose State Version
+ mid05tor12cn13: -------------------------------------------------------
+ mid05tor12cn13: 9e55358e BMC Active(*) ibm-v1.99.10-0-r11-0-g9c65260
+ mid05tor12cn13: 6e71e1af BMC Ready ibm-v1.99.10-113-g65edf7d-r10-0-gcdf7635 <--- bad hash for 1742D
+
+ mid05tor12cn16: ID Purpose State Version
+ mid05tor12cn16: -------------------------------------------------------
+ mid05tor12cn16: efc8a851 BMC Ready ibm-v1.99.10-113-g65edf7d-r10-0-gcdf7635 <--- correct hash for 1742D
+ mid05tor12cn16: b48d27e1 BMC Active(*) ibm-v1.99.10-113-g65edf7d-r3-0-g9e4f715
+
+#. Flash up to 1742D, activate and reboot: ::
+
+ mid05tor12cn13: ID Purpose State Version
+ mid05tor12cn13: -------------------------------------------------------
+ mid05tor12cn13: 9e55358e BMC Active ibm-v1.99.10-0-r11-0-g9c65260
+ mid05tor12cn13: 221d9020 Host Active(*) IBM-witherspoon-redbud-ibm-OP9_v1.19_1.33
+ mid05tor12cn13: 6e71e1af BMC Active(*) ibm-v1.99.10-113-g65edf7d-r10-0-gcdf7635 <--- bad hash, active
+ mid05tor12cn13:
+
+#. Flash down to 1742C, activate and reboot: ::
+
+ mid05tor12cn13: ID Purpose State Version
+ mid05tor12cn13: -------------------------------------------------------
+ mid05tor12cn13: 9e55358e BMC Active ibm-v1.99.10-0-r11-0-g9c65260
+ mid05tor12cn13: 221d9020 Host Active(*) IBM-witherspoon-redbud-ibm-OP9_v1.19_1.33
+ mid05tor12cn13: 6e71e1af BMC Active(*) ibm-v1.99.10-113-g65edf7d-r10-0-gcdf7635
+ mid05tor12cn13: f6590ce0 BMC Active(+) ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d <--- 1742C
+ mid05tor12cn13:
+
+#. Delete the bad hash firmware: ``rflash -d 6e71e1af``
+
+ **Note:** This is optional because the BMC only allows 2 firmware max, so it would get pushed out.
+
+#. Flash back up to 1742D (with correct hash), activate and reboot: ::
+
+ mid05tor12cn13: ID Purpose State Version
+ mid05tor12cn13: -------------------------------------------------------
+ mid05tor12cn13: 221d9020 Host Active(*) IBM-witherspoon-redbud-ibm-OP9_v1.19_1.33
+ mid05tor12cn13: efc8a851 BMC Active(*) ibm-v1.99.10-113-g65edf7d-r10-0-gcdf7635 <--- good hash
+ mid05tor12cn13: f6590ce0 BMC Active ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d
+ mid05tor12cn13:
+
+Two active BMCs
+---------------
+
+If you have two active BMCs::
+
+ [root@mgt03 ~]# rflash f7n02 -l
+ f7n02: ID Purpose State Version
+ f7n02: -------------------------------------------------------
+ f7n02: b5273d71 BMC Active(*) ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d
+ f7n02: 30ee1c48 Host Active(*) IBM-witherspoon-ibm-OP9_v1.19_1.112
+ f7n02: 4f33e0f4 Host Failed(+) IBM-witherspoon-ibm-OP9_v1.19_1.109
+ f7n02: f6590ce0 BMC Active(*) ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d
+ f7n02:
+
+There's no way to de-activate one manually, recover by doing the following:
+
+#. Flash the BMC to the previous level of the firmware and reboot BMC
+#. Delete the duplicate firmware using ``rflash -d ``
+#. Re-flash the BMC to the target level and reboot the BMC.
diff --git a/docs/source/references/coral/known_issues/openbmc/SW407037.rst b/docs/source/references/coral/known_issues/openbmc/SW407037.rst
new file mode 100644
index 000000000..5f939ede3
--- /dev/null
+++ b/docs/source/references/coral/known_issues/openbmc/SW407037.rst
@@ -0,0 +1,38 @@
+SW407037 - bmcsetup does not successfully configure the IP (Sev1)
+=================================================================
+
+* **Issue:** `SW407037 `_
+* **Reported:** 1742C (ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d)
+* **Fixed:** Fixed in xCAT after 11/07/17 `#4242 `_
+
+**Issue:**
+
+OpenBMC firmware has problems with ipmi inband support of the ``access on`` comamnd and the work around is to use the ``raw 0x06 0x40`` instead. In early Sept, we switched to using ``access on`` because the implementation looked like it was working, since then we have found some issues with it and recommendation is to revert back to the raw command.
+
+See related issues describing potential problems:
+* https://github.com/openbmc/openbmc/issues/2493
+* https://github.com/openbmc/openbmc/issues/2492
+
+This problem is very severe because if the network is not configured correctly, the access to the BMC is lost.
+
+**Work-around**
+
+Use one of the following work arounds:
+
+#. Install a version of xCAT built after November, 07, 2017 which includes the fix. (**Recommended**)
+
+#. Manually patch bmcsetup using changes in PR: https://github.com/xcat2/xcat-core/pull/4247, then run ``mknb ppc64``
+
+#. Patch the system with provided patch:
+
+ #. Download patch file: https://github.com/xcat2/xcat-core/files/1451181/bmcsetup.4242.patch.txt
+
+ #. If file name is ``/tmp/bmcsetup.4242.patch.txt``
+
+ #. ``cd /opt/xcat/share/xcat/netboot/genesis/ppc64/fs/usr/bin``
+
+ #. ``patch -p0 < /tmp/bmcsetup.4242.patch.txt``
+
+ #. ``mknb ppc64``
+
+
diff --git a/docs/source/references/coral/known_issues/openbmc/index.rst b/docs/source/references/coral/known_issues/openbmc/index.rst
new file mode 100644
index 000000000..0f01bb3f9
--- /dev/null
+++ b/docs/source/references/coral/known_issues/openbmc/index.rst
@@ -0,0 +1,47 @@
+OpenBMC Management Issues
+=========================
+
+xCAT
+----
+
+2.13.8
+``````
+
+Please see the `2.13.8 Release Notes `_ for the full list of known issues.
+
+.. toctree::
+ :maxdepth: 2
+
+ 2_13_8.rst
+
+Firmware
+--------
+
+The following versions indicate the level of firmware the issue was reported.
+
+
+1742C - ibm-v1.99.10-113-g65edf7d-r8-0-g713d86d
+```````````````````````````````````````````````
+
+.. toctree::
+ :maxdepth: 1
+
+ SW407037.rst
+
+1740A - ibm-v1.99.10-0-r11
+``````````````````````````
+
+.. toctree::
+ :maxdepth: 1
+
+ SW406771.rst
+
+
+1738A - ibm-v1.99.10-0-r7
+``````````````````````````
+
+.. toctree::
+ :maxdepth: 1
+
+ SW404161.rst
+ SW402273.rst
diff --git a/perl-xCAT/xCAT/DBobjUtils.pm b/perl-xCAT/xCAT/DBobjUtils.pm
index 0d6697955..9eb185374 100755
--- a/perl-xCAT/xCAT/DBobjUtils.pm
+++ b/perl-xCAT/xCAT/DBobjUtils.pm
@@ -949,6 +949,7 @@ sub setobjdefs
my @setattrlist = ();
my %checkedattrs;
my $invalidattr;
+ my $conditionlist;
foreach my $this_attr (@{ $datatype->{'attrs'} }) {
my %keyhash;
@@ -1008,7 +1009,12 @@ sub setobjdefs
$checkedattrs{$attr_name} = 1;
if ($invalidattr->{$attr_name}->{valid} != 1) {
$invalidattr->{$attr_name}->{valid} = 0;
- $invalidattr->{$attr_name}->{condition} = "\'$check_attr=$check_value\'";
+ $invalidattr->{$attr_name}->{condition}=$check_attr;
+ if (defined($conditionlist->{$check_attr})) {
+ $conditionlist->{$check_attr}=$conditionlist->{$check_attr}.",".$check_value;
+ } else {
+ $conditionlist->{$check_attr}=$check_value;
+ }
}
next;
@@ -1017,8 +1023,12 @@ sub setobjdefs
if (!($objhash{$objname}{$check_attr} =~ /\b$check_value\b/) && !($DBattrvals{$objname}{$check_attr} =~ /\b$check_value\b/)) {
if ($invalidattr->{$attr_name}->{valid} != 1) {
$invalidattr->{$attr_name}->{valid} = 0;
- $invalidattr->{$attr_name}->{condition} = "\'$check_attr=$check_value\'";
-
+ $invalidattr->{$attr_name}->{condition}=$check_attr;
+ if (defined($conditionlist->{$check_attr})) {
+ $conditionlist->{$check_attr}=$conditionlist->{$check_attr}.",".$check_value;
+ } else {
+ $conditionlist->{$check_attr}=$check_value;
+ }
}
next;
@@ -1163,20 +1173,19 @@ sub setobjdefs
if ($invalidattr->{$att}->{valid} != 1) {
my $tt = $invalidattr->{$att}->{valid};
#if attribute is set invalid, check if its pre-check attribute exists in group objects, pick the attribute into valid.
- # ex. if I want to set hdwctrlpoint I will have
- # to match the right value for mgtmethod, but mgtmethod does exist in node object in chdef command
- # if mgtmethod exists in group objects, set hdwctrlpoint valid
- my $conditionkv=$invalidattr->{$att}->{condition};
- $conditionkv=~s/(^'|'$)//g;
- my ($attk, $attv)=split("=", $conditionkv);
- foreach my $tmpgrp (@tmplgrplist) {
- if ($DBgroupsattr{$tmpgrp}{$attk} eq $attv) {
- $pickvalidattr=1;
- last;
- }
+ # ex. like if I want to set hdwctrlpoint I will have
+ # to match the right value for mgtmethod
+ # if mgtmethod exists in group objects and its value match the one of only_if value, set hdwctrlpoint valid
+ my $conditionkey=$invalidattr->{$att}->{condition};
+ foreach my $tmpgrp (@tmplgrplist) {
+ if (($DBgroupsattr{$tmpgrp}{$conditionkey}) && ($conditionlist->{$conditionkey} =~ $DBgroupsattr{$tmpgrp}{$conditionkey})) {
+ $pickvalidattr=1;
+ last;
}
+ }
if ($pickvalidattr != 1) {
- push @{ $rsp->{data} }, "Cannot set the attr=\'$att\' attribute unless $invalidattr->{$att}->{condition}.";
+ $conditionlist->{$conditionkey}=~s/,/ or /g;
+ push @{ $rsp->{data} }, "Cannot set the attr=\'$att\' attribute unless $invalidattr->{$att}->{condition} value is $conditionlist->{$conditionkey}.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
}
}
diff --git a/perl-xCAT/xCAT/DSHCLI.pm b/perl-xCAT/xCAT/DSHCLI.pm
index 7e22de2d3..c1f59fdea 100644
--- a/perl-xCAT/xCAT/DSHCLI.pm
+++ b/perl-xCAT/xCAT/DSHCLI.pm
@@ -835,7 +835,7 @@ sub fork_fanout_dcp
my @target_file = split '/', $$options{'source'};
$rcp_config{'dest-file'} =
-"$$options{'target'}/$target_file[$#target_file]._$$target_properties{'hostname'}";
+ "$$options{'target'}/$target_file[$#target_file]._$$target_properties{'hostname'}";
}
@@ -850,6 +850,8 @@ sub fork_fanout_dcp
$$options{'destDir_srcFile'}{$user_target};
}
+ $dsh_trace
+ && ($rcp_config{'trace'} = 1);
#eval "require RemoteShell::$rsh_extension";
eval "require xCAT::$rsh_extension";
my $remoteshell = "xCAT::$rsh_extension";
@@ -5198,8 +5200,10 @@ sub parse_rsync_input_file_on_MN
foreach my $target_node (@dest_host)
{
- # skip the node if it's NOT in the permitted list
- if ($dest_node && !grep /^$target_node$/, @dest_nodes) {
+ # skip the node if it's NOT in the permitted list and if
+ # it's not a SN doing a hierarchical mode transfer
+ if ($dest_node && !(grep /^$target_node$/, @dest_nodes)
+ && ($rsyncSN != 1) ) {
next;
}
$$options{'destDir_srcFile'}{$target_node} ||= {};
@@ -5214,7 +5218,13 @@ sub parse_rsync_input_file_on_MN
if ($rsyncSN == 1)
{ # syncing the SN
$dest_dir = $syncdir; # the SN sync dir
- $dest_dir .= dirname($srcfile);
+ if($srcfile =~ /\/$/){
+ #the srcfile is a directory
+ $dest_dir .= $srcfile;
+ }else{
+ #the srcfile is a file
+ $dest_dir .= dirname($srcfile);
+ }
$dest_dir =~ s/\s*//g; #remove blanks
}
$$options{'destDir_srcFile'}{$target_node}{$dest_dir} ||=
@@ -5655,11 +5665,30 @@ sub parse_rsync_input_file_on_SN
} else { # not processing EXECUTE, EXECUTEALWAYS or APPEND
# otherwise it is just the synclist
- if ($line =~ /(.+) -> (.+)/)
+ # xCAT supports the syncfile format:
+ # file -> file
+ # file -> (noderange for permitted nodes) file
+ if ($line =~ /(.+) -> (.+)/ || $line =~ /(.+) -> +\((.+)\) +(.+)/)
{
$process_line = 1;
- my $src_file = $1;
- my $dest_file = $2;
+ my $src_file;
+ my $dest_file;
+ my $dest_node;
+ my @dest_nodes;
+ if ($line =~ /(.+) -> +\((.+)\) +(.+)/) {
+ $src_file = $1;
+ $dest_node = $2;
+ $dest_file = $3;
+ } elsif ($line =~ /(.+) -> (.+)/) {
+ $src_file = $1;
+ $dest_file = $2;
+ }
+
+ # get all the permitted nodes for the line
+ $dest_node =~ s/\s//g;
+ if ($dest_node) {
+ @dest_nodes = noderange($dest_node);
+ }
$dest_file =~ s/[\s;]//g; # remove blanks
# see if destination is a directory
@@ -5688,6 +5717,10 @@ sub parse_rsync_input_file_on_SN
foreach my $target_node (@dest_host)
{
+ # skip the node if it's NOT in the permitted list
+ if ($dest_node && ! grep /^$target_node$/, @dest_nodes) {
+ next;
+ }
$$options{'destDir_srcFile'}{$target_node} ||= {};
# for each file on the line
diff --git a/perl-xCAT/xCAT/RSYNC.pm b/perl-xCAT/xCAT/RSYNC.pm
index b40158d80..bd6d6efa3 100644
--- a/perl-xCAT/xCAT/RSYNC.pm
+++ b/perl-xCAT/xCAT/RSYNC.pm
@@ -156,7 +156,11 @@ sub remote_copy_command
$dest_user_host =
"$$config{'dest-user'}@" . "$$config{'dest-host'}";
}
- print RSCYCCMDFILE "#!/bin/sh\n";
+ if ($$config{'trace'}) {
+ print RSCYCCMDFILE "#!/bin/sh -x\n";
+ } else {
+ print RSCYCCMDFILE "#!/bin/sh\n";
+ }
if ($localhost == 1) { # running to the MN from the MN
print RSCYCCMDFILE
"/bin/mkdir -p $dest_dir_list\n";
diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm
index f01edfd98..02760f105 100755
--- a/perl-xCAT/xCAT/Schema.pm
+++ b/perl-xCAT/xCAT/Schema.pm
@@ -694,17 +694,25 @@ passed as argument rather than by table value',
},
},
pdu => {
- cols => [qw(node nodetype outlet machinetype modelnum serialnum comments disable)],
+ cols => [qw(node nodetype pdutype outlet username password snmpversion community snmpuser authtype authkey privtype privkey seclevel comments disable)],
keys => [qw(node)],
nodecol => "node",
table_desc => 'Parameters to use when interrogating pdus',
descriptions => {
node => 'The hostname/address of the pdu to which the settings apply',
nodetype => 'The node type should be pdu ',
+ pdutype => 'The type of pdu ',
outlet => 'The pdu outlet count',
- machinetype => 'The pdu machine type',
- modelnum => 'The pdu model number',
- serialnum => 'The pdu serial number',
+ username => 'The remote login user name',
+ password => 'The remote login password',
+ snmpversion => 'The version to use to communicate with switch. SNMPv1 is assumed by default.',
+ community => 'The community string to use for SNMPv1/v2',
+ snmpuser => 'The username to use for SNMPv3 communication, ignored for SNMPv1',
+ authtype => 'The authentication protocol(MD5|SHA) to use for SNMPv3.',
+ authkey => 'The authentication passphrase for SNMPv3 ',
+ privtype => 'The privacy protocol(AES|DES) to use for SNMPv3.',
+ privkey => 'The privacy passphrase to use for SNMPv3.',
+ seclevel => 'The Security Level(noAuthNoPriv|authNoPriv|authPriv) to use for SNMPv3.',
comments => 'Any user-written notes.',
disable => "Set to 'yes' or '1' to comment out this row.",
},
@@ -803,7 +811,7 @@ passed as argument rather than by table value',
pkglist => 'The fully qualified name of the file that stores the distro packages list that will be included in the image. Make sure that if the pkgs in the pkglist have dependency pkgs, the dependency pkgs should be found in one of the pkgdir',
pkgdir => 'The name of the directory where the distro packages are stored. It could be set to multiple paths. The multiple paths must be separated by ",". The first path in the value of osimage.pkgdir must be the OS base pkg dir path, such as pkgdir=/install/rhels6.2/x86_64,/install/updates . In the os base pkg path, there are default repository data. And in the other pkg path(s), the users should make sure there are repository data. If not, use "createrepo" command to create them. For ubuntu, multiple mirrors can be specified in the pkgdir attribute, the mirrors must be prefixed by the protocol(http/ssh) and delimited with "," between each other.',
otherpkglist => 'The fully qualified name of the file that stores non-distro package lists that will be included in the image. It could be set to multiple paths. The multiple paths must be separated by ",".',
- otherpkgdir => 'The base directory where the non-distro packages are stored. Only 1 local directory supported at present.',
+ otherpkgdir => 'The base directory and urls of internet repos from which the non-distro packages are retrived. Only 1 local directory is supported at present. The entries should be delimited with comma ",". Currently, the internet repos are only supported on Ubuntu and Redhat.',
exlist => 'The fully qualified name of the file that stores the file names and directory names that will be excluded from the image during packimage command. It is used for diskless image only.',
postinstall => 'Supported in diskless image only. The fully qualified name of the scripts running in non-chroot mode after the package installation but before initrd generation during genimage. If multiple scripts are specified, they should be seperated with comma ",". A set of osimage attributes are exported as the environment variables to be used in the postinstall scripts:
@@ -950,19 +958,19 @@ passed as argument rather than by table value',
table_desc => 'List of all Service Nodes and services that will be set up on the Service Node.',
descriptions => {
node => 'The hostname of the service node as known by the Management Node.',
- nameserver => 'Do we set up DNS on this service node? Valid values: 2, 1, no or 0. If 2, creates named.conf as dns slave, using the management node as dns master, and starts named. If 1, creates named.conf file with forwarding to the management node and starts named. If no or 0, it does not change the current state of the service. ',
- dhcpserver => 'Do we set up DHCP on this service node? Not supported on AIX. Valid values:yes or 1, no or 0. If yes, runs makedhcp -n. If no or 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:yes or 1, no or 0. If yes, configures and starts atftp. If no or 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:yes or 1, no or 0.If no or 0, it does not change the current state of the service. ',
- conserver => 'Do we set up Conserver on this service node? Valid values:yes or 1, no or 0. If yes, configures and starts conserver daemon. If no or 0, it does not change the current state of the service.',
- monserver => 'Is this a monitoring event collection point? Valid values:yes or 1, no or 0. If no or 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:yes or 1, no or 0. If no or 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:yes or 1, no or 0. If no or 0, it does not change the current state of the service.',
- ftpserver => 'Do we set up a ftp server on this service node? Not supported on AIX Valid values:yes or 1, no or 0. If yes, configure and start vsftpd. (You must manually install vsftpd on the service nodes before this.) If no or 0, it does not change the current state of the service. xCAT is not using ftp for compute nodes provisioning or any other xCAT features, so this attribute can be set to 0 if the ftp service will not be used for other purposes',
- nimserver => 'Not used. Do we set up a NIM server on this service node? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.',
- ipforward => 'Do we set up ip forwarding on this service node? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.',
+ nameserver => 'Do we set up DNS on this service node? Valid values: 2, 1, or 0. If 2, creates named.conf as dns slave, using the management node as dns master, and starts named. If 1, creates named.conf file with forwarding to the management node and starts named. If 0, it does not change the current state of the service. ',
+ 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.',
+ 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.',
+ ftpserver => 'Do we set up a ftp server on this service node? Not supported on AIX Valid values:1 or 0. If 1, configure and start vsftpd. (You must manually install vsftpd on the service nodes before this.) If 0, it does not change the current state of the service. xCAT is not using ftp for compute nodes provisioning or any other xCAT features, so this attribute can be set to 0 if the ftp service will not be used for other purposes',
+ nimserver => 'Not used. Do we set up a NIM server on this service node? Valid values:1 or 0. If 0, it does not change the current state of the service.',
+ ipforward => 'Do we set up ip forwarding on this service node? Valid values:1 or 0. If 0, it does not change the current state of the service.',
dhcpinterfaces => 'The network interfaces DHCP server should listen on for the target node. This attribute can be used for management node and service nodes. If defined, it will override the values defined in site.dhcpinterfaces. This is a comma separated list of device names. !remote! indicates a non-local network for relay DHCP. For example: !remote!,eth0,eth1',
- proxydhcp => 'Do we set up proxydhcp service on this node? valid values: yes or 1, no or 0. If yes, the proxydhcp daemon will be enabled on this node.',
+ proxydhcp => 'Do we set up proxydhcp service on this node? valid values: 1 or 0. If 1, the proxydhcp daemon will be enabled on this node.',
comments => 'Any user-written notes.',
disable => "Set to 'yes' or '1' to comment out this row.",
@@ -2950,24 +2958,64 @@ my @nodeattrs = (
tabentry => 'pdu.nodetype',
access_tabentry => 'pdu.node=attr:node',
},
+ { attr_name => 'pdutype',
+ only_if => 'nodetype=pdu',
+ tabentry => 'pdu.pdutype',
+ access_tabentry => 'pdu.node=attr:node',
+ },
{ attr_name => 'outlet',
only_if => 'nodetype=pdu',
tabentry => 'pdu.outlet',
access_tabentry => 'pdu.node=attr:node',
},
- { attr_name => 'machinetype',
+ { attr_name => 'username',
only_if => 'nodetype=pdu',
- tabentry => 'pdu.machinetype',
+ tabentry => 'pdu.username',
access_tabentry => 'pdu.node=attr:node',
},
- { attr_name => 'modelnum',
+ { attr_name => 'password',
only_if => 'nodetype=pdu',
- tabentry => 'pdu.modelnum',
+ tabentry => 'pdu.password',
access_tabentry => 'pdu.node=attr:node',
},
- { attr_name => 'serialnum',
+ { attr_name => 'snmpversion',
only_if => 'nodetype=pdu',
- tabentry => 'pdu.serialnum',
+ tabentry => 'pdu.snmpversion',
+ access_tabentry => 'pdu.node=attr:node',
+ },
+ { attr_name => 'community',
+ only_if => 'nodetype=pdu',
+ tabentry => 'pdu.community',
+ access_tabentry => 'pdu.node=attr:node',
+ },
+ { attr_name => 'snmpuser',
+ only_if => 'nodetype=pdu',
+ tabentry => 'pdu.snmpuser',
+ access_tabentry => 'pdu.node=attr:node',
+ },
+ { attr_name => 'authtype',
+ only_if => 'nodetype=pdu',
+ tabentry => 'pdu.authtype',
+ access_tabentry => 'pdu.node=attr:node',
+ },
+ { attr_name => 'authkey',
+ only_if => 'nodetype=pdu',
+ tabentry => 'pdu.authkey',
+ access_tabentry => 'pdu.node=attr:node',
+ },
+ { attr_name => 'privtype',
+ only_if => 'nodetype=pdu',
+ tabentry => 'pdu.privtype',
+ access_tabentry => 'pdu.node=attr:node',
+ },
+ { attr_name => 'privkey',
+ only_if => 'nodetype=pdu',
+ tabentry => 'pdu.privkey',
+ access_tabentry => 'pdu.node=attr:node',
+ },
+ { attr_name => 'seclevel',
+ only_if => 'nodetype=pdu',
+ tabentry => 'pdu.seclevel',
access_tabentry => 'pdu.node=attr:node',
},
diff --git a/perl-xCAT/xCAT/Scope.pm b/perl-xCAT/xCAT/Scope.pm
index 39bb3da44..215709361 100644
--- a/perl-xCAT/xCAT/Scope.pm
+++ b/perl-xCAT/xCAT/Scope.pm
@@ -219,6 +219,10 @@ sub get_broadcast_disjoint_scope_with_parallel {
my $reqs = get_parallel_scope($req);
my $handled4me = 0; # indicate myself is already handled.
+ if (xCAT::Utils->isMN()) { # For MN, add itself always.
+ push @requests, @$reqs;
+ $handled4me = 1;
+ }
my %prehandledhash = ();# the servers which is already handled.
foreach (@$extras) {
my $xcatdest = $_;
diff --git a/perl-xCAT/xCAT/ServiceNodeUtils.pm b/perl-xCAT/xCAT/ServiceNodeUtils.pm
index c27601874..13051df88 100755
--- a/perl-xCAT/xCAT/ServiceNodeUtils.pm
+++ b/perl-xCAT/xCAT/ServiceNodeUtils.pm
@@ -509,8 +509,11 @@ sub get_ServiceNode
# get site.master this will be the default
my $master = xCAT::TableUtils->get_site_Master();
- $noderestab = xCAT::Table->new('noderes');
+ unless($master){
+ xCAT::MsgUtils->message('SW',"site.master is not set!\n");
+ }
+ $noderestab = xCAT::Table->new('noderes');
unless ($noderestab) # no noderes table, use default site.master
{
xCAT::MsgUtils->message('I',
@@ -548,7 +551,7 @@ sub get_ServiceNode
my $key = $rec->{$snattribute};
push @{ $snhash{$key} }, $node;
}
- else # use site.master
+ elsif($master) # use site.master
{
push @{ $snhash{$master} }, $node;
}
@@ -595,7 +598,7 @@ sub get_ServiceNode
my $key = $rec->{$snattribute};
push @{ $snhash{$key} }, $node;
}
- else
+ elsif($master)
{ # use site.master
push @{ $snhash{$master} }, $node;
}
@@ -631,7 +634,7 @@ sub get_ServiceNode
my $key = $rec->{$snattribute};
push @{ $snhash{$key} }, $node;
}
- else
+ elsif($master)
{ # use site.master
push @{ $snhash{$master} }, $node;
}
@@ -675,7 +678,7 @@ sub get_ServiceNode
my $key = $sn->{$snattribute};
push @{ $snhash{$key} }, $node;
}
- else
+ elsif($master)
{ # no service node use master
push @{ $snhash{$master} }, $node;
}
diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm
index 67d1bee90..454f8cbc1 100755
--- a/perl-xCAT/xCAT/Usage.pm
+++ b/perl-xCAT/xCAT/Usage.pm
@@ -146,6 +146,7 @@ my %usage = (
rspconfig [userid= username= password=]
OpenBMC specific:
rspconfig [ipsrc|ip|netmask|gateway|hostname|vlan]
+ rspconfig dump [-l|--list] [-g|--generate] [-c|--clear {|all}] [-d|--download ]
iDataplex specific:
rspconfig [thermprofile]
rspconfig [thermprofile=]
@@ -353,7 +354,8 @@ my %usage = (
OpenPOWER OpenBMC specific:
rflash {[-c|--check] | [-l|--list]}
rflash {[-c|--check] | [-a|--activate] | [-u|--upload]}
- rflash {[-a|--activate] | [-d|--delete]}",
+ rflash [-d] [--no-host-reboot]
+ rflash {[-a|--activate] | [--delete]}",
"mkhwconn" =>
"Usage:
mkhwconn [-h|--help]
diff --git a/perl-xCAT/xCAT/Utils.pm b/perl-xCAT/xCAT/Utils.pm
index 35b9abea2..6a7f12c3a 100644
--- a/perl-xCAT/xCAT/Utils.pm
+++ b/perl-xCAT/xCAT/Utils.pm
@@ -48,7 +48,7 @@ require xCAT::Version;
require DBI;
our @ISA = qw(Exporter);
-our @EXPORT_OK = qw(genpassword runcmd3);
+our @EXPORT_OK = qw(genpassword runcmd3 natural_sort_cmp);
# The functions that has been moved to TableUtils.pm
@@ -4918,5 +4918,35 @@ sub acquire_lock_imageop {
return (0,$lock);
}
+#--------------------------------------------------------------------------------
+
+=head3 natural_sort_cmp
+ compare $left and $right by natural ordering.
+=cut
+
+#--------------------------------------------------------------------------------
+sub natural_sort_cmp($$) {
+ my $left = shift;
+ my $right = shift;
+ while() {
+ if( !($left =~ /\d+(\.\d+)?/) ) {
+ return $left cmp $right;
+ }
+ my $before = $`;
+ my $match = $&;
+ my $after = $';
+ if( !($right =~ /\d+(\.\d+)?/) ) {
+ return $left cmp $right;
+ }
+ if( $before ne $` ) {
+ return $left cmp $right;
+ } elsif( $match != $& ) {
+ return $match <=> $&;
+ } else {
+ $left = $after;
+ $right = $';
+ }
+ }
+}
1;
diff --git a/perl-xCAT/xCAT/data/switchinfo.pm b/perl-xCAT/xCAT/data/switchinfo.pm
index cf8f1af80..1a8986877 100644
--- a/perl-xCAT/xCAT/data/switchinfo.pm
+++ b/perl-xCAT/xCAT/data/switchinfo.pm
@@ -21,7 +21,8 @@ our %global_mac_identity = (
"8c:ea:1b" => "Edgecore Networks Switch",
"a8:2b:b5" => "Edgecore Networks Switch",
"3c:2c:99" => "Edgecore Networks Switch",
- "70:72:cf" => "Edgecore Networks Switch"
+ "70:72:cf" => "Edgecore Networks Switch",
+ "6c:64:1a" => "Penguin Computing switch"
);
#the hash to lookup switch type with vendor
@@ -40,7 +41,8 @@ our %global_switch_type = (
MELLAN => "Mellanox",
Cumulus => "onie",
cumulus => "onie",
- Edgecore => "onie"
+ Edgecore => "onie",
+ coral => "crpdu"
);
diff --git a/xCAT-client/bin/rcons b/xCAT-client/bin/rcons
index c5b1b78df..7a432c08c 100755
--- a/xCAT-client/bin/rcons
+++ b/xCAT-client/bin/rcons
@@ -62,6 +62,9 @@ done
# confluent if this keyword is defined in the site table. This allows for confluent to
# be installed on the xCAT management node and switch between conserver & confluent
USE_CONFLUENT=0
+# If conluent is not enable, check the service status of goconserver.
+# If goconserver is strated, use rcons through goconserver, otherwise through conserver.
+USE_GOCONSERVER=0
CONSOLE_SERVICE_KEYWORD=`tabdump site | grep consoleservice | cut -d, -f1 | tr -d '"'`
CONSOLE_SERVICE_VALUE=`tabdump site | grep consoleservice | cut -d, -f2 | tr -d '"'`
@@ -71,6 +74,20 @@ if [ "$CONSOLE_SERVICE_KEYWORD" == "consoleservice" ]; then
fi
fi
+if [ $USE_CONFLUENT != "1" ] && [ -f "/usr/bin/congo" ] && [ -f "/usr/bin/goconserver" ]; then
+ GOCONSERVER_RC=`service goconserver status >& /dev/null; echo $?`
+ if [[ ${GOCONSERVER_RC} == 0 ]]; then
+ USE_GOCONSERVER=1
+ fi
+ if [[ ${USE_GOCONSERVER} == 1 ]]; then
+ CONSERVER_RC=`pidof conserver >> /dev/null; echo $?`
+ if [[ ${CONSERVER_RC} == 0 ]]; then
+ echo "Error: Both goconserver and conserver are running, please stop one of them, and retry..."
+ exit 1
+ fi
+ fi
+fi
+
if [ $USE_CONFLUENT == "1" ] && ([ -x "/opt/confluent/bin/confetty" ] || [ -x "/usr/bin/confetty" ] || [ -x "/usr/local/bin/confetty" ]); then
# use confluent, make sure conserver is not also running
CONSERVER_RC=`pidof conserver >> /dev/null; echo $?`
@@ -78,6 +95,11 @@ if [ $USE_CONFLUENT == "1" ] && ([ -x "/opt/confluent/bin/confetty" ] || [ -x "/
echo "Error: consoleservice is set to 'confluent' but conserver is running. Stop conserver, run makeconfluentcfg, and retry..."
exit 1
fi
+ GOCONSERVER_RC=`service goconserver status >& /dev/null; echo $?`
+ if [[ ${GOCONSERVER_RC} == 0 ]]; then
+ echo "Error: consoleservice is set to 'confluent' but goconserver is running. Stop goconserver, run makeconfluentcfg, and retry..."
+ exit 1
+ fi
CONFETTY="confetty"
if [ -x "/opt/confluent/bin/confetty" ]; then
CONFETTY="/opt/confluent/bin/confetty"
@@ -103,6 +125,53 @@ if [ $USE_CONFLUENT == "1" ] && ([ -x "/opt/confluent/bin/confetty" ] || [ -x "/
CONSERVER="-s $CONSERVER"
fi
$CONFETTY $CONSCONTROLPATH $CONSERVER $1
+elif [ $USE_GOCONSERVER == "1" ]; then
+ # use goconserver
+ # make sure confluent is not also running, only if confluent is installed
+ if [[ -f "/etc/init.d/confluent" ]]; then
+ CONFLUENT_RC=`service confluent status >& /dev/null; echo $?`
+ if [[ ${CONFLUENT_RC} == 0 ]]; then
+ echo "Error: confluent is running. Stop confluent, run makegocons, and retry..."
+ exit 1
+ fi
+ fi
+ if [ -z "$CONSERVER" ]; then
+ CONSERVER=`nodels $1 nodehm.conserver 2>/dev/null | awk -F: '{print $2}' | tr -d ' '`
+ fi
+
+ if [ -z "$CONSERVER" ]; then
+ CONSERVER=$XCATHOST
+ fi
+ if [ -z "$CONSERVER" ]; then
+ CONSERVER=`hostname`
+ fi
+ CONGO_ENV="CONGO_SSL_KEY=$HOME/.xcat/client-cred.pem \
+ CONGO_SSL_CERT=$HOME/.xcat/client-cred.pem \
+ CONGO_SSL_CA_CERT=$HOME/.xcat/ca.pem \
+ CONGO_PORT=12430 \
+ CONGO_CLIENT_TYPE=xcat"
+ if [ "$CONSERVER" == `hostname` ]; then
+ host=`hostname -s`
+ if [ $? -ne 0 ]; then
+ echo "Error: could not get the short hostname for $CONSERVER."
+ exit 1
+ fi
+ CONGO_ENV="$CONGO_ENV \
+ CONGO_SERVER_HOST=$host \
+ CONGO_URL=https://$host:12429"
+ exec env $CONGO_ENV /usr/bin/congo console $1
+ else
+ host=`ssh $CONSERVER hostname -s`
+ if [ $? -ne 0 ]; then
+ echo "Error: could not get the short hostname for $CONSERVER."
+ exit 1
+ fi
+ CONGO_ENV="$CONGO_ENV \
+ CONGO_SERVER_HOST=$host \
+ CONGO_URL=https://$host:12429"
+ exec ssh -t $CONSERVER "$CONGO_ENV /usr/bin/congo console $1"
+ fi
+
elif [ -f "/usr/bin/console" ] || [ -f "/bin/console" ]; then
# use conserver
# make sure confluent is not also running, only if confluent is installed
diff --git a/xCAT-client/debian/xcat-client.links b/xCAT-client/debian/xcat-client.links
index ed2ac8134..0bf090cd8 100644
--- a/xCAT-client/debian/xcat-client.links
+++ b/xCAT-client/debian/xcat-client.links
@@ -6,6 +6,7 @@ opt/xcat/bin/xcatclient opt/xcat/sbin/makeknownhosts
opt/xcat/bin/xcatclient opt/xcat/sbin/nodeset
opt/xcat/bin/xcatclient opt/xcat/sbin/setupiscsidev
opt/xcat/bin/xcatclient opt/xcat/sbin/makeconservercf
+opt/xcat/bin/xcatclient opt/xcat/sbin/makegocons
opt/xcat/bin/xcatclient opt/xcat/bin/rbeacon
opt/xcat/bin/xcatclient opt/xcat/bin/rvitals
opt/xcat/bin/xcatclient opt/xcat/bin/nodestat
diff --git a/xCAT-client/pods/man1/bmcdiscover.1.pod b/xCAT-client/pods/man1/bmcdiscover.1.pod
index fc9ddfe5a..20ffd84b4 100644
--- a/xCAT-client/pods/man1/bmcdiscover.1.pod
+++ b/xCAT-client/pods/man1/bmcdiscover.1.pod
@@ -10,10 +10,6 @@ B [B<-v>|B<--version>]
B [B<--sn> I] [B<-s> I] [B<-u> I] [B<-p> I] [B<-z>] [B<-w>] B<--range> I
-B B<-u> I B<-p> I B<-i> I B<--check>
-
-B [B<-u> I] [B<-p> I] B<-i> I B<--ipsource>
-
=head1 DESCRIPTION
@@ -61,14 +57,6 @@ BMC user name.
BMC user password.
-=item B<--check>
-
-Check BMC administrator User/Password.
-
-=item B<--ipsource>
-
-Display the BMC IP configuration.
-
=item B<-h|--help>
Display usage message
@@ -117,14 +105,6 @@ Output is similar to:
bmcdiscover -s nmap --range "10.4.22-23.100-254" -w -z
-5. To check if the username or password is correct against the BMC:
-
- bmcdiscover -i 10.4.23.254 -u USERID -p PASSW0RD --check
-
-6. Get BMC IP Address source, DHCP Address or static Address
-
- bmcdiscover -i 10.4.23.254 -u USERID -p PASSW0RD --ipsource
-
=head1 SEE ALSO
L
diff --git a/xCAT-client/pods/man1/rflash.1.pod b/xCAT-client/pods/man1/rflash.1.pod
index ee2b29da1..447bdc332 100644
--- a/xCAT-client/pods/man1/rflash.1.pod
+++ b/xCAT-client/pods/man1/rflash.1.pod
@@ -34,7 +34,9 @@ B I {[B<-c>|B<--check>] | [B<-l>|B<--list>]}
B I I {[B<-c>|B<--check>] | [B<-a>|B<--activate>] | [B<-u>|B<--upload>]}
-B I I {[B<-a>|B<--activate>] | [B<-d>|B<--delete>]}
+B I I [B<-d>] [B<--no-host-reboot>]
+
+B I I {[B<-a>|B<--activate>] | [B<--delete>]}
=head1 B
@@ -91,14 +93,44 @@ The command will update firmware for NeXtScale FPC when given an FPC node and th
=head2 OpenPOWER specific (using IPMI):
-The command will update firmware for OpenPOWER BMC when given an OpenPOWER node and either the hpm formatted file path or path to a data directory.
+The command will update firmware for OpenPOWER BMC when given an OpenPOWER node with I and either the hpm formatted file path or path to a data directory.
+
B When using B in hierarchical environment, the hpm file or data directory must be accessible from Service Nodes.
-=head2 OpenPOWER OpenBMC specific:
+=head2 OpenPOWER specific (using OpenBMC):
+
+The command will update firmware for OpenPOWER BMC when given an OpenPOWER node with I and either an update .tar file or an uploaded image id.
+
+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 (*) 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.
+
+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.
+
+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
+
+To apply the firmware level, a reboot is required to BMC and HOST.
-The command will update firmware for OpenPOWER OpenBMC when given an OpenPOWER node and either an update .tar file or an uploaded image id.
B When using B in hierarchical environment, the .tar file must be accessible from Service Nodes.
+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.
+
+B 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.
+
=head1 B
=over 7
@@ -159,7 +191,7 @@ List currently uploaded update images. "(*)" indicates currently active image.
Upload update image. Specified file must be in .tar format.
-=item B<-d|--delete>
+=item B<--delete>
Delete update image from BMC
@@ -213,14 +245,14 @@ Print verbose message to rflash log file (/var/log/xcat/rflash/fs3.log) when upd
rflash fs3 /firmware/8335_810.1543.20151021b_update.hpm -V
=item 6.
-To update the firmware on IBM Power S822LC for Big Data machine specify the node name and the file path of the data directory containing pUpdate utility and BMC and/or PNOR update files:
+To update the firmware on IBM Power S822LC for Big Data machine specify the node name and the file path of the data directory containing pUpdate utility, both BMC and PNOR update files:
rflash briggs01 -d /root/supermicro/OP825
=item 7.
To update the firmware on the OpenBMC machine, specify the firmare update file to upload and activate:
- rflash p9euh02 -a /tmp/witherspoon.pnor.squashfs.tar
+ rflash p9euh02 -a /tmp/witherspoon.pnor.squashfs.tar
=back
diff --git a/xCAT-client/pods/man1/rmdef.1.pod b/xCAT-client/pods/man1/rmdef.1.pod
index 95b4358b1..38b67b077 100644
--- a/xCAT-client/pods/man1/rmdef.1.pod
+++ b/xCAT-client/pods/man1/rmdef.1.pod
@@ -58,7 +58,7 @@ A set of comma delimited object types.
=item B<-C|--cleanup>
-Perform additional cleanup by running B on the objects specified in the I.
+Perform additional cleanup by running B and B on the objects specified in the I.
=item B<-V|--verbose>
diff --git a/xCAT-client/pods/man1/rspconfig.1.pod b/xCAT-client/pods/man1/rspconfig.1.pod
index a61149197..fbd1fa6f0 100644
--- a/xCAT-client/pods/man1/rspconfig.1.pod
+++ b/xCAT-client/pods/man1/rspconfig.1.pod
@@ -26,6 +26,8 @@ B I B=I
B I {B|B|B|B|B|B|B}
+B I B [B<-l>|B<--list>] [B<-g>|B<--generate>] [B<-c>|B<--clear> {I|B}] [B<-d>|B<--download> I]
+
=head2 MPA specific:
B I {B|B|B|B|B|B|B|B|B }
@@ -324,6 +326,26 @@ Select whether each memory bank should be enabled or disabled. State changes tak
The subnet mask.
+=item B
+
+Manage OpenBMC system dumps. If no sub-option is provided, will generate, wait, and download the dump.
+
+=over 4
+
+=item
+B<-c> will clear a single specified dump, or use 'all' to clear all dumps on the BMC.
+
+=item
+B<-l> will list all the generated dumps on the BMC.
+
+=item
+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.
+
+=back
+
=item B={[I],[I],[I],[I]|*}
For MPA: get or set the MPA network parameters. If '*' is specified, all parameters are read from the xCAT database.
@@ -813,6 +835,30 @@ Output is similar to:
fsp: Success
+=item 31.
+To list BMC dumps available for download:
+
+ rspconfig p9euh02 dump -l
+
+Output is similar to:
+
+ p9euh02: [1] Generated: 09/06/2017 14:31:49, Size: 4528
+ p9euh02: [2] Generated: 09/06/2017 14:31:55, Size: 4516
+ p9euh02: [3] Generated: 09/06/2017 14:32:01, Size: 4236
+ p9euh02: [4] Generated: 09/06/2017 14:32:07, Size: 4248
+ p9euh02: [5] Generated: 09/06/2017 14:32:11, Size: 4268
+
+=item 32.
+To generate and download BMC dump:
+
+ rspconfig p9euh02 dump
+
+Output is similar to:
+
+ Capturing BMC Diagnostic information, this will take some time...
+ p9euh02: Dump requested. Target ID is 6, waiting for BMC to generate...
+ p9euh02: Dump 6 generated. Downloading to /var/log/xcat/dump/20171211-0951_p9euh02_dump_6.tar.xz
+
=back
=head1 SEE ALSO
diff --git a/xCAT-client/pods/man8/makeconservercf.8.pod b/xCAT-client/pods/man8/makeconservercf.8.pod
index 5b4dad03d..036c28757 100644
--- a/xCAT-client/pods/man8/makeconservercf.8.pod
+++ b/xCAT-client/pods/man8/makeconservercf.8.pod
@@ -6,6 +6,8 @@ B - creates the conserver configuration file from info in the x
B [B<-V|--verbose>] [B<-d|--delete>] [I]
+B [B<-V|--verbose>] [B<-C|--cleanup>]
+
B [B<-V|--verbose>] [B<-l|--local>] [I]
B [B<-V|--verbose>] [B<-c|--conserver>] [I]
@@ -24,6 +26,8 @@ does not have nodehm.cons set, it will not be written to the file.
If B<-d> is specified, B will remove specified nodes from /etc/conserver.cf file. If I is not specified, all xCAT nodes will be removed from /etc/conserver.cf file.
+If B<-C|--cleanup> is specified, B will remove console configuration entries from /etc/conserver.cf for the nodes whose definitions have been removed from xCATdb. B specify any noderange.
+
In the case of a hierarchical cluster (i.e. one with service nodes) B will determine
which nodes will have their consoles accessed from the management node and which from a service node
(based on the nodehm.conserver attribute). The /etc/conserver.cf file will be created accordingly on
@@ -38,6 +42,10 @@ all relevant management/service nodes. If B<-l> is specified, it will only crea
Delete rather than add or refresh the nodes specified as a noderange.
+=item B<-C|--cleanup>
+
+Remove the entries for the nodes whose definitions have been removed from xCAT db.
+
=item B<-c|--conserver>
Only set up the conserver on the conserver host. If no conserver host
diff --git a/xCAT-client/pods/man8/makegocons.8.pod b/xCAT-client/pods/man8/makegocons.8.pod
new file mode 100644
index 000000000..504c9dd69
--- /dev/null
+++ b/xCAT-client/pods/man8/makegocons.8.pod
@@ -0,0 +1,98 @@
+=head1 NAME
+
+B - Register or unregister the node in the goconserver service
+
+=head1 SYNOPSIS
+
+B [B<-V|--verbose>] [B<-d|--delete>] [I]
+
+B [B<-h|--help|-v|--version>]
+
+
+=head1 DESCRIPTION
+
+The B command will start the goconserver service if it is not started, then
+send the REST request to create or delete the session resource in the goconserver service. The session
+information including the session command or ssh connection parameters (for openbmc) is generated by xcat
+based on the records in the related tables (e.g. nodehm, ipmi, ppc, openbmc).
+
+By default B will register the session for all of the nodes in xcat.
+
+If a I is specified, only the session in the specified scope will be affected, goconserver
+service will not be restarted and the other session will not be disconnected. This is the advantage
+of goconserver over the conserver service with B.
+
+If B<-d> is specified, B will remove the session in the goconserver service.
+
+In the case of a hierarchical cluster (i.e. one with service nodes) B will determine
+which nodes will have their consoles accessed from the management node and which from a service node
+(based on the nodehm.conserver attribute).
+
+For openbmc which uses ssh as the terminal session connection method, goconserver can help save the system
+resources as goconserver could handle the ssh connection within goroutine which is more light-weighted than the command process.
+
+B goconserver is an experimental feature, it will not be installed with xcat and will only support the systemd based systems.
+Download and setup the rpm or deb package manually. Release link:
+
+ https://github.com/chenglch/goconserver/releases
+
+=head1 OPTIONS
+
+=over 10
+
+=item B<-d|--delete>
+
+Delete rather than add or refresh the nodes specified as a noderange.
+
+=item B<-v|--version>
+
+Display version.
+
+=item B<-V|--verbose>
+
+Verbose mode.
+
+=item B<-h|--help>
+
+Display usage message.
+
+=back
+
+
+=head1 RETURN VALUE
+
+=over 2
+
+=item 0.
+The command completed successfully.
+
+=item 1.
+An error has occurred.
+
+=back
+
+=head1 EXAMPLES
+
+=over 2
+
+=item 1.
+To create goconserver configuration for all the nodes.
+
+ makegocons
+
+=item 2.
+To create goconserver configuration for nodes node01-node10.
+
+ makegocons node01-node10
+
+=item 3.
+To remove goconserver configuration for node01.
+
+ makegocons -d node01
+
+=back
+
+=head1 SEE ALSO
+
+L
+
diff --git a/xCAT-client/xCAT-client.spec b/xCAT-client/xCAT-client.spec
index 05dd07a37..5b44dabcf 100644
--- a/xCAT-client/xCAT-client.spec
+++ b/xCAT-client/xCAT-client.spec
@@ -150,6 +150,7 @@ ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/sbin/makeknownhosts
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/sbin/nodeset
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/sbin/setupiscsidev
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/sbin/makeconservercf
+ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/sbin/makegocons
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/rbeacon
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/rvitals
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/nodestat
diff --git a/xCAT-genesis-builder/buildrpm b/xCAT-genesis-builder/buildrpm
index 8253ce5d1..dfd318818 100755
--- a/xCAT-genesis-builder/buildrpm
+++ b/xCAT-genesis-builder/buildrpm
@@ -20,8 +20,11 @@ if [ -z $1 ]; then
if [ $BUILDARCH = "ppc64le" ]; then
HOSTOS="Pegas1.0"
BUILDARCH="ppc64"
- else
+ elif [ $BUILDARCH = "ppc64" ]; then
HOSTOS="fedora26"
+ elif [ $BUILDARCH = "x86_64" ]; then
+ yum install efibootmgr bc -y
+ HOSTOS="centos7"
fi
fi
@@ -35,9 +38,22 @@ else
DRACUTMODDIR=/usr/lib/dracut/modules.d/97xcat
fi
+# get all modules in the kernel
+cd $DIR
+KERVER=`uname -r`
+if [ ! -e "./default_module_list" ]; then
+ mv ./installkernel ./default_module_list
+fi
+echo "#!/bin/bash" > ./installkernel
+for line in `cat /lib/modules/$KERVER/modules.dep | awk -F: '{print \$1}'`; do
+ basename $line >> ./installkernel;
+done
+sed -i 's/\(.*\)\.ko.*/instmods \1/g' ./installkernel
+chmod +x ./installkernel
+cd -
+
mkdir -p $DRACUTMODDIR
cp $DIR/* $DRACUTMODDIR
-
# Remove the ipr(IBM Power RAID) stuff when building on x86_64
if [ $BUILDARCH = "x86_64" ]; then
sed -i 's/dracut_install \/lib64\/libform.so.5//' $DRACUTMODDIR/install
@@ -48,6 +64,11 @@ if [ $BUILDARCH = "x86_64" ]; then
sed -i '/\/usr\/sbin\/iprconfig/ d' $DRACUTMODDIR/install
sed -i '/hwdb.bin/ d' $DRACUTMODDIR/install
sed -i 's/instmods ipr//' $DRACUTMODDIR/installkernel
+ sed -i 's/ mkreiserfs//' $DRACUTMODDIR/install
+ sed -i 's/ reiserfstune//' $DRACUTMODDIR/install
+ sed -i 's/ vconfig//' $DRACUTMODDIR/install
+ sed -i 's/\/lib\/terminfo\/l\/linux/\/usr\/share\/terminfo\/l\/linux/g' $DRACUTMODDIR/install
+ sed -i 's/\/lib\/terminfo\/v\/vt100/\/usr\/share\/terminfo\/v\/vt100/g' $DRACUTMODDIR/install
fi
if [ "$HOSTOS" = "mcp" ]; then
#Special handlings for MCP PPC64 platform building.
@@ -130,12 +151,11 @@ if [ "$HOSTOS" = "mcp" ]; then
else
echo Creating the initramfs in /tmp/xcatgenesis.$$.rfs using dracut ...
fi
-
# On Fedora 20 ppc64, dracut uses host-only mode by default
if [ $BUILDARCH = "ppc64" ]; then
dracut -m "xcat base" -N -f /tmp/xcatgenesis.$$.rfs $KERNELVERSION
else
- dracut -m "xcat base" -f /tmp/xcatgenesis.$$.rfs $KERNELVERSION
+ dracut -m "xcat base" --no-early-microcode -N -f /tmp/xcatgenesis.$$.rfs $KERNELVERSION
fi
if [ $? -ne 0 ]; then
@@ -145,6 +165,7 @@ fi
echo Expanding the initramfs into /tmp/xcatgenesis.$$/opt/xcat/share/xcat/netboot/genesis/$BUILDARCH/fs ...
cd /tmp/xcatgenesis.$$/opt/xcat/share/xcat/netboot/genesis/$BUILDARCH/fs
+
zcat /tmp/xcatgenesis.$$.rfs|cpio -dumi
# add the perl library
@@ -159,13 +180,15 @@ for d in `echo $PERL_LIB_DIR`; do
fi
done
+
# create the predictable naming for nics
LIB_UDEV_RULES="/lib/udev/rules.d/"
-cp $DRACUTMODDIR/80-net-name-slot.rules /tmp/xcatgenesis.$$/opt/xcat/share/xcat/netboot/genesis/$BUILDARCH/fs/lib/udev/rules.d/
-
-if [ $? -ne 0 ]; then
- echo "ERROR - expanding the initramfs, please correct the issues and try again"
- exit 1
+if [ ! -e "$LIB_UDEV_RULES/80-net-name-slot.rules" ]; then
+ cp $DRACUTMODDIR/80-net-name-slot.rules /tmp/xcatgenesis.$$/opt/xcat/share/xcat/netboot/genesis/$BUILDARCH/fs/lib/udev/rules.d/
+ if [ $? -ne 0 ]; then
+ echo "ERROR - expanding the initramfs, please correct the issues and try again"
+ exit 1
+ fi
fi
# add the kernel
diff --git a/xCAT-genesis-builder/xCAT-genesis-base.spec b/xCAT-genesis-builder/xCAT-genesis-base.spec
old mode 100755
new mode 100644
index f716c87db..1b9cb3e46
--- a/xCAT-genesis-builder/xCAT-genesis-base.spec
+++ b/xCAT-genesis-builder/xCAT-genesis-base.spec
@@ -29,6 +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
Buildroot: %{_localstatedir}/tmp/xCAT-genesis
BuildRequires: /usr/sbin/ntp-wait
@@ -51,6 +52,79 @@ tar jxf %{SOURCE1}
cd -
+%pretrans -p
+-- Lua block of code for removing a directory recursively
+-- The Lua function remove_directory_deep should be called
+-- with a directory name or, in a spec file, also with
+-- a rpm macro defined to a directory name. This function
+-- is a possible lua equivalent of the shell command "rm -rf"
+-- using the lua posix extension embedded in rpm
+local leaf_indent = '| '
+local tail_leaf_indent = ' '
+local leaf_prefix = '|-- '
+local tail_leaf_prefix = '`-- '
+local link_prefix = ' -> '
+
+local function printf(...)
+ io.write(string.format(unpack(arg)))
+end
+
+local function remove_directory(directory, level, prefix)
+ local num_dirs = 0
+ local num_files = 0
+ if posix.access(directory,"rw") then
+ local files = posix.dir(directory)
+ local last_file_index = table.getn(files)
+ table.sort(files)
+ for i, name in ipairs(files) do
+ if name ~= '.' and name ~= '..' then
+ local full_name = string.format('%s/%s', directory, name)
+ local info = assert(posix.stat(full_name))
+ local is_tail = (i==last_file_index)
+ local prefix2 = is_tail and tail_leaf_prefix or leaf_prefix
+ local link = ''
+ if info.type == 'link' then
+ linked_name = assert(posix.readlink(full_name))
+ link = string.format('%s%s', link_prefix, linked_name)
+ posix.unlink(full_name)
+ end
+
+ -- printf('%s%s%s%s\n', prefix, prefix2, name, link)
+
+ if info.type == 'directory' then
+ local indent = is_tail and tail_leaf_indent or leaf_indent
+ sub_dirs, sub_files = remove_directory(full_name, level+1,
+ prefix .. indent)
+ num_dirs = num_dirs + sub_dirs + 1
+ num_files = num_files + sub_files
+ posix.rmdir(full_name)
+ else
+ posix.unlink(full_name)
+ num_files = num_files + 1
+ end
+ end
+ end
+ end -- if access
+ return num_dirs, num_files
+end
+
+local function remove_directory_deep(directory)
+
+ -- print(directory)
+
+ num_dirs, num_files = remove_directory(directory, 0, '')
+
+ -- printf('\ndropped %d directories, %d files\n', num_dirs, num_files)
+
+ posix.rmdir(directory)
+end
+
+remove_directory_deep("/opt/xcat/share/xcat/netboot/genesis/%{tarch}/fs/bin")
+remove_directory_deep("/opt/xcat/share/xcat/netboot/genesis/%{tarch}/fs/sbin")
+remove_directory_deep("/opt/xcat/share/xcat/netboot/genesis/%{tarch}/fs/lib")
+remove_directory_deep("/opt/xcat/share/xcat/netboot/genesis/%{tarch}/fs/lib64")
+remove_directory_deep("/opt/xcat/share/xcat/netboot/genesis/%{tarch}/fs/var/run")
+
%post
if [ "$1" == "2" ]; then #only on upgrade, as on install it's probably not going to work...
if [ -f "/proc/cmdline" ]; then # prevent running it during install into chroot image
diff --git a/xCAT-genesis-scripts/bin/bmcsetup b/xCAT-genesis-scripts/bin/bmcsetup
index 31114c4d9..151e5d12d 100755
--- a/xCAT-genesis-scripts/bin/bmcsetup
+++ b/xCAT-genesis-scripts/bin/bmcsetup
@@ -396,7 +396,11 @@ fi
# update the node status to 'bmcready' for openbmc, no more configuration is needed.
if [ ! -z "$ISOPENBMC" ]; then
# To enable network configuration for openbmc
- ipmitool -d 0 lan set $LANCHAN access on
+ #
+ # For OpenBMC, FW team still suggest running the raw command instead of access on, use raw for now
+ #
+ # ipmitool -d 0 lan set $LANCHAN access on
+ ipmitool -d 0 raw 0x06 0x40 $LANCHAN 0x42 0x44
# update the node status to 'bmcready'
if [ ! -z "$XCATMASTER" ]; then
# Wait for some time for the new network setting is ready
diff --git a/xCAT-genesis-scripts/bin/dodiscovery b/xCAT-genesis-scripts/bin/dodiscovery
index d72d8cd85..c23f99fae 100755
--- a/xCAT-genesis-scripts/bin/dodiscovery
+++ b/xCAT-genesis-scripts/bin/dodiscovery
@@ -50,17 +50,12 @@ if [ $timewaiting != 700 -a $timewaiting -gt 450 ]; then
logger -s -t $log_label -p local4.warning "Obtained an IP address $NICSGETTINGADDR but it took $timewaiting cycles, you may want to check the spanning tree configuration in the switch."
fi
logger -s -t $log_label -p local4.info "Network configuration complete, commencing transmit of discovery packets"
-XCATPORT=3001
+read XCATMASTER XCATPORT < <(grep xcatd= /proc/cmdline| sed 's/.*xcatd=\([^ ]*\).*/\1/' |tr ':' ' ')
+if [[ -z $XCATPORT ]]; then
+ XCATPORT=3001
+fi
export XCATPORT
-for parm in `cat /proc/cmdline`; do
- key=`echo $parm|awk -F= '{print $1}'`
- if [ "$key" = "xcatd" ]; then
- XCATMASTER=`echo $parm|awk -F= '{print $2}'|awk -F: '{print $1}'`
- XCATPORT=`echo $parm|awk -F= '{print $2}'|awk -F: '{print $2}'`
- fi
-done
-
-
+
#time to make our packet...
while [ ! -r /restart ]; do
@@ -69,7 +64,7 @@ while [ ! -r /restart ]; do
#the existence of "/processing" indicates that my findme request is under processing
if [ -f "/processing" ]; then
- if [ $curtime -gt $[ $reqtime + $maxresptime ] ]; then
+ if [ $curtime -gt $((reqtime+maxresptime)) ]; then
#I think my findme request processing is timeout, I will resend the findme request
logger -s -t $log_label -p local4.info "seems the processing of my findme request cost more than $maxresptime, send new findme request"
rm -rf /processing
@@ -134,8 +129,8 @@ fi
# The MEMORY will look like this: 32868920
MEMORY=`cat /proc/meminfo |grep MemTotal|awk '{printf "%.0fMB\n", $2/1024}'`
-# The DISKSIZE will look like this: sdb:250GB,sda:250GB
-DISKSIZE=`cat /proc/partitions |grep -e "sd.\>" |awk -F' ' '{printf "%s:%.0fGB\n", $4, $3*0.000001024}' |sed 'N;s/\n/,/'`
+# The DISKSIZE will look like this: sda:960GB,sdb:960GB,sdc:480GB,sdd:480GB (sorted by major,minor)
+DISKSIZE="$(grep -v name /proc/partitions |sort -g -k 1,2 |awk 'BEGIN{sep=""} /[^0-9]$/{printf("%s%s:%.0fGB", sep, $4, $3/1024^2) ; sep=","}')"
logger -s -t $log_label -p local4.info "Beginning echo information to discovery packet file..."
echo '' > /tmp/discopacket
@@ -153,12 +148,12 @@ if [ "$UUID" != "unknown" ]; then
echo "$UUID " >> /tmp/discopacket
fi
-flag_mtm=`echo '$MTM' | sed 's/0//g'`
-if [ $flag_mtm ] && [ "$MTM" != "unknown" ]; then
+flag_mtm=`echo "$MTM" | sed 's/0//g'`
+if [ "$flag_mtm" ] && [ "$MTM" != "unknown" ]; then
MTM=`echo $MTM | sed 's/\.//g'`
echo "$MTM " >> /tmp/discopacket
fi
-flag_serial=`echo '$SERIAL' | sed 's/0//g'`
+flag_serial=`echo "$SERIAL" | sed 's/0//g'`
if [ $flag_serial ] && [ "$SERIAL" != "unknown" ]; then
SERIAL=`echo $SERIAL | sed 's/\.//g'`
echo "$SERIAL " >> /tmp/discopacket
@@ -192,7 +187,7 @@ fi
if [ -f "/usr/sbin/dmidecode" ]; then
for onboard in `dmidecode -t 41|egrep '(Type:|Bus Address)'|grep -A1 Ethernet|grep -v Ethernet|sed -e 's/.*Address: //'`; do
obdevs=("${obdevs[@]}" $onboard)
- if [ ${onboard#*.}=0 ]; then
+ if [ ${onboard#*.} = 0 ]; then
truncslot=${onboard%.*}
for obslot in `grep $truncslot /sys/class/net/*/device/uevent|sed -e s/.*=//`; do
if ! dmidecode -t 41|grep $obslot > /dev/null; then
@@ -218,7 +213,7 @@ for dev in `ip link|grep -B1 ether|grep UP|awk '{print $2}'|sed -e s/://|grep -v
SLOTNAME=`dmidecode -t 9|egrep '(Designation|Address)'|grep -B1 $PCI_SLOT|grep Designation|sed -e 's/.*Designation:[ ]*//'`
if [ -z "$SLOTNAME" ]; then #check for on board device
index=1
- for s in ${obdevs[@]}; do
+ for s in "${obdevs[@]}"; do
if [ "$s" = "$PCI_SLOT" ]; then
ONBOARDINDEX=$index
break
diff --git a/xCAT-probe/subcmds/osdeploy b/xCAT-probe/subcmds/osdeploy
index 1b23044cc..bbcbd1914 100755
--- a/xCAT-probe/subcmds/osdeploy
+++ b/xCAT-probe/subcmds/osdeploy
@@ -154,7 +154,10 @@ if ($debug) {
}
#if failed to pass pre-check, exit directly
-exit $rst if ($rst);
+if ($rst){
+ probe_utils->send_msg("stdout", "f", "Provison pre-check");
+ exit $rst;
+}
# record every status's start time and end time for each node
# $node_status_time{$node}{$status}{start_time} = $start_time;
@@ -203,7 +206,7 @@ sub do_pre_check {
my @error = ();
my $sub_func_rst = obtain_install_nic(\$installnic, \@error);
if ($sub_func_rst) {
- probe_utils->send_msg("stdout", "f", "Failed to obtain install NIC in current server");
+ probe_utils->send_msg("stdout", "f", "Obtain install NIC in current server");
probe_utils->send_msg("stdout", "d", "$_") foreach (@error);
} else {
probe_utils->send_msg("stdout", "i", "The install NIC in current server is $installnic");
@@ -248,7 +251,7 @@ sub obtain_install_nic {
return 1;
}
- $$installnic_ref = `ip addr |grep -B2 $master_ip_in_site|awk -F" " '/mtu/{gsub(/:/,"",\$2); print \$2}'`;
+ $$installnic_ref = `ip -4 -o a|awk -F"\\\\" '/$master_ip_in_site/ {print \$1}' |awk -F" " '{print \$NF}'`;
chomp($$installnic_ref);
if (!$$installnic_ref) {
push @$return_error_ref, "The value of 'master' in 'site' table is $master_ip_in_site, can't get corresponding network interface in current server";
diff --git a/xCAT-server/lib/perl/xCAT/Goconserver.pm b/xCAT-server/lib/perl/xCAT/Goconserver.pm
new file mode 100644
index 000000000..f1b5cc0a0
--- /dev/null
+++ b/xCAT-server/lib/perl/xCAT/Goconserver.pm
@@ -0,0 +1,108 @@
+#!/usr/bin/perl
+## IBM(c) 2107 EPL license http://www.eclipse.org/legal/epl-v10.html
+
+package xCAT::Goconserver;
+
+BEGIN
+{
+ $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
+}
+use lib "$::XCATROOT/lib/perl";
+use strict;
+use warnings "all";
+
+use HTTP::Request;
+use HTTP::Headers;
+use LWP;
+use JSON;
+use IO::Socket::SSL qw( SSL_VERIFY_PEER );
+
+sub http_request {
+ my ($method, $url, $data) = @_;
+ my @user = getpwuid($>);
+ my $homedir = $user[7];
+ my $rsp;
+ my $brower = LWP::UserAgent->new( ssl_opts => {
+ SSL_key_file => xCAT::Utils->getHomeDir() . "/.xcat/client-cred.pem",
+ SSL_cert_file => xCAT::Utils->getHomeDir() . "/.xcat/client-cred.pem",
+ SSL_ca_file => xCAT::Utils->getHomeDir() . "/.xcat/ca.pem",
+ SSL_use_cert => 1,
+ SSL_verify_mode => SSL_VERIFY_PEER, }, );
+ my $header = HTTP::Headers->new('Content-Type' => 'application/json');
+ # $data = encode_json $data if defined($data);
+ $data = JSON->new->encode($data) if defined($data);
+ my $request = HTTP::Request->new( $method, $url, $header, $data );
+ my $response = $brower->request($request);
+ if (!$response->is_success()) {
+ xCAT::MsgUtils->message("S", "Failed to send request to $url, rc=".$response->status_line());
+ return undef;
+ }
+ my $content = $response->content();
+ if ($content) {
+ return decode_json $content;
+ }
+ return "";
+}
+
+sub delete_nodes {
+ my ($api_url, $node_map, $delmode, $callback) = @_;
+ my $url = "$api_url/bulk/nodes";
+ my @a = ();
+ my ($data, $rsp, $ret);
+ $data->{nodes} = \@a;
+ foreach my $node (keys %{$node_map}) {
+ my $temp;
+ $temp->{name} = $node;
+ push @a, $temp;
+ }
+ $ret = 0;
+ my $response = http_request("DELETE", $url, $data);
+ if (!defined($response)) {
+ $rsp->{data}->[0] = "Failed to send delete request.";
+ xCAT::MsgUtils->message("E", $rsp, $callback);
+ return 1;
+ } elsif ($delmode) {
+ while (my ($k, $v) = each %{$response}) {
+ if ($v ne "Deleted") {
+ $rsp->{data}->[0] = "$k: Failed to delete entry in goconserver: $v";
+ xCAT::MsgUtils->message("E", $rsp, $callback);
+ $ret = 1;
+ } else {
+ $rsp->{data}->[0] = "$k: $v";
+ xCAT::MsgUtils->message("I", $rsp, $callback);
+ }
+ }
+ }
+ return $ret;
+}
+
+sub create_nodes {
+ my ($api_url, $node_map, $callback) = @_;
+ my $url = "$api_url/bulk/nodes";
+ my ($data, $rsp, @a, $ret);
+ $data->{nodes} = \@a;
+ while (my ($k, $v) = each %{$node_map}) {
+ push @a, $v;
+ }
+ $ret = 0;
+ my $response = http_request("POST", $url, $data);
+ if (!defined($response)) {
+ $rsp->{data}->[0] = "Failed to send create request.";
+ xCAT::MsgUtils->message("E", $rsp, $callback);
+ return 1;
+ } elsif ($response) {
+ while (my ($k, $v) = each %{$response}) {
+ if ($v ne "Created") {
+ $rsp->{data}->[0] = "$k: Failed to create console entry in goconserver: $v";
+ xCAT::MsgUtils->message("E", $rsp, $::callback);
+ $ret = 1;
+ } else {
+ $rsp->{data}->[0] = "$k: $v";
+ xCAT::MsgUtils->message("I", $rsp, $::callback);
+ }
+ }
+ }
+ return $ret;
+}
+
+1;
\ No newline at end of file
diff --git a/xCAT-server/lib/perl/xCAT/Postage.pm b/xCAT-server/lib/perl/xCAT/Postage.pm
index ffcc0ba8d..d0ef0f3ab 100644
--- a/xCAT-server/lib/perl/xCAT/Postage.pm
+++ b/xCAT-server/lib/perl/xCAT/Postage.pm
@@ -413,8 +413,29 @@ sub makescript {
$noderesent = $::GLOBAL_TAB_HASH{noderes}{$node};
}
+ unless ($master) {
+ #the ip address of the mn facing the compute node
+ my @ipfnd = xCAT::NetworkUtils->my_ip_facing($node);
+ my $ipfndscalar = @ipfnd;
+ unless ($ipfnd[0]) {
+ $master = $ipfnd[1];
+ if ($ipfndscalar > 2) {
+ foreach my $ipinfnd (@ipfnd) {
+ if ($::XCATSITEVALS{master} and $ipinfnd eq $::XCATSITEVALS{master}) {
+ $master = $ipinfnd;
+ last;
+ }
+ }
+ }
+ if ($master) {
+ $::GLOBAL_TAB_HASH{noderes}{$node}{xcatmaster} = $master;
+ }
+ }
+ }
+
if (!defined($master)) {
$::GLOBAL_TAB_HASH{noderes}{$node}{xcatmaster} = $::XCATSITEVALS{master};
+ $master = $::XCATSITEVALS{master};
}
#get the node type, service node or compute node
@@ -1535,10 +1556,22 @@ sub collect_all_attribs_for_tables_in_template
$::GLOBAL_TAB_HASH{noderes}{$node}{xcatmaster} eq ""))
{
my $value = undef;
- my @valued = xCAT::NetworkUtils->my_ip_facing($node);
- unless ($valued[0]) { $value = $valued[1]; }
-
- $::GLOBAL_TAB_HASH{$tabname}{$node}{$attrib} = $value;
+ my @ipfnd = xCAT::NetworkUtils->my_ip_facing($node);
+ my $ipfndscalar = @ipfnd;
+ unless ($ipfnd[0]) {
+ $value = $ipfnd[1];
+ if ($ipfndscalar > 2) {
+ foreach my $ipinfnd (@ipfnd) {
+ if ($::XCATSITEVALS{master} and $ipinfnd eq $::XCATSITEVALS{master}) {
+ $value = $ipinfnd;
+ last;
+ }
+ }
+ }
+ }
+ if ($value) {
+ $::GLOBAL_TAB_HASH{$tabname}{$node}{$attrib} = $value;
+ }
}
# for nodetype.os and nodetype.arch
diff --git a/xCAT-server/lib/perl/xCAT/xcatd.pm b/xCAT-server/lib/perl/xCAT/xcatd.pm
index 5e60e5ebb..721d31972 100644
--- a/xCAT-server/lib/perl/xCAT/xcatd.pm
+++ b/xCAT-server/lib/perl/xCAT/xcatd.pm
@@ -192,7 +192,7 @@ sub validate {
$status = "Denied";
$rc = 0;
}
- if (($request->{command}->[0] ne "getdestiny") && ($request->{command}->[0] ne "getbladecons") && ($request->{command}->[0] ne "getipmicons")) {
+ if (($request->{command}->[0] ne "getdestiny") && ($request->{command}->[0] ne "getbladecons") && ($request->{command}->[0] ne "getipmicons") && ($request->{command}->[0] ne "getopenbmccons")) {
# set username authenticated to run command
# if from Trusted host, use input username, else set from creds
diff --git a/xCAT-server/lib/xcat/monitoring/monitorctrl.pm b/xCAT-server/lib/xcat/monitoring/monitorctrl.pm
index 8d278aeaa..12adfc9e7 100644
--- a/xCAT-server/lib/xcat/monitoring/monitorctrl.pm
+++ b/xCAT-server/lib/xcat/monitoring/monitorctrl.pm
@@ -704,9 +704,7 @@ sub setNodeStatusAttributes {
$updates{'status'} = $_;
$updates{'statustime'} = $currtime;
my $nodestate = "@$nodes status: $updates{'status'} statustime: $updates{'statustime'}";
- openlog('xcat', 'ndelay', 'local4');
- syslog('local4|info', '%s', $nodestate);
- closelog();
+ xCAT::MsgUtils->message('S', "$nodestate");
my $where_clause;
my $dbname = xCAT::Utils->get_DBName();
diff --git a/xCAT-server/lib/xcat/plugins/AAsn.pm b/xCAT-server/lib/xcat/plugins/AAsn.pm
index 40b90d15a..4bef1e5e0 100755
--- a/xCAT-server/lib/xcat/plugins/AAsn.pm
+++ b/xCAT-server/lib/xcat/plugins/AAsn.pm
@@ -488,8 +488,14 @@ sub setup_CONS
{
my ($nodename) = @_;
my $rc = 0;
-
- my $cmd;
+ 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;
+ }
+ }
my $cmdref;
$cmdref->{command}->[0] = "makeconservercf";
$cmdref->{arg}->[0] = "-l";
diff --git a/xCAT-server/lib/xcat/plugins/DBobjectdefs.pm b/xCAT-server/lib/xcat/plugins/DBobjectdefs.pm
index 416251f44..0ca5df5c5 100755
--- a/xCAT-server/lib/xcat/plugins/DBobjectdefs.pm
+++ b/xCAT-server/lib/xcat/plugins/DBobjectdefs.pm
@@ -4417,6 +4417,12 @@ sub defrm
node => [@allnodes],
arg => ['offline'],
}, $doreq, 0 ,1);
+
+ # Run makeconservercf -d
+ @output = xCAT::Utils->runxcmd({
+ command => ['makeconservercf'],
+ node => [@allnodes],
+ arg => ['-d'],}, $doreq, 0, 1);
}
}
diff --git a/xCAT-server/lib/xcat/plugins/anaconda.pm b/xCAT-server/lib/xcat/plugins/anaconda.pm
index e6f759104..1a1d4088c 100644
--- a/xCAT-server/lib/xcat/plugins/anaconda.pm
+++ b/xCAT-server/lib/xcat/plugins/anaconda.pm
@@ -549,17 +549,39 @@ sub mknetboot
$xcatmaster = '!myipfn!'; #allow service nodes to dynamically nominate themselves as a good contact point, this is of limited use in the event that xcat is not the dhcp/tftp server
}
- if ($ient and $ient->{tftpserver} and $ient->{tftpserver} ne '') {
+ if ($ient and $ient->{nfsserver} and $ient->{nfsserver} ne '') {
+ $imgsrv = $ient->{nfsserver};
+ }elsif ($ient and $ient->{tftpserver} and $ient->{tftpserver} ne '') {
$imgsrv = $ient->{tftpserver};
} else {
- $ient = $reshash->{$node}->[0];
$imgsrv = $xcatmaster;
}
+
unless ($imgsrv) {
xCAT::MsgUtils->report_node_error($callback, $node, "Unable to determine or reasonably guess the image server for $node");
next;
}
+ my $imgsrvip;
+ unless($imgsrv eq '!myipfn!' or xCAT::NetworkUtils->validate_ip($imgsrv)==0){
+ # if imgsrv is hostname, convert it to ip address
+ # the host name might not be resolved inside initrd
+ $imgsrvip = xCAT::NetworkUtils->getipaddr($imgsrv);
+ }
+ unless($imgsrvip){
+ $imgsrvip=$imgsrv;
+ }
+
+ my $xcatmasterip;
+ if (xCAT::NetworkUtils->validate_ip($xcatmaster)) {
+ # if xcatmaster is hostname, convert it to ip address
+ # the host name might not be resolved inside initrd
+ $xcatmasterip = xCAT::NetworkUtils->getipaddr($xcatmaster);
+ }
+ unless($xcatmasterip){
+ $xcatmasterip=$xcatmaster
+ }
+
# Start to build kcmdline
my $kcmdline;
@@ -570,11 +592,8 @@ sub mknetboot
# get entry for nfs root if it exists:
# have to get nfssvr and nfsdir from noderes table
- my $nfssrv = $imgsrv;
+ my $nfssrv = $imgsrvip;
my $nfsdir = $rootimgdir;
- if ($ient->{nfsserver}) {
- $nfssrv = $ient->{nfsserver};
- }
if ($ient->{nfsdir} ne '') {
$nfsdir = $ient->{nfsdir} . "/netboot/$osver/$arch/$profile";
@@ -597,9 +616,9 @@ sub mknetboot
}
} else {
if (-r "$rootimgdir/rootimg-statelite.gz.metainfo") {
- $kcmdline = "imgurl=$httpmethod://$imgsrv:$httpport/$rootimgdir/rootimg-statelite.gz.metainfo STATEMNT=";
+ $kcmdline = "imgurl=$httpmethod://$imgsrvip:$httpport/$rootimgdir/rootimg-statelite.gz.metainfo STATEMNT=";
} else {
- $kcmdline = "imgurl=$httpmethod://$imgsrv:$httpport/$rootimgdir/rootimg-statelite.gz STATEMNT=";
+ $kcmdline = "imgurl=$httpmethod://$imgsrvip:$httpport/$rootimgdir/rootimg-statelite.gz STATEMNT=";
}
}
@@ -626,21 +645,6 @@ sub mknetboot
}
}
$kcmdline .= $statemnt . " ";
- my $xcatmasterip;
-
- # if xcatmaster is hostname, convert it to ip address
- if (xCAT::NetworkUtils->validate_ip($xcatmaster)) {
-
- # Using XCAT= will cause problems rc.statelite.ppc.redhat
- # when trying to run chroot command
- $xcatmasterip = xCAT::NetworkUtils->getipaddr($xcatmaster);
- if (!$xcatmasterip)
- {
- $xcatmasterip = $xcatmaster;
- }
- } else {
- $xcatmasterip = $xcatmaster;
- }
$kcmdline .= "XCAT=$xcatmasterip:$xcatdport ";
@@ -669,11 +673,11 @@ sub mknetboot
}
else {
if (-r "$rootimgdir/$compressedrootimg.metainfo") {
- $kcmdline = "imgurl=$httpmethod://$imgsrv:$httpport/$rootimgdir/$compressedrootimg.metainfo ";
+ $kcmdline = "imgurl=$httpmethod://$imgsrvip:$httpport/$rootimgdir/$compressedrootimg.metainfo ";
} else {
- $kcmdline = "imgurl=$httpmethod://$imgsrv:$httpport/$rootimgdir/$compressedrootimg ";
+ $kcmdline = "imgurl=$httpmethod://$imgsrvip:$httpport/$rootimgdir/$compressedrootimg ";
}
- $kcmdline .= "XCAT=$xcatmaster:$xcatdport ";
+ $kcmdline .= "XCAT=$xcatmasterip:$xcatdport ";
$kcmdline .= "NODE=$node ";
# add flow control setting
@@ -686,23 +690,10 @@ sub mknetboot
}
if (($::XCATSITEVALS{xcatdebugmode} eq "1") or ($::XCATSITEVALS{xcatdebugmode} eq "2")) {
-
- my ($host, $ipaddr) = xCAT::NetworkUtils->gethostnameandip($xcatmaster);
- if ($ipaddr) {
-
- #for use in postscript and postbootscript in xcatdsklspost in the rootimg
- $kcmdline .= " LOGSERVER=$ipaddr ";
-
- #for use in syslog dracut module in the initrd
- $kcmdline .= " syslog.server=$ipaddr syslog.type=rsyslogd syslog.filter=*.* ";
- }
- else {
- #for use in postscript and postbootscript in xcatdsklspost in the rootimg
- $kcmdline .= " LOGSERVER=$xcatmaster ";
-
- #for use in syslog dracut module in the initrd
- $kcmdline .= " syslog.server=$xcatmaster syslog.type=rsyslogd syslog.filter=*.* ";
- }
+ #for use in postscript and postbootscript in xcatdsklspost in the rootimg
+ $kcmdline .= " LOGSERVER=$xcatmasterip ";
+ #for use in syslog dracut module in the initrd
+ $kcmdline .= " syslog.server=$xcatmasterip syslog.type=rsyslogd syslog.filter=*.* ";
$kcmdline .= " xcatdebugmode=$::XCATSITEVALS{xcatdebugmode} ";
}
diff --git a/xCAT-server/lib/xcat/plugins/blade.pm b/xCAT-server/lib/xcat/plugins/blade.pm
index c202c331b..c621b8f5a 100644
--- a/xCAT-server/lib/xcat/plugins/blade.pm
+++ b/xCAT-server/lib/xcat/plugins/blade.pm
@@ -4579,6 +4579,10 @@ sub process_request {
$req->{noderange} = [$node];
$req->{discoverymethod} = ['blade'];
$doreq->($req);
+ if (defined($req->{error})) {
+ $request->{error}->[0] = '1';
+ $request->{error_msg}->[0] = $req->{error_msg}->[0];
+ }
%{$req} = (); #Clear request. it is done
return 0;
}
diff --git a/xCAT-server/lib/xcat/plugins/bmcdiscover.pm b/xCAT-server/lib/xcat/plugins/bmcdiscover.pm
index 18a6fec22..01f42f45b 100644
--- a/xCAT-server/lib/xcat/plugins/bmcdiscover.pm
+++ b/xCAT-server/lib/xcat/plugins/bmcdiscover.pm
@@ -50,6 +50,8 @@ my $openbmc_pass;
$::P9_WITHERSPOON_MFG_ID = "42817";
$::P9_WITHERSPOON_PRODUCT_ID = "16975";
+my %node_in_list = ();
+
#-------------------------------------------------------
=head3 handled_commands
@@ -106,6 +108,14 @@ sub preprocess_request {
push @requests, $reqcopy;
}
return \@requests;
+ } elsif (grep /--check/, @ARGV) {
+ $callback->({ error => ["The option '--check' is not supported"], errorcode=>[1]});
+ $request = ();
+ return;
+ } elsif (grep /--ipsource/, @ARGV) {
+ $callback->({ error => ["The option '--ipsource' is not supported"], errorcode=>[1]});
+ $request = ();
+ return;
} else {
return [$request];
}
@@ -186,12 +196,6 @@ sub bmcdiscovery_usage {
push @{ $rsp->{data} }, "\tbmcdiscover [-v|--version]";
push @{ $rsp->{data} }, "\tbmcdiscover [--sn ] [-s scan_method] [-u bmc_user] [-p bmc_passwd] [-z] [-w] --range ip_range\n";
- push @{ $rsp->{data} }, "\tCheck BMC administrator User/Password:\n";
- push @{ $rsp->{data} }, "\t\tbmcdiscover -u bmc_user -p bmc_password -i bmc_ip --check\n";
-
- push @{ $rsp->{data} }, "\tDisplay the BMC IP configuration:\n";
- push @{ $rsp->{data} }, "\t\tbmcdiscover [-u bmc_user] [-p bmc_passwd] -i bmc_ip --ipsource";
-
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
return 0;
}
@@ -619,6 +623,17 @@ sub scan_process {
$ipmac{$_} = $new_mac;
}
+ my $nodelisttab;
+ if ($nodelisttab = xCAT::Table->new("nodelist")) {
+ my @nodes_in_list = $nodelisttab->getAllAttribs("node");
+ foreach my $node (@nodes_in_list) {
+ $node_in_list{$node->{node}} = 1;
+ }
+ } else {
+ xCAT::MsgUtils->message("E", " Could not read the nodelist table\n");
+ return 1;
+ }
+
###############################
# Set the signal handler for ^c
###############################
@@ -677,17 +692,14 @@ sub scan_process {
my @mc_cmds = ("/opt/xcat/bin/ipmitool-xcat -I lanplus -H ${$live_ip}[$i] -P $openbmc_pass mc info -N 1 -R 1",
"/opt/xcat/bin/ipmitool-xcat -I lanplus -H ${$live_ip}[$i] $bmcusername $bmcpassword mc info -N 1 -R 1");
my $mc_info;
- my $flag;
foreach my $mc_cmd (@mc_cmds) {
$mc_info = xCAT::Utils->runcmd($mc_cmd, -1);
if ($mc_info =~ /Manufacturer ID\s*:\s*(\d+)\s*Manufacturer Name.+\s*Product ID\s*:\s*(\d+)/) {
if ($1 eq $::P9_WITHERSPOON_MFG_ID and $2 eq $::P9_WITHERSPOON_PRODUCT_ID) {
bmcdiscovery_openbmc(${$live_ip}[$i], $opz, $opw, $request_command);
- $flag = 1;
last;
} else {
bmcdiscovery_ipmi(${$live_ip}[$i], $opz, $opw, $request_command);
- $flag = 1;
last;
}
}
@@ -1009,7 +1021,6 @@ sub bmcdiscovery_ipmi {
my $opz = shift;
my $opw = shift;
my $request_command = shift;
- my $node = sprintf("node-%08x", unpack("N*", inet_aton($ip)));
my $bmcstr = "BMC Session ID";
my $bmcusername = '';
my $bmcpassword = '';
@@ -1020,6 +1031,9 @@ sub bmcdiscovery_ipmi {
$bmcpassword = "-P $bmc_pass";
}
+ my $mtms_node = "";
+ my $mac_node = "";
+
my $node_data = $ip;
my $icmd = "/opt/xcat/bin/ipmitool-xcat -vv -I lanplus $bmcusername $bmcpassword -H $ip chassis status ";
my $output = xCAT::Utils->runcmd("$icmd", -1);
@@ -1086,11 +1100,12 @@ sub bmcdiscovery_ipmi {
}
$node_data .= ",mp,bmc,$::opt_SN,$::opt_SN";
if ($mtm and $serial) {
- $node = "node-$mtm-$serial";
- $node =~ s/(.*)/\L$1/g;
- $node =~ s/[\s:\._]/-/g;
- } else {
- $node = "node-$ipmac{$ip}";
+ $mtms_node = "node-$mtm-$serial";
+ $mtms_node =~ s/(.*)/\L$1/g;
+ $mtms_node =~ s/[\s:\._]/-/g;
+ }
+ if ($ipmac{$ip}) {
+ $mac_node = "node-$ipmac{$ip}";
}
} elsif ($output =~ /error : unauthorized name/) {
xCAT::MsgUtils->message("W", { data => ["BMC username is incorrect for $ip"] }, $::CALLBACK);
@@ -1100,7 +1115,7 @@ sub bmcdiscovery_ipmi {
return;
}
- display_output($opz,$opw,$node,$node_data,"ipmi",$request_command);
+ display_output($opz,$opw,$mtms_node,$mac_node,$node_data,"ipmi",$request_command);
}
}
@@ -1121,7 +1136,8 @@ sub bmcdiscovery_openbmc{
my $opz = shift;
my $opw = shift;
my $request_command = shift;
- my $node = sprintf("node-%08x", unpack("N*", inet_aton($ip)));
+ my $mtms_node = "";
+ my $mac_node = "";
print "$ip: Detected openbmc, attempting to obtain system information...\n";
my $http_protocol="https";
@@ -1197,21 +1213,22 @@ sub bmcdiscovery_openbmc{
}
$node_data .= ",mp,bmc,$::opt_SN,$::opt_SN";
if ($mtm and $serial) {
- $node = "node-$mtm-$serial";
- $node =~ s/(.*)/\L$1/g;
- $node =~ s/[\s:\._]/-/g;
- } else {
- $node = "node-$ipmac{$ip}";
+ $mtms_node = "node-$mtm-$serial";
+ $mtms_node =~ s/(.*)/\L$1/g;
+ $mtms_node =~ s/[\s:\._]/-/g;
+ }
+ if ($ipmac{$ip}) {
+ $mac_node = "node-$ipmac{$ip}";
}
} else {
if ($login_response->status_line =~ /401 Unauthorized/) {
xCAT::MsgUtils->message("W", { data => ["Invalid username or password for $ip"] }, $::CALLBACK);
} else {
- xCAT::MsgUtils->message("W", { data => ["$login_response->status_line for $ip"] }, $::CALLBACK);
+ xCAT::MsgUtils->message("W", { data => ["Received response " . $login_response->status_line . " for $ip"] }, $::CALLBACK);
}
return;
}
- display_output($opz,$opw,$node,$node_data,"openbmc",$request_command);
+ display_output($opz,$opw,$mtms_node,$mac_node,$node_data,"openbmc",$request_command);
}
@@ -1227,11 +1244,19 @@ sub bmcdiscovery_openbmc{
sub display_output {
my $opz = shift;
my $opw = shift;
- my $node = shift;
+ my $mtms_node = shift;
+ my $mac_node = shift;
my $node_data = shift;
my $mgttype = shift;
my $request_command = shift;
+ my $node;
+ if (($node_in_list{$mac_node} and !$node_in_list{$mtms_node}) or (!$node_in_list{$mac_node} and !$mtms_node)) {
+ $node = $mac_node;
+ } else {
+ $node = $mtms_node;
+ }
+
if (defined($opw)) {
my $rsp = {};
push @{ $rsp->{data} }, "Writing $node ($node_data) to database...";
diff --git a/xCAT-server/lib/xcat/plugins/conserver.pm b/xCAT-server/lib/xcat/plugins/conserver.pm
index 11c3f9b90..d54cbe10d 100644
--- a/xCAT-server/lib/xcat/plugins/conserver.pm
+++ b/xCAT-server/lib/xcat/plugins/conserver.pm
@@ -8,6 +8,7 @@ use xCAT::TableUtils;
use Getopt::Long;
use Sys::Hostname;
use xCAT::SvrUtils;
+use xCAT::Scope;
use strict;
use Data::Dumper;
@@ -28,6 +29,7 @@ my $usage_string =
The default goes down to all the conservers on
the server nodes and set them up
-d|--delete Conserver has the relevant entries for the given noderange removed immediately from configuration
+ -C|--cleanup To remove the entries for the nodes that do not exist in xCAT db
-t|--trust Add additional trusted hosts.
-h|--help Display this usage statement.
-V|--verbose Verbose mode.
@@ -71,6 +73,7 @@ sub preprocess_request {
'l|local' => \$::LOCAL,
'h|help' => \$::HELP,
'D|debug' => \$::DEBUG,
+ 'C|cleanup' => \$::CLEANUP,
'v|version' => \$::VERSION,
'V|verbose' => \$::VERBOSE)) {
$request = {};
@@ -98,8 +101,25 @@ sub preprocess_request {
$request = {};
return;
}
-
-
+ if ($::CLEANUP && ($::CONSERVER or $::LOCAL)) {
+ $callback->({ data => "Can not specify -l|--local or -c|--conserver together with -C|--cleanup." });
+ $request = {};
+ return;
+ }
+ # The cleanup shall run on both MN and all SNs
+ if ($::CLEANUP) {
+ if ($noderange && @$noderange > 0) {
+ $callback->({ data => "Can not specify noderange together with -C|--cleanup." });
+ $request = {};
+ return;
+ }
+ my @sns = xCAT::ServiceNodeUtils->getSNList();
+ unless ( @sns > 0 ) {
+ return xCAT::Scope->get_parallel_scope($request);
+ }
+ return xCAT::Scope->get_broadcast_scope_with_parallel($request, \@sns);
+ }
+
# get site master
my $master = xCAT::TableUtils->get_site_Master();
if (!$master) { $master = hostname(); }
@@ -182,6 +202,15 @@ sub process_request {
my $req = shift;
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) {
+ my $rsp->{data}->[0] = "goconserver is started, please stop it at first.";
+ xCAT::MsgUtils->message("E", $rsp, $cb);
+ return;
+ }
+ }
makeconservercf($req, $cb);
}
}
@@ -326,7 +355,8 @@ sub makeconservercf {
#$Getopt::Long::pass_through=1;
my $delmode;
GetOptions('d|delete' => \$delmode,
- 't|trust=s' => \$::TRUSTED_HOST
+ 't|trust=s' => \$::TRUSTED_HOST,
+ 'C|cleanup' => \$::CLEANUP,
);
my $nodes = $req->{node};
my $svboot = 0;
@@ -400,6 +430,18 @@ sub makeconservercf {
#$cb->({node=>[{name=>$node,error=>"Bad configuration, check attributes under the nodehm category",errorcode=>1}]});
xCAT::SvrUtils::sendmsg([ 1, "Bad configuration, check attributes under the nodehm category" ], $cb, $node);
}
+ } elsif ($::CLEANUP) {
+ my $nodelstab = xCAT::Table->new('nodelist');
+ my @allnodeset = $nodelstab->getAllAttribs('node');
+ my %allnodehash = map { $_->{node} => 1 } @allnodeset;
+ my $rmnodes = delete_undefined_nodes_entry(\@filecontent, \%allnodehash);
+ my $rsp;
+ if (!defined($rmnodes)) {
+ $rsp->{data}->[0] = "Nothing removed";
+ } else{
+ $rsp->{data}->[0] = "Remove console entry for the nodes:".join(',', @$rmnodes);
+ }
+ xCAT::MsgUtils->message("I", $rsp, $cb);
} else { #no nodes specified, do em all up
zapcfg(\@filecontent); # strip all xCAT configured nodes from config
@@ -599,6 +641,41 @@ sub donodeent {
}
return 0;
}
+# Remove cons entries for the undefined nodes
+sub delete_undefined_nodes_entry {
+ my $content = shift;
+ my $allnodeshash = shift;
+ my $idx = 0;
+ my $toidx = -1;
+ my $skip = 0;
+ my $skipnext = 0;
+ my @rmnodes = ();
+ while ($idx <= $#$content) {
+ if ($content->[$idx] =~ /^#xCAT BEGIN (\S+) CONS/) {
+ $toidx = $idx;
+ my $node = $1;
+ unless (exists($allnodeshash->{$node})) {
+ $skip = 1;
+ $skipnext = 1;
+ push @rmnodes, $node;
+ print __LINE__."===== push node: $node==\n";
+ }
+ } elsif ($content->[$idx] =~ /^#xCAT END/) {
+ $skipnext = 0;
+ }
+ if ($skip) {
+ splice(@$content, $idx, 1);
+ } else {
+ $idx++;
+ }
+ $skip = $skipnext;
+ }
+ if (scalar(@rmnodes) > 0) {
+ return \@rmnodes;
+ } else {
+ return undef;
+ }
+}
# Delete any xcat added node entries from the file
sub zapcfg {
diff --git a/xCAT-server/lib/xcat/plugins/credentials.pm b/xCAT-server/lib/xcat/plugins/credentials.pm
index 7e128a782..828bc253f 100644
--- a/xCAT-server/lib/xcat/plugins/credentials.pm
+++ b/xCAT-server/lib/xcat/plugins/credentials.pm
@@ -321,6 +321,7 @@ sub process_request
open($tmpfile, $tfilename);
@filecontent = <$tmpfile>;
close($tmpfile);
+ $filecontent[$#filecontent] =~ s/\n?$/\n/;
$retdata = "\n" . join('', @filecontent);
push @{ $rsp->{'data'} }, { content => [$retdata], desc => [$parm] };
$retdata = "";
diff --git a/xCAT-server/lib/xcat/plugins/ddns.pm b/xCAT-server/lib/xcat/plugins/ddns.pm
index 47da7c5bb..b17e3c295 100755
--- a/xCAT-server/lib/xcat/plugins/ddns.pm
+++ b/xCAT-server/lib/xcat/plugins/ddns.pm
@@ -1223,8 +1223,8 @@ sub update_namedconf {
}
unless ($gotoptions) {
push @newnamed, "options {\n";
+ push @newnamed, "\tdirectory \"" . $ctx->{zonesdir} . "\";\n";
unless ($slave && xCAT::Utils->isLinux()) {
- push @newnamed, "\tdirectory \"" . $ctx->{zonesdir} . "\";\n";
push @newnamed, "\tallow-recursion { any; };\n";
}
@@ -1274,6 +1274,19 @@ sub update_namedconf {
push @newnamed, "};\n\n";
}
+ # include external configuration file(s) if present in site.namedincludes
+ my @entries = xCAT::TableUtils->get_site_attribute("namedincludes");
+ my $site_entry = $entries[0];
+ if (defined($site_entry)) {
+ my @includes = split /[ ,]/, $site_entry;
+ foreach (@includes) {
+ if (defined($_)) {
+ push @newnamed, "include \"$_\";\n";
+ }
+ }
+ push @newnamed, "\n";
+ }
+
unless ($slave) {
unless ($gotkey) {
unless ($ctx->{privkey}) { #need to generate one
diff --git a/xCAT-server/lib/xcat/plugins/debian.pm b/xCAT-server/lib/xcat/plugins/debian.pm
index 72b795efe..eb0281b4e 100644
--- a/xCAT-server/lib/xcat/plugins/debian.pm
+++ b/xCAT-server/lib/xcat/plugins/debian.pm
@@ -1267,44 +1267,24 @@ sub mknetboot
my $xcatmaster;
$ient = $reshash->{$node}->[0]; #$restab->getNodeAttribs($node, ['tftpserver']);
-
- if ($ient and $ient->{xcatmaster})
- {
+ if ($ient and $ient->{xcatmaster}) {
$xcatmaster = $ient->{xcatmaster};
} else {
$xcatmaster = '!myipfn!'; #allow service nodes to dynamically nominate themselves as a good contact point, this is of limited use in the event that xcat is not the dhcp/tftp server
}
- if ($ient and $ient->{tftpserver})
- {
+ if ($ient and $ient->{nfsserver} and $ient->{nfsserver} ne '') {
+ $imgsrv = $ient->{nfsserver};
+ }elsif ($ient and $ient->{tftpserver} and $ient->{tftpserver} ne '') {
$imgsrv = $ient->{tftpserver};
- }
- else
- {
- $ient = $reshash->{$node}->[0]; #$restab->getNodeAttribs($node, ['xcatmaster']);
- #if ($ient and $ient->{xcatmaster})
- #{
- # $imgsrv = $ient->{xcatmaster};
- #}
- #else
- #{
- # master not correct for service node pools
- #$ient = $sitetab->getAttribs({key => master}, value);
- #if ($ient and $ient->{value})
- #{
- # $imgsrv = $ient->{value};
- #}
- #else
- #{
- # $imgsrv = '!myipfn!';
- #}
- #}
+ } else {
$imgsrv = $xcatmaster;
}
unless ($imgsrv) {
xCAT::MsgUtils->report_node_error($callback, $node, "Unable to determine or reasonably guess the image server for $node");
next;
}
+
my $kcmdline;
if ($statelite) {
if (rootfstype ne "ramdisk") {
@@ -1313,9 +1293,6 @@ sub mknetboot
# have to get nfssvr and nfsdir from noderes table
my $nfssrv = $imgsrv;
my $nfsdir = $rootimgdir;
- if ($ient->{nfsserver}) {
- $nfssrv = $ient->{nfsserver};
- }
if ($ient->{nfsdir} ne '') {
$nfsdir = $ient->{nfsdir} . "/netboot/$osver/$arch/$profile";
diff --git a/xCAT-server/lib/xcat/plugins/dhcp.pm b/xCAT-server/lib/xcat/plugins/dhcp.pm
index 13ce40aa4..c824641be 100644
--- a/xCAT-server/lib/xcat/plugins/dhcp.pm
+++ b/xCAT-server/lib/xcat/plugins/dhcp.pm
@@ -747,6 +747,7 @@ sub addnode
print $omshell "new host\n";
print $omshell "set name = \"$hostname\"\n";
print $omshell "set hardware-address = " . $mac . "\n";
+ print $omshell "set dhcp-client-identifier = " . $mac . "\n";
print $omshell "set hardware-type = $hardwaretype\n";
if ($ip eq "DENIED")
@@ -978,48 +979,6 @@ sub check_options
return 0;
}
- # if not help and not -n, dhcpd needs to be running
- if (!($opt->{h}) && (!($opt->{n}))) {
- if (xCAT::Utils->isLinux()) {
-
- #my $DHCPSERVER="dhcpd";
- #if( -e "/etc/init.d/isc-dhcp-server" ){
- # $DHCPSERVER="isc-dhcp-server";
- #}
-
- #my @output = xCAT::Utils->runcmd("service $DHCPSERVER status", -1);
- #if ($::RUNCMD_RC != 0) { # not running
- my $ret = 0;
- $ret = xCAT::Utils->checkservicestatus("dhcp");
- if ($ret != 0)
- {
- my $rsp = {};
- $rsp->{data}->[0] = "dhcp server is not running. please start the dhcp server.";
- xCAT::MsgUtils->message("E", $rsp, $callback, 1);
- return 1;
- }
- } else { # AIX
- my @output = xCAT::Utils->runcmd("lssrc -s dhcpsd ", -1);
- if ($::RUNCMD_RC != 0) { # not running
- my $rsp = {};
- $rsp->{data}->[0] = "dhcpsd is not running. Run startsrc -s dhcpsd and rerun your command.";
- xCAT::MsgUtils->message("E", $rsp, $callback, 1);
- return 1;
- } else { # check the status
- # the return output varies, sometime status is the third sometimes the 4th col
- if (grep /inoperative/, @output)
- {
- my $rsp = {};
- $rsp->{data}->[0] = "dhcpsd is not running. Run startsrc -s dhcpsd and rerun your command.";
- xCAT::MsgUtils->message("E", $rsp, $callback, 1);
- return 1;
-
- }
- }
- }
- }
-
-
# check to see if -q is listed with any other options which is not allowed
if ($opt->{q} and ($opt->{a} || $opt->{d} || $opt->{n} || $opt->{r} || $opt->{l} || $statements)) {
my $rsp = {};
@@ -1132,9 +1091,11 @@ sub preprocess_request
xCAT::MsgUtils->trace($verbose_on_off, "d", "dhcp: dhcp server on $_->{net}: $_->{dhcpserver}");
}
}
+ } elsif ($snonly == 1) {
+ $snonly = 0;
+ xCAT::MsgUtils->trace($verbose_on_off, "d", "dhcp: disjointdhcps mode is disabled as no service nodes are running dhcp service.");
}
-
my @nodes = ();
# if the new option is not specified
@@ -1381,17 +1342,6 @@ sub process_request
return [];
}
-
- # if option is query then call listnode for each node and return
- if ($opt{q})
- {
- # call listnode for each node requested
- foreach my $node (@{ $req->{node} }) {
- listnode($node, $callback);
- }
- return;
- }
-
# if current node is a servicenode, make sure that it is also a dhcpserver
my $isok = 1;
if (xCAT::Utils->isServiceNode()) {
@@ -1413,6 +1363,57 @@ sub process_request
return;
}
+ # if not -n, dhcpd needs to be running
+ if (!($opt{n})) {
+ if (xCAT::Utils->isLinux()) {
+
+ #my $DHCPSERVER="dhcpd";
+ #if( -e "/etc/init.d/isc-dhcp-server" ){
+ # $DHCPSERVER="isc-dhcp-server";
+ #}
+
+ #my @output = xCAT::Utils->runcmd("service $DHCPSERVER status", -1);
+ #if ($::RUNCMD_RC != 0) { # not running
+ my $ret = 0;
+ $ret = xCAT::Utils->checkservicestatus("dhcp");
+ if ($ret != 0)
+ {
+ my $rsp = {};
+ $rsp->{data}->[0] = "dhcp server is not running. please start the dhcp server.";
+ xCAT::MsgUtils->message("E", $rsp, $callback, 1);
+ return;
+ }
+ } else { # AIX
+ my @output = xCAT::Utils->runcmd("lssrc -s dhcpsd ", -1);
+ if ($::RUNCMD_RC != 0) { # not running
+ my $rsp = {};
+ $rsp->{data}->[0] = "dhcpsd is not running. Run startsrc -s dhcpsd and rerun your command.";
+ xCAT::MsgUtils->message("E", $rsp, $callback, 1);
+ return;
+ } else { # check the status
+ # the return output varies, sometime status is the third sometimes the 4th col
+ if (grep /inoperative/, @output)
+ {
+ my $rsp = {};
+ $rsp->{data}->[0] = "dhcpsd is not running. Run startsrc -s dhcpsd and rerun your command.";
+ xCAT::MsgUtils->message("E", $rsp, $callback, 1);
+ return;
+
+ }
+ }
+ }
+ }
+
+ # if option is query then call listnode for each node and return
+ if ($opt{q})
+ {
+ # call listnode for each node requested
+ foreach my $node (@{ $req->{node} }) {
+ listnode($node, $callback);
+ }
+ return;
+ }
+
my $servicenodetab = xCAT::Table->new('servicenode');
my @nodeinfo = xCAT::NetworkUtils->determinehostname;
my $nodename = pop @nodeinfo; # get hostname
diff --git a/xCAT-server/lib/xcat/plugins/goconserver.pm b/xCAT-server/lib/xcat/plugins/goconserver.pm
new file mode 100644
index 000000000..0fcf0d141
--- /dev/null
+++ b/xCAT-server/lib/xcat/plugins/goconserver.pm
@@ -0,0 +1,422 @@
+# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
+#TODO: delete entries not being refreshed if no noderange
+package xCAT_plugin::goconserver;
+BEGIN {
+ $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
+}
+use lib "$::XCATROOT/lib/perl";
+use strict;
+use xCAT::Table;
+use xCAT::Utils;
+use xCAT::TableUtils;
+use Getopt::Long;
+use Sys::Hostname;
+use xCAT::SvrUtils;
+use xCAT::Goconserver;
+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.
+ -v|--version Display the version number.";
+
+my $version_string = xCAT::Utils->Version();
+
+sub handled_commands {
+ return {
+ makegocons => "goconserver"
+ }
+}
+
+sub preprocess_request {
+ my $request = shift;
+ if ($request->{_xcatpreprocessed}->[0] == 1) { return [$request]; }
+ $::callback = shift;
+ my @requests;
+ my $noderange = $request->{node}; #Should be arrayref
+
+ #display usage statement if -h
+ my $extrargs = $request->{arg};
+ my @exargs = ($request->{arg});
+ if (ref($extrargs)) {
+ @exargs = @$extrargs;
+ }
+ @ARGV = @exargs;
+
+ $isSN = xCAT::Utils->isServiceNode();
+ my @hostinfo = xCAT::NetworkUtils->determinehostname();
+ my %iphash = ();
+ foreach (@hostinfo) { $iphash{$_} = 1; }
+
+ $Getopt::Long::ignorecase = 0;
+
+ #$Getopt::Long::pass_through=1;
+ if (!GetOptions(
+ 'c|conserver' => \$::CONSERVER,
+ 'l|local' => \$::LOCAL,
+ 'h|help' => \$::HELP,
+ 'D|debug' => \$::DEBUG,
+ 'v|version' => \$::VERSION,
+ 'V|verbose' => \$::VERBOSE)) {
+ $request = {};
+ return;
+ }
+ if ($::HELP) {
+ $::callback->({ data => $usage_string });
+ $request = {};
+ return;
+ }
+ if ($::VERSION) {
+ $::callback->({ data => $version_string });
+ $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();
+ if (!$master) { $master = hostname(); }
+
+ # get conserver for each node
+ my %cons_hash = ();
+ my $hmtab = xCAT::Table->new('nodehm');
+ my @items;
+ my $allnodes = 1;
+ if ($noderange && @$noderange > 0) {
+ $allnodes = 0;
+ my $hmcache = $hmtab->getNodesAttribs($noderange, [ 'node', 'serialport', 'cons', 'conserver' ]);
+ foreach my $node (@$noderange) {
+ my $ent = $hmcache->{$node}->[0]; #$hmtab->getNodeAttribs($node,['node', 'serialport','cons', 'conserver']);
+ push @items, $ent;
+ }
+ } else {
+ $allnodes = 1;
+ @items = $hmtab->getAllNodeAttribs([ 'node', 'serialport', 'cons', 'conserver' ]);
+ }
+
+ my @nodes = ();
+ foreach (@items) {
+ if (((!defined($_->{cons})) || ($_->{cons} eq "")) and !defined($_->{serialport})) {
+ my $rsp->{data}->[0] = $_->{node} .": ignore, cons attribute or serialport attribute is not specified.";
+ xCAT::MsgUtils->message("I", $rsp, $::callback);
+ next;
+ }
+ if (defined($_->{conserver})) { push @{ $cons_hash{ $_->{conserver} }{nodes} }, $_->{node}; }
+ else { push @{ $cons_hash{$master}{nodes} }, $_->{node}; }
+ 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
+ } #end foreach
+
+ if ($::DEBUG) {
+ my $rsp;
+ $rsp->{data}->[0] = "In preprocess_request, request is " . Dumper(@requests);
+ xCAT::MsgUtils->message("I", $rsp, $::callback);
+ }
+ return \@requests;
+}
+
+sub process_request {
+ my $req = shift;
+ $::callback = shift;
+ my @hostinfo = xCAT::NetworkUtils->determinehostname();
+ $host = $hostinfo[-1];
+ $isSN = xCAT::Utils->isServiceNode();
+ if ($req->{command}->[0] eq "makegocons") {
+ makegocons($req, \@hostinfo);
+ }
+}
+
+sub get_cons_map {
+ my ($req, $iphashref) = @_;
+ my %cons_map;
+ my %iphash = %{$iphashref};
+ my $hmtab = xCAT::Table->new('nodehm');
+ my @cons_nodes;
+
+ if (($req->{node} and @{$req->{node}} > 0) or $req->{noderange}->[0]) {
+ # Note: do not consider terminal server currently
+ @cons_nodes = $hmtab->getNodesAttribs($req->{node}, [ 'node', 'cons', 'serialport', 'mgt', 'conserver', 'consoleondemand' ]);
+ # Adjust the data structure to make the result consistent with the getAllNodeAttribs() call we make if a noderange was not specified
+ my @tmpcons_nodes;
+ foreach my $ent (@cons_nodes)
+ {
+ foreach my $nodeent (keys %$ent)
+ {
+ push @tmpcons_nodes, $ent->{$nodeent}->[0];
+ }
+ }
+ @cons_nodes = @tmpcons_nodes
+
+ } else {
+ @cons_nodes = $hmtab->getAllNodeAttribs([ 'cons', 'serialport', 'mgt', 'conserver', 'consoleondemand' ]);
+ }
+ $hmtab->close();
+ my $rsp;
+
+ foreach (@cons_nodes) {
+ if ($_->{cons} or defined($_->{'serialport'})) {
+ unless ($_->{cons}) { $_->{cons} = $_->{mgt}; } #populate with fallback
+ if ($isSN && $_->{conserver} && exists($iphash{ $_->{conserver} }) || !$isSN) {
+ $cons_map{ $_->{node} } = $_; # also put the ref to the entry in a hash for quick look up
+ } else {
+ $rsp->{data}->[0] = $_->{node} .": ignore, the host for conserver could not be determined.";
+ xCAT::MsgUtils->message("I", $rsp, $::callback);
+ }
+ } else {
+ $rsp->{data}->[0] = $_->{node} .": ignore, cons attribute or serialport attribute is not specified.";
+ xCAT::MsgUtils->message("I", $rsp, $::callback);
+ }
+ }
+ return %cons_map;
+}
+
+sub gen_request_data {
+ my ($cons_map, $siteondemand) = @_;
+ my (@openbmc_nodes, $data);
+ while (my ($k, $v) = each %{$cons_map}) {
+ my $ondemand;
+ if ($siteondemand) {
+ $ondemand = \1;
+ } else {
+ $ondemand = \0;
+ }
+ my $cmd;
+ my $cmeth = $v->{cons};
+ if ($cmeth eq "openbmc") {
+ push @openbmc_nodes, $k;
+ } else {
+ $cmd = $::XCATROOT . "/share/xcat/cons/$cmeth"." ".$k;
+ if (!(!$isSN && $v->{conserver} && xCAT::NetworkUtils->thishostisnot($v->{conserver}))) {
+ my $env;
+ my $locerror = $isSN ? "PERL_BADLANG=0 " : '';
+ if (defined($ENV{'XCATSSLVER'})) {
+ $env = "XCATSSLVER=$ENV{'XCATSSLVER'} ";
+ }
+ $cmd = $locerror.$env.$cmd;
+ }
+ $data->{$k}->{driver} = "cmd";
+ $data->{$k}->{params}->{cmd} = $cmd;
+ $data->{$k}->{name} = $k;
+ }
+ if (defined($v->{consoleondemand})) {
+ # consoleondemand attribute for node can be "1", "yes", "0" and "no"
+ if (($v->{consoleondemand} eq "1") || lc($v->{consoleondemand}) eq "yes") {
+ $ondemand = \1;
+ }
+ elsif (($v->{consoleondemand} eq "0") || lc($v->{consoleondemand}) eq "no") {
+ $ondemand = \0;
+ }
+ }
+ $data->{$k}->{ondemand} = $ondemand;
+ }
+ if (@openbmc_nodes) {
+ my $passwd_table = xCAT::Table->new('passwd');
+ my $passwd_hash = $passwd_table->getAttribs({ 'key' => 'openbmc' }, qw(username password));
+ $passwd_table->close();
+ my $openbmc_table = xCAT::Table->new('openbmc');
+ my $openbmc_hash = $openbmc_table->getNodesAttribs(\@openbmc_nodes, ['bmc','consport', 'username', 'password']);
+ $openbmc_table->close();
+ foreach my $node (@openbmc_nodes) {
+ if (defined($openbmc_hash->{$node}->[0])) {
+ if (!$openbmc_hash->{$node}->[0]->{'bmc'}) {
+ xCAT::SvrUtils::sendmsg("Error: Unable to get attribute bmc", $::callback, $node);
+ delete $data->{$node};
+ next;
+ }
+ $data->{$node}->{params}->{host} = $openbmc_hash->{$node}->[0]->{'bmc'};
+ if ($openbmc_hash->{$node}->[0]->{'username'}) {
+ $data->{$node}->{params}->{user} = $openbmc_hash->{$node}->[0]->{'username'};
+ } elsif ($passwd_hash and $passwd_hash->{username}) {
+ $data->{$node}->{params}->{user} = $passwd_hash->{username};
+ } else {
+ xCAT::SvrUtils::sendmsg("Error: Unable to get attribute username", $::callback, $node);
+ delete $data->{$node};
+ next;
+ }
+ if ($openbmc_hash->{$node}->[0]->{'password'}) {
+ $data->{$node}->{params}->{password} = $openbmc_hash->{$node}->[0]->{'password'};
+ } elsif ($passwd_hash and $passwd_hash->{password}) {
+ $data->{$node}->{params}->{password} = $passwd_hash->{password};
+ } else {
+ xCAT::SvrUtils::sendmsg("Error: Unable to get attribute password", $::callback, $node);
+ delete $data->{$node};
+ next;
+ }
+ if ($openbmc_hash->{$node}->[0]->{'consport'}) {
+ $data->{$node}->{params}->{consport} = $openbmc_hash->{$node}->[0]->{'consport'};
+ } else {
+ $data->{$node}->{params}->{port} = $bmc_cons_port;
+ }
+ $data->{$node}->{name} = $node;
+ $data->{$node}->{driver} = "ssh";
+ }
+ }
+ }
+ return $data;
+}
+
+
+sub start_goconserver {
+ my $rsp;
+ 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) {
+ $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);
+ }
+ return 0;
+}
+
+sub makegocons {
+ my $req = shift;
+ my $hostinfo = shift;
+ my $extrargs = $req->{arg};
+ my @exargs = ($req->{arg});
+ if (ref($extrargs)) {
+ @exargs = @$extrargs;
+ }
+ @ARGV = @exargs;
+ $Getopt::Long::ignorecase = 0;
+ my $delmode;
+ GetOptions('d|delete' => \$delmode,
+ );
+
+ my $svboot = 0;
+ if (exists($req->{svboot})) {
+ $svboot = 1;
+ }
+ my %iphash = ();
+ foreach (@$hostinfo) { $iphash{$_} = 1; }
+ my %cons_map = get_cons_map($req, \%iphash);
+ if (! %cons_map) {
+ xCAT::SvrUtils::sendmsg([ 1, "Could not get any console request entry" ], $::callback);
+ return 1;
+ }
+ my $ret = start_goconserver();
+ if ($ret != 0) {
+ return 1;
+ }
+ my @entries = xCAT::TableUtils->get_site_attribute("consoleondemand");
+ my $site_entry = $entries[0];
+ my $siteondemand = 0;
+ if (defined($site_entry)) {
+ if (lc($site_entry) eq "yes") {
+ $siteondemand = 1;
+ }
+ elsif (lc($site_entry) ne "no") {
+ # consoleondemand attribute is set, but it is not "yes" or "no"
+ xCAT::SvrUtils::sendmsg([ 1, "Unexpected value $site_entry for consoleondemand attribute in site table" ], $::callback);
+ }
+ }
+ my (@nodes);
+ my $data = gen_request_data(\%cons_map, $siteondemand);
+ if (! $data) {
+ xCAT::SvrUtils::sendmsg([ 1, "Could not generate the request data" ], $::callback);
+ return 1;
+ }
+ my $api_url = "https://$host:$go_api_port";
+ $ret = xCAT::Goconserver::delete_nodes($api_url, $data, $delmode, $::callback);
+ if ($delmode) {
+ return $ret;
+ }
+ $ret = xCAT::Goconserver::create_nodes($api_url, $data, $::callback);
+ if ($ret != 0) {
+ xCAT::SvrUtils::sendmsg([ 1, "Failed to create console entry in goconserver. "], $::callback);
+ return $ret;
+ }
+ return 0;
+}
+
+1;
\ No newline at end of file
diff --git a/xCAT-server/lib/xcat/plugins/hpblade.pm b/xCAT-server/lib/xcat/plugins/hpblade.pm
index 364627ba7..e3c9f0477 100755
--- a/xCAT-server/lib/xcat/plugins/hpblade.pm
+++ b/xCAT-server/lib/xcat/plugins/hpblade.pm
@@ -771,6 +771,10 @@ sub process_request {
my $req = {%$request};
$req->{command} = ['discovered'];
$req->{noderange} = [ $macmap{$mac} ];
+ if (defined($req->{error})) {
+ $request->{error}->[0] = '1';
+ $request->{error_msg}->[0] = $req->{error_msg}->[0];
+ }
$doreq->($req);
%{$req} = (); #Clear request. it is done
#undef $mactab;
diff --git a/xCAT-server/lib/xcat/plugins/ipmi.pm b/xCAT-server/lib/xcat/plugins/ipmi.pm
index 699112ff9..56db4df57 100644
--- a/xCAT-server/lib/xcat/plugins/ipmi.pm
+++ b/xCAT-server/lib/xcat/plugins/ipmi.pm
@@ -527,7 +527,7 @@ sub on_bmc_connect {
return;
}
if ($command eq "rpower") {
- unless (defined $sessdata->{device_id}) { #need get device id data initted for S3 support
+ unless ($sessdata->{subcommand} eq "reseat" or defined $sessdata->{device_id}) { #need get device id data initted for S3 support
$sessdata->{ipmisession}->subcmd(netfn => 6, command => 1, data => [], callback => \&gotdevid, callback_args => $sessdata);
return;
}
@@ -8993,13 +8993,18 @@ sub donode {
$sessiondata{$node} = {
node => $node, #this seems redundant, but some code will not be privy to what the key was
bmcnum => $bmcnum,
- ipmisession => xCAT::IPMI->new(bmc => $bmcip, userid => $user, password => $pass),
+ #ipmisession => xCAT::IPMI->new(bmc => $bmcip, userid => $user, password => $pass),
command => $command,
extraargs => \@exargs,
subcommand => $exargs[0],
xcatdebugmode => $xcatdebugmode,
outfunc => $callback,
};
+ if ($command eq "rpower" and $exargs[0] eq "reseat") {
+ on_bmc_connect(0, $sessiondata{$node});
+ return 0;
+ }
+ $sessiondata{$node}->{ipmisession} = xCAT::IPMI->new(bmc => $bmcip, userid => $user, password => $pass);
if ($sessiondata{$node}->{ipmisession}->{error}) {
xCAT::SvrUtils::sendmsg([ 1, $sessiondata{$node}->{ipmisession}->{error} ], $callback, $node, %allerrornodes);
} else {
diff --git a/xCAT-server/lib/xcat/plugins/mknb.pm b/xCAT-server/lib/xcat/plugins/mknb.pm
index 5219e3b51..894ccc650 100644
--- a/xCAT-server/lib/xcat/plugins/mknb.pm
+++ b/xCAT-server/lib/xcat/plugins/mknb.pm
@@ -140,7 +140,7 @@ sub process_request {
my $rc;
my $invisibletouch = 0;
if (-e "$::XCATROOT/share/xcat/netboot/genesis/$arch") {
- $rc = system("cp -a $::XCATROOT/share/xcat/netboot/genesis/$arch/fs/* $tempdir");
+ $rc = system("shopt -s dotglob; GLOBIGNORE=\".:..\" cp -a $::XCATROOT/share/xcat/netboot/genesis/$arch/fs/* $tempdir");
$rc = system("cp -a $::XCATROOT/share/xcat/netboot/genesis/$arch/kernel $tftpdir/xcat/genesis.kernel.$arch");
$invisibletouch = 1;
} else {
diff --git a/xCAT-server/lib/xcat/plugins/nodediscover.pm b/xCAT-server/lib/xcat/plugins/nodediscover.pm
index fcc2aa4a4..c357000eb 100644
--- a/xCAT-server/lib/xcat/plugins/nodediscover.pm
+++ b/xCAT-server/lib/xcat/plugins/nodediscover.pm
@@ -182,9 +182,7 @@ sub process_request {
$basicdata->{memory} = $request->{memory}->[0];
}
if ($request->{disksize}->[0]) {
- my @disks = split /\n/, $request->{disksize}->[0];
- my $disk_info = join(",", @disks);
- $basicdata->{disksize} = $disk_info;
+ $basicdata->{disksize} = $request->{disksize}->[0];
}
if ($request->{cpucount}->[0]) {
$basicdata->{cpucount} = $request->{cpucount}->[0];
@@ -267,6 +265,12 @@ sub process_request {
my $macstring = "";
if (defined($request->{mac})) {
+ if (!inet_aton($node)) {
+ xCAT::MsgUtils->message("S", "xcat.discovery.nodediscover: Can not resolve IP for the matching node:$node. Make sure \"makehosts\" and \"makedns\" have been run for $node.");
+ $request->{error} = [0];
+ $request->{error_msg} = ["Can not resolve IP for the matching node:$node."];
+ return;
+ }
my $mactab = xCAT::Table->new("mac", -create => 1);
my @ifinfo;
my %usednames;
@@ -274,6 +278,7 @@ sub process_request {
my @hostnames_to_update = ();
my %bydriverindex;
my $forcenic = 0; #-1 is force skip, 0 is use default behavior, 1 is force to be declared even if hosttag is skipped to do so
+ my $localnic = 0;
foreach (@{ $request->{mac} }) {
@ifinfo = split /\|/;
@@ -320,9 +325,6 @@ sub process_request {
$hosttag = "$node-$ifinfo[1]";
push @hostnames_to_update, $hosttag;
}
- elsif (!inet_aton($node)) {
- xCAT::MsgUtils->message("S", "xcat.discovery.nodediscover: Can not resolve IP for the matching node:$node. Make sure \"makehosts\" and \"makedns\" have been run for $node.");
- }
}
#print Dumper($hosttag) . "\n";
if ($hosttag) {
@@ -332,6 +334,7 @@ sub process_request {
}
if ($hosttag eq $node) {
$macstring .= $currmac . "|";
+ $localnic = 1;
} else {
$macstring .= $currmac . "!" . $hosttag . "|";
}
@@ -349,6 +352,11 @@ sub process_request {
if ($forcenic == 1) { $macstring .= $currmac . "|"; }
}
}
+ unless ($localnic) {
+ $request->{error} = [1];
+ $request->{error_msg} = ["No nic found in deploy network for $node"];
+ return;
+ }
$macstring =~ s/\|\z//;
$mactab->setNodeAttribs($node, { mac => $macstring });
if (scalar @hostnames_to_update) {
diff --git a/xCAT-server/lib/xcat/plugins/openbmc.pm b/xCAT-server/lib/xcat/plugins/openbmc.pm
index 958fc5ba4..695db59d7 100644
--- a/xCAT-server/lib/xcat/plugins/openbmc.pm
+++ b/xCAT-server/lib/xcat/plugins/openbmc.pm
@@ -18,6 +18,7 @@ use warnings "all";
use JSON;
use HTTP::Async;
use HTTP::Cookies;
+use LWP::UserAgent;
use File::Basename;
use File::Spec;
use File::Copy qw/copy cp mv move/;
@@ -33,6 +34,7 @@ use xCAT::SvrUtils;
use xCAT::GlobalDef;
use xCAT_monitoring::monitorctrl;
use POSIX qw(WNOHANG);
+use xCAT::Utils qw/natural_sort_cmp/;
$::VERBOSE = 0;
# String constants for rbeacon states
@@ -49,9 +51,15 @@ $::POWER_STATE_RESET = "reset";
$::POWER_STATE_REBOOT = "reboot";
$::UPLOAD_FILE = "";
$::UPLOAD_FILE_VERSION = "";
+$::UPLOAD_PNOR = "";
+$::UPLOAD_PNOR_VERSION = "";
+$::UPLOAD_FILE_HASH_ID = "";
+$::UPLOAD_PNOR_HASH_ID = "";
$::RSETBOOT_URL_PATH = "boot";
# To improve the output to users, store this value as a global
$::UPLOAD_AND_ACTIVATE = 0;
+$::UPLOAD_ACTIVATE_STREAM = 0;
+$::RFLASH_STREAM_NO_HOST_REBOOT = 0;
$::NO_ATTRIBUTES_RETURNED = "No attributes returned from the BMC.";
@@ -59,6 +67,31 @@ $::UPLOAD_WAIT_ATTEMPT = 6;
$::UPLOAD_WAIT_INTERVAL = 10;
$::UPLOAD_WAIT_TOTALTIME = int($::UPLOAD_WAIT_ATTEMPT*$::UPLOAD_WAIT_INTERVAL);
+$::RPOWER_CHECK_INTERVAL = 2;
+$::RPOWER_MAX_RETRY = 30;
+
+$::BMC_MAX_RETRY = 20;
+$::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_WAIT_VLAN_DONE = 15;
+$::RSPCONFIG_WAIT_IP_DONE = 3;
+$::RSPCONFIG_DUMP_CMD_TIME = 0;
+
+$::XCAT_LOG_DIR = "/var/log/xcat";
+$::RAS_POLICY_TABLE = "/opt/ibm/ras/lib/policyTable.json";
+$::XCAT_LOG_RFLASH_DIR = $::XCAT_LOG_DIR . "/rflash/";
+$::XCAT_LOG_DUMP_DIR = $::XCAT_LOG_DIR . "/dump/";
+
+unless (-d $::XCAT_LOG_RFLASH_DIR) {
+ mkpath($::XCAT_LOG_RFLASH_DIR);
+}
+unless (-d $::XCAT_LOG_DUMP_DIR) {
+ mkpath($::XCAT_LOG_DUMP_DIR);
+}
+
sub unsupported {
my $callback = shift;
if (defined($::OPENBMC_DEVEL) && ($::OPENBMC_DEVEL eq "YES")) {
@@ -105,7 +138,7 @@ my %sensor_units = (
"$prefix.Sensor.Value.Unit.Joules" => "Joules"
);
my %child_node_map; # pid => node
-
+my %fw_tar_files;
my $http_protocol="https";
my $openbmc_url = "/org/openbmc";
my $openbmc_project_url = "/xyz/openbmc_project";
@@ -121,10 +154,16 @@ my %status_info = (
method => "POST",
init_url => "/login",
},
+ LOGIN_REQUEST_GENERAL => {
+ method => "POST",
+ init_url => "/login",
+ },
LOGIN_RESPONSE => {
process => \&login_response,
},
-
+ LOGIN_RESPONSE_GENERAL => {
+ process => \&login_response,
+ },
RBEACON_ON_REQUEST => {
method => "PUT",
init_url => "$openbmc_project_url/led/groups/enclosure_identify/attr/Asserted",
@@ -176,9 +215,17 @@ my %status_info = (
init_url => "$openbmc_project_url/software",
data => "xyz.openbmc_project.Software.Activation.RequestedActivations.Active",
},
+ RFLASH_UPDATE_HOST_ACTIVATE_REQUEST => {
+ method => "PUT",
+ init_url => "$openbmc_project_url/software",
+ data => "xyz.openbmc_project.Software.Activation.RequestedActivations.Active",
+ },
RFLASH_UPDATE_ACTIVATE_RESPONSE => {
process => \&rflash_response,
},
+ RFLASH_UPDATE_HOST_ACTIVATE_RESPONSE => {
+ process => \&rflash_response,
+ },
RFLASH_UPDATE_CHECK_STATE_REQUEST => {
method => "GET",
init_url => "$openbmc_project_url/software",
@@ -269,6 +316,20 @@ my %status_info = (
method => "GET",
init_url => "$openbmc_project_url/state/enumerate",
},
+ RPOWER_BMC_STATUS_REQUEST => {
+ method => "GET",
+ init_url => "$openbmc_project_url/state/enumerate",
+ },
+ RPOWER_BMC_CHECK_REQUEST => {
+ method => "GET",
+ init_url => "$openbmc_project_url/state/enumerate",
+ },
+ RPOWER_BMC_STATUS_RESPONSE => {
+ process => \&rpower_response,
+ },
+ RPOWER_BMC_CHECK_RESPONSE => {
+ process => \&rpower_response,
+ },
RPOWER_CHECK_RESPONSE => {
process => \&rpower_response,
},
@@ -304,14 +365,45 @@ my %status_info = (
RSPCONFIG_GET_RESPONSE => {
process => \&rspconfig_response,
},
- RSPCONFIG_SET_REQUEST => {
+ RSPCONFIG_SET_PASSWD_REQUEST => {
+ method => "POST",
+ init_url => "/xyz/openbmc_project/user/root/action/SetPassword",
+ data => "",
+ },
+ "RSPCONFIG_PASSWD_VERIFY" => {
+ process => \&rspconfig_response,
+ },
+ RSPCONFIG_SET_HOSTNAME_REQUEST => {
method => "PUT",
- init_url => "$openbmc_project_url/network",
+ init_url => "$openbmc_project_url/network/config/attr/HostName",
data => "[]",
},
RSPCONFIG_SET_RESPONSE => {
process => \&rspconfig_response,
},
+ RSPCONFIG_IPOBJECT_REQUEST => {
+ method => "POST",
+ init_url => "$openbmc_project_url/network/#NIC#/action/IP",
+ data => "",
+ },
+ RSPCONFIG_IPOBJECT_RESPONSE => {
+ process => \&rspconfig_response,
+ },
+ RSPCONFIG_VLAN_REQUEST => {
+ method => "POST",
+ init_url => "$openbmc_project_url/network/action/VLAN",
+ data => "",
+ },
+ RSPCONFIG_VLAN_RESPONSE => {
+ process => \&rspconfig_response,
+ },
+ RSPCONFIG_CHECK_REQUEST => {
+ method => "GET",
+ init_url => "$openbmc_project_url/network/enumerate",
+ },
+ RSPCONFIG_CHECK_RESPONSE => {
+ process => \&rspconfig_response,
+ },
RSPCONFIG_DHCP_REQUEST => {
method => "POST",
init_url => "$openbmc_project_url/network/action/Reset",
@@ -320,12 +412,68 @@ my %status_info = (
RSPCONFIG_DHCP_RESPONSE => {
process => \&rspconfig_response,
},
+ RSPCONFIG_DHCPDIS_REQUEST => {
+ method => "PUT",
+ init_url => "$openbmc_project_url/network/#NIC#/attr/DHCPEnabled",
+ data => 0,
+ },
+ RSPCONFIG_DHCPDIS_RESPONSE => {
+ process => \&rspconfig_response,
+ },
+ RSPCONFIG_DELETE_REQUEST => {
+ method => "DELETE",
+ init_url => "",
+ },
+ RSPCONFIG_DELETE_RESPONSE => {
+ process => \&rspconfig_response,
+ },
+ RSPCONFIG_PRINT_BMCINFO => {
+ process => \&rspconfig_response,
+ },
RSPCONFIG_SSHCFG_REQUEST => {
process => \&rspconfig_sshcfg_response,
},
RSPCONFIG_SSHCFG_RESPONSE => {
process => \&rspconfig_sshcfg_response,
},
+ RSPCONFIG_DUMP_LIST_REQUEST => {
+ method => "GET",
+ init_url => "$openbmc_project_url/dump/enumerate",
+ },
+ RSPCONFIG_DUMP_LIST_RESPONSE => {
+ process => \&rspconfig_dump_response,
+ },
+ RSPCONFIG_DUMP_CHECK_RESPONSE => {
+ process => \&rspconfig_dump_response,
+ },
+ RSPCONFIG_DUMP_CREATE_REQUEST => {
+ method => "POST",
+ init_url => "$openbmc_project_url/dump/action/CreateDump",
+ data => "[]",
+ },
+ RSPCONFIG_DUMP_CREATE_RESPONSE => {
+ process => \&rspconfig_dump_response,
+ },
+ RSPCONFIG_DUMP_CLEAR_REQUEST => {
+ method => "POST",
+ init_url => "$openbmc_project_url/dump/entry/#ID#/action/Delete",
+ data => "[]",
+ },
+ RSPCONFIG_DUMP_CLEAR_ALL_REQUEST => {
+ method => "POST",
+ init_url => "$openbmc_project_url/dump/action/DeleteAll",
+ data => "[]",
+ },
+ RSPCONFIG_DUMP_CLEAR_RESPONSE => {
+ process => \&rspconfig_dump_response,
+ },
+ RSPCONFIG_DUMP_DOWNLOAD_REQUEST => {
+ init_url => "download/dump/#ID#",
+ process => \&rspconfig_dump_response,
+ },
+ RSPCONFIG_DUMP_DOWNLOAD_RESPONSE => {
+ process => \&rspconfig_dump_response,
+ },
RVITALS_REQUEST => {
method => "GET",
init_url => "$openbmc_project_url/sensors/enumerate",
@@ -339,6 +487,7 @@ $::RESPONSE_OK = "200 OK";
$::RESPONSE_SERVER_ERROR = "500 Internal Server Error";
$::RESPONSE_SERVICE_UNAVAILABLE = "503 Service Unavailable";
$::RESPONSE_FORBIDDEN = "403 Forbidden";
+$::RESPONSE_NOT_FOUND = "404 Not Found";
$::RESPONSE_METHOD_NOT_ALLOWED = "405 Method Not Allowed";
$::RESPONSE_SERVICE_TIMEOUT = "504 Gateway Timeout";
@@ -388,6 +537,8 @@ my $flag_debug = "[openbmc_debug]";
my %login_pid_node; # used in process_request, record login fork pid map
+my $event_mapping = "";
+
#-------------------------------------------------------
=head3 preprocess_request
@@ -437,6 +588,12 @@ sub preprocess_request {
$callback = shift;
+ if ($::XCATSITEVALS{xcatdebugmode}) { $xcatdebugmode = $::XCATSITEVALS{xcatdebugmode} }
+
+ if ($xcatdebugmode) {
+ process_debug_info("OpenBMC");
+ }
+
my $command = $request->{command}->[0];
my $noderange = $request->{node};
my $extrargs = $request->{arg};
@@ -493,6 +650,48 @@ sub retry_after {
$node_wait{$node} = time() + $timeout;
}
+#-------------------------------------------------------
+
+=head3 retry_check_times
+
+ The request will be delayed for the given time and then
+ send the reqeust based on the BMC status after BMCreboot.
+
+=cut
+
+#-------------------------------------------------------
+sub retry_check_times {
+ my ($node, $request_status, $check_type, $wait_time, $response_status) = @_;
+ if ($node_info{$node}{$check_type} > 0) {
+ $node_info{$node}{$check_type}--;
+ if ($node_info{$node}{wait_start}) {
+ $node_info{$node}{wait_end} = time();
+ } else {
+ $node_info{$node}{wait_start} = time();
+ }
+ my $retry_msg = "Retry BMC state, wait for $wait_time seconds ...";
+ xCAT::MsgUtils->message("I", { data => ["$node: $retry_msg"] }, $callback);
+ if ($response_status ne $::RESPONSE_SERVICE_UNAVAILABLE) {
+ my $login_url = "$http_protocol://$node_info{$node}{bmc}/login";
+ my $content = '[ "' . $node_info{$node}{username} .'", "' . $node_info{$node}{password} . '" ]';
+ $status_info{LOGIN_REQUEST_GENERAL}{data} = $content;
+ $node_info{$node}{cur_status} = "LOGIN_REQUEST_GENERAL";
+ $node_wait{$node} = time() + $wait_time;
+ return;
+ }
+
+ $node_info{$node}{cur_status} = $request_status;
+ $node_wait{$node} = time() + $wait_time;
+ return;
+ } else {
+ my $wait_time_X = $node_info{$node}{wait_end} - $node_info{$node}{wait_start};
+ my $msg="Error: Sent bmcreboot but state did not change to BMC Ready after waiting $wait_time_X seconds. (State=BMC NotReady).";
+ xCAT::SvrUtils::sendmsg([1, $msg], $callback, $node);
+ $node_info{$node}{cur_status} = "";
+ $wait_node_num--;
+ return;
+ }
+}
#-------------------------------------------------------
@@ -515,8 +714,6 @@ sub process_request {
@exargs = @$extrargs;
}
- if ($::XCATSITEVALS{xcatdebugmode}) { $xcatdebugmode = $::XCATSITEVALS{xcatdebugmode} }
-
my $check = parse_node_info($noderange);
my $rst = parse_command_status($command, \@exargs);
return if ($rst);
@@ -583,19 +780,28 @@ sub process_request {
foreach my $node (keys %node_info) {
if (!$valid_nodes{$node}) {
- xCAT::SvrUtils::sendmsg([1, $::RESPONSE_SERVICE_UNAVAILABLE], $callback, $node);
+ xCAT::SvrUtils::sendmsg([1, "BMC did not respond. Validate BMC configuration and retry the command."], $callback, $node);
$wait_node_num--;
- } else {
- $login_url = "$http_protocol://$node_info{$node}{bmc}/login";
- $content = '{ "data": [ "' . $node_info{$node}{username} .'", "' . $node_info{$node}{password} . '" ] }';
- if ($xcatdebugmode) {
- my $debug_info = "curl -k -c cjar -H \"Content-Type: application/json\" -d '{ \"data\": [\"$node_info{$node}{username}\", \"xxxxxx\"] }' $login_url";
- process_debug_info($node, $debug_info);
- }
- $handle_id = xCAT::OPENBMC->new($async, $login_url, $content);
- $handle_id_node{$handle_id} = $node;
- $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
+ next;
}
+ if ($next_status{LOGIN_RESPONSE} eq "RSPCONFIG_SET_HOSTNAME_REQUEST" and $status_info{RSPCONFIG_SET_HOSTNAME_REQUEST}{data} =~ /^\*$/) {
+ if ($node_info{$node}{bmc} =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
+ my $info_msg = "Invalid OpenBMC Hostname $node_info{$node}{bmc}, can't set to OpenBMC";
+ xCAT::SvrUtils::sendmsg($info_msg, $callback, $node);
+ $wait_node_num--;
+ next;
+ }
+ }
+
+ $login_url = "$http_protocol://$node_info{$node}{bmc}/login";
+ $content = '{ "data": [ "' . $node_info{$node}{username} .'", "' . $node_info{$node}{password} . '" ] }';
+ if ($xcatdebugmode) {
+ my $debug_info = "curl -k -c cjar -H \"Content-Type: application/json\" -d '{ \"data\": [\"$node_info{$node}{username}\", \"xxxxxx\"] }' $login_url";
+ process_debug_info($node, $debug_info);
+ }
+ $handle_id = xCAT::OPENBMC->new($async, $login_url, $content);
+ $handle_id_node{$handle_id} = $node;
+ $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
}
if ($next_status{LOGIN_RESPONSE} eq "RSPCONFIG_SSHCFG_REQUEST") {
@@ -631,11 +837,41 @@ rmdir \"/tmp/\$userid\" \n";
while (1) {
unless ($wait_node_num) {
+ if ($event_mapping and (ref($event_mapping) ne "HASH")) {
+ xCAT::SvrUtils::sendmsg("$event_mapping, install the OpenBMC RAS package to obtain more details logging messages.", $callback);
+ }
if ($next_status{LOGIN_RESPONSE} eq "RSPCONFIG_SSHCFG_REQUEST") {
my $home = xCAT::Utils->getHomeDir("root");
unlink "$home/.ssh/copy.sh";
File::Path->remove_tree("$home/.ssh/tmp/");
}
+ if ($::UPLOAD_AND_ACTIVATE or $next_status{LOGIN_RESPONSE} eq "RFLASH_UPDATE_ACTIVATE_REQUEST") {
+ my %rflash_result = ();
+ foreach my $node (keys %node_info) {
+ if ($node_info{$node}{rst} =~ /successful/) {
+ push @{ $rflash_result{success} }, $node;
+ } else {
+ $node_info{$node}{rst} = "BMC is not ready" unless ($node_info{$node}{rst});
+ push @{ $rflash_result{fail} }, "$node: $node_info{$node}{rst}";
+ }
+ }
+ xCAT::MsgUtils->message("I", { data => ["-------------------------------------------------------"] }, $callback);
+ my $summary = "Firmware update complete: ";
+ my $total = keys %node_info;
+ my $success = 0;
+ my $fail = 0;
+ $success = @{ $rflash_result{success} } if (defined $rflash_result{success} and @{ $rflash_result{success} });
+ $fail = @{ $rflash_result{fail} } if (defined $rflash_result{fail} and @{ $rflash_result{fail} });
+ $summary .= "Total=$total Success=$success Failed=$fail";
+ xCAT::MsgUtils->message("I", { data => ["$summary"] }, $callback);
+
+ if ($rflash_result{fail}) {
+ foreach (@{ $rflash_result{fail} }) {
+ xCAT::MsgUtils->message("I", { data => ["$_"] }, $callback);
+ }
+ }
+ xCAT::MsgUtils->message("I", { data => ["-------------------------------------------------------"] }, $callback);
+ }
last;
}
while (my ($response, $handle_id) = $async->wait_for_next_response) {
@@ -712,6 +948,12 @@ sub parse_args {
if (scalar(@ARGV) >= 2 and ($command =~ /rpower|rinv|rvitals/)) {
return ([ 1, "Only one option is supported at the same time for $command" ]);
+ } elsif (scalar(@ARGV) >= 2 and $command eq "reventlog") {
+ my $option_s;
+ GetOptions( 's' => \$option_s );
+ return ([ 1, "The -s option is not supported for OpenBMC." ]) if ($option_s);
+ return ([ 1, "Only one option is supported at the same time for $command" ]);
+
} elsif (scalar(@ARGV) == 0 and $command =~ /rpower|rspconfig|rflash/) {
return ([ 1, "No option specified for $command" ]);
} else {
@@ -739,49 +981,81 @@ sub parse_args {
return ([ 1, "Unsupported command: $command $subcommand" ]);
}
} elsif ($command eq "reventlog") {
- my $option_s = 0;
- unless (GetOptions("s" => \$option_s,)) {
- return ([1, "Error parsing arguments." ]);
- }
$subcommand = "all" if (!defined($ARGV[0]));
unless ($subcommand =~ /^\d$|^\d+$|^all$|^clear$/) {
return ([ 1, "Unsupported command: $command $subcommand" ]);
}
} elsif ($command eq "rspconfig") {
+ my $num_subcommand = @ARGV;
my $setorget;
+ my $all_subcommand = "";
foreach $subcommand (@ARGV) {
if ($subcommand =~ /^(\w+)=(.*)/) {
- return ([ 1, "Can not configure and display nodes' value at the same time" ]) if ($setorget and $setorget eq "get");
+ return ([ 1, "Can not set and query OpenBMC information at the same time" ]) if ($setorget and $setorget eq "get");
my $key = $1;
my $value = $2;
return ([ 1, "Changing ipsrc value is currently not supported." ]) if ($key eq "ipsrc");
- return ([ 1, "Unsupported command: $command $key" ]) unless ($key =~ /^ip$|^netmask$|^gateway$|^hostname$|^vlan$/);
+ return ([ 1, "Unsupported command: $command $key" ]) unless ($key =~ /^ip$|^netmask$|^gateway$|^hostname$|^vlan$|^admin_passwd$/);
+ return ([ 1, "The option '$key' can not work with other options." ]) if ($key =~ /^hostname$|^admin_passwd$/ and $num_subcommand > 1);
+ if ($key eq "admin_passwd") {
+ my $comma_num = $value =~ tr/,/,/;
+ return ([ 1, "Invalid parameter for option $key: $value" ]) if ($comma_num != 1);
+ if ($subcommand =~ /^admin_passwd=(.*),(.*)/) {
+ return ([ 1, "Invalid parameter for option $key: $value" ]) if ($1 eq "" or $2 eq "");
+ }
+ }
my $nodes_num = @$noderange;
return ([ 1, "Invalid parameter for option $key" ]) unless ($value);
- return ([ 1, "Invalid parameter for option $key: $value" ]) if ($key =~ /^netmask$|^gateway$/ and !xCAT::NetworkUtils->isIpaddr($value));
+ return ([ 1, "Invalid parameter for option $key: $value" ]) if (($key eq "netmask") and !xCAT::NetworkUtils->isIpaddr($value));
+ return ([ 1, "Invalid parameter for option $key: $value" ]) if (($key eq "gateway") and ($value !~ "0.0.0.0" and !xCAT::NetworkUtils->isIpaddr($value)));
if ($key eq "ip") {
return ([ 1, "Can not configure more than 1 nodes' ip at the same time" ]) if ($nodes_num >= 2 and $value ne "dhcp");
- if ($value ne "dhcp" and !xCAT::NetworkUtils->isIpaddr($value)) {
- return ([ 1, "Invalid parameter for option $key: $value" ]);
+ if ($value ne "dhcp" ) {
+ if (!xCAT::NetworkUtils->isIpaddr($value)) {
+ return ([ 1, "Invalid parameter for option $key: $value" ]);
+ } else {
+ $all_subcommand .= $key . ",";
+ }
+ } else {
+ return ([ 1, "Setting ip=dhcp must be issued without other options." ]) if ($num_subcommand > 1);
}
+ } elsif ($key =~ /^netmask$|^gateway$|^vlan$/) {
+ $all_subcommand .= $key . ",";
}
$setorget = "set";
- #
- # disable function until fully tested
- #
- unless (($key eq "ip" and $value eq "dhcp") or $key eq "hostname") {
- $check = unsupported($callback); if (ref($check) eq "ARRAY") { return $check; }
- }
} elsif ($subcommand =~ /^ip$|^netmask$|^gateway$|^hostname$|^vlan$|^ipsrc$/) {
- return ([ 1, "Can not configure and display nodes' value at the same time" ]) if ($setorget and $setorget eq "set");
+ return ([ 1, "Can not set and query OpenBMC information at the same time" ]) if ($setorget and $setorget eq "set");
$setorget = "get";
} 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 "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*$/);
+ } 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");
+ } elsif ($option and $option !~ /^-l$|^--list$|^-g$|^--generate$/) {
+ return ([ 1, "Invalid parameter for $command $option" ]);
+ }
+ return;
} else {
return ([ 1, "Unsupported command: $command $subcommand" ]);
}
- }
+ }
+ if ($all_subcommand) {
+ if ($all_subcommand !~ /ip/ or $all_subcommand !~ /netmask/ or $all_subcommand !~ /gateway/) {
+ if ($all_subcommand =~ /vlan/) {
+ return ([ 1, "VLAN must be configured with IP, netmask and gateway" ]);
+ } else {
+ return ([ 1, "IP, netmask and gateway must be configured together." ]);
+ }
+ }
+ }
} elsif ($command eq "rvitals") {
$subcommand = "all" if (!defined($ARGV[0]));
unless ($subcommand =~ /^temp$|^voltage$|^wattage$|^fanspeed$|^power$|^altitude$|^all$/) {
@@ -790,8 +1064,10 @@ sub parse_args {
} elsif ($command eq "rflash") {
my $filename_passed = 0;
my $updateid_passed = 0;
+ my $filepath_passed = 0;
my $option_flag;
+ my @tarball_path;
my $invalid_options = "";
my @flash_arguments;
@@ -810,26 +1086,41 @@ sub parse_args {
}
# check if option starting with - was passed
elsif ($opt =~ /^-/) {
- if ($option_flag) {
- $option_flag .= " " . $opt;
- } else {
- $option_flag .= $opt;
+ # do not add verbose option to the $option_flag in order to preserve arg checks below
+ if ($opt !~ /^-V$|^--verbose$/) {
+ if ($option_flag) {
+ $option_flag .= " " . $opt;
+ } else {
+ $option_flag .= $opt;
+ }
}
}
+ elsif ($opt =~ /.*\//) {
+ $filepath_passed = 1;
+ push (@tarball_path, $opt);
+ }
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\n";
+ print "DEBUG filename=$filename_passed, updateid=$updateid_passed, options=$option_flag, invalid=$invalid_options rflash_arguments=@flash_arguments\n";
if ($option_flag =~ tr{ }{ } > 0) {
- return ([ 1, "Multiple options specified is not supported. Options specified: $option_flag"]);
+ unless ($verbose or $option_flag =~/^-d --no-host-reboot$/) {
+ return ([ 1, "Multiple options are not supported. Options specified: $option_flag"]);
+ }
}
if (scalar @flash_arguments > 1) {
- return ([1, "More than one firmware specified is not supported."]);
+ if ($filename_passed and $option_flag !~ /^-d$/) {
+ return ([1, "More than one firmware specified is not supported."]);
+ } elsif ($option_flag =~ /^-d$/) {
+ return ([1, "More than one directory specified is not supported."]);
+ } else {
+ return ([ 1, "Invalid firmware specified with $option_flag" ]);
+ }
}
if ($filename_passed) {
@@ -841,15 +1132,36 @@ sub parse_args {
else {
if ($updateid_passed) {
# Updateid was passed, check flags allowed with update id
- if ($option_flag !~ /^^-d$|^--delete$|^-a$|^--activate$/) {
+ if ($option_flag !~ /^--delete$|^-a$|^--activate$/) {
return ([ 1, "Invalid option specified when an update id is provided: $option_flag" ]);
}
- }
- else {
+ my $action = "activate";
+ if ($option_flag =~ /^--delete$/) {
+ $action = "delete";
+ }
+ xCAT::SvrUtils::sendmsg("Attempting to $action ID=$flash_arguments[0], please wait...", $callback);
+ } elsif ($filepath_passed) {
+ if ($option_flag =~ /^-d|^-d --no-host-reboot$/) {
+ if (scalar @tarball_path > 1) {
+ return ([1, "More than one directory specified is not supported"]);
+ }
+ if ($invalid_options) {
+ return ([ 1, "Invalid option specified $invalid_options"]);
+ }
+ if (!opendir(DIR, $tarball_path[0])) {
+ return ([1, "Can't open directory : $tarball_path[0]"]);
+ }
+ closedir(DIR);
+ } elsif ($option_flag =~ /^-c$|^--check$|^-u$|^--upload$|^-a$|^--activate$/) {
+ return ([ 1, "Invalid firmware specified with $option_flag" ]);
+ } else {
+ return ([ 1, "Invalid option specified" ]);
+ }
+ } else {
# Neither Filename nor updateid was not passed, check flags allowed without file or updateid
- if ($option_flag !~ /^-c$|^--check$|^-l$|^--list/) {
+ if ($option_flag !~ /^-c$|^--check$|^-l$|^--list$/) {
return ([ 1, "Invalid option specified with $option_flag: $invalid_options" ]);
- }
+ }
}
}
} else {
@@ -931,9 +1243,15 @@ sub parse_command_status {
$next_status{RPOWER_ON_REQUEST} = "RPOWER_ON_RESPONSE";
$status_info{RPOWER_ON_RESPONSE}{argv} = "$subcommand";
} elsif ($subcommand eq "bmcreboot") {
- $next_status{LOGIN_RESPONSE} = "RPOWER_BMCREBOOT_REQUEST";
+ $next_status{LOGIN_RESPONSE} = "RINV_FIRM_REQUEST";
+ $next_status{RINV_FIRM_REQUEST} = "RINV_FIRM_RESPONSE";
+ $next_status{RINV_FIRM_RESPONSE}{PENDING} = "RSPCONFIG_DUMP_CLEAR_ALL_REQUEST";
+ $next_status{RSPCONFIG_DUMP_CLEAR_ALL_REQUEST} = "RSPCONFIG_DUMP_CLEAR_RESPONSE";
+ $next_status{RSPCONFIG_DUMP_CLEAR_RESPONSE} = "RPOWER_BMCREBOOT_REQUEST";
+ $next_status{RINV_FIRM_RESPONSE}{NO_PENDING} = "RPOWER_BMCREBOOT_REQUEST";
$next_status{RPOWER_BMCREBOOT_REQUEST} = "RPOWER_RESET_RESPONSE";
$status_info{RPOWER_RESET_RESPONSE}{argv} = "$subcommand";
+ $status_info{RINV_FIRM_RESPONSE}{check} = 1;
}
}
@@ -1006,12 +1324,6 @@ sub parse_command_status {
}
if ($command eq "reventlog") {
- my $option_s = 0;
- if ($$subcommands[-1] and $$subcommands[-1] eq "-s") {
- $option_s = 1;
- pop(@$subcommands);
- }
-
if (defined($$subcommands[0])) {
$subcommand = $$subcommands[0];
} else {
@@ -1025,55 +1337,168 @@ sub parse_command_status {
$next_status{LOGIN_RESPONSE} = "REVENTLOG_REQUEST";
$next_status{REVENTLOG_REQUEST} = "REVENTLOG_RESPONSE";
$status_info{REVENTLOG_RESPONSE}{argv} = "$subcommand";
- $status_info{REVENTLOG_RESPONSE}{argv} .= ",s" if ($option_s);
+ if (-e "$::RAS_POLICY_TABLE") {
+ my $policy_json = `cat $::RAS_POLICY_TABLE`;
+ if ($policy_json) {
+ my $policy_hash = decode_json $policy_json;
+ $event_mapping = $policy_hash->{events};
+ } else {
+ $event_mapping = "No data in $::RAS_POLICY_TABLE";
+ }
+ } else {
+ $event_mapping = "Could not find '$::RAS_POLICY_TABLE'";
+ }
}
}
if ($command eq "rspconfig") {
my @options = ();
- foreach $subcommand (@$subcommands) {
- if ($subcommand =~ /^ip$|^netmask$|^gateway$|^hostname$|^vlan$|^ipsrc$/) {
- $next_status{LOGIN_RESPONSE} = "RSPCONFIG_GET_REQUEST";
- $next_status{RSPCONFIG_GET_REQUEST} = "RSPCONFIG_GET_RESPONSE";
- push @options, $subcommand;
- } elsif ($subcommand =~ /^sshcfg$/) {
+ my $num_subcommand = @$subcommands;
+ if ($num_subcommand == 1) {
+ $subcommand = $$subcommands[0];
+ if ($subcommand =~ /^sshcfg$/) {
# Special processing to copy ssh keys, currently there is no REST API to do this.
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_SSHCFG_REQUEST";
$next_status{RSPCONFIG_SSHCFG_REQUEST} = "RSPCONFIG_SSHCFG_RESPONSE";
return 0;
+ }
+ if ($subcommand eq "ip=dhcp") {
+ $next_status{LOGIN_RESPONSE} = "RSPCONFIG_DHCP_REQUEST";
+ $next_status{RSPCONFIG_DHCP_REQUEST} = "RSPCONFIG_DHCP_RESPONSE";
+ $next_status{RSPCONFIG_DHCP_RESPONSE} = "RPOWER_BMCREBOOT_REQUEST";
+ $next_status{RPOWER_BMCREBOOT_REQUEST} = "RPOWER_RESET_RESPONSE";
+ $status_info{RPOWER_RESET_RESPONSE}{argv} = "bmcreboot";
+ return 0;
+ }
+ if ($subcommand =~ /^hostname=(.+)/) {
+ $next_status{LOGIN_RESPONSE} = "RSPCONFIG_SET_HOSTNAME_REQUEST";
+ $next_status{RSPCONFIG_SET_HOSTNAME_REQUEST} = "RSPCONFIG_SET_RESPONSE";
+ $next_status{RSPCONFIG_SET_RESPONSE} = "RSPCONFIG_GET_REQUEST";
+ $next_status{RSPCONFIG_GET_REQUEST} = "RSPCONFIG_GET_RESPONSE";
+
+ $status_info{RSPCONFIG_SET_HOSTNAME_REQUEST}{data} = $1;
+ $status_info{RSPCONFIG_SET_RESPONSE}{argv} = "Hostname";
+ $status_info{RSPCONFIG_GET_RESPONSE}{argv} = "hostname";
+ return 0;
+ }
+ }
+
+ $subcommand = $$subcommands[0];
+ if ($subcommand eq "dump") {
+ my $dump_opt = "";
+ $dump_opt = $$subcommands[1] if (defined $$subcommands[1]);
+ if ($dump_opt =~ /-l|--list/) {
+ $next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_LIST_REQUEST";
+ $next_status{RSPCONFIG_DUMP_LIST_REQUEST} = "RSPCONFIG_DUMP_LIST_RESPONSE";
+ } elsif ($dump_opt =~ /-g|--generate/) {
+ $next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_CREATE_REQUEST";
+ $next_status{RSPCONFIG_DUMP_CREATE_REQUEST} = "RSPCONFIG_DUMP_CREATE_RESPONSE";
+ } elsif ($dump_opt =~ /-c|--clear/) {
+ if ($$subcommands[2] eq "all") {
+ $next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_CLEAR_ALL_REQUEST";
+ $next_status{RSPCONFIG_DUMP_CLEAR_ALL_REQUEST} = "RSPCONFIG_DUMP_CLEAR_RESPONSE";
+ } else {
+ $next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_CLEAR_REQUEST";
+ $next_status{RSPCONFIG_DUMP_CLEAR_REQUEST} = "RSPCONFIG_DUMP_CLEAR_RESPONSE";
+ $status_info{RSPCONFIG_DUMP_CLEAR_REQUEST}{init_url} =~ s/#ID#/$$subcommands[2]/g;
+ }
+ $status_info{RSPCONFIG_DUMP_CLEAR_RESPONSE}{argv} = $$subcommands[2];
+ } elsif ($dump_opt =~ /-d|--download/) {
+ # Verify directory for download is there
+ unless (-d $::XCAT_LOG_DUMP_DIR) {
+ xCAT::SvrUtils::sendmsg([1, "Unable to create directory " . $::XCAT_LOG_DUMP_DIR . " to download dump file, cannot continue."], $callback);
+ 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];
+ } 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
+ # Verify directory for download is there
+ unless (-d $::XCAT_LOG_DUMP_DIR) {
+ xCAT::SvrUtils::sendmsg([1, "Unable to find directory " . $::XCAT_LOG_DUMP_DIR . " to download dump file"], $callback);
+ return 1;
+ }
+ $::RSPCONFIG_DUMP_CMD_TIME = time(); #Save time of rspcommand start to use in the dump filename
+ xCAT::SvrUtils::sendmsg("Capturing BMC Diagnostic information, this will take some time...", $callback);
+ $next_status{LOGIN_RESPONSE} = "RSPCONFIG_DUMP_CREATE_REQUEST";
+ $next_status{RSPCONFIG_DUMP_CREATE_REQUEST} = "RSPCONFIG_DUMP_CREATE_RESPONSE";
+ $next_status{RSPCONFIG_DUMP_CREATE_RESPONSE} = "RSPCONFIG_DUMP_LIST_REQUEST";
+ $next_status{RSPCONFIG_DUMP_LIST_REQUEST} = "RSPCONFIG_DUMP_CHECK_RESPONSE";
+ $next_status{RSPCONFIG_DUMP_CHECK_RESPONSE} = "RSPCONFIG_DUMP_DOWNLOAD_REQUEST";
+ $next_status{RSPCONFIG_DUMP_DOWNLOAD_REQUEST} = "RSPCONFIG_DUMP_DOWNLOAD_RESPONSE";
+ }
+ return 0;
+ }
+
+ if ($subcommand =~ /^admin_passwd=(.+),(.+)/) {
+ my $currentpasswd = $1;
+ my $newpasswd = $2;
+ $next_status{LOGIN_RESPONSE} = "RSPCONFIG_PASSWD_VERIFY";
+ $next_status{RSPCONFIG_PASSWD_VERIFY} = "RSPCONFIG_SET_PASSWD_REQUEST";
+ $next_status{RSPCONFIG_SET_PASSWD_REQUEST} = "RSPCONFIG_SET_RESPONSE";
+
+ $status_info{RSPCONFIG_PASSWD_VERIFY}{argv} = "$currentpasswd";
+ $status_info{RSPCONFIG_SET_PASSWD_REQUEST}{data} = "[\"$newpasswd\"]";
+ $status_info{RSPCONFIG_SET_RESPONSE}{argv} = "Password";
+ return 0;
+ }
+
+ my $type = "obj";
+ my %tmp_hash = ();
+ foreach $subcommand (@$subcommands) {
+ if ($subcommand =~ /^ip$|^netmask$|^gateway$|^hostname$|^vlan$|^ipsrc$/) {
+ $type = "get";
+ push @options, $subcommand;
} elsif ($subcommand =~ /^(\w+)=(.+)/) {
my $key = $1;
my $value = $2;
- if ($key eq "ip" and $value eq "dhcp") {
- $next_status{LOGIN_RESPONSE} = "RSPCONFIG_DHCP_REQUEST";
- $next_status{RSPCONFIG_DHCP_REQUEST} = "RSPCONFIG_DHCP_RESPONSE";
- $next_status{RSPCONFIG_DHCP_RESPONSE} = "RPOWER_BMCREBOOT_REQUEST";
- $next_status{RPOWER_BMCREBOOT_REQUEST} = "RPOWER_RESET_RESPONSE";
- $status_info{RPOWER_RESET_RESPONSE}{argv} = "bmcreboot";
- } elsif ($key =~ /^hostname$/) {
- $next_status{LOGIN_RESPONSE} = "RSPCONFIG_SET_REQUEST";
- $next_status{RSPCONFIG_SET_REQUEST} = "RSPCONFIG_SET_RESPONSE";
- $next_status{RSPCONFIG_SET_RESPONSE} = "RSPCONFIG_GET_REQUEST";
- $next_status{RSPCONFIG_GET_REQUEST} = "RSPCONFIG_GET_RESPONSE";
-
- $status_info{RSPCONFIG_SET_REQUEST}{data} = "$value";
- $status_info{RSPCONFIG_SET_REQUEST}{init_url} .= "/config/attr/HostName";
- push @options, $key;
-
- } else {
- $next_status{LOGIN_RESPONSE} = "RSPCONFIG_SET_REQUEST";
- $next_status{RSPCONFIG_SET_REQUEST} = "RSPCONFIG_SET_RESPONSE";
- $next_status{RSPCONFIG_SET_RESPONSE} = "RSPCONFIG_GET_REQUEST";
- $next_status{RSPCONFIG_GET_REQUEST} = "RSPCONFIG_GET_RESPONSE";
- if ($key eq "ip") {
- $status_info{RSPCONFIG_SET_RESPONSE}{ip} = $value;
- }
- $status_info{RSPCONFIG_SET_REQUEST}{data} = ""; # wait for interface, ip/netmask/gateway is $value
- push @options, $key;
- }
+ $type = "vlan" if ($key eq "vlan");
+ $tmp_hash{$key} = $value;
}
}
- $status_info{RSPCONFIG_GET_RESPONSE}{argv} = join(",", @options);
+ if ($type eq "get") {
+ $next_status{LOGIN_RESPONSE} = "RSPCONFIG_GET_REQUEST";
+ $next_status{RSPCONFIG_GET_REQUEST} = "RSPCONFIG_GET_RESPONSE";
+ $status_info{RSPCONFIG_GET_RESPONSE}{argv} = join(",", @options);
+ } else {
+ $next_status{LOGIN_RESPONSE} = "RSPCONFIG_GET_REQUEST";
+ $next_status{RSPCONFIG_GET_REQUEST} = "RSPCONFIG_GET_RESPONSE";
+ my $prefix = xCAT::NetworkUtils::formatNetmask($tmp_hash{netmask}, 0, 1);
+
+ if ($type eq "obj") {
+ $next_status{RSPCONFIG_GET_RESPONSE} = "RSPCONFIG_IPOBJECT_REQUEST";
+ $next_status{RSPCONFIG_IPOBJECT_REQUEST} = "RSPCONFIG_IPOBJECT_RESPONSE";
+
+ $status_info{RSPCONFIG_CHECK_RESPONSE}{argv} = "$tmp_hash{ip}-$prefix-$tmp_hash{gateway}";
+ $status_info{RSPCONFIG_PRINT_BMCINFO}{data} = "BMC IP: $tmp_hash{ip},BMC Netmask: $tmp_hash{netmask},BMC Gateway: $tmp_hash{gateway}";
+ } elsif ($type eq "vlan") {
+ $next_status{RSPCONFIG_GET_RESPONSE} = "RSPCONFIG_VLAN_REQUEST";
+ $next_status{RSPCONFIG_VLAN_REQUEST} = "RSPCONFIG_VLAN_RESPONSE";
+ $next_status{RSPCONFIG_VLAN_RESPONSE} = "RSPCONFIG_IPOBJECT_REQUEST";
+ $next_status{RSPCONFIG_IPOBJECT_REQUEST} = "RSPCONFIG_IPOBJECT_RESPONSE";
+
+ $status_info{RSPCONFIG_VLAN_REQUEST}{data} = "[\"#NIC#\",\"$tmp_hash{vlan}\"]";
+ $status_info{RSPCONFIG_IPOBJECT_REQUEST}{init_url} =~ s/#NIC#/#NIC#_$tmp_hash{vlan}/g;
+ $status_info{RSPCONFIG_CHECK_RESPONSE}{argv} = "$tmp_hash{vlan}-$tmp_hash{ip}-$prefix-$tmp_hash{gateway}";
+ $status_info{RSPCONFIG_PRINT_BMCINFO}{data} = "BMC IP: $tmp_hash{ip},BMC Netmask: $tmp_hash{netmask},BMC Gateway: $tmp_hash{gateway},BMC VLAN ID: $tmp_hash{vlan}";
+ }
+
+ $next_status{RSPCONFIG_IPOBJECT_RESPONSE} = "RSPCONFIG_CHECK_REQUEST";
+ $next_status{RSPCONFIG_CHECK_REQUEST} = "RSPCONFIG_CHECK_RESPONSE";
+ $next_status{RSPCONFIG_CHECK_RESPONSE}{STATIC} = "RSPCONFIG_DELETE_REQUEST";
+ $next_status{RSPCONFIG_DELETE_REQUEST} = "RSPCONFIG_DELETE_RESPONSE";
+ $next_status{RSPCONFIG_CHECK_RESPONSE}{DHCP} = "RSPCONFIG_DHCPDIS_REQUEST";
+ $next_status{RSPCONFIG_DHCPDIS_REQUEST} = "RSPCONFIG_DHCPDIS_RESPONSE";
+ $next_status{RSPCONFIG_DELETE_RESPONSE} = "RSPCONFIG_PRINT_BMCINFO";
+ $next_status{RSPCONFIG_DHCPDIS_RESPONSE} = "RSPCONFIG_PRINT_BMCINFO";
+
+ $status_info{RSPCONFIG_GET_RESPONSE}{argv} = "all";
+ $status_info{RSPCONFIG_IPOBJECT_REQUEST}{data} = "[\"xyz.openbmc_project.Network.IP.Protocol.IPv4\",\"$tmp_hash{ip}\",$prefix,\"$tmp_hash{gateway}\"]";
+ }
}
if ($command eq "rvitals") {
@@ -1095,18 +1520,28 @@ sub parse_command_status {
my $upload = 0;
my $activate = 0;
my $update_file;
+ my $streamline = 0;
+ my $nohost_reboot = 0;
foreach $subcommand (@$subcommands) {
if ($subcommand =~ /-c|--check/) {
$check_version = 1;
} elsif ($subcommand =~ /-l|--list/) {
$list = 1;
- } elsif ($subcommand =~ /-d|--delete/) {
+ } elsif ($subcommand =~ /--delete/) {
$delete = 1;
} elsif ($subcommand =~ /-u|--upload/) {
$upload = 1;
} elsif ($subcommand =~ /-a|--activate/) {
$activate = 1;
+ } elsif ($subcommand =~ /-d/) {
+ my $check = unsupported($callback); if (ref($check) eq "ARRAY") {
+ xCAT::SvrUtils::sendmsg($check, $callback);
+ return 1;
+ }
+ $streamline = 1;
+ } elsif ($subcommand =~ /--no-host-reboot/) {
+ $nohost_reboot = 1;
} else {
$update_file = $subcommand;
}
@@ -1114,10 +1549,13 @@ sub parse_command_status {
my $file_id = undef;
my $grep_cmd = "/usr/bin/grep -a";
+ my $tr_cmd = "/usr/bin/tr";
+ my $sha512sum_cmd = "/usr/bin/sha512sum";
my $version_tag = '"^version="';
my $purpose_tag = '"purpose="';
my $purpose_value;
my $version_value;
+
if (defined $update_file) {
# Filename or file id was specified
if ($update_file =~ /.*\.tar$/) {
@@ -1131,7 +1569,7 @@ sub parse_command_status {
}
# Verify file exists and is readable
unless (-r $::UPLOAD_FILE) {
- xCAT::SvrUtils::sendmsg([1,"Cannot access $::UPLOAD_FILE"], $callback);
+ xCAT::SvrUtils::sendmsg([1,"Cannot access $::UPLOAD_FILE. Check the management node and/or service nodes."], $callback);
return 1;
}
if ($activate) {
@@ -1153,12 +1591,79 @@ sub parse_command_status {
$purpose_value = "Host";
}
$::UPLOAD_FILE_VERSION = $version_value;
+ if (-x $sha512sum_cmd && -x $tr_cmd) {
+ # Save hash id this firmware version should resolve to:
+ # take version string, get rid of newline, run through sha512sum, take first 8 characters
+ $::UPLOAD_FILE_HASH_ID = substr(`echo $::UPLOAD_FILE_VERSION | $tr_cmd -d '\n' | $sha512sum_cmd`, 0,8);
+ }
+ else {
+ if ($::VERBOSE) {
+ xCAT::SvrUtils::sendmsg("WARN: No hashing check being done. ($sha512sum_cmd or $tr_cmd commands not found)
+", $callback);
+ }
+ }
}
if ($check_version) {
# 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)) {
+ my @tar_files = readdir(DIR);
+ foreach my $file (@tar_files) {
+ if ($file !~ /.*\.tar$/) {
+ next;
+ } else {
+ my $full_path_file = $update_file."/".$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`;
+ chomp($firmware_version_in_file);
+ chomp($purpose_version_in_file);
+ if (defined($firmware_version_in_file) and defined($purpose_version_in_file)) {
+ (my $purpose_string,$purpose_value) = split("=", $purpose_version_in_file);
+ (my $version_string,$version_value) = split("=", $firmware_version_in_file);
+ if ($purpose_value =~ /Purpose.BMC$/ and $version_string =~/version/){
+ $::UPLOAD_FILE = $full_path_file;
+ $::UPLOAD_FILE_VERSION = $version_value;
+ } elsif ($purpose_value =~ /Purpose.Host$/ and $version_value =~ /witherspoon/) {
+ $::UPLOAD_PNOR = $full_path_file;
+ $::UPLOAD_PNOR_VERSION = $version_value;
+ }
+ }
+ }
+ }
+ my $return_code = 0;
+ if (!$::UPLOAD_FILE) {
+ xCAT::SvrUtils::sendmsg([1,"No BMC tar file found in $update_file"], $callback);
+ $return_code = 1;
+ }
+ if (!$::UPLOAD_PNOR) {
+ xCAT::SvrUtils::sendmsg([1,"No PNOR tar file found in $update_file"], $callback);
+ $return_code = 1;
+ }
+ if ($return_code) {
+ return 1;
+ }
+ if ($streamline) {
+ $::UPLOAD_ACTIVATE_STREAM = 1;
+ if ($nohost_reboot) {
+ $::RFLASH_STREAM_NO_HOST_REBOOT = 1;
+ $nohost_reboot = 0;
+ }
+ $streamline = 0;
+ if (-x $sha512sum_cmd && -x $tr_cmd) {
+ # Save hash id this firmware version should resolve to:
+ $::UPLOAD_FILE_HASH_ID = substr(`echo $::UPLOAD_FILE_VERSION | $tr_cmd -d '\n' | $sha512sum_cmd`, 0,8);
+ $::UPLOAD_PNOR_HASH_ID = substr(`echo $::UPLOAD_PNOR_VERSION | $tr_cmd -d '\n' | $sha512sum_cmd`, 0,8);
+ }
+ else {
+ if ($::VERBOSE) {
+ xCAT::SvrUtils::sendmsg("WARN: No hashing check being done. ($sha512sum_cmd or $tr_cmd commands not found)
+", $callback);
+ }
+ }
+ }
}
else {
# Check if hex number for the updateid is passed
@@ -1171,6 +1676,11 @@ sub parse_command_status {
}
}
}
+ if ($upload or $::UPLOAD_AND_ACTIVATE) {
+ xCAT::SvrUtils::sendmsg("Attempting to upload $::UPLOAD_FILE, please wait...", $callback);
+ } elsif ($::UPLOAD_ACTIVATE_STREAM) {
+ xCAT::SvrUtils::sendmsg("Attempting to upload $::UPLOAD_FILE and $::UPLOAD_PNOR, please wait...", $callback);
+ }
if ($check_version) {
# Display firmware version on BMC
$next_status{LOGIN_RESPONSE} = "RINV_FIRM_REQUEST";
@@ -1210,13 +1720,48 @@ sub parse_command_status {
$next_status{"RFLASH_FILE_UPLOAD_REQUEST"} = "RFLASH_FILE_UPLOAD_RESPONSE";
$next_status{"RFLASH_FILE_UPLOAD_RESPONSE"} = "RFLASH_UPDATE_CHECK_ID_REQUEST";
$next_status{"RFLASH_UPDATE_CHECK_ID_REQUEST"} = "RFLASH_UPDATE_CHECK_ID_RESPONSE";
- #
- # This code is different from the "activate" flow above because the CHECK_ID_RESPONSE contains
- # the activation flow after we successfully obtain the ID for the firmware piece that was uploaded.
- #
+ $next_status{"RFLASH_UPDATE_CHECK_ID_RESPONSE"} = "RFLASH_UPDATE_ACTIVATE_REQUEST";
+ $next_status{"RFLASH_UPDATE_ACTIVATE_REQUEST"} = "RFLASH_UPDATE_ACTIVATE_RESPONSE";
+ $next_status{"RFLASH_UPDATE_ACTIVATE_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST";
+ $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";
}
+ if ($::UPLOAD_ACTIVATE_STREAM) {
+ $next_status{LOGIN_RESPONSE} = "RFLASH_FILE_UPLOAD_REQUEST";
+ $next_status{RFLASH_FILE_UPLOAD_REQUEST} = "RFLASH_FILE_UPLOAD_RESPONSE";
+ $next_status{RFLASH_FILE_UPLOAD_RESPONSE} = "RFLASH_UPDATE_CHECK_ID_REQUEST";
+ $next_status{RFLASH_UPDATE_CHECK_ID_REQUEST} = "RFLASH_UPDATE_CHECK_ID_RESPONSE";
+ $next_status{RFLASH_UPDATE_CHECK_ID_RESPONSE} = "RFLASH_UPDATE_ACTIVATE_REQUEST";
+ $next_status{RFLASH_UPDATE_ACTIVATE_REQUEST} = "RFLASH_UPDATE_ACTIVATE_RESPONSE";
+ $next_status{RFLASH_UPDATE_ACTIVATE_RESPONSE} = "RFLASH_UPDATE_HOST_ACTIVATE_REQUEST";
+ $next_status{RFLASH_UPDATE_HOST_ACTIVATE_REQUEST} = "RFLASH_UPDATE_HOST_ACTIVATE_RESPONSE";
+ $next_status{RFLASH_UPDATE_HOST_ACTIVATE_RESPONSE} = "RFLASH_UPDATE_CHECK_STATE_REQUEST";
+ $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";
+ $next_status{RPOWER_RESET_RESPONSE} = "RPOWER_BMC_CHECK_REQUEST";
+ $next_status{RPOWER_BMC_CHECK_REQUEST} = "RPOWER_BMC_STATUS_RESPONSE";
+ $next_status{LOGIN_REQUEST_GENERAL} = "LOGIN_RESPONSE_GENERAL";
+ $next_status{LOGIN_RESPONSE_GENERAL} = "RPOWER_BMC_STATUS_REQUEST";
+ $next_status{RPOWER_BMC_STATUS_REQUEST} = "RPOWER_BMC_STATUS_RESPONSE";
+ $status_info{RPOWER_BMC_STATUS_RESPONSE}{argv} = "bmcstate";
+ if (!$::RFLASH_STREAM_NO_HOST_REBOOT) {
+ $next_status{RPOWER_BMC_STATUS_RESPONSE} = "RPOWER_OFF_REQUEST";
+ $next_status{RPOWER_OFF_REQUEST} = "RPOWER_OFF_RESPONSE";
+ $next_status{RPOWER_OFF_RESPONSE} = "RPOWER_CHECK_REQUEST";
+ $next_status{RPOWER_CHECK_REQUEST} = "RPOWER_CHECK_RESPONSE";
+ $next_status{RPOWER_CHECK_RESPONSE}{ON} = "RPOWER_CHECK_REQUEST";
+ $next_status{RPOWER_CHECK_RESPONSE}{OFF} = "RPOWER_ON_REQUEST";
+ $next_status{RPOWER_ON_REQUEST} = "RPOWER_ON_RESPONSE";
+ $status_info{RPOWER_ON_RESPONSE}{argv} = "boot";
+ }
+ }
}
-
return;
}
@@ -1241,7 +1786,7 @@ sub fork_process_login {
sleep(1);
$rst = 1;
} elsif ($child == 0) {
- exit(login_logout_request($node));
+ exit(login_request($node));
} else {
$login_pid_node{$child} = $node;
}
@@ -1303,12 +1848,19 @@ sub parse_node_info {
if (defined($openbmc_hash->{$node}->[0])) {
if ($openbmc_hash->{$node}->[0]->{'bmc'}) {
$node_info{$node}{bmc} = $openbmc_hash->{$node}->[0]->{'bmc'};
- } else {
+ $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);
$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}) {
@@ -1332,7 +1884,9 @@ sub parse_node_info {
}
$node_info{$node}{cur_status} = "LOGIN_REQUEST";
- $node_info{$node}{retry_times} = 0;
+ $node_info{$node}{rpower_check_times} = $::RPOWER_MAX_RETRY;
+ $node_info{$node}{bmc_conn_check_times} = $::BMC_MAX_RETRY;
+ $node_info{$node}{bmcstate_check_times} = $::BMC_MAX_RETRY;
} else {
xCAT::SvrUtils::sendmsg("Error: Unable to get information from openbmc table", $callback, $node);
$rst = 1;
@@ -1365,7 +1919,7 @@ sub gen_send_request {
my $node = shift;
my $method;
my $request_url;
- my $content;
+ my $content = "";
if ($node_info{$node}{method}) {
$method = $node_info{$node}{method};
@@ -1379,6 +1933,12 @@ sub gen_send_request {
} elsif ($status_info{ $node_info{$node}{cur_status} }{data} =~ /^\[\]$/) {
# Special handling of empty data list
$content = '{"data":[]}';
+ } elsif ($status_info{ $node_info{$node}{cur_status} }{data} =~ /^\[.+\]$/) {
+ $content = '{"data":' . $status_info{ $node_info{$node}{cur_status} }{data} . '}';
+ } elsif (($status_info{ $node_info{$node}{cur_status} }{init_url} =~ /config\/attr\/HostName$/) &&
+ ($status_info{ $node_info{$node}{cur_status} }{data} =~ /^\*$/)) {
+ # Special handling for hostname=*
+ $content = '{"data":"' . $node_info{$node}{bmc} . '"}';
} else {
$content = '{"data":"' . $status_info{ $node_info{$node}{cur_status} }{data} . '"}';
}
@@ -1396,11 +1956,15 @@ sub gen_send_request {
if ($method eq "GET") {
$debug_info = "curl -k -b cjar -X $method -H \"Content-Type: application/json\" $request_url";
} else {
- if ($::UPLOAD_FILE) {
+ if ($::UPLOAD_FILE and !$::UPLOAD_ACTIVATE_STREAM) {
# Slightly different debug message when doing a file upload
$debug_info = "curl -k -b cjar -X $method -H \"Content-Type: application/json\" -T $::UPLOAD_FILE $request_url";
} else {
- $debug_info = "curl -k -b cjar -X $method -H \"Content-Type: application/json\" -d '$content' $request_url";
+ if ($node_info{$node}{cur_status} eq "LOGIN_REQUEST_GENERAL") {
+ $debug_info = "curl -k -c cjar -H \"Content-Type: application/json\" -d '{ \"data\": [\"$node_info{$node}{username}\", \"xxxxxx\"] }' $request_url";
+ } else {
+ $debug_info = "curl -k -b cjar -X $method -H \"Content-Type: application/json\" -d '$content' $request_url";
+ }
}
}
process_debug_info($node, $debug_info);
@@ -1446,6 +2010,11 @@ 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$/) {
+ 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) {
@@ -1466,38 +2035,49 @@ sub deal_with_response {
$error = $::RESPONSE_SERVICE_TIMEOUT;
} else {
my $response_info = decode_json $response->content;
+ # Handle 500
if ($response->status_line eq $::RESPONSE_SERVER_ERROR) {
- $error = $response_info->{'data'}->{'exception'};
+ $error = "[" . $response->code . "] " . $response_info->{'data'}->{'exception'};
+ # Handle 403
} elsif ($response->status_line eq $::RESPONSE_FORBIDDEN) {
#
# For any invalid data that we can detect, provide a better response message
#
- if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_ACTIVATE_RESPONSE") {
+ if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_ACTIVATE_RESPONSE" or $node_info{$node}{cur_status} eq "RFLASH_UPDATE_HOST_ACTIVATE_RESPONSE") {
# If 403 is received for an activation, that means the activation ID is incorrect
$error = "Invalid ID provided to activate. Use the -l option to view valid firmware IDs.";
} 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 {
$error = "$::RESPONSE_FORBIDDEN - Requested endpoint does not exists and may indicate function is not yet supported by OpenBMC firmware.";
}
- } elsif ($response_info->{'data'}->{'description'} =~ /path or object not found: (.+)/) {
+ # Handle 404
+ } elsif ($response->status_line eq $::RESPONSE_NOT_FOUND) {
#
# For any invalid data that we can detect, provide a better response message
#
if ($node_info{$node}{cur_status} eq "RFLASH_DELETE_IMAGE_RESPONSE") {
$error = "Invalid ID provided to delete. Use the -l option to view valid firmware IDs.";
} else {
- $error = "Path or object not found: $1";
+ $error = "[" . $response->code . "] " . $response_info->{'data'}->{'description'};
}
} else {
- $error = $response_info->{'data'}->{'description'};
+ $error = "[" . $response->code . "] " . $response_info->{'data'}->{'description'};
}
}
- xCAT::SvrUtils::sendmsg([1, $error], $callback, $node);
- $wait_node_num--;
- return;
+ if (!($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_CLEAR_RESPONSE" and $next_status{ $node_info{$node}{cur_status} })) {
+ xCAT::SvrUtils::sendmsg([1, $error], $callback, $node);
+ if ($::UPLOAD_AND_ACTIVATE or $next_status{LOGIN_RESPONSE} eq "RFLASH_UPDATE_ACTIVATE_REQUEST") {
+ $node_info{$node}{rst} = $error;
+ my $rflash_log_file = xCAT::Utils->full_path($node.".log", $::XCAT_LOG_RFLASH_DIR);
+ open (RFLASH_LOG_FILE_HANDLE, ">> $rflash_log_file");
+ print RFLASH_LOG_FILE_HANDLE "$error\n";
+ close (RFLASH_LOG_FILE_HANDLE);
+ }
+ $wait_node_num--;
+ return;
+ }
}
if ($status_info{ $node_info{$node}{cur_status} }->{process}) {
@@ -1526,6 +2106,9 @@ sub process_debug_info {
my $node = shift;
my $debug_msg = shift;
my $ts_node = localtime() . " " . $node;
+ if (!$debug_msg) {
+ $debug_msg = "";
+ }
xCAT::SvrUtils::sendmsg("$flag_debug $debug_msg", $callback, $ts_node);
xCAT::MsgUtils->trace(0, "D", "$flag_debug $node $debug_msg");
@@ -1533,7 +2116,7 @@ sub process_debug_info {
#-------------------------------------------------------
-=head3 login_logout_request
+=head3 login_request
Send login request using curl command
Input:
@@ -1542,27 +2125,25 @@ sub process_debug_info {
=cut
#-------------------------------------------------------
-sub login_logout_request {
+sub login_request {
my $node = shift;
- my $request_url = "$http_protocol://" . $node_info{$node}{bmc};
- my $content_login = '{ "data": [ "' . $node_info{$node}{username} .'", "' . $node_info{$node}{password} . '" ] }';
- my $content_logout = '{ "data": [ ] }';
- my $cjar_id = "/tmp/_xcat_cjar.$node";
+ my $login_url = "$http_protocol://" . $node_info{$node}{bmc} . "/login";
+ my $data = '{ "data": [ "' . $node_info{$node}{username} .'", "' . $node_info{$node}{password} . '" ] }';
- 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 . "'";
+ my $brower = LWP::UserAgent->new( ssl_opts => { SSL_verify_mode => 0x00, verify_hostname => 0 }, timeout => 20);
+ my $cookie_jar = HTTP::Cookies->new();
+ my $header = HTTP::Headers->new('Content-Type' => 'application/json');
+ $brower->cookie_jar($cookie_jar);
- my $curl_login_result = `$curl_login_cmd -s -m 10`;
+ my $login_request = HTTP::Request->new( 'POST', $login_url, $header, $data );
+ my $login_response = $brower->request($login_request);
- unless ($curl_login_result) {
- if ($xcatdebugmode) {
- my $debug_info = "LOGIN Failed using curl command";
- process_debug_info($node, $debug_info);
- }
+ # Check the return code
+ if ($login_response->code eq 500 or $login_response->code eq 404) {
+ # handle only 404 and 504 in this code, defer to deal_with_response for the rest
+ xCAT::SvrUtils::sendmsg([1 ,"[" . $login_response->code . "] Login to BMC failed: " . $login_response->status_line . "."], $callback, $node);
return 1;
- } else {
- my $curl_logout_result = `$curl_logout_cmd`;
}
return 0;
@@ -1610,7 +2191,6 @@ sub rpower_response {
my $node = shift;
my $response = shift;
my %new_status = ();
- my $max_retry_times = 5;
my $response_info = decode_json $response->content;
@@ -1645,6 +2225,10 @@ sub rpower_response {
if ($response_info->{'message'} eq $::RESPONSE_OK) {
if (defined $status_info{RPOWER_RESET_RESPONSE}{argv} and $status_info{RPOWER_RESET_RESPONSE}{argv} =~ /bmcreboot$/) {
xCAT::SvrUtils::sendmsg("BMC $::POWER_STATE_REBOOT", $callback, $node);
+ if ($::UPLOAD_ACTIVATE_STREAM) {
+ retry_after($node, "RPOWER_BMC_CHECK_REQUEST", 15);
+ return;
+ }
}
$new_status{$::STATUS_POWERING_ON} = [$node];
}
@@ -1653,7 +2237,7 @@ sub rpower_response {
xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%new_status, 1) if (%new_status);
my $all_status;
- if ($node_info{$node}{cur_status} eq "RPOWER_STATUS_RESPONSE" or $node_info{$node}{cur_status} eq "RPOWER_CHECK_RESPONSE") {
+ if ($node_info{$node}{cur_status} eq "RPOWER_STATUS_RESPONSE" or $node_info{$node}{cur_status} eq "RPOWER_CHECK_RESPONSE" or $node_info{$node}{cur_status} eq "RPOWER_BMC_STATUS_RESPONSE") {
my $bmc_state = "";
my $bmc_transition_state = "";
my $chassis_state = "";
@@ -1684,11 +2268,32 @@ sub rpower_response {
print "$node: DEBUG State CurrentHostState=$host_state\n";
print "$node: DEBUG State RequestedHostTransition=$host_transition_state\n";
}
-
if (defined $status_info{RPOWER_STATUS_RESPONSE}{argv} and $status_info{RPOWER_STATUS_RESPONSE}{argv} =~ /bmcstate$/) {
my $bmc_short_state = (split(/\./, $bmc_state))[-1];
xCAT::SvrUtils::sendmsg("BMC $bmc_short_state", $callback, $node);
- } else {
+ } elsif ($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$/) {
+ my $bmc_short_state = (split(/\./, $bmc_state))[-1];
+ if (defined($bmc_state) and $bmc_state !~ /State.BMC.BMCState.Ready$/) {
+ if ($node_info{$node}{bmcstate_check_times} > 0) {
+ $node_info{$node}{bmcstate_check_times}--;
+ if ($node_info{$node}{wait_start}) {
+ $node_info{$node}{wait_end} = time();
+ } else {
+ $node_info{$node}{wait_start} = time();
+ }
+ retry_after($node, "RPOWER_BMC_STATUS_REQUEST", $::BMC_CHECK_INTERVAL);
+ return;
+ } else {
+ my $wait_time_X = $node_info{$node}{wait_end} - $node_info{$node}{wait_start};
+ xCAT::SvrUtils::sendmsg([1, "Error: Sent bmcreboot but state did not change to BMC Ready after waiting $wait_time_X seconds. (State=BMC $bmc_short_state)."], $callback, $node);
+ $node_info{$node}{cur_status} = "";
+ $wait_node_num--;
+ return;
+ }
+ }
+ xCAT::SvrUtils::sendmsg("BMC $bmc_short_state", $callback, $node);
+
+ }else {
if ($chassis_state =~ /Off$/) {
# Chassis state is Off, but check if we can detect transition states
if ((defined($::OPENBMC_PWR) and ($::OPENBMC_PWR eq "YES")) and
@@ -1730,10 +2335,18 @@ sub rpower_response {
if ($all_status eq "$::POWER_STATE_OFF") {
$node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }{OFF};
} else {
- $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }{ON};
- $node_info{$node}{retry_times}++;
- if ($node_info{$node}{retry_times} >= $max_retry_times) {
- xCAT::SvrUtils::sendmsg("Internal Error, failed to rpower off, please try again", $callback, $node);
+ if ($node_info{$node}{rpower_check_times} > 0) {
+ $node_info{$node}{rpower_check_times}--;
+ if ($node_info{$node}{wait_start}) {
+ $node_info{$node}{wait_end} = time();
+ } else {
+ $node_info{$node}{wait_start} = time();
+ }
+ retry_after($node, $next_status{ $node_info{$node}{cur_status} }{ON}, $::RPOWER_CHECK_INTERVAL);
+ return;
+ } else {
+ my $wait_time_X = $node_info{$node}{wait_end} - $node_info{$node}{wait_start};
+ xCAT::SvrUtils::sendmsg([1, "Error: Sent power-off command but state did not change to $::POWER_STATE_OFF after waiting $wait_time_X seconds. (State=$all_status)."], $callback, $node);
$node_info{$node}{cur_status} = "";
$wait_node_num--;
return;
@@ -1787,6 +2400,7 @@ sub rinv_response {
my $src;
my $content_info;
my @sorted_output;
+ my $to_clear_dump = 0;
# Get the functional IDs to accurately mark the active running FW
my $functional = get_functional_software_ids($response_info);
@@ -1799,12 +2413,25 @@ sub rinv_response {
my $sw_id = (split(/\//, $key_url))[-1];
if (defined($content{Version}) and $content{Version}) {
my $purpose_value = uc ((split(/\./, $content{Purpose}))[-1]);
- $purpose_value = "[$sw_id]$purpose_value";
+ if ($purpose_value =~ /BMC/) {
+ $purpose_value = "[B$sw_id]$purpose_value";
+ } else {
+ $purpose_value = "[H$sw_id]$purpose_value";
+ }
my $activation_value = (split(/\./, $content{Activation}))[-1];
my $priority_value = -1;
if (defined($content{Priority})) {
$priority_value = $content{Priority};
}
+
+ if ($status_info{RINV_FIRM_RESPONSE}{check}) {
+ if (($purpose_value =~ /BMC/) and
+ ($priority_value == 0 and %{$functional} and !exists($functional->{$sw_id}))) {
+ $to_clear_dump = 1;
+ last;
+ }
+ }
+
#
# For 'rinv firm', only print Active software, unless verbose is specified
#
@@ -1816,10 +2443,12 @@ sub rinv_response {
# to cause the sorting of this line before any additional info lines
#
$content_info = "$purpose_value Firmware Product: $content{Version} ($activation_value)";
- my $indicator = "*";
+ my $indicator = "";
if ($priority_value == 0 and %{$functional} and !exists($functional->{$sw_id})) {
# indicate that a reboot is needed if priority = 0 and it's not in the functional list
$indicator = "+";
+ } elsif (%{$functional} and exists($functional->{$sw_id})) {
+ $indicator = "*";
}
$content_info .= $indicator;
push (@sorted_output, $content_info);
@@ -1866,25 +2495,38 @@ sub rinv_response {
}
}
}
- # If sorted array has any contents, sort it and print it
+ @sorted_output = () if ($status_info{RINV_FIRM_RESPONSE}{check});
+ # If sorted array has any contents, sort it naturally and print it
if (scalar @sorted_output > 0) {
# sort alpha, then numeric
- my @sorted_output = grep {s/(^|\D)0+(\d)/$1$2/g,1} sort
- grep {s/(\d+)/sprintf"%06.6d",$1/ge,1} @sorted_output;
- foreach (@sorted_output) {
+ foreach (sort natural_sort_cmp @sorted_output) {
#
# The firmware output requires the ID to be part of the string to sort correctly.
# Remove this ID from the output to the user
#
$_ =~ s/\[.*?\]//;
- xCAT::SvrUtils::sendmsg("$_", $callback, $node);
+ xCAT::MsgUtils->message("I", { data => ["$node: $_"] }, $callback);
}
} else {
- xCAT::SvrUtils::sendmsg("$::NO_ATTRIBUTES_RETURNED", $callback, $node);
+ if ($status_info{RINV_FIRM_RESPONSE}{check}) {
+ if ($to_clear_dump) {
+ xCAT::MsgUtils->message("I", { data => ["$node: Firmware will be flashed on reboot, deleting all BMC diagnostics..."] }, $callback);
+ }
+ } else {
+ xCAT::MsgUtils->message("I", { data => ["$node: $::NO_ATTRIBUTES_RETURNED"] }, $callback);
+ }
}
if ($next_status{ $node_info{$node}{cur_status} }) {
- $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
+ if ($status_info{RINV_FIRM_RESPONSE}{check}) {
+ if ($to_clear_dump) {
+ $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }{PENDING};
+ } else {
+ $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }{NO_PENDING}
+ }
+ } else {
+ $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
+ }
gen_send_request($node);
} else {
$wait_node_num--;
@@ -2042,42 +2684,27 @@ sub reventlog_response {
xCAT::SvrUtils::sendmsg("clear", $callback, $node);
}
} else {
- my ($entry_string, $option_s) = split(",", $status_info{REVENTLOG_RESPONSE}{argv});
+ my $entry_string = $status_info{REVENTLOG_RESPONSE}{argv};
my $content_info;
my %output = ();
my $entry_num = 0;
$entry_string = "all" if ($entry_string eq "0");
$entry_num = 0 + $entry_string if ($entry_string ne "all");
+ my $max_entry = 0;
foreach my $key_url (keys %{$response_info->{data}}) {
my %content = %{ ${ $response_info->{data} }{$key_url} };
- my $timestamp = $content{Timestamp};
- my $id_num = 0 + $content{Id} if ($content{Id});
- if ($content{Message}) {
- my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($content{Timestamp}/1000);
- $mon += 1;
- $year += 1900;
- my $UTC_time = sprintf ("%02d/%02d/%04d %02d:%02d:%02d", $mon, $mday, $year, $hour, $min, $sec);
- my $content_info = $UTC_time . " [$content{Id}] " . $content{Message};
- $output{$timestamp} = $content_info;
- }
+ next unless ($content{Id});
+ my $id_num = 0 + $content{Id};
+ my $event_msg = parse_event_data(\%content);
+ $output{$id_num} = $event_msg if ($event_msg);
+ $max_entry = $id_num if ($id_num > $max_entry);
}
- my $count = 0;
- if ($option_s) {
- xCAT::SvrUtils::sendmsg("$::NO_ATTRIBUTES_RETURNED", $callback, $node) if (!%output);
- foreach my $key ( sort { $b <=> $a } keys %output) {
- xCAT::MsgUtils->message("I", { data => ["$node: $output{$key}"] }, $callback) if ($output{$key});
- $count++;
- last if ($entry_string ne "all" and $count >= $entry_num);
- }
- } else {
- xCAT::SvrUtils::sendmsg("$::NO_ATTRIBUTES_RETURNED", $callback, $node) if (!%output);
- foreach my $key (sort keys %output) {
- xCAT::MsgUtils->message("I", { data => ["$node: $output{$key}"] }, $callback) if ($output{$key});
- $count++;
- last if ($entry_string ne "all" and $count >= $entry_num);
- }
+ xCAT::SvrUtils::sendmsg("$::NO_ATTRIBUTES_RETURNED", $callback, $node) if (!%output);
+ # If option is "all", print out all sorted msg. If is a num, print out the last msg (sorted)
+ foreach my $key ( sort { $a <=> $b } keys %output) {
+ xCAT::MsgUtils->message("I", { data => ["$node: $output{$key}"] }, $callback) if ($entry_string eq "all" or $key > ($max_entry - $entry_num));
}
}
@@ -2091,6 +2718,82 @@ sub reventlog_response {
#-------------------------------------------------------
+=head3 parse_event_data
+
+ Parse reventlog data
+ Input:
+ $content: data for single entry
+
+=cut
+
+#-------------------------------------------------------
+sub parse_event_data {
+ my $content = shift;
+ my $content_info = "";
+
+ my $timestamp = $$content{Timestamp};
+ my $id_num = $$content{Id};
+ if ($$content{Message}) {
+ my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($$content{Timestamp}/1000);
+ $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 $callout;
+ my $msg_pid;
+ my $i2c_device;
+ my $esel;
+
+ if (defined $$content{AdditionalData} and $$content{AdditionalData}) {
+ foreach my $addition (@{ $$content{AdditionalData} }) {
+ if ($addition =~ /CALLOUT_INVENTORY_PATH=(.+)/) {
+ $callout = $1;
+ }
+ if ($addition =~ /CALLOUT_DEVICE_PATH/) {
+ $callout = "I2C";
+ my @info = split("=", $addition);
+ my $tmp = $info[1];
+ my @tmp_data = split("/", $tmp);
+ my $data_num = @tmp_data;
+ $i2c_device = join("/", @tmp_data[($data_num-4)..($data_num-1)])
+ }
+ if ($addition =~ /ESEL/) {
+ my @info = split("=", $addition);
+ $esel = $info[1];
+ # maybe useful, so leave it here
+ }
+ if ($addition =~ /GPU/) {
+ my @info = split(" ", $addition);
+ $callout = "/xyz/openbmc_project/inventory/system/chassis/motherboard/gpu" . $info[-1];
+ }
+ if ($addition =~ /PID=(\d*)/) {
+ $msg_pid = $1;
+ }
+ }
+ }
+
+ $messgae .= "||$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};
+ $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}";
+ }
+ } else {
+ $content_info = "$UTC_time [$id_num]: $messgae (PID: $msg_pid), Resolved: $$content{Resolved}";
+ }
+ }
+
+ return $content_info;
+}
+
+#-------------------------------------------------------
+
=head3 rspconfig_response
Deal with response of rspconfig command
@@ -2105,19 +2808,14 @@ sub rspconfig_response {
my $node = shift;
my $response = shift;
- my $response_info = decode_json $response->content;
+ my $response_info;
+ $response_info = decode_json $response->content if ($response);
if ($node_info{$node}{cur_status} eq "RSPCONFIG_GET_RESPONSE") {
- my $address = "n/a";
- my $gateway = "n/a";
- my $prefix = "n/a";
- my $vlan = 0;
my $hostname = "";
my $default_gateway = "n/a";
- my $adapter_id = "n/a";
- my $ipsrc = "n/a";
+ my %nicinfo = ();
my $error;
- my $path;
my @output;
my $grep_string = $status_info{RSPCONFIG_GET_RESPONSE}{argv};
foreach my $key_url (keys %{$response_info->{data}}) {
@@ -2132,72 +2830,214 @@ sub rspconfig_response {
}
}
-
- ($path, $adapter_id) = (split(/\/ipv4\//, $key_url));
+ my ($path, $adapter_id) = (split(/\/ipv4\//, $key_url));
if ($adapter_id) {
+ if ( (defined($content{Origin}) and $content{Origin} =~ /LinkLocal/) or
+ (defined($content{Address}) and $content{Address} =~ /^169.254/) ) {
+ # OpenBMC driver has a interim bug where ZeroConfigIP comes up as DHCP instead of LinkLocal.
+ # To protect xCAT while the drivers change, check the 169.254 IP also
+ if ($xcatdebugmode) {
+ my $debugmsg = "Found LocalLink " . $content{Address} . " for interface " . $key_url . " Ignoring...";
+ process_debug_info($node, $debugmsg);
+ }
+ next;
+ }
+ my $nic = $path;
+ $nic =~ s/(.*\/)//g;
+ unless (defined($nicinfo{$nic}{address})) {
+ $nicinfo{$nic}{address} = "n/a";
+ $nicinfo{$nic}{gateway} = "n/a";
+ $nicinfo{$nic}{ipsrc} = "n/a";
+ $nicinfo{$nic}{netmask} = "n/a";
+ $nicinfo{$nic}{prefix} = "n/a";
+ $nicinfo{$nic}{vlan} = "Disable";
+ }
+
+
if (defined($content{Address}) and $content{Address}) {
- unless ($address =~ /n\/a/) {
+ unless ($nicinfo{$nic}{address} =~ /n\/a/) {
# We have already processed an entry with adapter information.
# This must be a second entry. Display an error. Currently only supporting
# an adapter with a single IP address set.
$error = "Interfaces with multiple IP addresses are not supported";
- last;
+ $node_info{$node}{cur_status} = "";
+ # Terminate loop on this error unless we are looking for hostname to display
+ last unless ($grep_string =~ /(.*)hostname(.*)/);
}
- $address = $content{Address};
+ $nicinfo{$nic}{address} = $content{Address};
}
if (defined($content{Gateway}) and $content{Gateway}) {
- $gateway = $content{Gateway};
+ $nicinfo{$nic}{gateway} = $content{Gateway};
}
if (defined($content{PrefixLength}) and $content{PrefixLength}) {
- $prefix = $content{PrefixLength};
+ $nicinfo{$nic}{prefix} = $content{PrefixLength};
}
if (defined($content{Origin})) {
- $ipsrc = $content{Origin};
- $ipsrc =~ s/^.*\.(\w+)/$1/;
+ $nicinfo{$nic}{ipsrc} = $content{Origin};
+ $nicinfo{$nic}{ipsrc} =~ s/^.*\.(\w+)/$1/;
}
if (defined($response_info->{data}->{$path}->{Id})) {
- $vlan = $response_info->{data}->{$path}->{Id};
+ $nicinfo{$nic}{vlan} = $response_info->{data}->{$path}->{Id};
}
}
}
+ if ($grep_string =~ /(.*)hostname(.*)/) {
+ xCAT::SvrUtils::sendmsg("BMC hostname: $hostname", $callback, $node);
+ unless ($1 or $2) {
+ $wait_node_num--;
+ return;
+ }
+ }
+ if (scalar (keys %nicinfo) == 0) {
+ $error = "No valid BMC network information";
+ $node_info{$node}{cur_status} = "";
+ }
if ($error) {
- # Display error message once, regardless of how many subcommands were specified
- push @output, $error;
- }
- else {
+ xCAT::SvrUtils::sendmsg([1,"$error"], $callback, $node);
+ } else {
+ my @address = ();
+ my @ipsrc = ();
+ my @netmask = ();
+ my @gateway = ();
+ my @vlan = ();
+ my @nics = keys %nicinfo;
+ foreach my $nic (@nics) {
+ my $addon_info = '';
+ if ($#nics > 1) {
+ $addon_info = " for $nic";
+ }
+ push @address, "BMC IP$addon_info: $nicinfo{$nic}{address}";
+ push @ipsrc, "BMC IP Source$addon_info: $nicinfo{$nic}{ipsrc}";
+ if ($nicinfo{$nic}{address}) {
+ my $mask_shift = 32 - $nicinfo{$nic}{prefix};
+ my $decimal_mask = (2 ** $nicinfo{$nic}{prefix} - 1) << $mask_shift;
+ push @netmask, "BMC Netmask$addon_info: " . join('.', unpack("C4", pack("N", $decimal_mask)));
+ }
+ push @gateway, "BMC Gateway$addon_info: $nicinfo{$nic}{gateway} (default: $default_gateway)";
+ push @vlan, "BMC VLAN ID$addon_info: $nicinfo{$nic}{vlan}";
+ }
foreach my $opt (split /,/,$grep_string) {
if ($opt eq "ip") {
- push @output, "BMC IP: $address";
+ push @output, @address;
} elsif ($opt eq "ipsrc") {
- push @output, "BMC IP Source: $ipsrc";
+ push @output, @ipsrc;
} elsif ($opt eq "netmask") {
- if ($address) {
- my $decimal_mask = (2 ** $prefix - 1) << (32 - $prefix);
- my $netmask = join('.', unpack("C4", pack("N", $decimal_mask)));
- push @output, "BMC Netmask: " . $netmask;
- }
+ push @output, @netmask;
} elsif ($opt eq "gateway") {
- push @output, "BMC Gateway: $gateway (default: $default_gateway)";
+ push @output, @gateway;
} elsif ($opt eq "vlan") {
- if ($vlan) {
- push @output, "BMC VLAN ID: $vlan";
- } else {
- push @output, "BMC VLAN ID: Disabled";
+ push @output, @vlan;
+ }
+ }
+ xCAT::SvrUtils::sendmsg("$_", $callback, $node) foreach (@output);
+
+ if ($grep_string eq "all") {
+ # If all current values equal the input, just print out message
+ my @checks = split("-", $status_info{RSPCONFIG_CHECK_RESPONSE}{argv});
+ my $check_num = @checks;
+ my $check_vlan;
+ if ($check_num == 4) {
+ $check_vlan = shift @checks;
+ }
+ my ($check_ip,$check_netmask,$check_gateway) = @checks;
+ my $the_nic_to_config = undef;
+ foreach my $nic (@nics) {
+ my $address = $nicinfo{$nic}{address};
+ my $prefix = $nicinfo{$nic}{prefix};
+ my $gateway = $nicinfo{$nic}{gateway};
+ if ($check_ip eq $address and $check_netmask eq $prefix and $check_gateway eq $gateway) {
+ if (($check_vlan and $check_vlan eq $nicinfo{$nic}{vlan}) or !$check_vlan) {
+ $next_status{ $node_info{$node}{cur_status} } = "RSPCONFIG_PRINT_BMCINFO";
+ $the_nic_to_config = $nic;
+ last;
+ }
}
- } elsif ($opt eq "hostname") {
- push @output, "BMC Hostname: $hostname";
+ # Only deal with the nic whose IP matching the BMC IP configured for the node
+ if ($address eq $node_info{$node}{bmcip}) {
+ $the_nic_to_config = $nic;
+ last;
+ }
+ }
+ if (!defined($the_nic_to_config)) {
+ xCAT::SvrUtils::sendmsg("Can not find the correct device to configure", $callback, $node);
+ $wait_node_num--;
+ return;
+ } else {
+ my $next_state = $next_status{ $node_info{$node}{cur_status} };
+ # To create an Object with vlan tag, shall be operated to the eth0
+ if ($next_state eq "RSPCONFIG_VLAN_REQUEST") {
+ $the_nic_to_config =~ s/(\_\d*)//g;
+ $status_info{$next_state}{data} =~ s/#NIC#/$the_nic_to_config/g;
+ }
+ $status_info{RSPCONFIG_IPOBJECT_REQUEST}{init_url} =~ s/#NIC#/$the_nic_to_config/g;
+ $node_info{$node}{nic} = $the_nic_to_config;
}
}
}
+ }
+
+ my $origin_type;
+ if ($node_info{$node}{cur_status} eq "RSPCONFIG_CHECK_RESPONSE") {
+ my @checks = split("-", $status_info{RSPCONFIG_CHECK_RESPONSE}{argv});
+ my $check_num = @checks;
+ my $check_vlan;
+ if ($check_num == 4) {
+ $check_vlan = shift @checks;
+ }
+ my ($check_ip,$check_netmask,$check_gateway) = @checks;
+ my $check_result = 0;
+ foreach my $key_url (keys %{$response_info->{data}}) {
+ my %content = %{ ${ $response_info->{data} }{$key_url} };
+ my ($path, $adapter_id) = (split(/\/ipv4\//, $key_url));
+ if ($adapter_id) {
+ if (defined($content{Address}) and $content{Address}) {
+ if ($content{Address} eq $node_info{$node}{bmcip}) {
+ if ($content{Origin} =~ /Static/) {
+ $origin_type = "STATIC";
+ $status_info{RSPCONFIG_DELETE_REQUEST}{init_url} = "$key_url";
+ } else {
+ $origin_type = "DHCP";
+ my $nic = $path;
+ $nic =~ s/(.*\/)//g;
+ $status_info{RSPCONFIG_DHCPDIS_REQUEST}{init_url} =~ s/#NIC#/$nic/g
+ }
+ } else {
+ if (($content{Address} eq $check_ip) and
+ ($content{PrefixLength} eq $check_netmask) and
+ ($content{Gateway} eq $check_gateway)) {
+ if ($check_vlan) {
+ if (defined($response_info->{data}->{$path}->{Id}) and $response_info->{data}->{$path}->{Id} eq $check_vlan) {
+ $check_result = 1;
+ }
+ } else {
+ $check_result = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (!$check_result or !$origin_type) {
+ xCAT::SvrUtils::sendmsg("Config IP failed", $callback, $node);
+ $next_status{ $node_info{$node}{cur_status} } = "";
+ }
+ }
- xCAT::SvrUtils::sendmsg("$_", $callback, $node) foreach (@output);
+ if ($node_info{$node}{cur_status} eq "RSPCONFIG_PASSWD_VERIFY") {
+ if ($status_info{RSPCONFIG_PASSWD_VERIFY}{argv} ne $node_info{$node}{password}) {
+ xCAT::SvrUtils::sendmsg("Current BMC password is incorrect, cannot set the new password.", $callback, $node);
+ $wait_node_num--;
+ return;
+ }
}
if ($node_info{$node}{cur_status} eq "RSPCONFIG_SET_RESPONSE") {
if ($response_info->{'message'} eq $::RESPONSE_OK) {
- xCAT::SvrUtils::sendmsg("BMC Setting Hostname...", $callback, $node);
+ if (defined $status_info{RSPCONFIG_SET_RESPONSE}{argv}) {
+ xCAT::SvrUtils::sendmsg("BMC Setting $status_info{RSPCONFIG_SET_RESPONSE}{argv}...", $callback, $node);
+ }
}
}
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DHCP_RESPONSE") {
@@ -2206,9 +3046,40 @@ sub rspconfig_response {
}
}
+ if ($node_info{$node}{cur_status} eq "RSPCONFIG_PRINT_BMCINFO") {
+ if ($status_info{RSPCONFIG_PRINT_BMCINFO}{data}) {
+ my @output = split(",", $status_info{RSPCONFIG_PRINT_BMCINFO}{data});
+ xCAT::SvrUtils::sendmsg($_, $callback, $node) foreach (@output);
+ }
+ }
+
+ if ($node_info{$node}{cur_status} eq "RSPCONFIG_VLAN_RESPONSE") {
+ if ($xcatdebugmode) {
+ process_debug_info($node, "Wait $::RSPCONFIG_WAIT_VLAN_DONE seconds for interface with VLAN tag be ready");
+ }
+ retry_after($node, $next_status{ $node_info{$node}{cur_status} }, $::RSPCONFIG_WAIT_VLAN_DONE);
+ return;
+ }
+
+ if ($node_info{$node}{cur_status} eq "RSPCONFIG_IPOBJECT_RESPONSE") {
+ if ($xcatdebugmode) {
+ process_debug_info($node, "Wait $::RSPCONFIG_WAIT_IP_DONE seconds for the configuration done");
+ }
+ retry_after($node, $next_status{ $node_info{$node}{cur_status} }, $::RSPCONFIG_WAIT_IP_DONE);
+ return;
+ }
+
if ($next_status{ $node_info{$node}{cur_status} }) {
- $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
- gen_send_request($node);
+ if ($node_info{$node}{cur_status} eq "RSPCONFIG_CHECK_RESPONSE") {
+ $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} }{$origin_type};
+ } else {
+ $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
+ }
+ if ($node_info{$node}{cur_status} eq "RSPCONFIG_PRINT_BMCINFO") {
+ $status_info{ $node_info{$node}{cur_status} }->{process}->($node, "");
+ } else {
+ gen_send_request($node);
+ }
} else {
$wait_node_num--;
}
@@ -2236,6 +3107,7 @@ sub rspconfig_sshcfg_response {
xCAT::SvrUtils::sendmsg("Failed to fork child process for rspconfig sshcfg.", $callback, $node);
sleep(1)
} elsif ($child == 0) {
+ $async->remove_all;
exit(sshcfg_process($node))
} else {
$child_node_map{$child} = $node;
@@ -2301,6 +3173,203 @@ sub sshcfg_process {
return $rc;
}
+
+#-------------------------------------------------------
+
+=head3 rspconfig_dump_response
+
+ Deal with request and response of rspconfig command for dump subcommand.
+ Input:
+ $node: nodename of current response
+ $response: Async return response
+
+=cut
+
+#-------------------------------------------------------
+sub rspconfig_dump_response {
+ my $node = shift;
+ my $response = shift;
+
+ my $response_info = decode_json $response->content if (defined($response));
+
+ if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_LIST_RESPONSE" or $node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_CHECK_RESPONSE") {
+ my %dump_info = ();
+ my $gen_check = 0;
+ foreach my $key_url (keys %{$response_info->{data}}) {
+ my %content = %{ ${ $response_info->{data} }{$key_url} };
+ my $id;
+ if (defined $content{Elapsed}) {
+ $id = $key_url;
+ $id =~ s/.*\///g;
+
+ if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_CHECK_RESPONSE") {
+ if ($id eq $node_info{$node}{dump_id}) {
+ $gen_check = 1;
+ last;
+ }
+ next;
+ }
+
+ my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($content{Elapsed});
+ $mon += 1;
+ $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}";
+ }
+ }
+
+ 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 (!$gen_check and $node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_CHECK_RESPONSE") {
+ if (!exists($node_info{$node}{dump_wait_attemp})) {
+ $node_info{$node}{dump_wait_attemp} = $::RSPCONFIG_DUMP_MAX_RETRY;
+ }
+ if ( $node_info{$node}{dump_wait_attemp} > 0) {
+ $node_info{$node}{dump_wait_attemp} --;
+ retry_after($node, "RSPCONFIG_DUMP_LIST_REQUEST", $::RSPCONFIG_DUMP_INTERVAL);
+ unless ($node_info{$node}{dump_wait_attemp} % int(8)) { # display message every 8 iterations of the interval
+ xCAT::SvrUtils::sendmsg("Still waiting for dump $node_info{$node}{dump_id} to be generated...", $callback, $node);
+ }
+ return;
+ } else {
+ xCAT::SvrUtils::sendmsg([1,"Could not find dump $node_info{$node}{dump_id} after waiting $::RSPCONFIG_DUMP_WAIT_TOTALTIME seconds."], $callback, $node);
+ $wait_node_num--;
+ return;
+ }
+ }
+ }
+
+ if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_DOWNLOAD_REQUEST") {
+ my $child = xCAT::Utils->xfork;
+ if (!defined($child)) {
+ xCAT::SvrUtils::sendmsg("Failed to fork child process for rspconfig dump download.", $callback, $node);
+ sleep(1)
+ } elsif ($child == 0) {
+ $async->remove_all;
+ exit(dump_download_process($node))
+ } else {
+ $child_node_map{$child} = $node;
+ }
+ $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
+ return;
+ }
+
+ if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_CREATE_RESPONSE") {
+ if ($response_info->{'message'} eq $::RESPONSE_OK) {
+ if ($response_info->{'data'}) {
+ my $dump_id = $response_info->{'data'};
+ if ($next_status{ $node_info{$node}{cur_status} }) {
+ $node_info{$node}{dump_id} = $dump_id;
+ xCAT::SvrUtils::sendmsg("Dump requested. Target ID is $dump_id, waiting for BMC to generate...", $callback, $node);
+ } else {
+ xCAT::SvrUtils::sendmsg("[$dump_id] success", $callback, $node);
+ }
+ } else {
+ xCAT::SvrUtils::sendmsg([1, "BMC returned $::RESPONSE_OK but no ID was returned. Verify manually on the BMC."], $callback, $node);
+ $wait_node_num--;
+ return;
+ }
+ }
+ }
+
+ if ($node_info{$node}{cur_status} eq "RSPCONFIG_DUMP_CLEAR_RESPONSE") {
+ if ($response_info->{'message'} eq $::RESPONSE_OK) {
+ my $dump_id = $status_info{RSPCONFIG_DUMP_CLEAR_RESPONSE}{argv};
+ xCAT::MsgUtils->message("I", { data => ["[$dump_id] clear"] }, $callback) unless ($next_status{ $node_info{$node}{cur_status} });
+ } else {
+ my $error_msg = "Could not clear BMC diagnostics successfully (". $response_info->{'message'} . "), ignoring...";
+ xCAT::MsgUtils->message("W", { data => ["$node: $error_msg"] }, $callback) if ($next_status{ $node_info{$node}{cur_status} });
+ }
+ }
+
+ if ($next_status{ $node_info{$node}{cur_status} }) {
+ $node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
+ if ($node_info{$node}{method} || $status_info{ $node_info{$node}{cur_status} }{method}) {
+ gen_send_request($node);
+ } elsif ($status_info{ $node_info{$node}{cur_status} }->{process}) {
+ $status_info{ $node_info{$node}{cur_status} }->{process}->($node, undef);
+ }
+ } else {
+ $wait_node_num--;
+ }
+}
+
+#-------------------------------------------------------
+
+=head3 dump_download_process
+
+ Process of download dump tar.xz.
+ Input:
+ $node: nodename of current response
+
+=cut
+
+#-------------------------------------------------------
+sub dump_download_process {
+ my $node = shift;
+
+ my $request_url = "$http_protocol://" . $node_info{$node}{bmc};
+ my $content_login = '{ "data": [ "' . $node_info{$node}{username} .'", "' . $node_info{$node}{password} . '" ] }';
+ my $content_logout = '{ "data": [ ] }';
+ my $cjar_id = "/tmp/_xcat_cjar.$node";
+ my $dump_id;
+ $dump_id = $status_info{RSPCONFIG_DUMP_DOWNLOAD_REQUEST}{argv} if ($status_info{RSPCONFIG_DUMP_DOWNLOAD_REQUEST}{argv});
+ $dump_id = $node_info{$node}{dump_id} if ($node_info{$node}{dump_id});
+ my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($::RSPCONFIG_DUMP_CMD_TIME);
+ $mon += 1;
+ $year += 1900;
+ my $formatted_time = sprintf ("%04d%02d%02d-%02d%02d", $year, $mon, $mday, $hour, $min);
+ my $file_name = $::XCAT_LOG_DUMP_DIR . $formatted_time . "_$node" . "_dump_$dump_id.tar.xz";
+ my $down_url;
+ $down_url = $status_info{RSPCONFIG_DUMP_DOWNLOAD_REQUEST}{init_url};
+ $down_url =~ s/#ID#/$dump_id/g;
+
+ 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 . "'";
+ my $curl_dwld_cmd = "curl -J -b $cjar_id -k -H 'Content-Type: application/octet-stream' -X GET $request_url/$down_url -o $file_name";
+
+ my $curl_login_result = `$curl_login_cmd -s`;
+ my $h;
+ if (!$curl_login_result) {
+ xCAT::SvrUtils::sendmsg([1, "Did not receive response from OpenBMC after running command '$curl_login_cmd'"], $callback, $node);
+ return 1;
+ }
+ eval { $h = from_json($curl_login_result) };
+ if ($@) {
+ xCAT::SvrUtils::sendmsg([1, "Received wrong format response for command '$curl_login_cmd': $curl_login_result)"], $callback, $node);
+ return 1;
+ }
+ if ($h->{message} eq $::RESPONSE_OK) {
+ 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) {
+ my $debugmsg = "RSPCONFIG_DUMP_DOWNLOAD_REQUEST: CMD: $curl_dwld_cmd";
+ process_debug_info($node, $debugmsg);
+ }
+ `$curl_logout_cmd -s`;
+ # Verify the file actually got downloaded
+ if (-e $file_name) {
+ xCAT::SvrUtils::sendmsg("Downloaded dump $dump_id to $file_name", $callback, $node) if ($::VERBOSE);
+ }
+ else {
+ xCAT::SvrUtils::sendmsg([1, "Failed to download dump $dump_id to $file_name. Verify destination directory exists and has correct access permissions."], $callback, $node);
+ return 1;
+ }
+ } else {
+ xCAT::SvrUtils::sendmsg([1, "Failed to download dump $dump_id :" . $h->{message} . " - " . $h->{data}->{description}], $callback, $node);
+ return 1;
+ }
+ } else {
+ xCAT::SvrUtils::sendmsg([1, "Unable to login :" . $h->{message} . " - " . $h->{data}->{description}], $callback, $node);
+ return 1;
+ }
+ return 0;
+}
+
#-------------------------------------------------------
=head3 rvitals_response
@@ -2369,9 +3438,7 @@ sub rvitals_response {
# If sorted array has any contents, sort it and print it
if (scalar @sorted_output > 0) {
# Sort the output, alpha, then numeric
- my @sorted_output = grep {s/(^|\D)0+(\d)/$1$2/g,1} sort
- grep {s/(\d+)/sprintf"%06.6d",$1/ge,1} @sorted_output;
- xCAT::SvrUtils::sendmsg("$_", $callback, $node) foreach (@sorted_output);
+ xCAT::MsgUtils->message("I", { data => ["$node: $_"] }, $callback) foreach (sort natural_sort_cmp @sorted_output);
} else {
xCAT::SvrUtils::sendmsg("$::NO_ATTRIBUTES_RETURNED", $callback, $node);
}
@@ -2409,7 +3476,8 @@ sub rflash_response {
my $update_activation = "Unknown";
my $update_purpose;
my $update_version;
-
+ my $rflash_log_file = xCAT::Utils->full_path($node.".log", $::XCAT_LOG_RFLASH_DIR);
+ open (RFLASH_LOG_FILE_HANDLE, ">> $rflash_log_file");
if ($node_info{$node}{cur_status} eq "RFLASH_LIST_RESPONSE") {
# Get the functional IDs to accurately mark the active running FW
my $functional = get_functional_software_ids($response_info);
@@ -2423,6 +3491,11 @@ sub rflash_response {
xCAT::SvrUtils::sendmsg("-" x 55, $callback, $node);
foreach my $key_url (keys %{$response_info->{data}}) {
+ # Initialize values to Unknown for each loop, incase they are not defined in the BMC
+ $update_activation = "Unknown";
+ $update_purpose = "Unknown";
+ $update_version = "Unknown";
+
my %content = %{ ${ $response_info->{data} }{$key_url} };
$update_id = (split(/\//, $key_url))[ -1 ];
@@ -2483,66 +3556,131 @@ sub rflash_response {
#
# TODO: Remove this block when proper request can be generated
#
- if ($::UPLOAD_FILE) {
+ if ($::UPLOAD_FILE){
+ $fw_tar_files{$::UPLOAD_FILE}=$::UPLOAD_FILE_VERSION;
+ }
+ if ($::UPLOAD_PNOR){
+ $fw_tar_files{$::UPLOAD_PNOR}=$::UPLOAD_PNOR_VERSION;
+ }
+ if (%fw_tar_files) {
my $child = xCAT::Utils->xfork;
if (!defined($child)) {
xCAT::SvrUtils::sendmsg("Failed to fork child process to upload firmware image.", $callback, $node);
sleep(1)
} elsif ($child == 0) {
+ $async->remove_all;
exit(rflash_upload($node, $callback))
} else {
$child_node_map{$child} = $node;
}
}
}
- if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_ACTIVATE_RESPONSE") {
- xCAT::SvrUtils::sendmsg("rflash started, please wait...", $callback, $node);
+ 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 ($::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_SET_PRIORITY_RESPONSE") {
print "Update priority has been set";
}
if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_CHECK_STATE_RESPONSE") {
- my $activation_state;
- my $progress_state;
- my $priority_state;
+ my %activation_state;
+ my %progress_state;
+ my %priority_state;
+ my %update_ids;
+ my $update_res=0;
+ my $version;
foreach my $key_url (keys %{$response_info->{data}}) {
- my $content = ${ $response_info->{data} }{$key_url};
- # Get values of some attributes to determine activation status
- if ($key_url eq "Activation") {
- $activation_state = ${ $response_info->{data} }{$key_url};
- }
- if ($key_url eq "Progress") {
- $progress_state = ${ $response_info->{data} }{$key_url};
- }
- if ($key_url eq "Priority") {
- $priority_state = ${ $response_info->{data} }{$key_url};
+ if ($::UPLOAD_ACTIVATE_STREAM or $::UPLOAD_AND_ACTIVATE) {
+ my %content = %{${$response_info->{data}}{$key_url}};
+ $version = $content{Version};
+ if (defined($version)) {
+ if ($version ne $::UPLOAD_FILE_VERSION and $version ne $::UPLOAD_PNOR_VERSION) {
+ next;
+ }
+ # Get values of some attributes to determine activation status
+ $activation_state{$version} = $content{Activation};
+ $progress_state{$version} = $content{Progress};
+ $priority_state{$version} = $content{Priority};
+ $update_ids{$version} = (split(/\//, $key_url))[ -1 ];
+ }
+ } else {
+ # This is for -a option
+ $version = "default";
+ if ($key_url eq "Activation") {
+ $activation_state{$version} = ${ $response_info->{data} }{$key_url};
+ }
+ if ($key_url eq "Progress") {
+ $progress_state{$version} = ${ $response_info->{data} }{$key_url};
+ }
+ if ($key_url eq "Priority") {
+ $priority_state{$version} = ${ $response_info->{data} }{$key_url};
+ }
}
}
-
- if ($activation_state =~ /Software.Activation.Activations.Failed/) {
- # Activation failed. Report error and exit
- xCAT::SvrUtils::sendmsg([1,"Firmware activation Failed."], $callback, $node);
- $wait_node_num--;
- return;
- }
- elsif ($activation_state =~ /Software.Activation.Activations.Active/) {
- if (scalar($priority_state) == 0) {
- # Activation state of active and priority of 0 indicates the activation has been completed
- xCAT::SvrUtils::sendmsg("Firmware activation Successful.", $callback, $node);
- $wait_node_num--;
+ my $firm_msg;
+ my $version_num = 0;
+ my $rsp;
+ my $length = keys %activation_state;
+ foreach my $firm_version (keys %activation_state) {
+ if ($firm_version eq "default") {
+ $firm_msg = "Firmware";
+ } else {
+ $firm_msg = "Firmware $firm_version";
+ }
+ if ($activation_state{$firm_version} =~ /Software.Activation.Activations.Failed/) {
+ # Activation failed. Report error and exit
+ my $flash_failed_msg = "$firm_msg activation failed.";
+ xCAT::SvrUtils::sendmsg([1,"$flash_failed_msg"], $callback, $node);
+ $update_res = 1;
+ print RFLASH_LOG_FILE_HANDLE "$flash_failed_msg\n";
+ close (RFLASH_LOG_FILE_HANDLE);
+ $node_info{$node}{rst} = "$flash_failed_msg";
+ } elsif ($activation_state{$firm_version} =~ /Software.Activation.Activations.Active/) {
+ if (scalar($priority_state{$firm_version}) == 0) {
+ $version_num ++;
+ my $flash_success_msg = "$node: $firm_msg activation successful.";
+ push @{ $rsp->{data} },$flash_success_msg;
+ # Activation state of active and priority of 0 indicates the activation has been completed
+ if ( $length == $version_num ) {
+ xCAT::MsgUtils->message("I", $rsp, $callback) if ($rsp);
+ print RFLASH_LOG_FILE_HANDLE "$flash_success_msg\n";
+ $node_info{$node}{rst} = "$flash_success_msg";
+ if (!$::UPLOAD_ACTIVATE_STREAM) {
+ $wait_node_num--;
+ return;
+ }
+ else{
+ $next_status{ $node_info{$node}{cur_status} } = "RPOWER_BMCREBOOT_REQUEST";
+ }
+ }
+ } else {
+ # Activation state of active and priority of non 0 - need to just set priority to 0 to activate
+ print "$firm_version update is already active, just need to set priority to 0\n";
+ if ($::UPLOAD_ACTIVATE_STREAM) {
+ $status_info{RFLASH_SET_PRIORITY_REQUEST}{init_url} =
+ $::SOFTWARE_URL . "/$update_ids{$firm_version}/attr/Priority";
+ }
+ $next_status{ $node_info{$node}{cur_status} } = "RFLASH_SET_PRIORITY_REQUEST";
+ }
+ } elsif ($activation_state{$firm_version} =~ /Software.Activation.Activations.Activating/) {
+ my $activating_progress_msg = "Activating $firm_msg... $progress_state{$firm_version}\%";
+ if ($::VERBOSE) {
+ xCAT::SvrUtils::sendmsg("$activating_progress_msg", $callback, $node);
+ }
+ print RFLASH_LOG_FILE_HANDLE "$activating_progress_msg\n";
+ close (RFLASH_LOG_FILE_HANDLE);
+ # Activation still going, sleep for a bit, then print the progress value
+ # Set next state to come back here to chect the activation status again.
+ retry_after($node, "RFLASH_UPDATE_CHECK_STATE_REQUEST", 15);
return;
}
- else {
- # Activation state of active and priority of non 0 - need to just set priority to 0 to activate
- print "Update is already active, just need to set priority to 0\n";
- $next_status{ $node_info{$node}{cur_status} } = "RFLASH_SET_PRIORITY_REQUEST";
- }
}
- elsif ($activation_state =~ /Software.Activation.Activations.Activating/) {
- xCAT::SvrUtils::sendmsg("Activating firmware . . . $progress_state\%", $callback, $node);
- # Activation still going, sleep for a bit, then print the progress value
- # Set next state to come back here to chect the activation status again.
- retry_after($node, "RFLASH_UPDATE_CHECK_STATE_REQUEST", 15);
+ if ($update_res) {
+ close (RFLASH_LOG_FILE_HANDLE);
+ $wait_node_num--;
return;
}
}
@@ -2552,10 +3690,11 @@ sub rflash_response {
my $progress_state;
my $priority_state;
my $found_match = 0;
+ my $found_pnor_match = 0;
my $debugmsg;
if ($xcatdebugmode) {
- $debugmsg = "CHECK_ID_RESPONSE: Looking for software ID: $::UPLOAD_FILE_VERSION...";
+ $debugmsg = "CHECK_ID_RESPONSE: Looking for software ID: $::UPLOAD_FILE_VERSION $::UPLOAD_PNOR_VERSION...";
process_debug_info($node, $debugmsg);
}
# Look through all the software entries and find the id of the one that matches
@@ -2575,37 +3714,69 @@ sub rflash_response {
$found_match = 1;
# Found a match of uploaded file version with the image in software/enumerate
+ # If we have a saved expected hash ID, compare it to the one just found
+ if ($::UPLOAD_FILE_HASH_ID && ($::UPLOAD_FILE_HASH_ID ne $update_id)) {
+ xCAT::SvrUtils::sendmsg([1,"Firmware uploaded but activation cancelled due to hash ID mismatch. $update_id does not match expected $::UPLOAD_FILE_HASH_ID. Verify BMC firmware is at the latest level."], $callback, $node);
+ $wait_node_num--;
+ return; # Stop processing for this node, do not activate. Firmware shold be left in "Ready" state.
+ }
# Set the image id for the activation request
$status_info{RFLASH_UPDATE_ACTIVATE_REQUEST}{init_url} =
$::SOFTWARE_URL . "/$update_id/attr/RequestedActivation";
$status_info{RFLASH_UPDATE_CHECK_STATE_REQUEST}{init_url} =
- $::SOFTWARE_URL . "/$update_id";
+ $::SOFTWARE_URL . "/enumerate";
$status_info{RFLASH_SET_PRIORITY_REQUEST}{init_url} =
$::SOFTWARE_URL . "/$update_id/attr/Priority";
- # Set next steps to activate the image
- $next_status{ $node_info{$node}{cur_status} } = "RFLASH_UPDATE_ACTIVATE_REQUEST";
- $next_status{"RFLASH_UPDATE_ACTIVATE_REQUEST"} = "RFLASH_UPDATE_ACTIVATE_RESPONSE";
- $next_status{"RFLASH_UPDATE_ACTIVATE_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST";
- $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";
- last;
+ my $upload_success_msg = "Firmware upload successful. Attempting to activate firmware: $::UPLOAD_FILE_VERSION (ID: $update_id)";
+ xCAT::SvrUtils::sendmsg("$upload_success_msg", $callback, $node);
+ print RFLASH_LOG_FILE_HANDLE "$upload_success_msg\n";
+ } elsif ($update_version eq $::UPLOAD_PNOR_VERSION) {
+ $found_pnor_match = 1;
+ if ($::UPLOAD_PNOR_HASH_ID && ($::UPLOAD_PNOR_HASH_ID ne $update_id)) {
+ xCAT::SvrUtils::sendmsg([1,"Firmware uploaded but activation cancelled due to hash ID mismatch. $update_id does not match expected $::UPLOAD_PNOR_HASH_ID. Verify BMC firmware is at the latest level."], $callback, $node);
+ $wait_node_num--;
+ return;
+ }
+ $status_info{RFLASH_UPDATE_HOST_ACTIVATE_REQUEST}{init_url} =
+ $::SOFTWARE_URL . "/$update_id/attr/RequestedActivation";
+ $status_info{RFLASH_UPDATE_CHECK_STATE_REQUEST}{init_url} =
+ $::SOFTWARE_URL . "/enumerate";
+ $status_info{RFLASH_SET_PRIORITY_REQUEST}{init_url} =
+ $::SOFTWARE_URL . "/$update_id/attr/Priority";
+ my $upload_success_msg = "Firmware upload successful. Attempting to activate firmware: $::UPLOAD_PNOR_VERSION (ID: $update_id)";
+ xCAT::SvrUtils::sendmsg("$upload_success_msg", $callback, $node);
+ print RFLASH_LOG_FILE_HANDLE "$upload_success_msg\n";
}
+
}
}
- if (!$found_match) {
- if (!exists($node_info{node}{upload_wait_attemp})) {
- $node_info{node}{upload_wait_attemp} = $::UPLOAD_WAIT_ATTEMPT;
+ if ($::UPLOAD_ACTIVATE_STREAM and (!$found_match or !$found_pnor_match) or !$found_match) {
+ if (!exists($node_info{$node}{upload_wait_attemp})) {
+ $node_info{$node}{upload_wait_attemp} = $::UPLOAD_WAIT_ATTEMPT;
}
- if($node_info{node}{upload_wait_attemp} > 0) {
- $node_info{node}{upload_wait_attemp} --;
- xCAT::SvrUtils::sendmsg("Could not find ID for firmware $::UPLOAD_FILE_VERSION to activate, waiting $::UPLOAD_WAIT_INTERVAL seconds and retry...", $callback, $node);
+ my $upload_file_version = "";
+ if (!$found_match) {
+ $upload_file_version = $::UPLOAD_FILE_VERSION;
+ } else {
+ $upload_file_version = $::UPLOAD_PNOR_VERSION;
+ }
+ if($node_info{$node}{upload_wait_attemp} > 0) {
+ $node_info{$node}{upload_wait_attemp} --;
+ my $retry_msg = "Could not find ID for firmware $upload_file_version to activate, waiting $::UPLOAD_WAIT_INTERVAL seconds and retry...";
+ if ($::VERBOSE) {
+ xCAT::SvrUtils::sendmsg("$retry_msg", $callback, $node);
+ }
+ print RFLASH_LOG_FILE_HANDLE "$retry_msg\n";
+ close (RFLASH_LOG_FILE_HANDLE);
retry_after($node, "RFLASH_UPDATE_CHECK_ID_REQUEST", $::UPLOAD_WAIT_INTERVAL);
return;
} else {
- xCAT::SvrUtils::sendmsg([1,"Could not find firmware $::UPLOAD_FILE_VERSION after waiting $::UPLOAD_WAIT_TOTALTIME seconds."], $callback, $node);
+ my $no_firmware_msg = "Could not find firmware $upload_file_version after waiting $::UPLOAD_WAIT_TOTALTIME seconds.";
+ xCAT::SvrUtils::sendmsg([1,"$no_firmware_msg"], $callback, $node);
+ print RFLASH_LOG_FILE_HANDLE "$no_firmware_msg\n";
+ close (RFLASH_LOG_FILE_HANDLE);
+ $node_info{$node}{rst} = "$no_firmware_msg";
$wait_node_num--;
return;
}
@@ -2613,9 +3784,11 @@ sub rflash_response {
}
if ($node_info{$node}{cur_status} eq "RFLASH_DELETE_IMAGE_RESPONSE") {
- xCAT::SvrUtils::sendmsg("Firmware removed", $callback, $node);
+ xCAT::SvrUtils::sendmsg("Firmware removed", $callback, $node);
}
+ close (RFLASH_LOG_FILE_HANDLE);
+
if ($next_status{ $node_info{$node}{cur_status} }) {
$node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
if ($node_info{$node}{method} || $status_info{ $node_info{$node}{cur_status} }{method}) {
@@ -2633,42 +3806,100 @@ 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;
# 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 . "'";
- my $curl_upload_cmd = "curl -b $cjar_id -k -H 'Content-Type: application/octet-stream' -X PUT -T " . $::UPLOAD_FILE . " $request_url/upload/image/";
+
+ 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);
+ }
+ }
+
+ my $rflash_log_file = xCAT::Utils->full_path($node.".log", $::XCAT_LOG_RFLASH_DIR);
+ open (RFLASH_LOG_FILE_HANDLE, ">> $rflash_log_file");
# Try to login
- my $curl_login_result = `$curl_login_cmd`;
- my $h = from_json($curl_login_result); # convert command output to hash
- if ($h->{message} eq $::RESPONSE_OK) {
- # Login successfull, upload the file
- xCAT::SvrUtils::sendmsg("Uploading $::UPLOAD_FILE ...", $callback, $node);
- if ($xcatdebugmode) {
- my $debugmsg = "RFLASH_FILE_UPLOAD_RESPONSE: CMD: $curl_upload_cmd";
- process_debug_info($node, $debugmsg);
- }
- my $curl_upload_result = `$curl_upload_cmd`;
- $h = from_json($curl_upload_result); # convert command output to hash
- if ($h->{message} eq $::RESPONSE_OK) {
- # Upload successful, display message
- if ($::UPLOAD_AND_ACTIVATE) {
- xCAT::SvrUtils::sendmsg("Firmware upload successful. Attempting to activate firmware: $::UPLOAD_FILE_VERSION", $callback, $node);
- } else {
- xCAT::SvrUtils::sendmsg("Firmware upload successful. Use -l option to list.", $callback, $node);
- }
- # Try to logoff, no need to check result, as there is nothing else to do if failure
- my $curl_logout_result = `$curl_logout_cmd`;
- }
- else {
- xCAT::SvrUtils::sendmsg("Failed to upload update file $::UPLOAD_FILE :" . $h->{message} . " - " . $h->{data}->{description}, $callback, $node);
- return 1;
- }
- }
- else {
- xCAT::SvrUtils::sendmsg("Unable to login :" . $h->{message} . " - " . $h->{data}->{description}, $callback, $node);
+ my $curl_login_result = `$curl_login_cmd -s`;
+ my $h;
+ if (!$curl_login_result) {
+ my $curl_error = "Did not receive response from OpenBMC after running command '$curl_login_cmd'";
+ xCAT::SvrUtils::sendmsg([1, "$curl_error"], $callback, $node);
+ print RFLASH_LOG_FILE_HANDLE "$curl_error\n";
+ $node_info{$node}{rst} = "$curl_error";
+ return 1;
+ }
+ eval { $h = from_json($curl_login_result) }; # convert command output to hash
+ if ($@) {
+ my $curl_error = "Received wrong format response for command '$curl_login_cmd': $curl_login_result";
+ xCAT::SvrUtils::sendmsg([1, "$curl_error"], $callback, $node);
+ print RFLASH_LOG_FILE_HANDLE "$curl_error\n";
+ $node_info{$node}{rst} = "$curl_error";
return 1;
}
+ if ($h->{message} eq $::RESPONSE_OK) {
+ foreach my $upload_cmd(@curl_upload_cmds){
+ while((my $file,my $version)=each(%fw_tar_files)){
+ my $uploading_msg = "Uploading $file ...";
+ # Login successfull, upload the file
+ if ($::VERBOSE) {
+ xCAT::SvrUtils::sendmsg("$uploading_msg", $callback, $node);
+ }
+ print RFLASH_LOG_FILE_HANDLE "$uploading_msg\n";
+
+ if ($xcatdebugmode) {
+ my $debugmsg = "RFLASH_FILE_UPLOAD_RESPONSE: CMD: $upload_cmd";
+ process_debug_info($node, $debugmsg);
+ }
+ my $curl_upload_result = `$upload_cmd`;
+ if (!$curl_upload_result) {
+ my $curl_error = "Did not receive response from OpenBMC after running command '$upload_cmd'";
+ xCAT::SvrUtils::sendmsg([1, "$curl_error"], $callback, $node);
+ print RFLASH_LOG_FILE_HANDLE "$curl_error\n";
+ $node_info{$node}{rst} = "$curl_error";
+ return 1;
+ }
+ eval { $h = from_json($curl_upload_result) }; # convert command output to hash
+ if ($@) {
+ my $curl_error = "Received wrong format response from command '$upload_cmd': $curl_upload_result";
+ xCAT::SvrUtils::sendmsg([1, "$curl_error"], $callback, $node);
+ print RFLASH_LOG_FILE_HANDLE "$curl_error\n";
+ $node_info{$node}{rst} = "$curl_error";
+ return 1;
+ }
+ if ($h->{message} eq $::RESPONSE_OK) {
+ # Upload successful, display message
+ my $upload_success_msg = "Firmware upload successful. Use -l option to list.";
+ unless ($::UPLOAD_AND_ACTIVATE or $::UPLOAD_ACTIVATE_STREAM) {
+ xCAT::SvrUtils::sendmsg("$upload_success_msg", $callback, $node);
+ }
+ print RFLASH_LOG_FILE_HANDLE "$upload_success_msg\n";
+ # Try to logoff, no need to check result, as there is nothing else to do if failure
+ } else {
+ my $upload_fail_msg = "Failed to upload update file $file :" . $h->{message} . " - " . $h->{data}->{description};
+ xCAT::SvrUtils::sendmsg("$upload_fail_msg", $callback, $node);
+ print RFLASH_LOG_FILE_HANDLE "$upload_fail_msg\n";
+ close (RFLASH_LOG_FILE_HANDLE);
+ $node_info{$node}{rst} = "$upload_fail_msg";
+ return 1;
+ }
+ }
+ }
+ # Try to logoff, no need to check result, as there is nothing else to do if failure
+ my $curl_logout_result = `$curl_logout_cmd -s`;
+ }
+ else {
+ my $unable_login_msg = "Unable to login :" . $h->{message} . " - " . $h->{data}->{description};
+ xCAT::SvrUtils::sendmsg("$unable_login_msg", $callback, $node);
+ print RFLASH_LOG_FILE_HANDLE "$unable_login_msg\n";
+ close (RFLASH_LOG_FILE_HANDLE);
+ $node_info{$node}{rst} = "$unable_login_msg";
+ return 1;
+ }
+
+ close (RFLASH_LOG_FILE_HANDLE);
return 0;
}
1;
diff --git a/xCAT-server/lib/xcat/plugins/packimage.pm b/xCAT-server/lib/xcat/plugins/packimage.pm
index fa450e7c9..f12bda2cf 100755
--- a/xCAT-server/lib/xcat/plugins/packimage.pm
+++ b/xCAT-server/lib/xcat/plugins/packimage.pm
@@ -629,6 +629,7 @@ sub copybootscript {
copy("$installroot/postscripts/xcatdsklspost", "$rootimg_dir/opt/xcat/xcatdsklspost");
if ($timezone[0]) {
+ unlink("$rootimg_dir/etc/localtime");
copy("$rootimg_dir/usr/share/zoneinfo/$timezone[0]", "$rootimg_dir/etc/localtime");
}
diff --git a/xCAT-server/lib/xcat/plugins/pdu.pm b/xCAT-server/lib/xcat/plugins/pdu.pm
index d8b3848db..852bdd816 100644
--- a/xCAT-server/lib/xcat/plugins/pdu.pm
+++ b/xCAT-server/lib/xcat/plugins/pdu.pm
@@ -71,6 +71,41 @@ sub handled_commands
};
}
+sub pdu_usage
+{
+ my ($callback, $command) = @_;
+ my $usagemsg =
+ "Usage:
+ pdudiscover [|--range ipranges] [-r|-x|-z] [-w] [-V|--verbose] [--setup]
+ rpower pdunodes [off|on|stat|reset]
+
+ The following command supports IR PDU with pdutype=irpdu :
+ rpower CN [pduoff|pduon|pdustat|pdustatus|pdureset]
+
+ The following commands support CR PDU with pdutype=crpdu :
+ rpower pdunodes relay=[1|2|3] [on|off]
+ rinv pdunodes
+ rvitals pdunodes
+ rspconfig pdunodes sshcfg
+ rspconfig pdunodes snmpcfg
+ rspconfig pdunode [hostname=|ip=|mask=]
+
+ \n";
+
+ if ($callback)
+ {
+ my $rsp = {};
+ $rsp->{data}->[0] = $usagemsg;
+ xCAT::MsgUtils->message("I", $rsp, $callback);
+ }
+ else
+ {
+ xCAT::MsgUtils->message("I", $usagemsg);
+ }
+ return;
+
+}
+
#--------------------------------------------------------------------------------
=head3 preprocess_request
@@ -94,15 +129,12 @@ sub preprocess_request {
my $usage_string=xCAT::Usage->parseCommand($command, @exargs);
if ($usage_string) {
- $callback->({data=>[$usage_string]});
- $req = {};
- return;
+ &pdu_usage($callback, $command);
+ return 1;
}
if ((!$noderange) && ($command ne "pdudiscover") ){
- $usage_string = xCAT::Usage->getUsage($command);
- $callback->({ data => $usage_string });
- $req = {};
+ &pdu_usage($callback, $command);
return;
}
@@ -137,11 +169,6 @@ sub process_request
@exargs = @$extrargs;
}
- #fill in the total outlet count for each pdu
- $pdutab = xCAT::Table->new('pdu');
- @pduents = $pdutab->getAllNodeAttribs(['node', 'outlet']);
- #fill_outletCount(\@pduents, $callback);
-
if( $command eq "rinv") {
#for higher performance, handle node in batch
return showMFR($noderange, $callback);
@@ -149,6 +176,7 @@ sub process_request
return showMonitorData($noderange, $callback);
}elsif ($command eq "rpower") {
my $subcmd = $exargs[0];
+ my $subcmd2 = $exargs[1];
if (($subcmd eq 'pduoff') || ($subcmd eq 'pduon') || ($subcmd eq 'pdustat')|| ($subcmd eq 'pdureset') ){
#if one day, pdu node have pdu attribute, handle in this section too
return powerpduoutlet($noderange, $subcmd, $callback);
@@ -169,11 +197,14 @@ sub process_request
}
}
if(@allpdunodes) {
- if(($subcmd eq 'on') || ($subcmd eq 'off') || ($subcmd eq 'stat') || ($subcmd eq 'state') || ($subcmd eq 'reset') ){
+ if ( ($subcmd =~ /relay/) || ($subcmd2 =~ /relay/) ) {
+ process_powerrelay($request,$subreq,\@allpdunodes,$callback);
+ } elsif(($subcmd eq 'on') || ($subcmd eq 'off') || ($subcmd eq 'stat') || ($subcmd eq 'state') || ($subcmd eq 'reset') ){
return powerpdu(\@allpdunodes, $subcmd, $callback);
} else {
my $pdunode = join (",", @allpdunodes);
$callback->({ errorcode => [1],error => "The option $subcmd is not support for pdu node(s) $pdunode."});
+ &pdu_usage($callback, $command);
}
}
}
@@ -181,15 +212,19 @@ sub process_request
my $subcmd = $exargs[0];
if ($subcmd eq 'sshcfg') {
process_sshcfg($noderange, $subcmd, $callback);
+ }elsif ($subcmd eq 'snmpcfg') {
+ process_snmpcfg($noderange, $subcmd, $callback);
}elsif ($subcmd =~ /ip|netmask|hostname/) {
process_netcfg($request, $subreq, $subcmd, $callback);
} else {
$callback->({ errorcode => [1],error => "The input $command $subcmd is not support for pdu"});
+ &pdu_usage($callback, $command);
}
}elsif($command eq "pdudiscover") {
process_pdudiscover($request, $subreq, $callback);
}elsif($command eq "nodeset") {
$callback->({ errorcode => [1],error => "The input $command is not support for pdu"});
+ &pdu_usage($callback, $command);
}else{
#reserve for other new command in future
}
@@ -197,29 +232,30 @@ sub process_request
return;
}
+#-------------------------------------------------------
+
+=head3 fill_outletcount
+
+ Get outlet count for IR PDU.
+
+=cut
+
+#-------------------------------------------------------
sub fill_outletCount {
- my $pduentries = shift;
+ my $session = shift;
+ my $pdu = shift;
my $callback = shift;
my $outletoid = ".1.3.6.1.4.1.2.6.223.8.2.1.0";
my $pdutab = xCAT::Table->new('pdu');
- foreach my $pdu (@$pduentries) {
- my $cur_pdu = $pdu->{node};
- my $count = $pdu->{outlet};
- #get total outlet number for the pdu
- if (!$count) {
- my $session = connectTopdu($cur_pdu,$callback);
- #will not log this error to output
- if (!$session) {
- next;
- }
- $count = $session->get("$outletoid");
- if ($count) {
- $pdutab->setNodeAttribs($cur_pdu, {outlet => $count});
- }
- }
- $pdunodes->{$cur_pdu}->{outlet}=$count;
+ my $count = $session->get("$outletoid");
+ if ($count) {
+ $pdutab->setNodeAttribs($pdu, {outlet => $count});
}
+
+ return $count;
+
+
}
#-------------------------------------------------------
@@ -240,13 +276,25 @@ sub powerpdu {
return powerstat($noderange, $callback);
}
+ my $pdutab = xCAT::Table->new('pdu');
+ my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype','outlet']);
+
foreach my $node (@$noderange) {
+ if ($pduhash->{$node}->[0]->{pdutype} eq 'crpdu') {
+ process_relay($node,$subcmd,$callback,1,3);
+ next;
+ }
+
my $session = connectTopdu($node,$callback);
if (!$session) {
$callback->({ errorcode => [1],error => "Couldn't connect to $node"});
next;
}
- my $count = $pdunodes->{$node}->{outlet};
+ my $count = $pduhash->{$node}->[0]->{outlet};
+ unless ($count) {
+ $count = fill_outletCount($session, $node, $callback);
+ }
+
my $value;
my $statstr;
if ($subcmd eq "off") {
@@ -295,6 +343,9 @@ sub powerpduoutlet {
my $nodetab = xCAT::Table->new('pduoutlet');
my $nodepdu = $nodetab->getNodesAttribs($noderange,['pdu']);
+ my $pdutab = xCAT::Table->new('pdu');
+ my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype','outlet']);
+
foreach my $node (@$noderange) {
# the pdu attribute needs to be set
if(! $nodepdu->{$node}->[0]->{pdu}){
@@ -305,12 +356,20 @@ sub powerpduoutlet {
my @pdus = split /,/, $nodepdu->{$node}->[0]->{pdu};
foreach my $pdu_outlet (@pdus) {
my ($pdu, $outlet) = split /:/, $pdu_outlet;
+ if ($pduhash->{$pdu}->[0]->{pdutype} eq 'crpdu') {
+ $callback->({ error => "$node: This command doesn't supports CONSTELLATION PDU with pdutype=crpdu for $pdu"});
+ next;
+ }
my $session = connectTopdu($pdu,$callback);
if (!$session) {
$callback->({ errorcode => [1],error => "$node: Couldn't connect to $pdu"});
next;
}
- if ($outlet > $pdunodes->{$pdu}->{outlet} ) {
+ my $count = $pduhash->{$pdu}->[0]->{outlet};
+ unless ($count) {
+ $count = fill_outletCount($session, $pdu, $callback);
+ }
+ if ($outlet > $count ) {
$callback->({ error => "$node: $pdu outlet number $outlet is invalid"});
next;
}
@@ -382,13 +441,60 @@ sub powerstat {
my $callback = shift;
my $output;
+ my $pdutab = xCAT::Table->new('pdu');
+ my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype','outlet','snmpversion','snmpuser','authtype','authkey','privtype','privkey','seclevel']);
+
foreach my $pdu (@$noderange) {
+ if ($pduhash->{$pdu}->[0]->{pdutype} eq 'crpdu') {
+ my $snmpversion = $pduhash->{$pdu}->[0]->{snmpversion};
+ if ($snmpversion =~ /3/) {
+ my $snmpuser = $pduhash->{$pdu}->[0]->{snmpuser};
+ my $seclevel = $pduhash->{$pdu}->[0]->{seclevel};
+ if ((defined $snmpuser) && (defined $seclevel)) {
+ my $authtype = $pduhash->{$pdu}->[0]->{authtype};
+ if (!defined $authtype) {
+ $authtype="MD5";
+ }
+ my $authkey = $pduhash->{$pdu}->[0]->{authkey};
+ my $privtype = $pduhash->{$pdu}->[0]->{privtype};
+ if (!defined $privtype) {
+ $privtype="DES";
+ }
+ my $privkey = $pduhash->{$pdu}->[0]->{privkey};
+ if (!defined $privkey) {
+ if (defined $authkey) {
+ $privkey=$authkey;
+ }
+ }
+ my $snmpcmd;
+ if ($seclevel eq "authNoPriv") {
+ $snmpcmd = "snmpwalk -v3 -u $snmpuser -a $authtype -A $authkey -l $seclevel";
+ } elsif ($seclevel eq "authPriv") {
+ $snmpcmd = "snmpwalk -v3 -u $snmpuser -a $authtype -A $authkey -l $seclevel -x $privtype -X $privkey";
+ } else { #default to notAuthNoPriv
+ $snmpcmd = "snmpwalk -v3 -u $snmpuser -l $seclevel";
+ }
+
+ for (my $relay = 1; $relay <= 3; $relay++) {
+ relaystat($pdu, $relay, $snmpcmd, $callback);
+ }
+ next;
+ }
+ }
+ xCAT::SvrUtils::sendmsg("please config snmpv3 to be able to query pdu relay status", $callback,$pdu);
+ xCAT::SvrUtils::sendmsg(" use chdef command to add pdu snmpv3 attributes to pdu table", $callback);
+ xCAT::SvrUtils::sendmsg(" then run 'rspconfig $pdu snmpcfg' command ", $callback);
+ next;
+ }
my $session = connectTopdu($pdu,$callback);
if (!$session) {
$callback->({ errorcode => [1],error => "Couldn't connect to $pdu"});
next;
}
- my $count = $pdunodes->{$pdu}->{outlet};
+ my $count = $pduhash->{$pdu}->[0]->{outlet};
+ unless ($count) {
+ $count = fill_outletCount($session, $pdu, $callback);
+ }
for (my $outlet =1; $outlet <= $count; $outlet++)
{
my $statstr = outletstat($session, $outlet);
@@ -518,6 +624,13 @@ sub process_netcfg {
my $pdu = @$nodes[0];
my $rsp = {};
+ my $pdutab = xCAT::Table->new('pdu');
+ my $pduhash = $pdutab->getNodesAttribs($nodes, ['pdutype']);
+ unless ($pduhash->{$pdu}->[0]->{pdutype} eq "crpdu") {
+ xCAT::SvrUtils::sendmsg("This command only supports CONSTELLATION PDU with pdutype=crpdu", $callback,$pdu);
+ return;
+ }
+
my $nodetab = xCAT::Table->new('hosts');
my $nodehash = $nodetab->getNodesAttribs($nodes,['ip','otherinterfaces']);
@@ -526,7 +639,7 @@ sub process_netcfg {
my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces};
($exp, $errstr) = session_connect($static_ip, $discover_ip);
if (defined $errstr) {
- xCAT::SvrUtils::sendmsg("Failed to connect", $callback);
+ xCAT::SvrUtils::sendmsg("Failed to connect", $callback,$pdu);
return;
}
@@ -603,8 +716,16 @@ sub process_sshcfg {
my $nodetab = xCAT::Table->new('hosts');
my $nodehash = $nodetab->getNodesAttribs($noderange,['ip','otherinterfaces']);
-
+
+ my $pdutab = xCAT::Table->new('pdu');
+ my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype']);
+
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);
+ next;
+ }
+
my $msg = " process_sshcfg";
xCAT::SvrUtils::sendmsg($msg, $callback, $pdu, %allerrornodes);
@@ -635,6 +756,15 @@ sub process_sshcfg {
return;
}
+#-------------------------------------------------------
+
+=head3 session_connect
+
+ open a expect session and connect to CR PDU.
+
+=cut
+
+#-------------------------------------------------------
sub session_connect {
my $static_ip = shift;
my $discover_ip = shift;
@@ -682,7 +812,15 @@ sub session_connect {
return ($ssh);
}
+#-------------------------------------------------------
+=head3 session_exec
+
+ execute command to CR PDU.
+
+=cut
+
+#-------------------------------------------------------
sub session_exec {
my $exp = shift;
my $cmd = shift;
@@ -765,11 +903,20 @@ sub process_pdudiscover {
sub showMFR {
my $noderange = shift;
my $callback = shift;
+ my $output;
my $nodetab = xCAT::Table->new('hosts');
my $nodehash = $nodetab->getNodesAttribs($noderange,['ip','otherinterfaces']);
+ my $pdutab = xCAT::Table->new('pdu');
+ my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype']);
+
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);
+ next;
+ }
+
# connect to PDU
my $static_ip = $nodehash->{$pdu}->[0]->{ip};
my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces};
@@ -814,11 +961,20 @@ sub showMFR {
sub showMonitorData {
my $noderange = shift;
my $callback = shift;
+ my $output;
my $nodetab = xCAT::Table->new('hosts');
my $nodehash = $nodetab->getNodesAttribs($noderange,['ip','otherinterfaces']);
+ my $pdutab = xCAT::Table->new('pdu');
+ my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype']);
+
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);
+ next;
+ }
+
# connect to PDU
my $static_ip = $nodehash->{$pdu}->[0]->{ip};
my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces};
@@ -844,5 +1000,264 @@ sub showMonitorData {
}
}
+#-------------------------------------------------------
+
+=head3 relaystat
+
+ process individual relay stat for CR PDU.
+ The OID for 3 relay:
+ 1.3.6.1.4.1.2.6.262.15.2.13
+ 1.3.6.1.4.1.2.6.262.15.2.14
+ 1.3.6.1.4.1.2.6.262.15.2.15
+
+=cut
+
+#-------------------------------------------------------
+sub relaystat {
+ my $pdu = shift;
+ my $relay = shift;
+ my $snmpcmd = shift;
+ my $callback = shift;
+
+ my $relayoid = $relay + 12;
+
+ #default pdu snmpv3, won't show up for snmpv1
+ my $cmd = "$snmpcmd $pdu 1.3.6.1.4.1.2.6.262.15.2.$relayoid";
+
+ my $result = xCAT::Utils->runcmd($cmd, 0);
+ my ($msg,$stat) = split /: /, $result;
+ if ($stat eq "1" ) {
+ xCAT::SvrUtils::sendmsg(" relay $relay is on", $callback, $pdu, %allerrornodes);
+ } elsif ( $stat eq "0" ) {
+ xCAT::SvrUtils::sendmsg(" relay $relay is off", $callback, $pdu, %allerrornodes);
+ } else {
+ xCAT::SvrUtils::sendmsg(" relay $relay is unknown", $callback, $pdu, %allerrornodes);
+ }
+
+ return;
+}
+
+#-------------------------------------------------------
+
+=head3 process_powerrelay
+
+ process relay action for CR PDU.
+
+=cut
+
+#-------------------------------------------------------
+sub process_powerrelay {
+ my $request = shift;
+ my $subreq = shift;
+ my $subcmd = shift;
+ my $callback = shift;
+
+ my $relay;
+ my $action;
+
+ my $extrargs = $request->{arg};
+ my @exargs = ($request->{arg});
+ if (ref($extrargs)) {
+ @exargs = @$extrargs;
+ }
+
+ my $nodes = $request->{node};
+
+ foreach my $cmd (@exargs) {
+ if ($cmd =~ /=/ ) {
+ my ($key, $value) = split(/=/, $cmd);
+ $relay = $value;
+ } else {
+ $action = $cmd;
+ }
+ }
+ if ( (defined $relay) && (defined $action) ) {
+ my $relay_count = 1;
+ foreach my $pdu (@$nodes) {
+ process_relay($pdu, $action, $callback, $relay, $relay_count);
+ }
+ } else {
+ xCAT::SvrUtils::sendmsg(" This command is not support, please define relay number and action", $callback);
+ }
+
+}
+
+#-------------------------------------------------------
+
+=head3 process_relay
+
+ process relay action for CR PDU.
+
+=cut
+
+#-------------------------------------------------------
+sub process_relay {
+ my $pdu = shift;
+ my $subcmd = shift;
+ my $callback = shift;
+ my $relay_num = shift;
+ my $relay_count = shift;
+
+ if ( !defined $relay_count ) {
+ $relay_num = 1;
+ $relay_count = 3;
+ }
+
+ my $nodetab = xCAT::Table->new('hosts');
+ my $nodehash = $nodetab->getNodeAttribs($pdu,['ip','otherinterfaces']);
+
+ # connect to PDU
+ my $static_ip = $nodehash->{$pdu}->[0]->{ip};
+ my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces};
+ my ($session, $errstr) = session_connect($static_ip, $discover_ip);
+
+ my $ret;
+ my $err;
+ my $statestr;
+
+
+ for (my $i = 0; $i < $relay_count; $i++) {
+ my $relay = $relay_num;
+ xCAT::SvrUtils::sendmsg(" power $subcmd for relay $relay_num", $callback,$pdu);
+ if ($subcmd eq "off") {
+ relay_action($session, $pdu, $relay, "OFF", $callback);
+ } elsif ( $subcmd eq "on") {
+ relay_action($session, $pdu, $relay, "ON", $callback);
+ } elsif ( $subcmd eq "reset") {
+ relay_action($session, $pdu, $relay, "OFF", $callback);
+ relay_action($session, $pdu, $relay, "ON", $callback);
+ } else {
+ xCAT::SvrUtils::sendmsg(" subcmd $subcmd is not support", $callback,$pdu);
+ }
+ $relay_num++;
+ }
+ $session->hard_close();
+
+}
+
+#-------------------------------------------------------
+
+=head3 realy_action
+
+ process individual relay action for CR PDU.
+
+=cut
+
+#-------------------------------------------------------
+sub relay_action {
+ my $session = shift;
+ my $pdu = shift;
+ my $relay = shift;
+ my $action = shift;
+ my $callback = shift;
+
+ my ($ret, $err) = session_exec($session, "/dev/shm/bin/PduManager -r $relay -v $action");
+ if (defined $err) {
+ xCAT::SvrUtils::sendmsg("Failed to process relay action: $err", $callback);
+ }
+ if (defined $ret) {
+ xCAT::SvrUtils::sendmsg("$ret", $callback,$pdu);
+ }
+}
+
+#-------------------------------------------------------
+
+=head3 process_snmpcfg
+
+ config snmp and snmpv3 for CR PDU.
+
+=cut
+
+#-------------------------------------------------------
+sub process_snmpcfg {
+ my $noderange = shift;
+ my $subcmd = shift;
+ my $callback = shift;
+ my $snmp_conf="/etc/snmp/snmpd.conf";
+ my $xCATSettingsSTART="xCAT settings START";
+ my $xCATSettingsEND="xCAT settings END";
+ my $xCATSettingsInfo="Entries between the START and END lines will be replaced each time by xCAT command";
+
+
+ my $nodetab = xCAT::Table->new('hosts');
+ my $nodehash = $nodetab->getNodesAttribs($noderange,['ip','otherinterfaces']);
+
+ my $pdutab = xCAT::Table->new('pdu');
+ my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype','community','snmpversion','snmpuser','authtype','authkey','privtype','privkey','seclevel']);
+
+ 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);
+ next;
+ }
+
+ my $community = $pduhash->{$pdu}->[0]->{community};
+ my $snmpversion = $pduhash->{$pdu}->[0]->{snmpversion};
+ my $snmpuser = $pduhash->{$pdu}->[0]->{snmpuser};
+ my $authtype = $pduhash->{$pdu}->[0]->{authtype};
+ if (!defined $authtype) {
+ $authtype="MD5";
+ }
+ my $authkey = $pduhash->{$pdu}->[0]->{authkey};
+ my $privtype = $pduhash->{$pdu}->[0]->{privtype};
+ if (!defined $privtype) {
+ $privtype="DES";
+ }
+ my $privkey = $pduhash->{$pdu}->[0]->{privkey};
+ if (!defined $privkey) {
+ if (defined $authkey) {
+ $privkey=$authkey;
+ }
+ }
+ my $seclevel = $pduhash->{$pdu}->[0]->{seclevel};
+
+ # connect to PDU
+ my $static_ip = $nodehash->{$pdu}->[0]->{ip};
+ my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces};
+ my ($exp, $errstr) = session_connect($static_ip, $discover_ip);
+
+ my $ret;
+ my $err;
+
+ ($ret, $err) = session_exec($exp, "sed -i '/$xCATSettingsSTART/,/$xCATSettingsEND/ d' $snmp_conf");
+ ($ret, $err) = session_exec($exp, "echo '# $xCATSettingsSTART' >> $snmp_conf");
+ ($ret, $err) = session_exec($exp, "echo '# $xCATSettingsInfo' >> $snmp_conf");
+ if (defined $community) {
+ ($ret, $err) = session_exec($exp, "echo 'com2sec readwrite default $community' >> $snmp_conf");
+ }
+ #set snmpv3 configuration
+ if ($snmpversion =~ /3/) {
+ if ((defined $snmpuser) && (defined $seclevel)) {
+ my $msg1;
+ if ($seclevel eq "authNoPriv") {
+ $msg1 = "createUser $snmpuser $authtype $authkey";
+ } elsif ($seclevel eq "authPriv") {
+ $msg1 = "createUser $snmpuser $authtype $authkey $privtype $privkey";
+ } else { #default to notAuthNoPriv
+ $msg1 = "createUser $snmpuser";
+ }
+ my $msg2 = "rwuser $snmpuser $seclevel .1.3.6.1.4.1.2.6.262";
+ ($ret, $err) = session_exec($exp, "sed -i '/\"$snmpuser\"/ d' /var/lib/net-snmp/snmpd.conf");
+ ($ret, $err) = session_exec($exp, "echo $msg1 >> $snmp_conf");
+ ($ret, $err) = session_exec($exp, "echo $msg2 >> $snmp_conf");
+ } else {
+ xCAT::SvrUtils::sendmsg("Need to define user name and security level for snmpv3 configuration", $callback);
+ }
+ }
+ ($ret, $err) = session_exec($exp, "echo '# $xCATSettingsEND' >> $snmp_conf");
+
+ #need to restart snmpd after config file changes
+ ($ret, $err) = session_exec($exp, "ps | grep snmpd | grep -v grep | awk '{ print $1}' | xargs kill -9");
+ ($ret, $err) = session_exec($exp, "/usr/sbin/snmpd -Lsd -Lf /dev/null -p /var/run/snmpd");
+ if (defined $err) {
+ xCAT::SvrUtils::sendmsg("Failed to configure snmp : $err", $callback);
+ }
+
+
+ $exp->hard_close();
+ }
+}
+
+
1;
diff --git a/xCAT-server/lib/xcat/plugins/petitboot.pm b/xCAT-server/lib/xcat/plugins/petitboot.pm
index e6707b7e5..ec53c84b0 100644
--- a/xCAT-server/lib/xcat/plugins/petitboot.pm
+++ b/xCAT-server/lib/xcat/plugins/petitboot.pm
@@ -94,8 +94,8 @@ sub setstate {
if ($kern->{kernel} !~ /^$tftpdir/) {
my $nodereshash = $nrhash{$node}->[0];
my $installsrv;
- if ($nodereshash and $nodereshash->{nfsserver}) {
- $installsrv = $nodereshash->{nfsserver};
+ if ($nodereshash and $nodereshash->{tftpserver}) {
+ $installsrv = $nodereshash->{tftpserver};
} elsif ($nodereshash->{xcatmaster}) {
$installsrv = $nodereshash->{xcatmaster};
} else {
@@ -574,7 +574,7 @@ sub process_request {
my $chaintab = xCAT::Table->new('chain', -create => 1);
my $chainhash = $chaintab->getNodesAttribs(\@nodes, ['currstate']);
my $noderestab = xCAT::Table->new('noderes', -create => 1);
- my $nodereshash = $noderestab->getNodesAttribs(\@nodes, [ 'tftpdir', 'xcatmaster', 'nfsserver', 'servicenode' ]);
+ my $nodereshash = $noderestab->getNodesAttribs(\@nodes, [ 'tftpdir', 'xcatmaster', 'tftpserver', 'servicenode' ]);
my $typetab = xCAT::Table->new('nodetype', -create => 1);
my $typehash = $typetab->getNodesAttribs(\@nodes, [ 'os', 'provmethod', 'arch', 'profile' ]);
my $linuximgtab = xCAT::Table->new('linuximage', -create => 1);
diff --git a/xCAT-server/lib/xcat/plugins/seqdiscovery.pm b/xCAT-server/lib/xcat/plugins/seqdiscovery.pm
index 7b8858156..c8aad37e2 100755
--- a/xCAT-server/lib/xcat/plugins/seqdiscovery.pm
+++ b/xCAT-server/lib/xcat/plugins/seqdiscovery.pm
@@ -398,10 +398,15 @@ sub findme {
my $req = {%$request};
$req->{command} = ['discovered'];
$req->{noderange} = [$node];
- $request->{bmc_node} = [$bmc_node];
+ $req->{bmc_node} = [$bmc_node];
$req->{updateswitch} = ['yes'];
$subreq->($req);
+ if (defined($req->{error})) {
+ $request->{error}->[0] = '1';
+ $request->{error_msg}->[0] = $req->{error_msg}->[0];
+ }
+
%{$req} = (); #Clear req structure, it's done..
undef $mactab;
} else {
diff --git a/xCAT-server/lib/xcat/plugins/sles.pm b/xCAT-server/lib/xcat/plugins/sles.pm
index b8bcc50c1..fe288bd0f 100644
--- a/xCAT-server/lib/xcat/plugins/sles.pm
+++ b/xCAT-server/lib/xcat/plugins/sles.pm
@@ -411,41 +411,21 @@ sub mknetboot
my $ient;
my $xcatmaster;
- $ient = $restab->getNodeAttribs($node, ['xcatmaster']);
- if ($ient and $ient->{xcatmaster})
- {
+ $ient = $reshash->{$node}->[0]; #$restab->getNodeAttribs($node, ['tftpserver']);
+ if ($ient and $ient->{xcatmaster}) {
$xcatmaster = $ient->{xcatmaster};
} else {
$xcatmaster = '!myipfn!'; #allow service nodes to dynamically nominate themselves as a good contact point, this is of limited use in the event that xcat is not the dhcp/tftp server
}
- $ient = $restab->getNodeAttribs($node, ['tftpserver']);
- if ($ient and $ient->{tftpserver})
- {
+ if ($ient and $ient->{nfsserver} and $ient->{nfsserver} ne '') {
+ $imgsrv = $ient->{nfsserver};
+ }elsif ($ient and $ient->{tftpserver} and $ient->{tftpserver} ne '') {
$imgsrv = $ient->{tftpserver};
- }
- else
- {
- # $ient = $restab->getNodeAttribs($node, ['xcatmaster']);
- # if ($ient and $ient->{xcatmaster})
- # {
- # $imgsrv = $ient->{xcatmaster};
- # }
- # else
- # {
- # # master removed, does not work for servicenode pools
- # #$ient = $sitetab->getAttribs({key => master}, value);
- # #if ($ient and $ient->{value})
- # #{
- # # $imgsrv = $ient->{value};
- # #}
- # #else
- # #{
- # $imgsrv = '!myipfn!';
- # #}
- # }
+ } else {
$imgsrv = $xcatmaster;
}
+
unless ($imgsrv)
{
xCAT::MsgUtils->report_node_error($callback, $node, "Unable to determine or reasonably guess the image server for $node");
@@ -463,14 +443,8 @@ sub mknetboot
my $nfssrv = $imgsrv;
my $nfsdir = $rootimgdir;
- if ($restab) {
- my $resHash = $restab->getNodeAttribs($node, [ 'nfsserver', 'nfsdir' ]);
- if ($resHash and $resHash->{nfsserver}) {
- $nfssrv = $resHash->{nfsserver};
- }
- if ($resHash and $resHash->{nfsdir} ne '') {
- $nfsdir = $resHash->{nfsdir} . "/netboot/$osver/$arch/$profile";
- }
+ if ($ient->{nfsdir} ne '') {
+ $nfsdir = $ient->{nfsdir} . "/netboot/$osver/$arch/$profile";
}
if (&using_dracut($rootimgdir)) {
$kcmdline = "root=nfs:$nfssrv:$nfsdir/rootimg:ro STATEMNT=";
diff --git a/xCAT-server/lib/xcat/plugins/switch.pm b/xCAT-server/lib/xcat/plugins/switch.pm
index 024070b67..1ace2fffb 100644
--- a/xCAT-server/lib/xcat/plugins/switch.pm
+++ b/xCAT-server/lib/xcat/plugins/switch.pm
@@ -373,6 +373,10 @@ sub process_request {
$request->{noderange} = [$node];
$request->{bmc_node} = [$bmc_node];
$doreq->($request);
+ if (defined($request->{error})) {
+ $req->{error}->[0] = '1';
+ $req->{error_msg}->[0] = $request->{error_msg}->[0];
+ }
%{$request} = (); #Clear req structure, it's done..
undef $mactab;
} else {
diff --git a/xCAT-server/lib/xcat/plugins/switchdiscover.pm b/xCAT-server/lib/xcat/plugins/switchdiscover.pm
index cd465848a..d7374d9d3 100644
--- a/xCAT-server/lib/xcat/plugins/switchdiscover.pm
+++ b/xCAT-server/lib/xcat/plugins/switchdiscover.pm
@@ -1150,6 +1150,9 @@ sub get_switchtype {
$key = $1;
return $xCAT::data::switchinfo::global_switch_type{$key};
} else {
+ if (exists($globalopt{pdu})) {
+ return "irpdu";
+ }
return $key;
}
}
@@ -1190,7 +1193,7 @@ sub xCATdB {
# it's attribute
##################################################
if (exists($globalopt{pdu})) {
- $ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$host,"groups=$device","ip=$ip","mac=$mac","nodetype=$device","mgt=$device","usercomment=$vendor"] }, $sub_req, 0, 1);
+ $ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$host,"groups=$device","ip=$ip","mac=$mac","nodetype=$device","mgt=$device","usercomment=$vendor","pdutype=$stype"] }, $sub_req, 0, 1);
} else {
$ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$host,"groups=$device","ip=$ip","mac=$mac","nodetype=$device","mgt=$device","usercomment=$vendor","switchtype=$stype"] }, $sub_req, 0, 1);
}
@@ -1286,6 +1289,8 @@ sub format_stanza {
$result .= "\tnodetype=$device\n";
if (!exists($globalopt{pdu})) {
$result .= "\tswitchtype=$stype\n";
+ } else {
+ $result .= "\tpdutype=$stype\n";
}
}
return ($result);
@@ -1328,6 +1333,8 @@ sub format_xml {
$result .= "nodetype=$device\n";
if (!exists($globalopt{pdu})) {
$result .= "switchtype=$stype\n";
+ } else {
+ $result .= "\tpdutype=$stype\n";
}
my $href = {
@@ -1399,7 +1406,7 @@ sub matchPredefineSwitch {
# only write to xcatdb if -w or --setup option specified
if ( (exists($globalopt{w})) || (exists($globalopt{setup})) ) {
if (exists($globalopt{pdu})) {
- xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$node,"otherinterfaces=$ip",'status=Matched',"mac=$mac","usercomment=$vendor"] }, $sub_req, 0, 1);
+ xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$node,"otherinterfaces=$ip",'status=Matched',"mac=$mac","usercomment=$vendor","pdutype=$stype"] }, $sub_req, 0, 1);
} else {
xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$node,"otherinterfaces=$ip",'status=Matched',"mac=$mac","switchtype=$stype","usercomment=$vendor"] }, $sub_req, 0, 1);
}
diff --git a/xCAT-server/lib/xcat/plugins/typemtms.pm b/xCAT-server/lib/xcat/plugins/typemtms.pm
index 33e4e6d0f..5911cdcd2 100644
--- a/xCAT-server/lib/xcat/plugins/typemtms.pm
+++ b/xCAT-server/lib/xcat/plugins/typemtms.pm
@@ -61,6 +61,10 @@ sub findme {
$req->{bmc_node} = [$bmc_node];
$req->{updateswitch} = ['yes'];
$subreq->($req);
+ if (defined($req->{error})) {
+ $request->{error}->[0] = '1';
+ $request->{error_msg}->[0] = $req->{error_msg}->[0];
+ }
%{$req} = ();
}
}
diff --git a/xCAT-server/lib/xcat/plugins/updatenode.pm b/xCAT-server/lib/xcat/plugins/updatenode.pm
index f45d68689..729fed4dd 100644
--- a/xCAT-server/lib/xcat/plugins/updatenode.pm
+++ b/xCAT-server/lib/xcat/plugins/updatenode.pm
@@ -686,7 +686,6 @@ sub preprocess_updatenode
}
# Get the MN names
- my @MNip = xCAT::NetworkUtils->determinehostname;
my @MNnodeinfo = xCAT::NetworkUtils->determinehostname;
my $MNnodename = pop @MNnodeinfo; # hostname
my @MNnodeipaddr = @MNnodeinfo; # ipaddresses
@@ -1695,6 +1694,24 @@ sub updatenodesyncfiles
}
}
+ my $dsh_from_user_env;
+ # get the Environment Variables and set DSH_FROM_USERID if possible (From updatenode client)
+ if (defined($request->{environment})) {
+ foreach my $envar (@{ $request->{environment} })
+ {
+ if ($envar =~ /^DSH_FROM_USERID=/) {
+ $dsh_from_user_env = $envar;
+ last;
+ }
+ }
+ }
+ unless ($dsh_from_user_env) {
+ # $request->{username} is gotten from CN in client certificate
+ if (($request->{username}) && defined($request->{username}->[0])) {
+ $dsh_from_user_env = 'DSH_FROM_USERID=' . $request->{username}->[0];
+ }
+ }
+
my $node_syncfile = xCAT::SvrUtils->getsynclistfile($nodes);
foreach my $node (@$nodes)
{
@@ -1745,6 +1762,10 @@ sub updatenodesyncfiles
} else { # else this is updatenode -F
$env = ["DSH_RSYNC_FILE=$synclist"];
}
+ if ($dsh_from_user_env) {
+ push @$env, $dsh_from_user_env;
+ }
+
push @$args, "--nodestatus";
if (defined($::fanout)) { # fanout
push @$args, "-f";
@@ -1765,6 +1786,7 @@ sub updatenodesyncfiles
if ($::VERBOSE)
{
+ push @$args, "-T";
my $rsp = {};
$rsp->{data}->[0] =
" $localhostname: Internal call command: xdcp $nodestring " . join(' ', @$args);
diff --git a/xCAT-server/lib/xcat/plugins/xdsh.pm b/xCAT-server/lib/xcat/plugins/xdsh.pm
index 3378e512a..2a2c98fd5 100644
--- a/xCAT-server/lib/xcat/plugins/xdsh.pm
+++ b/xCAT-server/lib/xcat/plugins/xdsh.pm
@@ -639,6 +639,7 @@ sub process_servicenodes_xdcp
$addreq->{'_xcatdest'} = $::mnname;
$addreq->{node} = \@sn;
$addreq->{noderange} = \@sn;
+ $addreq->{forceroot}->[0] = 1;
# check input request for --nodestatus
my $args = $req->{arg}; # argument
@@ -1215,6 +1216,9 @@ sub process_request
$ENV{DSH_FROM_USERID} = $request->{username}->[0];
}
}
+ if ($request->{forceroot}) {
+ $ENV{DSH_FROM_USERID} = 'root';
+ }
if ($command eq "xdsh")
{
xdsh($nodes, $args, $callback, $command, $request->{noderange}->[0]);
diff --git a/xCAT-server/lib/xcat/plugins/zzzdiscovery.pm b/xCAT-server/lib/xcat/plugins/zzzdiscovery.pm
index f76338081..fb11381ff 100644
--- a/xCAT-server/lib/xcat/plugins/zzzdiscovery.pm
+++ b/xCAT-server/lib/xcat/plugins/zzzdiscovery.pm
@@ -22,11 +22,15 @@ sub process_request {
my $doreq = shift;
if ($req->{command}->[0] eq 'findme') {
- if (!defined($req->{discoverymethod}) or !defined($req->{discoverymethod}->[0]) or ($req->{discoverymethod}->[0] eq 'undef')) {
+ if (!defined($req->{discoverymethod}) or !defined($req->{discoverymethod}->[0]) or ($req->{discoverymethod}->[0] eq 'undef') or defined($req->{error})) {
+ my $error_msg = ".";
+ if (defined($req->{error_msg}) and defined($req->{error_msg}->[0])) {
+ $error_msg = ": ". $req->{error_msg}->[0];
+ }
my $rsp = {};
- $rsp->{error}->[0] = "The discovery request can not be processed";
+ $rsp->{error}->[0] = "The discovery request can not be processed".$error_msg;
$cb->($rsp);
- xCAT::MsgUtils->message("S", "xcat.discovery.zzzdiscovery: ($req->{_xcat_clientmac}->[0]) Failed to discover the node.");
+ xCAT::MsgUtils->message("S", "xcat.discovery.zzzdiscovery: ($req->{_xcat_clientmac}->[0]) Failed for node discovery".$error_msg);
#now, notify the node that its findme request has been processed
my $client_ip = $req->{'_xcat_clientip'};
diff --git a/xCAT-server/sbin/xcatd b/xCAT-server/sbin/xcatd
index fc67c1446..c06495070 100755
--- a/xCAT-server/sbin/xcatd
+++ b/xCAT-server/sbin/xcatd
@@ -58,13 +58,14 @@ unless (($^O =~ /^aix/i) || ($os =~ /^sle[sc]10/) || (($os =~ /^rh.*5$/) && ($ar
}
use File::Basename;
use File::Path;
-use Time::HiRes qw(sleep);
+use Time::HiRes qw(sleep time);
use Thread qw(yield);
use Fcntl qw/:DEFAULT :flock/;
use xCAT::Client qw(submit_request);
my $clientselect = new IO::Select;
my $sslclients = 0; # THROTTLE
my $maxsslclients = 64; # default
+my $maxsslclientswarntime = 0;
my $batchclients = 50;
my @deferredmsgargs; # hold argumentlist for MsgUtils call until after fork
# parallelizing logging overhead with real work
@@ -594,7 +595,7 @@ sub grant_tcrequests {
my $availableslots = $batchclients;
if (not keys %{$requestors}) { return; } # skip the interaction with SSL if
# no requests are actually pending
- my $oldtime = time() - 180; # drop requests older than three minutes if still around
+ my $oldtime = int(time()) - 180; # drop requests older than three minutes if still around
my $msg;
eval { store_fd({ 'req' => 'get_client_count' }, $sslctl); $msg = fd_retrieve($sslctl); };
@@ -813,7 +814,7 @@ sub do_udp_service { # This function opens up a UDP port
} else { # for *now*, we'll do a tiny YAML subset
if ($data =~ /^resourcerequest: xcatd$/) {
$socket->send("ackresourcerequest\n", 0, $packets{$pkey}->[0]);
- $tcclients->{$pkey} = { sockaddr => $packets{$pkey}->[0], timestamp => time() }
+ $tcclients->{$pkey} = { sockaddr => $packets{$pkey}->[0], timestamp => int(time()) }
}
} # JSON maybe one day if important
if ($quit) { last; }
@@ -1432,6 +1433,11 @@ until ($quit) {
}
unless (scalar @pendingconnections) { next; } # if for some reason we landed here without any accepted connections, carry on..
if ($sslclients > $maxsslclients) { # we have enough children, wait for some to exit before spawning more
+ my $curtime = time();
+ if ($curtime > ($maxsslclientswarntime + 30)) {
+ xCAT::MsgUtils->message("S", "xcatd: Connections are being throttled. Current client count (" . ($sslclients + scalar @pendingconnections) . ") is greater than allowed ($maxsslclients)");
+ $maxsslclientswarntime=$curtime;
+ }
$bothwatcher->can_read(0.1); # when next connection tries to come in or a tenth of a second, whichever comes first
next; # just keep pulling things off listen queue onto our own
}
@@ -2046,8 +2052,9 @@ sub plugin_command {
my $nextxmittime = time() + 1;
while (($plugin_numchildren > 0) and ($check_fds->count > 0)) { # this tracks end of useful data from children much more closely
relay_fds($check_fds, $xcatresponses{xcatresponse});
- if (time() > $nextxmittime) {
- $nextxmittime = time() + 1;
+ my $currenttime = time();
+ if ($currenttime > $nextxmittime) {
+ $nextxmittime = $currenttime + 1;
send_response(\%xcatresponses, $sock);
$xcatresponses{xcatresponse} = [];
}
@@ -2930,7 +2937,7 @@ sub service_connection {
}
# ----used for command log start-------
- my $reqhandletime = time()-$cmdlog_starttime;
+ my $reqhandletime = sprintf("%.3f", time()-$cmdlog_starttime);
$cmdlog_alllog .= "[ElapsedTime] $reqhandletime s\n";
cmdlog_submitlog();
@@ -3002,7 +3009,7 @@ sub relay_fds { # Relays file descriptors from pipes to children to the SSL sock
# ----used for command log start-------
$cmdlog_alllog .= "Client abort requested\n";
- my $reqhandletime = time()-$cmdlog_starttime;
+ my $reqhandletime = sprintf("%.3f", time()-$cmdlog_starttime);
$cmdlog_alllog .= "[ElapsedTime] $reqhandletime s\n";
cmdlog_submitlog();
diff --git a/xCAT-server/share/xcat/cons/openbmc b/xCAT-server/share/xcat/cons/openbmc
index 1c503839c..91854150c 100755
--- a/xCAT-server/share/xcat/cons/openbmc
+++ b/xCAT-server/share/xcat/cons/openbmc
@@ -3,6 +3,7 @@
use Fcntl qw(:DEFAULT :flock);
use Time::HiRes qw(sleep);
use File::Path;
+use IO::Socket;
BEGIN {
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr';
}
@@ -91,9 +92,33 @@ if ($ENV{SSHCONSOLEPORT}) {
$sshport= $ENV{SSHCONSOLEPORT};
}
+#check if sshport is up
+my $sock = IO::Socket::INET->new(
+ PeerAddr => $bmcip,
+ PeerPort => $sshport,
+ Proto => "tcp",
+ Timeout => 10
+ );
+while (!defined($sock)) {
+ $sleepint = 10 + int(rand(20));
+ print "No BMC active at IP $bmcip, retrying in $sleepint seconds (Hit Ctrl-E,c,o to skip)\n";
+ sleep ($sleepint);
+ acquire_lock();
+ sleep(0.1);
+ release_lock();
+ $sock = IO::Socket::INET->new(
+ PeerAddr => $bmcip,
+ PeerPort => $sshport,
+ Proto => "tcp",
+ Timeout => 10
+ );
+}
+$sock->close();
+
+
# To automatically connect to the console without the need to send over the ssh keys,
# ensure sshpass is installed on the Management and/or Service Nodes.
-print "If unable to open the console, ensure sshpass is installed or ssh keys have been configured on the BMC.\n";
+print "Unable to open console. If BMC pings, ensure sshpass is installed or ssh keys have been configured on the BMC.\n";
if (-x '/usr/bin/sshpass') {
exec "/usr/bin/sshpass -p $password ssh -p $sshport -l $username -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $bmcip";
} else {
diff --git a/xCAT-server/share/xcat/netboot/rh/genimage b/xCAT-server/share/xcat/netboot/rh/genimage
index 9a7e5d9e5..2b535fea6 100755
--- a/xCAT-server/share/xcat/netboot/rh/genimage
+++ b/xCAT-server/share/xcat/netboot/rh/genimage
@@ -455,7 +455,30 @@ unless ($onlyinitrd) {
}
my %extrapkgnames;
my %repohash;
+
+
+
if (keys(%extra_hash) > 0) {
+ my @otherpkgdir_url;
+ my @otherpkgdir_local;
+ foreach my $tmpdir (split ',', $srcdir_otherpkgs){
+ if($tmpdir =~ /^http:.*/){
+ push @otherpkgdir_url, $tmpdir;
+ }else{
+ push @otherpkgdir_local,$tmpdir;
+ }
+ }
+
+ if(scalar @otherpkgdir_local >1){
+ print "genimage: at most only 1 local dir in otherpkgdir is supported.\n";
+ exit 1;
+ }
+
+ my $srcdir_otherpkgs_local;
+ if(scalar @otherpkgdir_local == 1){
+ $srcdir_otherpkgs_local=$otherpkgdir_local[0];
+ }
+
open($yumconfig, ">>", "/tmp/genimage.$$.yum.conf");
my $index = 1;
foreach $pass (sort { $a <=> $b } (keys(%extra_hash))) {
@@ -468,7 +491,13 @@ unless ($onlyinitrd) {
}
if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next; }
- print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n";
+ foreach(@otherpkgdir_url){
+ print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=$_\ngpgpcheck=0\n\n";
+ $repohash{$pass}{$index} = 1;
+ $index++;
+ }
+
+ print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs_local/$_\ngpgpcheck=0\n\n";
$repohash{$pass}{$index} = 1;
$index++;
my $pa = $extra_hash{$pass}{$_};
@@ -488,10 +517,6 @@ unless ($onlyinitrd) {
$yumcmd_base .= "--enablerepo=$osver-$arch-$_ ";
}
- # for (1..$index) {
- # $yumcmd .= "--enablerepo=otherpkgs$_ ";
- # }
-
# Hack uname when deal otherpkgs
use_hackuname($arch, $kernelver);
use_devnull();
diff --git a/xCAT-server/share/xcat/netboot/sles/genimage b/xCAT-server/share/xcat/netboot/sles/genimage
index 0f914415e..944c48485 100755
--- a/xCAT-server/share/xcat/netboot/sles/genimage
+++ b/xCAT-server/share/xcat/netboot/sles/genimage
@@ -615,7 +615,7 @@ if ((-d "$rootimg_dir/usr/share/dracut") or (-d "$rootimg_dir/usr/lib/dracut"))
$dracutmode = 1;
# get dracut version
- $dracutver = `chroot $rootimg_dir rpm -qi dracut | awk '/Version/{print \$3}' `;
+ $dracutver = `chroot $rootimg_dir rpm -qi dracut | awk '/Version/{print \$3}' | awk -F. '{print \$1}'`;
chomp($dracutver);
if ($dracutver =~ /^\d\d\d$/) {
if ($dracutver >= "033") {
diff --git a/xCAT-server/share/xcat/scripts/configonie b/xCAT-server/share/xcat/scripts/configonie
index b3ba6ce27..64a78c942 100755
--- a/xCAT-server/share/xcat/scripts/configonie
+++ b/xCAT-server/share/xcat/scripts/configonie
@@ -153,6 +153,7 @@ sub config_ssh {
print "$switch is not reachable\n";
next;
}
+
my ($exp, $errstr) = cumulus_connect($ssh_ip, $userid, $password, $timeout);
if (!defined $exp) {
@@ -290,6 +291,9 @@ sub install_license {
xCAT::MsgUtils->message("E","Failed to $cmd to $switch");
next;
}
+ #restart switchd and reload interface
+ $cmd = "xdsh $switch 'systemctl enable switchd;systemctl restart switchd;ifreload -a' ";
+ xCAT::Utils->runcmd($cmd, 0);
push (@config_switches, $switch);
}
if (@config_switches) {
@@ -350,8 +354,35 @@ sub config_snmp {
sub config_ntp {
my @config_switches;
my $cmd;
+ my $master;
+ my $ntpservers;
+ my $timezone;
+
+
+ #get ntpserver, master and timezone from site table
+ my @entries = xCAT::TableUtils->get_site_attribute("master");
+ my $master = $entries[0];
+
+ @entries = xCAT::TableUtils->get_site_attribute("timezone");
+ $timezone = $entries[0];
+
+ @entries = xCAT::TableUtils->get_site_attribute("ntpservers");
+ my $t_entry = $entries[0];
+ if (defined($t_entry)) {
+ $ntpservers = $t_entry;
+ } else {
+ $ntpservers = $master;
+ }
+
+ my @servers = split(',', $ntpservers);
+
+ #use ntpserver from network table if available
+ my $nettab = xCAT::Table->new("networks");
+ my @nets;
+ if ($nettab) {
+ @nets = $nettab->getAllAttribs('net','mask','ntpservers');
+ }
- my $master = `hostname -i`;
my $file = "temp.txt";
open(FILE , ">$file")
@@ -360,7 +391,6 @@ sub config_ntp {
print FILE "driftfile /var/lib/ntp/drift\n";
print FILE "disable auth\n";
print FILE "restrict 127.0.0.1\n";
- print FILE "server $master iburst\n";
print FILE "interface listen eth0\n";
foreach my $switch (@nodes) {
@@ -371,15 +401,31 @@ sub config_ntp {
xCAT::MsgUtils->message("E","xdsh command to $switch failed");
next;
}
- my $cmd_line = "echo 'US/Eastern'>/etc/timezone;dpkg-reconfigure --frontend noninteractive tzdata";
- print "$cmd_line\n";
- $cmd = "xdsh $switch $cmd_line";
+ $cmd = "xdsh $switch 'echo $timezone >/etc/timezone;dpkg-reconfigure --frontend noninteractive tzdata' ";
+ $rc= xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0) {
print "Failed to update ntp timezone\n";
xCAT::MsgUtils->message("E","Failed to update ntp timezone for $switch");
- next;
}
- print "$cmd\n";
+ #use ntpserver from network table if available
+ my $ntpserver;
+ foreach my $net (@nets) {
+ if (xCAT::NetworkUtils::isInSameSubnet( $net->{'net'}, $switch, $net->{'mask'}, 0)) {
+ $ntpserver=$net->{'ntpservers'};
+ if (defined $ntpserver) {
+ if ($ntpserver =~ /xcatmaster/) {
+ @servers = $master;
+ } else {
+ @servers = split(',', $ntpserver);
+ }
+ }
+ last;
+ }
+ }
+ foreach my $server (@servers) {
+ `echo "server $server iburst" >> $file`;
+ }
+
$cmd = "xdcp $switch $file";
$rc= xCAT::Utils->runcmd($cmd, 0);
$cmd = "xdsh $switch 'cp /etc/ntp.conf /etc/ntp.conf.orig;cp $file /etc/ntp.conf;rm -fr $file;systemctl restart ntp;systemctl enable ntp' ";
@@ -398,6 +444,7 @@ sub config_ntp {
my $csw = join(",",@config_switches);
$cmd = "chdef $csw status=ntp_configured";
$rc= xCAT::Utils->runcmd($cmd, 0);
+ print "$csw: ntp configured\n";
}
diff --git a/xCAT-server/share/xcat/scripts/xHRM b/xCAT-server/share/xcat/scripts/xHRM
index 9b8dc8576..64d015911 100755
--- a/xCAT-server/share/xcat/scripts/xHRM
+++ b/xCAT-server/share/xcat/scripts/xHRM
@@ -1,6 +1,6 @@
-#!/bin/bash
-if [ "$(uname -s|tr 'A-Z' 'a-z')" = "linux" ];then
- str_dir_name=`dirname $0`
+#!/bin/bash
+if [ "$(uname -s|tr '[:upper:]' '[:lower:]')" = "linux" ];then
+ str_dir_name=$(dirname $0)
. $str_dir_name/xcatlib.sh
fi
#written in bash for fewest prerequisites
@@ -9,35 +9,35 @@ function get_def_interface {
#are in bash, the best alternative is to use ping to get at it
#don't want to grep in /etc/hosts or presume DNS
#we are, however, presuming ipv4 for the moment
- retval=$(ping -c 1 `hostname`|head -n 1|cut -d\( -f 2|cut -d\) -f 1)
+ retval=$(ping -c 1 "$(hostname)"|head -n 1|cut -d\( -f 2|cut -d\) -f 1)
if [ -z "$retval" -o "127.0.0.1" = "$retval" ]; then #ok, that didn't pan out, now we grab the first address that looks sane
#retval=`ifconfig|grep inet" " |grep -v addr:127.0.0.1|grep -v 'addr:169.254'|head -n 1|cut -d: -f 2|cut -d' ' -f 1`
- retval=`ip -4 -oneline addr show|grep -v "127.0.0.1"|grep -v '169.254'|head -n 1|awk -F 'inet ' '{print $2}'|awk -F '/' '{print $1}'`
+ retval=$(ip -4 -oneline addr show|grep -v "127.0.0.1"|grep -v '169.254'|head -n 1|awk -F 'inet ' '{print $2}'|awk -F '/' '{print $1}')
fi
if [ -z "$retval" ]; then
echo "ERROR: Unable to reasonably guess the 'default' interface" >&2
exit 1
fi
#iface=`ifconfig|grep -v inet6|egrep '(Link|inet)'|grep -B1 'addr:'$retval |head -n 1|awk '{print $1}'`
- iface=`ip -4 -oneline addr show|grep -i $retval|awk -F ':' '{print $2}'|awk -F ' ' '{print $1}'|grep -o "[^ ]\+\( \+[^ ]\+\)*"`
+ iface=$(ip -4 -oneline addr show|grep -i $retval|awk -F ':' '{print $2}'|awk -F ' ' '{print $1}'|grep -o "[^ ]\+\( \+[^ ]\+\)*")
if [ -z "$iface" ]; then
echo "ERROR: Unable to reasonably guess the default interface" >&2
exit 1
fi
- if brctl show | grep ^$iface >& /dev/null; then #
+ if brctl show | grep ^$iface &> /dev/null; then #
OIFS=$IFS
IFS=$'\n'
INMATCH=0
for brline in $(brctl show); do
IFS=$OIFS
- if [ $(expr match "$brline" $iface) == $(expr length $iface) ]; then
+ if [ "$(expr match "$brline" $iface)" == ${#iface} ]; then
INMATCH=1
- elif [ $(expr match "$brline" " ") != 1 ]; then
+ elif [ "$(expr match "$brline" " ")" != 1 ]; then
INMATCH=0
fi
if [ "$INMATCH" == 1 ]; then
- if ! ethtool -i `echo $brline|awk '{print $NF}'`|grep "driver: tun" >& /dev/null; then
- iface=`echo $brline|awk '{print $NF}'`
+ if ! ethtool -i "$(echo $brline|awk '{print $NF}')"|grep "driver: tun" >& /dev/null; then
+ iface=$(echo $brline|awk '{print $NF}')
echo "$iface"
IFS=$OFIS
return
@@ -60,7 +60,7 @@ function debianpreconf(){
mkdir -p "/etc/network/interfaces.d"
fi
#search xcat flag
- XCATFLAG=`grep "#XCAT_CONFIG" /etc/network/interfaces`
+ XCATFLAG=$(grep "#XCAT_CONFIG" /etc/network/interfaces)
if [ -n "$XCATFLAG" ];then
return
fi
@@ -77,8 +77,7 @@ function debianpreconf(){
CONFFILE=''
#read the backfile
- cat /etc/network/interfaces.bak | while read LINE
- do
+ while read LINE; do
if [ ! "$LINE" ];then
continue
fi
@@ -87,7 +86,7 @@ function debianpreconf(){
continue
fi
- CONFTYPE=`echo $LINE | cut -d" " -f1`
+ CONFTYPE=$(echo $LINE | cut -d" " -f1)
if [ $CONFTYPE = 'auto' -o $CONFTYPE = 'allow-hotplug' ];then
LINE=${LINE#$CONFTYPE}
for NICNAME in $LINE; do
@@ -95,7 +94,7 @@ function debianpreconf(){
done
elif [ $CONFTYPE = 'iface' -o $CONFTYPE = 'mapping' ];then
#find out the nic name, should think about the eth0:1
- NICNAME=`echo $LINE | cut -d" " -f 2 | cut -d":" -f 1`
+ NICNAME=$(echo $LINE | cut -d" " -f 2 | cut -d":" -f 1)
CONFFILE="/etc/network/interfaces.d/$NICNAME"
if [ ! -e $CONFFILE ];then
echo "auto $NICNAME" > $CONFFILE
@@ -107,13 +106,13 @@ function debianpreconf(){
echo $LINE >> $CONFFILE
fi
- done
+ done /dev/null; then
exit 0;
fi
@@ -124,64 +123,54 @@ elif [ "bridgeprereq" = "$1" ]; then
modprobe bridge
NETDESC="$2"
- # get the port for installation
- if [ -n "$INSTALLNIC" ]; then
- INSPORT=$INSTALLNIC
- elif [ -n "$PRIMARYNIC" ]; then
- INSPORT=$PRIMARYNIC
- fi
- if [ -z "$INSPORT" ] || [[ "$INSPORT" =~ ^(mac|MAC)$ ]]; then
- if [ -n "$MACADDRESS" ] ; then
- INSPORT=$MACADDRESS;
- else
- echo "should configure mac in $NODE definition."
- exit 1
- fi
- fi
-
- if [[ "$INSPORT" =~ ^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$ ]] ; then
- INSPORT=`ip -oneline link show|grep -i ether|grep -i $INSPORT |awk -F ':' '{print $2}'|grep -o "[^ ]\+\( \+[^ ]\+\)*"`
- fi
-
- if [ -z "$NETDESC" ]; then
- if [ -n "$INSPORT" ]; then
- NETDESC=$INSPORT:default
- else
- echo "Incorrect usage"
- exit 1
- fi
- fi
if echo "$NETDESC"|grep ':'> /dev/null; then
- PORTS=`echo "$NETDESC"|cut -d: -f 1`
- BNAME=`echo "$NETDESC"|cut -d: -f 2`
+ PORTS=$(echo "$NETDESC"|cut -d: -f 1)
+ BNAME=$(echo "$NETDESC"|cut -d: -f 2)
else
- if [ -n "$INSTALLNIC" ]; then
- PORTS=$INSPORT
+ if [ -n "$NETDESC" ]; then
+ BNAME=$NETDESC
+ else
+ BNAME=default
fi
- BNAME=$NETDESC
+
+ # get the port for installation
+ if [ -n "$INSTALLNIC" ]; then
+ PORTS=$INSTALLNIC
+ elif [ -n "$PRIMARYNIC" ]; then
+ PORTS=$PRIMARYNIC
+ else
+ PORTS=$(get_def_interface)
+ fi
+
+ if [ -z "$PORTS" ] || [[ "$PORTS" =~ ^(mac|MAC)$ ]]; then
+ if [ -n "$MACADDRESS" ] ; then
+ PORTS=$(ip -oneline link show|grep -i ether|grep -i $MACADDRESS |awk -F ':' '{print $2}'|grep -o "[^ ]\+\( \+[^ ]\+\)*")
+ else
+ echo "should configure mac in $NODE definition."
+ exit 1
+ fi
+ fi
+
fi
# To check whether the brctl have been installed
- if ! which brctl > /dev/null; then
+ if ! which brctl &> /dev/null; then
echo "No bridge-utils installed, pls install it first"
exit 1
fi
- if brctl showstp "$BNAME" > /dev/null; then
- echo "$BNAME"
+ if brctl showstp "$BNAME" &> /dev/null; then
+ echo "$BNAME already exists"
exit 0
fi
- #Still here, that means we must build a bridge
- if [ -z "$PORTS" ]; then #No ports specified, default to whatever looks up
- PORTS=$(get_def_interface)
- fi
+
if [ -z "$PORTS" ]; then #This has been checked many times before in theory, check again just in case
exit 1
fi
#TO check whether the NIC had been attached to another bridge
- bridgename=`brctl show |grep $PORTS`
+ bridgename=$(brctl show |grep $PORTS)
if [ ! -z "$bridgename" ]; then
echo "Device $PORTS is already a member of another bridge"
exit 1
@@ -195,15 +184,15 @@ elif [ "bridgeprereq" = "$1" ]; then
if echo "$PORTS"|grep '&'; then #we have bonding... fun to be had
#To be slack, going to just support one bond for now..
modprobe bonding miimon=100 mode=4
- PORTS=`echo $PORTS |sed -e 's/&/ /'`
+ PORTS="${PORTS//&/ }"
ip link set bond0 up
for p in $PORTS; do
#TODO: we are only going to manage the default
#route for now
- saveroutes=`ip route | grep default| grep "dev $p"|grep via|sed -e 's/dev .*//'`
+ saveroutes=$(ip route | grep default| grep "dev $p"|grep via|sed -e 's/dev .*//')
OIFS=$IFS
IFS=$'\n'
- saveip=`ip addr show dev $p scope global|grep inet|grep -v dynamic|sed -e 's/inet.//'|sed -e 's/[^ ]*$//'`
+ saveip=$(ip addr show dev $p scope global|grep inet|grep -v dynamic|sed -e 's/inet.//'|sed -e 's/[^ ]*$//')
if [ ! -z "$saveip" ]; then
for line in $saveip; do
ip addr add dev bond0 $line
@@ -235,16 +224,12 @@ elif [ "bridgeprereq" = "$1" ]; then
brctl addbr $BNAME
brctl setfd $BNAME 0 #fast forwarding
ip link set $BNAME up
- saveroutes=`ip route | grep default| grep "dev $PORTS"|grep via|sed -e 's/dev .*//'`
- OIFS=$IFS
- IFS=$'\n'
- saveip=`ip addr show dev $PORTS scope global|grep inet|sed -e 's/inet.//'|sed -e 's/[^ ]*$//'`
+ saveroutes="$(ip route | grep default| grep "dev $PORTS"|grep via|sed -e 's/dev .*//')"
+ saveip="$(ip -4 -o addr show dev $PORTS scope global | sed 's/.*inet //'| sed 's/\( global \).*/\1/')"
if [ ! -z "$saveip" ]; then
- for line in $saveip; do
- IFS=$OIFS
- newline=`echo $line|sed 's/dynamic//g'`
- ip addr add dev $BNAME $newline
- done
+ while read line; do
+ ip addr add dev $BNAME ${line//dynamic}
+ done <<<"$saveip"
else
if [ ! -z "$3" ]; then
ip addr add dev $BNAME $3
@@ -252,16 +237,10 @@ elif [ "bridgeprereq" = "$1" ]; then
fi
brctl addif $BNAME $PORTS
if [ ! -z "$saveip" ]; then
- OIFS=$IFS
- IFS=$'\n'
- for line in $saveip; do
- IFS=$OIFS
- newline=`echo $line|sed 's/dynamic//g'`
- ip addr del dev $PORTS $newline
- done
- IFS=$OIFS
+ while read line; do
+ ip addr del dev $PORTS ${line//dynamic}
+ done <<<"$saveip"
fi
- IFS=$OIFS
if [ ! -z "$saveroutes" ]; then
ip route add $saveroutes
fi
@@ -284,19 +263,19 @@ elif [ "bridgeprereq" = "$1" ]; then
#write into the network configuration file
if [[ $isSLES -eq 1 ]]; then
- cat >$nwdir/ifcfg-$PORTS <> $nwdir/ifcfg-$PORTS
+ echo "HWADDR='$mac'"
fi
if [ ! -z "$vlan" ]; then
- echo "VLAN='yes'" >> $nwdir/ifcfg-$PORTS
- fi
- cat >$nwdir/ifcfg-$BNAME <"$nwdir/ifcfg-$PORTS"
+ { cat <> $nwdir/ifcfg-$BNAME
+ echo "IPADDR='$3'"
if [ ! -z "$4" ]; then
- echo "NETMASK='$4'" >> $nwdir/ifcfg-$BNAME
+ echo "NETMASK='$4'"
fi
else
- echo "BOOTPROTO=dhcp" >> $nwdir/ifcfg-$BNAME
- fi
+ echo "BOOTPROTO=dhcp"
+ fi; } >$nwdir/ifcfg-$BNAME
elif [ $isDebian ];then
#ubuntu/debian
echo "auto $PORTS" >$nwdir/$PORTS
@@ -320,46 +299,48 @@ EOF
echo " vlan-raw-device $PORTORG"
fi
- echo "auto $BNAME" > $nwdir/$BNAME
+ { echo "auto $BNAME"
if [ ! -z "$3" ];then
- echo "iface $BNAME inet static" >> $nwdir/$BNAME
- echo " address $3" >> $nwdir/$BNAME
+ echo "iface $BNAME inet static"
+ echo " address $3"
if [ ! -z "$4" ];then
- echo " netmask $4" >> $nwdir/$BNAME
+ echo " netmask $4"
else
- echo " netmask 255.255.255.0" >> $nwdir/$BNAME
+ echo " netmask 255.255.255.0"
fi
else
- my_subnet=`ip addr show dev $BNAME scope global|grep inet|grep -v dynamic|sed -e 's/inet.//'| awk '{print $1}'`
+ my_subnet=$(ip -4 -o addr show dev "$BNAME" scope global | awk '!/dynamic/{print $4}' )
if [ ! -z "$my_subnet" ]; then
- bridge_ip=`echo "$my_subnet"|cut -d\/ -f 1`
- bridge_mask=`echo "$my_subnet"|cut -d\/ -f 2`
- bridge_mask=`v4prefix2mask $bridge_mask`
- echo "iface $BNAME inet static" >> $nwdir/$BNAME
- echo " address $bridge_ip" >> $nwdir/$BNAME
- echo " netmask $bridge_mask" >> $nwdir/$BNAME
+ bridge_ip="${my_subnet//\/*}"
+ bridge_mask="${my_subnet##*\/}"
+ bridge_mask=$(v4prefix2mask "$bridge_mask")
+ echo "iface $BNAME inet static"
+ echo " address $bridge_ip"
+ echo " netmask $bridge_mask";
else
- echo "iface $BNAME inet dhcp" >> $nwdir/$BNAME
+ echo "iface $BNAME inet dhcp"
fi
fi
- echo " bridge_ports $PORTS" >> $nwdir/$BNAME
- echo " bridge_stp off" >> $nwdir/$BNAME
- echo " bridge_fd 0" >> $nwdir/$BNAME
- echo " bridge_maxwait 0" >> $nwdir/$BNAME
+ echo " bridge_ports $PORTS"
+ echo " bridge_stp off"
+ echo " bridge_fd 0"
+ echo " bridge_maxwait 0"; } > "$nwdir/$BNAME"
else
- cat >$nwdir/ifcfg-$PORTS <> $nwdir/ifcfg-$PORTS
+ echo "HWADDR=$mac"
fi
if [ ! -z "$vlan" ]; then
- echo "VLAN=yes" >> $nwdir/ifcfg-$PORTS
- fi
- cat >$nwdir/ifcfg-$BNAME <"$nwdir/ifcfg-$PORTS"
+ { cat <> $nwdir/ifcfg-$BNAME
+ echo "IPADDR=$3"
if [ ! -z "$4" ]; then
- echo "NETMASK=$4" >> $nwdir/ifcfg-$BNAME
+ echo "NETMASK=$4"
fi
else
- echo "BOOTPROTO=dhcp" >> $nwdir/ifcfg-$BNAME
- fi
+ echo "$ATTRS"
+ fi ; } > "$nwdir/ifcfg-$BNAME"
fi
- ifdown $BNAME;ifup $BNAME
+ ifdown "$BNAME"; ifup "$BNAME"
fi #END bridge config.
-
-
diff --git a/xCAT-server/share/xcat/scripts/xdcpmerge.sh b/xCAT-server/share/xcat/scripts/xdcpmerge.sh
index b7724e9f1..39922add6 100755
--- a/xCAT-server/share/xcat/scripts/xdcpmerge.sh
+++ b/xCAT-server/share/xcat/scripts/xdcpmerge.sh
@@ -82,24 +82,22 @@ for i in $*; do
done
# remove the last delimiter
userlisttmp="${userlist%?}"
- listend=")'"
+ listend="):'"
userlist=$userlisttmp$listend
grepcmd=$grepcmd$userlist
#set -x
- grepcmd="$grepcmd $filebackup > $filebackup.nodups"
+ grepcmd="$grepcmd $mergefile > $mergefile.nodups"
#echo "grepcmd=$grepcmd"
# now run it
eval $grepcmd
- # if no dups file created
- if [ -s "$filebackup.nodups" ]; then
- cp -p $filebackup.nodups $filebackup
- #echo "cp -p $filebackup.nodups $filebackup"
- rm $filebackup.nodups
- fi
fi
- # Now update the currentfile
- cat $filebackup $mergefile > $curfile
- #echo "cat $filebackup $mergefile > $curfile"
+
+ # add new entries from mergefile, if any
+ if [ -a "$mergefile.nodups" ]; then
+ cat $mergefile.nodups >> $curfile
+ rm $mergefile.nodups
+ fi
+
# now cleanup
rm $filebackup.userlist
# echo "rm $filebackup.userlist"
diff --git a/xCAT-test/autotest/bundle/hdctrl_openpower_openbmc.bundle b/xCAT-test/autotest/bundle/hdctrl_openpower_openbmc.bundle
index d7233bcf8..f7ac6792d 100644
--- a/xCAT-test/autotest/bundle/hdctrl_openpower_openbmc.bundle
+++ b/xCAT-test/autotest/bundle/hdctrl_openpower_openbmc.bundle
@@ -1,14 +1,13 @@
description:the cases in this bundle is to used to verify xCAT hardware control funtions on openpower servers which are mananged using openbmc.
#INCLUDE:hdctrl_general.bundle#
-rinv_uuid
-rinv_vpd
rinv_cpu
rinv_dimm
+rinv_check_active_fw_count
+rinv_check_active_fw_count_verbose
rinv_wrongbmcpasswd
rvitals_wattage
rvitals_fanspeed
rvitals_power
-rvitals_leds
rvitals_altitude
rsetboot_net_statcheck
rsetboot_cd_statcheck
@@ -38,4 +37,41 @@ rspconfig_set_all
rspconfig_set_all_invalid
rspconfig_set_vlan
rspconfig_set_vlan_invalid
+rflash_option_c_without_specify_noderange
+rflash_option_l_without_specify_noderange
+rflash_option_a_without_specify_noderange
+rflash_option_u_without_specify_noderange
+rflash_option_d_without_specify_noderange
+rflash_without_option
+rflash_unsupport_multiple_option_a_u
+rflash_unsupport_multiple_option_a_c
+rflash_unsupport_multiple_option_a_l
+rflash_unsupport_multiple_option_a_d
+rflash_unsupport_multiple_option_c_l
+rflash_unsupport_multiple_option_c_u
+rflash_unsupport_multiple_option_c_d
+rflash_unsupport_multiple_option_l_d
+rflash_unsupport_multiple_option_l_u
+rflash_unsupport_multiple_option_u_d
+rflash_option_c_file_not_exist
+rflash_option_c_with_multiple_values
+rflash_option_c_against_node
+rflash_option_check_with_V_against_node
+rflash_option_l_with_value
+rflash_option_l
+rflash_option_u_file_not_exist
+rflash_option_u_with_multiple_values
+rflash_option_a_file_not_exist
+rflash_option_a_with_multiple_values
+rflash_option_a_with_non_existent_id
+rflash_option_delete_with_multiple_values
+rflash_option_delete_with_non_existent_id
+rflash_option_d_with_multiple_values
+rflash_option_d_with_non_existent_dir
+rflash_usage
+reventlog_s_openbmc
+rpower_softoff
+rpower_suspend_OpenpowerBmc
+rpower_wake_OpenpowerBmc
+rpower_errorcommand_OpenpowerBmc
rpower_wrongpasswd
diff --git a/xCAT-test/autotest/bundle/rhels6.7_ppc64.bundle b/xCAT-test/autotest/bundle/rhels6.7_ppc64.bundle
index a8baaf719..0c63b2152 100644
--- a/xCAT-test/autotest/bundle/rhels6.7_ppc64.bundle
+++ b/xCAT-test/autotest/bundle/rhels6.7_ppc64.bundle
@@ -270,9 +270,6 @@ updatenode_postscripts_loginfo
bmcdiscover_h
bmcdiscover_nmap_range
bmcdiscover_v
-bmcdiscover_check_paswd
-bmcdiscover_check_passwd_wrong
-bmcdiscover_get_ipsource
bmcdiscover_range_w
bmcdiscover_range_z
xcatd_start
diff --git a/xCAT-test/autotest/bundle/rhels6.8_ppc64.bundle b/xCAT-test/autotest/bundle/rhels6.8_ppc64.bundle
index 8e2b31650..a52f8f658 100644
--- a/xCAT-test/autotest/bundle/rhels6.8_ppc64.bundle
+++ b/xCAT-test/autotest/bundle/rhels6.8_ppc64.bundle
@@ -279,9 +279,6 @@ updatenode_postscripts_loginfo
bmcdiscover_h
bmcdiscover_nmap_range
bmcdiscover_v
-bmcdiscover_check_paswd
-bmcdiscover_check_passwd_wrong
-bmcdiscover_get_ipsource
bmcdiscover_range_w
bmcdiscover_range_z
xcatd_start
diff --git a/xCAT-test/autotest/bundle/rhels6.9_ppc64.bundle b/xCAT-test/autotest/bundle/rhels6.9_ppc64.bundle
index 8c51b3bde..6383297db 100644
--- a/xCAT-test/autotest/bundle/rhels6.9_ppc64.bundle
+++ b/xCAT-test/autotest/bundle/rhels6.9_ppc64.bundle
@@ -286,9 +286,6 @@ updatenode_postscripts_loginfo
bmcdiscover_h
bmcdiscover_nmap_range
bmcdiscover_v
-bmcdiscover_check_paswd
-bmcdiscover_check_passwd_wrong
-bmcdiscover_get_ipsource
bmcdiscover_range_w
bmcdiscover_range_z
xcatd_start
diff --git a/xCAT-test/autotest/bundle/rhels7.2_ppc64.bundle b/xCAT-test/autotest/bundle/rhels7.2_ppc64.bundle
index 9052328cc..8ec407b9c 100644
--- a/xCAT-test/autotest/bundle/rhels7.2_ppc64.bundle
+++ b/xCAT-test/autotest/bundle/rhels7.2_ppc64.bundle
@@ -283,9 +283,6 @@ updatenode_postscripts_loginfo
bmcdiscover_h
bmcdiscover_nmap_range
bmcdiscover_v
-bmcdiscover_check_paswd
-bmcdiscover_check_passwd_wrong
-bmcdiscover_get_ipsource
bmcdiscover_range_w
bmcdiscover_range_z
xcatd_start
diff --git a/xCAT-test/autotest/bundle/rhels7.2_ppc64le.bundle b/xCAT-test/autotest/bundle/rhels7.2_ppc64le.bundle
index 5d0b84fc1..5897e2359 100644
--- a/xCAT-test/autotest/bundle/rhels7.2_ppc64le.bundle
+++ b/xCAT-test/autotest/bundle/rhels7.2_ppc64le.bundle
@@ -276,9 +276,6 @@ updatenode_postscripts_loginfo
bmcdiscover_h
bmcdiscover_nmap_range
bmcdiscover_v
-bmcdiscover_check_paswd
-bmcdiscover_check_passwd_wrong
-bmcdiscover_get_ipsource
bmcdiscover_range_w
bmcdiscover_range_z
xcatd_start
diff --git a/xCAT-test/autotest/bundle/rhels7.3_ppc64.bundle b/xCAT-test/autotest/bundle/rhels7.3_ppc64.bundle
index f7719f913..4a97903ff 100644
--- a/xCAT-test/autotest/bundle/rhels7.3_ppc64.bundle
+++ b/xCAT-test/autotest/bundle/rhels7.3_ppc64.bundle
@@ -285,9 +285,6 @@ updatenode_postscripts_loginfo
bmcdiscover_h
bmcdiscover_nmap_range
bmcdiscover_v
-bmcdiscover_check_paswd
-bmcdiscover_check_passwd_wrong
-bmcdiscover_get_ipsource
bmcdiscover_range_w
bmcdiscover_range_z
xcatd_start
diff --git a/xCAT-test/autotest/bundle/rhels7.3_ppc64le.bundle b/xCAT-test/autotest/bundle/rhels7.3_ppc64le.bundle
index a63c77516..53cf9a829 100644
--- a/xCAT-test/autotest/bundle/rhels7.3_ppc64le.bundle
+++ b/xCAT-test/autotest/bundle/rhels7.3_ppc64le.bundle
@@ -282,9 +282,6 @@ updatenode_postscripts_loginfo
bmcdiscover_h
bmcdiscover_nmap_range
bmcdiscover_v
-bmcdiscover_check_paswd
-bmcdiscover_check_passwd_wrong
-bmcdiscover_get_ipsource
bmcdiscover_range_w
bmcdiscover_range_z
xcatd_start
diff --git a/xCAT-test/autotest/bundle/rhels7.4-pegas_ppc64le.bundle b/xCAT-test/autotest/bundle/rhels7.4-pegas_ppc64le.bundle
index 3dd31e7a2..455f4b74b 100644
--- a/xCAT-test/autotest/bundle/rhels7.4-pegas_ppc64le.bundle
+++ b/xCAT-test/autotest/bundle/rhels7.4-pegas_ppc64le.bundle
@@ -5,9 +5,6 @@ bmcdiscover_version
bmcdiscover_h
bmcdiscover_nmap_range
bmcdiscover_v
-bmcdiscover_check_paswd
-bmcdiscover_check_passwd_wrong
-bmcdiscover_get_ipsource
bmcdiscover_range_w
bmcdiscover_range_u_p_i_ipsource
bmcdiscover_range_z
diff --git a/xCAT-test/autotest/bundle/rhels7.4_ppc64.bundle b/xCAT-test/autotest/bundle/rhels7.4_ppc64.bundle
index 6953afe2e..a3edd6c14 100644
--- a/xCAT-test/autotest/bundle/rhels7.4_ppc64.bundle
+++ b/xCAT-test/autotest/bundle/rhels7.4_ppc64.bundle
@@ -287,9 +287,6 @@ updatenode_postscripts_loginfo
bmcdiscover_h
bmcdiscover_nmap_range
bmcdiscover_v
-bmcdiscover_check_paswd
-bmcdiscover_check_passwd_wrong
-bmcdiscover_get_ipsource
bmcdiscover_range_w
bmcdiscover_range_z
xcatd_start
diff --git a/xCAT-test/autotest/bundle/rhels7.4_ppc64le.bundle b/xCAT-test/autotest/bundle/rhels7.4_ppc64le.bundle
index 9bed2a4d3..01a45ed44 100644
--- a/xCAT-test/autotest/bundle/rhels7.4_ppc64le.bundle
+++ b/xCAT-test/autotest/bundle/rhels7.4_ppc64le.bundle
@@ -282,9 +282,6 @@ updatenode_postscripts_loginfo
bmcdiscover_h
bmcdiscover_nmap_range
bmcdiscover_v
-bmcdiscover_check_paswd
-bmcdiscover_check_passwd_wrong
-bmcdiscover_get_ipsource
bmcdiscover_range_w
bmcdiscover_range_z
xcatd_start
diff --git a/xCAT-test/autotest/testcase/UT_openbmc/rflash_cases0 b/xCAT-test/autotest/testcase/UT_openbmc/rflash_cases0
new file mode 100644
index 000000000..760e651e5
--- /dev/null
+++ b/xCAT-test/autotest/testcase/UT_openbmc/rflash_cases0
@@ -0,0 +1,72 @@
+start:rflash_check
+description: Make sure the --check option works
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN --check
+check:rc==0
+check:output=~$$CN: BMC Firmware Product
+check:output=~$$CN: HOST Firmware Product
+end
+
+start:rflash_invalid_activate
+description: Provide an invalid option for activte, file does not end in .tar
+os:Linux
+hcp:openbmc
+cmd: rflash $$CN -a /tmp/abc123.tz
+check:rc==1
+check:output=~Error: Invalid option
+end
+
+start:rflash_invalid_activate_and_delete
+description: Cannot specify -a and -d at the same time
+os:Linux
+hcp:openbmc
+cmd: rflash $$CN -a 123 -d 123
+check:rc==1
+check:output=~Error: Multiple options are not supported
+end
+
+start:rflash_invalid_id
+description: Passing an invalid ID to activate
+os:Linux
+hcp:openbmc
+cmd: rflash $$CN -a 123
+check:rc==1
+check:output=~Error: Invalid ID provided to activate
+end
+
+start:rflash_invalid_multiple_id_3
+description: Code does not currently support multiple IDs to activate
+os:Linux
+hcp:openbmc
+cmd: rflash $$CN -a 123 abc asdbas
+check:rc==1
+check:output=~Error: More than one firmware specified is not supported
+end
+
+start:rflash_invalid_multiple_id_2
+description: Code does not currently support multiple IDs to activate
+os:Linux
+hcp:openbmc
+cmd: rflash $$CN -a asdbas 123
+check:rc==1
+check:output=~Error: More than one firmware specified is not supported
+end
+
+start:rflash_invalid_node
+description: Activate a valid ID hash but forget to put in a node range
+os:Linux
+hcp:openbmc
+cmd: rflash -a 221d9020
+check:rc==1
+check:output=~Error: Invalid nodes and/or groups in noderange: 221d9020
+end
+
+start:rflash_invalid_delete_2
+description: Attempt to delete more than 1 ID from the FW
+os:Linux
+hcp:openbmc
+cmd: rflash $$CN -d 221d9020 221d9020
+check:rc==1
+check:output=~Error: More than one firmware specified is not supported
+end
diff --git a/xCAT-test/autotest/testcase/UT_openbmc/rinv_cases0 b/xCAT-test/autotest/testcase/UT_openbmc/rinv_cases0
new file mode 100644
index 000000000..2faa0d1e4
--- /dev/null
+++ b/xCAT-test/autotest/testcase/UT_openbmc/rinv_cases0
@@ -0,0 +1,36 @@
+start:rinv_record_firmware_level
+description: Record the firmware level for the start of each testcase
+hcp:openbmc
+cmd: rinv $$CN firm
+check:rc==0
+end
+
+start:rinv_check_active_fw_count
+description: Ensure that there is only 2 active firmware, one for bmc and one for pnor
+hcp:openbmc
+cmd: rinv $$CN firm | tee /tmp/xcattest.rinv_check_active_fw_count.output
+check:rc==0
+cmd: grep -i ibm /tmp/xcattest.rinv_check_active_fw_count.output | grep -i 'HOST Firmware Product' | grep -i 'Active)\*' | wc -l
+check:rc==0
+check:output=~1
+cmd: grep -i ibm /tmp/xcattest.rinv_check_active_fw_count.output | grep -i 'BMC Firmware Product'|grep -i 'Active)\*' | wc -l
+check:rc==0
+check:output=~1
+cmd : rm -rf /tmp/xcattest.rinv_check_active_fw_count.output
+check:rc==0
+end
+
+start:rinv_check_active_fw_count_verbose
+description: Ensure that there is only 2 active firmware, one for bmc and one for pnor (in verbose mode) (Issue #4236)
+hcp:openbmc
+cmd: rinv $$CN firm -V | tee /tmp/xcattest.rinv_check_active_fw_count_verbose.output
+check:rc==0
+cmd: grep -i ibm /tmp/xcattest.rinv_check_active_fw_count_verbose.output| grep -i 'HOST Firmware Product' | grep -i 'Active)\*' | wc -l
+check:rc==0
+check:output=~1
+cmd: grep -i ibm /tmp/xcattest.rinv_check_active_fw_count_verbose.output | grep -i 'BMC Firmware Product'|grep -i 'Active)\*' | wc -l
+check:rc==0
+check:output=~1
+cmd : rm -rf /tmp/xcattest.rinv_check_active_fw_count_verbose.output
+check:rc==0
+end
diff --git a/xCAT-test/autotest/testcase/UT_openbmc/rspconfig_cases0 b/xCAT-test/autotest/testcase/UT_openbmc/rspconfig_cases0
new file mode 100644
index 000000000..a1d4c4925
--- /dev/null
+++ b/xCAT-test/autotest/testcase/UT_openbmc/rspconfig_cases0
@@ -0,0 +1,71 @@
+start:rspconfig_record_firmware_level
+description: Record the firmware level for the start of each testcase
+hcp:openbmc
+cmd: rinv $$CN firm
+check:rc==0
+end
+
+start:rspconfig_get_all
+description: Check that we can get all the attributes from the BMC
+os:Linux
+hcp:openbmc
+cmd:rspconfig $$CN ip netmask gateway hostname vlan
+check:rc==0
+check:output=~$$CN: BMC IP:
+check:output=~$$CN: BMC Netmask:
+check:output=~$$CN: BMC Gateway:
+check:output=~$$CN: BMC Hostname:
+check:output=~$$CN: BMC VLAN ID:
+end
+
+start:rspconfig_get_all_error
+description: Check the parsing code for rspconfig (error cases)
+hcp: openbmc
+cmd: rspconfig $$CN ip,netmask,gateway,hostname,vlan
+check:rc==1
+check:output=~Error: Unsupported command
+end
+
+start:rspconfig_get_set_error
+description: Check the parsing code for rspconfig (error cases) - Cannot get/set in same line
+hcp: openbmc
+cmd: rspconfig $$CN ip netmask=255.0.0.0
+check:rc==1
+check:output=~Error: Can not set and query OpenBMC information at the same time
+end
+
+start:rspconfig_get_and_set_hostname
+description: Test setting and getting hostname on the BMC
+os:Linux
+hcp:openbmc
+# Save the hostname to a file....
+cmd:rspconfig $$CN hostname | tee /tmp/xcattest.rspconfig.hostname
+check:rc==0
+check:output=~$$CN: BMC Hostname:
+# Set to witherspoon first
+cmd:rspconfig $$CN hostname=witherspoon
+check:rc==0
+check:output=~$$CN: BMC Setting Hostname...
+# Check that it's set to witherspoon
+cmd:rspconfig $$CN hostname
+check:rc==0
+check:output=~$$CN: BMC Hostname: witherspoon
+# Set to -UTset
+cmd:rspconfig $$CN hostname=$$CN-UTset
+check:rc==0
+check:output=~$$CN: BMC Setting Hostname...
+# Check that it's set
+cmd:rspconfig $$CN hostname
+check:rc==0
+check:output=~$$CN: BMC Hostname: $$CN-UTset
+# Restore to saved version
+cmd:grep BMC /tmp/xcattest.rspconfig.hostname | cut -d' ' -f4 | xargs -i{} rspconfig $$CN hostname={}
+check:rc==0
+check:output=~$$CN: BMC Setting Hostname...
+cmd:rspconfig $$CN hostname
+check:rc==0
+check:output=~$$CN: BMC Hostname:
+cmd:rm /tmp/xcattest.rspconfig.hostname
+check:rc==0
+end
+
diff --git a/xCAT-test/autotest/testcase/bmcdiscover/cases0 b/xCAT-test/autotest/testcase/bmcdiscover/cases0
index da39b4d41..da035e3d1 100644
--- a/xCAT-test/autotest/testcase/bmcdiscover/cases0
+++ b/xCAT-test/autotest/testcase/bmcdiscover/cases0
@@ -50,20 +50,14 @@ end
start:bmcdiscover_check_paswd
cmd:bmcdiscover -i $$bmcrange -u $$bmcusername -p $$bmcpasswd --check
-check:rc==0
-check:output=~Correct ADMINISTRATOR
-end
-
-start:bmcdiscover_check_passwd_wrong
-cmd:bmcdiscover -i $$bmcrange -u $$bmcusername -p test$$bmcpasswd --check
-check:rc==0
-check:output=~Invalid username or password | Wrong BMC password
+check:rc==1
+check:output=~is not supported
end
start:bmcdiscover_get_ipsource
cmd:bmcdiscover -i $$bmcrange -u $$bmcusername -p $$bmcpasswd --ipsource
-check:rc==0
-check:output=~Static Address
+check:rc==1
+check:output=~is not supported
end
start:bmcdiscover_range_w
@@ -73,12 +67,6 @@ check:output=~Writing node
check:output=~$$bmcrange,\w*,\w*,$$bmcusername,$$bmcpasswd
end
-start:bmcdiscover_range_u_p_i_ipsource
-description:check the bmcrange is which type address
-cmd:bmcdiscover -i $$bmcrange -u $$bmcusername -p $$bmcpasswd --ipsource
-check:rc==0
-check:output=~IP Address Source : Static Address
-end
start:bmcdiscover_range_z
cmd:bmcdiscover --range $$bmcrange -u $$bmcusername -p $$bmcpasswd -z
check:rc==0
diff --git a/xCAT-test/autotest/testcase/installation/switch_to_dns_forward_mode b/xCAT-test/autotest/testcase/installation/switch_to_dns_forward_mode
new file mode 100644
index 000000000..62197d18c
--- /dev/null
+++ b/xCAT-test/autotest/testcase/installation/switch_to_dns_forward_mode
@@ -0,0 +1,64 @@
+start:switch_to_dns_forward_mode
+description:The test case is used to switch the whole testing cluster to run in dns forward mode. This test case should run after service node deployment.
+os:Linux
+
+##
+# Check if everything is fine
+##
+cmd:getent hosts $$MN
+check:rc==0
+cmd:getent hosts $$SN
+check:rc==0
+cmd:getent hosts $$CN
+check:rc==0
+
+# Turn off the DNS forward
+cmd:chdef -t site forwarders=
+check:rc==0
+cmd:chdef -t site nameservers=''
+check:rc==0
+cmd:makedns -n
+check:rc==0
+
+# Restart the named service
+cmd:service named restart
+cmd:sleep 1
+
+# Check if an outside host name resolving does not work
+cmd:xdsh $$CN "getent hosts w3.ibm.com"
+check:rc!=0
+
+##
+# Change to use the DNS server in c910
+##
+cmd:chdef -t site forwarders=10.0.0.103,10.0.0.101
+check:rc==0
+cmd:chdef -t site nameservers=''
+check:rc==0
+cmd:makedns -n
+check:rc==0
+
+# Restart the named service on $$MN and $$SN
+cmd:service named restart
+cmd:sleep 1
+cmd:xdsh service 'service named restart'
+cmd:sleep 1
+
+##
+# Check if everything is still fine
+##
+cmd:getent hosts $$MN
+check:rc==0
+cmd:getent hosts $$SN
+check:rc==0
+cmd:getent hosts $$CN
+check:rc==0
+cmd:xdsh $$CN "getent hosts $$MN"
+check:rc==0
+cmd:xdsh $$CN "getent hosts $$SN"
+check:rc==0
+cmd:xdsh $$CN "getent hosts $$CN"
+check:rc==0
+# Check if an outside host name resolving works
+cmd:xdsh $$CN "getent hosts w3.ibm.com"
+check:rc==0
diff --git a/xCAT-test/autotest/testcase/nodeset/cases0 b/xCAT-test/autotest/testcase/nodeset/cases0
index 54be05539..ef8f97e6b 100644
--- a/xCAT-test/autotest/testcase/nodeset/cases0
+++ b/xCAT-test/autotest/testcase/nodeset/cases0
@@ -411,8 +411,9 @@ check:rc==0
cmd:nodeset testnode1 osimage=rhels7.99-ppc64le-install-compute
#Ignore the exit code check as nonexistenode is fake and dispatching always fail
#check:rc==0
+#nodeset will be always run on MN (#4426)
cmd:test -f /tftpboot.1/petitboot/testnode1
-check:rc!=0
+check:rc==0
cmd:xdsh $$SN 'test -f /tftpboot.1/petitboot/testnode1'
check:rc!=0
cmd:nodeset testnode1 offline
@@ -435,6 +436,8 @@ cmd:chdef -t site tftpdir=/tftpboot
check:rc==0
cmd:rm -rf /tftpboot.1
cmd:xdsh $$SN 'rm -rf /tftpboot.1'
+cmd:makedns -d testnode1
+check:rc==0
cmd:chdef -t node -o testnode1 ip=
check:rc==0
cmd:cp -f /etc/hosts.xcattestbak /etc/hosts
diff --git a/xCAT-test/autotest/testcase/performance/Dockerfile b/xCAT-test/autotest/testcase/performance/Dockerfile
new file mode 100644
index 000000000..f388114d8
--- /dev/null
+++ b/xCAT-test/autotest/testcase/performance/Dockerfile
@@ -0,0 +1,8 @@
+FROM alpine:latest
+MAINTAINER binxu
+RUN apk add --update openssh bash wget && \
+ ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa && \
+ sed -i "s/UsePrivilegeSeparation.*/UsePrivilegeSeparation no/g" /etc/ssh/sshd_config && sed -i "s/UsePAM.*/UsePAM no/g" /etc/ssh/sshd_config && sed -i "s/PermitRootLogin.*/PermitRootLogin yes/g" /etc/ssh/sshd_config && sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/g" /etc/ssh/sshd_config && \
+ echo "root:cluster" | chpasswd
+EXPOSE 22
+CMD ["/usr/sbin/sshd","-D", "-o PermitRootLogin=yes"]
diff --git a/xCAT-test/autotest/testcase/performance/case0 b/xCAT-test/autotest/testcase/performance/case0
index 6ed131c19..58d9299b5 100644
--- a/xCAT-test/autotest/testcase/performance/case0
+++ b/xCAT-test/autotest/testcase/performance/case0
@@ -8,11 +8,197 @@ cmd:xcatperftest 5000 /opt/xcat/share/xcat/tools/autotest/perfcmds.lst
check:rc==0
end
-start:perftest_5000_without_conf
-description:Default performance testing on 5000 fake nodes without extra configuraiton on MN
+start:UT_perftest_5000_MN_only
+description:Default performance testing on 5000 fake nodes without extra configuration on MN
os:Linux
cmd:which yum &>/dev/null && yum install -y bridge-utils || apt install -y bridge-utils
check:rc==0
cmd:xcatperftest 5000 /opt/xcat/share/xcat/tools/autotest/perfcmds.lst
check:rc==0
end
+
+start:perftest_5000_with_simulators
+description:Default performance testing on 5000 fake nodes
+os:Linux
+### From reg_linux_diskfull_installation_flat
+cmd:fdisk -l
+cmd:df -T
+
+cmd:MINIISO=NUll;if [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu" ]] && [[ "__GETNODEATTR($$CN,arch)__" =~ "ppc64" ]];then mkdir /tmp/iso; mount -o loop $$MINIISO /tmp/iso ; mkdir -p /install/__GETNODEATTR($$CN,os)__/__GETNODEATTR($$CN,arch)__/install/netboot; cp /tmp/iso/install/initrd.gz /install/__GETNODEATTR($$CN,os)__/__GETNODEATTR($$CN,arch)__/install/netboot;umount /tmp/iso; rmdir /tmp/iso; fi
+check:rc==0
+cmd:chdef -t node -o $$CN servicenode= monserver= nfsserver= tftpserver= xcatmaster= status=
+check:rc==0
+cmd:chdef -t node -o $$SN servicenode= monserver= nfsserver= tftpserver= xcatmaster= status=
+check:rc==0
+cmd:makeconservercf
+check:rc==0
+cmd:cat /etc/conserver.cf | grep $$CN
+check:output=~$$CN
+cmd:cat /etc/conserver.cf | grep $$SN
+check:output=~$$SN
+cmd:sleep 20
+cmd:makedhcp -n
+check:rc==0
+cmd:makedhcp -a
+check:rc==0
+cmd:sleep 10
+cmd:a=0;while true; do [ $a -eq 100 ] && exit 1;output=$(makedhcp -q $$CN);[ $? -ne 0 ] && exit 1;echo $output|grep $$CN 2>/dev/null && exit 0;a=$[$a+1];sleep 1;done
+check:rc==0
+cmd:a=0;while true; do [ $a -eq 100 ] && exit 1;output=$(makedhcp -q $$SN);[ $? -ne 0 ] && exit 1;echo $output|grep $$SN 2>/dev/null && exit 0;a=$[$a+1];sleep 1;done
+check:rc==0
+cmd:copycds $$ISO
+check:rc==0
+cmd:lsdef -l $$SN,$$CN
+check:rc==0
+cmd:rinstall $$SN,$$CN osimage=__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-install-compute
+check:rc==0
+#check:output=~Provision node\(s\)\: $$CN
+#check:output=~Provision node\(s\)\: $$SN
+cmd:if [[ -f /var/lib/dhcp/db/dhcpd.leases ]]; then cat /var/lib/dhcp/db/dhcpd.leases; elif [[ -f /var/lib/dhcpd/dhcpd.leases ]];then cat /var/lib/dhcpd/dhcpd.leases;elif [[ -f /var/lib/dhcp/dhcpd.leases ]];then cat /var/lib/dhcp/dhcpd.leases; fi
+
+#After starting installation, began run fake nodes testing on MN
+cmd:which yum &>/dev/null && yum install -y bridge-utils || apt install -y bridge-utils
+cmd:FAKE_NETWORK_PRO=173.18 FAKE_NETWORK_BMC=192.169 PERF_RPT_FILE=perfreport-5000.log.daily xcatperftest 5000 /opt/xcat/share/xcat/tools/autotest/perfcmds.lst
+check:rc==0
+
+cmd:PERF_CREATE_ONLY=y FAKE_NETWORK_PRO=173.18 FAKE_NETWORK_BMC=192.169 xcatperftest 5000 /opt/xcat/share/xcat/tools/autotest/perfcmds.lst
+check:rc==0
+cmd:makehosts -n perftest
+check:rc==0
+
+#Make sure SN and CN is deployed sucessfully
+cmd:a=0;while ! `lsdef $$CN -i status|grep -E "booted|failed" >/dev/null`; do sleep 20;((a++));if [ $a -gt 50 ];then break;fi done
+cmd:ping $$CN -c 3
+check:rc==0
+cmd:a=0;while ! `lsdef $$SN -i status|grep -E "booted|failed" >/dev/null`; do sleep 20;((a++));if [ $a -gt 50 ];then break;fi done
+cmd:ping $$SN -c 3
+check:rc==0
+
+#Setup Simulater environment on SN/CN
+cmd:xdsh $$SN,$$CN "rm -rf /tmp/perf && mkdir -p /tmp/perf"
+check:rc==0
+cmd:scp /opt/xcat/share/xcat/tools/autotest/testcase/performance/* root@$$CN:/tmp/perf
+check:rc==0
+cmd:scp /opt/xcat/share/xcat/tools/autotest/testcase/performance/* root@$$SN:/tmp/perf
+check:rc==0
+
+# For openbmc simulation setup on SN
+cmd:PERF_SIM_NIC=$$SECONDNIC xcatperftest create fake[1-1000] openbmc
+check:rc==0
+cmd:scp /opt/xcat/share/xcat/tools/autotest/result/perf-openbmc-create.sh root@$$SN:/tmp/perf
+check:rc==0
+cmd:xdsh $$SN PERF_SIM_NIC=$$SECONDNIC PERF_SIM_ADDR=192.169.251.252 bash /tmp/perf/simulatorctl.sh setup openbmc
+check:rc==0
+cmd:PERF_SIM_NIC=$$SECONDNIC PERF_SIM_ADDR=192.169.251.251 bash /opt/xcat/share/xcat/tools/autotest/testcase/performance/simulatorctl.sh setup openbmc --mn
+check:rc==0
+cmd:ping 192.169.251.252 -c 3
+check:rc==0
+
+# Testing for HW remote control CLIs
+cmd:PERF_NOCREATE=1 PERF_RPT_FILE=perfreport-5000.log.daily xcatperftest 5000 /opt/xcat/share/xcat/tools/autotest/testcase/performance/hwcmd.lst
+check:rc==0
+cmd:xdsh $$SN PERF_SIM_NIC=$$SECONDNIC PERF_SIM_ADDR=192.169.251.252 bash /tmp/perf/simulatorctl.sh clean openbmc
+check:rc==0
+cmd:PERF_SIM_NIC=$$SECONDNIC PERF_SIM_ADDR=192.169.251.251 bash /opt/xcat/share/xcat/tools/autotest/testcase/performance/simulatorctl.sh clean openbmc --mn
+check:rc==0
+
+# For container simulation setup on SN/CN
+cmd:xcatperftest create fake[1-100] docker
+check:rc==0
+cmd:scp /opt/xcat/share/xcat/tools/autotest/result/perf-docker-create.sh root@$$CN:/tmp/perf
+check:rc==0
+
+cmd:xcatperftest create fake[501-600] docker
+check:rc==0
+cmd:scp /opt/xcat/share/xcat/tools/autotest/result/perf-docker-create.sh root@$$SN:/tmp/perf
+check:rc==0
+
+cmd:xdsh $$CN PERF_SIM_NIC=$$SECONDNIC PERF_SIM_ADDR=173.18.251.252 bash /tmp/perf/simulatorctl.sh setup docker
+check:rc==0
+
+cmd:xdsh $$SN PERF_SIM_NIC=$$SECONDNIC PERF_SIM_ADDR=173.18.251.253 bash /tmp/perf/simulatorctl.sh setup docker
+check:rc==0
+
+cmd:PERF_SIM_NIC=$$SECONDNIC PERF_SIM_ADDR=173.18.251.251 bash /opt/xcat/share/xcat/tools/autotest/testcase/performance/simulatorctl.sh setup docker --mn
+check:rc==0
+cmd:ping 173.18.251.252 -c 3
+check:rc==0
+
+# Testing for updatenode, xdsh, nodestat, pping, etc
+cmd:PERF_NOCREATE=1 PERF_RPT_FILE=perfreport-5000.log.daily xcatperftest 5000 /opt/xcat/share/xcat/tools/autotest/testcase/performance/nodecmd.lst
+check:rc==0
+
+cmd:xdsh $$CN,$$SN PERF_SIM_NIC=$$SECONDNIC bash /tmp/perf/simulatorctl.sh clean docker
+check:rc==0
+
+cmd:PERF_SIM_NIC=$$SECONDNIC PERF_SIM_ADDR=173.18.251.251 bash /opt/xcat/share/xcat/tools/autotest/testcase/performance/simulatorctl.sh clean docker --mn
+check:rc==0
+
+end
+
+
+start:UT_perftest_1000_with_simulators
+description: UT for performance testing with simulators on an existing environment with one compute node.
+os:Linux
+
+# Create fake nodes
+cmd:PERF_CREATE_ONLY=y FAKE_NETWORK_PRO=173.18 FAKE_NETWORK_BMC=192.169 xcatperftest 1000 /opt/xcat/share/xcat/tools/autotest/perfcmds.lst
+check:rc==0
+cmd:makehosts -n perftest
+check:rc==0
+
+#Make sure CN is deployed sucessfully
+cmd:ping $$CN -c 3
+check:rc==0
+
+#Setup Simulater environment
+cmd:xdsh $$CN "rm -rf /tmp/perf && mkdir -p /tmp/perf"
+check:rc==0
+cmd:scp /opt/xcat/share/xcat/tools/autotest/testcase/performance/* root@$$CN:/tmp/perf
+check:rc==0
+
+# For openbmc simulation setup
+cmd:xcatperftest create fake[1-1000] openbmc
+check:rc==0
+cmd:scp /opt/xcat/share/xcat/tools/autotest/result/perf-openbmc-create.sh root@$$CN:/tmp/perf
+check:rc==0
+cmd:xdsh $$CN PERF_SIM_ADDR=192.169.251.252 bash /tmp/perf/simulatorctl.sh setup openbmc
+check:rc==0
+cmd:PERF_SIM_ADDR=192.169.251.251 bash /opt/xcat/share/xcat/tools/autotest/testcase/performance/simulatorctl.sh setup openbmc --mn
+check:rc==0
+cmd:ping 192.169.251.252 -c 3
+check:rc==0
+
+# Testing for HW remote control CLIs
+cmd:PERF_NOCREATE=1 xcatperftest 1000 /opt/xcat/share/xcat/tools/autotest/testcase/performance/hwcmd.lst
+check:rc==0
+cmd:xdsh $$CN PERF_SIM_ADDR=192.169.251.252 bash /tmp/perf/simulatorctl.sh clean openbmc
+check:rc==0
+cmd:PERF_SIM_ADDR=192.169.251.251 bash /opt/xcat/share/xcat/tools/autotest/testcase/performance/simulatorctl.sh clean openbmc --mn
+check:rc==0
+
+# For container simulation setup
+cmd:xcatperftest create fake[1-50] docker
+check:rc==0
+cmd:scp /opt/xcat/share/xcat/tools/autotest/result/perf-docker-create.sh root@$$CN:/tmp/perf
+check:rc==0
+
+cmd:xdsh $$CN PERF_SIM_ADDR=173.18.251.252 bash /tmp/perf/simulatorctl.sh setup docker
+check:rc==0
+
+cmd:PERF_SIM_ADDR=173.18.251.251 bash /opt/xcat/share/xcat/tools/autotest/testcase/performance/simulatorctl.sh setup docker --mn
+check:rc==0
+cmd:ping 173.18.251.252 -c 3
+check:rc==0
+
+# Testing for updatenode, xdsh, nodestat, pping, etc
+cmd:PERF_NOCREATE=1 xcatperftest 1000 /opt/xcat/share/xcat/tools/autotest/testcase/performance/nodecmd.lst
+check:rc==0
+
+cmd:xdsh $$CN bash /tmp/perf/simulatorctl.sh clean docker
+check:rc==0
+
+cmd:PERF_SIM_ADDR=173.18.251.251 bash /opt/xcat/share/xcat/tools/autotest/testcase/performance/simulatorctl.sh clean docker --mn
+check:rc==0
+
+end
diff --git a/xCAT-test/autotest/testcase/performance/hwcmd.lst b/xCAT-test/autotest/testcase/performance/hwcmd.lst
new file mode 100644
index 000000000..8dc866eb9
--- /dev/null
+++ b/xCAT-test/autotest/testcase/performance/hwcmd.lst
@@ -0,0 +1,5 @@
+#SERIES# 1,50,100,250,500,1000
+rsetboot #NODES# default
+rpower #NODES# stat
+rinv #NODES# all
+rflash #NODES# -l
diff --git a/xCAT-test/autotest/testcase/performance/nodecmd.lst b/xCAT-test/autotest/testcase/performance/nodecmd.lst
new file mode 100644
index 000000000..933f98109
--- /dev/null
+++ b/xCAT-test/autotest/testcase/performance/nodecmd.lst
@@ -0,0 +1,4 @@
+#SERIES# 1,50,100,250,500,1000
+nodestat #NODES#
+pping #NODES#
+xdsh #NODES# true
diff --git a/xCAT-test/autotest/testcase/performance/simulatorctl.sh b/xCAT-test/autotest/testcase/performance/simulatorctl.sh
new file mode 100644
index 000000000..764536862
--- /dev/null
+++ b/xCAT-test/autotest/testcase/performance/simulatorctl.sh
@@ -0,0 +1,168 @@
+#!/bin/bash
+# IBM(c) 2017 EPL license http://www.eclipse.org/legal/epl-v10.html
+#(C)IBM Corp
+#
+if [ -z $LC_ALL ]; then
+ export LC_ALL=C
+fi
+# Give a simple usage
+if [ -z "$1" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
+ echo "Setup, run and clean the simulators for performance testing..."
+ echo " $0 run "
+ exit
+fi
+
+if [ -z $PERF_SIM_ADDR ]; then
+ PERF_SIM_ADDR='192.168.251.251'
+fi
+
+if [ -z $PERF_SIM_MASK ]; then
+ PERF_SIM_MASK='255.255.0.0'
+fi
+
+# Optional, The NIC used by simulator.
+if [ -z $PERF_SIM_NIC ]; then
+ PERF_SIM_NIC='eth1'
+fi
+
+#IBM_POWER_TOOLS_URL='http://public.dhe.ibm.com/software/server/POWER/Linux/yum/OSS/RHEL/7/ppc64le'
+OPEN_POWER_TOOLS_URL='http://ftp.unicamp.br/pub/ppc64el/rhel/7/docker-ppc64el'
+OPENBMC_SIMULATOR_URL='https://github.com/xuweibj/openbmc_simulator'
+PERF_SIM_TESTING_CWD='/tmp/perf'
+PERF_SIM_RESULT_DIR='/opt/xcat/share/xcat/tools/autotest/result'
+PERF_SIM_CASE_DIR='/opt/xcat/share/xcat/tools/autotest/testcase/performance'
+
+arch=`arch`
+driver="$2"
+if [ "$driver" != "docker" ] && [ "$driver" != "openbmc" ]; then
+ echo "Error: not supported simulator type '$driver'."
+ exit -1
+fi
+
+setup_docker()
+{
+ if [ ! -z $1 ]; then # run on MN with --mn
+ echo "Prepare on management node side..."
+ prefix=$(ipcalc -p $PERF_SIM_ADDR $PERF_SIM_MASK|awk -F= '{print $2}')
+ ip addr add $PERF_SIM_ADDR/$prefix dev $PERF_SIM_NIC #label $PERF_SIM_NIC:100
+ return
+ fi
+
+ if [[ $arch =~ 'ppc64' ]]; then
+ # The URL is from OpenPOWER Linux Community
+ echo "[docker] name=Docker baseurl=$OPEN_POWER_TOOLS_URL enabled=1 gpgcheck=0" | \
+ awk 'BEGIN{RS=" ";ORS="\n";}{print $0}' > /etc/yum.repos.d/docker.repo
+ yum repolist
+ #workaround as the public repo has issue to install container-selinux
+ yum install -y http://ftp.unicamp.br/pub/ppc64el/rhel/7/docker-ppc64el/container-selinux-2.9-4.el7.noarch.rpm
+ yum install -y docker-ce bridge-utils initscripts
+ service docker start
+ sleep 5
+
+ else
+ echo "Error: not supported platform."
+ fi
+
+ # Create the bridge network for testing, and add the physical interface inside
+ #docker network ls|grep perf-net > /dev/null && docker network rm perf-net
+ netaddr=$(ipcalc -n $PERF_SIM_ADDR $PERF_SIM_MASK|awk -F= '{print $2}')
+ prefix=$(ipcalc -p $PERF_SIM_ADDR $PERF_SIM_MASK|awk -F= '{print $2}')
+ docker network create --gateway $PERF_SIM_ADDR --subnet $netaddr/$prefix perf-net
+ bruuid=$(docker network ls | awk '/perf-net/ {print $1}')
+ brctl addif br-$bruuid $PERF_SIM_NIC
+ brctl show br-$bruuid
+
+ # Prepare the docker image
+ [ -f $PERF_SIM_TESTING_CWD/Dockerfile ] && rootpath=$PERF_SIM_TESTING_CWD || rootpath=$PERF_SIM_CASE_DIR
+ docker build -t perf-alpine-ssh $rootpath
+ docker images
+
+ # run the containers
+ run_docker
+}
+
+run_docker()
+{
+ echo "Run docker simulator for node range..."
+ script=$(ls -1 $PERF_SIM_TESTING_CWD/perf-docker-create.sh || ls -1 $PERF_SIM_RESULT_DIR}/perf-docker-create.sh)
+ if [ ! "x" = "x$script" ]; then
+ sh -x $script
+ return
+ fi
+ echo "WARN: Not found the script for run docker simulator..."
+}
+
+clean_docker()
+{
+ if [ ! -z $1 ]; then
+ echo "Cleanup on management node side..."
+ prefix=$(ipcalc -p $PERF_SIM_ADDR $PERF_SIM_MASK|awk -F= '{print $2}')
+ ip addr del $PERF_SIM_ADDR/$prefix dev $PERF_SIM_NIC #label $PERF_SIM_NIC:100
+ return
+ fi
+
+ ids=$(docker ps -a -q)
+ [ "x" = "x$ids" ] || docker rm -f $ids
+ docker network ls| grep perf-net && docker network rm perf-net
+ brctl show
+}
+
+setup_openbmc()
+{
+ ip addr flush dev $PERF_SIM_NIC
+ prefix=$(ipcalc -p $PERF_SIM_ADDR $PERF_SIM_MASK|awk -F= '{print $2}')
+ #ip addr flush dev $PERF_SIM_NIC
+ ip addr add $PERF_SIM_ADDR/$prefix dev $PERF_SIM_NIC #label $PERF_SIM_NIC:100
+
+ if [ ! -z $1 ]; then
+ echo "Prepare on management node side..."
+ return
+ fi
+
+ which yum &>/dev/null && yum install -y git || apt install -y git
+ mkdir -p $PERF_SIM_TESTING_CWD && cd $PERF_SIM_TESTING_CWD && git clone $OPENBMC_SIMULATOR_URL
+ chmod +x $PERF_SIM_TESTING_CWD/openbmc_simulator/simulator
+ run_openbmc
+}
+
+run_openbmc()
+{
+ echo "Run openbmc simulator for node range..."
+ script=$(ls -1 $PERF_SIM_TESTING_CWD/perf-openbmc-create.sh || ls -1 $PERF_SIM_RESULT_DIR}/perf-openbmc-create.sh)
+ if [ ! "x" = "x$script" ]; then
+ sh $script setup
+ return
+ fi
+ echo "WARN: Not found the script for run openbmc simulator..."
+}
+
+clean_openbmc()
+{
+ prefix=$(ipcalc -p $PERF_SIM_ADDR $PERF_SIM_MASK|awk -F= '{print $2}')
+ if [ ! -z $1 ]; then
+ echo "Cleanup on management node side..."
+ ip addr del $PERF_SIM_ADDR/$prefix dev $PERF_SIM_NIC #label $PERF_SIM_NIC:100
+ return
+ fi
+
+ echo "Cleanup openbmc simulator for node range..."
+
+ script=$(ls -1 $PERF_SIM_TESTING_CWD/perf-openbmc-create.sh || ls -1 $PERF_SIM_RESULT_DIR}/perf-openbmc-create.sh)
+ if [ ! "x" = "x$script" ]; then
+ sh $script clean
+ ip addr del $PERF_SIM_ADDR/$prefix dev $PERF_SIM_NIC #label $PERF_SIM_NIC:100
+ return
+ fi
+ echo "WARN: Not found the script for run openbmc simulator..."
+}
+
+
+# Mail program
+if [ "$1" = "setup" ]; then
+ eval "setup_$driver $3"
+elif [ "$1" = "clean" ]; then
+ eval "clean_$driver $3"
+else
+ echo "Error: not supported action."
+ exit -1
+fi
\ No newline at end of file
diff --git a/xCAT-test/autotest/testcase/reventlog/cases0 b/xCAT-test/autotest/testcase/reventlog/cases0
index 1bbca123e..5e73493b7 100644
--- a/xCAT-test/autotest/testcase/reventlog/cases0
+++ b/xCAT-test/autotest/testcase/reventlog/cases0
@@ -18,3 +18,24 @@ cmd:reventlog $$CN 5
check:rc==0
check:output=~$$CN\s*:\s*.*\d\d/\d\d/\d\d\s*\S+|$$CN: no SEL entries|Entry
end
+
+start:reventlog_s_openbmc
+description: For openbmc, reventlog has dropped option s
+os:Linux
+hcp:openbmc
+cmd:reventlog $$CN 10 -s
+check:output=~The -s option is not supported for OpenBMC
+check:rc!=0
+cmd:reventlog $$CN 10 -s 1
+check:output=~The -s option is not supported for OpenBMC
+check:rc!=0
+cmd:reventlog $$CN -s all
+check:output=~The -s option is not supported for OpenBMC
+check:rc!=0
+cmd:reventlog $$CN -s
+check:output=~Error: Unsupported command
+check:rc!=0
+cmd:reventlog $$CN all aaa
+check:output=~Error: Only one option is supported at the same time
+check:rc!=0
+end
diff --git a/xCAT-test/autotest/testcase/rflash/rflash_openbmc.0 b/xCAT-test/autotest/testcase/rflash/rflash_openbmc.0
new file mode 100644
index 000000000..62a05dd1c
--- /dev/null
+++ b/xCAT-test/autotest/testcase/rflash/rflash_openbmc.0
@@ -0,0 +1,485 @@
+start:rflash_option_c_without_specify_noderange
+description: basic usage check for option c. if without specify noderange for rflash command, should offer usage message
+os:Linux
+hcp:openbmc
+cmd:rflash -c
+check:output=~Usage:
+cmd:rflash -c 1.tar
+check:rc != 0
+check:output=~Error: Invalid nodes and/or groups in noderange
+end
+
+start:rflash_option_l_without_specify_noderange
+description: basic usage check for option l. if without specify noderange for rflash command, should offer usage message
+os:Linux
+hcp:openbmc
+cmd:rflash -l
+check:output=~Usage:
+end
+
+start:rflash_option_a_without_specify_noderange
+description: basic usage check for option a. if without specify noderange for rflash command, should offer usage message
+os:Linux
+hcp:openbmc
+cmd:rflash -a
+check:output=~Usage:
+cmd:rflash -a 1.tar
+check:rc != 0
+check:output=~Error: Invalid nodes and/or groups in noderange
+cmd:rflash -a 123abc
+check:rc != 0
+check:output=~Error: Invalid nodes and/or groups in noderange
+end
+
+start:rflash_option_u_without_specify_noderange
+description: basic usage check for option u. if without specify noderange for rflash command, should offer usage message
+os:Linux
+hcp:openbmc
+cmd:rflash -u
+check:output=~Usage:
+cmd:rflash -u 1.tar
+check:rc != 0
+check:output=~Error: Invalid nodes and/or groups in noderange
+end
+
+start:rflash_option_d_without_specify_noderange
+description: basic usage check for option d. if without specify noderange for rflash command, should offer usage message
+os:Linux
+hcp:openbmc
+cmd:rflash -d
+check:output=~Usage:
+cmd:rflash -d /1234
+check:Usage:
+cmd:rflash --delete 1234abc
+check:rc != 0
+check:output=~Error: Invalid nodes and/or groups in noderange
+end
+
+start:rflash_without_option
+description: basic usage check, if without option, should throw out a error
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN 1.tar
+check:rc != 0
+check:output=~Error: Invalid option specified when a file is provided:
+end
+
+start:rflash_unsupport_multiple_option_a_u
+description: basic usage check. If specify multiple options a+u, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -a 1.tz -u
+check:output=~Error: Multiple options are not supported
+check:rc != 0
+end
+
+start:rflash_unsupport_multiple_option_a_c
+description: basic usage check. If specify multiple options a+c, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -a 1.tz -c
+check:output=~Error: Multiple options are not supported
+check:rc != 0
+end
+
+start:rflash_unsupport_multiple_option_a_l
+description: basic usage check. If specify multiple options a+l, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -a 1.tz -l
+check:output=~Error: Multiple options are not supported
+check:rc != 0
+end
+
+start:rflash_unsupport_multiple_option_a_d
+description: basic usage check. If specify multiple options a+d, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -a 1.tz -d
+check:output=~Error: Multiple options are not supported
+check:rc != 0
+end
+
+start:rflash_unsupport_multiple_option_c_l
+description: basic usage check. If specify multiple options c+l, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -c 1.tz -l
+check:output=~Error: Multiple options are not supported
+check:rc != 0
+end
+
+start:rflash_unsupport_multiple_option_c_u
+description: basic usage check. If specify multiple options c+u, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -c 1.tz -u
+check:output=~Error: Multiple options are not supported
+check:rc != 0
+end
+
+start:rflash_unsupport_multiple_option_c_d
+description: basic usage check. If specify multiple options c+d, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -c 1.tz -d
+check:output=~Error: Multiple options are not supported
+check:rc != 0
+end
+
+start:rflash_unsupport_multiple_option_l_d
+description: basic usage check. If specify multiple options l+d, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -l -d
+check:output=~Error: Multiple options are not supported
+check:rc != 0
+end
+
+start:rflash_unsupport_multiple_option_l_u
+description: basic usage check. If specify multiple options l+u, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -l -u
+check:output=~Error: Multiple options are not supported
+check:rc != 0
+end
+
+start:rflash_unsupport_multiple_option_u_d
+description: basic usage check. If specify multiple options u+d, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -u -d
+check:output=~Error: Multiple options are not supported
+check:rc != 0
+end
+
+start:rflash_option_c_file_not_exist
+description: basic usage check for option c. if the file does not exist, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -c /tmp/abc123.tz
+check:output=~Error: Invalid firmware specified with
+check:rc != 0
+cmd:rflash $$CN -c /tmp/
+check:output=~Error: Invalid firmware specified with
+check:rc != 0
+cmd:rflash $$CN /tmp/abc123.tz -c
+check:output=~Error: Invalid firmware specified with
+check:rc != 0
+cmd:rflash $$CN /tmp/ -c
+check:output=~Error: Invalid firmware specified with
+check:rc != 0
+cmd:rflash $$CN 1.tar -c
+check:output=~Error: Cannot access
+check:rc != 0
+cmd:rflash $$CN -c /tmp/1.tar
+check:output=~Error: Cannot access
+check:rc != 0
+end
+
+start:rflash_option_c_with_multiple_values
+description: basic usage check for option c. if there are multiple value assigned to c option, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -c /tmp/abc123.tz /tmp/abc124.tz
+check:output=~Error: Invalid firmware specified with
+check:rc != 0
+cmd:rflash $$CN -c 1.tz 2.tz 3.tz
+check:output=~Error: Invalid firmware specified with
+check:rc != 0
+cmd:rflash $$CN 1.tz 2.tz 3.tz -c
+check:output=~Error: Invalid firmware specified with
+check:rc != 0
+cmd:rflash $$CN 1.tz -c 2.tz
+check:output=~Error: Invalid firmware specified with
+check:rc != 0
+end
+
+start:rflash_option_c_against_node
+description: Make sure the -c option against node works
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -c |tee /tmp/rflash_option_c.output
+check:rc == 0
+cmd:grep -i ibm /tmp/rflash_option_c.output |grep -i 'HOST Firmware Product' | grep -i 'Active)\*' | wc -l
+check:rc==0
+check:output=~1
+cmd:grep -i ibm /tmp/rflash_option_c.output |grep -i 'BMC Firmware Product' | grep -i 'Active)\*' | wc -l
+check:rc==0
+check:output=~1
+cmd:rm -rf /tmp/rflash_option_c.output
+check:rc==0
+end
+
+start:rflash_option_check_with_V_against_node
+description: Make sure the --check option with V works
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN --check -V |tee /tmp/rflash_option_check_with_V.output
+check:rc == 0
+cmd:grep -i ibm /tmp/rflash_option_check_with_V.output |grep -i 'HOST Firmware Product' | grep -i 'Active)\*' | wc -l
+check:rc==0
+check:output=~1
+cmd:grep -i ibm /tmp/rflash_option_check_with_V.output |grep -i 'BMC Firmware Product' | grep -i 'Active)\*' | wc -l
+check:rc==0
+check:output=~1
+cmd:rm -rf /tmp/rflash_option_check_with_V.output
+check:rc==0
+end
+
+
+start:rflash_option_l_with_value
+description: basic usage check for option l. if there is value for l option, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -l /tmp/abc123.tz
+check:output=~Error: Invalid option
+check:rc != 0
+cmd: rflash $$CN /tmp/abc123.tz -l
+check:output=~Error: Invalid option
+check:rc != 0
+end
+
+start:rflash_option_l
+description: Make sure the -l option works
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -l |tee /tmp/rflash_option_l.output
+check:rc == 0
+cmd:grep -i ' bmc ' /tmp/rflash_option_l.output | grep -i 'Active(\*)' | wc -l
+check:rc==0
+check:output=~1
+cmd:grep -i ' host ' /tmp/rflash_option_l.output | grep -i 'Active(\*)' | wc -l
+check:rc==0
+check:output=~1
+cmd:rm -rf /tmp/rflash_option_l.output
+check:rc==0
+end
+
+
+start:rflash_option_u_file_not_exist
+description: basic usage check for option u. if the file does not exist, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -u /tmp/abc123.tz
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN -u /tmp/
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN /tmp/abc123.tz -u
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN /tmp/ -u
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN 1.tar -u
+check:output=~Error: Cannot access
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN -u /tmp/1.tar
+check:output=~Error: Cannot access
+check:output!~Attempting to
+check:rc != 0
+end
+
+start:rflash_option_u_with_multiple_values
+description: basic usage check for option u. if there are multiple value assigned to u option, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -u /tmp/abc123.tz /tmp/abc124.tz
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN -u 1.tz 2.tz 3.tz
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN 1.tz 2.tz 3.tz -u
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN 1.tz -u 2.tz
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+end
+
+start:rflash_option_a_file_not_exist
+description: basic usage check for option a. if the file does not exist, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -a /tmp/abc123.tz
+check:output=~rror: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN -a /tmp/
+check:output=~rror: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN /tmp/abc123.tz -a
+check:output=~rror: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN /tmp/ -a
+check:output=~rror: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN 1.tar -a
+check:output=~Error: Cannot access
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN -a /tmp/1.tar
+check:output=~Error: Cannot access
+check:output!~Attempting to
+check:rc != 0
+end
+
+start:rflash_option_a_with_multiple_values
+description: basic usage check for option a. if there are multiple value assigned to a option, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -a /tmp/abc123.tz /tmp/abc124.tz
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN -a 1.tz 2.tz 3.tz
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN 1.tz 2.tz 3.tz -a
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN 1.tz -a 2.tz
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN 1234567 -a 2345678
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN -a 123 abc asdbas
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to
+check:rc != 0
+end
+
+
+start:rflash_option_a_with_non_existent_id
+description: basic usage check for option a. if active a non-existent firmware ID, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -a 1234567
+check:output=~Error: Invalid ID provided to activate
+check:output!~Attempting to activate
+check:rc != 0
+cmd:rflash $$CN -a 123abcm
+check:output=~Error: Invalid ID provided to activate
+check:output!~Attempting to activate
+check:rc != 0
+end
+
+start:rflash_option_delete_with_multiple_values
+description: basic usage check for option delete. if there are multiple value assigned to delete option, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN --delete 1234567 2345678
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to delete
+check:rc != 0
+cmd:rflash $$CN 1234567 2345678 --delete
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to delete
+check:rc != 0
+cmd:rflash $$CN 1234567 --delete 2345678
+check:output=~Error: Invalid firmware specified with
+check:output!~Attempting to delete
+check:rc != 0
+end
+
+start:rflash_option_delete_with_non_existent_id
+description: basic usage check for option --delete. if delete a non-existent firmware ID, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN --delete 1234567
+check:output=~Error: Invalid ID provided to delete
+check:output!~Attempting to delete
+check:rc != 0
+cmd:rflash $$CN --delete 123abcm
+check:output=~Error: Invalid ID provided to delete
+check:output!~Attempting to delete
+check:rc != 0
+end
+
+start:rflash_option_d_with_multiple_values
+description: basic usage check for option d. if there are multiple value assigned to d option, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rflash $$CN -d /123/ /234/
+check:output=~Error: More than one
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN /123/ /234/ -d
+check:output=~Error: More than one
+check:output!~Attempting to
+check:rc != 0
+cmd:rflash $$CN /123/ -d /234/
+check:output=~Error: More than one
+check:output!~Attempting to
+check:rc != 0
+end
+
+
+start:rflash_option_d_with_non_existent_dir
+description: basic usage check for option -d. if try to oprate non-existent dir by d option, should throw out error message
+os:Linux
+hcp:openbmc
+cmd:rm -rf /tmp/bogus123
+check:rc == 0
+cmd:rflash $$CN -d /tmp/bogus123
+check:output=~Error: Can't open directory
+check:output!~Attempting to
+check:rc != 0
+cmd:mkdir -p /tmp/bogus123
+check:rc == 0
+cmd:rflash $$CN /tmp/bogus123 -d
+check:output =~Error: No BMC tar file found
+check:output =~Error: No PNOR tar file found
+check:output!~Attempting to
+check:rc != 0
+cmd:touch /tmp/bogus123/obmc-phosphor-image-witherspoon.ubi.mtd.tar
+check:rc == 0
+cmd:rflash $$CN -d /tmp/bogus123
+check:output =~Error: No BMC tar file found
+check:output =~Error: No PNOR tar file found
+check:output!~Attempting to
+check:rc != 0
+cmd:touch /tmp/bogus123/witherspoon.pnor.squashfs.tar
+check:rc == 0
+cmd:rflash $$CN -d /tmp/bogus123
+check:output =~Error: No BMC tar file found
+check:output =~Error: No PNOR tar file found
+check:output!~Attempting to
+check:rc != 0
+cmd:rm -rf /tmp/bogus123
+check:rc == 0
+end
+
+start:rflash_usage
+description:checke the usage of rflash for openbmc
+os:Linux
+hcp:openbmc
+cmd:rflash -h
+check:output =~Usage:
+check:output =~OpenPOWER OpenBMC specific:
+check:output =~ -d.+–no-host-reboot
+check:output =~ image_id.+--delete
+check:rc == 0
+end
+
diff --git a/xCAT-test/autotest/testcase/rpower/cases0 b/xCAT-test/autotest/testcase/rpower/cases0
index 485758810..19ec464ae 100644
--- a/xCAT-test/autotest/testcase/rpower/cases0
+++ b/xCAT-test/autotest/testcase/rpower/cases0
@@ -160,25 +160,23 @@ check:rc==0
end
start:rpower_suspend_OpenpowerBmc
+hcp:openbmc
cmd:rpower $$CN suspend
-check:output=~Error: unsupported command rpower suspend for OpenPOWER
+check:output=~Error: Unsupported command: rpower suspend
check:rc==1
end
-start:rpower_softoff_OpenpowerBmc
-cmd:rpower $$CN softoff
-check:output=~Error: unsupported command rpower softoff for OpenPOWER
-check:rc==1
-end
start:rpower_wake_OpenpowerBmc
+hcp:openbmc
cmd:rpower $$CN wake
-check:output=~Error: unsupported command rpower wake for OpenPOWER
+check:output=~Error: Unsupported command: rpower wake
check:rc==1
end
start:rpower_errorcommand_OpenpowerBmc
+hcp:openbmc
cmd:rpower $$CN ddd
-check:output=~Unsupported command:
+check:output=~Error: Unsupported command: rpower ddd
check:rc==1
end
diff --git a/xCAT-test/autotest/testcase/rspconfig/cases0 b/xCAT-test/autotest/testcase/rspconfig/cases0
index 8266cc402..da4ddb70f 100644
--- a/xCAT-test/autotest/testcase/rspconfig/cases0
+++ b/xCAT-test/autotest/testcase/rspconfig/cases0
@@ -142,35 +142,45 @@ end
start:rspconfig_list_ip
despcription:rspconfig list bmc ip
-cmd:/opt/xcat/share/xcat/tools/autotest/testcase/rspconfig/rspconfig.sh -lip $$CN
+cmd:rspconfig $$CN ip
check:rc==0
+check:output=~__GETNODEATTR($$CN,bmc)__
end
start:rspconfig_list_gateway
+hcp:openbmc
description:rspconfig list openbmc gateway
Attribute: $$CN-The operation object of rspconfig command
-cmd:/opt/xcat/share/xcat/tools/autotest/testcase/rspconfig/rspconfig.sh -lg $$CN
+cmd:rspconfig $$CN gateway
+check:output=~$$CN: BMC Gateway:
check:rc==0
end
start:rspconfig_list_netmask
+hcp:openbmc
description:rspconfig list openbmc netmask
Attribute: $$CN-The operation object of rspconfig command
-cmd:/opt/xcat/share/xcat/tools/autotest/testcase/rspconfig/rspconfig.sh -ln $$CN
+cmd:rspconfig $$CN netmask
check:rc==0
+check:output=~$$CN: BMC Netmask:
end
start:rspconfig_list_vlan
-description:rspconfig list openbmc netmask
+description:rspconfig list openbmc vlan
Attribute: $$CN-The operation object of rspconfig command
-cmd:/opt/xcat/share/xcat/tools/autotest/testcase/rspconfig/rspconfig.sh -lv $$CN
+cmd: rspconfig $$CN vlan
check:rc==0
+check:output=~$$CN: BMC VLAN ID:
end
start:rspconfig_list_all
-description:rspconfig list openbmc netmask
+description:rspconfig list openbmc ip gateway netmask vlan
Attribute: $$CN-The operation object of rspconfig command
-cmd:/opt/xcat/share/xcat/tools/autotest/testcase/rspconfig/rspconfig.sh -la $$CN
+cmd: rspconfig $$CN ip gateway netmask vlan
check:rc==0
+check:output=~$$CN: BMC VLAN ID:
+check:output=~$$CN: BMC Gateway:
+check:output=~$$CN: BMC Netmask:
+check:output=~__GETNODEATTR($$CN,bmc)__
end
diff --git a/xCAT-test/autotest/testcase/snpool/cfg_wrong_cn_in_sn_pool_tftp_sync_mode b/xCAT-test/autotest/testcase/snpool/cfg_wrong_cn_in_sn_pool_tftp_sync_mode
new file mode 100644
index 000000000..235fe1e6c
--- /dev/null
+++ b/xCAT-test/autotest/testcase/snpool/cfg_wrong_cn_in_sn_pool_tftp_sync_mode
@@ -0,0 +1,155 @@
+start:cfg_wrong_cn_in_sn_pool_tftp_sync_mode
+description:The test case is intend to test the error handling of the service node pool when a compute has misconfigured node definition
+cmd:fdisk -l
+cmd:df -T
+#cmd:XCAT_DATABASE=$$XCAT_DATABASE /opt/xcat/share/xcat/tools/autotest/testcase/installation/pre_deploy_sn __GETNODEATTR($$SN,os)__ __GETNODEATTR($$SN,arch)__
+cmd:if [ ! -f /etc/xcat/cfgloc ];then XCAT_DATABASE=$$XCAT_DATABASE /opt/xcat/share/xcat/tools/autotest/testcase/installation/pre_deploy_sn __GETNODEATTR($$SN,os)__ __GETNODEATTR($$SN,arch)__;fi
+check:rc==0
+
+cmd:chtab key=nameservers site.value=""
+check:rc==0
+
+cmd:makedns -n
+check:rc==0
+cmd:makeconservercf $$SN,$$CN
+check:rc==0
+cmd:cat /etc/conserver.cf | grep $$SN
+check:output=~$$SN
+cmd:cat /etc/conserver.cf | grep $$CN
+check:output=~$$CN
+cmd:sleep 20
+cmd:if [[ "__GETNODEATTR($$SN,arch)__" = "ppc64" ]]; then getmacs -D $$SN -V; fi
+check:rc==0
+cmd:if [[ "__GETNODEATTR($$SN,arch)__" = "ppc64" ]]; then getmacs -D $$CN -V; fi
+check:rc==0
+cmd:makedhcp -n
+check:rc==0
+cmd:makedhcp -a
+check:rc==0
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then cat /var/lib/dhcp/db/dhcpd.leases|grep $$SN;elif cat /etc/*release |grep "Red Hat" >/dev/null;then cat /var/lib/dhcpd/dhcpd.leases|grep $$SN;fi
+check:output=~$$SN
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then cat /var/lib/dhcp/db/dhcpd.leases|grep $$CN;elif cat /etc/*release |grep "Red Hat" >/dev/null;then cat /var/lib/dhcpd/dhcpd.leases|grep $$CN;fi
+check:output=~$$CN
+cmd:chdef -t node $$SN,$$CN groups=service,all
+check:rc==0
+cmd:chdef -t group -o service profile=service installnic=mac
+check:rc==0
+cmd:chdef -t group -o service setupnfs=1 setupdhcp=1 setuptftp=1 setupnameserver=1 setupconserver=1 setupntp=1
+check:rc==0
+cmd:chdef -t group -o service nfsserver= tftpserver= xcatmaster= monserver=
+check:rc==0
+
+cmd:copycds $$ISO
+check:rc==0
+
+cmd:chdef -t site clustersite sharedtftp=0
+check:rc==0
+cmd:chdef -t site clustersite installloc=""
+check:rc==0
+
+cmd:cd /install/post/otherpkgs/__GETNODEATTR($$SN,os)__/__GETNODEATTR($$SN,arch)__/xcat/xcat-core && createrepo .
+check:rc==0
+
+cmd:if [[ "__GETNODEATTR($$SN,os)__" =~ "rh" ]]; then path="rh";elif [[ "__GETNODEATTR($$SN,os)__" =~ "sles" ]];then path="sles";fi; ver="__GETNODEATTR($$SN,os)__"; tmp=${ver%.*};ver=`echo "$tmp"|sed 's:[a-zA-Z]::g'`;cd /install/post/otherpkgs/__GETNODEATTR($$SN,os)__/__GETNODEATTR($$SN,arch)__/xcat/xcat-dep/$path$ver/__GETNODEATTR($$SN,arch)__ && createrepo .;
+check:rc==0
+
+cmd:chdef -t osimage __GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-service otherpkgdir=/install/post/otherpkgs/__GETNODEATTR($$SN,os)__/__GETNODEATTR($$SN,arch)__
+check:rc==0
+
+cmd:if [[ "__GETNODEATTR($$SN,os)__" =~ "rh" ]]; then path="rh";elif [[ "__GETNODEATTR($$SN,os)__" =~ "sles" ]];then path="sles";fi; ver="__GETNODEATTR($$SN,os)__"; chdef -t osimage __GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-service otherpkglist=/opt/xcat/share/xcat/install/$path/service.${ver%.*}.__GETNODEATTR($$SN,arch)__.otherpkgs.pkglist;
+check:rc==0
+
+cmd:rinstall $$SN,$$CN osimage=__GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-service
+check:rc==0
+check:output=~Provision node\(s\)\: $$SN $$CN
+
+cmd:if [[ -f /var/lib/dhcp/db/dhcpd.leases ]]; then cat /var/lib/dhcp/db/dhcpd.leases; elif [[ -f /var/lib/dhcpd/dhcpd.leases ]];then cat /var/lib/dhcpd/dhcpd.leases;elif [[ -f /var/lib/dhcp/dhcpd.leases ]];then cat /var/lib/dhcp/dhcpd.leases; fi
+cmd:/opt/xcat/share/xcat/tools/autotest/testcase/installation/customize_sleep_for_sn __GETNODEATTR($$SN,os)__ __GETNODEATTR($$SN,arch)__
+
+#Check status on SN after SN is installed
+cmd:ping $$SN -c 3
+check:rc==0
+check:output=~64 bytes from $$SN
+cmd:lsdef -l $$SN | grep status
+check:rc==0
+check:output=~booted
+cmd:xdsh $$SN date
+check:rc==0
+check:output=~\d\d:\d\d:\d\d
+#after bug 2586 is fixed, following 2 lines should be removed.
+cmd:if [[ "__GETNODEATTR($$SN,os)__" =~ "sles" ]];then xdsh $$SN service xcatd restart; fi
+check:rc==0
+cmd:xdsh $$SN "ps -ef | grep xcatd"
+check:rc==0
+check:output=~xcatd:
+cmd:xdsh $$SN "lsdef"
+check:rc==0
+check:output=~$$SN: $$SN
+cmd:xdsh $$SN "tabdump site"
+check:rc==0
+check:output=~tftpdir
+cmd:rsync -auv --exclude 'autoinst' /install $$SN:/
+check:rc==0
+
+#Check status on CN after CN is installed since CN is taken as another SN.
+cmd:ping $$CN -c 3
+check:rc==0
+check:output=~64 bytes from $$CN
+cmd:lsdef -l $$CN | grep status
+check:rc==0
+check:output=~booted
+cmd:xdsh $$CN date
+check:rc==0
+check:output=~\d\d:\d\d:\d\d
+#after bug 2586 is fixed, following 2 lines should be removed.
+cmd:if [[ "__GETNODEATTR($$CN,os)__" =~ "sles" ]];then xdsh $$CN service xcatd restart; fi
+check:rc==0
+cmd:xdsh $$CN "ps -ef | grep xcatd"
+check:rc==0
+check:output=~xcatd:
+cmd:xdsh $$CN "lsdef"
+check:rc==0
+check:output=~$$CN: $$CN
+cmd:xdsh $$CN "tabdump site"
+check:rc==0
+check:output=~tftpdir
+cmd:rsync -auv --exclude 'autoinst' /install $$CN:/
+check:rc==0
+
+#create a test compute node, set it's xcatmaster as SN, set it's service node as SN and CN
+cmd:mkdef -t node -o compute1 groups=compute ip=10.0.0.199 mac=4a:c8:f7:de:d0:09 profile=compute os=__GETNODEATTR($$CN,os)__ arch=__GETNODEATTR($$CN,arch)__ netboot=__GETNODEATTR($$CN,netboot)__
+check:rc==0
+cmd:chdef -t node -o compute1 servicenode=$$SN,$$CN xcatmaster=$$SN
+check:rc==0
+cmd:makehosts compute1
+check:rc==0
+cmd:cat /etc/hosts
+check:output=~compute1
+cmd:cp /etc/resolv.conf /etc/resolv.conf.bak
+cmd:echo "nameserver $$MN" >> /etc/resolv.conf
+check:rc==0
+cmd:makedns -n
+check:rc==0
+cmd:makedhcp -n
+check:rc==0
+cmd:makedhcp -a
+check:rc==0
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then cat /var/lib/dhcp/db/dhcpd.leases|grep compute1;elif cat /etc/*release |grep "Red Hat" >/dev/null;then cat /var/lib/dhcpd/dhcpd.leases|grep compute1;fi
+check:output=~compute1
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then xdsh $$SN cat /var/lib/dhcp/db/dhcpd.leases|grep compute1;elif cat /etc/*release |grep "Red Hat" >/dev/null;then xdsh $$SN cat /var/lib/dhcpd/dhcpd.leases|grep compute1;fi
+check:output=~compute1
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then xdsh $$CN cat /var/lib/dhcp/db/dhcpd.leases|grep compute1;elif cat /etc/*release |grep "Red Hat" >/dev/null;then xdsh $$CN cat /var/lib/dhcpd/dhcpd.leases|grep compute1;fi
+check:output=~compute1
+##
+# Unset mac
+##
+cmd:chdef compute1 mac=
+check:rc==0
+cmd:nodeset compute1 osimage=__GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-compute
+check:rc!=0
+check:output=~compute1: Error
+
+cmd:noderm compute1
+check:rc==0
+cmd:cp -f /etc/resolv.conf.bak /etc/resolv.conf
+end
diff --git a/xCAT-test/autotest/testcase/snpool/not_set_xcatmaster_in_sn_pool_tftp_sync_mode b/xCAT-test/autotest/testcase/snpool/not_set_xcatmaster_in_sn_pool_tftp_sync_mode
new file mode 100644
index 000000000..805f33e21
--- /dev/null
+++ b/xCAT-test/autotest/testcase/snpool/not_set_xcatmaster_in_sn_pool_tftp_sync_mode
@@ -0,0 +1,165 @@
+start:not_set_xcatmaster_in_sn_pool_tftp_sync_mode
+description: this case is to test when compute nodes' xcatmaster is not set in service node pool environment, compute node's provision files are correctly set after nodeset.
+cmd:fdisk -l
+cmd:df -T
+#cmd:XCAT_DATABASE=$$XCAT_DATABASE /opt/xcat/share/xcat/tools/autotest/testcase/installation/pre_deploy_sn __GETNODEATTR($$SN,os)__ __GETNODEATTR($$SN,arch)__
+cmd:if [ ! -f /etc/xcat/cfgloc ];then XCAT_DATABASE=$$XCAT_DATABASE /opt/xcat/share/xcat/tools/autotest/testcase/installation/pre_deploy_sn __GETNODEATTR($$SN,os)__ __GETNODEATTR($$SN,arch)__;fi
+check:rc==0
+
+cmd:chtab key=nameservers site.value=""
+check:rc==0
+
+cmd:makedns -n
+check:rc==0
+cmd:makeconservercf $$SN,$$CN
+check:rc==0
+cmd:cat /etc/conserver.cf | grep $$SN
+check:output=~$$SN
+cmd:cat /etc/conserver.cf | grep $$CN
+check:output=~$$CN
+cmd:sleep 20
+cmd:if [[ "__GETNODEATTR($$SN,arch)__" = "ppc64" ]]; then getmacs -D $$SN -V; fi
+check:rc==0
+cmd:if [[ "__GETNODEATTR($$SN,arch)__" = "ppc64" ]]; then getmacs -D $$CN -V; fi
+check:rc==0
+cmd:makedhcp -n
+check:rc==0
+cmd:makedhcp -a
+check:rc==0
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then cat /var/lib/dhcp/db/dhcpd.leases|grep $$SN;elif cat /etc/*release |grep "Red Hat" >/dev/null;then cat /var/lib/dhcpd/dhcpd.leases|grep $$SN;fi
+check:output=~$$SN
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then cat /var/lib/dhcp/db/dhcpd.leases|grep $$CN;elif cat /etc/*release |grep "Red Hat" >/dev/null;then cat /var/lib/dhcpd/dhcpd.leases|grep $$CN;fi
+check:output=~$$CN
+cmd:chdef -t node $$SN,$$CN groups=service,all
+check:rc==0
+cmd:chdef -t group -o service profile=service installnic=mac
+check:rc==0
+cmd:chdef -t group -o service setupnfs=1 setupdhcp=1 setuptftp=1 setupnameserver=1 setupconserver=1 setupntp=1
+check:rc==0
+cmd:chdef -t group -o service nfsserver= tftpserver= xcatmaster= monserver=
+check:rc==0
+
+cmd:copycds $$ISO
+check:rc==0
+
+
+cmd:chdef -t site clustersite sharedtftp=0
+check:rc==0
+cmd:chdef -t site clustersite installloc=""
+check:rc==0
+
+cmd:cd /install/post/otherpkgs/__GETNODEATTR($$SN,os)__/__GETNODEATTR($$SN,arch)__/xcat/xcat-core && createrepo .
+check:rc==0
+
+cmd:if [[ "__GETNODEATTR($$SN,os)__" =~ "rh" ]]; then path="rh";elif [[ "__GETNODEATTR($$SN,os)__" =~ "sles" ]];then path="sles";fi; ver="__GETNODEATTR($$SN,os)__"; tmp=${ver%.*};ver=`echo "$tmp"|sed 's:[a-zA-Z]::g'`;cd /install/post/otherpkgs/__GETNODEATTR($$SN,os)__/__GETNODEATTR($$SN,arch)__/xcat/xcat-dep/$path$ver/__GETNODEATTR($$SN,arch)__ && createrepo .;
+check:rc==0
+
+cmd:chdef -t osimage __GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-service otherpkgdir=/install/post/otherpkgs/__GETNODEATTR($$SN,os)__/__GETNODEATTR($$SN,arch)__
+check:rc==0
+
+cmd:if [[ "__GETNODEATTR($$SN,os)__" =~ "rh" ]]; then path="rh";elif [[ "__GETNODEATTR($$SN,os)__" =~ "sles" ]];then path="sles";fi; ver="__GETNODEATTR($$SN,os)__"; chdef -t osimage __GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-service otherpkglist=/opt/xcat/share/xcat/install/$path/service.${ver%.*}.__GETNODEATTR($$SN,arch)__.otherpkgs.pkglist;
+check:rc==0
+
+cmd:rinstall $$SN,$$CN osimage=__GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-service
+check:rc==0
+check:output=~Provision node\(s\)\: $$SN $$CN
+
+cmd:if [[ -f /var/lib/dhcp/db/dhcpd.leases ]]; then cat /var/lib/dhcp/db/dhcpd.leases; elif [[ -f /var/lib/dhcpd/dhcpd.leases ]];then cat /var/lib/dhcpd/dhcpd.leases;elif [[ -f /var/lib/dhcp/dhcpd.leases ]];then cat /var/lib/dhcp/dhcpd.leases; fi
+cmd:/opt/xcat/share/xcat/tools/autotest/testcase/installation/customize_sleep_for_sn __GETNODEATTR($$SN,os)__ __GETNODEATTR($$SN,arch)__
+
+#Check status on SN after SN is installed
+cmd:ping $$SN -c 3
+check:rc==0
+check:output=~64 bytes from $$SN
+cmd:lsdef -l $$SN | grep status
+check:rc==0
+check:output=~booted
+cmd:xdsh $$SN date
+check:rc==0
+check:output=~\d\d:\d\d:\d\d
+#after bug 2586 is fixed, following 2 lines should be removed.
+cmd:if [[ "__GETNODEATTR($$SN,os)__" =~ "sles" ]];then xdsh $$SN service xcatd restart; fi
+check:rc==0
+cmd:xdsh $$SN "ps -ef |grep xcatd"
+check:rc==0
+check:output=~xcatd:
+cmd:xdsh $$SN "lsdef"
+check:rc==0
+check:output=~$$SN: $$SN
+cmd:xdsh $$SN "tabdump site"
+check:rc==0
+check:output=~tftpdir
+cmd:rsync -auv --exclude 'autoinst' /install $$SN:/
+check:rc==0
+
+#Check status on CN after CN is installed since CN is taken as another SN.
+cmd:ping $$CN -c 3
+check:rc==0
+check:output=~64 bytes from $$CN
+cmd:lsdef -l $$CN | grep status
+check:rc==0
+check:output=~booted
+cmd:xdsh $$CN date
+check:rc==0
+check:output=~\d\d:\d\d:\d\d
+#after bug 2586 is fixed, following 2 lines should be removed.
+cmd:if [[ "__GETNODEATTR($$CN,os)__" =~ "sles" ]];then xdsh $$CN service xcatd restart; fi
+check:rc==0
+cmd:xdsh $$CN "ps -ef |grep xcatd"
+check:rc==0
+check:output=~xcatd:
+cmd:xdsh $$CN "lsdef"
+check:rc==0
+check:output=~$$CN: $$CN
+cmd:xdsh $$CN "tabdump site"
+check:rc==0
+check:output=~tftpdir
+cmd:rsync -auv --exclude 'autoinst' /install $$CN:/
+check:rc==0
+
+#create a test compute node, don't set it's xcatmaster, set it's service node as SN and CN
+cmd:mkdef -t node -o compute1 groups=compute ip=10.0.0.199 mac=4a:c8:f7:de:d0:09 profile=compute os=__GETNODEATTR($$CN,os)__ arch=__GETNODEATTR($$CN,arch)__ netboot=__GETNODEATTR($$CN,netboot)__
+check:rc==0
+cmd:chdef -t node -o compute1 servicenode=$$SN,$$CN xcatmaster=
+check:rc==0
+cmd:makehosts compute1
+check:rc==0
+cmd:cat /etc/hosts
+check:output=~compute1
+cmd:cp /etc/resolv.conf /etc/resolv.conf.bak
+cmd:echo "nameserver $$MN" >> /etc/resolv.conf
+check:rc==0
+cmd:makedns -n
+check:rc==0
+cmd:makedhcp -n
+check:rc==0
+cmd:makedhcp -a
+check:rc==0
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then cat /var/lib/dhcp/db/dhcpd.leases|grep compute1;elif cat /etc/*release |grep "Red Hat" >/dev/null;then cat /var/lib/dhcpd/dhcpd.leases|grep compute1;fi
+check:output=~compute1
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then xdsh $$SN cat /var/lib/dhcp/db/dhcpd.leases|grep compute1;elif cat /etc/*release |grep "Red Hat" >/dev/null;then xdsh $$SN cat /var/lib/dhcpd/dhcpd.leases|grep compute1;fi
+check:output=~compute1
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then xdsh $$CN cat /var/lib/dhcp/db/dhcpd.leases|grep compute1;elif cat /etc/*release |grep "Red Hat" >/dev/null;then xdsh $$CN cat /var/lib/dhcpd/dhcpd.leases|grep compute1;fi
+check:output=~compute1
+cmd:nodeset compute1 osimage=__GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-compute
+check:rc==0
+check:output=~compute1: install __GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-compute
+cmd:if [[ "__GETNODEATTR($$CN,netboot)__" =~ "grub2" ]]; then cat /tftpboot/boot/__GETNODEATTR($$CN,netboot)__/compute1;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "yaboot" ]];then cat /tftpboot/yaboot.conf*;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "xnba" ]];then cat /tftpboot/xcat/xnba/nodes/compute1;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "petitboot" ]];then cat /tftpboot/petitboot/compute1;fi
+check:output=~http://$$MN|http://$$MASTERIP|http://${next-server}
+cmd:if [[ "__GETNODEATTR($$CN,netboot)__" =~ "grub2" ]]; then xdsh $$SN cat /tftpboot/boot/__GETNODEATTR($$CN,netboot)__/compute1;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "yaboot" ]];then xdsh $$SN cat /tftpboot/yaboot.conf*;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "xnba" ]];then xdsh $$SN cat /tftpboot/xcat/xnba/nodes/compute1;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "petitboot" ]];then xdsh $$SN cat /tftpboot/petitboot/compute1;fi
+check:output=~http://$$SN|http://__GETNODEATTR($$SN,ip)__|http://${next-server}
+cmd:if [[ "__GETNODEATTR($$CN,netboot)__" =~ "grub2" ]]; then xdsh $$CN cat /tftpboot/boot/__GETNODEATTR($$CN,netboot)__/compute1;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "yaboot" ]];then xdsh $$CN cat /tftpboot/yaboot.conf*;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "xnba" ]];then xdsh $$CN cat /tftpboot/xcat/xnba/nodes/compute1;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "petitboot" ]];then xdsh $$CN cat /tftpboot/petitboot/compute1;fi
+check:output=~http://$$CN|http://__GETNODEATTR($$CN,ip)__|http://${next-server}
+
+#process the speicial case when netboot=petitboot, since we have no physical machine test environment at the moment
+cmd:if [[ "__GETNODEATTR($$CN,arch)__" =~ "ppc64le" ]] && [[ "__GETNODEATTR($$CN,netboot)__" != "petitboot" ]]; then chdef compute1 netboot=petitboot;nodeset compute1 osimage=__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-install-compute;cat /tftpboot/petitboot/compute1;else echo "http://$$MN";fi
+check:output=~http://$$MN|http://$$MASTERIP|http://${next-server}
+cmd:if [[ "__GETNODEATTR($$CN,arch)__" =~ "ppc64le" ]]; then xdsh $$SN cat /tftpboot/petitboot/compute1;else echo "http://$$SN";fi
+check:output=~http://$$SN|http://__GETNODEATTR($$SN,ip)__|http://${next-server}
+cmd:if [[ "__GETNODEATTR($$CN,arch)__" =~ "ppc64le" ]]; then xdsh $$CN cat /tftpboot/petitboot/compute1;else echo "http://$$CN";fi
+check:output=~http://$$CN|http://__GETNODEATTR($$CN,ip)__|http://${next-server}
+
+cmd:noderm compute1
+check:rc==0
+cmd:cp -f /etc/resolv.conf.bak /etc/resolv.conf
+end
diff --git a/xCAT-test/autotest/testcase/snpool/set_disjointdhcps_in_sn_pool_tftp_sync_mode b/xCAT-test/autotest/testcase/snpool/set_disjointdhcps_in_sn_pool_tftp_sync_mode
new file mode 100644
index 000000000..8c369410e
--- /dev/null
+++ b/xCAT-test/autotest/testcase/snpool/set_disjointdhcps_in_sn_pool_tftp_sync_mode
@@ -0,0 +1,118 @@
+start:set_disjointdhcps_in_sn_pool_tftp_sync_mode
+description: Verify the disjointdhcps feature when petitboot is used for OS loader.
+cmd:rmdef testnode1
+cmd:rm -f /tftpboot/petitboot/testnode1
+cmd:mkdef -t node -o testnode1 arch=ppc64le cons=bmc groups=ipmi ip=10.1.1.200 mac=e6:d4:d2:3a:ad:06 mgt=ipmi profile=compute os=rhels7.99
+check:rc==0
+cmd:cp -f /etc/hosts /etc/hosts.xcattestbak
+cmd:echo "10.1.1.200 testnode1" >> /etc/hosts
+cmd:makedns -n
+check:rc==0
+cmd:chdef testnode1 netboot=petitboot addkcmdline=debug
+check:rc==0
+cmd:mkdef "rhels7.99-ppc64le-install-compute" -u profile=compute provmethod=install osvers=rhels7.99 osarch=ppc64le
+cmd:xdsh $$SN 'mkdir -p /install/rhels7.99/ppc64le'
+cmd:xdsh $$SN 'mkdir -p /install/rhels7.99/ppc64le/ppc/ppc64le'
+cmd:xdsh $$SN 'echo blah >/install/rhels7.99/ppc64le/ppc/ppc64le/vmlinuz'
+cmd:xdsh $$SN 'echo blah >/install/rhels7.99/ppc64le/ppc/ppc64le/initrd.img'
+cmd:xdsh $$CN 'mkdir -p /install/rhels7.99/ppc64le'
+cmd:xdsh $$CN 'mkdir -p /install/rhels7.99/ppc64le/ppc/ppc64le'
+cmd:xdsh $$CN 'echo blah >/install/rhels7.99/ppc64le/ppc/ppc64le/vmlinuz'
+cmd:xdsh $$CN 'echo blah >/install/rhels7.99/ppc64le/ppc/ppc64le/initrd.img'
+cmd:mkdir -p /install/rhels7.99/ppc64le
+cmd:mkdir -p /install/rhels7.99/ppc64le/ppc/ppc64le
+cmd:echo blah >/install/rhels7.99/ppc64le/ppc/ppc64le/vmlinuz
+cmd:echo blah >/install/rhels7.99/ppc64le/ppc/ppc64le/initrd.img
+cmd:nodeset testnode1 osimage=rhels7.99-ppc64le-install-compute
+check:rc==0
+cmd:grep "debug" /tftpboot/petitboot/testnode1
+check:rc==0
+#cmd:makedhcp -q testnode1 | grep ^testnode1:
+#check:rc==0
+cmd:nodeset testnode1 offline
+check:rc==0
+cmd:grep "debug" /tftpboot/petitboot/testnode1
+check:rc!=0
+cmd:chdef -t site sharedtftp=0 disjointdhcps=0
+check:rc==0
+cmd:xdsh $$SN 'umount /tftpboot'
+cmd:xdsh $$CN 'umount /tftpboot'
+
+##
+# Do rsync against /tftpboot directory
+##
+##
+
+cmd:cd / && rsync -P -p -r -o -g -v tftpboot $$SN:/
+check:rc==0
+cmd:cd / && rsync -P -p -r -o -g -v tftpboot $$CN:/
+check:rc==0
+
+cmd:nodeset testnode1 osimage=rhels7.99-ppc64le-install-compute
+check:rc==0
+cmd:xdsh $$SN 'test -f /tftpboot/petitboot/testnode1'
+check:rc==0
+cmd:xdsh $$CN 'test -f /tftpboot/petitboot/testnode1'
+check:rc==0
+cmd:nodeset testnode1 offline
+check:rc==0
+
+##
+# Do testing
+##
+##
+
+cmd:chdef -t site disjointdhcps=1
+check:rc==0
+cmd:chdef -t node testnode1 servicenode=$$SN
+
+check:rc==0
+cmd:nodeset testnode1 osimage=rhels7.99-ppc64le-install-compute
+check:rc==0
+cmd:test -f /tftpboot/petitboot/testnode1
+check:rc!=0
+cmd:xdsh $$SN 'test -f /tftpboot/petitboot/testnode1'
+check:rc==0
+cmd:xdsh $$CN 'test -f /tftpboot/petitboot/testnode1'
+check:rc!=0
+cmd:nodeset testnode1 offline
+check:rc==0
+# DHCP dynamic range
+cmd:chdef -t network 20_0_0_0-255_0_0_0 net=20.0.0.0 mask=255.0.0.0 dynamicrange=20.0.0.1-20.0.0.2 tftpserver=$$SN dhcpserver=$$CN
+check:rc==0
+cmd:nodeset testnode1 osimage=rhels7.99-ppc64le-install-compute
+#check:rc==0
+cmd:xdsh $$SN 'test -f /tftpboot/petitboot/testnode1'
+check:rc==0
+cmd:xdsh $$CN 'test -f /tftpboot/petitboot/testnode1'
+check:rc!=0
+##
+# Check the DHCP lease file
+##
+cmd:xdsh $$CN 'cat /var/lib/dhcp/db/dhcpd.leases /var/lib/dhcpd/dhcpd.leases 2>/dev/null' | grep e6:d4:d2:3a:ad:06
+check:rc==0
+
+##
+# Clean up
+##
+##
+
+#cmd:chdef -t site sharedtftp=1
+#check:rc==0
+cmd:chdef -t site disjointdhcps=0
+check:rc==0
+cmd:xdsh $$SN 'rm -rf /tftpboot'
+cmd:xdsh $$CN 'rm -rf /tftpboot'
+cmd:chdef -t node -o testnode1 ip=
+check:rc==0
+cmd:cp -f /etc/hosts.xcattestbak /etc/hosts
+cmd:getent hosts testnode1 | grep testnode1
+check:rc!=0
+cmd:nodeset testnode1 osimage=rhels7.99-ppc64le-install-compute
+check:rc!=0
+cmd:noderm testnode1
+cmd:rmdef -t osimage -o "rhels7.99-ppc64le-install-compute"
+cmd:rm -rf /install/rhels7.99
+cmd:xdsh $$SN 'rm -rf /install/rhels7.99'
+cmd:xdsh $$CN 'rm -rf /install/rhels7.99'
+end
diff --git a/xCAT-test/autotest/testcase/snpool/set_xcatmaster_in_sn_pool_tftp_sync_mode b/xCAT-test/autotest/testcase/snpool/set_xcatmaster_in_sn_pool_tftp_sync_mode
new file mode 100644
index 000000000..204826de1
--- /dev/null
+++ b/xCAT-test/autotest/testcase/snpool/set_xcatmaster_in_sn_pool_tftp_sync_mode
@@ -0,0 +1,165 @@
+start:set_xcatmaster_in_sn_pool_tftp_sync_mode
+description: this case is to test when compute nodes' xcatmaster is set in service node pool environment,compute node's provision files are correctly set after nodeset.
+cmd:fdisk -l
+cmd:df -T
+#cmd:XCAT_DATABASE=$$XCAT_DATABASE /opt/xcat/share/xcat/tools/autotest/testcase/installation/pre_deploy_sn __GETNODEATTR($$SN,os)__ __GETNODEATTR($$SN,arch)__
+cmd:if [ ! -f /etc/xcat/cfgloc ];then XCAT_DATABASE=$$XCAT_DATABASE /opt/xcat/share/xcat/tools/autotest/testcase/installation/pre_deploy_sn __GETNODEATTR($$SN,os)__ __GETNODEATTR($$SN,arch)__;fi
+check:rc==0
+
+cmd:chtab key=nameservers site.value=""
+check:rc==0
+
+cmd:makedns -n
+check:rc==0
+cmd:makeconservercf $$SN,$$CN
+check:rc==0
+cmd:cat /etc/conserver.cf | grep $$SN
+check:output=~$$SN
+cmd:cat /etc/conserver.cf | grep $$CN
+check:output=~$$CN
+cmd:sleep 20
+cmd:if [[ "__GETNODEATTR($$SN,arch)__" = "ppc64" ]]; then getmacs -D $$SN -V; fi
+check:rc==0
+cmd:if [[ "__GETNODEATTR($$SN,arch)__" = "ppc64" ]]; then getmacs -D $$CN -V; fi
+check:rc==0
+cmd:makedhcp -n
+check:rc==0
+cmd:makedhcp -a
+check:rc==0
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then cat /var/lib/dhcp/db/dhcpd.leases|grep $$SN;elif cat /etc/*release |grep "Red Hat" >/dev/null;then cat /var/lib/dhcpd/dhcpd.leases|grep $$SN;fi
+check:output=~$$SN
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then cat /var/lib/dhcp/db/dhcpd.leases|grep $$CN;elif cat /etc/*release |grep "Red Hat" >/dev/null;then cat /var/lib/dhcpd/dhcpd.leases|grep $$CN;fi
+check:output=~$$CN
+cmd:chdef -t node $$SN,$$CN groups=service,all
+check:rc==0
+cmd:chdef -t group -o service profile=service installnic=mac
+check:rc==0
+cmd:chdef -t group -o service setupnfs=1 setupdhcp=1 setuptftp=1 setupnameserver=1 setupconserver=1 setupntp=1
+check:rc==0
+cmd:chdef -t group -o service nfsserver= tftpserver= xcatmaster= monserver=
+check:rc==0
+
+cmd:copycds $$ISO
+check:rc==0
+
+cmd:chdef -t site clustersite sharedtftp=0
+check:rc==0
+cmd:chdef -t site clustersite installloc=""
+check:rc==0
+
+cmd:cd /install/post/otherpkgs/__GETNODEATTR($$SN,os)__/__GETNODEATTR($$SN,arch)__/xcat/xcat-core && createrepo .
+check:rc==0
+
+cmd:if [[ "__GETNODEATTR($$SN,os)__" =~ "rh" ]]; then path="rh";elif [[ "__GETNODEATTR($$SN,os)__" =~ "sles" ]];then path="sles";fi; ver="__GETNODEATTR($$SN,os)__"; tmp=${ver%.*};ver=`echo "$tmp"|sed 's:[a-zA-Z]::g'`;cd /install/post/otherpkgs/__GETNODEATTR($$SN,os)__/__GETNODEATTR($$SN,arch)__/xcat/xcat-dep/$path$ver/__GETNODEATTR($$SN,arch)__ && createrepo .;
+check:rc==0
+
+cmd:chdef -t osimage __GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-service otherpkgdir=/install/post/otherpkgs/__GETNODEATTR($$SN,os)__/__GETNODEATTR($$SN,arch)__
+check:rc==0
+
+cmd:if [[ "__GETNODEATTR($$SN,os)__" =~ "rh" ]]; then path="rh";elif [[ "__GETNODEATTR($$SN,os)__" =~ "sles" ]];then path="sles";fi; ver="__GETNODEATTR($$SN,os)__"; chdef -t osimage __GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-service otherpkglist=/opt/xcat/share/xcat/install/$path/service.${ver%.*}.__GETNODEATTR($$SN,arch)__.otherpkgs.pkglist;
+check:rc==0
+
+cmd:rinstall $$SN,$$CN osimage=__GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-service
+check:rc==0
+check:output=~Provision node\(s\)\: $$SN $$CN
+
+cmd:if [[ -f /var/lib/dhcp/db/dhcpd.leases ]]; then cat /var/lib/dhcp/db/dhcpd.leases; elif [[ -f /var/lib/dhcpd/dhcpd.leases ]];then cat /var/lib/dhcpd/dhcpd.leases;elif [[ -f /var/lib/dhcp/dhcpd.leases ]];then cat /var/lib/dhcp/dhcpd.leases; fi
+cmd:/opt/xcat/share/xcat/tools/autotest/testcase/installation/customize_sleep_for_sn __GETNODEATTR($$SN,os)__ __GETNODEATTR($$SN,arch)__
+
+#Check status on SN after SN is installed
+cmd:ping $$SN -c 3
+check:rc==0
+check:output=~64 bytes from $$SN
+cmd:lsdef -l $$SN | grep status
+check:rc==0
+check:output=~booted
+cmd:xdsh $$SN date
+check:rc==0
+check:output=~\d\d:\d\d:\d\d
+#after bug 2586 is fixed, following 2 lines should be removed.
+cmd:if [[ "__GETNODEATTR($$SN,os)__" =~ "sles" ]];then xdsh $$SN service xcatd restart; fi
+check:rc==0
+cmd:xdsh $$SN "ps -ef |grep xcatd"
+check:rc==0
+check:output=~xcatd:
+cmd:xdsh $$SN "lsdef"
+check:rc==0
+check:output=~$$SN: $$SN
+cmd:xdsh $$SN "tabdump site"
+check:rc==0
+check:output=~tftpdir
+cmd:rsync -auv --exclude 'autoinst' /install $$SN:/
+check:rc==0
+
+#Check status on CN after CN is installed since CN is taken as another SN.
+cmd:ping $$CN -c 3
+check:rc==0
+check:output=~64 bytes from $$CN
+cmd:lsdef -l $$CN | grep status
+check:rc==0
+check:output=~booted
+cmd:xdsh $$CN date
+check:rc==0
+check:output=~\d\d:\d\d:\d\d
+#after bug 2586 is fixed, following 2 lines should be removed.
+cmd:if [[ "__GETNODEATTR($$CN,os)__" =~ "sles" ]];then xdsh $$CN service xcatd restart; fi
+check:rc==0
+cmd:xdsh $$CN "ps -ef |grep xcatd"
+check:rc==0
+check:output=~xcatd:
+cmd:xdsh $$CN "lsdef"
+check:rc==0
+check:output=~$$CN: $$CN
+cmd:xdsh $$CN "tabdump site"
+check:rc==0
+check:output=~tftpdir
+cmd:rsync -auv --exclude 'autoinst' /install $$CN:/
+check:rc==0
+
+
+#create a test compute node, set it's xcatmaster as SN, set it's service node as SN and CN
+cmd:mkdef -t node -o compute1 groups=compute ip=10.0.0.199 mac=4a:c8:f7:de:d0:09 profile=compute os=__GETNODEATTR($$CN,os)__ arch=__GETNODEATTR($$CN,arch)__ netboot=__GETNODEATTR($$CN,netboot)__
+check:rc==0
+cmd:chdef -t node -o compute1 servicenode=$$SN,$$CN xcatmaster=$$SN
+check:rc==0
+cmd:makehosts compute1
+check:rc==0
+cmd:cat /etc/hosts
+check:output=~compute1
+cmd:cp /etc/resolv.conf /etc/resolv.conf.bak
+cmd:echo "nameserver $$MN" >> /etc/resolv.conf
+check:rc==0
+cmd:makedns -n
+check:rc==0
+cmd:makedhcp -n
+check:rc==0
+cmd:makedhcp -a
+check:rc==0
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then cat /var/lib/dhcp/db/dhcpd.leases|grep compute1;elif cat /etc/*release |grep "Red Hat" >/dev/null;then cat /var/lib/dhcpd/dhcpd.leases|grep compute1;fi
+check:output=~compute1
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then xdsh $$SN cat /var/lib/dhcp/db/dhcpd.leases|grep compute1;elif cat /etc/*release |grep "Red Hat" >/dev/null;then xdsh $$SN cat /var/lib/dhcpd/dhcpd.leases|grep compute1;fi
+check:output=~compute1
+cmd:if cat /etc/*release |grep SUSE >/dev/null;then xdsh $$CN cat /var/lib/dhcp/db/dhcpd.leases|grep compute1;elif cat /etc/*release |grep "Red Hat" >/dev/null;then xdsh $$CN cat /var/lib/dhcpd/dhcpd.leases|grep compute1;fi
+check:output=~compute1
+cmd:nodeset compute1 osimage=__GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-compute
+check:rc==0
+check:output=~compute1: install __GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-compute
+cmd:if [[ "__GETNODEATTR($$CN,netboot)__" =~ "grub2" ]]; then cat /tftpboot/boot/__GETNODEATTR($$CN,netboot)__/compute1;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "yaboot" ]];then cat /tftpboot/yaboot.conf*;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "xnba" ]];then cat /tftpboot/xcat/xnba/nodes/compute1;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "petitboot" ]];then cat /tftpboot/petitboot/compute1;fi
+check:output=~http://$$SN|http://__GETNODEATTR($$SN,ip)__|http://${next-server}
+cmd:if [[ "__GETNODEATTR($$CN,netboot)__" =~ "grub2" ]]; then xdsh $$SN cat /tftpboot/boot/__GETNODEATTR($$CN,netboot)__/compute1;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "yaboot" ]];then xdsh $$SN cat /tftpboot/yaboot.conf*;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "xnba" ]];then xdsh $$SN cat /tftpboot/xcat/xnba/nodes/compute1;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "petitboot" ]];then xdsh $$SN cat /tftpboot/petitboot/compute1;fi
+check:output=~http://$$SN|http://__GETNODEATTR($$SN,ip)__|http://${next-server}
+cmd:if [[ "__GETNODEATTR($$CN,netboot)__" =~ "grub2" ]]; then xdsh $$CN cat /tftpboot/boot/__GETNODEATTR($$CN,netboot)__/compute1;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "yaboot" ]];then xdsh $$CN cat /tftpboot/yaboot.conf*;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "xnba" ]];then xdsh $$CN cat /tftpboot/xcat/xnba/nodes/compute1;elif [[ "__GETNODEATTR($$CN,netboot)__" =~ "petitboot" ]];then xdsh $$CN cat /tftpboot/petitboot/compute1;fi
+check:output=~http://$$SN|http://__GETNODEATTR($$SN,ip)__|http://${next-server}
+
+#process the speicial case when netboot=petitboot, since we have no physical machine test environment at the moment
+cmd:if [[ "__GETNODEATTR($$CN,arch)__" =~ "ppc64le" ]] && [[ "__GETNODEATTR($$CN,netboot)__" != "petitboot" ]]; then chdef compute1 netboot=petitboot;nodeset compute1 osimage=__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-install-compute;cat /tftpboot/petitboot/compute1;else echo "http://$$SN";fi
+check:output=~http://$$SN|http://__GETNODEATTR($$SN,ip)__|http://${next-server}
+cmd:if [[ "__GETNODEATTR($$CN,arch)__" =~ "ppc64le" ]]; then xdsh $$SN cat /tftpboot/petitboot/compute1;else echo "http://$$SN";fi
+check:output=~http://$$SN|http://__GETNODEATTR($$SN,ip)__|http://${next-server}
+cmd:if [[ "__GETNODEATTR($$CN,arch)__" =~ "ppc64le" ]]; then xdsh $$CN cat /tftpboot/petitboot/compute1;else echo "http://$$SN";fi
+check:output=~http://$$SN|http://__GETNODEATTR($$SN,ip)__|http://${next-server}
+
+cmd:noderm compute1
+check:rc==0
+cmd:cp -f /etc/resolv.conf.bak /etc/resolv.conf
+end
diff --git a/xCAT-test/autotest/testcase/snpool/setup_sn_pool_tftp_sync_mode b/xCAT-test/autotest/testcase/snpool/setup_sn_pool_tftp_sync_mode
new file mode 100644
index 000000000..3f088945f
--- /dev/null
+++ b/xCAT-test/autotest/testcase/snpool/setup_sn_pool_tftp_sync_mode
@@ -0,0 +1,118 @@
+start:setup_sn_pool_tftp_sync_mode
+description: this case is to test when sharedtftp=0 and installloc=/install are not set on mn, after all service nodes are installed, /tftpboot and /install directory on all service nodes are separated and need to be rsynced. Since test framework only support 1 sn and 1 cn parameter. This case will install CN as another service node.
+cmd:fdisk -l
+cmd:df -T
+#cmd:XCAT_DATABASE=$$XCAT_DATABASE /opt/xcat/share/xcat/tools/autotest/testcase/installation/pre_deploy_sn __GETNODEATTR($$SN,os)__ __GETNODEATTR($$SN,arch)__
+cmd:if [ ! -f /etc/xcat/cfgloc ];then XCAT_DATABASE=$$XCAT_DATABASE /opt/xcat/share/xcat/tools/autotest/testcase/installation/pre_deploy_sn __GETNODEATTR($$SN,os)__ __GETNODEATTR($$SN,arch)__;fi
+check:rc==0
+
+cmd:chtab key=nameservers site.value=""
+check:rc==0
+
+cmd:makedns -n
+check:rc==0
+cmd:makeconservercf $$SN,$$CN
+check:rc==0
+cmd:cat /etc/conserver.cf | grep $$SN
+check:output=~$$SN
+cmd:cat /etc/conserver.cf | grep $$CN
+check:output=~$$CN
+cmd:sleep 20
+cmd:if [[ "__GETNODEATTR($$SN,arch)__" = "ppc64" ]]; then getmacs -D $$SN -V; fi
+check:rc==0
+cmd:if [[ "__GETNODEATTR($$SN,arch)__" = "ppc64" ]]; then getmacs -D $$CN -V; fi
+check:rc==0
+cmd:makedhcp -n
+check:rc==0
+cmd:makedhcp -a
+check:rc==0
+cmd:if cat /etc/*release | grep SUSE >/dev/null ; then cat /var/lib/dhcp/db/dhcpd.leases | grep $$SN ; elif cat /etc/*release | grep "Red Hat" >/dev/null ; then cat /var/lib/dhcpd/dhcpd.leases | grep $$SN ; fi
+check:output=~$$SN
+cmd:if cat /etc/*release | grep SUSE >/dev/null ; then cat /var/lib/dhcp/db/dhcpd.leases | grep $$CN ; elif cat /etc/*release | grep "Red Hat" >/dev/null ; then cat /var/lib/dhcpd/dhcpd.leases | grep $$CN ; fi
+check:output=~$$CN
+cmd:chdef -t node $$SN,$$CN groups=service,all
+check:rc==0
+cmd:chdef -t group -o service profile=service installnic=mac
+check:rc==0
+cmd:chdef -t group -o service setupnfs=1 setupdhcp=1 setuptftp=1 setupnameserver=1 setupconserver=1 setupntp=1
+check:rc==0
+cmd:chdef -t group -o service nfsserver= tftpserver= xcatmaster= monserver=
+check:rc==0
+
+cmd:copycds $$ISO
+check:rc==0
+
+cmd:chdef -t site clustersite sharedtftp=0
+check:rc==0
+cmd:chdef -t site clustersite installloc=""
+check:rc==0
+
+cmd:cd /install/post/otherpkgs/__GETNODEATTR($$SN,os)__/__GETNODEATTR($$SN,arch)__/xcat/xcat-core && createrepo .
+check:rc==0
+
+cmd:if [[ "__GETNODEATTR($$SN,os)__" =~ "rh" ]]; then path="rh";elif [[ "__GETNODEATTR($$SN,os)__" =~ "sles" ]];then path="sles";fi; ver="__GETNODEATTR($$SN,os)__"; tmp=${ver%.*};ver=`echo "$tmp"|sed 's:[a-zA-Z]::g'`;cd /install/post/otherpkgs/__GETNODEATTR($$SN,os)__/__GETNODEATTR($$SN,arch)__/xcat/xcat-dep/$path$ver/__GETNODEATTR($$SN,arch)__ && createrepo .;
+check:rc==0
+
+cmd:chdef -t osimage __GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-service otherpkgdir=/install/post/otherpkgs/__GETNODEATTR($$SN,os)__/__GETNODEATTR($$SN,arch)__
+check:rc==0
+
+cmd:if [[ "__GETNODEATTR($$SN,os)__" =~ "rh" ]]; then path="rh";elif [[ "__GETNODEATTR($$SN,os)__" =~ "sles" ]];then path="sles";fi; ver="__GETNODEATTR($$SN,os)__"; chdef -t osimage __GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-service otherpkglist=/opt/xcat/share/xcat/install/$path/service.${ver%.*}.__GETNODEATTR($$SN,arch)__.otherpkgs.pkglist;
+check:rc==0
+
+cmd:rinstall $$SN,$$CN osimage=__GETNODEATTR($$SN,os)__-__GETNODEATTR($$SN,arch)__-install-service
+check:rc==0
+check:output=~Provision node\(s\)\: $$SN $$CN
+
+cmd:if [[ -f /var/lib/dhcp/db/dhcpd.leases ]]; then cat /var/lib/dhcp/db/dhcpd.leases; elif [[ -f /var/lib/dhcpd/dhcpd.leases ]];then cat /var/lib/dhcpd/dhcpd.leases;elif [[ -f /var/lib/dhcp/dhcpd.leases ]];then cat /var/lib/dhcp/dhcpd.leases; fi
+cmd:/opt/xcat/share/xcat/tools/autotest/testcase/installation/customize_sleep_for_sn __GETNODEATTR($$SN,os)__ __GETNODEATTR($$SN,arch)__
+
+#Check status on SN after SN is installed
+cmd:ping $$SN -c 3
+check:rc==0
+check:output=~64 bytes from $$SN
+cmd:lsdef -l $$SN | grep status
+check:rc==0
+check:output=~booted
+cmd:xdsh $$SN date
+check:rc==0
+check:output=~\d\d:\d\d:\d\d
+#after bug 2586 is fixed, following 2 lines should be removed.
+cmd:if [[ "__GETNODEATTR($$SN,os)__" =~ "sles" ]];then xdsh $$SN service xcatd restart; fi
+check:rc==0
+cmd:xdsh $$SN "ps -ef |grep xcatd"
+check:rc==0
+check:output=~xcatd:
+cmd:xdsh $$SN "lsdef"
+check:rc==0
+check:output=~$$SN: $$SN
+cmd:xdsh $$SN "tabdump site"
+check:rc==0
+check:output=~tftpdir
+cmd:rsync -auv --exclude 'autoinst' /install $$SN:/
+check:rc==0
+
+#Check status on CN after CN is installed since CN is taken as another SN.
+cmd:ping $$CN -c 3
+check:rc==0
+check:output=~64 bytes from $$CN
+cmd:lsdef -l $$CN | grep status
+check:rc==0
+check:output=~booted
+cmd:xdsh $$CN date
+check:rc==0
+check:output=~\d\d:\d\d:\d\d
+#after bug 2586 is fixed, following 2 lines should be removed.
+cmd:if [[ "__GETNODEATTR($$CN,os)__" =~ "sles" ]] ; then xdsh $$CN service xcatd restart ; fi
+check:rc==0
+cmd:xdsh $$CN "ps -ef |grep xcatd"
+check:rc==0
+check:output=~xcatd:
+cmd:xdsh $$CN "lsdef"
+check:rc==0
+check:output=~$$CN: $$CN
+cmd:xdsh $$CN "tabdump site"
+check:rc==0
+check:output=~tftpdir
+cmd:rsync -auv --exclude 'autoinst' /install $$CN:/
+check:rc==0
+end
diff --git a/xCAT-test/autotest/testcase/updatenode/filesyncing_hierarchy_case b/xCAT-test/autotest/testcase/updatenode/filesyncing_hierarchy_case
new file mode 100644
index 000000000..6b62feffb
--- /dev/null
+++ b/xCAT-test/autotest/testcase/updatenode/filesyncing_hierarchy_case
@@ -0,0 +1,77 @@
+start:updatenode_f_F_hierarchy
+description: verify the behavior of updatenode -f/-F in the hierarchy environment-- (1)the different kind of synclist entries including destination nodes (2)make sure the location of directory to hold the files/dirs to sync on SN is correct (3)check the result of updatenode -f/-F
+
+#create environment files to hold variables accross the case
+cmd: MYENVFILE="/tmp/updatenode_f_F_hierarchy.envs"; rm -rf $MYENVFILE; echo "MYENVFILE=\"$MYENVFILE\"">> $MYENVFILE; chmod +x $MYENVFILE
+#obtain and save the site.SNsyncfiledir
+cmd: source /tmp/updatenode_f_F_hierarchy.envs;echo $(lsdef -t site -o clustersite -i SNsyncfiledir|grep SNsyncfiledir||echo "SNsyncfiledir=/var/xcat/syncfiles")>>$MYENVFILE
+#create and save dir to hold intermidate files/dirs related to the case
+cmd: source /tmp/updatenode_f_F_hierarchy.envs;SYNCDIR='/tmp/updatenode_f_F_hierarchy.dir/';echo "SYNCDIR=\"$SYNCDIR\"">>$MYENVFILE; rm -rf $SYNCDIR; mkdir -p $SYNCDIR
+#create and save synclist path
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; SYNCLIST="$SYNCDIR/synclist";echo "SYNCLIST=\"$SYNCLIST\"">>$MYENVFILE
+
+#obtain the cn's osimage name, backup the osimage definition, save the osimage name and the path to the osimage stanza
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; CNOSIMGSTANZA="$SYNCDIR/osimage.stanza";CNOSIMG=__GETNODEATTR($$CN,provmethod)__;lsdef -t osimage -o $CNOSIMG -z>$CNOSIMGSTANZA; echo "CNOSIMGSTANZA=\"$CNOSIMGSTANZA\"" >> $MYENVFILE; echo "CNOSIMG=\"$CNOSIMG\"">>$MYENVFILE
+#specify the synclists attribute for cn's osimage
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; chdef -t osimage -o $CNOSIMG synclists=$SYNCLIST
+check:rc==0
+
+#create the dirs+files to sync, append the sync list entries
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; echo "$SYNCDIR/testdir1/ -> ($$CN) /tmp/" >>$SYNCLIST ; mkdir -p "$SYNCDIR/testdir1/"; echo "hellotest" > "$SYNCDIR/testdir1/testfile1"
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; echo "$SYNCDIR/testdir2/* -> ($$CN) /tmp/" >>$SYNCLIST; mkdir -p "$SYNCDIR/testdir2/"; echo "hellotest" > "$SYNCDIR/testdir2/testfile2"
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; echo "$SYNCDIR/testdir3 -> ($$CN) /tmp/" >>$SYNCLIST; mkdir -p "$SYNCDIR/testdir3/"; echo "hellotest" > "$SYNCDIR/testdir3/testfile3"
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; echo "$SYNCDIR/testdir4/testfile4 -> ($$CN) /tmp/" >>$SYNCLIST; mkdir -p "$SYNCDIR/testdir4/"; echo "hellotest" > "$SYNCDIR/testdir4/testfile4"
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; echo "$SYNCDIR/testdir5/testfile5 -> /tmp/" >>$SYNCLIST; mkdir -p "$SYNCDIR/testdir5/"; echo "hellotest" > "$SYNCDIR/testdir5/testfile5"
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; echo "$SYNCDIR/testdir6/testfile6 -> ($$SN) /tmp/" >>$SYNCLIST; mkdir -p "$SYNCDIR/testdir6/"; echo "hellotest" > "$SYNCDIR/testdir6/testfile6"
+
+#clear up the SNsyncfiledir directory on sn
+cmd: source /tmp/updatenode_f_F_hierarchy.envs;ssh $$SN "rm -rf $SNsyncfiledir/*"
+
+#run updatenode -f
+cmd: updatenode $$CN -f
+check:rc==0
+
+#verify the behavior of updatenode -f
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$SN "cat $SNsyncfiledir/$SYNCDIR/testdir1/testfile1|grep 'hellotest'"
+check:rc==0
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$SN "cat $SNsyncfiledir/$SYNCDIR/testdir2/testfile2|grep 'hellotest'"
+check:rc==0
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$SN "cat $SNsyncfiledir/$SYNCDIR/testdir3/testfile3|grep 'hellotest'"
+check:rc==0
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$SN "cat $SNsyncfiledir/$SYNCDIR/testdir4/testfile4|grep 'hellotest'"
+check:rc==0
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$SN "cat $SNsyncfiledir/$SYNCDIR/testdir5/testfile5|grep 'hellotest'"
+check:rc==0
+
+#clean up existing files/dirs with the same name as the ones to sync
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$CN "rm -rf /tmp/test{dir,file}*"
+
+#run updatenode -F
+cmd: updatenode $$CN -F
+check:rc==0
+
+#verify the behavior of updatenode -F
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$CN "cat /tmp/testfile1|grep 'hellotest'"
+check:rc==0
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$CN "cat /tmp/testfile2|grep 'hellotest'"
+check:rc==0
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$CN "cat /tmp/testdir3/testfile3|grep 'hellotest'"
+check:rc==0
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$CN "cat /tmp/testfile4|grep 'hellotest'"
+check:rc==0
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$CN "cat /tmp/testfile5|grep 'hellotest'"
+check:rc==0
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$CN "cat /tmp/testfile6|grep 'hellotest'"
+check:rc!=0
+
+# restore the cn osimage definition
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; cat $CNOSIMGSTANZA|chdef -z
+check:rc==0
+
+#clean up the intermidate dirs/files generated in this case
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$SN "rm -rf $SNsyncfiledir/*"
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; ssh $$CN "rm -rf /tmp/test{dir,file}*"
+cmd: source /tmp/updatenode_f_F_hierarchy.envs; rm -rf $SYNCDIR
+cmd: rm -rf /tmp/updatenode_f_F_hierarchy.envs
+
+end
diff --git a/xCAT-test/bin/xcatperftest b/xCAT-test/bin/xcatperftest
index 1c4afe364..547291fd8 100755
--- a/xCAT-test/bin/xcatperftest
+++ b/xCAT-test/bin/xcatperftest
@@ -15,7 +15,7 @@
# $prog [command-list-file]
#
###################################################################
-
+#set -x
if [ -z $LC_ALL ]; then
export LC_ALL=C
fi
@@ -38,12 +38,16 @@ if [ -z "$1" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
echo " "
echo "Generate a bunch of fake nodes and Run the performance testing for the commands listed in file:"
echo " [PERF_DRYRUN=y] [PERF_NOCREATE=y] $0 [command-list-file]"
+ echo " "
+ echo "Generate the script for creating the fake simulators for the given node range:"
+ echo " $0 create [ docker | openbmc ]"
exit
fi
-PERF_RUN_WITH_ENV=0
if [ "$1" = "run" ]; then
PERF_RUN_WITH_ENV=1
+elif [ "$1" = "create" ]; then
+ PERF_RUN_WITH_SIM=1
else
isNumber $1
if [ ! $? -eq 0 ]; then
@@ -70,7 +74,7 @@ preChecking()
echo $val | sed s/,$//
}
-if [ "$PERF_RUN_WITH_ENV" = "0" ] && [ -z $PERF_DRYRUN ]; then
+if [ -z $PERF_RUN_WITH_ENV ] && [ -z $PERF_RUN_WITH_SIM ] && [ -z $PERF_DRYRUN ]; then
pass=$(preChecking)
if [ ! -z "$pass" ]; then
echo "Error: Missing required tools: $pass"
@@ -80,7 +84,9 @@ fi
# If the command list file is not specified, the tool will only create the stanz file for fake nodes.
# If it is specified but not exists, the tool will exit with error.
-if [ ! -z $2 ]; then
+if [ "$PERF_RUN_WITH_SIM" = "1" ]; then
+ [ -z $2 ] && echo "ERROR: Not specify the node range." && exit -1
+elif [ ! -z $2 ]; then
if [ -f $2 ]; then
RUN_CMD_LIST=$2
else
@@ -147,6 +153,11 @@ if [ -z $PERF_NODETEMPL ]; then
PERF_NODETEMPL="`arch`-template"
fi
+# Optional, The NIC used by simulator.
+if [ -z $PERF_SIM_NIC ]; then
+ PERF_SIM_NIC='eth1'
+fi
+
# Optional, The delimiter which is used for CSV.
# By default, it is comma, but it could be changed when you set environment variable `PERF_CSV_CHAR`
if [ -z $PERF_CSV_CHAR ]; then
@@ -161,9 +172,13 @@ if [ -z $PERFORMANCE_DIR ]; then
PERFORMANCE_DIR=$XCATROOT/share/xcat/tools/autotest/result
fi
PERFORMANCE_NODE_TMPL=$PERFORMANCE_DIR/perf-node.tmpl
-PERFORMANCE_REPORT=$PERFORMANCE_DIR/perfreport-$FAKE_NODE_TOTAL.log.$MYSUFFIX
PERFORMANCE_STANZ=$PERFORMANCE_DIR/perfstanz-$FAKE_NODE_TOTAL.$MYSUFFIX
+if [ -z $PERF_RPT_FILE ]; then
+ PERF_RPT_FILE=perfreport-$FAKE_NODE_TOTAL.log.$MYSUFFIX
+fi
+PERFORMANCE_REPORT=$PERFORMANCE_DIR/$PERF_RPT_FILE
+
# Get a random MAC address
genMAC()
{
@@ -178,13 +193,17 @@ genStanz()
else
echo -n .
fi
-
+ mgt='ipmi'
+ if [[ `arch` =~ 'ppc64' ]]; then
+ mgt='openbmc'
+ fi
sed -e '/Object name:/c \'"$1"':\n objtype=node' \
-e '/ip=/c \ ip='"$3"'' \
-e '/mac=/c \ mac='"$2"'' \
-e '/bmc=/c \ bmc='"$4"'' \
- -e '/bmcusername=/c \ bmcusername=fake' \
- -e '/bmcpassword=/c \ bmcpassword=fake' \
+ -e '/mgt=/c \ mgt='"$mgt"'' \
+ -e '/bmcusername=/c \ bmcusername=root' \
+ -e '/bmcpassword=/c \ bmcpassword=0penBmc' \
-e '/groups=/c \ groups=all,'"$FAKE_NODE_GROUP"'' \
-e '/postscripts=/c \ postscripts=mypostboot' \
-e '/postbootscripts=/c \ postbootscripts=mypostboot' \
@@ -203,11 +222,11 @@ fakeNode()
# Create a fake xCAT network definition
fakeNetwork()
{
- lsdef -t network -o net-$FAKE_NODE_PREFIX > /dev/null 2>&1
+ lsdef -t network -o perf-net-$FAKE_NODE_PREFIX > /dev/null 2>&1
if [ 0 != $? ]; then
- mkdef -t network net-$FAKE_NODE_PREFIX net=$FAKE_NETWORK_PRO.0.0 mask=$FAKE_NETWORK_MASK > /dev/null
+ mkdef -t network perf-net-$FAKE_NODE_PREFIX net=$FAKE_NETWORK_PRO.0.0 mask=$FAKE_NETWORK_MASK > /dev/null
else
- chdef -t network -o net-$FAKE_NODE_PREFIX net=$FAKE_NETWORK_PRO.0.0 mask=$FAKE_NETWORK_MASK > /dev/null
+ chdef -t network -o perf-net-$FAKE_NODE_PREFIX net=$FAKE_NETWORK_PRO.0.0 mask=$FAKE_NETWORK_MASK > /dev/null
fi
}
@@ -218,7 +237,9 @@ fakeInterface()
if [ -z "$2" ]; then
[ -z "$result" ] && brctl addbr $1
ifconfig $1 $FAKE_NETWORK_PRO.251.254 netmask $FAKE_NETWORK_MASK || echo "$1 is not configured successfully"
+ ifconfig $1:0 $FAKE_NETWORK_BMC.251.254 netmask $FAKE_NETWORK_MASK || echo "$1:0 is not configured successfully"
elif [ ! -z "$result" ]; then
+ ifconfig $1:0 0.0.0.0
ifconfig $1 down
brctl delbr $1 || echo "$1 is not removed successfully, you may need to clean up manually."
fi
@@ -371,6 +392,37 @@ if [ "$PERF_RUN_WITH_ENV" = "1" ]; then
exit 0
fi
+if [ "$PERF_RUN_WITH_SIM" = "1" ]; then
+ simmode="docker"
+ [ ! -z $3 ] && simmode=$3
+ echo "Generate the $simmode simulators for $2 ..."
+
+ PERFORMANCE_SCRIPT=$PERFORMANCE_DIR/perf-$simmode-create.sh
+ echo "#!/bin/bash" > $PERFORMANCE_SCRIPT
+
+ if [ "$simmode" = "docker" ]; then
+ lsdef $2 -i ip -c | \
+ awk -F '=' '{ print substr($1, 0 ,index($1,":")-1),$2}' | \
+ while read name ip; \
+ do \
+ echo "docker run -itd --rm --name $name --net perf-net --ip $ip --hostname $name -v /root/.ssh:/root/.ssh perf-alpine-ssh" >> $PERFORMANCE_SCRIPT; \
+ done
+ elif [ "$simmode" = "openbmc" ]; then
+ options="-d random -t 10"
+ bmcips=`lsdef $2 -i bmc -c | awk -F '=' '{printf "%s ", $2}'`
+ echo "if [ \"\$1\" = \"setup\" ]; then /tmp/perf/openbmc_simulator/simulator -n $PERF_SIM_NIC $options -r $bmcips; fi" >> $PERFORMANCE_SCRIPT
+ echo "if [ \"\$1\" = \"clean\" ]; then /tmp/perf/openbmc_simulator/simulator -c -n $PERF_SIM_NIC -r $bmcips; fi" >> $PERFORMANCE_SCRIPT
+ else
+ echo "Not supported simulator type: $simmode"
+ rm -f $PERFORMANCE_SCRIPT
+ exit -1
+ fi
+
+ echo
+ echo "Done. Check the performance script in $PERFORMANCE_SCRIPT"
+ exit 0
+fi
+
#Get available OS image, it will be used for nodeset if possible
osimage=$(getOSimage)
if [ -z "$osimage" ]; then
@@ -411,6 +463,8 @@ if [ -z $PERF_NOCREATE ]; then
#create fake network for makedns, makedhcp etc...
fakeNetwork
execCmd "cat $PERFORMANCE_STANZ | mkdef -z -f" "$FAKE_NODE_TOTAL"
+
+ [ -z $PERF_CREATE_ONLY ] || exit 0
# fake interface is required for topology with service nodes as it will determine if then Mn/Sn are
# in the same subnet with CNs
fakeInterface $FAKE_NETWORK_INTF
diff --git a/xCAT-test/xcattest b/xCAT-test/xcattest
index 5bb76bb13..dedc49867 100755
--- a/xCAT-test/xcattest
+++ b/xCAT-test/xcattest
@@ -95,7 +95,7 @@ Options:
-f : specify the configuration file. If 'System' tag is used, only [System] section in the configuration file will be used. If 'System' is not used all other sections of the configuration file will be used, like [Table], [Object], etc.
-c : Comma separated list of command names to test.
-t : Comma separated list of test case names to test.
- -b : Comma separated list of bundle names to test. If a bundle name is specified without an absolute path, bundles under $bundledir will be searched
+ -b : Comma separated list of bundle names to test. If a bundle name is specified without an absolute path, such like /[$i]->{name}/,@{ $invalidcases{"noruncases"} })){
+ delete_item_from_array($case_ref->[$i]->{name}, $invalidcases{"noruncases"});
+ }
} else {
$skip = 1;
push @{ $invalidcases{"invalidcasename"} }, $name;
@@ -900,6 +917,9 @@ sub load_case {
foreach my $os (@newvalidoslist) {
if ($currentos =~ /$os/i) {
$valid = 1;
+ if(grep (/$case_ref->[$i]->{name}/,@{ $invalidcases{"noruncases"} })){
+ delete_item_from_array($case_ref->[$i]->{name}, $invalidcases{"noruncases"});
+ }
last;
}
}
@@ -909,8 +929,10 @@ sub load_case {
$$case_name_index_map_ref{$case_ref->[$i]->{name}}=$case_name_index_map_bak{$case_ref->[$i]->{name}};
}else{
delete $$case_name_index_map_ref{$case_ref->[$i]->{name}};
+ if(! grep (/$case_ref->[$i]->{name}/,@{ $invalidcases{"noruncases"} })){
+ push @{ $invalidcases{"noruncases"} }, $case_ref->[$i]->{name};
+ }
}
- push @{ $invalidcases{"noruncases"} }, $case_ref->[$i]->{name};
}
}
$newcmdstart = 0;
@@ -929,7 +951,13 @@ sub load_case {
$case_arch="x86";
}
- my $env_arch = $config{var}{ARCH};
+ my $env_arch = "";
+ if(exists($config{var}{ARCH})){
+ $env_arch = $config{var}{ARCH};
+ }else{
+ $env_arch =`uname -m`;
+ chomp($env_arch);
+ }
if($env_arch =~ /ppc/i && $env_arch !~ /le|el/i){
$env_arch="ppc";
}elsif($env_arch =~ /ppc/i && $env_arch =~ /le|el/i){
@@ -941,14 +969,19 @@ sub load_case {
my $valid = 0;
if ($case_arch eq $env_arch) {
$valid = 1;
+ if(grep (/$case_ref->[$i]->{name}/,@{ $invalidcases{"noruncases"} })){
+ delete_item_from_array($case_ref->[$i]->{name}, $invalidcases{"noruncases"});
+ }
}
unless ($valid) {
if(exists($case_name_index_map_bak{$case_ref->[$i]->{name}})){
$$case_name_index_map_ref{$case_ref->[$i]->{name}}=$case_name_index_map_bak{$case_ref->[$i]->{name}};
}else{
delete $$case_name_index_map_ref{$case_ref->[$i]->{name}};
+ if(! grep (/$case_ref->[$i]->{name}/,@{ $invalidcases{"noruncases"} })){
+ push @{ $invalidcases{"noruncases"} }, $case_ref->[$i]->{name};
+ }
}
- push @{ $invalidcases{"noruncases"} }, $case_ref->[$i]->{name};
}
}
$newcmdstart = 0;
@@ -958,16 +991,21 @@ sub load_case {
if ($run_case_flag) {
#To judge whether need to skip the current case
my $valid = 0;
- if ($case_ref->[$i]->{hcp} =~ /$config{var}{HCP}/i) {
+ if (exists ($config{var}{HCP}) && ($case_ref->[$i]->{hcp} =~ /$config{var}{HCP}/i)) {
$valid = 1;
+ if(grep (/$case_ref->[$i]->{name}/,@{ $invalidcases{"noruncases"} })){
+ delete_item_from_array($case_ref->[$i]->{name}, $invalidcases{"noruncases"});
+ }
}
unless ($valid) {
if(exists($case_name_index_map_bak{$case_ref->[$i]->{name}})){
$$case_name_index_map_ref{$case_ref->[$i]->{name}}=$case_name_index_map_bak{$case_ref->[$i]->{name}};
}else{
delete $$case_name_index_map_ref{$case_ref->[$i]->{name}};
+ if(! grep (/$case_ref->[$i]->{name}/,@{ $invalidcases{"noruncases"} })){
+ push @{ $invalidcases{"noruncases"} }, $case_ref->[$i]->{name};
+ }
}
- push @{ $invalidcases{"noruncases"} }, $case_ref->[$i]->{name};
}
}
$newcmdstart = 0;
@@ -995,11 +1033,8 @@ sub load_case {
$m = 0;
if ($run_case_flag) {
$case_ref->[$i]->{cmd}->[$j][$m] = getvar($1, \%config);
- if ($case_ref->[$i]->{cmd}->[$j][$m] =~ /miss attribute/) {
- my $errlog = "$case_ref->[$i]->{name} $case_ref->[$i]->{cmd}->[$j][$m]";
- if (!(grep /$errlog/, @{ $invalidcases{"missattr"} })) {
- push @{ $invalidcases{"missattr"} }, $errlog;
- }
+ if ($case_ref->[$i]->{cmd}->[$j][$m] =~ /miss attribute (.+)/) {
+ update_miss_attr($case_ref->[$i]->{cmd}->[$j][$m], $case_ref->[$i]->{name}, \@{$invalidcases{"missattr"}});
}
} else {
$case_ref->[$i]->{cmd}->[$j][$m] = $1;
@@ -1010,10 +1045,7 @@ sub load_case {
if ($run_case_flag) {
$case_ref->[$i]->{check}->[$j][$z] = getvar($1, \%config);
if ($case_ref->[$i]->{check}->[$j][$z] =~ /miss attribute/) {
- my $errlog = "$case_ref->[$i]->{name} $case_ref->[$i]->{check}->[$j][$z]";
- if (!(grep /$errlog/, @{ $invalidcases{"missattr"} })) {
- push @{ $invalidcases{"missattr"} }, $errlog;
- }
+ update_miss_attr($case_ref->[$i]->{check}->[$j][$z], $case_ref->[$i]->{name}, \@{$invalidcases{"missattr"}});
}
} else {
$case_ref->[$i]->{check}->[$j][$z] = $1;
@@ -1025,10 +1057,7 @@ sub load_case {
if ($run_case_flag) {
$case_ref->[$i]->{cmdcheck}->[$j][$z] = getvar($1, \%config);
if ($case_ref->[$i]->{cmdcheck}->[$j][$z] =~ /miss attribute/) {
- my $errlog = "$case_ref->[$i]->{name} $case_ref->[$i]->{cmdcheck}->[$j][$z]";
- if (!(grep /$errlog/, @{ $invalidcases{"missattr"} })) {
- push @{ $invalidcases{"missattr"} }, $errlog;
- }
+ update_miss_attr($case_ref->[$i]->{cmdcheck}->[$j][$z],$case_ref->[$i]->{name}, \@{$invalidcases{"missattr"}});
}
} else {
$case_ref->[$i]->{cmdcheck}->[$j][$z] = $1;
@@ -1054,37 +1083,55 @@ sub load_case {
#log_this($running_log_fd, "Case name invalid:", @{ $invalidcases{"invalidcasename"} });
$$error_ref = "Case name invalid: " . join(",", @{ $invalidcases{"invalidcasename"} });
push @wrong_cases, @{ $invalidcases{"invalidcasename"} };
- $caseerror = 1;
+ $caseerror = 2;
}
if ($run_case_flag) {
if ($invalidcases{"missattr"}) {
-
- #log_this($running_log_fd, "Miss attribute:", @{$invalidcases{"missattr"}});
- $$error_ref = "Miss attribute: " . join(",", @{ $invalidcases{"missattr"} });
+ log_this($running_log_fd, "Miss attribute:", @{$invalidcases{"missattr"}});
+ #$$error_ref = "Miss attribute: " . join(",", @{ $invalidcases{"missattr"} });
foreach my $line (@{ $invalidcases{"missattr"} }) {
my @name = split(" ", $line);
if (!(grep /$name[0]/, @wrong_cases)) {
push @wrong_cases, $name[0];
}
}
- $caseerror = 1;
+ $caseerror = 2;
}
- if ($invalidcases{"noruncases"}) {
- log_this($running_log_fd, "Not to run:", @{ $invalidcases{"noruncases"} });
+ if ($invalidcases{"noruncases"} && @{$invalidcases{"noruncases"}}) {
+ log_this($running_log_fd, "Unsuitable current environment:", @{ $invalidcases{"noruncases"} });
push @wrong_cases, @{ $invalidcases{"noruncases"} };
+ $caseerror = 2;
}
- unless ($caseerror) {
+ # To filter unexisted cases
+ my @unexisted_cases;
+ foreach my $case (@{$cases_to_be_run_ref}){
+ if(!(grep { /^$case$/ } @wrong_cases) && !defined ($$case_name_index_map_ref{$case})){
+ push @unexisted_cases, $case;
+ }
+ }
+ if(@unexisted_cases){
+ log_this($running_log_fd, "Not existed:", @unexisted_cases);
+ push @wrong_cases, @unexisted_cases;
+ $caseerror = 2;
+ }
+
+ if($caseerror) {
my @new_cases_to_be_run = ();
foreach my $c (@{$cases_to_be_run_ref}) {
if (!(grep { /^$c$/ } @wrong_cases)) {
push @new_cases_to_be_run, $c;
}
}
- log_this($running_log_fd, "To run:", @new_cases_to_be_run);
- #@{$cases_to_be_run_ref} = @new_cases_to_be_run;
+ @{$cases_to_be_run_ref} = @new_cases_to_be_run;
+ }
+
+ if (@{$cases_to_be_run_ref}){
+ log_this($running_log_fd, "To run:", @{$cases_to_be_run_ref});
+ }else{
+ log_this($running_log_fd, "To run:", "There is no valid case to run");
}
}
return $caseerror;
@@ -1384,9 +1431,27 @@ sub setup_env_by_configure_file {
}
}
+ return 0;
+}
+
+#--------------------------------------------------------
+# Fuction name: detect_current_env
+# Description: detect some important attribute in current environment, such as os, arch, hcp...
+# Atrributes:
+# $config_ref (input attribute)
+# The reference of global hash %config.
+# The structure of %config please refer to the comment of function load_config_file
+# $error_ref (output attribe)
+# The reference of scalar to save the error message generated during running current function
+# Retrun code: 0 Success 1 Failed
+#--------------------------------------------------------
+sub detect_current_env{
+ my $config_ref = shift;
+ my $error_ref = shift;
+
if (!exists $$config_ref{var}{OS}) {
my @output = runcmd("uname");
- $$config_ref{var}{OS} = $output[0];
+ $$config_ref{var}{OS} = lc($output[0]);
log_this($running_log_fd, "Detecting: OS = $$config_ref{var}{OS}");
} else {
$$config_ref{var}{OS} = lc($$config_ref{var}{OS});
@@ -1398,11 +1463,11 @@ sub setup_env_by_configure_file {
log_this($running_log_fd, "Warning: No compute node defined, can't get ARCH of compute node");
} else {
$$config_ref{var}{ARCH} = getnodeattr($$config_ref{var}{CN}, "arch");
- if ($$config_ref{var}{ARCH} =~ /le|el/) {
+ if ($$config_ref{var}{ARCH} =~ /le|el/i) {
$$config_ref{var}{ARCH} = 'ppc64le';
- } elsif ($$config_ref{var}{ARCH} =~ /ppc/) {
+ } elsif ($$config_ref{var}{ARCH} =~ /ppc/i) {
$$config_ref{var}{ARCH} = 'ppc';
- } elsif ($$config_ref{var}{ARCH} =~ /86/) {
+ } elsif ($$config_ref{var}{ARCH} =~ /86/i) {
$$config_ref{var}{ARCH} = 'x86';
}
log_this($running_log_fd, "Detecting: ARCH = $$config_ref{var}{ARCH}");
@@ -1423,6 +1488,9 @@ sub setup_env_by_configure_file {
return 0;
}
+
+
+
#--------------------------------------------------------
# Fuction name: runcmd
# Description: run a command after 'cmd' label in one case
@@ -1734,4 +1802,37 @@ sub print_table {
return 0;
}
+sub update_miss_attr {
+ my $org_str = shift;
+ my $case_name = shift;
+ my $miss_attr_arr_ref = shift;
+ my $insert_flag = 0;
+ my $index = 0;
+ foreach my $str (@{$miss_attr_arr_ref}){
+ my @words = split(" ", $str);
+ my @org_words = split(" ", $org_str);
+ if($case_name eq "$words[0]"){
+ if(!(grep { /^$org_words[2]$/} @words)){
+ $miss_attr_arr_ref->[$index] .= " $org_words[2]";
+ }
+ $insert_flag = 1;
+ last;
+ }
+ ++$index;
+ }
+
+ unless($insert_flag){
+ push @{$miss_attr_arr_ref}, "$case_name $org_str";
+ }
+}
+sub delete_item_from_array{
+ my $item = shift;
+ my $array_ref = shift;
+
+ my @tmp_arr=();
+ foreach (@$array_ref){
+ push @tmp_arr, $_ unless($_ eq $item);
+ }
+ @$array_ref = @tmp_arr;
+}
diff --git a/xCAT/debian/postinst b/xCAT/debian/postinst
index 09aeaed1e..3fedfd75e 100644
--- a/xCAT/debian/postinst
+++ b/xCAT/debian/postinst
@@ -35,7 +35,9 @@ case "$1" in
if [ -r "/tmp/xcat/mainservice.pid" ]; then
mv /tmp/xcat/mainservice.pid /var/run/xcat/mainservice.pid
fi
- xcatconfig -u
+ mkdir -p /var/log/xcat
+ date >> /var/log/xcat/upgrade.log
+ xcatconfig -u -V >> /var/log/xcat/upgrade.log
rm /tmp/xCAT_upgrade.tmp
else
xcatconfig -i -d -s
diff --git a/xCAT/postscripts/configinterface b/xCAT/postscripts/configinterface
index 9c248b2e4..4c99ec2aa 100755
--- a/xCAT/postscripts/configinterface
+++ b/xCAT/postscripts/configinterface
@@ -61,8 +61,9 @@ if [ ! -f $xcat_intf ]; then
fi
# license needs to set before start switchd
-if [ ! -e /etc/cumulus/.license* ]; then
- echo "ERROR: cumulus license file does not exist";
+/usr/cumulus/bin/cl-license 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ERROR: cumulus license does not exist";
exit 1;
fi
diff --git a/xCAT/postscripts/confignetwork b/xCAT/postscripts/confignetwork
index ca2273f37..4c61ceeed 100755
--- a/xCAT/postscripts/confignetwork
+++ b/xCAT/postscripts/confignetwork
@@ -297,6 +297,7 @@ function sort_nics_device_order {
all_nics_list=$*
eth_slot=""
+ ib_slot=""
bond_slot=""
vlan_slot=""
ib_slots=""
@@ -365,6 +366,7 @@ function sort_nics_device_order {
#find nicdevice type as base_nic_type
base_nic_dev=`echo "$nics_list" |sed -n "${num}p"|awk '{print $2}'`
if echo "$base_nic_dev"|grep "@" >/dev/null; then
+ temp_base_nic_type_one=''
for i in `echo "$base_nic_dev" |sed 's/@/ /g'`
do
temp_base_nic_type=`find_nic_type "$i" | $utolcmd`
@@ -394,6 +396,16 @@ function sort_nics_device_order {
eth_slot=$eth_slot" "$num
fi
+ #valid nic_dev and base_nic_dev pair as bond-infiniband
+ elif [ x"$base_nic_type" = "xinfiniband" ]&& \
+ [ x"$nic_dev_type" = "xbond" ]; then
+
+ if [ x"$ib_slot" = x ]; then
+ ib_slot=$num
+ else
+ ib_slot=$ib_slot" "$num
+ fi
+
#valid nic_dev and base_nic_dev pair as vlan-bond or bridge-bond
elif [ x"$base_nic_type" = "xbond" ]&& \
[ x"$nic_dev_type" = "xvlan" -o x"$nic_dev_type" = "xbridge" -o x"$nic_dev_type" = "xbridge_ovs" ]; then
@@ -422,7 +434,7 @@ function sort_nics_device_order {
log_error "Only support configuration of Bond/VLAN/Bridge on Red Hat."
fi
fi
- new_order=$eth_slot" "$bond_slot" "$vlan_slot
+ new_order=$eth_slot" "$ib_slot" "$bond_slot" "$vlan_slot
new_order_list=""
if [ -n "$new_order" ]; then
@@ -557,7 +569,7 @@ function configure_nicdevice {
#configure bond
elif [ x"$nic_dev_type" = "xbond" ]; then
- create_bond_interface ifname=$nic_dev slave_ports=$base_nic_for_bond
+ create_bond_interface ifname=$nic_dev slave_ports=$base_nic_for_bond slave_type=$base_nic_type
elif [ x"$nic_dev_type" = "xinfiniband" ]; then
log_info "Call configib for IB nics: $nic_dev, ports: $num_iba_ports"
log_info "NIC_IBNICS=$nic_dev NIC_IBAPORTS=$num_iba_ports configib"
diff --git a/xCAT/postscripts/nicutils.sh b/xCAT/postscripts/nicutils.sh
index cc443852a..766694e64 100755
--- a/xCAT/postscripts/nicutils.sh
+++ b/xCAT/postscripts/nicutils.sh
@@ -1263,11 +1263,7 @@ function create_bond_interface {
local xcatnet=""
local _ipaddr=""
local _netmask=""
- # note:
- # - "miimon" requires drivers for each slave nic support MII tool.
- # $ ethtool | grep "Link detected:"
- # - "802.3ad" mode requires a switch that is 802.3ad compliant.
- local _bonding_opts="mode=802.3ad miimon=100"
+ local _bonding_opts=""
local _mtu=""
local slave_ports=""
# parser input arguments
@@ -1280,7 +1276,8 @@ function create_bond_interface {
[ "$key" = "_netmask" ] || \
[ "$key" = "_bonding_opts" ] || \
[ "$key" = "_mtu" ] || \
- [ "$key" = "slave_ports" ]; then
+ [ "$key" = "slave_ports" ] || \
+ [ "$key" = "slave_type" ]; then
eval "$1"
fi
shift
@@ -1290,6 +1287,17 @@ function create_bond_interface {
log_error "No valid slave_ports defined. Abort!"
return 1
fi
+ if [ -z "$slave_type" ] || [ x"$slave_type" = "xethernet" ]; then
+ slave_type="Ethernet"
+ # note:
+ # - "miimon" requires drivers for each slave nic support MII tool.
+ # $ ethtool | grep "Link detected:"
+ # - "802.3ad" mode requires a switch that is 802.3ad compliant.
+ _bonding_opts="mode=802.3ad miimon=100"
+ elif [ "$slave_type" = "infiniband" ]; then
+ slave_type="Infiniband"
+ _bonding_opts="mode=1 miimon=100 fail_over_mac=1"
+ fi
# let's query "nicnetworks" table about its target "xcatnet"
if [ -n "$ifname" -a -z "$xcatnet" -a -z "$_ipaddr" ]; then
xcatnet=`query_nicnetworks_net $ifname`
@@ -1328,7 +1336,7 @@ function create_bond_interface {
# create required bond device
((i=0))
- while ! grep -sq "^$ifname$" /sys/class/net/bonding_masters;
+ while ! grep -sq "\b$ifname\b" /sys/class/net/bonding_masters;
do
[ $i -eq 0 ] && echo "+$ifname" >/sys/class/net/bonding_masters
$sleep 0.5
@@ -1414,7 +1422,7 @@ function create_bond_interface {
fi
cfg="${cfg}${cfg:+,}USERCTL=no"
- cfg="${cfg}${cfg:+,}TYPE=Ethernet"
+ cfg="${cfg}${cfg:+,}TYPE=$slave_type"
cfg="${cfg}${cfg:+,}SLAVE=yes"
cfg="${cfg}${cfg:+,}MASTER=$ifname"
cfg="${cfg}${cfg:+,}BOOTPROTO=none"
diff --git a/xCAT/postscripts/otherpkgs b/xCAT/postscripts/otherpkgs
index aa2a21684..eb17aae10 100755
--- a/xCAT/postscripts/otherpkgs
+++ b/xCAT/postscripts/otherpkgs
@@ -775,6 +775,39 @@ EOF`
fi
done
+ #add repo for url repos in otherpkgdir
+ if [ -n "OTHERPKGDIR_INTERNET" ];then
+ OIFS=$IFS
+ IFS=','
+ OTHERPKGDIRLIST_INTERNET=($OTHERPKGDIR_INTERNET)
+
+ index=$(array_get_size repo_path)
+ for url in ${OTHERPKGDIRLIST_INTERNET[@]}
+ do
+ if [ $hasyum -eq 1 ] || [ $haszypper -eq 1 ] ; then
+ REPOFILE="$repo_base/xCAT-otherpkgs$index.repo"
+ echo "[xcat-otherpkgs$index]" > $REPOFILE
+ echo "name=xcat-otherpkgs$index" >> $REPOFILE
+ echo "baseurl=$url" >> $REPOFILE
+ echo "enabled=1" >> $REPOFILE
+ echo "gpgcheck=0" >> $REPOFILE
+ index=$[index+1]
+ fi
+ done
+
+ IFS=$OIFS
+ if [ $hasyum -eq 1 ]; then
+ yum clean all
+ fi
+ if [ $haszypper -eq 1 ]; then
+ result=`zypper --non-interactive refresh 2>&1`
+ if [ $VERBOSE ]; then
+ echo "otherpkgs: zypper --non-interactive refresh"
+ echo " $result"
+ fi
+ fi
+ fi
+
#now update all the existing rpms
if [ $hasyum -eq 1 ]; then
if [ $VERBOSE ]; then
diff --git a/xCAT/postscripts/setroute b/xCAT/postscripts/setroute
index 09d904263..c30ec98d7 100755
--- a/xCAT/postscripts/setroute
+++ b/xCAT/postscripts/setroute
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
# IBM(c) 2011 EPL license http://www.eclipse.org/legal/epl-v10.html
#-------------------------------------------------------------------------------
@@ -14,10 +14,12 @@
#-------------------------------------------------------------------------------
if [ -z "$NODEROUTENAMES" ]; then
+ echo "No static routes need be configured on this node."
exit 0
fi
OP="replace"
+exit_code=0
if [ -n "$1" ] && [ "$1" = "add" ]; then
OP="add"
@@ -26,26 +28,38 @@ fi
for rn in `echo "$NODEROUTENAMES" | tr "," "\n"`
do
eval route_string=\$ROUTE_$rn
- net=`echo $route_string |cut -d',' -f1`
- mask=`echo $route_string |cut -d',' -f2`
- gw=`echo $route_string |cut -d',' -f3`
- ifname=`echo $route_string |cut -d',' -f4`
+ if [ -n "$route_string" ]; then
+ net=`echo $route_string |cut -d',' -f1`
+ mask=`echo $route_string |cut -d',' -f2`
+ gw=`echo $route_string |cut -d',' -f3`
+ ifname=`echo $route_string |cut -d',' -f4`
+ if [ -z "$gw" ]; then
+ echo "Error: Failed to configure route $rn as gateway is not configured."
+ exit_code=1
+ continue
+ fi
+ # remove the suffix /64 from ipv6 net
+ if echo $net | grep "/" 2>&1 1>/dev/null
+ then
+ net=`echo $net | awk -F'/' '{print $1}'`
+ fi
- # remove the suffix /64 from ipv6 net
- if echo $net | grep "/" 2>&1 1>/dev/null
- then
- net=`echo $net | awk -F'/' '{print $1}'`
+ # remove the prefix "/" from ipv6 mask
+ if echo $mask | grep "/" 2>&1 1>/dev/null
+ then
+ mask=`echo $mask | awk -F'/' '{print $2}'`
+ fi
+
+ cmd="routeop $OP $net $mask $gw $ifname"
+ result=`$cmd 2>&1`
+ if [ $? -ne 0 ]; then
+ exit_code=1
+ fi
+ echo $result
+ else
+ echo "Error: $rn is configured incomplete from xCAT routes table."
+ exit_code=1
fi
-
- # remove the prefix "/" from ipv6 mask
- if echo $mask | grep "/" 2>&1 1>/dev/null
- then
- mask=`echo $mask | awk -F'/' '{print $2}'`
- fi
-
- cmd="routeop $OP $net $mask $gw $ifname"
- result=`$cmd 2>&1`
- echo $result
done
-exit 0
+exit $exit_code
diff --git a/xCAT/postscripts/setupntp b/xCAT/postscripts/setupntp
index ea82028ae..90b0e223e 100755
--- a/xCAT/postscripts/setupntp
+++ b/xCAT/postscripts/setupntp
@@ -20,7 +20,7 @@ fi
#for service node, the makentp -a command will call this postscript
#so do not diable service node.
-
+exit_code=0;
master=$MASTER
setup=0
conf_file="/etc/ntp.conf"
@@ -103,10 +103,11 @@ if [ $OS_TYPE = Linux ]; then
echo "interface listen eth0" >>$conf_file
fi
- # ntpd will be hung if ntp service is not reachable
+ # will not exit here, let all the ntp configuration finish
+ # ntpd will timeout if ntp service is not reachable
if ! ping $master -c 1 > /dev/null 2>&1 ; then
echo "Error: ntpserver $master is not reachable, will not setup NTP"
- exit 1
+ exit_code=1
fi
#ntpd/ntpdate/sntp conflict with ntpd, stop the service first
@@ -115,10 +116,14 @@ if [ $OS_TYPE = Linux ]; then
stopservice ntpserver
fi
- logger -t xcat "setting current time"
- if ! ntpd -gq > /dev/null 2>&1 ; then
+ msg='syncing the clock ...'
+ logger -t xcat $msg
+ echo $msg
+ if ! timeout 120 ntpd -gq > /dev/null 2>&1 ; then
if ! ntpdate -t5 $master > /dev/null 2>&1; then
- logger -t xcat "WARNING: NTP Sync Failed!!"
+ msg='WARNING: NTP Sync Failed before timeout. ntp server will try to sync...'
+ logger -t xcat $msg
+ echo $msg
fi
fi
@@ -197,4 +202,4 @@ restrict 127.0.0.1" >>$conf_file
fi
/usr/sbin/chrctcp -S -a xntpd
fi
-exit $?
+exit $exit_code
diff --git a/xCAT/postscripts/xcatdsklspost b/xCAT/postscripts/xcatdsklspost
index 107c05f9f..d21f6a378 100755
--- a/xCAT/postscripts/xcatdsklspost
+++ b/xCAT/postscripts/xcatdsklspost
@@ -24,6 +24,7 @@
if [ -f /xcatpost/mypostscript.post ]; then
XCATDEBUGMODE=`grep 'XCATDEBUGMODE=' /xcatpost/mypostscript.post | cut -d= -f2 | tr -d \'\" | tr A-Z a-z`
MASTER_IP=`grep '^MASTER_IP=' /xcatpost/mypostscript.post |cut -d= -f2|sed s/\'//g`
+ NODE=`grep '^NODE=' /xcatpost/mypostscript.post |cut -d= -f2|sed s/\'//g`
else
for param in `cat /proc/cmdline`; do
key=`echo $param|awk -F= '{print $1}'`
@@ -381,6 +382,9 @@ else # for common mode MODE=1,2,3,5 (updatenode,moncfg,node deployment)
break
fi
done
+ if [ -z "$NODE" ]; then
+ NODE=`hostname -s`
+ fi
grep 'NODE' /opt/xcat/xcatinfo > /dev/null 2>&1
if [ $? -eq 0 ]; then
sed -i "s/NODE=.*/NODE=$NODE/" /opt/xcat/xcatinfo
@@ -679,15 +683,15 @@ if [ -n "$useflowcontrol" ]; then
else
new_fc="NO"
fi
- grep 'USEFLOWCONTROL' /opt/xcat/xcatinfo > /dev/null 2>&1
- if [ $? -eq 0 ]; then
- sed -i "s/USEFLOWCONTROL=.*/USEFLOWCONTROL=$new_fc/" /opt/xcat/xcatinfo
- else
- echo "USEFLOWCONTROL=$new_fc" >> /opt/xcat/xcatinfo
- fi
# no setting means do not use flowcontrol
else
- echo "USEFLOWCONTROL=NO" >> /opt/xcat/xcatinfo
+ new_fc="NO"
+fi
+grep 'USEFLOWCONTROL' /opt/xcat/xcatinfo > /dev/null 2>&1
+if [ $? -eq 0 ]; then
+ sed -i "s/USEFLOWCONTROL=.*/USEFLOWCONTROL=$new_fc/" /opt/xcat/xcatinfo
+else
+ echo "USEFLOWCONTROL=$new_fc" >> /opt/xcat/xcatinfo
fi
# Store the SERVICEGROUP into the xcatinfo file for node deployment, and also for updatenode -s
@@ -719,6 +723,9 @@ if [ "$MODE" = "1" ] || [ "$MODE" = "2" ]; then
mkdir -p /opt/xcat
touch /opt/xcat/xcatinfo
fi
+ if [ -z "$NODE" ]; then
+ NODE=`hostname -s`
+ fi
grep 'NODE' /opt/xcat/xcatinfo > /dev/null 2>&1
if [ $? -eq 0 ]; then
sed -i "s/NODE=.*/NODE=$NODE/" /opt/xcat/xcatinfo
diff --git a/xCAT/postscripts/xcatinstallpost b/xCAT/postscripts/xcatinstallpost
index fc4967375..e852799db 100755
--- a/xCAT/postscripts/xcatinstallpost
+++ b/xCAT/postscripts/xcatinstallpost
@@ -11,6 +11,7 @@ if [ -f /xcatpost/mypostscript.post ]; then
MASTER_IP=`grep '^MASTER_IP=' /xcatpost/mypostscript.post |cut -d= -f2|sed s/\'//g`
OSVER=`grep '^OSVER=' /xcatpost/mypostscript.post |cut -d= -f2|sed s/\'//g`
NODE=`grep '^NODE=' /xcatpost/mypostscript.post |cut -d= -f2|sed s/\'//g`
+ IMAGE=`grep '^PROVMETHOD=' /xcatpost/mypostscript.post |cut -d= -f2|sed s/\'//g`
fi
@@ -84,6 +85,14 @@ else
echo "NODE=$NODE" >> /opt/xcat/xcatinfo
fi
+#add image name to xcatinfo
+grep 'IMAGENAME' /opt/xcat/xcatinfo > /dev/null 2>&1
+if [ $? -eq 0 ]; then
+ sed -i "s/IMAGENAME=.*/IMAGENAME=$IMAGE/" /opt/xcat/xcatinfo
+else
+ echo "IMAGENAME=$IMAGE" >> /opt/xcat/xcatinfo
+fi
+
# Store the SERVICEGROUP into the xcatinfo file for statful installation
sn_group=`grep '^SERVICEGROUP' /xcatpost/mypostscript |cut -d= -f2 | tr -d \'\"`
if [ "x" != "x$sn_group" ]; then
diff --git a/xCAT/xCAT.spec b/xCAT/xCAT.spec
index 340f20006..e62ae73dd 100644
--- a/xCAT/xCAT.spec
+++ b/xCAT/xCAT.spec
@@ -249,7 +249,9 @@ if [ -r "/tmp/xcat/mainservice.pid" ]; then
mv /tmp/xcat/mainservice.pid /var/run/xcat/mainservice.pid
fi
-$RPM_INSTALL_PREFIX0/sbin/xcatconfig -u
+mkdir -p /var/log/xcat
+date >> /var/log/xcat/upgrade.log
+$RPM_INSTALL_PREFIX0/sbin/xcatconfig -u -V >> /var/log/xcat/upgrade.log
fi
exit 0
diff --git a/xCATsn/xCATsn.spec b/xCATsn/xCATsn.spec
index 8020b6b0f..07dde086c 100644
--- a/xCATsn/xCATsn.spec
+++ b/xCATsn/xCATsn.spec
@@ -190,7 +190,8 @@ if [ "$1" = "1" ]; then #Only if installing for the first time..
# setup sqlite if no other database
%ifos linux
-if [ -f "/proc/cmdline" ]; then #check to make sure this is not image install
+# prevent running it during install into chroot image
+if [ -f "/proc/cmdline" ] && [ "x$(stat -c '%i %d' /)" == "x$(stat -c '%i %d' /proc/1/root/. 2>/dev/null)" ]; then
if [ ! -s /etc/xcat/cfgloc ]; then # database is sqlite
$RPM_INSTALL_PREFIX0/sbin/xcatconfig -d
fi
@@ -216,10 +217,11 @@ fi
# start xcatd on linux
[ -e "/etc/init.d/$apachedaemon" ] && chkconfig $apachedaemon on
[ -e "/usr/lib/systemd/system/$apacheserviceunit" ] && systemctl enable $apacheserviceunit
-if [ -f "/proc/cmdline" ]; then # prevent running it during install into chroot image
- XCATROOT=$RPM_INSTALL_PREFIX0 /etc/init.d/xcatd restart
- [ -e "/etc/init.d/$apachedaemon" ] && /etc/init.d/$apachedaemon reload
- [ -e "/usr/lib/systemd/system/$apacheserviceunit" ] && systemctl reload $apacheserviceunit
+# prevent running it during install into chroot image
+if [ -f "/proc/cmdline" ] && [ "x$(stat -c '%i %d' /)" == "x$(stat -c '%i %d' /proc/1/root/. 2>/dev/null)" ]; then
+ XCATROOT=$RPM_INSTALL_PREFIX0 /etc/init.d/xcatd restart
+ [ -e "/etc/init.d/$apachedaemon" ] && /etc/init.d/$apachedaemon reload
+ [ -e "/usr/lib/systemd/system/$apacheserviceunit" ] && systemctl reload $apacheserviceunit
fi
echo "xCATsn is now installed"
%else
@@ -233,15 +235,17 @@ fi
%ifos linux
# prevent running it during install into chroot image and only run it if xCAT-genesis-scripts-x86_64
# was recently updated.
-if [ -f "/proc/cmdline" -a -f "/etc/xcat/genesis-scripts-updated" ]; then
- rm -f /etc/xcat/genesis-scripts-updated
- # On the SN do not run mknb if we are sharing /tftpboot with the MN
- SHAREDTFTP=`/opt/xcat/sbin/tabdump site | grep sharedtftp | cut -d'"' -f 4`
- if [ "$SHAREDTFTP" != "1" ]; then
+if [ -f "/proc/cmdline" ] && [ "x$(stat -c '%i %d' /)" == "x$(stat -c '%i %d' /proc/1/root/. 2>/dev/null)" ]; then
+ if [ -f "/etc/xcat/genesis-scripts-updated" ]; then
+ rm -f /etc/xcat/genesis-scripts-updated
+ # On the SN do not run mknb if we are sharing /tftpboot with the MN
+ SHAREDTFTP=`/opt/xcat/sbin/tabdump site | grep sharedtftp | cut -d'"' -f 4`
+ if [ "$SHAREDTFTP" != "1" ]; then
. /etc/profile.d/xcat.sh
echo Running '"'mknb `uname -m`'"', triggered by the installation/update of xCAT-genesis-scripts-x86_64 ...
mknb `uname -m`
fi
+ fi
fi
%endif