mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-05-18 04:07:16 +00:00
Deal with the conflict between master and 2.14 for mlnxofed_ib_install_v2_diskless.rst
This commit is contained in:
@@ -8,6 +8,8 @@ Documentation
|
||||
|
||||
Latest xCAT documentation is available at: http://xcat-docs.readthedocs.io/en/latest/
|
||||
|
||||
`document for xCAT 2.14 <http://xcat-docs.readthedocs.io/en/2.14.0/>`_
|
||||
|
||||
`document for xCAT 2.13.11 <http://xcat-docs.readthedocs.io/en/2.13.11/>`_
|
||||
|
||||
`document for xCAT 2.13.10 <http://xcat-docs.readthedocs.io/en/2.13.10/>`_
|
||||
|
||||
@@ -11,7 +11,7 @@ Currently only the ``bmcsetup`` command is officially supplied by xCAT to run to
|
||||
|
||||
runcmd=bmcsetup
|
||||
|
||||
**Note**: the command ``mknb <arch>`` is needed before reboot the node.
|
||||
.. note:: The command ``mknb <arch>`` is needed before reboot the node.
|
||||
|
||||
* runimage ::
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ The following example describes the steps for **rhels7.1** on **ppc64le**::
|
||||
cd confluent-dep-rh7-ppc64le/
|
||||
./mklocalrepo.sh
|
||||
|
||||
**Note:** If the OS/architecture you are looking for is not provided under confluent-dep, send an email to the xcat-user mailing list: xcat-user@lists.sourceforge.net
|
||||
.. note:: If the OS/architecture you are looking for is not provided under confluent-dep, send an email to the xcat-user mailing list: xcat-user@lists.sourceforge.net
|
||||
|
||||
|
||||
Install
|
||||
|
||||
@@ -5,7 +5,7 @@ Docker Registry is a stateless, highly scalable server side application that sto
|
||||
|
||||
This document describes how to set up a local private docker registry on Ubuntu 15.04 on x86_64.
|
||||
|
||||
**Note:** Ensure that docker registry is not already set up on this docker host.
|
||||
.. note:: Ensure that docker registry is not already set up on this docker host.
|
||||
|
||||
Setting Up Docker Host
|
||||
----------------------
|
||||
|
||||
@@ -6,10 +6,7 @@ Install Docker Engine
|
||||
|
||||
The Docker host to run xCAT Docker image should be a baremental or virtual server with Docker v1.10 or above installed. For the details on system requirements and Docker installation, refer to `Docker Installation Docs <https://docs.docker.com/engine/installation/>`_.
|
||||
|
||||
**Note:**
|
||||
|
||||
1. **Docker image** can only run on **Docker host** with the same architecture. Since xCAT currently only ships x86_64 and ppc64le Docker images, running xCAT in Docker requires x86_64 or ppc64le **Docker hosts**.
|
||||
|
||||
.. note:: Docker images can only run on Docker hosts with the same architecture. Since xCAT only ships x86_64 and ppc64le Docker images, running xCAT in Docker requires x86_64 or ppc64 Docker Hosts.
|
||||
|
||||
Shutdown the SELinux/Apparmor on Docker host
|
||||
--------------------------------------------
|
||||
|
||||
@@ -5,7 +5,15 @@ The Docker linux container technology is currently very popular. xCAT can help m
|
||||
|
||||
This document describes how to use xCAT for docker management, from Docker Host setup to docker container operations.
|
||||
|
||||
**Note:** The document was verified with **Docker Version 1.10, 1.11** and **Docker API version 1.22.** The Docker Host was verified on **ubuntu14.04.3 x86_64**, **ubuntu15.10 x86_64**, **ubuntu16.04 x86_64** and **ubuntu16.04 ppc64el**.
|
||||
.. note:: This document was verified with:
|
||||
* Docker Version 1.10, 1.11
|
||||
* Docker API version 1.22
|
||||
|
||||
Docker Host has been verified on the following OS/ARCH combinations:
|
||||
* Ubuntu 14.04.3,x86_64
|
||||
* Ubuntu 15.10,x86_64
|
||||
* Ubuntu 16.04,x86_64
|
||||
* Ubuntu 16.04,ppc64el
|
||||
|
||||
|
||||
Setting up Docker Host
|
||||
|
||||
@@ -30,7 +30,7 @@ Use the ``mkdef`` command to add additional networks to the xCAT database. (See
|
||||
|
||||
mkdef -t network clusternet net=11.0.0.0 mask=255.255.0.0 gateway=11.0.0.254 domain=app.cluster.com
|
||||
|
||||
Note: The ``makedns`` command (mentioned below) will only add nodes into the DNS configuration if the network for the node is defined.
|
||||
.. note:: The ``makedns`` command (mentioned below) will only add nodes into the DNS configuration if the network for the node is defined.
|
||||
|
||||
If you want to use a different hostname domain or a different set of nameservers for nodes that are on a particular network, set those attributes in the corresponding network object: ::
|
||||
|
||||
@@ -71,7 +71,7 @@ and the following entries will be added to **/etc/hosts**: ::
|
||||
|
||||
This information is used by the ``makehosts`` command to add the additional interface hostnames etc. to the **/etc/hosts** file. It is also used by xCAT adapter configuration postscripts to automatically configure the additional network interfaces on the node. See the section (refer to :ref:`specifying_additional_network_interfaces_for_cluster_nodes` ).
|
||||
|
||||
Note that it is a convention of xCAT that for Linux systems the short hostname is the primary hostname for the node, and the long hostname is an alias. To have the long hostname be the primary hostname, you can use the -l option on the makehosts command.
|
||||
.. note:: It is a convention of xCAT that for Linux systems the short hostname is the primary hostname for the node, and the long hostname is an alias. To have the long hostname be the primary hostname, you can use the -l option on the ``makehosts`` command.
|
||||
|
||||
Preparing for Using a DNS
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -207,7 +207,7 @@ For example: ::
|
||||
|
||||
The **<xcatmaster>** keyword will be interpreted as the value of the **<xcatmaster>** attribute of the node definition. The **<xcatmaster>** value for a node is the name of it's server as known by the node. This would be either the cluster-facing name of the service node or the cluster-facing name of the management node.
|
||||
|
||||
Note: for Linux, the site **nameservers** value must be set to **<xcatmaster>** before you run ``makedhcp``.
|
||||
.. note:: The site **nameservers** value must be set to **<xcatmaster>** before you run ``makedhcp``.
|
||||
|
||||
Make sure that the DNS service on the service nodes will be set up by xCAT.
|
||||
|
||||
@@ -293,7 +293,7 @@ Setting individual nic attribute values
|
||||
The nic attribute values may be set using the ``chdef`` or ``mkdef`` commands. You can specify the nic* values
|
||||
when creating an xCAT node definition with ``mkdef`` or you can update an existing node definition using ``chdef``.
|
||||
|
||||
Note: ``chdef`` does not support using the "-m" and "-p" options to modify the nic* attributes.
|
||||
.. note:: ``chdef`` does not support using the "-m" and "-p" options to modify the nic* attributes.
|
||||
|
||||
nicips example: ::
|
||||
|
||||
@@ -311,7 +311,7 @@ This value indicates that the hostname for **"eth1"** should be **"compute02-eth
|
||||
|
||||
The suffixes provided may be any string that will conform to the DNS naming rules.
|
||||
|
||||
Important Note: According to DNS rules a hostname must be a text string up to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus sign (-), and period (.). When you are specifying **"nichostnamesuffixes"** or **"nicaliases"** make sure the resulting hostnames will conform to this naming convention.
|
||||
.. warning:: According to DNS rules a hostname must be a text string up to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus sign (-), and period (.). When you are specifying **"nichostnamesuffixes"** or **"nicaliases"** make sure the resulting hostnames will conform to this naming convention.
|
||||
|
||||
nictypes example: ::
|
||||
|
||||
|
||||
@@ -9,9 +9,7 @@ Example: ::
|
||||
node01: Tesla K80, 0322415075970, GPU-b4f79b83-c282-4409-a0e8-0da3e06a13c3
|
||||
...
|
||||
|
||||
|
||||
|
||||
**Note: The following commands are provided as convenience.** *Always consult the nvidia-smi manpage for the latest supported functions.*
|
||||
.. warning:: The following commands are provided as convenience. Always consult the ``nvidia-smi`` manpage for the latest supported functions.
|
||||
|
||||
Management
|
||||
----------
|
||||
|
||||
@@ -46,7 +46,7 @@ You need to substitute the hostnames and ip address with your own values when se
|
||||
Configuring Shared Data
|
||||
=======================
|
||||
|
||||
``Note``: Shared data itself needs high availability also, the shared data should not become a single point of failure.
|
||||
.. note:: Shared data itself needs high availability also, the shared data should not become a single point of failure.
|
||||
|
||||
The configuration procedure will be quite different based on the shared data mechanism that will be used. Configuring these shared data mechanisms is beyond the scope of this documentation. After the shared data mechanism is configured, the following xCAT directory structure should be on the shared data, if this is done before xCAT is installed, you need to create the directories manually; if this is done after xCAT is installed, the directories need to be copied to the shared data. ::
|
||||
|
||||
@@ -57,7 +57,10 @@ The configuration procedure will be quite different based on the shared data mec
|
||||
/tftpboot
|
||||
|
||||
|
||||
``Note``:For MySQL, the database directory is ``/var/lib/mysql``; for PostGreSQL, the database directory is ``/var/lib/pgsql``; for DB2, the database directory is specified with the site attribute databaseloc; for sqlite, the database directory is /etc/xcat, already listed above.
|
||||
.. note:: * For MySQL, the database directory is ``/var/lib/mysql``
|
||||
* For PostGreSQL, the database directory is ``/var/lib/pgsql``
|
||||
* For DB2, the database directory is specified with the site attribute ``databaseloc``
|
||||
* For SQLite, the database directory is ``/etc/xcat``
|
||||
|
||||
Here is an example of how to make directories be shared data through NFS: ::
|
||||
|
||||
@@ -67,7 +70,6 @@ Here is an example of how to make directories be shared data through NFS: ::
|
||||
mount -o rw <nfssvr>:/dir4 /<dbdirectory>
|
||||
mount -o rw <nfssvr>:/dir5 /tftpboot
|
||||
|
||||
``Note``: if you need to setup high availability for some other applications, like the HPC software stack, between the two xCAT management nodes, the applications data should be on the shared data.
|
||||
|
||||
Setup xCAT on the Primary Management Node
|
||||
=========================================
|
||||
@@ -260,9 +262,7 @@ Besides the files mentioned above, there may be some additional customization fi
|
||||
/etc/inittab
|
||||
(and more)
|
||||
|
||||
``Note``:
|
||||
If the IBM HPC software stack is configured in your environment, execute additional steps required to copy additional data or configuration files for HAMN setup.
|
||||
The dhcpsd.cnf should be synchronized between the primary management node and standby management node only when the DHCP configuration on the two management nodes are exactly the same.
|
||||
.. note:: If the IBM HPC software stack is configured in your environment, execute additional steps required to copy additional data or configuration files for HAMN setup. The ``dhcpsd.cnf`` should be synchronized between the primary management node and standby management node only when the DHCP configuration on the two management nodes are exactly the same.
|
||||
|
||||
Cluster Maintenance Considerations
|
||||
==================================
|
||||
@@ -275,7 +275,7 @@ The standby management node should be taken into account when doing any maintena
|
||||
|
||||
#. Reboot management nodes - In the primary management node needs to be rebooted, since the daemons are set to not auto start at boot time, and the shared data will not be mounted automatically, you should mount the shared data and start the daemons manually.
|
||||
|
||||
``Note``: after software upgrade, some services that were set to not autostart on boot might be started by the software upgrade process, or even set to autostart on boot, the admin should check the services on both primary and standby management node, if any of the services are set to autostart on boot, turn it off; if any of the services are started on the backup management node, stop the service.
|
||||
.. note:: After software upgrade, some services that were set to not autostart on boot might be started by the software upgrade process, or even set to autostart on boot, the admin should check the services on both primary and standby management node, if any of the services are set to autostart on boot, turn it off; if any of the services are started on the backup management node, stop the service.
|
||||
|
||||
At this point, the HA MN Setup is complete, and customer workloads and system administration can continue on the primary management node until a failure occurs. The xcatdb and files on the standby management node will continue to be synchronized until such a failure occurs.
|
||||
|
||||
@@ -306,7 +306,7 @@ Here is an example of how to use this script: ::
|
||||
|
||||
/opt/xcat/share/xcat/hamn/deactivate-mn -i eth1:2 -v 9.114.47.97
|
||||
|
||||
**Notes**: This script will be over-written after xCAT is upgraded. If this script is customized, make sure backup it before upgrading xCAT.
|
||||
.. warning:: This script will be over-written after xCAT is upgraded. If this script is customized, make sure to back it up before upgrading xCAT.
|
||||
|
||||
On the current primary management node:
|
||||
|
||||
@@ -317,13 +317,13 @@ If the management node is still available and running the cluster, perform the f
|
||||
rmhwconn cec,frame
|
||||
rmhwconn cec,frame -T fnm
|
||||
|
||||
#. Stop the xCAT daemon.
|
||||
|
||||
``Note``: xCAT must be stopped on all Service Nodes also, and LL if using the database. ::
|
||||
#. Stop the xCAT daemon. ::
|
||||
|
||||
service xcatd stop
|
||||
service dhcpd stop
|
||||
|
||||
.. note:: xCAT must be stopped on all Service Nodes as well.
|
||||
|
||||
#. unexport the xCAT NFS directories
|
||||
|
||||
The exported xCAT NFS directories will prevent the shared data partitions from being unmounted, so the exported xCAT NFS directories should be unmounted before failover: ::
|
||||
@@ -372,7 +372,7 @@ Here is an example of how to use this script to make the machine be a primary ma
|
||||
|
||||
/opt/xcat/share/xcat/hamn/activate-mn -i eth1:2 -v 9.114.47.97 -m 255.255.255.0
|
||||
|
||||
**Notes**: This script will be over-written after xCAT is upgraded. If this script is customized, make sure backup it before upgrading xCAT.
|
||||
.. warning:: This script will be over-written after xCAT is upgraded. If this script is customized, make sure to back it up before upgrading xCAT.
|
||||
|
||||
On the new primary management node:
|
||||
|
||||
@@ -509,7 +509,7 @@ The operating system is installed on the internal disks.
|
||||
|
||||
If you place entries for the disk in ``/etc/fstab``, which is not required, ensure that the entries do not have the system automatically mount the disk.
|
||||
|
||||
``Note``: Since the file systems will not be mounted automatically during system reboot, it implies that you need to manually mount the file systems after the primary management node reboot. Before mounting the file systems, stop xcat daemon first; after the file systems are mounted, start xcat daemon.
|
||||
.. note:: Since the file systems will not be mounted automatically during system reboot this must be manually done and xCAT should be started **after** the filesystem is mounted.
|
||||
|
||||
#. Verify the file systems on the primary management node.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ Diskful (Stateful) Installation
|
||||
|
||||
Any cluster using statelite compute nodes must use a stateful (diskful) Service Nodes.
|
||||
|
||||
**Note:** All xCAT Service Nodes must be at the exact same xCAT version as the xCAT Management Node.
|
||||
.. note:: All xCAT Service Nodes must be at the exact same xCAT version as the xCAT Management Node.
|
||||
|
||||
Configure ``otherpkgdir`` and ``otherpkglist`` for service node osimage
|
||||
-----------------------------------------------------------------------
|
||||
@@ -50,7 +50,7 @@ Configure ``otherpkgdir`` and ``otherpkglist`` for service node osimage
|
||||
xcat/xcat-dep/rh7/x86_64/perl-Net-Telnet
|
||||
xcat/xcat-dep/rh7/x86_64/perl-Expect
|
||||
|
||||
**Note:** you will be installing the xCAT Service Node rpm xCATsn meta-package on the Service Node, not the xCAT Management Node meta-package. Do not install both.
|
||||
.. note:: You will be installing the xCAT Service Node RPM ``xCATsn`` on the Service Node, not the xCAT Management Node RPM. Do not install both.
|
||||
|
||||
Update the rhels6 RPM repository (rhels6 only)
|
||||
----------------------------------------------
|
||||
@@ -87,7 +87,7 @@ Update the rhels6 RPM repository (rhels6 only)
|
||||
createrepo \
|
||||
-g repodata /98462d05248098ef1724eddb2c0a127954aade64d4bb7d4e693cff32ab1e463c-comps-rhel6-Server.xml
|
||||
|
||||
**Note:** you should use ``comps-rhel6-Server.xml`` with its key as the group file.
|
||||
.. note:: You should use ``comps-rhel6-Server.xml`` with its key as the group file.
|
||||
|
||||
Install Service Nodes
|
||||
---------------------
|
||||
@@ -109,12 +109,7 @@ Watch the installation progress using either wcons or rcons: ::
|
||||
rcons <node_name>
|
||||
tail -f /var/log/messages
|
||||
|
||||
Note: We have experienced one problem while trying to install RHEL6 diskful
|
||||
Service Node working with SAS disks. The Service Node cannot reboots from SAS
|
||||
disk after the RHEL6 operating system has been installed. We are waiting for
|
||||
the build with fixes from RHEL6 team, once meet this problem, you need to
|
||||
manually select the SAS disk to be the first boot device and boots from the
|
||||
SAS disk.
|
||||
.. note:: We have experienced one problem while trying to install RHEL6 diskful Service Node working with SAS disks. The Service Node cannot reboots from SAS disk after the RHEL6 operating system has been installed. We are waiting for the build with fixes from RHEL6 team, once meet this problem, you need to manually select the SAS disk to be the first boot device and boots from the SAS disk.
|
||||
|
||||
Update Service Node Diskful Image
|
||||
---------------------------------
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Diskless (Stateless) Installation
|
||||
=================================
|
||||
|
||||
**Note: The stateless Service Node is not supported in ubuntu hierarchy cluster. For ubuntu, skip this section.**
|
||||
.. note:: The stateless Service Node is not supported in Ubunti hierarchy cluster. For Ubunti, skip this section.
|
||||
|
||||
If you want, your Service Nodes can be stateless (diskless). The Service Node
|
||||
must contain not only the OS, but also the xCAT software and its dependencies.
|
||||
@@ -56,7 +56,7 @@ When you run ``copycds``, xCAT will only create a Service Node stateful osimage
|
||||
postinstall
|
||||
rootimgdir
|
||||
|
||||
1, Create the exlist, pkglist and otherpkglist file.
|
||||
#. Create the exlist, pkglist and otherpkglist file.
|
||||
|
||||
xCAT ships a basic requirements lists that will create a fully functional Service Node. However, you may want to customize your service node by adding additional operating system packages or modifying the files excluded by the exclude list. Check the below files to see if it meets your needs. ::
|
||||
|
||||
@@ -95,9 +95,9 @@ When you run ``copycds``, xCAT will only create a Service Node stateful osimage
|
||||
xcat/xcat-dep/rh7/ppc64le/perl-Net-Telnet
|
||||
xcat/xcat-dep/rh7/ppc64le/perl-Expect
|
||||
|
||||
**Note:** you will be installing the xCAT Service Node rpm xCATsn meta-package on the Service Node, not the xCAT Management Node meta-package. Do not install both.
|
||||
.. note:: You will be installing the xCAT Service Node RPM ``xCATsn`` on the Service Node, not the xCAT Management Node RPM. Do not install both.
|
||||
|
||||
2, Create the postinstall script.
|
||||
#. Create the postinstall script.
|
||||
|
||||
xCAT ships a default postinstall script for stateless Service Node. You may also choose to create an appropriate /etc/fstab file in your
|
||||
Service Node image. :
|
||||
@@ -116,7 +116,7 @@ When you run ``copycds``, xCAT will only create a Service Node stateful osimage
|
||||
none /tmp tmpfs defaults,size=10m 0 2
|
||||
none /var/tmp tmpfs defaults,size=10m 0 2
|
||||
|
||||
3, Modify the Service Node osimage definition with given attributes.
|
||||
#. Modify the Service Node osimage definition with given attributes.
|
||||
|
||||
::
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ Backup xCAT management node data to backup server:
|
||||
~/.xcat
|
||||
/etc/xcat
|
||||
|
||||
**Notes**: backing up ``~/.xcat`` is for all users who have xCAT client certs.
|
||||
.. note:: Backing up ``~/.xcat`` is for all users who have xCAT client certs.
|
||||
|
||||
#. If there are customized files and directories for ``otherpkgdir``, ``pkgdir``, ``pkglist`` or ``template`` in some `osimage` definitions, backup these files and directories. for example: ::
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ Running Remote Commands in Parallel
|
||||
|
||||
You can use xdsh to run parallel commands on Ethernet switches. The following shows how to configure xCAT to run xdsh on the switches:
|
||||
|
||||
**[Note]**:Configure the switch to allow **ssh** or **telnet**. This varies for switch to switch. Refer to the switch command references to find out how to do it.
|
||||
.. note:: For this to work, configure the switch to allow **ssh** or **telnet**. The procedure varies from switch to switch, consult the reference guides for your switch to find out how to do this.
|
||||
|
||||
Add the switch in xCAT DB. Refer to the "Discovering Switches" section if you want xCAT to discover and define the switches for you. ::
|
||||
|
||||
@@ -97,7 +97,7 @@ Set the ssh or telnet username an d password. ::
|
||||
|
||||
xdsh bntc125 --devicetype EthSwitch::BNT "enable;configure terminal;vlan 3;end;show vlan"
|
||||
|
||||
Note that you can run multiple switch commands, they are separated by comma.
|
||||
.. note:: You can run multiple switch commands, each command is comma separated.
|
||||
|
||||
Also note that --devicetype is used here. xCAT supports the following switch types out of the box: ::
|
||||
|
||||
|
||||
@@ -8,4 +8,3 @@ Networking
|
||||
onie_switches/index.rst
|
||||
switchdiscover/index.rst
|
||||
infiniband/index.rst
|
||||
ipv6/index.rst
|
||||
|
||||
@@ -21,7 +21,11 @@ Burn new firmware on each ibaX: ::
|
||||
|
||||
mstflint -d 0002:01:00.0 -i <image location> b
|
||||
|
||||
Note: if this is a PureFlex MezzanineP adapter then you must select the correct image for each ibaX device. Note the difference in the firmware image at end of filename: _0.bin (iba0/iba2) & _1.bin (iba1/iba3)
|
||||
.. note:: If this is a PureFlex MezzanineP adapter, you must select the correct image for each ibaX device.
|
||||
|
||||
The difference in the firmware image at the end of the file name:
|
||||
* _0.bin (iba0/iba2)
|
||||
* _1.bin (iba1/iba3)
|
||||
|
||||
Verify download successful: ::
|
||||
|
||||
@@ -31,7 +35,7 @@ Activate the new firmware: ::
|
||||
|
||||
reboot the image
|
||||
|
||||
Note: the above 0002:01:00.0 device location was used as an example only. it is not meant to imply that there is only one device location or that your device will have the same device location.
|
||||
.. note:: The above ``0002:01:00.0`` device location is used as an example only. Validate your device location using the ``lspci`` command.
|
||||
|
||||
Mellanox Switch Firmware Upgrade
|
||||
--------------------------------
|
||||
|
||||
@@ -18,11 +18,11 @@ Diskful Installation
|
||||
chdef -t node -o <node_name> \
|
||||
-p postscripts="mlnxofed_ib_install -p /install/<path-to>/<MLNX_OFED_LINUX.iso>"
|
||||
|
||||
**[kernel mismatch issue]** The Mellanox OFED ISO is built against a series of specific kernel version. If the version of the linux kernel does not match any of the Mellanox offered pre-built kernel modules, you can pass the ``--add-kernel-support`` argument to the Mellanox installation script to build the kernel modules based on the version you are using. ::
|
||||
**[kernel mismatch issue]** The Mellanox OFED ISO is built against a series of specific kernel version. If the version of the linux kernel does not match any of the Mellanox offered pre-built kernel modules, you can pass the ``--add-kernel-support --force`` argument to the Mellanox installation script to build the kernel modules based on the version you are using. ::
|
||||
|
||||
chdef -t node -o <node_name> \
|
||||
-p postscripts="mlnxofed_ib_install -p /install/<path-to>/<MLNX_OFED_LINUX.iso> \
|
||||
-m --add-kernel-support -end-"
|
||||
-m --add-kernel-support --force -end-"
|
||||
|
||||
#. Provision the node ::
|
||||
|
||||
|
||||
@@ -26,14 +26,16 @@ Diskless Installation
|
||||
/install/postscripts/mlnxofed_ib_install \
|
||||
-p /install/<path-to>/<MLNX_OFED_LINUX.iso> -i $1 -n genimage
|
||||
|
||||
*Note: The $1 is a argument that is passed to the the postinstall script at runtime.*
|
||||
.. note:: The ``$1`` is a argument that is passed to the the postinstall script at runtime.
|
||||
|
||||
**[kernel mismatch issue]** The Mellanox OFED ISO is built against a series of specific kernel version. If the version of the linux kernel does not match any of the Mellanox offered pre-built kernel modules, you can pass the ``--add-kernel-support --without-32bit --without-fw-update --force`` arguments to the Mellanox installation script to build the kernel modules based on the version you are using. ::
|
||||
.. tip:: **Kernel Mismatch**
|
||||
|
||||
The Mellanox OFED ISO is built against a series of specific kernel version. If the version of the linux kernel being used does not match any of the pre-built kernels, pass ``--add-kernel-support --without-32bit --without-fw-update --force`` to the Mellanox installation script to build the kernel modules based on the kernel you are using. Example: ::
|
||||
|
||||
/install/postscripts/mlnxofed_ib_install \
|
||||
-p /install/<path-to>/<MLNX_OFED_LINUX.iso> -m --add-kernel-support --without-32bit --without-fw-update --force -end- \
|
||||
-i $1 -n genimage
|
||||
|
||||
/install/postscripts/mlnxofed_ib_install \
|
||||
-p /install/<path-to>/<MLNX_OFED_LINUX.iso> -m --add-kernel-support --without-32bit --without-fw-update --force -end- \
|
||||
-i $1 -n genimage
|
||||
|
||||
#. Generate the diskless image
|
||||
|
||||
Use the ``genimage`` command to generate the diskless image from the osimage definition ::
|
||||
|
||||
@@ -50,18 +50,7 @@ Then run the following: ::
|
||||
|
||||
rspconfig mswitch sshcfg=enable
|
||||
|
||||
**[Note]** For Mellanox switch in manufacturing defaults status, the user need to answer 'no' for the initial configuration wizard prompt as follows before run 'rspconfig'. ::
|
||||
|
||||
[s1mn][/](/)> ssh -l admin mswitch
|
||||
Mellanox MLNX-OS Switch Management
|
||||
Password:
|
||||
Last login: Wed Feb 20 20:09:50 2013 from 1.2.3.4
|
||||
Mellanox Switch
|
||||
Mellanox configuration wizard
|
||||
Do you want to use the wizard for initial configuration? **no**
|
||||
To return to the wizard from the CLI, enter the "configuration jump-start"
|
||||
command from configure mode. Launching CLI...
|
||||
switch-xxxxxx [standalone: unknown] > exit
|
||||
.. warning:: For Mellanox switch in manufacturing defaults, the user may need to log in once and answer **no** to the configuration wizard as ``rspconfig`` will fail when prompted against the wizard.
|
||||
|
||||
Setup syslog on the Switch
|
||||
--------------------------
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
IPv6
|
||||
====
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
ipv6_support.rst
|
||||
@@ -1,2 +0,0 @@
|
||||
Configuring IPv6
|
||||
================
|
||||
@@ -4,7 +4,7 @@ Installation and Configuration
|
||||
Cumulus OS Installtion
|
||||
----------------------
|
||||
|
||||
**Note:** *The following assumes that the physical switches have power and have obtained a DHCP IP address from the xCAT open range.*
|
||||
.. important:: The following assumes that the physical switches have power and have obtained a DHCP IP address from the xCAT open range.
|
||||
|
||||
xCAT provides support for detecting and installing the Cumulus Linux OS into ONIE enabled switches by utilizing DHCP to detect "**onie_vendor**" from the ``vendor-class-identifier`` string and then send it the Cumulus Linux OS installer.
|
||||
|
||||
@@ -41,16 +41,27 @@ xCAT provides support for detecting and installing the Cumulus Linux OS into ONI
|
||||
switchdiscover --range <IP range>
|
||||
|
||||
|
||||
#. Set the ``provmethod`` attribute of the target switch(es) to the Cumulus Linux install image: ::
|
||||
#. Run the ``nodeset`` command to set the ``provmethod`` attribute of the target switch(es) to the Cumulus Linux install image and prepare the DHCP/BOOTP lease information for the switch: ::
|
||||
|
||||
chdef frame[01-04]sw1 \
|
||||
provmethod="/install/custom/sw_os/cumulus/cumulus-linux-3.1.0-bcm-armel.bin"
|
||||
# nodeset frame01sw1 osimage=cumulus3.5.2-armel
|
||||
# lsdef frame01sw1
|
||||
Object name: frame01sw1
|
||||
arch=armv7l
|
||||
groups=switch,edge_switch
|
||||
ip=172.21.208.03
|
||||
mac=8C:EA:1B:E8:78:C0
|
||||
mgt=switch
|
||||
netboot=onie
|
||||
nodetype=switch
|
||||
postbootscripts=otherpkgs
|
||||
postscripts=syslog,remoteshell
|
||||
provmethod=cumulus3.5.2-armel
|
||||
switch=mid08
|
||||
switchport=3
|
||||
switchtype=onie
|
||||
usercomment=Edgecore Networks Switch
|
||||
|
||||
#. Run ``makedhcp`` to prepare the DHCP/BOOTP lease information for the switch: ::
|
||||
|
||||
makedhcp -a frame[01-04]sw1
|
||||
|
||||
Executing the ``makedhcp`` command will kick off the network install of the ONIE enabled switch. If there is no OS pre-loaded on the switch, the switch continues to send a DHCPREQUEST out to the network. After ``makedhcp`` is run against the switch, an entry is added to the leases file that will respond to the request with the Cumulus Linux installer file. ::
|
||||
``nodeset`` will executing the ``makedhcp`` command and kick off the network install of the ONIE enabled switch. If there is no OS pre-loaded on the switch, the switch continues to send a DHCPREQUEST out to the network. After ``makedhcp`` is run against the switch, an entry is added to the leases file that will respond to the request with the Cumulus Linux installer file. ::
|
||||
|
||||
host frame1sw1 {
|
||||
dynamic;
|
||||
@@ -59,7 +70,7 @@ xCAT provides support for detecting and installing the Cumulus Linux OS into ONI
|
||||
supersede server.ddns-hostname = "frame1sw1";
|
||||
supersede host-name = "frame1sw1";
|
||||
if substring (option vendor-class-identifier, 0, 11) = "onie_vendor" {
|
||||
supersede www-server = "http://192.168.27.1/install/custom/sw_os/cumulus/cumulus-linux-3.1.0-bcm-armel.bin";
|
||||
supersede www-server = "http://192.168.27.1/install/cumulus3.5.2/armel/cumulus-linux-3.5.2-bcm-armel.bin";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,24 @@
|
||||
Switch Management
|
||||
=================
|
||||
|
||||
Sync File support
|
||||
------------------
|
||||
|
||||
xCAT supports synchronize of configuration files for cumulus switches.
|
||||
|
||||
#. Use instructions in doc: :ref:`The_synclist_file` to set up syncfile.
|
||||
#. Add syncfile to cumulus osimage. ::
|
||||
|
||||
# chdef -t osimage cumulus3.5.2-armel synclists=/tmp/synclists
|
||||
1 object definitions have been created or modified.
|
||||
|
||||
#. run ``updatenode`` to sync the files to cumulus switches. ::
|
||||
|
||||
# updatenode mid08tor03 -F
|
||||
File synchronization has completed for nodes: "mid08tor03"
|
||||
|
||||
|
||||
|
||||
Switch Port and VLAN Configuration
|
||||
----------------------------------
|
||||
|
||||
@@ -14,7 +32,7 @@ xCAT will look for files in the above directory in the following order:
|
||||
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.
|
||||
.. 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: ::
|
||||
|
||||
@@ -26,7 +44,7 @@ Re-install OS
|
||||
|
||||
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:
|
||||
|
||||
**Note:** Assumption that the Cumulus Linux files are on the xCAT MN in the correct place.
|
||||
.. important:: This assumes that the Cumulus Linux files are on the xCAT MN in the correct place.
|
||||
|
||||
* **Using xCAT**, ``xdsh`` can invoke the reinstall of the OS: ::
|
||||
|
||||
|
||||
@@ -17,3 +17,27 @@ Prepare the Cumulus Linux files on the xCAT Management Node.
|
||||
cp cumulus-linux-3.1.0-bcm-armel.bin /install/custom/sw_os/cumulus/
|
||||
|
||||
|
||||
Cumulus osimage
|
||||
---------------
|
||||
|
||||
xCAT can able to create a cumulus osimage defintion via ``copycds`` command. ``copycds`` will copy cumulus installer to a destination directory, and create several relevant osimage definitions. **cumulus<release>-<arch>** is the default osimage name. ::
|
||||
|
||||
#run copycds command
|
||||
# copycds cumulus-linux-3.5.2-bcm-armel.bin
|
||||
|
||||
The ``pkgdir`` attribute will contain full path of cumulus installer as **/install/cumulus<release>/<arch>/<installer>**. ::
|
||||
|
||||
# lsdef -t osimage cumulus3.5.2-armel
|
||||
Object name: cumulus3.5.2-armel
|
||||
description=Cumulus Linux
|
||||
imagetype=linux
|
||||
osarch=armel
|
||||
osname=cumulus
|
||||
osvers=cumulus3.5.2
|
||||
pkgdir=/install/cumulus3.5.2/armel/cumulus-linux-3.5.2-bcm-armel.bin
|
||||
provmethod=install
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Full Install
|
||||
|
||||
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.
|
||||
.. important:: Make sure you back up all your data and configuration files as the binary install will erase all previous configuration.
|
||||
|
||||
#. Place the binary image under ``/install`` on the xCAT MN node.
|
||||
|
||||
@@ -22,7 +22,7 @@ Perform a full install from the ``.bin`` file of the new Cumulus Linux OS versio
|
||||
xdsh switch1 "/usr/cumulus/bin/onie-install -a -f -i \
|
||||
http://172.21.253.37/install/onie/cumulus-linux-3.4.1.bin && reboot"
|
||||
|
||||
**Note:** The full upgrade process may run 30 minutes or longer.
|
||||
.. attention:: The full upgrade process may run 30 minutes or longer.
|
||||
|
||||
#. After upgrading, the license should be installed, see :ref:`Activate the License <activate-the-license>` for details.
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ For example: ::
|
||||
|
||||
This means port 42 of switch1 is connected to port 50 of switch2. And switch1 can be accessed using SNMP version 3 and switch 2 can be accessed using SNMP version 2.
|
||||
|
||||
Note: The **username** and the **password** on the switches table are NOT the same as SSH user name and password. You have to configure SNMP on the switch for these parameters and then fill up this table. Use **tabdump switches -d** command to find out the meaning of each column.
|
||||
.. note:: The **username** and the **password** on the switches table are NOT the same as SSH user name and password. You have to configure SNMP on the switch for these parameters and then fill up this table. Use **tabdump switches -d** command to find out the meaning of each column.
|
||||
|
||||
**2. Populate the switch table**
|
||||
|
||||
@@ -148,7 +148,7 @@ For xCAT-vlan 2.7.5 and later versions, you can create vlans for other networks.
|
||||
|
||||
A tagged vlan will be created for the network that is on eth1 for node1, node2 and node3. For KVM clients, -i specifies the interface name on the KVM host that the vlan will be tagged on. If -i is omitted, the management networks will be assumed.
|
||||
|
||||
Note: After the vlan is created, the nodes can still be accessed by the mn using the management network. You can use **lsvan** command to list all the vlans.
|
||||
.. note:: After the vlan is created, the nodes can still be accessed by the mn using the management network. You can use **lsvan** command to list all the vlans.
|
||||
|
||||
For example: ::
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@ Adjusting Operating System tunables can improve large scale cluster performance,
|
||||
The open file limits are important to high concurrence network services, such as ``xcatd``. For a large cluster, it is required to increase the number of open file limit to avoid **Too many open files** error. The default value is *1024* in most OS distributions, to add below configuration in ``/etc/security/limits.conf`` to increase to *14096*.
|
||||
::
|
||||
|
||||
* soft nofiles 14096
|
||||
* hard nofiles 14096
|
||||
* soft nofile 14096
|
||||
* hard nofile 14096
|
||||
|
||||
|
||||
#. Tuning Network kernel parameters:
|
||||
|
||||
There might be hundreds of hosts in a big network for large cluster, tuning the network kernel parameters for optimum throughput and latency could improve the performance of distributed application. For example, adding below configuration in ``/etc/sysctl.conf`` to increase the buffer.
|
||||
There might be hundreds of hosts in a big network for large cluster, tuning the network kernel parameters for optimum throughput and latency could improve the performance of distributed application. For example, adding below configuration in ``/etc/sysctl.conf`` to increase the buffer size and queue length of **xCAT SSL listener** service access point ( port **3001** ).
|
||||
|
||||
::
|
||||
|
||||
@@ -23,6 +23,7 @@ Adjusting Operating System tunables can improve large scale cluster performance,
|
||||
net.core.wmem_max = 33554432
|
||||
net.core.rmem_default = 65536
|
||||
net.core.wmem_default = 65536
|
||||
net.core.somaxconn = 8192
|
||||
|
||||
net.ipv4.tcp_rmem = 4096 33554432 33554432
|
||||
net.ipv4.tcp_wmem = 4096 33554432 33554432
|
||||
|
||||
@@ -755,6 +755,29 @@ Delete all the event log for node1. ::
|
||||
[URI:/nodes/{noderange}/beacon] - The beacon resource for the node {noderange}
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
GET - Get the beacon status for the node {noderange}.
|
||||
`````````````````````````````````````````````````````
|
||||
|
||||
Refer to the man page: :doc:`rbeacon </guides/admin-guides/references/man1/rbeacon.1>`
|
||||
|
||||
**Returns:**
|
||||
|
||||
* Json format: An object which includes multiple '<name> : {att:value, attr:value ...}' pairs.
|
||||
|
||||
**Example:**
|
||||
|
||||
Get beacon for node1. ::
|
||||
|
||||
|
||||
curl -X GET -k 'https://127.0.0.1/xcatws/nodes/node1/beacon?userName=root&userPW=cluster&pretty=1'
|
||||
{
|
||||
"node1":{
|
||||
"beacon":[
|
||||
"Front:Blink Rear:Blink"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
PUT - Change the beacon status for the node {noderange}.
|
||||
````````````````````````````````````````````````````````
|
||||
|
||||
@@ -774,13 +797,6 @@ Turn on the beacon. ::
|
||||
|
||||
|
||||
curl -X PUT -k 'https://127.0.0.1/xcatws/nodes/node1/beacon?userName=root&userPW=cluster&pretty=1' -H Content-Type:application/json --data '{"action":"on"}'
|
||||
[
|
||||
{
|
||||
"name":"node1",
|
||||
"beacon":"on"
|
||||
}
|
||||
]
|
||||
|
||||
[URI:/nodes/{noderange}/updating] - The updating resource for the node {noderange}
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
@@ -2107,7 +2123,7 @@ Get OS and ARCH attributes from nodetype table for node1 and node2. ::
|
||||
[URI:/tables/{tablelist}/rows] - The non-node table resource
|
||||
------------------------------------------------------------
|
||||
|
||||
Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, polciy, etc.
|
||||
Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, policy, etc.
|
||||
|
||||
GET - Get all rows from non-node tables.
|
||||
````````````````````````````````````````
|
||||
@@ -2144,7 +2160,7 @@ Get all rows from networks table. ::
|
||||
[URI:/tables/{tablelist}/rows/{keys}] - The non-node table rows resource
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, polciy, etc.
|
||||
Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, policy, etc.
|
||||
|
||||
{keys} should be the name=value pairs which are used to search table. e.g. {keys} should be [net=192.168.1.0,mask=255.255.255.0] for networks table query since the net and mask are the keys of networks table.
|
||||
|
||||
@@ -2157,7 +2173,7 @@ GET - Get attributes for rows from non-node tables.
|
||||
|
||||
**Example:**
|
||||
|
||||
Get row which net=192.168.1.0,mask=255.255.255.0 from networks table. ::
|
||||
Get rows from networks table where net=192.168.1.0,mask=255.255.255.0. ::
|
||||
|
||||
|
||||
curl -X GET -k 'https://127.0.0.1/xcatws/tables/networks/rows/net=192.168.1.0,mask=255.255.255.0?userName=root&userPW=cluster&pretty=1'
|
||||
@@ -2201,14 +2217,14 @@ DELETE - Delete rows from a non-node table that have the attribute values specif
|
||||
|
||||
**Example:**
|
||||
|
||||
Delete a route row which routename=privnet in the routes table. ::
|
||||
Delete rows from routes table where routename=privnet. ::
|
||||
|
||||
|
||||
curl -X DELETE -k 'https://127.0.0.1/xcatws/tables/routes/rows/routename=privnet?userName=root&userPW=cluster&pretty=1'
|
||||
[URI:/tables/{tablelist}/rows/{keys}/{attrlist}] - The non-node table attributes resource
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, polciy, etc.
|
||||
Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, policy, etc.
|
||||
|
||||
GET - Get specific attributes for rows from non-node tables.
|
||||
````````````````````````````````````````````````````````````
|
||||
@@ -2219,7 +2235,7 @@ GET - Get specific attributes for rows from non-node tables.
|
||||
|
||||
**Example:**
|
||||
|
||||
Get attributes mgtifname and tftpserver which net=192.168.1.0,mask=255.255.255.0 from networks table. ::
|
||||
Get attributes mgtifname and tftpserver from networks table for each row where net=192.168.1.0,mask=255.255.255.0. ::
|
||||
|
||||
|
||||
curl -X GET -k 'https://127.0.0.1/xcatws/tables/networks/rows/net=192.168.1.0,mask=255.255.255.0/mgtifname,tftpserver?userName=root&userPW=cluster&pretty=1'
|
||||
|
||||
@@ -58,7 +58,15 @@ Then in the subsequent REST API access, the token can be used to replace the use
|
||||
|
||||
curl -X GET -k -H X-Auth-Token:5cabd675-bc2e-4318-b1d6-831fd1f32f97 'https://<FQDN of xCAT MN>/xcatws/<resource>?<parameters>
|
||||
|
||||
The validity of token is 24 hours. If an old token has expired, you will get a 'Authentication failure' error. Then you need reacquire a token with your account.
|
||||
The default validity of a token is 1 day. This default can be changed by the setting of `tokenexpiredays` attribute in `site` table. ::
|
||||
|
||||
chdef -t site clustersite tokenexpiredays=<days>
|
||||
|
||||
To make tokens valid forever use "never". ::
|
||||
|
||||
chdef -t site clustersite tokenexpiredays=never
|
||||
|
||||
If an old token has expired, you will get a 'Authentication failure' error. You will need to reacquire a token for your account.
|
||||
|
||||
|
||||
The Common Parameters for Resource URI
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
By default, xCAT will install the operating system on the first disk and with default partitions layout in the node. However, you may choose to customize the disk partitioning during the install process and define a specific disk layout. You can do this in one of two ways: '**partition definition file**' or '**partition definition script**'.
|
||||
|
||||
**Notes**
|
||||
.. note:: ``partition definition file`` can be used for RedHat, SLES, and Ubuntu. Because disk configuraiton for Ubuntu is different from RedHat, there may be some special sections required for Ubuntu.
|
||||
|
||||
- 'Partition definition file' way can be used for RedHat, SLES and Ubuntu.
|
||||
- 'partition definition script' way was tested only for RedHat and Ubuntu, use this feature on SLES at your own risk.
|
||||
- Because disk configuration for ubuntu is different from RedHat, there maybe some section special for ubuntu.
|
||||
.. warning:: ``partition definition script`` has only been tested on RedHat and Ubuntu, use at your own risk for SLES.
|
||||
|
||||
.. END_Overview
|
||||
|
||||
|
||||
+2
-2
@@ -17,9 +17,9 @@ The basic entry format looks like following: ::
|
||||
|
||||
The path_of_src_file* should be the full path of the source file on the Management Node.
|
||||
|
||||
The path_of_dst_file* should be the full path of the destination file on target node.
|
||||
The path_of_dst_file* should be the full path of the destination file on target node. Please make sure path_of_dst_file* is not a existing directory on target node, otherwise, the file sync with ``updatenode -r /usr/bin/scp`` or ``xdcp -r /usr/bin/scp`` will fail.
|
||||
|
||||
The path_of_dst_directory should be the full path of the destination directory.
|
||||
The path_of_dst_directory should be the full path of the destination directory. Please make sure *eth_of_dst_directory is not a existing file on target node, otherwise, the file sync with ``updatenode -r /usr/bin/scp`` or ``xdcp -r /usr/bin/scp`` will fail.
|
||||
|
||||
Since the synclist file is for common purpose, the target node need not be configured in it.
|
||||
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ The litefile table specifies the directories and files on the statelite nodes th
|
||||
|
||||
Currently, xCAT does not handle the relative links very well. The relative links are commonly used by the system libraries, for example, under ``/lib/`` directory, there will be one relative link matching one ``.so`` file. So, when you add one relative link to the litefile table (Not recommend), make sure the real file also be included, or put its directory name into the litefile table.
|
||||
|
||||
**Note**: It is recommended that you specify at least the entries listed below in the litefile table, because most of these files need to be writeable for the node to boot up successfully. When any changes are made to their options, make sure they won't affect the whole system.
|
||||
.. Note:: It is recommended that you specify at least the entries listed below in the litefile table, because most of these files need to be writeable for the node to boot up successfully. When any changes are made to their options, make sure they won't affect the whole system. If you want to run a command like ``/bin/ping`` using non-root users, add this command into ``litefile``, then root user have privilege to authorize the command for non-root users.
|
||||
|
||||
Sample Data for Redhat statelite setup
|
||||
``````````````````````````````````````
|
||||
|
||||
@@ -48,7 +48,7 @@ OPTIONS
|
||||
|
||||
\ **-**\ **-range**\
|
||||
|
||||
Specify one or more IP ranges acceptable to nmap. IP range can be hostnames, IP addresses, networks, etc. A single IP address (10.1.2.3) or an IP range (10.1.2.0/24) can be specified. If the range is very large, the \ **bmcdiscover**\ command may take a long time to return.
|
||||
Specify one or more IP ranges acceptable to nmap. IP range can be hostnames, IP addresses, networks, etc. A single IP address (10.1.2.3), several IPs with commas (10.1.2.3,10.1.2.10), Ip range with "-" (10.1.2.0-100) or an IP range (10.1.2.0/24) can be specified. If the range is very large, the \ **bmcdiscover**\ command may take a long time to return.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ SYNOPSIS
|
||||
|
||||
\ **packimage [-v| -**\ **-version]**\
|
||||
|
||||
\ **packimage**\ [\ **-m | -**\ **-method**\ \ *cpio|tar*\ ] [\ **-c | -**\ **-compress**\ \ *gzip|pigz|xz*\ ] \ *imagename*\
|
||||
\ **packimage**\ [\ **-m | -**\ **-method**\ \ *cpio|tar*\ ] [\ **-c | -**\ **-compress**\ \ *gzip|pigz|xz*\ ] [\ **--nosyncfiles**\ ] \ *imagename*\
|
||||
|
||||
|
||||
***********
|
||||
@@ -57,6 +57,8 @@ OPTIONS
|
||||
|
||||
\ **-c| -**\ **-compress**\ Compress Method (pigz,gzip,xz, default is pigz/gzip)
|
||||
|
||||
\ **--nosyncfiles**\ Bypass of syncfiles requested, will not sync files to root image directory
|
||||
|
||||
|
||||
************
|
||||
RETURN VALUE
|
||||
@@ -89,6 +91,14 @@ EXAMPLES
|
||||
packimage -m tar -c pigz rhels7.1-x86_64-netboot-compute
|
||||
|
||||
|
||||
3. To pack the osimage 'rhels7.1-x86_64-netboot-compute' without syncing files:
|
||||
|
||||
|
||||
.. code-block:: perl
|
||||
|
||||
packimage --nosyncfiles rhels7.1-x86_64-netboot-compute
|
||||
|
||||
|
||||
|
||||
*****
|
||||
FILES
|
||||
|
||||
@@ -39,7 +39,7 @@ OpenPOWER (OpenBMC) server specific:
|
||||
====================================
|
||||
|
||||
|
||||
\ **rinv**\ \ *noderange*\ [\ **model | serial | firm | cpu | dimm | all**\ ] [\ **-V | -**\ **-verbose**\ ]
|
||||
\ **rinv**\ \ *noderange*\ [\ **model**\ ][\ **serial**\ ][\ **firm**\ ][\ **cpu**\ ][\ **dimm**\ ][\ **all**\ ] [\ **-V | -**\ **-verbose**\ ]
|
||||
|
||||
|
||||
PPC (with HMC) specific:
|
||||
|
||||
@@ -19,7 +19,7 @@ SYNOPSIS
|
||||
********
|
||||
|
||||
|
||||
\ **updatenode**\ \ *noderange*\ [\ **-V | -**\ **-verbose**\ ] [\ **-F | -**\ **-sync**\ ] [\ **-f | -**\ **-snsync**\ ] [\ **-S | -**\ **-sw**\ ] [\ **-l**\ \ *userID*\ ] [\ **-P | -**\ **-scripts**\ [\ *script1,script2...*\ ]] [\ **-s | -**\ **-sn**\ ] [\ **-A | -**\ **-updateallsw**\ ] [\ **-c | -**\ **-cmdlineonly**\ ] [\ **-d**\ \ *alt_source_dir*\ ] [\ **-**\ **-fanout**\ =\ *fanout_value*\ ] [\ **-t**\ \ *timeout*\ } [\ *attr=val*\ [\ *attr=val...*\ ]] [\ **-n | -**\ **-noverify**\ ]
|
||||
\ **updatenode**\ \ *noderange*\ [\ **-V | -**\ **-verbose**\ ] [\ **-F | -**\ **-sync**\ ] [\ **-f | -**\ **-snsync**\ ] [\ **-r | -**\ **-node-rcp**\ [\ *full_path_to_remote_copy_command*\ ]] [\ **-S | -**\ **-sw**\ ] [\ **-l**\ \ *userID*\ ] [\ **-P | -**\ **-scripts**\ [\ *script1,script2...*\ ]] [\ **-s | -**\ **-sn**\ ] [\ **-A | -**\ **-updateallsw**\ ] [\ **-c | -**\ **-cmdlineonly**\ ] [\ **-d**\ \ *alt_source_dir*\ ] [\ **-**\ **-fanout**\ =\ *fanout_value*\ ] [\ **-t**\ \ *timeout*\ } [\ *attr=val*\ [\ *attr=val...*\ ]] [\ **-n | -**\ **-noverify**\ ]
|
||||
|
||||
\ **updatenode**\ \ **noderange**\ [\ **-k | -**\ **-security**\ ] [\ **-t**\ \ *timeout*\ ]
|
||||
|
||||
@@ -382,7 +382,7 @@ OPTIONS
|
||||
\ **-F|-**\ **-sync**\
|
||||
|
||||
Specifies that file synchronization should be
|
||||
performed on the nodes. rsync and ssh must
|
||||
performed on the nodes. rsync/scp and ssh must
|
||||
be installed and configured on the nodes.
|
||||
The function is not supported for NFS-based statelite installations.
|
||||
For NFS-based statelite installations to sync files, you should use the
|
||||
@@ -396,7 +396,7 @@ OPTIONS
|
||||
Specifies that file synchronization should be
|
||||
performed to the service nodes that service the
|
||||
nodes in the noderange. This updates the service
|
||||
nodes with the data to sync to the nodes. rsync and ssh must
|
||||
nodes with the data to sync to the nodes. rsync/scp and ssh must
|
||||
be installed and configured on the service nodes.
|
||||
For hierarchy, this optionally can be done before syncing the files
|
||||
to the nodes with the -F flag. If the -f flag is not used, then
|
||||
@@ -412,6 +412,20 @@ OPTIONS
|
||||
|
||||
|
||||
|
||||
[\ **-r | -**\ **-node-rcp**\ [\ *full_path_to_remote_copy_command*\ ]]
|
||||
|
||||
Specifies the full path of the remote copy command used for syncing files to node targets, such as "/usr/bin/rsync" or "/usr/bin/scp". If not specified, rsync will be used by default.
|
||||
|
||||
Notice: The synclist for "-r /usr/bin/scp" has some differences with "-r /usr/bin/rsync":
|
||||
|
||||
1) the ``EXECUTE`` clause is not supported in "-r /usr/bin/scp"
|
||||
|
||||
2) if the destination directory specified in synclist is an existing file on target node, "updatenode -r /usr/bin/scp" will fail with ``scp: <destination directory>: Not a directory``
|
||||
|
||||
3) if the destination file specified in synclist is an existing directory on target node, "updatenode -r /usr/bin/scp" will fail with ``scp: <destination file>: Is a directory``
|
||||
|
||||
|
||||
|
||||
\ **-g|-**\ **-genmypost**\
|
||||
|
||||
Will generate a new mypostscript file for the
|
||||
|
||||
@@ -229,9 +229,10 @@ For example, to run rscan command against the hardware control point of compute
|
||||
.. code-block:: perl
|
||||
|
||||
rscan __GETNODEATTR($$CN, hcp)__ -z
|
||||
3. B<GETTABLEVALUE(keyname, key, colname, table)> To get the value of column where keyname == key in specified table.
|
||||
|
||||
|
||||
3. \ **GETTABLEVALUE(keyname, key, colname, table)**\ To get the value of column where keyname == key in specified table.
|
||||
|
||||
|
||||
*****
|
||||
FILES
|
||||
|
||||
@@ -62,13 +62,13 @@ auditlog Attributes:
|
||||
|
||||
\ **clienttype**\
|
||||
|
||||
Type of command: cli,java,webui,other.
|
||||
Type of command: cli, java, webui, other.
|
||||
|
||||
|
||||
|
||||
\ **command**\
|
||||
|
||||
Command executed.
|
||||
Command executed. See auditskipcmds site table attribute to control which commands get logged.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ policy Attributes:
|
||||
|
||||
\ **rule**\
|
||||
|
||||
Specifies how this rule should be applied. Valid values are: allow, accept, trusted. Allow or accept will allow the user to run the commands. Any other value will deny the user access to the commands. Trusted means that once this client has been authenticated via the certificate, all other information that is sent (e.g. the username) is believed without question. This authorization should only be given to the xcatd on the management node at this time.
|
||||
Specifies how this rule should be applied. Valid values are: allow, trusted. Allow will allow the user to run the commands. Any other value will deny the user access to the commands. Trusted means that once this client has been authenticated via the certificate, all other information that is sent (e.g. the username) is believed without question. This authorization should only be given to the xcatd on the management node at this time.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ site Attributes:
|
||||
DATABASE ATTRIBUTES
|
||||
-----------------
|
||||
auditnosyslog: If set to 1, then commands will only be written to the auditlog table.
|
||||
This attribute set to 1 and auditskipcmds=ALL means no logging of commands.
|
||||
If this attribute is set to 1 and auditskipcmds=ALL means no logging of commands.
|
||||
Default is to write to both the auditlog table and syslog.
|
||||
auditskipcmds: List of commands and/or client types that will not be
|
||||
written to the auditlog table and syslog. See auditnosyslog.
|
||||
@@ -68,8 +68,7 @@ site Attributes:
|
||||
commands will be written.
|
||||
clienttype:web would skip all commands from the web client
|
||||
For example: tabdump,nodels,clienttype:web
|
||||
will not log tabdump,nodels and any web client commands.
|
||||
|
||||
will not log tabdump, nodels or any web client commands.
|
||||
databaseloc: Directory where we create the db instance directory.
|
||||
Default is /var/lib. Only DB2 is currently supported.
|
||||
Do not use the directory in the site.installloc or
|
||||
@@ -429,6 +428,8 @@ site Attributes:
|
||||
--------------------
|
||||
XCAT DAEMON ATTRIBUTES
|
||||
--------------------
|
||||
tokenexpiredays: Number of days before REST API token will expire. The default is 1.
|
||||
use 'never' if you want your token to never expire.
|
||||
useflowcontrol: (yes/1 or no/0). If yes, the postscript processing on each node
|
||||
contacts xcatd on the MN/SN using a lightweight UDP packet to wait
|
||||
until xcatd is ready to handle the requests associated with
|
||||
|
||||
@@ -19,7 +19,7 @@ SYNOPSIS
|
||||
********
|
||||
|
||||
|
||||
\ **token Attributes:**\ \ *tokenid*\ , \ *username*\ , \ *expire*\ , \ *comments*\ , \ *disable*\
|
||||
\ **token Attributes:**\ \ *tokenid*\ , \ *username*\ , \ *expire*\ , \ *created*\ , \ *access*\ , \ *comments*\ , \ *disable*\
|
||||
|
||||
|
||||
***********
|
||||
@@ -54,6 +54,18 @@ token Attributes:
|
||||
|
||||
|
||||
|
||||
\ **created**\
|
||||
|
||||
Creation time for this token.
|
||||
|
||||
|
||||
|
||||
\ **access**\
|
||||
|
||||
Last access time for this token.
|
||||
|
||||
|
||||
|
||||
\ **comments**\
|
||||
|
||||
Any user-provided notes.
|
||||
|
||||
@@ -59,13 +59,13 @@ auditlog Attributes:
|
||||
|
||||
\ **clienttype**\ (auditlog.clienttype)
|
||||
|
||||
Type of command: cli,java,webui,other.
|
||||
Type of command: cli, java, webui, other.
|
||||
|
||||
|
||||
|
||||
\ **command**\ (auditlog.command)
|
||||
|
||||
Command executed.
|
||||
Command executed. See auditskipcmds site table attribute to control which commands get logged.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ policy Attributes:
|
||||
|
||||
\ **rule**\ (policy.rule)
|
||||
|
||||
Specifies how this rule should be applied. Valid values are: allow, accept, trusted. Allow or accept will allow the user to run the commands. Any other value will deny the user access to the commands. Trusted means that once this client has been authenticated via the certificate, all other information that is sent (e.g. the username) is believed without question. This authorization should only be given to the xcatd on the management node at this time.
|
||||
Specifies how this rule should be applied. Valid values are: allow, trusted. Allow will allow the user to run the commands. Any other value will deny the user access to the commands. Trusted means that once this client has been authenticated via the certificate, all other information that is sent (e.g. the username) is believed without question. This authorization should only be given to the xcatd on the management node at this time.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,11 +23,11 @@ SYNOPSIS
|
||||
|
||||
\ **chtab**\ [\ **-v**\ | \ **-**\ **-version**\ ]
|
||||
|
||||
\ **chtab**\ [\ *keycolname=keyvalue*\ ] [\ *tablename.colname=newvalue*\ ]
|
||||
\ **chtab**\ \ *keycolname=keyvalue*\ [,\ *keycolname=keyvalue*\ ,...] \ *tablename.colname=newvalue*\ [\ *tablename.colname=newvalue*\ ...]
|
||||
|
||||
\ **chtab**\ [\ *keycolname=keyvalue*\ ] [\ *tablename.colname+=newvalue*\ ]
|
||||
\ **chtab**\ \ *keycolname=keyvalue*\ [,\ *keycolname=keyvalue*\ ,...] \ *tablename.colname+=newvalue*\ [\ *tablename.colname+=newvalue*\ ...]
|
||||
|
||||
\ **chtab -d**\ [\ *keycolname=keyvalue*\ ] [\ *tablename.colname=newvalue*\ ]
|
||||
\ **chtab -d**\ \ *keycolname=keyvalue*\ [,\ *keycolname=keyvalue*\ ,...] \ *tablename*\ [\ *tabname*\ ...]
|
||||
|
||||
|
||||
***********
|
||||
@@ -35,9 +35,9 @@ DESCRIPTION
|
||||
***********
|
||||
|
||||
|
||||
The chtab command adds, deletes or updates the attribute value in the specified table.column for the specified keyvalue. Normally, the given value will completely replace the current attribute value. But if "+=" is used instead of "=", the specified value will be appended to the coma separated list of the attribute, if it is not already there.
|
||||
The \ **chtab**\ command adds, deletes or updates the attribute values in the specified table.column for the specified \ *keyvalue*\ . Normally, the given value will completely replace the current attribute value. But if "+=" is used instead of "=", the specified value will be appended to the comma separated list of attributes, if it is not already there.
|
||||
|
||||
The chtab is designed to work without passing xcatd, so it's out of control of policy mechanism.
|
||||
The \ **chtab**\ does not pass through xcatd, so it is not controlled by the policy mechanism.
|
||||
|
||||
|
||||
*******
|
||||
|
||||
@@ -23,11 +23,11 @@ SYNOPSIS
|
||||
|
||||
\ **tabch**\ [\ **-v**\ | \ **-**\ **-version**\ ]
|
||||
|
||||
\ **tabch**\ [\ *keycolname=keyvalue*\ ] [\ *tablename.colname=newvalue*\ ]
|
||||
\ **tabch**\ \ *keycolname=keyvalue*\ [,\ *keycolname=keyvalue*\ ,...] \ *tablename.colname=newvalue*\ [\ *tablename.colname=newvalue*\ ...]
|
||||
|
||||
\ **tabch**\ [\ *keycolname=keyvalue*\ ] [\ *tablename.colname+=newvalue*\ ]
|
||||
\ **tabch**\ \ *keycolname=keyvalue*\ [,\ *keycolname=keyvalue*\ ,...] \ *tablename.colname+=newvalue*\ [\ *tablename.colname+=newvalue*\ ...]
|
||||
|
||||
\ **tabch -d**\ [\ *keycolname=keyvalue*\ ] [\ *tablename.colname=newvalue*\ ]
|
||||
\ **tabch -d**\ \ *keycolname=keyvalue*\ [,\ *keycolname=keyvalue*\ ,...] \ *tablename*\ [\ *tablename*\ ...]
|
||||
|
||||
|
||||
***********
|
||||
@@ -35,7 +35,7 @@ DESCRIPTION
|
||||
***********
|
||||
|
||||
|
||||
The tabch command adds, deletes or updates the attribute value in the specified table.column for the specified keyvalue. The difference between tabch and chtab is tabch runs as a plugin under the xcatd daemon. This give the additional security of being authorized by the daemon. Normally, the given value will completely replace the current attribute value. But if "+=" is used instead of "=", the specified value will be appended to the coma separated list of the attribute, if it is not already there.
|
||||
The \ **tabch**\ command adds, deletes or updates the attribute values in the specified table.column for the specified keyvalue. The difference between \ **tabch**\ and \ **chtab**\ is \ **tabch**\ runs as a plugin under the xcatd daemon. This give the additional security of being authorized by the daemon. Normally, the given value will completely replace the current attribute value. But if "+=" is used instead of "=", the specified value will be appended to the comma separated list of attributes, if it is not already there.
|
||||
|
||||
|
||||
*******
|
||||
|
||||
@@ -33,7 +33,7 @@ Stop xCAT Service
|
||||
|
||||
service xcatd stop
|
||||
|
||||
2. Stop xCAT related services(Optional)
|
||||
2. Stop xCAT related services (optional)
|
||||
|
||||
XCAT uses various network services on the management node and service nodes, the network services setup by xCAT may need to be cleaned up on the management node and service nodes before uninstalling xCAT.
|
||||
|
||||
@@ -48,128 +48,19 @@ Remove xCAT Files
|
||||
|
||||
1. Remove the xCAT RPMs
|
||||
|
||||
There is no easy way to distinct all the packages depending by xCAT. For packages shipped by xCAT, you can remove them by the commands below.
|
||||
There is no easy way to identify all xCAT packages. For packages shipped by xCAT, you can remove them by using the commands below.
|
||||
|
||||
[RHEL and SLES] ::
|
||||
|
||||
rpm -qa |grep -i xcat
|
||||
yum remove '*xcat*'
|
||||
yum remove '*xCAT*'
|
||||
|
||||
[Ubuntu] ::
|
||||
|
||||
dpkg -l | awk '/xcat/ { print $2 }'
|
||||
|
||||
If you want to remove more cleanly, the list below maybe helpful. Listed are the packages of xcat installation tarball. Some RPMs may not to be installed in a specific environment.
|
||||
To do an even more thorough cleanup, use links below to get a list of RPMs installed by xCAT. Some RPMs may not to be installed in a specific environment.
|
||||
|
||||
* XCAT Core Packages list (xcat-core):
|
||||
|
||||
[RHEL and SLES] ::
|
||||
|
||||
perl-xCAT
|
||||
xCAT
|
||||
xCAT-buildkit
|
||||
xCAT-client
|
||||
xCAT-confluent
|
||||
xCAT-genesis-scripts-ppc64
|
||||
xCAT-genesis-scripts-x86_64
|
||||
xCAT-server
|
||||
xCATsn
|
||||
xCAT-SoftLayer
|
||||
xCAT-test
|
||||
xCAT-vlan
|
||||
|
||||
[Ubuntu] ::
|
||||
|
||||
perl-xcat
|
||||
xcat
|
||||
xcat-buildkit
|
||||
xcat-client
|
||||
xcat-confluent
|
||||
xcat-genesis-scripts
|
||||
xcat-server
|
||||
xcatsn
|
||||
xcat-test
|
||||
xcat-vlan
|
||||
|
||||
* XCAT Dependency Packages (xcat-dep):
|
||||
|
||||
[RHEL and SLES] ::
|
||||
|
||||
conserver-xcat
|
||||
cpio
|
||||
cpio-lang
|
||||
elilo-xcat
|
||||
esxboot-xcat
|
||||
fping
|
||||
ganglia-devel
|
||||
ganglia-gmetad
|
||||
ganglia-gmond
|
||||
ganglia-gmond-modules-python
|
||||
ganglia-web
|
||||
grub2-xcat
|
||||
ipmitool-xcat
|
||||
libconfuse
|
||||
libconfuse-devel
|
||||
libganglia
|
||||
lldpd
|
||||
net-snmp-perl
|
||||
perl-AppConfig
|
||||
perl-Compress-Raw-Zlib
|
||||
perl-Crypt-Blowfish
|
||||
perl-Crypt-CBC
|
||||
perl-Crypt-Rijndael
|
||||
perl-Crypt-SSLeay
|
||||
perl-DBD-DB2
|
||||
perl-DBD-DB2Lite
|
||||
perl-DBD-Pg
|
||||
perl-DBD-SQLite
|
||||
perl-Expect
|
||||
perl-HTML-Form
|
||||
perl-IO-Compress-Base
|
||||
perl-IO-Compress-Zlib
|
||||
perl-IO-Socket-SSL
|
||||
perl-IO-Stty
|
||||
perl-IO-Tty
|
||||
perl-JSON
|
||||
perl-Net-DNS
|
||||
perl-Net-Telnet
|
||||
perl-SOAP-Lite
|
||||
perl-Test-Manifest
|
||||
perl-version
|
||||
perl-XML-Simple
|
||||
pyodbc
|
||||
rrdtool
|
||||
scsi-target-utils
|
||||
stunnel
|
||||
syslinux-xcat
|
||||
systemconfigurator
|
||||
systemimager-client
|
||||
systemimager-common
|
||||
systemimager-server
|
||||
xCAT-genesis-base-ppc64
|
||||
xCAT-genesis-base-x86_64
|
||||
xCAT-genesis-x86_64
|
||||
xCAT-UI-deps
|
||||
xnba-kvm
|
||||
xnba-undi
|
||||
yaboot-xcat
|
||||
zhcp
|
||||
|
||||
[Ubuntu] ::
|
||||
|
||||
conserver-xcat
|
||||
elilo-xcat
|
||||
grub2-xcat
|
||||
ipmitool-xcat
|
||||
syslinux
|
||||
syslinux-extlinux
|
||||
syslinux-xcat
|
||||
xcat-genesis-base-amd64
|
||||
xcat-genesis-base-ppc64
|
||||
xnba-undi
|
||||
|
||||
Along with xCAT development, above lists maybe change, you can get the latest list through below links:
|
||||
|
||||
|
||||
* XCAT Core Packages List (xcat-core)
|
||||
|
||||
[RHEL and SLES] ::
|
||||
@@ -178,31 +69,35 @@ Remove xCAT Files
|
||||
|
||||
[Ubuntu] ::
|
||||
|
||||
http://xcat.org/files/xcat/repos/apt/<version>/xcat-core/
|
||||
http://xcat.org/files/xcat/repos/apt/<version>/xcat-core/pool/main
|
||||
|
||||
* XCAT Dependency Packages (xcat-dep)
|
||||
|
||||
`RPM Packages List (RHEL and SLES) <http://xcat.org/files/xcat/repos/yum/xcat-dep/>`_
|
||||
|
||||
`Debian Packages List (Ubuntu) <http://xcat.org/files/xcat/repos/apt/xcat-dep/>`_
|
||||
|
||||
[RHEL and SLES] ::
|
||||
|
||||
http://xcat.org/files/xcat/repos/yum/xcat-dep/<os>/<arch>
|
||||
|
||||
Generally, we use ``yum install xCAT`` to install xCAT, so these are some RPMs shipped by operating system are installed during xCAT installation. We don't have an easy way to find out all of them, but keep these RPMs are harmless.
|
||||
[Ubuntu] ::
|
||||
|
||||
http://xcat.org/files/xcat/repos/apt/xcat-dep/pool/main
|
||||
|
||||
|
||||
When ``yum install xCAT`` is used to install xCAT, dependency RPMs provided by the Operating System will be installed. Keeping those rpms installed on the system is harmless.
|
||||
|
||||
|
||||
2. Remove xCAT certificate file ::
|
||||
|
||||
rm -rf /root/.xcat
|
||||
|
||||
3. Remove xCAT data file
|
||||
3. Remove xCAT data files
|
||||
|
||||
By default, xCAT use SQLite, remove SQLite data file under ``/etc/xcat/``. ::
|
||||
By default, xCAT uses SQLite, remove SQLite data files under ``/etc/xcat/``. ::
|
||||
|
||||
rm -rf /etc/xcat
|
||||
|
||||
4. Remove xCAT related file(Optional)
|
||||
4. Remove xCAT related files (optional)
|
||||
|
||||
XCAT has ever operated below directory when it was running. Do judgment by yourself before removing these directory, to avoid removing some directories used for other purpose in your environment. ::
|
||||
XCAT might have also created additional files and directories below. Take caution when removing these files as they may be used for other purposes in your environment. ::
|
||||
|
||||
/install
|
||||
/tftpboot
|
||||
|
||||
@@ -15,7 +15,7 @@ The following commands are currently supported:
|
||||
+----------------+-----------+-------------+----------------------------------+
|
||||
| rbeacon | Yes | 2.13.11 | |
|
||||
+----------------+-----------+-------------+----------------------------------+
|
||||
| rspconfig | No | | |
|
||||
| rspconfig | No | 2.14 | |
|
||||
+----------------+-----------+-------------+----------------------------------+
|
||||
| rsetboot | Yes | 2.13.11 | |
|
||||
+----------------+-----------+-------------+----------------------------------+
|
||||
@@ -23,7 +23,7 @@ The following commands are currently supported:
|
||||
+----------------+-----------+-------------+----------------------------------+
|
||||
| rflash | No | | |
|
||||
+----------------+-----------+-------------+----------------------------------+
|
||||
| reventlog | No | | |
|
||||
| reventlog | No | 2.14 | |
|
||||
+----------------+-----------+-------------+----------------------------------+
|
||||
|
||||
|
||||
|
||||
@@ -1311,7 +1311,7 @@ sub setobjdefs
|
||||
if (grep(/^$tempps$/, @xcatdefps)) {
|
||||
my $rsp;
|
||||
$rsp->{data}->[0] = "$obj: postscripts \'$tempps\' is already included in the \'xcatdefaults\'.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::callback);
|
||||
xCAT::MsgUtils->message("W", $rsp, $::callback);
|
||||
} else {
|
||||
push @newps, $tempps;
|
||||
}
|
||||
@@ -1325,7 +1325,7 @@ sub setobjdefs
|
||||
if (grep(/^$temppbs$/, @xcatdefpbs)) {
|
||||
my $rsp;
|
||||
$rsp->{data}->[0] = "$obj: postbootscripts \'$temppbs\' is already included in the \'xcatdefaults\'.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::callback);
|
||||
xCAT::MsgUtils->message("W", $rsp, $::callback);
|
||||
} else {
|
||||
push @newpbs, $temppbs;
|
||||
}
|
||||
|
||||
+45
-21
@@ -22,6 +22,8 @@ use xCAT::MsgUtils;
|
||||
use xCAT::Utils;
|
||||
use xCAT::TableUtils;
|
||||
use xCAT::NodeRange;
|
||||
use xCAT::DSHCLI;
|
||||
use Data::Dumper;
|
||||
use lib '/opt/xcat/xdsh';
|
||||
our @dsh_available_contexts = ();
|
||||
our @dsh_valid_contexts = ();
|
||||
@@ -922,6 +924,7 @@ sub fork_fanout_dcp
|
||||
$dsh_trace
|
||||
&& (xCAT::MsgUtils->message("I", $rsp, $::CALLBACK));
|
||||
|
||||
|
||||
my @process_info =
|
||||
xCAT::DSHCore->fork_output($user_target, @dcp_command);
|
||||
vec($$outfh_targets{'bitmap'}, fileno($process_info[1]), 1) = 1;
|
||||
@@ -1329,7 +1332,7 @@ sub fork_fanout_dsh
|
||||
#print "Command=@dsh_command\n";
|
||||
|
||||
#@process_info = xCAT::DSHCore->fork_output($user_target, @dsh_command);
|
||||
push(@commands, \@dsh_command); #print Dumper(\@commands);
|
||||
push(@commands, \@dsh_command);
|
||||
@process_info = xCAT::DSHCore->fork_output_for_commands($user_target, @commands);
|
||||
if ($process_info[0] == -2)
|
||||
{
|
||||
@@ -4531,15 +4534,6 @@ sub parse_and_run_dcp
|
||||
}
|
||||
}
|
||||
|
||||
# invalid to put the -F with the -r flag
|
||||
if ($options{'File'} && $options{'node-rcp'})
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"If -F option is use, then -r is invalid. The command will always the rsync using ssh.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
# invalid to put the -s without the -F flag
|
||||
if (!($options{'File'}) && $options{'rsyncSN'})
|
||||
@@ -4566,22 +4560,31 @@ sub parse_and_run_dcp
|
||||
}
|
||||
|
||||
}
|
||||
elsif ($^O eq 'linux')
|
||||
elsif (($^O eq 'linux') and !$options{'node-rcp'})
|
||||
{
|
||||
$options{'node-rcp'} = '/usr/bin/rsync';
|
||||
}
|
||||
}
|
||||
my $remotecopycommand = $options{'node-rcp'};
|
||||
if ($options{'node-rcp'}
|
||||
&& (!-f $options{'node-rcp'} || !-x $options{'node-rcp'}))
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"Remote command: $remotecopycommand does not exist or is not executable.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
my $remotecopycommand = $options{'node-rcp'};
|
||||
if ($options{'node-rcp'}) {
|
||||
if (!-f $options{'node-rcp'} || !-x $options{'node-rcp'})
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"Remote command: $remotecopycommand does not exist or is not executable.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($remotecopycommand !~ /\/(rcp|scp|rsync)$/){
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"Remote command: $remotecopycommand is invalid, the support remote commands: scp,rcp,rsync.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#
|
||||
# build list of nodes
|
||||
my @nodelist;
|
||||
@@ -4673,6 +4676,7 @@ sub parse_and_run_dcp
|
||||
{
|
||||
$::SYNCSN = 1;
|
||||
}
|
||||
|
||||
|
||||
# the parsing of the file will fill in an array of postscripts
|
||||
# need to be run if the associated file is updated
|
||||
@@ -4726,6 +4730,7 @@ sub parse_and_run_dcp
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] = "Error parsing the rsync file:$syncfile.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
|
||||
$::FAILED_NODES=scalar @nodelist;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5067,6 +5072,7 @@ sub parse_rsync_input_file_on_MN
|
||||
my $addappendscript = 0;
|
||||
open(INPUTFILE, "< $input_file") || die "File $input_file does not exist\n";
|
||||
|
||||
|
||||
while (my $line = <INPUTFILE>)
|
||||
{
|
||||
chomp $line;
|
||||
@@ -5284,6 +5290,15 @@ sub parse_rsync_input_file_on_MN
|
||||
{
|
||||
$$options{'nodes'} = join ',', keys %{ $$options{'destDir_srcFile'} };
|
||||
}
|
||||
|
||||
my $remotecopycommand=$$options{'node-rcp'};
|
||||
if($remotecopycommand !~ /\/rsync$/ and @::postscripts){
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] ="key word 'EXECUTE' is unavailable when the remote copy command specified by '-r|--node-rcp' is $remotecopycommand. Does 'EXECUTEALWAYS' work for you?";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5780,6 +5795,15 @@ sub parse_rsync_input_file_on_SN
|
||||
{
|
||||
$$options{'nodes'} = join ',', keys %{ $$options{'destDir_srcFile'} };
|
||||
}
|
||||
|
||||
my $remotecopycommand=$$options{'node-rcp'};
|
||||
if($remotecopycommand !~ /\/rsync$/ and @::postscripts){
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] ="key word 'EXECUTE' is unavailable when the remote copy command specified by '-r|--node-rcp' is $remotecopycommand. Does 'EXECUTEALWAYS' work for you?";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+79
-26
@@ -5,7 +5,6 @@ package xCAT::SSH;
|
||||
|
||||
# cannot use strict
|
||||
use base xCAT::DSHRemoteShell;
|
||||
|
||||
# Determine if OS is AIX or Linux
|
||||
# Configure standard locations of commands based on OS
|
||||
|
||||
@@ -136,33 +135,87 @@ sub remote_copy_command {
|
||||
my @src_files = ();
|
||||
my @dest_file = ();
|
||||
|
||||
my @src_file_list = split $::__DCP_DELIM, $$config{'src-file'};
|
||||
if ($$config{'destDir_srcFile'}){
|
||||
my $dest_dir_list = join ' ', keys %{ $$config{'destDir_srcFile'} };
|
||||
my $dest_user_host = $$config{'dest-host'};
|
||||
if ($::SYNCSN == 1)
|
||||
{ # syncing service node
|
||||
#todo
|
||||
$scpfile = "/tmp/scp_$$config{'dest-host'}";
|
||||
}
|
||||
else
|
||||
{
|
||||
$scpfile = "/tmp/scp_$$config{'dest-host'}";
|
||||
}
|
||||
|
||||
open SCPCMDFILE, "> $scpfile"
|
||||
or die "Can not open file $scpfile";
|
||||
if ($$config{'dest-user'})
|
||||
{
|
||||
$dest_user_host =
|
||||
"$$config{'dest-user'}@" . "$$config{'dest-host'}";
|
||||
}
|
||||
if ($$config{'trace'}) {
|
||||
print SCPCMDFILE "#!/bin/sh -x\n";
|
||||
} else {
|
||||
print SCPCMDFILE "#!/bin/sh\n";
|
||||
}
|
||||
|
||||
foreach $src_file (@src_file_list) {
|
||||
my @src_path = ();
|
||||
$$config{'src-user'} && push @src_path, "$$config{'src-user'}@";
|
||||
$$config{'src-host'} && push @src_path, "$$config{'src-host'}:";
|
||||
$$config{'src-file'} && push @src_path, $src_file;
|
||||
push @src_files, (join '', @src_path);
|
||||
print SCPCMDFILE
|
||||
"/usr/bin/ssh $dest_user_host '/bin/mkdir -p $dest_dir_list'\n";
|
||||
|
||||
foreach my $dest_dir (keys %{ $$config{'destDir_srcFile'} }){
|
||||
if($$config{'destDir_srcFile'}{$dest_dir}{'same_dest_name'}){
|
||||
my @src_file =
|
||||
@{ $$config{'destDir_srcFile'}{$dest_dir}{'same_dest_name'} };
|
||||
my $src_file_list = join ' ', @src_file;
|
||||
print SCPCMDFILE
|
||||
"$exec_path -p -r $src_file_list $dest_user_host:$dest_dir\n";
|
||||
}
|
||||
|
||||
if($$config{'destDir_srcFile'}{$dest_dir}{'diff_dest_name'}){
|
||||
my %diff_dest_hash =
|
||||
%{ $$config{'destDir_srcFile'}{$dest_dir}{'diff_dest_name'} };
|
||||
foreach my $src_file_diff_dest (keys %diff_dest_hash)
|
||||
{
|
||||
my $diff_basename = $diff_dest_hash{$src_file_diff_dest};
|
||||
print SCPCMDFILE
|
||||
"$exec_path -p -r $src_file_diff_dest $dest_user_host:$dest_dir/$diff_basename\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close SCPCMDFILE;
|
||||
chmod 0755, $scpfile;
|
||||
@command = ('/bin/sh', '-c', $scpfile);
|
||||
}else{
|
||||
my @src_file_list = split $::__DCP_DELIM, $$config{'src-file'};
|
||||
|
||||
foreach $src_file (@src_file_list) {
|
||||
my @src_path = ();
|
||||
$$config{'src-user'} && push @src_path, "$$config{'src-user'}@";
|
||||
$$config{'src-host'} && push @src_path, "$$config{'src-host'}:";
|
||||
$$config{'src-file'} && push @src_path, $src_file;
|
||||
push @src_files, (join '', @src_path);
|
||||
}
|
||||
|
||||
$$config{'dest-user'} && push @dest_file, "$$config{'dest-user'}@";
|
||||
$$config{'dest-host'} && push @dest_file, "$$config{'dest-host'}:";
|
||||
$$config{'dest-file'} && push @dest_file, $$config{'dest-file'};
|
||||
|
||||
push @command, $exec_path;
|
||||
$$config{'preserve'} && push @command, '-p';
|
||||
$$config{'recursive'} && push @command, '-r';
|
||||
|
||||
if ($$config{'options'}) {
|
||||
my @options = split ' ', $$config{'options'};
|
||||
push @command, @options;
|
||||
}
|
||||
|
||||
($ssh_version eq 'OpenSSH') && push @command, '-B';
|
||||
push @command, @src_files;
|
||||
push @command, (join '', @dest_file);
|
||||
}
|
||||
|
||||
$$config{'dest-user'} && push @dest_file, "$$config{'dest-user'}@";
|
||||
$$config{'dest-host'} && push @dest_file, "$$config{'dest-host'}:";
|
||||
$$config{'dest-file'} && push @dest_file, $$config{'dest-file'};
|
||||
|
||||
push @command, $exec_path;
|
||||
$$config{'preserve'} && push @command, '-p';
|
||||
$$config{'recursive'} && push @command, '-r';
|
||||
|
||||
if ($$config{'options'}) {
|
||||
my @options = split ' ', $$config{'options'};
|
||||
push @command, @options;
|
||||
}
|
||||
|
||||
($ssh_version eq 'OpenSSH') && push @command, '-B';
|
||||
push @command, @src_files;
|
||||
push @command, (join '', @dest_file);
|
||||
|
||||
return @command;
|
||||
}
|
||||
|
||||
|
||||
@@ -890,7 +890,7 @@ passed as argument rather than by table value',
|
||||
noderange => 'The Noderange that this rule applies to. Default is "*" (all nodes). Not supported with the *def commands.',
|
||||
parameters => 'A regular expression that matches the command parameters (everything except the noderange) that this rule applies to. Default is "*" (all parameters). Not supported with the *def commands.',
|
||||
time => 'Time ranges that this command may be executed in. This is not supported.',
|
||||
rule => 'Specifies how this rule should be applied. Valid values are: allow, accept, trusted. Allow or accept will allow the user to run the commands. Any other value will deny the user access to the commands. Trusted means that once this client has been authenticated via the certificate, all other information that is sent (e.g. the username) is believed without question. This authorization should only be given to the xcatd on the management node at this time.',
|
||||
rule => 'Specifies how this rule should be applied. Valid values are: allow, trusted. Allow will allow the user to run the commands. Any other value will deny the user access to the commands. Trusted means that once this client has been authenticated via the certificate, all other information that is sent (e.g. the username) is believed without question. This authorization should only be given to the xcatd on the management node at this time.',
|
||||
comments => 'Any user-written notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
},
|
||||
@@ -998,15 +998,15 @@ passed as argument rather than by table value',
|
||||
"DATABASE ATTRIBUTES\n" .
|
||||
" -----------------\n" .
|
||||
" auditnosyslog: If set to 1, then commands will only be written to the auditlog table.\n" .
|
||||
" This attribute set to 1 and auditskipcmds=ALL means no logging of commands.\n" .
|
||||
" If this attribute is set to 1 and auditskipcmds=ALL means no logging of commands.\n" .
|
||||
" Default is to write to both the auditlog table and syslog.\n" .
|
||||
" auditskipcmds: List of commands and/or client types that will not be\n" .
|
||||
" written to the auditlog table and syslog. See auditnosyslog.\n" .
|
||||
" 'ALL' means all cmds will be skipped. If attribute is null, all\n" .
|
||||
" commands will be written.\n" .
|
||||
" commands will be written.\n" .
|
||||
" clienttype:web would skip all commands from the web client\n" .
|
||||
" For example: tabdump,nodels,clienttype:web \n" .
|
||||
" will not log tabdump,nodels and any web client commands.\n\n" .
|
||||
" For example: tabdump,nodels,clienttype:web \n" .
|
||||
" will not log tabdump, nodels or any web client commands.\n" .
|
||||
" databaseloc: Directory where we create the db instance directory.\n" .
|
||||
" Default is /var/lib. Only DB2 is currently supported.\n" .
|
||||
" Do not use the directory in the site.installloc or\n" .
|
||||
@@ -1285,6 +1285,8 @@ passed as argument rather than by table value',
|
||||
" --------------------\n" .
|
||||
"XCAT DAEMON ATTRIBUTES\n" .
|
||||
" --------------------\n" .
|
||||
" tokenexpiredays: Number of days before REST API token will expire. The default is 1.\n" .
|
||||
" use 'never' if you want your token to never expire.\n" .
|
||||
" useflowcontrol: (yes/1 or no/0). If yes, the postscript processing on each node\n" .
|
||||
" contacts xcatd on the MN/SN using a lightweight UDP packet to wait\n" .
|
||||
" until xcatd is ready to handle the requests associated with\n" .
|
||||
@@ -1448,8 +1450,8 @@ passed as argument rather than by table value',
|
||||
audittime => 'The timestamp for the audit entry.',
|
||||
userid => 'The user running the command.',
|
||||
clientname => 'The client machine, where the command originated.',
|
||||
clienttype => 'Type of command: cli,java,webui,other.',
|
||||
command => 'Command executed.',
|
||||
clienttype => 'Type of command: cli, java, webui, other.',
|
||||
command => 'Command executed. See auditskipcmds site table attribute to control which commands get logged.',
|
||||
noderange => 'The noderange on which the command was run.',
|
||||
args => 'The command argument list.',
|
||||
status => 'Allowed or Denied.',
|
||||
@@ -1802,13 +1804,15 @@ zvmivp => {
|
||||
},
|
||||
},
|
||||
token => {
|
||||
cols => [qw(tokenid username expire comments disable)],
|
||||
cols => [qw(tokenid username expire created access comments disable)],
|
||||
keys => [qw(tokenid)],
|
||||
table_desc => 'The token of users for authentication.',
|
||||
descriptions => {
|
||||
tokenid => 'It is a UUID as an unified identify for the user.',
|
||||
username => 'The user name.',
|
||||
expire => 'The expire time for this token.',
|
||||
created => 'Creation time for this token.',
|
||||
access => 'Last access time for this token.',
|
||||
comments => 'Any user-provided notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
},
|
||||
|
||||
@@ -351,7 +351,7 @@ sub init_dbworker {
|
||||
xCAT::MsgUtils->message("S", "xcatd: possible BUG encountered by xCAT DB worker " . $err);
|
||||
if ($currcon) {
|
||||
eval { #avoid hang by allowin client to die too
|
||||
store_fd("*XCATBUGDETECTED*:$err:*XCATBUGDETECTED*\n", $currcon);
|
||||
store_fd(["*XCATBUGDETECTED*:$err:*XCATBUGDETECTED*\n"], $currcon);
|
||||
$clientset->remove($currcon);
|
||||
close($currcon);
|
||||
};
|
||||
|
||||
@@ -136,7 +136,7 @@ my %usage = (
|
||||
",
|
||||
"rinv.openbmc" =>
|
||||
"OpenPOWER (OpenBMC) server specific:
|
||||
rinv <noderange> [model|serial|firm|cpu|dimm|all] [-V|--verbose]
|
||||
rinv <noderange> [model][serial][firm][cpu][dimm][all] [-V|--verbose]
|
||||
",
|
||||
"rinv.end" =>
|
||||
"PPC specific(with HMC):
|
||||
@@ -500,7 +500,7 @@ my %usage = (
|
||||
or
|
||||
updatenode <noderange> [-V|--verbose] [-k|--security] [-s|--sn] [-t <timeout>]
|
||||
or
|
||||
updatenode <noderange> [-V|--verbose] [-F|--sync | -f|--snsync] [-l|--user[username]] [--fanout=[fanout value]] [-S|--sw] [-t <timeout>]
|
||||
updatenode <noderange> [-V|--verbose] [-F|--sync | -f|--snsync] [-r|--node-rcp <node_remote_copy>] [-l|--user[username]] [--fanout=[fanout value]] [-S|--sw] [-t <timeout>]
|
||||
[-P|--scripts [script1,script2,...]] [-s|--sn]
|
||||
[-A|--updateallsw] [-c|--cmdlineonly] [-d alt_source_dir]
|
||||
[attr=val [attr=val...]]
|
||||
@@ -520,7 +520,9 @@ Options:
|
||||
|
||||
[-f|--snsync] Performs File Syncing to the service nodes that service
|
||||
the nodes in the noderange.
|
||||
|
||||
|
||||
[-r|--node-rcp] Specifies the full path of the remote copy command used for sync files to node targets, such as /usr/bin/rsync and /usr/bin/scp
|
||||
|
||||
[-g|--genmypost] Will generate a new mypostscript file for the
|
||||
the nodes in the noderange, if site precreatemypostscripts is 1 or YES.
|
||||
|
||||
@@ -616,7 +618,6 @@ $usage{"rspconfig.openbmc"} = $usage{"rspconfig.common"} .
|
||||
$usage{"rinv"} = $usage{"rinv.common"} .
|
||||
$usage{"rinv.begin"} .
|
||||
$usage{"rinv.openbmc"} .
|
||||
" " .
|
||||
$usage{"rinv.end"};
|
||||
|
||||
$usage{"rinv.openbmc"} = $usage{"rinv.common"} .
|
||||
@@ -632,7 +633,6 @@ $usage{"rbeacon.openbmc"} = $usage{"rbeacon.common"} .
|
||||
$usage{"rvitals"} = $usage{"rvitals.common"} .
|
||||
$usage{"rvitals.begin"} .
|
||||
$usage{"rvitals.openbmc"} .
|
||||
" " .
|
||||
$usage{"rvitals.end"};
|
||||
|
||||
$usage{"rvitals.openbmc"} = $usage{"rvitals.common"} .
|
||||
@@ -650,7 +650,6 @@ $usage{"rflash.openbmc"} = $usage{"rflash.common"} .
|
||||
$usage{"rpower"} = $usage{"rpower.common"} .
|
||||
$usage{"rpower.begin"} .
|
||||
$usage{"rpower.openbmc"} .
|
||||
" " .
|
||||
$usage{"rpower.end"};
|
||||
|
||||
$usage{"rpower.openbmc"} = $usage{"rpower.common"} .
|
||||
|
||||
@@ -3894,6 +3894,42 @@ sub gettimezone
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 time2string
|
||||
Return passed in time (in DateTime format) as a string in YYYY/MM/DD HH:MM:SS format
|
||||
Arguments:
|
||||
Unix DateTime as returned by time() for example
|
||||
Optional Separator character for date, default is "/"
|
||||
Returns:
|
||||
String in YYYY/MM/DD HH:MM:SS format
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
None
|
||||
Example:
|
||||
my $time_string = xCAT::Utils->time2string($time,"-");
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub time2string
|
||||
{
|
||||
my $unixtime = shift;
|
||||
my $date_separator;
|
||||
if ($unixtime =~ /xCAT::Utils/)
|
||||
{
|
||||
$unixtime = shift;
|
||||
$date_separator = shift // "/"; # Optional date separator, if not specified, default to "/"
|
||||
}
|
||||
my $time_separator = ":";
|
||||
|
||||
my ($sec, $min, $hour, $mday, $mon, $year) = localtime($unixtime);
|
||||
$year += 1900;
|
||||
$mon += 1;
|
||||
return $year . $date_separator . $mon . $date_separator . $mday . " " . $hour . $time_separator . $min . $time_separator . $sec;
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 specialservicemgr
|
||||
some special services cannot be processed in sysVinit, upstart and systemd framework, should be process here...
|
||||
Arguments:
|
||||
|
||||
@@ -21,14 +21,16 @@ $Term::ANSIColor::AUTORESET = 1;
|
||||
|
||||
#---Global attributes---
|
||||
my $rst = 0;
|
||||
my $retries = 5; # Try this many times to get response
|
||||
my $check_result_str="``CI CHECK RESULT`` : ";
|
||||
my $last_func_start = timelocal(localtime());
|
||||
my $GITHUB_API = "https://api.github.com";
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: runcmd
|
||||
# Description: run a command after 'cmd' label in one case
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
# Attributes:
|
||||
# Return code:
|
||||
# $::RUNCMD_RC : the return code of command
|
||||
# @$outref : the output of command
|
||||
#--------------------------------------------------------
|
||||
@@ -53,12 +55,12 @@ sub runcmd
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: get_files_recursive
|
||||
# Description: Search all file in one directory recursively
|
||||
# Atrributes:
|
||||
# Attributes:
|
||||
# $dir (input attribute)
|
||||
# The target scan directory
|
||||
# $files_path_ref (output attribute)
|
||||
# the reference of array where save all vaild files under $dir
|
||||
# Retrun code:
|
||||
# Return code:
|
||||
#--------------------------------------------------------
|
||||
sub get_files_recursive
|
||||
{
|
||||
@@ -91,13 +93,29 @@ sub get_files_recursive
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: check_pr_format
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
# Attributes:
|
||||
# Return code:
|
||||
#--------------------------------------------------------
|
||||
sub check_pr_format{
|
||||
if($ENV{'TRAVIS_EVENT_TYPE'} eq "pull_request"){
|
||||
my $pr_url = "https://api.github.com/repos/$ENV{'TRAVIS_REPO_SLUG'}/pulls/$ENV{'TRAVIS_PULL_REQUEST'}";
|
||||
my $pr_url_resp = get($pr_url);
|
||||
my $pr_url = "$GITHUB_API/repos/$ENV{'TRAVIS_REPO_SLUG'}/pulls/$ENV{'TRAVIS_PULL_REQUEST'}";
|
||||
my $pr_url_resp;
|
||||
my $counter = 1;
|
||||
while($counter <= $retries) {
|
||||
$pr_url_resp = get($pr_url);
|
||||
if ($pr_url_resp) {
|
||||
last; # Got response, no more retries
|
||||
} else {
|
||||
sleep($counter*2); # Sleep and try again
|
||||
print "[check_pr_format] $counter Did not get response, sleeping ". $counter*2 . "\n";
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
unless ($pr_url_resp) {
|
||||
print "[check_pr_format] After $retries retries, not able to get response from $pr_url \n";
|
||||
# Failed after trying a few times, return error
|
||||
return 1;
|
||||
}
|
||||
my $pr_content = decode_json($pr_url_resp);
|
||||
my $pr_title = $pr_content->{title};
|
||||
my $pr_body = $pr_content->{body};
|
||||
@@ -111,20 +129,23 @@ sub check_pr_format{
|
||||
|
||||
my $checkrst="";
|
||||
if(! $pr_title){
|
||||
$checkrst.="Miss title.";
|
||||
$checkrst.="Missing title.";
|
||||
}
|
||||
if(! $pr_body){
|
||||
$checkrst.="Miss description.";
|
||||
$checkrst.="Missing description.";
|
||||
}
|
||||
|
||||
if(! $pr_milestone){
|
||||
$checkrst.="Miss milestone.";
|
||||
$checkrst.="Missing milestone.";
|
||||
}
|
||||
|
||||
if(! $pr_labels_len){
|
||||
$checkrst.="Miss labels.";
|
||||
$checkrst.="Missing labels.";
|
||||
}
|
||||
|
||||
# Guard against root user making commits
|
||||
$checkrst.=check_commit_owner('root');
|
||||
|
||||
if(length($checkrst) == 0){
|
||||
$check_result_str .= "> **PR FORMAT CORRECT**";
|
||||
send_back_comment("$check_result_str");
|
||||
@@ -143,22 +164,89 @@ sub check_pr_format{
|
||||
}
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: check_pr_format
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
# Fuction name: check_commit_owner
|
||||
# Description: Verify commits are not done by specified user
|
||||
# Attributes: user login to reject
|
||||
# Return:
|
||||
# Error string -User rejected,
|
||||
# Empty string -User not rejected
|
||||
#--------------------------------------------------------
|
||||
sub check_commit_owner{
|
||||
my $invalid_user = shift;
|
||||
if($ENV{'TRAVIS_EVENT_TYPE'} eq "pull_request"){
|
||||
my $commits_content;
|
||||
my $commits_len = 0;
|
||||
my $json = new JSON;
|
||||
my $commits_url = "$GITHUB_API/repos/$ENV{'TRAVIS_REPO_SLUG'}/pulls/$ENV{'TRAVIS_PULL_REQUEST'}/commits";
|
||||
my $commits_url_resp;
|
||||
my $counter = 1;
|
||||
while($counter <= $retries) {
|
||||
$commits_url_resp = get($commits_url);
|
||||
if ($commits_url_resp) {
|
||||
last; # Got response, no more retries
|
||||
} else {
|
||||
sleep($counter*2); # Sleep and try again
|
||||
print "[check_commit_owner] $counter Did not get response, sleeping ". $counter*2 . "\n";
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
if ($commits_url_resp) {
|
||||
$commits_content = $json->decode($commits_url_resp);
|
||||
$commits_len = @$commits_content;
|
||||
} else {
|
||||
print "[check_commit_owner] After $retries retries, not able to get response from $commits_url \n";
|
||||
return "Unable to verify login of committer.";
|
||||
}
|
||||
|
||||
if($commits_len > 0) {
|
||||
foreach my $commit (@{$commits_content}){
|
||||
my $committer = $commit->{committer};
|
||||
my $committer_login = $committer->{login};
|
||||
print "[check_commit_owner] Committer login $committer_login \n";
|
||||
if($committer_login =~ /^$invalid_user$/) {
|
||||
# Committer logins matches
|
||||
return "Commits by $invalid_user not allowed";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: send_back_comment
|
||||
# Description: Append to comment of the PR passed $message
|
||||
# Attributes: Message to append to PR
|
||||
# Return code:
|
||||
#--------------------------------------------------------
|
||||
sub send_back_comment{
|
||||
my $message = shift;
|
||||
|
||||
my $comment_url = "https://api.github.com/repos/$ENV{'TRAVIS_REPO_SLUG'}/issues/$ENV{'TRAVIS_PULL_REQUEST'}/comments";
|
||||
my $comment_url_resp = get($comment_url);
|
||||
my $comment_url = "$GITHUB_API/repos/$ENV{'TRAVIS_REPO_SLUG'}/issues/$ENV{'TRAVIS_PULL_REQUEST'}/comments";
|
||||
my $json = new JSON;
|
||||
my $comment_content = $json->decode($comment_url_resp);
|
||||
my $comment_len = @$comment_content;
|
||||
my $comment_len = 0;
|
||||
my $comment_content;
|
||||
my $comment_url_resp;
|
||||
my $counter = 1;
|
||||
while($counter <= $retries) {
|
||||
$comment_url_resp = get($comment_url);
|
||||
if ($comment_url_resp) {
|
||||
last; # Got response, no more retries
|
||||
} else {
|
||||
sleep($counter*2); # Sleep and try again
|
||||
print "[send_back_comment] $counter Did not get response, sleeping ". $counter*2 . "\n";
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
unless ($comment_url_resp) {
|
||||
print "[send_back_comment] After $retries retries, not able to get response from $comment_url \n";
|
||||
# Failed after trying a few times, return
|
||||
return;
|
||||
}
|
||||
print "\n\n>>>>>Dumper comment_url_resp:\n";
|
||||
print Dumper $comment_url_resp;
|
||||
|
||||
#print "\n\n>>>>>Dumper comment_content: $comment_len\n";
|
||||
#print Dumper $comment_content;
|
||||
$comment_content = $json->decode($comment_url_resp);
|
||||
$comment_len = @$comment_content;
|
||||
|
||||
my $post_url = $comment_url;
|
||||
my $post_method = "POST";
|
||||
@@ -178,15 +266,15 @@ sub send_back_comment{
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: build_xcat_core
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
# Attributes:
|
||||
# Return code:
|
||||
#--------------------------------------------------------
|
||||
sub build_xcat_core{
|
||||
my @output;
|
||||
my @cmds = ("gpg --list-keys",
|
||||
"sed -i '/SignWith: yes/d' $ENV{'PWD'}/build-ubunturepo");
|
||||
foreach my $cmd (@cmds){
|
||||
print "[build_xcat_core] to run $cmd\n";
|
||||
print "[build_xcat_core] running $cmd\n";
|
||||
@output = runcmd("$cmd");
|
||||
if($::RUNCMD_RC){
|
||||
print "[build_xcat_core] $cmd ....[Failed]\n";
|
||||
@@ -226,8 +314,8 @@ sub build_xcat_core{
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: install_xcat
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
# Attributes:
|
||||
# Return code:
|
||||
#--------------------------------------------------------
|
||||
sub install_xcat{
|
||||
|
||||
@@ -239,7 +327,7 @@ sub install_xcat{
|
||||
"sudo apt-get -qq update");
|
||||
my @output;
|
||||
foreach my $cmd (@cmds){
|
||||
print "[install_xcat] to run $cmd\n";
|
||||
print "[install_xcat] running $cmd\n";
|
||||
@output = runcmd("$cmd");
|
||||
if($::RUNCMD_RC){
|
||||
print RED "[install_xcat] $cmd. ...[Failed]\n";
|
||||
@@ -267,7 +355,7 @@ sub install_xcat{
|
||||
}else{
|
||||
print "[install_xcat] $cmd ....[Pass]\n";
|
||||
|
||||
print "\n------To config xcat and check if xcat work correctly-----\n";
|
||||
print "\n------Config xcat and verify xcat is working correctly-----\n";
|
||||
@cmds = ("sudo -s /opt/xcat/share/xcat/scripts/setup-local-client.sh -f travis",
|
||||
"sudo -s /opt/xcat/sbin/chtab priority=1.1 policy.name=travis policy.rule=allow",
|
||||
". /etc/profile.d/xcat.sh && tabdump policy",
|
||||
@@ -277,7 +365,7 @@ sub install_xcat{
|
||||
"service xcatd status");
|
||||
my $ret = 0;
|
||||
foreach my $cmd (@cmds){
|
||||
print "\n[install_xcat] To run $cmd.....\n";
|
||||
print "\n[install_xcat] running $cmd.....\n";
|
||||
@output = runcmd("$cmd");
|
||||
print Dumper \@output;
|
||||
if($::RUNCMD_RC){
|
||||
@@ -303,8 +391,8 @@ sub install_xcat{
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: check_syntax
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
# Attributes:
|
||||
# Return code:
|
||||
#--------------------------------------------------------
|
||||
sub check_syntax{
|
||||
my @output;
|
||||
@@ -356,8 +444,8 @@ sub check_syntax{
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: run_fast_regression_test
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
# Attributes:
|
||||
# Return code:
|
||||
#--------------------------------------------------------
|
||||
sub run_fast_regression_test{
|
||||
my $cmd = "sudo apt-get install xcat-test --force-yes";
|
||||
@@ -428,11 +516,11 @@ sub run_fast_regression_test{
|
||||
|
||||
if($failnum){
|
||||
my $log_str = join (",", @failcase );
|
||||
$check_result_str .= "> **FAST REGRESSION TEST Failed**: Totalcase $casenum Pass $passnum failed $failnum FailedCases: $log_str. Please click ``Details`` label in ``Merge pull request`` box for detailed information";
|
||||
$check_result_str .= "> **FAST REGRESSION TEST Failed**: Totalcase $casenum Passed $passnum Failed $failnum FailedCases: $log_str. Please click ``Details`` label in ``Merge pull request`` box for detailed information";
|
||||
send_back_comment("$check_result_str");
|
||||
return 1;
|
||||
}else{
|
||||
$check_result_str .= "> **FAST REGRESSION TEST Successful**: Totalcase $casenum Pass $passnum failed $failnum";
|
||||
$check_result_str .= "> **FAST REGRESSION TEST Successful**: Totalcase $casenum Passed $passnum Failed $failnum";
|
||||
send_back_comment("$check_result_str");
|
||||
}
|
||||
|
||||
@@ -440,10 +528,10 @@ sub run_fast_regression_test{
|
||||
}
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Fuction name: run_fast_regression_test
|
||||
# Fuction name: mark_time
|
||||
# Description:
|
||||
# Atrributes:
|
||||
# Retrun code:
|
||||
# Attributes:
|
||||
# Return code:
|
||||
#--------------------------------------------------------
|
||||
sub mark_time{
|
||||
my $func_name=shift;
|
||||
@@ -457,7 +545,7 @@ sub mark_time{
|
||||
#===============Main Process=============================
|
||||
|
||||
#Dumper Travis Environment Attribute
|
||||
print GREEN "\n------Dumper Travis Environment Attribute------\n";
|
||||
print GREEN "\n------ Travis Environment Attributes ------\n";
|
||||
my @travis_env_attr = ("TRAVIS_REPO_SLUG",
|
||||
"TRAVIS_BRANCH",
|
||||
"TRAVIS_EVENT_TYPE",
|
||||
@@ -492,47 +580,47 @@ print Dumper \@disk;
|
||||
|
||||
#Start to check the format of pull request
|
||||
$last_func_start = timelocal(localtime());
|
||||
print GREEN "\n------To Check Pull Request Format------\n";
|
||||
print GREEN "\n------ Checking Pull Request Format ------\n";
|
||||
$rst = check_pr_format();
|
||||
if($rst){
|
||||
print RED "Check pull request format failed\n";
|
||||
print RED "Check of pull request format failed\n";
|
||||
exit $rst;
|
||||
}
|
||||
mark_time("check_pr_format");
|
||||
|
||||
#Start to build xcat core
|
||||
|
||||
print GREEN "\n------To Build xCAT core package------\n";
|
||||
print GREEN "\n------ Building xCAT core package ------\n";
|
||||
$rst = build_xcat_core();
|
||||
if($rst){
|
||||
print RED "Build xCAT core package failed\n";
|
||||
print RED "Build of xCAT core package failed\n";
|
||||
exit $rst;
|
||||
}
|
||||
mark_time("build_xcat_core");
|
||||
|
||||
#Start to install xcat
|
||||
print GREEN "\n------To install xcat------\n";
|
||||
print GREEN "\n------Installing xCAT ------\n";
|
||||
$rst = install_xcat();
|
||||
if($rst){
|
||||
print RED "Install xcat failed\n";
|
||||
print RED "Install of xCAT failed\n";
|
||||
exit $rst;
|
||||
}
|
||||
mark_time("install_xcat");
|
||||
|
||||
#Check the syntax of changing code
|
||||
print GREEN "\n------To check the syntax of changing code------\n";
|
||||
print GREEN "\n------ Checking the syntax of changed code------\n";
|
||||
$rst = check_syntax();
|
||||
if($rst){
|
||||
print RED "check the syntax of changing code failed\n";
|
||||
print RED "Check syntax of changed code failed\n";
|
||||
exit $rst;
|
||||
}
|
||||
mark_time("check_syntax");
|
||||
|
||||
#run fast regression
|
||||
print GREEN "\n------To run fast regression test------\n";
|
||||
print GREEN "\n------Running fast regression test ------\n";
|
||||
$rst = run_fast_regression_test();
|
||||
if($rst){
|
||||
print RED "Run fast regression test failed\n";
|
||||
print RED "Run of fast regression test failed\n";
|
||||
exit $rst;
|
||||
}
|
||||
mark_time("run_fast_regression_test");
|
||||
|
||||
@@ -56,7 +56,7 @@ if (!($tmp =~ / (--help|-h|-v|--version)/)) {
|
||||
my $arg = shift(@ARGV);
|
||||
|
||||
# Set the noderange
|
||||
if ($arg !~ /^-/) {
|
||||
if ($arg and $arg !~ /^-/) {
|
||||
my @tempnr = ();
|
||||
foreach my $nr (split(/,/, $arg)) {
|
||||
if ($nr =~ /^\^(.*)$/) {
|
||||
@@ -82,7 +82,7 @@ if (!($tmp =~ / (--help|-h|-v|--version)/)) {
|
||||
push(@{ $cmdref->{arg} }, @ARGV);
|
||||
|
||||
# check the syntax
|
||||
my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY);
|
||||
my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY,$RCP);
|
||||
if (
|
||||
!GetOptions(
|
||||
'A|updateallsw' => \$ALLSW,
|
||||
@@ -103,6 +103,7 @@ if (
|
||||
'fanout=i' => \$fanout,
|
||||
't|timetout=i' => \$timeout,
|
||||
'n|noverify' => \$NOVERIFY,
|
||||
'r|node-rcp' => \$RCP,
|
||||
)
|
||||
) {
|
||||
&updatenode_usage();
|
||||
|
||||
@@ -27,7 +27,7 @@ Note: The scan method currently support is B<nmap>.
|
||||
|
||||
=item B<--range>
|
||||
|
||||
Specify one or more IP ranges acceptable to nmap. IP range can be hostnames, IP addresses, networks, etc. A single IP address (10.1.2.3) or an IP range (10.1.2.0/24) can be specified. If the range is very large, the B<bmcdiscover> command may take a long time to return.
|
||||
Specify one or more IP ranges acceptable to nmap. IP range can be hostnames, IP addresses, networks, etc. A single IP address (10.1.2.3), several IPs with commas (10.1.2.3,10.1.2.10), Ip range with "-" (10.1.2.0-100) or an IP range (10.1.2.0/24) can be specified. If the range is very large, the B<bmcdiscover> command may take a long time to return.
|
||||
|
||||
=item B<--sn>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ B<packimage [-h| --help]>
|
||||
|
||||
B<packimage [-v| --version]>
|
||||
|
||||
B<packimage> [B<-m>|B<--method> I<cpio|tar>] [B<-c>|B<--compress> I<gzip|pigz|xz>] I<imagename>
|
||||
B<packimage> [B<-m>|B<--method> I<cpio|tar>] [B<-c>|B<--compress> I<gzip|pigz|xz>] [B<--nosyncfiles>] I<imagename>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
@@ -31,6 +31,8 @@ B<-m| --method> Archive Method (cpio,tar,squashfs, default is cpio)
|
||||
|
||||
B<-c| --compress> Compress Method (pigz,gzip,xz, default is pigz/gzip)
|
||||
|
||||
B<--nosyncfiles> Bypass of syncfiles requested, will not sync files to root image directory
|
||||
|
||||
|
||||
=head1 RETURN VALUE
|
||||
|
||||
@@ -48,6 +50,10 @@ B<-c| --compress> Compress Method (pigz,gzip,xz, default is pigz/gzip)
|
||||
|
||||
packimage -m tar -c pigz rhels7.1-x86_64-netboot-compute
|
||||
|
||||
3. To pack the osimage 'rhels7.1-x86_64-netboot-compute' without syncing files:
|
||||
|
||||
packimage --nosyncfiles rhels7.1-x86_64-netboot-compute
|
||||
|
||||
=head1 FILES
|
||||
|
||||
/opt/xcat/sbin/packimage
|
||||
|
||||
@@ -16,7 +16,7 @@ B<rinv> I<noderange> [B<model>|B<serial>|B<deviceid>|B<uuid>|B<guid>|B<vpd>|B<mp
|
||||
|
||||
=head2 OpenPOWER (OpenBMC) server specific:
|
||||
|
||||
B<rinv> I<noderange> [B<model>|B<serial>|B<firm>|B<cpu>|B<dimm>|B<all>] [B<-V>|B<--verbose>]
|
||||
B<rinv> I<noderange> [B<model>][B<serial>][B<firm>][B<cpu>][B<dimm>][B<all>] [B<-V>|B<--verbose>]
|
||||
|
||||
=head2 PPC (with HMC) specific:
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ B<updatenode> - Update nodes in an xCAT cluster environment.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<updatenode> I<noderange> [B<-V>|B<--verbose>] [B<-F>|B<--sync>] [B<-f>|B<--snsync>] [B<-S>|B<--sw>] [B<-l> I<userID>] [B<-P>|B<--scripts> [I<script1,script2...>]] [B<-s>|B<--sn>] [B<-A>|B<--updateallsw>] [B<-c>|B<--cmdlineonly>] [B<-d> I<alt_source_dir>] [B<--fanout>=I<fanout_value>] [B<-t> I<timeout>} [I<attr=val> [I<attr=val...>]] [B<-n>|B<--noverify>]
|
||||
B<updatenode> I<noderange> [B<-V>|B<--verbose>] [B<-F>|B<--sync>] [B<-f>|B<--snsync>] [B<-r>|B<--node-rcp> [I<full_path_to_remote_copy_command>]] [B<-S>|B<--sw>] [B<-l> I<userID>] [B<-P>|B<--scripts> [I<script1,script2...>]] [B<-s>|B<--sn>] [B<-A>|B<--updateallsw>] [B<-c>|B<--cmdlineonly>] [B<-d> I<alt_source_dir>] [B<--fanout>=I<fanout_value>] [B<-t> I<timeout>} [I<attr=val> [I<attr=val...>]] [B<-n>|B<--noverify>]
|
||||
|
||||
B<updatenode> B<noderange> [B<-k>|B<--security>] [B<-t> I<timeout>]
|
||||
|
||||
@@ -289,7 +289,7 @@ Used to specify a source directory other than the standard lpp_source directory
|
||||
=item B<-F|--sync>
|
||||
|
||||
Specifies that file synchronization should be
|
||||
performed on the nodes. rsync and ssh must
|
||||
performed on the nodes. rsync/scp and ssh must
|
||||
be installed and configured on the nodes.
|
||||
The function is not supported for NFS-based statelite installations.
|
||||
For NFS-based statelite installations to sync files, you should use the
|
||||
@@ -302,7 +302,7 @@ litefile table with source location specified in the litetree table.
|
||||
Specifies that file synchronization should be
|
||||
performed to the service nodes that service the
|
||||
nodes in the noderange. This updates the service
|
||||
nodes with the data to sync to the nodes. rsync and ssh must
|
||||
nodes with the data to sync to the nodes. rsync/scp and ssh must
|
||||
be installed and configured on the service nodes.
|
||||
For hierarchy, this optionally can be done before syncing the files
|
||||
to the nodes with the -F flag. If the -f flag is not used, then
|
||||
@@ -316,6 +316,20 @@ For statelite installations to sync files, you should use the
|
||||
read-only option for files/directories listed in
|
||||
litefile table with source location specified in the litetree table.
|
||||
|
||||
|
||||
=item [B<-r>|B<--node-rcp> [I<full_path_to_remote_copy_command>]]
|
||||
|
||||
Specifies the full path of the remote copy command used for syncing files to node targets, such as "/usr/bin/rsync" or "/usr/bin/scp". If not specified, rsync will be used by default.
|
||||
|
||||
Notice: The synclist for "-r /usr/bin/scp" has some differences with "-r /usr/bin/rsync":
|
||||
|
||||
1) the ``EXECUTE`` clause is not supported in "-r /usr/bin/scp"
|
||||
|
||||
2) if the destination directory specified in synclist is an existing file on target node, "updatenode -r /usr/bin/scp" will fail with ``scp: <destination directory>: Not a directory``
|
||||
|
||||
3) if the destination file specified in synclist is an existing directory on target node, "updatenode -r /usr/bin/scp" will fail with ``scp: <destination file>: Is a directory``
|
||||
|
||||
|
||||
=item B<-g|--genmypost>
|
||||
|
||||
Will generate a new mypostscript file for the
|
||||
|
||||
@@ -8,17 +8,17 @@ B<chtab> [B<-h> | B<--help>]
|
||||
|
||||
B<chtab> [B<-v> | B<--version>]
|
||||
|
||||
B<chtab> [I<keycolname=keyvalue>] [I<tablename.colname=newvalue>]
|
||||
B<chtab> I<keycolname=keyvalue>[,I<keycolname=keyvalue>,...] I<tablename.colname=newvalue> [I<tablename.colname=newvalue> ...]
|
||||
|
||||
B<chtab> [I<keycolname=keyvalue>] [I<tablename.colname+=newvalue>]
|
||||
B<chtab> I<keycolname=keyvalue>[,I<keycolname=keyvalue>,...] I<tablename.colname+=newvalue> [I<tablename.colname+=newvalue> ...]
|
||||
|
||||
B<chtab -d> [I<keycolname=keyvalue>] [I<tablename.colname=newvalue>]
|
||||
B<chtab -d> I<keycolname=keyvalue>[,I<keycolname=keyvalue>,...] I<tablename> [I<tabname> ...]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The chtab command adds, deletes or updates the attribute value in the specified table.column for the specified keyvalue. Normally, the given value will completely replace the current attribute value. But if "+=" is used instead of "=", the specified value will be appended to the coma separated list of the attribute, if it is not already there.
|
||||
The B<chtab> command adds, deletes or updates the attribute values in the specified table.column for the specified I<keyvalue>. Normally, the given value will completely replace the current attribute value. But if "+=" is used instead of "=", the specified value will be appended to the comma separated list of attributes, if it is not already there.
|
||||
|
||||
The chtab is designed to work without passing xcatd, so it's out of control of policy mechanism.
|
||||
The B<chtab> does not pass through xcatd, so it is not controlled by the policy mechanism.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
@@ -8,15 +8,15 @@ B<tabch> [B<-h> | B<--help>]
|
||||
|
||||
B<tabch> [B<-v> | B<--version>]
|
||||
|
||||
B<tabch> [I<keycolname=keyvalue>] [I<tablename.colname=newvalue>]
|
||||
B<tabch> I<keycolname=keyvalue>[,I<keycolname=keyvalue>,...] I<tablename.colname=newvalue> [I<tablename.colname=newvalue> ...]
|
||||
|
||||
B<tabch> [I<keycolname=keyvalue>] [I<tablename.colname+=newvalue>]
|
||||
B<tabch> I<keycolname=keyvalue>[,I<keycolname=keyvalue>,...] I<tablename.colname+=newvalue> [I<tablename.colname+=newvalue> ...]
|
||||
|
||||
B<tabch -d> [I<keycolname=keyvalue>] [I<tablename.colname=newvalue>]
|
||||
B<tabch -d> I<keycolname=keyvalue>[,I<keycolname=keyvalue>,...] I<tablename> [I<tablename> ...]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The tabch command adds, deletes or updates the attribute value in the specified table.column for the specified keyvalue. The difference between tabch and chtab is tabch runs as a plugin under the xcatd daemon. This give the additional security of being authorized by the daemon. Normally, the given value will completely replace the current attribute value. But if "+=" is used instead of "=", the specified value will be appended to the coma separated list of the attribute, if it is not already there.
|
||||
The B<tabch> command adds, deletes or updates the attribute values in the specified table.column for the specified keyvalue. The difference between B<tabch> and B<chtab> is B<tabch> runs as a plugin under the xcatd daemon. This give the additional security of being authorized by the daemon. Normally, the given value will completely replace the current attribute value. But if "+=" is used instead of "=", the specified value will be appended to the comma separated list of attributes, if it is not already there.
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
@@ -319,6 +319,11 @@ if [ "$destiny" != "discover" ]; then #we aren't discoverying, we probably can a
|
||||
logger -s -t $log_label -p local4.info "Getting initial certificate --> $XCATMASTER:$XCATPORT"
|
||||
/bin/getcert $XCATMASTER:$XCATPORT
|
||||
fi
|
||||
if [ "$destiny" ]; then
|
||||
# run getdestiny to update node status
|
||||
/bin/getdestiny $XCATMASTER:$XCATPORT >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
while :; do
|
||||
|
||||
grepconfigraid=`echo $destiny|grep "configraid"`
|
||||
@@ -389,7 +394,7 @@ while :; do
|
||||
tar xvf `basename $destparameter`
|
||||
./runme.sh
|
||||
cd -
|
||||
logger -s -t $log_label -p local4.info "Running nextdestiny $XCATMASTER:$XCATPORT..."
|
||||
logger -s -t $log_label -p local4.info "Running nextdestiny $XCATMASTER:$XCATPORT..."
|
||||
destiny=`/bin/nextdestiny $XCATMASTER:$XCATPORT`
|
||||
dest=`echo $destiny|awk -F= '{print $1}'`
|
||||
logger -s -t $log_label -p local4.info "nextdestiny - Complete."
|
||||
|
||||
@@ -527,6 +527,16 @@ class OpenBMCFlashTask(ParallelNodesCommand):
|
||||
|
||||
try:
|
||||
obmc.login()
|
||||
# Before uploading file, check CPU DD version
|
||||
inventory_info_dict = obmc.get_inventory_info('cpu')
|
||||
cpu_info = inventory_info_dict["CPU"]
|
||||
for info in cpu_info:
|
||||
if info.startswith("CPU0 Version : 20"):
|
||||
# Display warning the only certain firmware versions are supported on DD 2.0
|
||||
self.callback.info( '%s: Warning: DD 2.0 processor detected on this node, should not have firmware > ibm-v2.0-0-r13.6 (BMC) and > v1.19_1.94 (Host).' % node)
|
||||
if info.startswith("CPU0 Version : 21"):
|
||||
if self.verbose:
|
||||
self.callback.info( '%s: DD 2.1 processor' % node)
|
||||
except (SelfServerException, SelfClientException) as e:
|
||||
return self._msg_process(node, e.message, msg_type='E')
|
||||
|
||||
|
||||
@@ -74,18 +74,47 @@ class OpenBMCInventoryTask(ParallelNodesCommand):
|
||||
|
||||
return firm_info
|
||||
|
||||
def get_info(self, inventory_type, **kw):
|
||||
def get_info(self, inventory_types, **kw):
|
||||
|
||||
node = kw['node']
|
||||
obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback,
|
||||
debugmode=self.debugmode, verbose=self.verbose)
|
||||
|
||||
inventory_info = []
|
||||
|
||||
# inventory_types contains an array of different inventories to get
|
||||
# Go through the array and set flags to optimize invnetory calls
|
||||
model_or_serial = 0
|
||||
cpu_or_dimm = 0
|
||||
all = 0
|
||||
inventory_type = 'all'
|
||||
for type in inventory_types:
|
||||
if type == 'model' or type == 'serial':
|
||||
# For model and serial we can make a single call
|
||||
model_or_serial = 1
|
||||
if type == 'cpu' or type == 'dimm':
|
||||
# For cpu and dimm we can make a single call
|
||||
cpu_or_dimm = 1
|
||||
if type == 'all':
|
||||
all = 1
|
||||
if all == 1:
|
||||
inventory_type = 'all'
|
||||
elif model_or_serial == 1 and cpu_or_dimm == 1:
|
||||
# Both model_or_serial and cpu_or_dimm were set, might as well ask for all
|
||||
inventory_type = 'all'
|
||||
elif model_or_serial == 1:
|
||||
inventory_type = 'model'
|
||||
elif cpu_or_dimm == 1:
|
||||
inventory_type = 'cpu'
|
||||
|
||||
try:
|
||||
obmc.login()
|
||||
inventory_info_dict = obmc.get_inventory_info()
|
||||
# Extract the data from the BMC
|
||||
inventory_info_dict = obmc.get_inventory_info(inventory_type)
|
||||
|
||||
if inventory_type == 'all' or not inventory_type:
|
||||
# Process returned inventory_info_dict depending on the inventory requested
|
||||
if all == 1:
|
||||
# Everything gets displayed, even firmware
|
||||
keys = inventory_info_dict.keys()
|
||||
keys.sort()
|
||||
for key in keys:
|
||||
@@ -95,17 +124,28 @@ class OpenBMCInventoryTask(ParallelNodesCommand):
|
||||
firm_info = self._get_firm_info(firm_dict_list)
|
||||
|
||||
inventory_info += firm_info
|
||||
elif inventory_type == 'model' or inventory_type == 'serial':
|
||||
key = 'Model' if inventory_type == 'model' else 'SerialNumber'
|
||||
if 'SYSTEM' in inventory_info_dict:
|
||||
for system_info in inventory_info_dict['SYSTEM']:
|
||||
if key in system_info:
|
||||
inventory_info = [system_info]
|
||||
break
|
||||
else:
|
||||
key = inventory_type.upper()
|
||||
if key in inventory_info_dict:
|
||||
inventory_info = utils.sort_string_with_numbers(inventory_info_dict[key])
|
||||
if model_or_serial == 1:
|
||||
# Model or serial was requested
|
||||
for one_inventory_type in inventory_types:
|
||||
if one_inventory_type == 'model':
|
||||
key = 'Model'
|
||||
elif one_inventory_type == 'serial':
|
||||
key = 'SerialNumber'
|
||||
else:
|
||||
continue
|
||||
|
||||
if 'SYSTEM' in inventory_info_dict:
|
||||
for system_info in inventory_info_dict['SYSTEM']:
|
||||
if key in system_info:
|
||||
inventory_info += [system_info]
|
||||
break
|
||||
if cpu_or_dimm:
|
||||
# cpu or dimm was requested
|
||||
for one_inventory_type in inventory_types:
|
||||
key = one_inventory_type.upper()
|
||||
if key in inventory_info_dict:
|
||||
inventory_info += utils.sort_string_with_numbers(inventory_info_dict[key])
|
||||
|
||||
if not inventory_info:
|
||||
inventory_info = ['No attributes returned from the BMC.']
|
||||
|
||||
@@ -10,10 +10,10 @@ class InventoryInterface(object):
|
||||
interface_type = 'inventory'
|
||||
version = '1.0'
|
||||
|
||||
def get_inventory_info(self, task, inventory_type=None):
|
||||
def get_inventory_info(self, task, inventory_type=[]):
|
||||
"""Return the inventory info of the task's nodes.
|
||||
|
||||
:param inventory_type: type of inventory info want to get.
|
||||
:param inventory_type: array of type of inventory info want to get.
|
||||
:param task: a Task instance containing the nodes to act on.
|
||||
:return inventory info list
|
||||
"""
|
||||
|
||||
@@ -49,7 +49,13 @@ DUMP_URLS = {
|
||||
|
||||
GARD_CLEAR_URL = "/org/open_power/control/gard/action/Reset"
|
||||
|
||||
INVENTORY_URL = "/inventory/enumerate"
|
||||
INVENTORY_URLS = {
|
||||
"all" : "/inventory/enumerate",
|
||||
"model" : "/inventory/system",
|
||||
"serial" : "/inventory/system",
|
||||
"cpu" : "/inventory/system/chassis/motherboard/enumerate",
|
||||
"dimm" : "/inventory/system/chassis/motherboard/enumerate",
|
||||
}
|
||||
|
||||
LEDS_URL = "/led/physical/enumerate"
|
||||
|
||||
@@ -546,11 +552,19 @@ class OpenBMCRest(object):
|
||||
error = 'Received wrong format response: %s' % sensor_data
|
||||
raise SelfServerException(error)
|
||||
|
||||
def get_inventory_info(self):
|
||||
def get_inventory_info(self, inventory_type):
|
||||
|
||||
inventory_data = self.request('GET', INVENTORY_URL, cmd='get_inventory_info')
|
||||
inventory_data = self.request('GET', INVENTORY_URLS[inventory_type], cmd='get_inventory_info')
|
||||
try:
|
||||
inverntory_dict = {}
|
||||
inventory_dict = {}
|
||||
if inventory_type == 'model' or inventory_type == 'serial':
|
||||
# The format of returned data for model and serial a different from other inventory types
|
||||
inventory_dict['SYSTEM'] = []
|
||||
for key, value in inventory_data.items():
|
||||
inventory_dict['SYSTEM'].append('%s %s : %s' % ("SYSTEM", key, value))
|
||||
|
||||
return inventory_dict
|
||||
|
||||
for key, value in inventory_data.items():
|
||||
if 'Present' not in value:
|
||||
logger.debug('Not "Present" for %s' % key)
|
||||
@@ -572,13 +586,13 @@ class OpenBMCRest(object):
|
||||
else:
|
||||
source = key_id
|
||||
|
||||
if key_type not in inverntory_dict:
|
||||
inverntory_dict[key_type] = []
|
||||
if key_type not in inventory_dict:
|
||||
inventory_dict[key_type] = []
|
||||
|
||||
for (sub_key, v) in value.items():
|
||||
inverntory_dict[key_type].append('%s %s : %s' % (source.upper(), sub_key, v))
|
||||
inventory_dict[key_type].append('%s %s : %s' % (source.upper(), sub_key, v))
|
||||
|
||||
return inverntory_dict
|
||||
return inventory_dict
|
||||
except KeyError:
|
||||
error = 'Received wrong format response: %s' % inventory_data
|
||||
raise SelfServerException(error)
|
||||
|
||||
@@ -223,9 +223,16 @@ class OpenBMCManager(base.BaseManager):
|
||||
if not args or (len(args) == 1 and args[0] in ['-V', '--verbose']):
|
||||
args.append('all')
|
||||
|
||||
# We are not using a standard Python options (with - or --) because
|
||||
# of that, we need to specify multiple identical choices. If only
|
||||
# one optional choice is specified - [all|cpu|dimm|firm|model|serial]
|
||||
# only one option at a time is allowed.
|
||||
# If specified - [all][cpu][dimm][firm][model][serial], then multiple
|
||||
# options are accepted, but they are required to be ordered,
|
||||
# e.g "cpu dimm" will work, but not "dimm cpu"
|
||||
rinv_usage = """
|
||||
Usage:
|
||||
rinv [-V|--verbose] [all|cpu|dimm|firm|model|serial]
|
||||
rinv [-V|--verbose] [all|cpu|dimm|firm|model|serial] [all|cpu|dimm|firm|model|serial] [all|cpu|dimm|firm|model|serial] [all|cpu|dimm|firm|model|serial] [all|cpu|dimm|firm|model|serial]
|
||||
|
||||
Options:
|
||||
-V --verbose rinv verbose mode.
|
||||
@@ -235,22 +242,37 @@ class OpenBMCManager(base.BaseManager):
|
||||
opts = docopt(rinv_usage, argv=args)
|
||||
|
||||
self.verbose = opts.pop('--verbose')
|
||||
action = [k for k,v in opts.items() if v][0]
|
||||
actions = [k for k,v in opts.items() if v]
|
||||
except Exception as e:
|
||||
self.messager.error("Failed to parse arguments for rinv: %s" % args)
|
||||
return
|
||||
|
||||
# 2, validate the args
|
||||
if action not in INVENTORY_OPTIONS:
|
||||
self.messager.error("Not supported subcommand for rinv: %s" % action)
|
||||
return
|
||||
run_firmware_inventory = 0
|
||||
run_other_inventory = 0
|
||||
for action in actions:
|
||||
# Check if each action is valid
|
||||
if action not in INVENTORY_OPTIONS:
|
||||
self.messager.error("Not supported subcommand for rinv: %s" % action)
|
||||
return
|
||||
else:
|
||||
# Valid action, set flags for which calls to make later
|
||||
if action == 'all':
|
||||
run_firmware_inventory = 0
|
||||
run_other_inventory = 1
|
||||
break # get all inventory, nothing else matters
|
||||
elif action == 'firm':
|
||||
run_firmware_inventory = 1
|
||||
else:
|
||||
run_other_inventory = 1
|
||||
|
||||
# 3, run the subcommands
|
||||
runner = OpenBMCInventoryTask(nodesinfo, callback=self.messager, debugmode=self.debugmode, verbose=self.verbose)
|
||||
if action == 'firm':
|
||||
if run_firmware_inventory == 1:
|
||||
DefaultInventoryManager().get_firm_info(runner)
|
||||
else:
|
||||
DefaultInventoryManager().get_inventory_info(runner, action)
|
||||
actions.remove('firm') # Remove element from actions array
|
||||
if run_other_inventory == 1:
|
||||
DefaultInventoryManager().get_inventory_info(runner, actions)
|
||||
|
||||
def rpower(self, nodesinfo, args):
|
||||
|
||||
|
||||
@@ -553,6 +553,45 @@ sub is_ntp_ready{
|
||||
|
||||
#------------------------------------------
|
||||
|
||||
=head3
|
||||
Description:
|
||||
Test if rsyslog service is ready to use in current operating system
|
||||
Arguments:
|
||||
errormsg_ref: if there is something wrong for ntp service, this attribute save the possible reason.
|
||||
Returns:
|
||||
1 : yes
|
||||
0 : no
|
||||
=cut
|
||||
|
||||
#------------------------------------------
|
||||
sub is_rsyslog_ready {
|
||||
my $errormsg_ref = shift;
|
||||
$errormsg_ref= shift if (($errormsg_ref) && ($errormsg_ref =~ /probe_utils/));
|
||||
|
||||
my $is_active = 1;
|
||||
my $tmp = `pidof systemd`;
|
||||
chomp($tmp);
|
||||
if ($tmp) {
|
||||
`systemctl is-active --quiet rsyslog 2>&1`;
|
||||
if ($?) {
|
||||
$is_active = 0;
|
||||
}
|
||||
} else {
|
||||
my $output = `service rsyslog status 2>&1 | grep "Active: active (running)"`;
|
||||
if (!$output) {
|
||||
$is_active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$is_active) {
|
||||
$$errormsg_ref = "rsyslog service is not running! Please check on current node";
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#------------------------------------------
|
||||
|
||||
=head3
|
||||
Description:
|
||||
Convert second to time
|
||||
|
||||
@@ -16,6 +16,8 @@ my $program_name = basename("$0");
|
||||
my $help;
|
||||
my $noderange = "";
|
||||
my $test;
|
||||
my $osimage;
|
||||
my $osimagecmd = "";
|
||||
my $output = "stdout";
|
||||
my $verbose = 0;
|
||||
my $rst = 0;
|
||||
@@ -30,6 +32,7 @@ Description:
|
||||
Options:
|
||||
-h : Get usage information of $program_name
|
||||
-V : To print additional debug information.
|
||||
--osimage=<name>: Provide the osimage name to run the probe against
|
||||
";
|
||||
|
||||
#-------------------------------------
|
||||
@@ -38,6 +41,7 @@ Options:
|
||||
if (
|
||||
!GetOptions("--help|h" => \$help,
|
||||
"T" => \$test,
|
||||
"osimage=s" => \$osimage,
|
||||
"V|verbose" => \$VERBOSE))
|
||||
{
|
||||
probe_utils->send_msg("$output", "f", "Invalid parameter for $program_name");
|
||||
@@ -68,18 +72,15 @@ if (scalar(@ARGV) >= 1) {
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# Run all osinage probe checks one after another
|
||||
check_for_duplicate_rootimgdir();
|
||||
check_for_valid_osimage_attributes();
|
||||
|
||||
# Check for osimage definitions with duplicate values for rootimgdir
|
||||
sub check_for_duplicate_rootimgdir {
|
||||
probe_utils->send_msg("$output", "i", "==> Checking for duplicate usage of the rootimgdir in diskless images...");
|
||||
my $na = "N/A";
|
||||
|
||||
my %rootimgdir_osimage_hash;
|
||||
my $any_dups = 0;
|
||||
|
||||
my $all_osimages_rootimgdir = `lsdef -t osimage -i rootimgdir -c 2> /dev/null`;
|
||||
my $all_osimages_rootimgdir = `lsdef -t osimage $osimagecmd -i rootimgdir -c 2> /dev/null`;
|
||||
chomp($all_osimages_rootimgdir);
|
||||
my @all_osimages_rootimgdir_lines = split("[\n\r]", $all_osimages_rootimgdir);
|
||||
|
||||
@@ -137,6 +138,7 @@ sub check_for_duplicate_rootimgdir {
|
||||
|
||||
# Check attributes in osimage definitions for valid format
|
||||
sub check_for_valid_osimage_attributes {
|
||||
probe_utils->send_msg("$output", "i", "==> Checking for valid osimage template attribute ... ");
|
||||
my $na = "N/A";
|
||||
|
||||
my $rc = 0;
|
||||
@@ -145,7 +147,7 @@ sub check_for_valid_osimage_attributes {
|
||||
my $any_dups = 0;
|
||||
|
||||
# Check if any osimage object has "template" attribute set to service.tmpl or compute.tmpl
|
||||
my $all_osimages_template = `lsdef -t osimage -i template -c 2> /dev/null`;
|
||||
my $all_osimages_template = `lsdef -t osimage $osimagecmd -i template -c 2> /dev/null`;
|
||||
chomp($all_osimages_template);
|
||||
my @all_osimages_template_lines = split("[\n\r]", $all_osimages_template);
|
||||
|
||||
@@ -176,3 +178,66 @@ sub check_for_valid_osimage_attributes {
|
||||
|
||||
return $rc;
|
||||
}
|
||||
|
||||
sub check_valid_files_defined {
|
||||
probe_utils->send_msg("$output", "i", "==> Checking that valid files are specified in osimage attributes ...");
|
||||
my $rc = 0;
|
||||
my $osimage_list = `lsdef -t osimage $osimagecmd -s 2> /dev/null`;
|
||||
chomp($osimage_list);
|
||||
my @all_osimage_lists = split("[\n]", $osimage_list);
|
||||
|
||||
foreach (@all_osimage_lists) {
|
||||
# loop over the osimage name
|
||||
my ($osimage_name, $junk) = split " ", $_;
|
||||
probe_utils->send_msg("$output", "d", "Inspecting osimage=$osimage_name") if ($VERBOSE);
|
||||
|
||||
my @attributes = qw ( otherpkglist pkglist template );
|
||||
foreach (@attributes) {
|
||||
# loop over the attributes to check
|
||||
probe_utils->send_msg("$output", "d", "Checking attribute=$_ ...") if ($VERBOSE);
|
||||
|
||||
my $osimage_attribute = `lsdef -t osimage -o $osimage_name -i $_ -c 2> /dev/null`;
|
||||
chomp($osimage_attribute);
|
||||
my ($junk, $file) = split "=", $osimage_attribute;
|
||||
if ($file eq "") {
|
||||
# if no file is defined, skip
|
||||
next;
|
||||
}
|
||||
|
||||
if ($file =~ /\,/) {
|
||||
my @files = split /,/, $file;
|
||||
foreach my $f (@files) {
|
||||
probe_utils->send_msg("$output", "d", "Defined in $_, checking for file: $f") if ($VERBOSE);
|
||||
if (! -e $f) {
|
||||
probe_utils->send_msg("$output", "f", "In $_, NON-EXISTANT FILE: $f");
|
||||
$rc = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($rc == 0) {
|
||||
probe_utils->send_msg("$output", "o", "Files specified in the osimage attributes seem to be valid.");
|
||||
}
|
||||
}
|
||||
#
|
||||
# MAIN
|
||||
#
|
||||
# Run all osimage probe checks one after another
|
||||
|
||||
if ($osimage) {
|
||||
$osimagecmd = "-o $osimage";
|
||||
probe_utils->send_msg("$output", "d", "[osimagecheck] osimage passed in: $osimage") if ($VERBOSE);
|
||||
# verify a valid osimage name was passed in
|
||||
my $osimage_output = `lsdef -t osimage $osimagecmd 2>&1`;
|
||||
if ($osimage_output =~ /Error: Could not find/) {
|
||||
probe_utils->send_msg("$output", "f", "Invalid osimage name passed in: $osimage");
|
||||
exit 1;
|
||||
}
|
||||
} else {
|
||||
probe_utils->send_msg("$output", "d", "[osimagecheck] No osimage passed in, checking all osimages ...") if ($VERBOSE);
|
||||
}
|
||||
check_for_duplicate_rootimgdir();
|
||||
check_for_valid_osimage_attributes();
|
||||
check_valid_files_defined();
|
||||
|
||||
|
||||
+242
-12
@@ -57,10 +57,12 @@ sub do_main_job {
|
||||
my $checkpoint;
|
||||
my $rc = 0;
|
||||
my $installnicip;
|
||||
my $flag = "w";
|
||||
|
||||
#check if all xcat deamons are running
|
||||
$rst = check_all_xcat_deamons(\$checkpoint, \@error);
|
||||
print_check_result($checkpoint, "f", $rst, \@error);
|
||||
#check if all xcat daemons are running
|
||||
($rst, $flag) = check_all_xcat_daemons(\$checkpoint, \@error);
|
||||
print_check_result($checkpoint, $flag, $rst, \@error);
|
||||
$rst = 0 if ($flag == "w");
|
||||
return $rst if ($rst);
|
||||
|
||||
#check if xcatd can receive request
|
||||
@@ -119,6 +121,11 @@ sub do_main_job {
|
||||
print_check_result($checkpoint, "f", $rst, \@error);
|
||||
$rc |= $rst;
|
||||
|
||||
#check rsyslog service
|
||||
$rst = check_rsyslog_service(\$checkpoint, \@error);
|
||||
print_check_result($checkpoint, "f", $rst, \@error);
|
||||
$rc |= $rst;
|
||||
|
||||
#Below are the 'warning` level check points
|
||||
|
||||
#check if firewall is close
|
||||
@@ -131,10 +138,29 @@ sub do_main_job {
|
||||
print_check_result($checkpoint, "w", $rst, \@error);
|
||||
$rc |= $rst;
|
||||
|
||||
#check linux ulimits configuration
|
||||
($rst, $flag) = check_ulimits(\$checkpoint, \@error);
|
||||
print_check_result($checkpoint, $flag, $rst, \@error);
|
||||
$rc |= $rst;
|
||||
|
||||
#check network parameter configuration
|
||||
($rst, $flag) = check_network_parameter(\$checkpoint, \@error);
|
||||
print_check_result($checkpoint, $flag, $rst, \@error);
|
||||
$rc |= $rst;
|
||||
|
||||
#some sepecific check points in MN
|
||||
if (!$is_sn) {
|
||||
|
||||
#check xCAT daemon attributes configuration
|
||||
($rst, $flag) = check_daemon_attributes(\$checkpoint, \@error);
|
||||
print_check_result($checkpoint, $flag, $rst, \@error);
|
||||
$rc |= $rst;
|
||||
|
||||
#check if log can be recorded in log file
|
||||
$rst = check_log_record(\$checkpoint, \@error);
|
||||
print_check_result($checkpoint, "w", $rst, \@error);
|
||||
$rc |= $rst;
|
||||
|
||||
#check if server ip is a static ip in MN
|
||||
$rst = check_server_ip_static($installnicip,\$checkpoint, \@error);
|
||||
print_check_result($checkpoint, "w", $rst, \@error);
|
||||
@@ -257,15 +283,16 @@ sub print_check_result {
|
||||
|
||||
}
|
||||
|
||||
sub check_all_xcat_deamons {
|
||||
sub check_all_xcat_daemons {
|
||||
my $checkpoint_ref = shift;
|
||||
my $error_ref = shift;
|
||||
my $rst = 0;
|
||||
my $rst_type = "f";
|
||||
|
||||
$$checkpoint_ref = "Checking all xCAT deamons are running...";
|
||||
$$checkpoint_ref = "Checking all xCAT daemons are running...";
|
||||
@$error_ref = ();
|
||||
|
||||
my @deamon_list = ("SSL listener",
|
||||
my @daemon_list = ("SSL listener",
|
||||
"DB Access",
|
||||
"UDP listener",
|
||||
"install monitor",
|
||||
@@ -273,14 +300,28 @@ sub check_all_xcat_deamons {
|
||||
"Command log writer");
|
||||
|
||||
my $output = `ps aux 2>&1|grep -v grep|grep xcatd`;
|
||||
foreach my $deamon (@deamon_list) {
|
||||
if ($output !~ /$deamon/) {
|
||||
push @$error_ref, "Deamon '$deamon' isn't running";
|
||||
foreach my $daemon (@daemon_list) {
|
||||
my $counter = $output =~ s/$daemon/$daemon/g;
|
||||
if ($counter > 1) {
|
||||
if ($daemon == "SSL listener") {
|
||||
my $cur_pid = `cat /var/run/xcatd.pid`;
|
||||
my @ssl_pids = `ps aux 2>&1|grep -v grep|grep "xcatd: $daemon"|awk -F' ' '{print \$2}'`;
|
||||
foreach my $ssl_pid (@ssl_pids) {
|
||||
next if ($cur_pid == $ssl_pid);
|
||||
my $child_pid = `ps --ppid $ssl_pid 2>&1 | grep "xcatd SSL:" | wc -l`;
|
||||
chomp($child_pid);
|
||||
$rst_type = "w" if ($child_pid);
|
||||
}
|
||||
}
|
||||
push @$error_ref, "More Daemon '$daemon' is running";
|
||||
$rst = 1;
|
||||
} elsif ($counter == 0) {
|
||||
push @$error_ref, "Daemon '$daemon' isn't running";
|
||||
$rst = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $rst;
|
||||
return ($rst, $rst_type);
|
||||
}
|
||||
|
||||
sub check_xcatd_receive_request {
|
||||
@@ -699,6 +740,97 @@ sub check_tftp_service {
|
||||
return $rst;
|
||||
}
|
||||
|
||||
sub check_rsyslog_service {
|
||||
my $checkpoint_ref = shift;
|
||||
my $error_ref = shift;
|
||||
my $rst = 0;
|
||||
|
||||
$$checkpoint_ref = "Checking rsyslog service is configured...";
|
||||
@$error_ref = ();
|
||||
|
||||
my $error;
|
||||
if (!probe_utils->is_rsyslog_ready(\$error)) {
|
||||
push @$error_ref, "$error";
|
||||
$rst = 1;
|
||||
}
|
||||
return $rst;
|
||||
}
|
||||
|
||||
sub check_log_record {
|
||||
my $checkpoint_ref = shift;
|
||||
my $error_ref = shift;
|
||||
my $rst = 0;
|
||||
|
||||
my $log_file = "/var/log/xcat/cluster.log";
|
||||
$$checkpoint_ref = "Checking xCAT log is stored in $log_file...";
|
||||
@$error_ref = ();
|
||||
|
||||
unless (-e $log_file) {
|
||||
my $os_ver = `cat /etc/*release* 2>&1`;
|
||||
if ($os_ver =~ /suse/i and $os_ver =~ /VERSION=\"11.*\"/) {
|
||||
return 2;
|
||||
} else {
|
||||
push @$error_ref, "No log file $log_file found";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
my @snlist = xCAT::ServiceNodeUtils->getAllSN();
|
||||
my $service_nodes = join(",", @snlist);
|
||||
|
||||
my $start_time = time();
|
||||
my $log_msg = "xcatprobe rsyslog checking $start_time";
|
||||
my @valid_nodes;
|
||||
|
||||
`logger -p local4.info -t xcat $log_msg on MN 2>&1`;
|
||||
if ($?) {
|
||||
push @$error_ref, "Failed to run command 'logger' on MN";
|
||||
$rst = 1;
|
||||
return $rst;
|
||||
}
|
||||
sleep(5);
|
||||
|
||||
my @mn_grep_logs = `grep "$log_msg on MN" $log_file`;
|
||||
unless (@mn_grep_logs) {
|
||||
push @$error_ref, "Failed to store MN logs to $log_file";
|
||||
$rst = 1;
|
||||
return $rst;
|
||||
}
|
||||
|
||||
my @invld_nodes = ();
|
||||
my @output = `xdsh $service_nodes -s "logger -p local4.info -t xcat $log_msg on SN && echo OKAY" 2>&1`;
|
||||
|
||||
foreach my $line (@output) {
|
||||
chomp($line);
|
||||
if ($line =~ /(\w+): OKAY/) {
|
||||
push @valid_nodes, $1;
|
||||
} elsif ($line =~ /(\w+): ssh: connect to host .+ No route to host/) {
|
||||
push @invld_nodes, $1;
|
||||
}
|
||||
}
|
||||
sleep(5);
|
||||
|
||||
my @grep_logs = `grep "$log_msg on SN" $log_file | grep -v "Allowing" | grep -v "dispatch"`;
|
||||
foreach my $grep_log (@grep_logs) {
|
||||
if ($grep_log =~ /.+ \d+:\d+:\d+ (\w+) xcat: $log_msg on SN/) {
|
||||
push @checked_nodes, $1;
|
||||
}
|
||||
}
|
||||
|
||||
my %hash_pass = map{$_=>1} @checked_nodes;
|
||||
my @error_nodes = grep {!$hash_pass{$_}} @valid_nodes;
|
||||
if (@error_nodes) {
|
||||
push @$error_ref, "Failed to store logs come from " . join(",", @error_nodes) . " to $log_file on MN";
|
||||
$rst = 1;
|
||||
}
|
||||
if (@invld_nodes) {
|
||||
push @$error_ref, "Failed to connect SN " . join(",", @invld_nodes);
|
||||
$rst = 1;
|
||||
}
|
||||
|
||||
return $rst;
|
||||
}
|
||||
|
||||
sub check_ntp_service{
|
||||
my $checkpoint_ref = shift;
|
||||
my $error_ref = shift;
|
||||
@@ -816,7 +948,7 @@ sub check_dhcp_service {
|
||||
# on sn, just check dhcpd service whether running
|
||||
my $dhcpoutput = `ps aux 2>&1| grep dhcpd |grep -v grep`;
|
||||
if (!$dhcpoutput) {
|
||||
push @$error_ref, "There isn't 'dhcpd' deamon in current server";
|
||||
push @$error_ref, "There isn't 'dhcpd' daemon in current server";
|
||||
$rst = 1;
|
||||
}
|
||||
} else {
|
||||
@@ -941,6 +1073,104 @@ sub check_dhcp_leases {
|
||||
return $rst;
|
||||
}
|
||||
|
||||
sub check_ulimits {
|
||||
my $checkpoint_ref = shift;
|
||||
my $error_ref = shift;
|
||||
my $rst = 0;
|
||||
my $rst_type = "w";
|
||||
|
||||
$$checkpoint_ref = "Checking Linux ulimits configuration...";
|
||||
@$error_ref = ();
|
||||
|
||||
my $nofile_num = `sh -c 'ulimit -n' 2>&1`;
|
||||
chomp($nofile_num);
|
||||
|
||||
my $process_id = `cat /var/run/xcatd.pid`;
|
||||
chomp($process_id);
|
||||
my $process_folder = "/proc/$process_id/fd/";
|
||||
|
||||
my $open_num = 0;
|
||||
$open_num = `ls $process_folder | wc -l` if (-e $process_folder);
|
||||
chomp($open_num);
|
||||
return ($rst, $rst_type) unless($open_num);
|
||||
|
||||
my $percent = $open_num/$nofile_num;
|
||||
unless ($percent < 0.8) {
|
||||
push @$error_ref, "The number of open files is not enough for xcatd service, increase the limits for it according to xCAT document";
|
||||
$rst = 1;
|
||||
if ($percent >= 1) {
|
||||
$rst_type = "f";
|
||||
}
|
||||
}
|
||||
return ($rst, $rst_type);
|
||||
}
|
||||
|
||||
sub check_network_parameter {
|
||||
my $checkpoint_ref = shift;
|
||||
my $error_ref = shift;
|
||||
my $rst = 0;
|
||||
my $rst_type = "w";
|
||||
|
||||
$$checkpoint_ref = "Checking network kernel parameter configuration...";
|
||||
@$error_ref = ();
|
||||
|
||||
my $net_set_file = "/etc/sysctl.conf";
|
||||
my $net_gc_thresh = 512;
|
||||
my $net_set_value = `sysctl -n net.ipv4.neigh.default.gc_thresh2`;
|
||||
chomp($net_set_value);
|
||||
$net_gc_thresh = $net_set_value if ($net_set_value);
|
||||
|
||||
my $arp_num = `arp -a | wc -l`;
|
||||
chomp($arp_num);
|
||||
|
||||
my $percent = $arp_num/$net_gc_thresh;
|
||||
unless ($percent < 0.8) {
|
||||
push @$error_ref, "Most ARP has been used, please tuning network parameter as document";
|
||||
$rst = 1;
|
||||
if ($percent >= 1) {
|
||||
$rst_type = "f";
|
||||
}
|
||||
}
|
||||
return ($rst, $rst_type);
|
||||
}
|
||||
|
||||
sub check_daemon_attributes {
|
||||
my $checkpoint_ref = shift;
|
||||
my $error_ref = shift;
|
||||
my $rst = 0;
|
||||
$rst_type = "w";
|
||||
|
||||
$$checkpoint_ref = "Checking xCAT daemon attributes configuration...";
|
||||
@$error_ref = ();
|
||||
|
||||
my $node_num = `nodels 2>&1 | wc -l`;
|
||||
chomp($node_num);
|
||||
my $xcatmaxconnections = 64;
|
||||
my $xcatmaxbatchconnections = 50;
|
||||
|
||||
my @site_max_info = `lsdef -t site -i xcatmaxconnections,xcatmaxbatchconnections -c 2>&1`;
|
||||
foreach my $site_max (@site_max_info) {
|
||||
if ($site_max =~ /xcatmaxconnections=(\d+)/) {
|
||||
$xcatmaxconnections_site = $1;
|
||||
}
|
||||
if ($site_max =~ /xcatmaxbatchconnections=(\d+)/) {
|
||||
$xcatmaxbatchconnections_site = $1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($xcatmaxconnections_site <= $xcatmaxbatchconnections_site) {
|
||||
push @$error_ref, "Attribute xcatmaxbatchconnections must be less than xcatmaxconnections.";
|
||||
$rst = 1;
|
||||
$rst_type = "f";
|
||||
} elsif ($xcatmaxconnections_site < $xcatmaxconnections or
|
||||
$xcatmaxbatchconnections_site < $xcatmaxbatchconnections and
|
||||
$node_num >= 500) {
|
||||
push @$error_ref, "Management nodes are more than 500, please tuning xCAT daemon attributes as document";
|
||||
$rst = 1;
|
||||
}
|
||||
return ($rst, $rst_type);
|
||||
}
|
||||
|
||||
sub returncmdoutput {
|
||||
my $rst = shift;
|
||||
my $error_ref = shift;
|
||||
@@ -1034,7 +1264,7 @@ while ($hierarchy_instance->read_reply(\%reply_cache)) {
|
||||
|
||||
#print ">>>$reply_cache{$servers}->[$_]<<<\n";
|
||||
#For cases like below:
|
||||
#c910f02c04p04: [ok] :All xCAT deamons are running
|
||||
#c910f02c04p04: [ok] :All xCAT daemons are running
|
||||
if ($reply_cache{$servers}->[$_] =~ /^(\w+)\s*:\s*(\[\w+\]\s*):\s*(.*)/) {
|
||||
if ("$1" eq "$server") {
|
||||
$logmsg = "$2: $3";
|
||||
|
||||
@@ -193,6 +193,9 @@ sub new {
|
||||
foreach (keys %args) { #store all passed parameters
|
||||
$self->{$_} = $args{$_};
|
||||
}
|
||||
unless ($args{'node'}) { #default to port 623 unless specified
|
||||
$self->{'node'} = $args{'bmc'};
|
||||
}
|
||||
unless ($args{'port'}) { #default to port 623 unless specified
|
||||
$self->{'port'} = 623;
|
||||
}
|
||||
@@ -482,7 +485,7 @@ sub subcmd {
|
||||
my $command_string = $command_info{$args{netfn}}->{$args{command}};
|
||||
my $data_values = join ", ", @{$args{data}};
|
||||
my $msg = sprintf ("[ipmi_debug] $self->{onlogon_args}->{command}:$self->{onlogon_args}->{subcommand}(@{$self->{onlogon_args}->{extraargs}}), raw_cmd: netfn(0x%02x=>%s), cmd(0x%02x=>%s), data=[%s]", $args{netfn}, $netfn_types{$args{netfn}}, $args{command}, $command_string, $data_values);
|
||||
xCAT::SvrUtils::sendmsg([0, $msg], $self->{onlogon_args}->{outfunc});
|
||||
xCAT::SvrUtils::sendmsg([0, $msg], $self->{onlogon_args}->{outfunc}, $self->{node});
|
||||
}
|
||||
my $seqincrement = 7;
|
||||
while ($tabooseq{ $self->{expectednetfn} }->{ $self->{expectedcmd} }->{ $self->{seqlun} } and $seqincrement) { #avoid using a seqlun formerly marked 'taboo', but don't advance by more than 7, just in case
|
||||
@@ -679,9 +682,14 @@ sub handle_ipmi_packet {
|
||||
if ($rsp[5] & 0b10000000) {
|
||||
$encrypted = 1;
|
||||
}
|
||||
|
||||
#------------------------modified to support openbmc ipmi command----------------
|
||||
unless ($rsp[5] & 0b01000000) {
|
||||
return 3; #we refuse to examine unauthenticated packets in this context
|
||||
if ($self->{max_privilege} != 0) {
|
||||
return 3; #we refuse to examine unauthenticated packets in this context
|
||||
}
|
||||
}
|
||||
|
||||
splice(@rsp, 0, 4); #ditch the rmcp header
|
||||
my @authcode = splice(@rsp, -12); #strip away authcode and remember it
|
||||
my @expectedcode = unpack("C*", hmac_sha1(pack("C*", @rsp), $self->{k1}));
|
||||
@@ -763,10 +771,13 @@ sub got_rmcp_response {
|
||||
return 9;
|
||||
}
|
||||
$byte = shift @data;
|
||||
unless ($byte >= 4) {
|
||||
|
||||
# add $byte == 0 to support openbmc ipmi command
|
||||
unless ($byte >= 4 or $byte == 0) {
|
||||
$self->{onlogon}->("ERROR: Cannot acquire sufficient privilege", $self->{onlogon_args});
|
||||
return 9;
|
||||
}
|
||||
$self->{max_privilege} = $byte if ($byte == 0);
|
||||
splice @data, 0, 5;
|
||||
$self->{pendingsessionid} = [ splice @data, 0, 4 ];
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ use xCAT_monitoring::monitorctrl;
|
||||
use xCAT::TableUtils;
|
||||
|
||||
my $LOCK_DIR = "/var/lock/xcat/";
|
||||
my $LOCK_PATH = "/var/lock/xcat/agent-$$.lock";
|
||||
my $AGENT_SOCK_PATH = "/var/run/xcat/agent-$$.sock";
|
||||
my $LOCK_PATH = "/var/lock/xcat/agent.lock";
|
||||
my $AGENT_SOCK_PATH = "/var/run/xcat/agent.sock";
|
||||
my $PYTHON_LOG_PATH = "/var/log/xcat/agent.log";
|
||||
my $PYTHON_AGENT_FILE = "/opt/xcat/lib/python/agent/agent.py";
|
||||
my $MSG_TYPE = "message";
|
||||
@@ -62,8 +62,15 @@ sub send_request {
|
||||
# if lock is released unexpectedly, python side would aware of the error after
|
||||
# getting this lock
|
||||
sub acquire_lock {
|
||||
my $ppid = shift;
|
||||
$ppid = shift if (($ppid) && ($ppid =~ /OPENBMC/));
|
||||
|
||||
mkpath($LOCK_DIR);
|
||||
# always create a new lock file
|
||||
if ($ppid) {
|
||||
$LOCK_PATH = "$LOCK_PATH.$ppid";
|
||||
$AGENT_SOCK_PATH = "$AGENT_SOCK_PATH.$ppid";
|
||||
}
|
||||
unlink($LOCK_PATH);
|
||||
open($lock_fd, ">>", $LOCK_PATH) or return undef;
|
||||
flock($lock_fd, LOCK_EX) or return undef;
|
||||
@@ -82,7 +89,10 @@ sub python_agent_reaper {
|
||||
}
|
||||
sub start_python_agent {
|
||||
|
||||
if (!defined(acquire_lock())) {
|
||||
my $ppid = shift;
|
||||
$ppid = shift if (($ppid) && ($ppid =~ /OPENBMC/));
|
||||
|
||||
if (!defined(acquire_lock($ppid))) {
|
||||
xCAT::MsgUtils->message("S", "start_python_agent() Error: Failed to acquire lock");
|
||||
return undef;
|
||||
}
|
||||
|
||||
@@ -7,11 +7,14 @@ BEGIN
|
||||
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr';
|
||||
}
|
||||
use strict;
|
||||
use Date::Parse;
|
||||
use xCAT::Table;
|
||||
use xCAT::TableUtils;
|
||||
use xCAT::MsgUtils;
|
||||
use Data::Dumper;
|
||||
use xCAT::NodeRange;
|
||||
use xCAT::Utils;
|
||||
use Scalar::Util qw/looks_like_number/;
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
@@ -70,6 +73,11 @@ sub validate {
|
||||
return 0;
|
||||
}
|
||||
|
||||
my $remote_host = undef;
|
||||
if ($request->{'remote_client'} && defined($request->{'remote_client'}->[0])) {
|
||||
$remote_host = $request->{'remote_client'}->[0];
|
||||
}
|
||||
|
||||
my $policies = $policytable->getAllEntries;
|
||||
$policytable->close;
|
||||
my $rule;
|
||||
@@ -111,9 +119,20 @@ sub validate {
|
||||
#TODO: time ranges
|
||||
}
|
||||
if ($rule->{host} and $rule->{host} ne '*') {
|
||||
|
||||
#TODO: more complex matching (lists, noderanges?, wildcards)
|
||||
next unless ($peerhost eq $rule->{host});
|
||||
if (defined($remote_host) and $remote_host ne '') {
|
||||
my @tmp_hosts = split(",",$remote_host);
|
||||
my $found = 0;
|
||||
foreach my $tmp_host (@tmp_hosts) {
|
||||
if ($tmp_host eq $rule->{host}) {
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
next unless ($found);
|
||||
} else {
|
||||
next unless ($peerhost eq $rule->{host});
|
||||
}
|
||||
}
|
||||
if ($rule->{commands} and $rule->{commands} ne '*') {
|
||||
my @commands = split(",", $rule->{commands});
|
||||
@@ -351,36 +370,66 @@ sub validate {
|
||||
return 0;
|
||||
}
|
||||
|
||||
my $tokentimeout = 86400; # one day
|
||||
my $one_day = 86400; # one day in seconds
|
||||
my $days = 1; # default days for token expiration
|
||||
my $never_label = "never";
|
||||
|
||||
# this subroutine search the token table
|
||||
# 1. find the existed token entry for the user and reset the expire time
|
||||
# 1.1. if not find existed token, create a new one and add it to token table
|
||||
# 2. clean up the expired token
|
||||
# this subroutine creates a new token in token table
|
||||
# 1. If old style unix DateTime format token found in the token table
|
||||
# if expired -> remove it
|
||||
# if not expired -> replace unix DateTime expiration with new human readable format
|
||||
# 2. create a new token and add it to token table
|
||||
#
|
||||
# this subroutine is called after the account has been authorized
|
||||
sub gettoken {
|
||||
my $class = shift;
|
||||
my $req = shift;
|
||||
|
||||
my $current_time = time();
|
||||
my $user = $req->{gettoken}->[0]->{username}->[0];
|
||||
my $tokentb = xCAT::Table->new('token');
|
||||
unless ($tokentb) {
|
||||
return undef;
|
||||
}
|
||||
my $tokens = $tokentb->getAllEntries;
|
||||
|
||||
# Search for "old" style tokens containing unix DateTime format expiration date
|
||||
foreach my $token (@{$tokens}) {
|
||||
|
||||
#clean the expired token
|
||||
if ($token->{'expire'} < time()) {
|
||||
$tokentb->delEntries({ 'tokenid' => $token->{tokenid} });
|
||||
if ($token->{'expire'} and looks_like_number($token->{'expire'})) {
|
||||
# Expiration field contains only digits -> this is a old style token with unix DateTime format
|
||||
|
||||
if ($token->{'expire'} and ($token->{'expire'} < $current_time)) {
|
||||
# Clean expired token with old unix DateTime format
|
||||
$tokentb->delEntries({ tokenid => $token->{tokenid} });
|
||||
} else {
|
||||
# Change non-expired old style token to new human readable format
|
||||
$tokentb->setAttribs({ tokenid => $token->{tokenid}, username => $token->{'username'} }, {expire => xCAT::Utils->time2string($token->{'expire'}, "-")});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# create a new token for this request
|
||||
# create a new token id
|
||||
my $uuid = xCAT::Utils->genUUID();
|
||||
my $expiretime = time() + $tokentimeout;
|
||||
$tokentb->setAttribs({ tokenid => $uuid, username => $user }, { expire => $expiretime });
|
||||
# extract site table setting for number of days before token expires
|
||||
my $token_days = xCAT::TableUtils->get_site_attribute("tokenexpiredays");
|
||||
my $expiretime = $current_time + $one_day; # default is one day
|
||||
my $expire_time_string = xCAT::Utils->time2string($expiretime, "-");
|
||||
if ($token_days and (uc($token_days) eq uc($never_label))) {
|
||||
# Tokens never expire
|
||||
$expiretime = $never_label;
|
||||
$expire_time_string = $never_label;
|
||||
}
|
||||
elsif ($token_days and $token_days > 0) {
|
||||
# Use number of days from site table
|
||||
$days = $token_days;
|
||||
$expiretime = $current_time + $one_day * $days;
|
||||
$expire_time_string = xCAT::Utils->time2string($expiretime, "-");
|
||||
}
|
||||
my $access_time_string = xCAT::Utils->time2string($current_time, "-");
|
||||
# create a new token and set its expiration and creation time
|
||||
$tokentb->setAttribs({ tokenid => $uuid, username => $user },
|
||||
{ expire => $expire_time_string, created => $access_time_string });
|
||||
$tokentb->close();
|
||||
|
||||
return ($uuid, $expiretime);
|
||||
@@ -391,6 +440,7 @@ sub verifytoken {
|
||||
my $class = shift;
|
||||
my $req = shift;
|
||||
|
||||
my $current_time = time();
|
||||
my $tokenid = $req->{tokens}->[0]->{tokenid}->[0];
|
||||
my $tokentb = xCAT::Table->new('token');
|
||||
unless ($tokentb) {
|
||||
@@ -398,16 +448,33 @@ sub verifytoken {
|
||||
}
|
||||
my $token = $tokentb->getAttribs({ 'tokenid' => $tokenid }, ('username', 'expire'));
|
||||
if (defined($token) && defined($token->{'username'}) && defined($token->{'expire'})) {
|
||||
my $expiretime = time() + $tokentimeout;
|
||||
if ($token->{'expire'} < time()) {
|
||||
$tokentb->delEntries({ 'tokenid' => $token->{tokenid} });
|
||||
return undef;
|
||||
|
||||
if ($token->{'expire'} and looks_like_number($token->{'expire'})) {
|
||||
# Expiration field contains only digits -> this is a old style token with unix DateTime format
|
||||
if ($token->{'expire'} and $token->{'expire'} < $current_time) {
|
||||
# Clean expired token with old unix DateTime format
|
||||
$tokentb->delEntries({ 'tokenid' => $token->{tokenid} });
|
||||
return undef;
|
||||
} else {
|
||||
# Change non-expired old style token to new human readable format
|
||||
$tokentb->setAttribs({ tokenid => $tokenid, username => $token->{'username'} },
|
||||
{access => xCAT::Utils->time2string($current_time, "-"),
|
||||
expire => xCAT::Utils->time2string($token->{'expire'}, "-")});
|
||||
return $token->{'username'};
|
||||
}
|
||||
} else {
|
||||
return $token->{'username'};
|
||||
if ($token->{'expire'} and ($token->{'expire'} ne "never") and str2time($token->{'expire'}) < $current_time) {
|
||||
# Expired new style token
|
||||
return undef;
|
||||
} else {
|
||||
# Not expired new style token - update current access time
|
||||
$tokentb->setAttribs({ tokenid => $tokenid, username => $token->{'username'} }, {access => xCAT::Utils->time2string($current_time, "-")});
|
||||
return $token->{'username'};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# Token entry was not found
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -4555,17 +4555,19 @@ sub defmk_usage
|
||||
$rsp->{data}->[3] = " [-o object-names] [-z|--stanza ]";
|
||||
$rsp->{data}->[4] = " [-d | --dynamic] [-w attr==val [-w attr=~val] ...]";
|
||||
$rsp->{data}->[5] = " [-f | --force] [noderange] [attr=val [attr=val...]]";
|
||||
$rsp->{data}->[6] = "\nThe following data object types are supported by xCAT.\n";
|
||||
my $n = 6;
|
||||
$rsp->{data}->[6] = "\nThe following data object types are supported by xCAT:\n";
|
||||
my $n = 7;
|
||||
my $dataobj;
|
||||
|
||||
foreach my $t (sort(keys %{xCAT::Schema::defspec}))
|
||||
{
|
||||
$rsp->{data}->[$n] = "$t";
|
||||
$n++;
|
||||
$dataobj = $dataobj . ' ' . $t;
|
||||
}
|
||||
$rsp->{data}->[$n] = "$dataobj\n";
|
||||
$n++;
|
||||
$rsp->{data}->[$n] = "\nUse the \'-h\' option together with the \'-t\' option to";
|
||||
$n++;
|
||||
$rsp->{data}->[$n] = "get a list of valid attribute names for each object type.\n";
|
||||
$rsp->{data}->[$n] = " get a list of valid attribute names for each object type.\n";
|
||||
xCAT::MsgUtils->message("I", $rsp, $::callback);
|
||||
return 0;
|
||||
}
|
||||
@@ -4596,17 +4598,23 @@ sub defch_usage
|
||||
$rsp->{data}->[3] = " chdef [-V | --verbose] [-t object-types] [-o object-names] [-d | --dynamic]";
|
||||
$rsp->{data}->[4] = " [-z | --stanza] [-m | --minus] [-p | --plus]";
|
||||
$rsp->{data}->[5] = " [-w attr==val [-w attr=~val] ... ] [noderange] [attr=val [attr=val...]]\n";
|
||||
$rsp->{data}->[6] = "\nThe following data object types are supported by xCAT.\n";
|
||||
$rsp->{data}->[6] = "\nThe following data object types are supported by xCAT:\n";
|
||||
my $n = 7;
|
||||
my $dataobj;
|
||||
|
||||
foreach my $t (sort(keys %{xCAT::Schema::defspec}))
|
||||
{
|
||||
$rsp->{data}->[$n] = "$t";
|
||||
$n++;
|
||||
if ($dataobj) {
|
||||
$dataobj = $dataobj . ',' . $t;
|
||||
} else {
|
||||
$dataobj = $t;
|
||||
}
|
||||
}
|
||||
$rsp->{data}->[$n] = "$dataobj\n";
|
||||
$n++;
|
||||
$rsp->{data}->[$n] = "\nUse the \'-h\' option together with the \'-t\' option to";
|
||||
$n++;
|
||||
$rsp->{data}->[$n] = "get a list of valid attribute names for each object type.\n";
|
||||
$rsp->{data}->[$n] = " get a list of valid attribute names for each object type.\n";
|
||||
xCAT::MsgUtils->message("I", $rsp, $::callback);
|
||||
return 0;
|
||||
}
|
||||
@@ -4638,17 +4646,19 @@ sub defls_usage
|
||||
$rsp->{data}->[4] = " lsdef [-V | --verbose] [-t object-types] [-o object-names]";
|
||||
$rsp->{data}->[5] = " [ -l | --long] [-s | --short] [-a | --all] [-z | --stanza ] [-S]";
|
||||
$rsp->{data}->[6] = " [-i attr-list] [-w attr==val [-w attr=~val] ...] [noderange]\n";
|
||||
$rsp->{data}->[7] = "\nThe following data object types are supported by xCAT.\n";
|
||||
my $n = 6;
|
||||
$rsp->{data}->[7] = "\nThe following data object types are supported by xCAT:\n";
|
||||
my $n = 8;
|
||||
my $dataobj;
|
||||
|
||||
foreach my $t (sort(keys %{xCAT::Schema::defspec}))
|
||||
{
|
||||
$rsp->{data}->[$n] = "$t";
|
||||
$n++;
|
||||
$dataobj = $dataobj . ' ' . $t;
|
||||
}
|
||||
$rsp->{data}->[$n] = "$dataobj\n";
|
||||
$n++;
|
||||
$rsp->{data}->[$n] = "\nUse the \'-h\' option together with the \'-t\' option to";
|
||||
$n++;
|
||||
$rsp->{data}->[$n] = "get a list of valid attribute names for each object type.\n";
|
||||
$rsp->{data}->[$n] = " get a list of valid attribute names for each object type.\n";
|
||||
xCAT::MsgUtils->message("I", $rsp, $::callback);
|
||||
return 0;
|
||||
}
|
||||
@@ -4677,17 +4687,19 @@ sub defrm_usage
|
||||
$rsp->{data}->[1] = " rmdef [-h | --help ] [-t object-types]\n";
|
||||
$rsp->{data}->[2] = " rmdef [-V | --verbose] [-t object-types] [-a | --all] [-f | --force]";
|
||||
$rsp->{data}->[3] = " [-o object-names] [-C | --cleanup] [noderange]\n";
|
||||
$rsp->{data}->[4] = "\nThe following data object types are supported by xCAT.\n";
|
||||
$rsp->{data}->[4] = "\nThe following data object types are supported by xCAT:\n";
|
||||
my $n = 5;
|
||||
my $dataobj;
|
||||
|
||||
foreach my $t (sort(keys %{xCAT::Schema::defspec}))
|
||||
{
|
||||
$rsp->{data}->[$n] = "$t";
|
||||
$n++;
|
||||
$dataobj = $dataobj . ' ' . $t;
|
||||
}
|
||||
$rsp->{data}->[$n] = "$dataobj\n";
|
||||
$n++;
|
||||
$rsp->{data}->[$n] = "\nUse the \'-h\' option together with the \'-t\' option to";
|
||||
$n++;
|
||||
$rsp->{data}->[$n] = "get a list of valid attribute names for each object type.\n";
|
||||
$rsp->{data}->[$n] = " get a list of valid attribute names for each object type.\n";
|
||||
xCAT::MsgUtils->message("I", $rsp, $::callback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ use HTTP::Cookies;
|
||||
use HTTP::Response;
|
||||
use JSON;
|
||||
|
||||
my $log_label = "bmcdiscover:";
|
||||
my $nmap_path;
|
||||
my %ipmac = ();
|
||||
|
||||
@@ -595,6 +596,7 @@ sub scan_process {
|
||||
$bcmd = join(" ", $nmap_path, " -sn -n $range");
|
||||
}
|
||||
|
||||
xCAT::MsgUtils->trace(0, "I", "$log_label Try to scan live IPs by command $bcmd ...");
|
||||
$ip_info_list = xCAT::Utils->runcmd("$bcmd", -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp = {};
|
||||
@@ -617,7 +619,7 @@ sub scan_process {
|
||||
my $live_mac = split_comma_delim_str($mac_list);
|
||||
my %pipe_map;
|
||||
if (scalar(@{$live_ip}) > 0) {
|
||||
|
||||
xCAT::MsgUtils->trace(0, "I", "$log_label Scaned live IPs " . scalar(@{$live_ip}) . " with mac " . scalar(@{$live_mac}));
|
||||
foreach (@{$live_ip}) {
|
||||
my $new_mac = lc(shift @{$live_mac});
|
||||
$new_mac =~ s/\://g;
|
||||
@@ -696,7 +698,11 @@ sub scan_process {
|
||||
my $is_openbmc = 0;
|
||||
foreach my $mc_cmd (@mc_cmds) {
|
||||
$mc_info = xCAT::Utils->runcmd($mc_cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
next;
|
||||
}
|
||||
if ($mc_info =~ /Manufacturer ID\s*:\s*(\d+)\s*Manufacturer Name.+\s*Product ID\s*:\s*(\d+)/) {
|
||||
xCAT::MsgUtils->trace(0, "D", "$log_label Found ${$live_ip}[$i] Manufacturer ID: $1 Product ID: $2");
|
||||
if ($1 eq $::P9_WITHERSPOON_MFG_ID and $2 eq $::P9_WITHERSPOON_PRODUCT_ID) {
|
||||
bmcdiscovery_openbmc(${$live_ip}[$i], $opz, $opw, $request_command,$parent_fd);
|
||||
$is_openbmc = 1;
|
||||
@@ -756,7 +762,7 @@ sub format_stanza {
|
||||
my $node = shift;
|
||||
my $data = shift;
|
||||
my $mgt_type = shift;
|
||||
my ($bmcip, $bmcmtm, $bmcserial, $bmcuser, $bmcpass, $nodetype, $hwtype, $sn, $conserver) = split(/,/, $data);
|
||||
my ($bmcip, $bmcmtm, $bmcserial, $bmcuser, $bmcpass, $nodetype, $hwtype, $mac, $sn, $conserver) = split(/,/, $data);
|
||||
my $result;
|
||||
if (defined($bmcip)) {
|
||||
$result .= "$node:\n\tobjtype=node\n";
|
||||
@@ -803,7 +809,7 @@ sub write_to_xcatdb {
|
||||
my $node = shift;
|
||||
my $data = shift;
|
||||
my $mgt_type = shift;
|
||||
my ($bmcip, $bmcmtm, $bmcserial, $bmcuser, $bmcpass, $nodetype, $hwtype, $sn, $conserver) = split(/,/, $data);
|
||||
my ($bmcip, $bmcmtm, $bmcserial, $bmcuser, $bmcpass, $nodetype, $hwtype, $mac, $sn, $conserver) = split(/,/, $data);
|
||||
my $request_command = shift;
|
||||
my $ret;
|
||||
|
||||
@@ -813,10 +819,10 @@ sub write_to_xcatdb {
|
||||
"bmcusername=$bmcuser", "bmcpassword=$bmcpass", "nodetype=$nodetype",
|
||||
"servicenode=$sn", "conserver=$conserver",
|
||||
"hwtype=$hwtype", "groups=all" ] },
|
||||
$request_command, 0, 1);
|
||||
$request_command, -1, 1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp = {};
|
||||
push @{ $rsp->{data} }, "create or modify node is failed.\n";
|
||||
push @{ $rsp->{data} }, "Failed to run chdef command for node=$node\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return 2;
|
||||
}
|
||||
@@ -1044,6 +1050,9 @@ sub bmcdiscovery_ipmi {
|
||||
$bmcpassword = "-P $bmc_pass";
|
||||
}
|
||||
|
||||
my $log_info = "$ip: Detected ipmi, attempting to obtain system information...";
|
||||
xCAT::MsgUtils->trace(0, "D", "$log_label $log_info");
|
||||
|
||||
my $mtms_node = "";
|
||||
my $mac_node = "";
|
||||
|
||||
@@ -1112,15 +1121,17 @@ sub bmcdiscovery_ipmi {
|
||||
} else {
|
||||
$node_data .= ",,";
|
||||
}
|
||||
$node_data .= ",mp,bmc,$::opt_SN,$::opt_SN";
|
||||
$node_data .= ",mp,bmc";
|
||||
if ($mtm and $serial) {
|
||||
$mtms_node = "node-$mtm-$serial";
|
||||
$mtms_node =~ s/(.*)/\L$1/g;
|
||||
$mtms_node =~ s/[\s:\._]/-/g;
|
||||
}
|
||||
if ($ipmac{$ip}) {
|
||||
$node_data .= ",";
|
||||
} elsif ($ipmac{$ip}) {
|
||||
$mac_node = "node-$ipmac{$ip}";
|
||||
$node_data .= ",$ipmac{$ip}";
|
||||
}
|
||||
$node_data .= ",$::opt_SN,$::opt_SN";
|
||||
} elsif ($output =~ /error : unauthorized name/) {
|
||||
xCAT::MsgUtils->message("W", { data => ["BMC username is incorrect for $ip"] }, $::CALLBACK);
|
||||
return;
|
||||
@@ -1158,7 +1169,10 @@ sub bmcdiscovery_openbmc{
|
||||
my $mac_node = "";
|
||||
|
||||
store_fd({data=>1}, $fd);
|
||||
print "$ip: Detected openbmc, attempting to obtain system information...\n";
|
||||
my $log_info = "$ip: Detected openbmc, attempting to obtain system information...";
|
||||
print "$log_info\n";
|
||||
xCAT::MsgUtils->trace(0, "D", "$log_label $log_info");
|
||||
|
||||
my $http_protocol="https";
|
||||
my $openbmc_project_url = "xyz/openbmc_project";
|
||||
my $login_endpoint = "login";
|
||||
@@ -1230,18 +1244,26 @@ sub bmcdiscovery_openbmc{
|
||||
} else {
|
||||
$node_data .= ",,";
|
||||
}
|
||||
$node_data .= ",mp,bmc,$::opt_SN,$::opt_SN";
|
||||
$node_data .= ",mp,bmc";
|
||||
if ($mtm and $serial) {
|
||||
$mtms_node = "node-$mtm-$serial";
|
||||
$mtms_node =~ s/(.*)/\L$1/g;
|
||||
$mtms_node =~ s/[\s:\._]/-/g;
|
||||
}
|
||||
if ($ipmac{$ip}) {
|
||||
$node_data .= ",";
|
||||
} elsif ($ipmac{$ip}) {
|
||||
$mac_node = "node-$ipmac{$ip}";
|
||||
$node_data .= ",$ipmac{$ip}";
|
||||
}
|
||||
$node_data .= ",$::opt_SN,$::opt_SN";
|
||||
} else {
|
||||
if ($login_response->status_line =~ /401 Unauthorized/) {
|
||||
xCAT::MsgUtils->message("W", { data => ["Invalid username or password for $ip"] }, $::CALLBACK);
|
||||
my $login_status;
|
||||
eval { $login_status = $login_response->status_line };
|
||||
if ($@) {
|
||||
xCAT::MsgUtils->message("W", { data => ["Login failed for $ip and no status received from response"] }, $::CALLBACK);
|
||||
return;
|
||||
}
|
||||
if ($login_status =~ /401 Unauthorized/) {
|
||||
xCAT::MsgUtils->message("W", { data => ["Invalid username or password for $ip"] }, $::CALLBACK);
|
||||
} else {
|
||||
xCAT::MsgUtils->message("W", { data => ["Received response " . $login_response->status_line . " for $ip"] }, $::CALLBACK);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use Cwd;
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
|
||||
my $xcatdebugmode = 0;
|
||||
my $processed = 0;
|
||||
my $callback;
|
||||
|
||||
@@ -75,6 +76,9 @@ sub process_request {
|
||||
$callback->({ error => "copycds needs at least one full path to ISO currently.", errorcode => [1] });
|
||||
return;
|
||||
}
|
||||
|
||||
if ($::XCATSITEVALS{xcatdebugmode}) { $xcatdebugmode = $::XCATSITEVALS{xcatdebugmode} }
|
||||
|
||||
my $file;
|
||||
foreach (@args) {
|
||||
$identified = 0;
|
||||
@@ -111,6 +115,29 @@ sub process_request {
|
||||
|
||||
return;
|
||||
}
|
||||
if (grep /$file: data/, @filestat) {
|
||||
if ($xcatdebugmode) {
|
||||
$callback->({ info => "run copydata for data file = $file" });
|
||||
}
|
||||
my $newreq = dclone($request);
|
||||
$newreq->{command} = ['copydata']; #Note the singular, it's different
|
||||
$newreq->{arg} = [ "-f", $file ];
|
||||
if ($inspection)
|
||||
{
|
||||
push @{ $newreq->{arg} }, ("-i");
|
||||
}
|
||||
if ($nonoverwrite)
|
||||
{
|
||||
push @{ $newreq->{arg} }, ("-w");
|
||||
}
|
||||
if ($noosimage)
|
||||
{
|
||||
push @{ $newreq->{arg} }, ("-o");
|
||||
}
|
||||
|
||||
$doreq->($newreq, $callback);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $mntopts = "-t udf,iso9660"; #Prefer udf formate to iso when media supports both, like MS media
|
||||
|
||||
@@ -1528,7 +1528,7 @@ sub add_or_delete_records {
|
||||
next;
|
||||
}
|
||||
if ($reply->header->rcode ne 'NOERROR') {
|
||||
xCAT::SvrUtils::sendmsg([ 1, "Failure encountered updating $zone, error was " . $reply->header->rcode . ". See more details in system log." ], $callback);
|
||||
xCAT::SvrUtils::sendmsg([ 1, "Failure encountered updating $zone with entry '$entry', error was " . $reply->header->rcode . ". See more details in system log." ], $callback);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1549,7 +1549,7 @@ sub add_or_delete_records {
|
||||
next;
|
||||
}
|
||||
if ($reply->header->rcode ne 'NOERROR') {
|
||||
xCAT::SvrUtils::sendmsg([ 1, "Failure encountered updating $zone, error was " . $reply->header->rcode . ". See more details in system log." ], $callback);
|
||||
xCAT::SvrUtils::sendmsg([ 1, "Failure encountered updating $zone with entry '$entry', error was " . $reply->header->rcode . ". See more details in system log." ], $callback);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -786,6 +786,11 @@ sub mkinstall {
|
||||
(
|
||||
($arch =~ /x86/ and
|
||||
(
|
||||
(-r "$pkgdir/install/hwe-netboot/ubuntu-installer/$darch/linux"
|
||||
and $kernpath = "$pkgdir/hwe-install/netboot/ubuntu-installer/$darch/linux"
|
||||
and -r "$pkgdir/install/hwe-netboot/ubuntu-installer/$darch/initrd.gz"
|
||||
and $initrdpath = "$pkgdir/install/hwe-netboot/ubuntu-installer/$darch/initrd.gz"
|
||||
) or
|
||||
(-r "$pkgdir/install/netboot/ubuntu-installer/$darch/linux"
|
||||
and $kernpath = "$pkgdir/install/netboot/ubuntu-installer/$darch/linux"
|
||||
and -r "$pkgdir/install/netboot/ubuntu-installer/$darch/initrd.gz"
|
||||
|
||||
@@ -185,6 +185,11 @@ sub setdestiny {
|
||||
$state = $stents{$_}->[0]->{currstate};
|
||||
$state =~ s/ .*//;
|
||||
|
||||
#skip the node if state=ondiscover
|
||||
if ($state eq 'ondiscover') {
|
||||
next;
|
||||
}
|
||||
|
||||
#get the osimagename if nodetype.provmethod has osimage specified
|
||||
#use it for both sninit and genesis operating
|
||||
if (($state eq 'install') || ($state eq 'netboot') || ($state eq 'statelite')) {
|
||||
@@ -848,6 +853,11 @@ sub nextdestiny {
|
||||
}
|
||||
unless ($ref->{currchain}) { #If no current chain, copy the default
|
||||
$ref->{currchain} = $ref->{chain};
|
||||
} elsif ($ref->{currchain} !~ /[,;]/){
|
||||
if ($ref->{currstate} and ($ref->{currchain} =~ /$ref->{currstate}/)) {
|
||||
$ref->{currchain} = 'standby';
|
||||
$callnodeset = 0;
|
||||
}
|
||||
}
|
||||
my @chain = split /[,;]/, $ref->{currchain};
|
||||
|
||||
@@ -915,6 +925,16 @@ sub getdestiny {
|
||||
my %node_status = ();
|
||||
foreach $node (@$nodes) {
|
||||
unless ($chaintab) { #Without destiny, have the node wait with ssh hopefully open at least
|
||||
my $stat = xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState("standby", "getdestiny");
|
||||
if ($stat) {
|
||||
if (exists($node_status{$stat})) {
|
||||
push @{ $node_status{$stat} }, $node;
|
||||
} else {
|
||||
$node_status{$stat} = [$node];
|
||||
}
|
||||
xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%node_status, 1);
|
||||
}
|
||||
|
||||
$callback->({ node => [ { name => [$node], data => ['standby'], destiny => ['standby'] } ] });
|
||||
return;
|
||||
}
|
||||
@@ -928,10 +948,10 @@ sub getdestiny {
|
||||
#print "node=$node, stat=$stat\n";
|
||||
if ($stat) {
|
||||
if (exists($node_status{$stat})) {
|
||||
my $pa = $node_status{$stat};
|
||||
push(@$pa, $node);
|
||||
push @{ $node_status{$stat} }, $node;
|
||||
} else {
|
||||
$node_status{$stat} = [$node];
|
||||
}
|
||||
else { $node_status{$stat} = [$node]; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -979,10 +999,10 @@ sub getdestiny {
|
||||
#print "node=$node, stat=$stat\n";
|
||||
if ($stat) {
|
||||
if (exists($node_status{$stat})) {
|
||||
my $pa = $node_status{$stat};
|
||||
push(@$pa, $node);
|
||||
push @{ $node_status{$stat} }, $node;
|
||||
} else {
|
||||
$node_status{$stat} = [$node];
|
||||
}
|
||||
else { $node_status{$stat} = [$node]; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -693,7 +693,31 @@ sub addnode
|
||||
} elsif ($nrent and $nrent->{netboot} and $nrent->{netboot} eq 'petitboot') {
|
||||
$lstatements = 'option conf-file \"http://' . $nxtsrv . '/tftpboot/petitboot/' . $node . '\";' . $lstatements;
|
||||
} elsif ($nrent and $nrent->{netboot} and $nrent->{netboot} eq 'onie') {
|
||||
$lstatements = 'if substring (option vendor-class-identifier,0,11) = \"onie_vendor\" { option www-server = \"http://' . $nxtsrv . $ntent->{provmethod} . '\";}' . $lstatements;
|
||||
my $provmethod = $ntent->{provmethod};
|
||||
if ($provmethod) {
|
||||
my $linuximagetab = xCAT::Table->new('linuximage');
|
||||
my $imagetab = $linuximagetab->getAttribs({ imagename => $provmethod }, 'pkgdir');
|
||||
if ($imagetab) {
|
||||
my $image_pkgdir = $imagetab->{'pkgdir'};
|
||||
my @pkgdirs = split(/,/,$image_pkgdir);
|
||||
my $validpkgdir;
|
||||
foreach my $mypkgdir (@pkgdirs){
|
||||
if (-f $mypkgdir) {
|
||||
$lstatements = 'if substring (option vendor-class-identifier,0,11) = \"onie_vendor\" { option www-server = \"http://' . $nxtsrv . $mypkgdir . '\";}' . $lstatements;
|
||||
$validpkgdir = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
unless ($validpkgdir) {
|
||||
$callback->({ warning => ["osimage $provmethod pkgdir doesn't exists"]});
|
||||
}
|
||||
} else {
|
||||
$callback->({ warning => ["osimage $provmethod is not defined in the osimage table"]});
|
||||
}
|
||||
} else {
|
||||
$callback->({ warning => ["provmethod is not defined for $node"]});
|
||||
}
|
||||
|
||||
} elsif ($nrent and $nrent->{netboot} and $nrent->{netboot} eq 'nimol') {
|
||||
$lstatements = 'supersede server.filename=\"/vios/nodes/' . $node . '\";' . $lstatements;
|
||||
}
|
||||
|
||||
@@ -9045,7 +9045,7 @@ sub donode {
|
||||
on_bmc_connect(0, $sessiondata{$node});
|
||||
return 0;
|
||||
}
|
||||
$sessiondata{$node}->{ipmisession} = xCAT::IPMI->new(bmc => $bmcip, userid => $user, password => $pass);
|
||||
$sessiondata{$node}->{ipmisession} = xCAT::IPMI->new(bmc => $bmcip, userid => $user, password => $pass, node => $node);
|
||||
if ($sessiondata{$node}->{ipmisession}->{error}) {
|
||||
xCAT::SvrUtils::sendmsg([ 1, $sessiondata{$node}->{ipmisession}->{error} ], $callback, $node, %allerrornodes);
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
#!/usr/bin/env perl
|
||||
## IBM(c) 20013 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# This plugin is used to handle the command requests for cumulus OS support
|
||||
#
|
||||
|
||||
|
||||
package xCAT_plugin::onie;
|
||||
|
||||
BEGIN
|
||||
{
|
||||
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
||||
}
|
||||
use lib "$::XCATROOT/lib/perl";
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use File::Path;
|
||||
use File::Basename;
|
||||
|
||||
use xCAT::Utils;
|
||||
use xCAT::MsgUtils;
|
||||
use xCAT::TableUtils;
|
||||
use xCAT::SvrUtils;
|
||||
use xCAT::Table;
|
||||
my $xcatdebugmode = 0;
|
||||
$::VERBOSE = 0;
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
nodeset => 'nodehm:mgt=switch',
|
||||
copydata => 'onie',
|
||||
}
|
||||
}
|
||||
|
||||
my $CALLBACK; # used to hanel the output from xdsh
|
||||
|
||||
sub preprocess_request {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
|
||||
if ($request->{command}->[0] eq 'copydata')
|
||||
{
|
||||
return [$request];
|
||||
}
|
||||
|
||||
# if already preprocessed, go straight to request
|
||||
if ((defined($request->{_xcatpreprocessed}->[0]))
|
||||
&& ($request->{_xcatpreprocessed}->[0] == 1)) {
|
||||
return [$request];
|
||||
}
|
||||
|
||||
my $nodes = $request->{node};
|
||||
my $command = $request->{command}->[0];
|
||||
my $extraargs = $request->{arg};
|
||||
|
||||
if ($extraargs) {
|
||||
@ARGV = @{$extraargs};
|
||||
my ($verbose, $help, $ver);
|
||||
GetOptions("V" => \$verbose, 'h|help' => \$help, 'v|version' => \$ver);
|
||||
if ($help) {
|
||||
my $usage_string = xCAT::Usage->getUsage($command);
|
||||
my $rsp;
|
||||
push @{ $rsp->{data} }, $usage_string;
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
return ();
|
||||
}
|
||||
if ($ver) {
|
||||
my $ver_string = xCAT::Usage->getVersion($command);
|
||||
my $rsp;
|
||||
push @{ $rsp->{data} }, $ver_string;
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
return ();
|
||||
}
|
||||
|
||||
if ($verbose) {
|
||||
$::VERBOSE = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return [$request];
|
||||
}
|
||||
|
||||
sub process_request {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $subreq = shift;
|
||||
|
||||
my $nodes = $request->{node};
|
||||
my $command = $request->{command}->[0];
|
||||
my $args = $request->{arg};
|
||||
|
||||
if ($::XCATSITEVALS{xcatdebugmode} != 0) { $::VERBOSE = 1}
|
||||
|
||||
if ($command eq "copydata") {
|
||||
copydata($request, $callback);
|
||||
} elsif ($command eq "nodeset") {
|
||||
nodeset($request, $callback, $subreq);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# build cumulus OS image
|
||||
sub copydata {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $file;
|
||||
my $inspection = undef;
|
||||
my $noosimage = undef;
|
||||
my $nooverwrite = undef;
|
||||
|
||||
# get arguments
|
||||
my $args = $request->{arg};
|
||||
if ($args) {
|
||||
@ARGV = @{$args};
|
||||
GetOptions(
|
||||
'w' => \$nooverwrite,
|
||||
'o' => \$noosimage,
|
||||
'i' => \$inspection,
|
||||
'f=s' => \$file
|
||||
);
|
||||
}
|
||||
|
||||
if (!(-x $file)) {
|
||||
xCAT::MsgUtils->message("E", { error => ["$file is not executable, will not process"], errorcode => ["1"] }, $callback);
|
||||
return;
|
||||
}
|
||||
|
||||
#get install dir
|
||||
my $installroot = "/install";
|
||||
my $sitetab = xCAT::Table->new('site');
|
||||
my @ents = xCAT::TableUtils->get_site_attribute("installdir");
|
||||
my $site_ent = $ents[0];
|
||||
if (defined($site_ent))
|
||||
{
|
||||
$installroot = $site_ent;
|
||||
}
|
||||
|
||||
my $arch;
|
||||
my $desc;
|
||||
my $release;
|
||||
my $osname;
|
||||
my $filename = basename($file);
|
||||
my $output = `$file`;
|
||||
if ($inspection) {
|
||||
$callback->({ data => "file output: $output" });
|
||||
return;
|
||||
}
|
||||
foreach my $line (split /[\r\n]+/, $output) {
|
||||
if ($line =~ /^Architecture/) {
|
||||
($desc, $arch) = split /: /, $line ;
|
||||
chomp $arch;
|
||||
}
|
||||
if ($line =~ /^Release/) {
|
||||
($desc, $release) = split /: /, $line ;
|
||||
chomp $release;
|
||||
}
|
||||
if ($line =~ /cumulus/) {
|
||||
$osname = "cumulus" ;
|
||||
}
|
||||
}
|
||||
unless ($osname) {
|
||||
$osname="image";
|
||||
}
|
||||
|
||||
my $distname = $osname . $release;
|
||||
my $imagename = $distname . "-" . $arch;
|
||||
my $defaultpath = "$installroot/$distname/$arch";
|
||||
|
||||
#check if file exists
|
||||
if ( (-e "$defaultpath/$filename") && ($nooverwrite)){
|
||||
$callback->({ data => "$defaultpath/$filename is already exists, will not overwrite" });
|
||||
} else {
|
||||
$callback->({ data => "Copying media to $defaultpath" });
|
||||
mkpath ("$defaultpath");
|
||||
system("cp $file $defaultpath");
|
||||
$callback->({ data => "Media copy operation successful" });
|
||||
}
|
||||
|
||||
if ($noosimage) {
|
||||
$callback->({ data => "Option noosimage is specified, will not create osimage definition" });
|
||||
return;
|
||||
}
|
||||
|
||||
# generate the image objects
|
||||
my $oitab = xCAT::Table->new('osimage');
|
||||
unless ($oitab) {
|
||||
xCAT::MsgUtils->message("E", { error => ["Error: Cannot open table osimage."], errorcode => ["1"] }, $callback);
|
||||
return 1;
|
||||
}
|
||||
my $litab = xCAT::Table->new('linuximage');
|
||||
unless ($litab) {
|
||||
xCAT::MsgUtils->message("E", { error => ["Error: Cannot open table linuximage."], errorcode => ["1"] }, $callback);
|
||||
return 1;
|
||||
}
|
||||
my $pkgdir = "$defaultpath/$filename";
|
||||
my $imgdir = $litab->getAttribs({ 'imagename' => $imagename }, 'pkgdir');
|
||||
|
||||
if ($::VERBOSE) {
|
||||
$callback->({ data => "creating image $imagename with osarch=$arch, osvers=$distname" });
|
||||
}
|
||||
|
||||
my %values;
|
||||
$values{'imagetype'} = "linux";
|
||||
$values{'provmethod'} = "install";
|
||||
$values{'description'} = "Cumulus Linux";
|
||||
$values{'osname'} = "$osname";
|
||||
$values{'osvers'} = "$distname";
|
||||
$values{'osarch'} = "$arch";
|
||||
|
||||
$oitab->setAttribs({ 'imagename' => $imagename }, \%values);
|
||||
|
||||
# set a default package list
|
||||
$litab->setAttribs({ 'imagename' => $imagename }, { 'pkgdir' => $pkgdir });
|
||||
if ($::VERBOSE) {
|
||||
$callback->({ data => "setting pkgdir=$pkgdir for image $imagename" });
|
||||
}
|
||||
|
||||
#Need to update osdistro table?
|
||||
my @ret = xCAT::SvrUtils->update_osdistro_table($distname, $arch, $defaultpath, $imagename);
|
||||
if ($ret[0] != 0) {
|
||||
xCAT::MsgUtils->message("E", { error => ["Error when updating the osdistro tables."], errorcode => ["1"] }, $callback);
|
||||
}
|
||||
|
||||
xCAT::MsgUtils->message("I", { data => ["The image $imagename is created."] }, $callback);
|
||||
}
|
||||
|
||||
|
||||
# run the nodeset to updatenode provmethod
|
||||
sub nodeset {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $subreq = shift;
|
||||
|
||||
my $switches = $request->{'node'};
|
||||
my $args = $request->{arg};
|
||||
my $provmethod;
|
||||
my $image_pkgdir;
|
||||
|
||||
my $setosimg;
|
||||
foreach (@$args) {
|
||||
if (/osimage=(.*)/) {
|
||||
$setosimg = $1;
|
||||
}
|
||||
}
|
||||
|
||||
my $switchestab = xCAT::Table->new('switches');
|
||||
my $switcheshash = $switchestab->getNodesAttribs($switches, ['switchtype']);
|
||||
|
||||
my $nodetab = xCAT::Table->new('nodetype');
|
||||
my $nodehash = $nodetab->getNodesAttribs($switches, [ 'provmethod' ]);
|
||||
|
||||
foreach my $switch (@$switches) {
|
||||
if ($switcheshash->{$switch}->[0]->{switchtype} ne "onie") {
|
||||
xCAT::MsgUtils->message("E", { error => ["nodeset command is not processed for $switch, only supports switchtype=onie"], errorcode => ["1"] }, $callback);
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
if ($setosimg) {
|
||||
$provmethod = $setosimg;
|
||||
} else {
|
||||
$provmethod = $nodehash->{$switch}->[0]->{provmethod};
|
||||
}
|
||||
if ($::VERBOSE) {
|
||||
xCAT::MsgUtils->message("I", { data => ["$switch has provmethod=$provmethod"] }, $callback);
|
||||
}
|
||||
|
||||
#get pkgdir from osimage
|
||||
my $linuximagetab = xCAT::Table->new('linuximage');
|
||||
my $osimagetab = xCAT::Table->new('osimage');
|
||||
my $imagetab = $linuximagetab->getAttribs({ imagename => $provmethod },'pkgdir');
|
||||
my $osimghash = $osimagetab->getAttribs({ imagename => $provmethod },'osvers','osarch');
|
||||
unless($imagetab and $osimghash){
|
||||
xCAT::MsgUtils->message("E", { error => ["cannot find osimage \"$provmethod\" for $switch, please make sure the osimage specified in command line or node.provmethod exists!"], errorcode => ["1"] }, $callback);
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
my %attribs=('provmethod' => $provmethod,'os'=>$osimghash->{'osvers'},'arch'=>$osimghash->{'osarch'} );
|
||||
$nodetab->setAttribs({ 'node' => $switch }, \%attribs);
|
||||
$image_pkgdir = $imagetab->{'pkgdir'};
|
||||
|
||||
#validate the image pkgdir
|
||||
my $flag=0;
|
||||
if (-r $image_pkgdir) {
|
||||
my @filestat = `file $image_pkgdir`;
|
||||
if (grep /$image_pkgdir: data/, @filestat) {
|
||||
$flag=1;
|
||||
}
|
||||
}
|
||||
unless ($flag) {
|
||||
xCAT::MsgUtils->message("E", { error => ["The image '$image_pkgdir' is invalid"], errorcode => ["1"] }, $callback);
|
||||
next;
|
||||
}
|
||||
if ($::VERBOSE) {
|
||||
xCAT::MsgUtils->message("I", { data => ["osimage=$provmethod, pkgdir=$image_pkgdir"] }, $callback);
|
||||
}
|
||||
|
||||
#updateing DHCP entries
|
||||
my $ret = xCAT::Utils->runxcmd({ command => ["makedhcp"], node => [$switch] }, $subreq, 0, 1);
|
||||
if ($::RUNCMD_RC) {
|
||||
xCAT::MsgUtils->message("E", { error => ["Failed to run 'makedhcp' command"], errorcode => ["$::RUNCMD_RC"] }, $callback);
|
||||
}
|
||||
|
||||
xCAT::MsgUtils->message("I", { data => ["$switch: install $provmethod"] }, $callback);
|
||||
}
|
||||
return;
|
||||
}
|
||||
1;
|
||||
@@ -803,6 +803,14 @@ sub preprocess_request {
|
||||
return;
|
||||
}
|
||||
|
||||
#pdu commands will be handled in the pdu plugin
|
||||
if ($command eq "rpower") {
|
||||
my $subcmd = $exargs[0];
|
||||
if(($subcmd eq 'pduoff') || ($subcmd eq 'pduon') || ($subcmd eq 'pdustat') || ($subcmd eq 'pdureset')){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $parse_result = parse_args($command, $extrargs, $noderange);
|
||||
if (ref($parse_result) eq 'ARRAY') {
|
||||
my $error_data;
|
||||
@@ -953,8 +961,8 @@ sub process_request {
|
||||
|
||||
while (1) {
|
||||
last if ($child_num == 0 and !@nodes_login);
|
||||
my $cpid;
|
||||
while (($cpid = waitpid(-1, WNOHANG)) > 0) {
|
||||
my $cpid = waitpid(-1, WNOHANG);
|
||||
if ($cpid > 0) {
|
||||
if ($login_pid_node{$cpid}) {
|
||||
$child_num--;
|
||||
my $node = $login_pid_node{$cpid};
|
||||
@@ -964,7 +972,12 @@ sub process_request {
|
||||
}
|
||||
delete $login_pid_node{$cpid};
|
||||
}
|
||||
} elsif ($cpid == 0) {
|
||||
select(undef, undef, undef, 0.01);
|
||||
} elsif ($cpid < 0 and !@nodes_login) {
|
||||
last;
|
||||
}
|
||||
|
||||
if (@nodes_login) {
|
||||
if ($child_num < $max_child_num) {
|
||||
my $node = shift @nodes_login;
|
||||
@@ -1073,23 +1086,26 @@ rmdir \"/tmp/\$userid\" \n";
|
||||
while (my ($response, $handle_id) = $async->wait_for_next_response) {
|
||||
deal_with_response($handle_id, $response);
|
||||
}
|
||||
while ((my $cpid = waitpid(-1, WNOHANG)) > 0) {
|
||||
if ($child_node_map{$cpid}) {
|
||||
my $node = $child_node_map{$cpid};
|
||||
my $rc = $? >> 8;
|
||||
if ($rc != 0) {
|
||||
$wait_node_num--;
|
||||
} else {
|
||||
if ($status_info{ $node_info{$node}{cur_status} }->{process}) {
|
||||
$status_info{ $node_info{$node}{cur_status} }->{process}->($node, undef);
|
||||
} else {
|
||||
xCAT::SvrUtils::sendmsg([1,"Internal error, check the process handler for current status "
|
||||
.$node_info{$node}{cur_status}."."], $callback, $node);
|
||||
$wait_node_num--;
|
||||
}
|
||||
|
||||
if (%child_node_map) {
|
||||
while ((my $cpid = waitpid(-1, WNOHANG)) > 0) {
|
||||
if ($child_node_map{$cpid}) {
|
||||
my $node = $child_node_map{$cpid};
|
||||
my $rc = $? >> 8;
|
||||
if ($rc != 0) {
|
||||
$wait_node_num--;
|
||||
} else {
|
||||
if ($status_info{ $node_info{$node}{cur_status} }->{process}) {
|
||||
$status_info{ $node_info{$node}{cur_status} }->{process}->($node, undef);
|
||||
} else {
|
||||
xCAT::SvrUtils::sendmsg([1,"Internal error, check the process handler for current status "
|
||||
.$node_info{$node}{cur_status}."."], $callback, $node);
|
||||
$wait_node_num--;
|
||||
}
|
||||
|
||||
}
|
||||
delete $child_node_map{$cpid};
|
||||
}
|
||||
delete $child_node_map{$cpid};
|
||||
}
|
||||
}
|
||||
my @del;
|
||||
@@ -4625,6 +4641,7 @@ sub rflash_upload {
|
||||
# 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_check_cpu_dd_cmd = "curl -b $cjar_id -k -H 'Content-Type: application/json' -X GET $request_url/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0 | grep Version | cut -d: -f2";
|
||||
|
||||
if (%fw_tar_files) {
|
||||
foreach my $key (keys %fw_tar_files) {
|
||||
@@ -4656,6 +4673,17 @@ sub rflash_upload {
|
||||
}
|
||||
if ($h->{message} eq $::RESPONSE_OK) {
|
||||
if(%curl_upload_cmds){
|
||||
# Before uploading file, check CPU DD version
|
||||
my $curl_dd_check_result = `$curl_check_cpu_dd_cmd`;
|
||||
if ($curl_dd_check_result =~ "20") {
|
||||
# Display warning the only certain firmware versions are supported on DD 2.0
|
||||
xCAT::SvrUtils::sendmsg("Warning: DD 2.0 processor detected on this node, should not have firmware > ibm-v2.0-0-r13.6 (BMC) and > v1.19_1.94 (Host).", $callback, $node);
|
||||
}
|
||||
if ($curl_dd_check_result =~ "21") {
|
||||
if ($::VERBOSE) {
|
||||
xCAT::SvrUtils::sendmsg("DD 2.1 processor", $callback, $node);
|
||||
}
|
||||
}
|
||||
while((my $file,my $version)=each(%fw_tar_files)){
|
||||
my $uploading_msg = "Uploading $file ...";
|
||||
my $upload_cmd = $curl_upload_cmds{$file};
|
||||
|
||||
@@ -73,13 +73,27 @@ sub preprocess_request {
|
||||
if (ref($extrargs)) {
|
||||
@exargs = @$extrargs;
|
||||
}
|
||||
my $usage_string = xCAT::Usage->parseCommand($command, @exargs);
|
||||
# Request usage for openbmc sections only
|
||||
my $usage_string = xCAT::Usage->parseCommand($command . ".openbmc", @exargs);
|
||||
|
||||
if ($usage_string) {
|
||||
if ($usage_string =~ /cannot be found/) {
|
||||
# Could not find usage for openbmc section, try getting usage for all sections
|
||||
$usage_string = xCAT::Usage->parseCommand($command, @exargs);
|
||||
}
|
||||
$callback->({ data => [$usage_string] });
|
||||
$request = {};
|
||||
return;
|
||||
}
|
||||
|
||||
#pdu commands will be handled in the pdu plugin
|
||||
if ($command eq "rpower") {
|
||||
my $subcmd = $exargs[0];
|
||||
if(($subcmd eq 'pduoff') || ($subcmd eq 'pduon') || ($subcmd eq 'pdustat') || ($subcmd eq 'pdureset')){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $parse_result = parse_args($command, $extrargs, $noderange);
|
||||
if (ref($parse_result) eq 'ARRAY') {
|
||||
my $error_data;
|
||||
@@ -135,7 +149,7 @@ sub process_request {
|
||||
return unless(%node_info);
|
||||
|
||||
# If we can't start the python agent, exit immediately
|
||||
my $pid = xCAT::OPENBMC::start_python_agent();
|
||||
my $pid = xCAT::OPENBMC::start_python_agent($$);
|
||||
if (!defined($pid)) {
|
||||
xCAT::MsgUtils->message("E", { data => ["Failed to start the xCAT Python agent. Check /var/log/xcat/cluster.log for more information."] }, $callback);
|
||||
return;
|
||||
@@ -177,7 +191,7 @@ sub parse_args {
|
||||
return ([ 1, "Error parsing arguments." ]);
|
||||
}
|
||||
|
||||
if (scalar(@ARGV) >= 2 and ($command =~ /rbeacon|rinv|rpower|rvitals/)) {
|
||||
if (scalar(@ARGV) >= 2 and ($command =~ /rbeacon|rpower|rvitals/)) {
|
||||
return ([ 1, "Only one option is supported at the same time for $command" ]);
|
||||
} elsif (scalar(@ARGV) == 0 and $command =~ /rbeacon|rspconfig|rpower|rflash/) {
|
||||
return ([ 1, "No option specified for $command" ]);
|
||||
@@ -238,9 +252,18 @@ sub parse_args {
|
||||
return ([ 1, "Invalid option specified with '-l|--list'."]) if (@ARGV);
|
||||
}
|
||||
} elsif ($command eq "rinv") {
|
||||
$subcommand = "all" if (!defined($ARGV[0]));
|
||||
unless ($subcommand =~ /^all$|^cpu$|^dimm$|^firm$|^model$|^serial$/) {
|
||||
return ([ 1, "Unsupported command: $command $subcommand" ]);
|
||||
if (!defined($ARGV[0])) {
|
||||
$subcommand = "all";
|
||||
} else {
|
||||
foreach my $each_subcommand (@ARGV) {
|
||||
# Check if each passed subcommand is valid
|
||||
if ($each_subcommand =~ /^all$|^cpu$|^dimm$|^firm$|^model$|^serial$/) {
|
||||
$subcommand .= $each_subcommand . " ";
|
||||
} else {
|
||||
# Exit once we find an invalid subcommand
|
||||
return ([ 1, "Unsupported command: $command $each_subcommand" ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} elsif ($command eq "rpower") {
|
||||
unless ($subcommand =~ /^on$|^off$|^softoff$|^reset$|^boot$|^bmcreboot$|^bmcstate$|^status$|^stat$|^state$/) {
|
||||
|
||||
@@ -82,7 +82,7 @@ sub process_request {
|
||||
@ARGV = @{$args};
|
||||
}
|
||||
if (scalar(@ARGV) == 0) {
|
||||
$callback->({ info => ["Usage:\n packimage [-m| --method=cpio|tar] [-c| --compress=gzip|pigz|xz] <imagename>\n packimage [-h| --help]\n packimage [-v| --version]"] });
|
||||
$callback->({ info => ["Usage:\n packimage [-m| --method=cpio|tar] [-c| --compress=gzip|pigz|xz] [--nosyncfiles] <imagename>\n packimage [-h| --help]\n packimage [-v| --version]"] });
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ sub process_request {
|
||||
my $syncfile;
|
||||
my $rootimg_dir;
|
||||
my $destdir;
|
||||
my $nosyncfiles;
|
||||
my $imagename;
|
||||
my $dotorrent;
|
||||
my $provmethod;
|
||||
@@ -109,6 +110,7 @@ sub process_request {
|
||||
"method|m=s" => \$method,
|
||||
"compress|c=s" => \$compress,
|
||||
"tracker=s" => \$dotorrent,
|
||||
'nosyncfiles' => \$nosyncfiles,
|
||||
"help|h" => \$help,
|
||||
"version|v" => \$version
|
||||
);
|
||||
@@ -122,7 +124,7 @@ sub process_request {
|
||||
return 0;
|
||||
}
|
||||
if ($help) {
|
||||
$callback->({ info => ["Usage:\n packimage [-m| --method=cpio|tar] [-c| --compress=gzip|pigz|xz] <imagename>\n packimage [-h| --help]\n packimage [-v| --version]"] });
|
||||
$callback->({ info => ["Usage:\n packimage [-m| --method=cpio|tar] [-c| --compress=gzip|pigz|xz] [--nosyncfiles] <imagename>\n packimage [-h| --help]\n packimage [-v| --version]"] });
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -412,12 +414,15 @@ sub process_request {
|
||||
close($shadow);
|
||||
umask($oldmask);
|
||||
|
||||
# sync fils configured in the synclist to the rootimage
|
||||
$syncfile = xCAT::SvrUtils->getsynclistfile(undef, $osver, $arch, $profile, "netboot", $imagename);
|
||||
if (defined($syncfile) && -f $syncfile
|
||||
&& -d $rootimg_dir) {
|
||||
print "sync files from $syncfile to the $rootimg_dir\n";
|
||||
system("$::XCATROOT/bin/xdcp -i $rootimg_dir -F $syncfile");
|
||||
if (not $nosyncfiles) {
|
||||
# sync fils configured in the synclist to the rootimage
|
||||
$syncfile = xCAT::SvrUtils->getsynclistfile(undef, $osver, $arch, $profile, "netboot", $imagename);
|
||||
if ( defined($syncfile) && -f $syncfile && -d $rootimg_dir) {
|
||||
print "Syncing files from $syncfile to root image dir: $rootimg_dir\n";
|
||||
system("$::XCATROOT/bin/xdcp -i $rootimg_dir -F $syncfile");
|
||||
}
|
||||
} else {
|
||||
print "Bypass of syncfiles requested, will not sync files to root image directory.\n";
|
||||
}
|
||||
|
||||
my $temppath;
|
||||
@@ -500,7 +505,7 @@ sub process_request {
|
||||
my $checkoption2 = `tar --selinux 2>&1`;
|
||||
my $option;
|
||||
if ($checkoption1 !~ /unrecognized/) {
|
||||
$option .= "--xattrs-include='*' ";
|
||||
$option .= " --xattrs --xattrs-include='*' ";
|
||||
}
|
||||
if ($checkoption2 !~ /unrecognized/) {
|
||||
$option .= "--selinux ";
|
||||
|
||||
@@ -404,7 +404,7 @@ sub powerpduoutlet {
|
||||
if ($session->{ErrorStr}) {
|
||||
$callback->({ errorcode => [1],error => "$node: $pdu outlet $outlet has error = $session->{ErrorStr}"});
|
||||
} else {
|
||||
$output = "$pdu outlet $outlet is $statstr";
|
||||
$output = "$pdu operational state for outlet $outlet is $statstr";
|
||||
xCAT::SvrUtils::sendmsg($output, $callback, $node, %allerrornodes);
|
||||
}
|
||||
}
|
||||
@@ -508,7 +508,7 @@ sub powerstat {
|
||||
for (my $outlet =1; $outlet <= $count; $outlet++)
|
||||
{
|
||||
my $statstr = outletstat($session, $outlet);
|
||||
my $msg = " outlet $outlet is $statstr";
|
||||
my $msg = " operational state for the outlet $outlet is $statstr";
|
||||
xCAT::SvrUtils::sendmsg($msg, $callback, $pdu, %allerrornodes);
|
||||
}
|
||||
}
|
||||
@@ -519,6 +519,13 @@ sub powerstat {
|
||||
=head3 outletstat
|
||||
|
||||
Process command to query status of one pdu outlet
|
||||
ibmPduOutletState defined from mib file
|
||||
off(0)
|
||||
on(1)
|
||||
cycling(2)
|
||||
delaySwitch10(3)
|
||||
delaySwitch30(4)
|
||||
delaySwitch60(5)
|
||||
|
||||
=cut
|
||||
|
||||
@@ -535,12 +542,20 @@ sub outletstat {
|
||||
}
|
||||
|
||||
$output = $session->get("$oid.$outlet");
|
||||
if ($output eq 1) {
|
||||
$statstr = "on";
|
||||
} elsif ($output eq 0) {
|
||||
if ($output eq 0) {
|
||||
$statstr = "off";
|
||||
} elsif ($output eq 1) {
|
||||
$statstr = "on";
|
||||
} elsif ($output eq 2) {
|
||||
$statstr = "cycling";
|
||||
} elsif ($output eq 3) {
|
||||
$statstr = "delaySwitch10";
|
||||
} elsif ($output eq 4) {
|
||||
$statstr = "delaySwitch30";
|
||||
} elsif ($output eq 5) {
|
||||
$statstr = "delaySwitch60";
|
||||
} else {
|
||||
return;
|
||||
$statstr = "$output(unknown state)" ;
|
||||
}
|
||||
return $statstr;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ use xCAT::Utils;
|
||||
use xCAT::MsgUtils;
|
||||
use xCAT::SvrUtils;
|
||||
use xCAT::NodeRange;
|
||||
|
||||
use Data::Dumper;
|
||||
use Getopt::Long;
|
||||
1;
|
||||
|
||||
#-------------------------------------------------------
|
||||
@@ -46,11 +47,32 @@ sub process_request
|
||||
my $callback = shift;
|
||||
my $subreq = shift;
|
||||
|
||||
my $args= $request->{arg}; # argument
|
||||
@ARGV = @{$args};
|
||||
my $client;
|
||||
if ($request->{'_xcat_clienthost'}) {
|
||||
$client = $request->{'_xcat_clienthost'}->[0];
|
||||
}
|
||||
|
||||
|
||||
my %options = ();
|
||||
Getopt::Long::Configure("posix_default");
|
||||
Getopt::Long::Configure("no_gnu_compat");
|
||||
Getopt::Long::Configure("bundling");
|
||||
if (
|
||||
!GetOptions(
|
||||
'r|c|node-rcp=s' => \$options{'node-rcp'},
|
||||
)
|
||||
)
|
||||
{
|
||||
xCAT::MsgUtils->message("S", "Received syncfiles from $client, with invalid options @ARGV");
|
||||
return;
|
||||
}
|
||||
|
||||
if ($options{'node-rcp'}){
|
||||
$::RCP=$options{'node-rcp'};
|
||||
}
|
||||
|
||||
if ($client) { ($client) = noderange($client) }
|
||||
unless ($client) { #Not able to do identify the host in question
|
||||
xCAT::MsgUtils->message("S", "Received syncfiles from $client, which couldn't be correlated to a node (domain mismatch?)");
|
||||
@@ -101,7 +123,11 @@ sub syncfiles {
|
||||
foreach my $synclistfile (@sl) {
|
||||
|
||||
# call the xdcp plugin to handle the syncfile operation
|
||||
my $args = [ "-F", "$synclistfile" ];
|
||||
my $args = [ "-F", "$synclistfile"];
|
||||
if($::RCP){
|
||||
push @$args,"-r";
|
||||
push @$args, "$::RCP";
|
||||
}
|
||||
my $env = ["DSH_RSYNC_FILE=$synclistfile"];
|
||||
$subreq->({ command => ['xdcp'], node => [$node], arg => $args, env => $env }, $callback);
|
||||
}
|
||||
|
||||
@@ -2225,14 +2225,11 @@ sub tabch {
|
||||
my %rsp;
|
||||
push @{ $rsp{data} }, "Usage: tabch";
|
||||
push @{ $rsp{data} }, " To add or update rows for tables:";
|
||||
push @{ $rsp{data} }, " tabch [keycolname=keyvalue[,keycolname=keyvalue...]] [tablename.colname=newvalue] [tablename.colname=newvalue]...";
|
||||
push @{ $rsp{data} }, " tabch keycolname=keyvalue[,keycolname=keyvalue...] tablename.colname=newvalue [tablename.colname=newvalue...]";
|
||||
push @{ $rsp{data} }, " To delete rows from tables:";
|
||||
push @{ $rsp{data} }, " tabch -d|--delete keycolname=keyvalue[,keycolname=keyvalue...] tablename [tablename]...";
|
||||
push @{ $rsp{data} }, " tabch -d|--delete keycolname=keyvalue[,keycolname=keyvalue...] tablename [tablename...]";
|
||||
push @{ $rsp{data} }, " keycolname=keyvalue a column name-and-value pair ";
|
||||
push @{ $rsp{data} }, " that identifies the rows in a table to be changed.";
|
||||
push @{ $rsp{data} }, " a column name-and-value pair that identifies ";
|
||||
push @{ $rsp{data} }, " the rows in a table to be changed.";
|
||||
push @{ $rsp{data} }, " that identifies the rows in a table to be changed.";
|
||||
push @{ $rsp{data} }, " tablename.colname=newvalue ";
|
||||
push @{ $rsp{data} }, " the new value for the specified row and column of the table.";
|
||||
push @{ $rsp{data} }, " tabch [-h|--help]";
|
||||
|
||||
@@ -11,7 +11,6 @@ use lib "$::XCATROOT/lib/perl";
|
||||
|
||||
use xCAT::Table;
|
||||
use xCAT::Schema;
|
||||
use Data::Dumper;
|
||||
use xCAT::Utils;
|
||||
use xCAT::SvrUtils;
|
||||
use xCAT::Scope;
|
||||
@@ -30,6 +29,7 @@ use File::Basename;
|
||||
use xCAT::GlobalDef;
|
||||
use xCAT_monitoring::monitorctrl;
|
||||
use Socket;
|
||||
use Data::Dumper;
|
||||
|
||||
use strict;
|
||||
my $CALLBACK;
|
||||
@@ -209,7 +209,7 @@ sub preprocess_updatenode
|
||||
}
|
||||
|
||||
# parse the options
|
||||
my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY);
|
||||
my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY, $RCP);
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("no_pass_through");
|
||||
if (
|
||||
@@ -232,6 +232,7 @@ sub preprocess_updatenode
|
||||
'fanout=i' => \$fanout,
|
||||
't|timetout=i' => \$timeout,
|
||||
'n|noverify' => \$NOVERIFY,
|
||||
'r|node-rcp=s' =>\$RCP,
|
||||
|
||||
)
|
||||
)
|
||||
@@ -289,6 +290,11 @@ sub preprocess_updatenode
|
||||
} else {
|
||||
undef $::OS;
|
||||
}
|
||||
if (defined($RCP)) {
|
||||
$::RCP = $RCP;
|
||||
} else {
|
||||
undef $::RCP;
|
||||
}
|
||||
|
||||
# display the usage if -h or --help is specified
|
||||
if ($HELP)
|
||||
@@ -428,6 +434,15 @@ sub preprocess_updatenode
|
||||
return;
|
||||
}
|
||||
|
||||
if (($RCP) and (!$FILESYNC) and (!$SNFILESYNC)){
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "-r|--node-rcp option is valid when option -f or -F is specified";
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$callback->($rsp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
# -f must not be with any other flag, this updates service nodes syncfiles
|
||||
if ($SNFILESYNC && ($SWMAINTENANCE || $RERUNPS || defined($RERUNPS) || $SECURITY || $FILESYNC))
|
||||
{
|
||||
@@ -658,7 +673,11 @@ sub preprocess_updatenode
|
||||
{
|
||||
$request->{SNFileSyncing}->[0] = "yes";
|
||||
}
|
||||
|
||||
|
||||
if ($RCP){
|
||||
$request->{rcp}->[0]=$RCP;
|
||||
}
|
||||
|
||||
# If -F or -f then, call CFMUtils to check if any PCM CFM data is to be
|
||||
# built for the node. This will also create the synclists attribute in
|
||||
# the osimage for each node in the noderange
|
||||
@@ -685,6 +704,7 @@ sub preprocess_updatenode
|
||||
}
|
||||
|
||||
|
||||
|
||||
# - need to consider the mixed cluster case
|
||||
# - can't depend on the os of the MN - need to split out the AIX nodes
|
||||
my ($rc, $AIXnodes, $Linuxnodes) = xCAT::InstUtils->getOSnodes($nodes);
|
||||
@@ -752,6 +772,7 @@ sub preprocess_updatenode
|
||||
# process the -F or -f flags
|
||||
if (($FILESYNC) || ($SNFILESYNC))
|
||||
{
|
||||
|
||||
# If it is only -F or -f in the command, which are always run on the MN,
|
||||
# then run it now and you are
|
||||
# finished.
|
||||
@@ -821,6 +842,7 @@ sub preprocess_updatenode
|
||||
}
|
||||
|
||||
|
||||
|
||||
#
|
||||
# if hierarchy, then build the request for the service nodes
|
||||
#
|
||||
@@ -1078,7 +1100,6 @@ sub updatenode
|
||||
@::SUCCESSFULLNODES = ();
|
||||
@::FAILEDNODES = ();
|
||||
|
||||
#print Dumper($request);
|
||||
my $nodes = $request->{node};
|
||||
|
||||
#$request->{status}= "yes"; # for testing
|
||||
@@ -1135,7 +1156,7 @@ sub updatenode
|
||||
chomp $nimprime;
|
||||
|
||||
# parse the options
|
||||
my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY);
|
||||
my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY, $RCP);
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("no_pass_through");
|
||||
if (
|
||||
@@ -1158,6 +1179,7 @@ sub updatenode
|
||||
'fanout=i' => \$fanout,
|
||||
't|timetout=i' => \$timeout,
|
||||
'n|noverify' => \$NOVERIFY,
|
||||
'r|node-rcp=s' => \$RCP,
|
||||
)
|
||||
)
|
||||
{
|
||||
@@ -1211,6 +1233,11 @@ sub updatenode
|
||||
} else {
|
||||
undef $::OS;
|
||||
}
|
||||
if (defined($RCP)) {
|
||||
$::RCP = $RCP;
|
||||
} else {
|
||||
undef $::RCP;
|
||||
}
|
||||
|
||||
#
|
||||
# process @ARGV
|
||||
@@ -1712,6 +1739,7 @@ sub updatenodesyncfiles
|
||||
my %syncfile_node = ();
|
||||
my %syncfile_rootimage = ();
|
||||
|
||||
|
||||
# $::NOSYNCFILE default value is 0
|
||||
# if there is no syncfiles, set $::NOSYNCFILE=1
|
||||
$::NOSYNCFILE = 0;
|
||||
@@ -1828,6 +1856,10 @@ sub updatenodesyncfiles
|
||||
$CALLBACK = $callback;
|
||||
|
||||
|
||||
if($::RCP){
|
||||
push @$args, "--node-rcp";
|
||||
push @$args, "$::RCP";
|
||||
}
|
||||
$output =
|
||||
xCAT::Utils->runxcmd(
|
||||
{
|
||||
@@ -1841,21 +1873,32 @@ sub updatenodesyncfiles
|
||||
|
||||
# build the list of good and bad nodes
|
||||
&buildnodestatus(\@$output, $callback);
|
||||
if($::RUNCMD_RC and !@::FAILEDNODES){
|
||||
push @::FAILEDNODES,@{$syncfile_node{$synclist}};
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->{SNFileSyncing}->[0] eq "yes") {
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "File synchronization has completed for service nodes.";
|
||||
if(@::SUCCESSFULLNODES){
|
||||
$rsp->{data}->[0] = "File synchronization has completed for service nodes: \"".join(',',@::SUCCESSFULLNODES)."\"";
|
||||
}
|
||||
if (@::FAILEDNODES) {
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$rsp->{data}->[0] = "File synchronization failed for service nodes: \"".join(',',@::FAILEDNODES)."\"";
|
||||
}
|
||||
$callback->($rsp);
|
||||
}
|
||||
|
||||
if ($request->{FileSyncing}->[0] eq "yes") {
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "File synchronization has completed for nodes.";
|
||||
if(@::SUCCESSFULLNODES){
|
||||
$rsp->{data}->[0] = "File synchronization has completed for nodes: \"".join(',',@::SUCCESSFULLNODES)."\"";
|
||||
}
|
||||
|
||||
if (@::FAILEDNODES) {
|
||||
$rsp->{errorcode}->[0] = 1;
|
||||
$rsp->{data}->[0] = "File synchronization failed for nodes: \"".join(',',@::FAILEDNODES)."\"";
|
||||
}
|
||||
$callback->($rsp);
|
||||
}
|
||||
|
||||
@@ -17,13 +17,15 @@ use File::Basename;
|
||||
use File::Path;
|
||||
use POSIX;
|
||||
require xCAT::Table;
|
||||
|
||||
use Data::Dumper;
|
||||
require xCAT::Utils;
|
||||
require xCAT::Zone;
|
||||
require xCAT::TableUtils;
|
||||
require xCAT::ServiceNodeUtils;
|
||||
require xCAT::MsgUtils;
|
||||
use Getopt::Long;
|
||||
|
||||
|
||||
require xCAT::DSHCLI;
|
||||
1;
|
||||
|
||||
@@ -63,6 +65,7 @@ sub preprocess_request
|
||||
my $sn;
|
||||
my $rc = 0;
|
||||
|
||||
|
||||
#if already preprocessed, go straight to request
|
||||
if ((defined($req->{_xcatpreprocessed}))
|
||||
&& ($req->{_xcatpreprocessed}->[0] == 1))
|
||||
@@ -331,6 +334,11 @@ sub parse_xdcp_cmd
|
||||
}
|
||||
my $changedfile = 0;
|
||||
|
||||
if ($options{'node-rcp'}){
|
||||
$::RCP=$options{'node-rcp'};
|
||||
}
|
||||
|
||||
|
||||
# check to see if -F option and if there is, is the
|
||||
# input file fully defined path
|
||||
my $newfile;
|
||||
@@ -658,6 +666,10 @@ sub process_servicenodes_xdcp
|
||||
$addreq->{command}->[0] = $cmd;
|
||||
$addreq->{cwd}->[0] = $req->{cwd}->[0];
|
||||
$addreq->{env} = $req->{env};
|
||||
if($::RCP){
|
||||
push(@{ $addreq->{arg} }, "-r");
|
||||
push(@{ $addreq->{arg} }, "$::RCP");
|
||||
}
|
||||
&process_request($addreq, $callback, $sub_req);
|
||||
|
||||
if ($::FAILED_NODES == 0)
|
||||
|
||||
@@ -18,9 +18,9 @@ use strict;
|
||||
sub usage {
|
||||
print "Usage:\n";
|
||||
print " To add or update rows for tables:
|
||||
chtab [keycolname=keyvalue[,keycolname=keyvalue...]] [tablename.colname=newvalue] [tablename.colname=newvalue]...\n";
|
||||
chtab keycolname=keyvalue[,keycolname=keyvalue...] tablename.colname=newvalue [tablename.colname=newvalue...]\n";
|
||||
print " To delete rows from tables:
|
||||
chtab -d|--delete keycolname=keyvalue[,keycolname=keyvalue...] tablename [tablename]...\n";
|
||||
chtab -d|--delete keycolname=keyvalue[,keycolname=keyvalue...] tablename [tablename...]\n";
|
||||
print " To display usage and other information:
|
||||
chtab [-h|--help|-v|--Version]\n\n";
|
||||
print " -d|--delete Delete the rows from a list of tables.
|
||||
|
||||
+66
-31
@@ -809,7 +809,10 @@ sub do_udp_service { # This function opens up a UDP port
|
||||
my $hdl;
|
||||
foreach $hdl (@hdls) {
|
||||
if ($hdl == $socket) {
|
||||
$part = $socket->recv($data, 2000);
|
||||
$part = $socket->recv($data, 3000);
|
||||
if(length($data)>1500){
|
||||
xCAT::MsgUtils->message("S", "$0: received ".length($data)."B data packet from ".$socket->peerhost);
|
||||
}
|
||||
$packets{$part} = [ $part, $data ];
|
||||
} elsif ($hdl == $sslctl) {
|
||||
next;
|
||||
@@ -861,7 +864,10 @@ sub do_udp_service { # This function opens up a UDP port
|
||||
while (@hdls = $select->can_read(0)) { # grab any incoming requests during run
|
||||
foreach my $hdl (@hdls) {
|
||||
if ($hdl == $socket) {
|
||||
$part = $socket->recv($data, 1500);
|
||||
$part = $socket->recv($data,3000);
|
||||
if(length($data)>1500){
|
||||
xCAT::MsgUtils->message("S", "$0: received ".length($data)."B data packet from ".$socket->peerhost);
|
||||
}
|
||||
$packets{$part} = [ $part, $data ];
|
||||
|
||||
#} elsif ($hdl == $sslctl) {
|
||||
@@ -1003,11 +1009,16 @@ my %immediatechildren;
|
||||
|
||||
sub generic_reaper {
|
||||
local ($!);
|
||||
#print "generic_reaper in $$...";
|
||||
while (($CHILDPID = waitpid(-1, WNOHANG)) > 0) {
|
||||
if (($CHILDPID == $pid_UDP) && ($udpctl)) {
|
||||
|
||||
# got here because UDP child is gone
|
||||
close($udpctl); $udpctl = 0;
|
||||
#print "reaper for $CHILDPID...\n";
|
||||
if ($CHILDPID == $pid_UDP) {
|
||||
if ($udpctl) {
|
||||
# got here because UDP child is gone
|
||||
close($udpctl);
|
||||
$udpctl = 0;
|
||||
}
|
||||
$pid_UDP = 0;
|
||||
}
|
||||
yield;
|
||||
}
|
||||
@@ -1017,16 +1028,20 @@ sub generic_reaper {
|
||||
sub ssl_reaper {
|
||||
local ($!);
|
||||
my $numdone = 0;
|
||||
#print "ssl_reaper in $$...";
|
||||
while (($CHILDPID = waitpid(-1, WNOHANG)) > 0) {
|
||||
#print "reaper for $CHILDPID...\n";
|
||||
if ($immediatechildren{$CHILDPID}) {
|
||||
delete $immediatechildren{$CHILDPID};
|
||||
$sslclients--;
|
||||
$numdone--;
|
||||
}
|
||||
if (($CHILDPID == $pid_UDP) && ($udpctl)) {
|
||||
|
||||
# got here because UDP child is gone
|
||||
close($udpctl); $udpctl = 0;
|
||||
if ($CHILDPID == $pid_UDP) {
|
||||
if ($udpctl) {
|
||||
# got here because UDP child is gone
|
||||
close($udpctl);
|
||||
$udpctl = 0;
|
||||
}
|
||||
$pid_UDP = 0;
|
||||
}
|
||||
if ($CHILDPID == $cmdlog_svrpid) {
|
||||
@@ -1041,32 +1056,36 @@ sub ssl_reaper {
|
||||
|
||||
sub dispatch_reaper {
|
||||
local ($!);
|
||||
#print "dispatch_reaper in $$...";
|
||||
while (($CHILDPID = waitpid(-1, WNOHANG)) > 0) {
|
||||
#print "reaper for $CHILDPID...\n";
|
||||
if ($dispatched_children{$CHILDPID}) {
|
||||
delete $dispatched_children{$CHILDPID};
|
||||
$dispatch_children--;
|
||||
}
|
||||
if (($CHILDPID == $pid_UDP) && ($udpctl)) {
|
||||
|
||||
# got here because UDP child is gone
|
||||
close($udpctl); $udpctl = 0;
|
||||
}
|
||||
#if (($CHILDPID == $pid_UDP) && ($udpctl)) {
|
||||
#
|
||||
# # got here because UDP child is gone
|
||||
# close($udpctl); $udpctl = 0;
|
||||
#}
|
||||
}
|
||||
$SIG{CHLD} = \&dispatch_reaper;
|
||||
}
|
||||
|
||||
sub plugin_reaper {
|
||||
local ($!);
|
||||
#print "plugin_reaper in $$...";
|
||||
while (($CHILDPID = waitpid(-1, WNOHANG)) > 0) {
|
||||
#print "reaper for $CHILDPID...\n";
|
||||
if ($plugin_children{$CHILDPID}) {
|
||||
delete $plugin_children{$CHILDPID};
|
||||
$plugin_numchildren--;
|
||||
}
|
||||
if (($CHILDPID == $pid_UDP) && ($udpctl)) {
|
||||
|
||||
# got here because UDP child is gone
|
||||
close($udpctl); $udpctl = 0;
|
||||
}
|
||||
#if (($CHILDPID == $pid_UDP) && ($udpctl)) {
|
||||
#
|
||||
# # got here because UDP child is gone
|
||||
# close($udpctl); $udpctl = 0;
|
||||
#}
|
||||
}
|
||||
$SIG{CHLD} = \&plugin_reaper;
|
||||
}
|
||||
@@ -1162,6 +1181,7 @@ if (!defined $pid_MON) {
|
||||
}
|
||||
unless ($pid_MON) {
|
||||
$$progname = "xcatd: install monitor";
|
||||
$pid_UDP = 0;
|
||||
close($udpctl); $udpctl = 0;
|
||||
do_installm_service;
|
||||
xexit(0);
|
||||
@@ -1510,7 +1530,7 @@ until ($quit) {
|
||||
}
|
||||
|
||||
if ($child == 0) {
|
||||
close($udpctl); $udpctl = 0;
|
||||
close($udpctl); $udpctl = 0; $pid_UDP=0;
|
||||
$SIG{TERM} = $SIG{INT} = 'DEFAULT';
|
||||
$SIG{CHLD} = \&generic_reaper; # THROTTLE
|
||||
$listener->close;
|
||||
@@ -1614,16 +1634,27 @@ if (open($mainpidfile, "<", "/var/run/xcat/mainservice.pid")) {
|
||||
close($mainpidfile);
|
||||
}
|
||||
if ($listener) { $listener->close; }
|
||||
my $lastpid;
|
||||
while (keys %immediatechildren || $pid_UDP || $cmdlog_svrpid || $pid_MON) {
|
||||
$lastpid = wait();
|
||||
|
||||
$SIG{CHLD} = "DEFAULT"; # Disable the signal handler and let wait to cover the children quit
|
||||
|
||||
my $remains = keys %immediatechildren;
|
||||
xCAT::MsgUtils->trace(0, 'I', "xcatd is going to stop, waiting for $remains plugins to quit...");
|
||||
while ($remains || $pid_UDP || $cmdlog_svrpid || $pid_MON) {
|
||||
my $lastpid = wait();
|
||||
last if ($lastpid < 0);
|
||||
|
||||
# Found an valid child process
|
||||
if ($immediatechildren{$lastpid}) {
|
||||
delete $immediatechildren{$lastpid};
|
||||
} elsif ($lastpid == $pid_UDP) {
|
||||
$remains = keys %immediatechildren;
|
||||
}
|
||||
elsif ($lastpid == $pid_UDP) {
|
||||
$pid_UDP = 0;
|
||||
} elsif ($lastpid == $cmdlog_svrpid) {
|
||||
}
|
||||
elsif ($lastpid == $cmdlog_svrpid) {
|
||||
$cmdlog_svrpid = 0;
|
||||
} elsif ($lastpid == $pid_MON) {
|
||||
}
|
||||
elsif ($lastpid == $pid_MON) {
|
||||
$pid_MON = 0;
|
||||
}
|
||||
}
|
||||
@@ -2826,11 +2857,15 @@ sub service_connection {
|
||||
if ($peername) {
|
||||
|
||||
# for a valid account, get a token
|
||||
my $htime;
|
||||
my ($tokenid, $exptime) = xCAT::xcatd->gettoken($req);
|
||||
my ($sec, $min, $hour, $mday, $mon, $year) = localtime($exptime);
|
||||
$year += 1900;
|
||||
$mon += 1;
|
||||
my $htime = "$year-$mon-$mday $hour:$min:$sec";
|
||||
if ($exptime eq "never") {
|
||||
# If token expiration time was set to "never", return that to the user.
|
||||
$htime = $exptime;
|
||||
} else {
|
||||
# Token expiration is a unix DateTime, convert to readable string
|
||||
$htime = xCAT::Utils->time2string($exptime, "-");
|
||||
}
|
||||
$resp = { data => [ { token => [ { id => $tokenid, expire => $htime } ] } ] };
|
||||
} else {
|
||||
$resp = { error => ["Authentication failure"], errorcode => [1] };
|
||||
|
||||
@@ -195,7 +195,8 @@ sub snap_it {
|
||||
"/etc/hosts", "/etc/conserver.cf",
|
||||
"/var/log/conserver", "/etc/db_file.cr",
|
||||
"/etc/dhcpsd.cnf", "/var/adm/ras/nimlog",
|
||||
"/etc/resolv.conf", "/etc/named.conf", "/var/log/messages", "/var/log/xcat/*");
|
||||
"/etc/resolv.conf", "/etc/named.conf",
|
||||
"/var/log/messages", "/var/log/xcat/*");
|
||||
}
|
||||
|
||||
elsif ($OSname eq "Linux") {
|
||||
@@ -205,6 +206,7 @@ sub snap_it {
|
||||
"$INSTALLDIR/postscripts/*", "$INSTALLDIR/prescripts/*", "$INSTALLDIR/custom/*",
|
||||
"/tftpboot/*", "/var/log/consoles/*",
|
||||
"/etc/*-release", "/etc/dhcpd.conf",
|
||||
"/etc/rsyslog.conf", "/etc/rsyslog.d/*",
|
||||
"/var/lib/dhcpd/dhcpd.leases", "/etc/hosts", "/etc/resolv.conf",
|
||||
"/etc/named.conf", "/etc/conserver.cf", "/var/log/conserver",
|
||||
"/etc/nsswitch.conf", "/var/log/messages", "/var/log/xcat/*");
|
||||
@@ -382,6 +384,7 @@ chop($hostname = `hostname -s`);
|
||||
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
|
||||
localtime(time);
|
||||
$mon = $mon + 1;
|
||||
$year += 1900;
|
||||
my @date_array = ($mon, $mday, $hour, $min);
|
||||
|
||||
foreach my $item (@date_array) {
|
||||
@@ -390,8 +393,8 @@ foreach my $item (@date_array) {
|
||||
$item =~ tr/ /0/;
|
||||
}
|
||||
my $logdate = $date_array[0] . $date_array[1] . $date_array[2] . $date_array[3];
|
||||
$LogFile = $logDirectory . "/xcatsnap." . $hostname . "." . $logdate . ".log";
|
||||
$TarFile = $logDirectory . "/xcatsnap." . $hostname . "." . $logdate . ".tar";
|
||||
$LogFile = $logDirectory . "/xcatsnap." . $hostname . "." . $year . "-" . $logdate . ".log";
|
||||
$TarFile = $logDirectory . "/xcatsnap." . $hostname . "." . $year . "-" . $logdate . ".tar";
|
||||
|
||||
open(STDOUT, "| tee $LogFile");
|
||||
print "Time Stamp:" . `date`;
|
||||
@@ -408,6 +411,7 @@ print "Compiling Information...\n";
|
||||
print "Information compiled...\n";
|
||||
`chmod 400 $LogFile`; # Processing the log file
|
||||
print "Send $LogFile to IBM Support.\n";
|
||||
print "Compressing $TarFile ...\n";
|
||||
my $donotdelete = 0;
|
||||
if (`which gunzip` == 0) { # Compressing the tar file
|
||||
`gzip -f $TarFile`;
|
||||
|
||||
@@ -20,3 +20,4 @@ ntp
|
||||
gzip
|
||||
tar
|
||||
xz
|
||||
iputils
|
||||
|
||||
@@ -1501,9 +1501,9 @@ EOMS
|
||||
print $inifile " ([ \"\$xcatdebugmode\" = \"1\" ] || [ \"\$xcatdebugmode\" = \"2\" ]) && logger -t xcat -p debug \"Extracting root filesystem:\"\n";
|
||||
print $inifile " echo -n \"Extracting root filesystem:\"\n";
|
||||
print $inifile " if [ -r /rootimg.tar.gz ]; then\n";
|
||||
print $inifile " /bin/tar --selinux --xattrs-include='*' -zxf /rootimg.tar.gz\n";
|
||||
print $inifile " /bin/tar --selinux --xattrs --xattrs-include='*' -zxf /rootimg.tar.gz\n";
|
||||
print $inifile " elif [ -r /rootimg.tar.xz ]; then\n";
|
||||
print $inifile " /bin/tar --selinux --xattrs-include='*' -Jxf /rootimg.tar.xz\n";
|
||||
print $inifile " /bin/tar --selinux --xattrs --xattrs-include='*' -Jxf /rootimg.tar.xz\n";
|
||||
print $inifile " fi\n";
|
||||
print $inifile " ([ \"\$xcatdebugmode\" = \"1\" ] || [ \"\$xcatdebugmode\" = \"2\" ]) && logger -t xcat -p debug \"Done...\"\n";
|
||||
print $inifile " echo Done\n";
|
||||
|
||||
@@ -431,15 +431,18 @@ my %URIdef = (
|
||||
beacon => {
|
||||
desc => "[URI:/nodes/{noderange}/beacon] - The beacon resource for the node {noderange}",
|
||||
matcher => '^/nodes/[^/]*/beacon$',
|
||||
GET_backup => {
|
||||
GET => {
|
||||
desc => "Get the beacon status for the node {noderange}.",
|
||||
usage => "||$usagemsg{objreturn}|",
|
||||
example => "|Get beacon for node1.|GET|/nodes/node1/beacon|{\n \"node1\":{\n \"beacon\":[\n \"Front:Blink Rear:Blink\"\n ]\n }\n}|",
|
||||
cmd => "rbeacon",
|
||||
fhandler => \&common,
|
||||
fhandler => \&actionhdl,
|
||||
outhdler => \&actionout,
|
||||
},
|
||||
PUT => {
|
||||
desc => "Change the beacon status for the node {noderange}.",
|
||||
usage => "|$usagemsg{objchparam} DataBody: {action:on/off/blink}.|$usagemsg{non_getreturn}|",
|
||||
example => "|Turn on the beacon.|PUT|/nodes/node1/beacon {\"action\":\"on\"}|[\n {\n \"name\":\"node1\",\n \"beacon\":\"on\"\n }\n]|",
|
||||
example => "|Turn on the beacon.|PUT|/nodes/node1/beacon {\"action\":\"on\"}||",
|
||||
cmd => "rbeacon",
|
||||
fhandler => \&actionhdl,
|
||||
outhdler => \&noout,
|
||||
@@ -1192,7 +1195,7 @@ my %URIdef = (
|
||||
},
|
||||
table_all_rows => {
|
||||
desc => "[URI:/tables/{tablelist}/rows] - The non-node table resource",
|
||||
desc1 => "Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, polciy, etc.",
|
||||
desc1 => "Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, policy, etc.",
|
||||
matcher => '^/tables/[^/]+/rows$',
|
||||
GET => {
|
||||
desc => "Get all rows from non-node tables.",
|
||||
@@ -1204,13 +1207,13 @@ my %URIdef = (
|
||||
},
|
||||
table_rows => {
|
||||
desc => "[URI:/tables/{tablelist}/rows/{keys}] - The non-node table rows resource",
|
||||
desc1 => "Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, polciy, etc.",
|
||||
desc1 => "Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, policy, etc.",
|
||||
desc2 => "{keys} should be the name=value pairs which are used to search table. e.g. {keys} should be [net=192.168.1.0,mask=255.255.255.0] for networks table query since the net and mask are the keys of networks table.",
|
||||
matcher => '^/tables/[^/]+/rows/[^/]+$',
|
||||
GET => {
|
||||
desc => "Get attributes for rows from non-node tables.",
|
||||
usage => "||An object containing each table. Within each table object is an array of row objects containing the attributes.|",
|
||||
example => qq(|Get row which net=192.168.1.0,mask=255.255.255.0 from networks table.|GET|/tables/networks/rows/net=192.168.1.0,mask=255.255.255.0|{\n \"networks\":[\n {\n \"mgtifname\":\"eth0\",\n \"netname\":\"192_168_1_0-255_255_255_0\",\n \"tftpserver\":\"192.168.1.15\",\n \"gateway\":\"192.168.1.100\",\n \"staticrangeincrement\":\"1\",\n \"net\":\"192.168.1.0\",\n \"mask\":\"255.255.255.0\"\n }\n ]\n}|),
|
||||
example => qq(|Get rows from networks table where net=192.168.1.0,mask=255.255.255.0.|GET|/tables/networks/rows/net=192.168.1.0,mask=255.255.255.0|{\n \"networks\":[\n {\n \"mgtifname\":\"eth0\",\n \"netname\":\"192_168_1_0-255_255_255_0\",\n \"tftpserver\":\"192.168.1.15\",\n \"gateway\":\"192.168.1.100\",\n \"staticrangeincrement\":\"1\",\n \"net\":\"192.168.1.0\",\n \"mask\":\"255.255.255.0\"\n }\n ]\n}|),
|
||||
fhandler => \&tablerowhdl,
|
||||
outhdler => \&tableout,
|
||||
},
|
||||
@@ -1224,19 +1227,19 @@ my %URIdef = (
|
||||
DELETE => {
|
||||
desc => "Delete rows from a non-node table that have the attribute values specified in {keys}.",
|
||||
usage => "||$usagemsg{non_getreturn}|",
|
||||
example => '|Delete a route row which routename=privnet in the routes table.|DELETE|/tables/routes/rows/routename=privnet||',
|
||||
example => '|Delete rows from routes table where routename=privnet.|DELETE|/tables/routes/rows/routename=privnet||',
|
||||
fhandler => \&tablerowdelhdl,
|
||||
outhdler => \&noout,
|
||||
},
|
||||
},
|
||||
table_rows_attrs => {
|
||||
desc => "[URI:/tables/{tablelist}/rows/{keys}/{attrlist}] - The non-node table attributes resource",
|
||||
desc1 => "Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, polciy, etc.",
|
||||
desc1 => "Use this for tables that don't have node name as the key of the table, for example: passwd, site, networks, policy, etc.",
|
||||
matcher => '^/tables/[^/]+/rows/[^/]+/[^/]+$',
|
||||
GET => {
|
||||
desc => "Get specific attributes for rows from non-node tables.",
|
||||
usage => "||An object containing each table. Within each table object is an array of row objects containing the attributes.|",
|
||||
example => qq(|Get attributes mgtifname and tftpserver which net=192.168.1.0,mask=255.255.255.0 from networks table.|GET|/tables/networks/rows/net=192.168.1.0,mask=255.255.255.0/mgtifname,tftpserver|{\n \"networks\":[\n {\n \"mgtifname\":\"eth0\",\n \"tftpserver\":\"192.168.1.15\"\n }\n ]\n}|),
|
||||
example => qq(|Get attributes mgtifname and tftpserver from networks table for each row where net=192.168.1.0,mask=255.255.255.0.|GET|/tables/networks/rows/net=192.168.1.0,mask=255.255.255.0/mgtifname,tftpserver|{\n \"networks\":[\n {\n \"mgtifname\":\"eth0\",\n \"tftpserver\":\"192.168.1.15\"\n }\n ]\n}|),
|
||||
fhandler => \&tablerowhdl,
|
||||
outhdler => \&tableout,
|
||||
},
|
||||
@@ -1373,6 +1376,10 @@ my @path = split(/\//, $pathInfo); # The uri path like /nodes/node1/...
|
||||
my $pageContent = ''; # Global var containing the ouptut back to the rest client
|
||||
my %header_info; #Global var containing the extra info to the http header
|
||||
my $request = { clienttype => 'ws' }; # Global var that holds the request to send to xcatd
|
||||
my $remote_host = $q->remote_host();
|
||||
my ($client_name, $client_aliases) = gethostbyaddr(inet_aton($remote_host), AF_INET);
|
||||
$request->{remote_client}->[0]= $client_name.','.$client_aliases;
|
||||
|
||||
my $format = 'json'; # The output format for a request invoke
|
||||
my $xmlinstalled; # Global var to speicfy whether the xml modules have been loaded
|
||||
|
||||
@@ -1559,12 +1566,12 @@ if (defined($URIdef{$uriLayer1})) {
|
||||
} else {
|
||||
|
||||
# not matches to any resource group. Check the 'resource group' to improve the performance
|
||||
error("Unspported resource.", $STATUS_NOT_FOUND);
|
||||
error("Unsupported resource.", $STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
# the URI cannot match to any resources which are defined in %URIdef
|
||||
unless ($handled) {
|
||||
error("Unspported resource.", $STATUS_NOT_FOUND);
|
||||
error("Unsupported resource.", $STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
||||
@@ -1939,6 +1946,20 @@ sub actionout {
|
||||
|
||||
my $jsonnode;
|
||||
foreach my $d (@$data) {
|
||||
if (defined($d->{info})) {
|
||||
# OpenBMC format
|
||||
if ($param->{'resourcename'} =~ /(^eventlog$|^beacon$)/) {
|
||||
my ($node, $logentry) = split(/:/, $d->{info}->[0], 2);
|
||||
$logentry =~ s/^\s+|\s+$//g; # trim whitespace from log entry
|
||||
push @{ $jsonnode->{$node}->{ $param->{'resourcename'} } }, $logentry;
|
||||
} else {
|
||||
my ($node, $resourcename, $value) = split(/:/, $d->{info}->[0]);
|
||||
$resourcename =~ s/^\s+|\s+$//g; # trim whitespace from resourcename
|
||||
$value =~ s/^\s+|\s+$//g; # trim whitespace from value
|
||||
$jsonnode->{ $node }->{ $resourcename } = $value;
|
||||
}
|
||||
next;
|
||||
}
|
||||
unless (defined($d->{node}->[0]->{name})) {
|
||||
next;
|
||||
}
|
||||
@@ -2195,7 +2216,9 @@ sub actionhdl {
|
||||
push @args, 'clear';
|
||||
}
|
||||
} elsif ($params->{'resourcename'} eq "beacon") {
|
||||
if (isPut()) {
|
||||
if (isGET()) {
|
||||
push @args, 'stat';
|
||||
} elsif (isPut()) {
|
||||
push @args, $paramhash->{'action'};
|
||||
}
|
||||
} elsif ($params->{'resourcename'} eq "filesyncing") {
|
||||
@@ -2849,6 +2872,16 @@ sub tablerowhdl {
|
||||
# out of the node hash and make it the key
|
||||
my $responses = sendRequest($req, { SuppressEmpty => undef, ForceArray => 0, KeyAttr => [] });
|
||||
|
||||
if (@$responses[0]->{error}) {
|
||||
# Error returned, most likely invalid table, substitute a better error msg
|
||||
@$responses[0]->{error} = "No such table: @tables";
|
||||
}
|
||||
# Check if there is any real data in response
|
||||
# One key ('xcatdsource' => '<node>') is always returned.
|
||||
# If no other keys in response - no matches on key or attribute were returned from xcatd
|
||||
if (keys @$responses[0] <= 1) {
|
||||
@$responses[0]->{error} = "No table rows matched specified keys or attributes";
|
||||
}
|
||||
return $responses;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# The test for the REST API needs to specify
|
||||
# the specific node and userid/password for REST API access
|
||||
|
||||
[System]
|
||||
username=
|
||||
password=
|
||||
CN=
|
||||
@@ -4,7 +4,7 @@ os:Linux
|
||||
hcp:openbmc
|
||||
cmd:reventlog $$CN resolved
|
||||
check:rc==1
|
||||
check:output=~Error: Usage error. Provide a comma separated
|
||||
check:output=~Error: (\[.*?\]: )?Usage error. Provide a comma separated
|
||||
end
|
||||
|
||||
start:reventlog_resolved_parse_error2
|
||||
@@ -13,7 +13,7 @@ os:Linux
|
||||
hcp:openbmc
|
||||
cmd:reventlog $$CN resolved=
|
||||
check:rc==1
|
||||
check:output=~Error: Usage error. Provide a comma separated
|
||||
check:output=~Error: (\[.*?\]: )?Usage error. Provide a comma separated
|
||||
end
|
||||
|
||||
start:reventlog_resolved_parse_error3
|
||||
@@ -22,7 +22,7 @@ os:Linux
|
||||
hcp:openbmc
|
||||
cmd:reventlog $$CN resolved 1,2,3
|
||||
check:rc==1
|
||||
check:output=~Error: Usage error. Provide a comma separated
|
||||
check:output=~Error: (\[.*?\]: )?Usage error. Provide a comma separated
|
||||
end
|
||||
|
||||
start:reventlog_resolved_parse_error4
|
||||
@@ -31,7 +31,7 @@ os:Linux
|
||||
hcp:openbmc
|
||||
cmd:reventlog $$CN resolved=-1
|
||||
check:rc==1
|
||||
check:output=~Error: Invalid ID=
|
||||
check:output=~Error: (\[.*?\]: )?Invalid ID=
|
||||
end
|
||||
|
||||
start:reventlog_resolved_parse_error5
|
||||
@@ -40,7 +40,7 @@ os:Linux
|
||||
hcp:openbmc
|
||||
cmd:reventlog $$CN resolved=abc
|
||||
check:rc==1
|
||||
check:output=~Error: Invalid ID=
|
||||
check:output=~Error: (\[.*?\]: )?Invalid ID=
|
||||
end
|
||||
|
||||
start:reventlog_resolved_list
|
||||
|
||||
@@ -14,7 +14,7 @@ os:Linux
|
||||
hcp:openbmc
|
||||
cmd: rflash $$CN -a /tmp/abc123.tz
|
||||
check:rc==1
|
||||
check:output=~Error: Invalid firmware specified with -a
|
||||
check:output=~Error: (\[.*?\]: )?Invalid firmware specified with -a
|
||||
end
|
||||
|
||||
start:rflash_invalid_activate_and_delete
|
||||
@@ -23,7 +23,7 @@ os:Linux
|
||||
hcp:openbmc
|
||||
cmd: rflash $$CN -a 123 --delete 123
|
||||
check:rc==1
|
||||
check:output=~Error: Multiple options are not supported
|
||||
check:output=~Error: (\[.*?\]: )?Multiple options are not supported
|
||||
end
|
||||
|
||||
start:rflash_invalid_id
|
||||
@@ -32,7 +32,7 @@ os:Linux
|
||||
hcp:openbmc
|
||||
cmd: rflash $$CN -a 123
|
||||
check:rc==1
|
||||
check:output=~Error: Invalid ID provided to activate
|
||||
check:output=~Error: (\[.*?\]: )?Invalid ID provided to activate
|
||||
end
|
||||
|
||||
start:rflash_invalid_multiple_id_3
|
||||
@@ -41,7 +41,7 @@ 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
|
||||
check:output=~Error: (\[.*?\]: )?More than one firmware specified is not supported
|
||||
end
|
||||
|
||||
start:rflash_invalid_multiple_id_2
|
||||
@@ -50,7 +50,7 @@ os:Linux
|
||||
hcp:openbmc
|
||||
cmd: rflash $$CN -a asdbas 123
|
||||
check:rc==1
|
||||
check:output=~Error: More than one firmware specified is not supported
|
||||
check:output=~Error: (\[.*?\]: )?More than one firmware specified is not supported
|
||||
end
|
||||
|
||||
start:rflash_invalid_node
|
||||
@@ -59,7 +59,7 @@ os:Linux
|
||||
hcp:openbmc
|
||||
cmd: rflash -a 221d9020
|
||||
check:rc==1
|
||||
check:output=~Error: Invalid nodes and/or groups in noderange: 221d9020
|
||||
check:output=~Error: (\[.*?\]: )?Invalid nodes and/or groups in noderange: 221d9020
|
||||
end
|
||||
|
||||
start:rflash_invalid_delete_2
|
||||
@@ -68,7 +68,7 @@ os:Linux
|
||||
hcp:openbmc
|
||||
cmd: rflash $$CN --delete 221d9020 221d9020
|
||||
check:rc==1
|
||||
check:output=~Error: More than one firmware specified is not supported
|
||||
check:output=~Error: (\[.*?\]: )?More than one firmware specified is not supported
|
||||
end
|
||||
|
||||
start:rflash_delete_active_bmc
|
||||
@@ -77,5 +77,5 @@ os:Linux
|
||||
hcp:openbmc
|
||||
cmd: rflash $$CN -l | grep \* | grep BMC | awk '{print $2}' | xargs -i{} rflash $$CN --delete {}
|
||||
check:rc==1
|
||||
check:output=~$$CN: Error: Deleting currently active BMC firmware is not supported
|
||||
check:output=~$$CN: (\[.*?\]: )?Error: Deleting currently active BMC firmware is not supported
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user