2
0
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:
zhao er tao
2018-05-29 18:29:46 +08:00
168 changed files with 3828 additions and 1540 deletions
+2
View File
@@ -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/>`_
+1 -1
View File
@@ -1 +1 @@
2.14
2.14.1
+1 -1
View File
@@ -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.
::
+1 -1
View File
@@ -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: ::
-1
View File
@@ -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.
+2 -2
View File
@@ -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
@@ -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.
@@ -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 | |
+----------------+-----------+-------------+----------------------------------+
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+12 -8
View File
@@ -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.",
},
+1 -1
View File
@@ -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);
};
+5 -6
View File
@@ -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"} .
+36
View File
@@ -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:
+138 -50
View File
@@ -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");
+3 -2
View File
@@ -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();
+1 -1
View File
@@ -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>
+7 -1
View File
@@ -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
+1 -1
View File
@@ -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:
+17 -3
View File
@@ -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
+5 -5
View File
@@ -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
+4 -4
View File
@@ -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
+6 -1
View File
@@ -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):
+39
View File
@@ -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
+71 -6
View File
@@ -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
View File
@@ -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";
+14 -3
View File
@@ -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 ];
+13 -3
View File
@@ -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;
}
+86 -19
View File
@@ -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;
+30 -18
View File
@@ -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;
}
+36 -14
View File
@@ -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);
}
+27
View File
@@ -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
+2 -2
View File
@@ -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 {
+5
View File
@@ -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"
+26 -6
View File
@@ -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]; }
}
}
+25 -1
View File
@@ -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;
}
+1 -1
View File
@@ -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 {
+310
View File
@@ -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;
+45 -17
View File
@@ -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};
+29 -6
View 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$/) {
+14 -9
View File
@@ -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 ";
+21 -6
View File
@@ -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;
}
+28 -2
View File
@@ -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);
}
+2 -5
View File
@@ -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]";
+50 -7
View File
@@ -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);
}
+13 -1
View File
@@ -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)
+2 -2
View File
@@ -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
View File
@@ -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] };
+7 -3
View File
@@ -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";
+45 -12
View File
@@ -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;
}
+7
View File
@@ -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