2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-05-18 12:17:16 +00:00

merge master(commit:a183e3b8f241fb168b830dbe3f8f6f5b40fe1834) to 2.13 branch (#3929)

It is for 2.13.7 RC1
This commit is contained in:
yangsong
2017-09-15 16:56:02 +08:00
committed by Bin Xu
parent ca64b15cab
commit 294d59a307
152 changed files with 6173 additions and 889 deletions
+1 -1
View File
@@ -1 +1 @@
2.13.6
2.13.7
+1 -1
View File
@@ -524,7 +524,7 @@ __EOF__
FILES_PATH="files"
FRS="/var/www/${SERVER}/${FILES_PATH}"
APT_DIR="${FRS}/xcat"
APT_REPO_DIR="${APT_DIR}/repos/apt"
APT_REPO_DIR="${APT_DIR}/repos/apt/devel"
# Decide whether to upload the xcat-dep package or NOT (default is to NOT upload xcat-dep
if [ "$UP" != "1" ]; then
+1 -1
View File
@@ -225,7 +225,7 @@ if [ "$OSNAME" == "AIX" ]; then
else
# Linux
SYSGRP=root
YUM=yum
YUM=yum/devel
FRSDIR='2.x_Linux'
fi
chgrp -R -h $SYSGRP *
+1
View File
@@ -6,6 +6,7 @@ Advanced Topics
chain/index.rst
cluster_maintenance/index.rst
migration/index.rst
confluent/index.rst
docker/index.rst
domain_name_resolution/index.rst
+7
View File
@@ -0,0 +1,7 @@
Migrate xCat Management node
============================
.. toctree::
:maxdepth: 2
migration.rst
@@ -0,0 +1,189 @@
xCAT Management Node Migration
==============================
This document describes how to migrate xCAT Management node to a new node. The following example describes a typical scenario, this example is verified on redhat7.3.
#. Initially, the first xcat management node is active, and the second node is passive.
#. Backup all useful xCAT data from xCAT Management node to back-up server at regular intervals.
#. When the first xCAT management node is broken, use backup to restore original xCAT data to the second node with the same host name and ip.
Backup Old xCAT Management Node
-------------------------------
Backup xCAT management node data to backup server:
1.1 Backup xCAT important files and directories:
#. Get ``installdir`` from ``site`` table, backup ``installdir`` directory,
in this case, back up ``install`` directory: ::
lsdef -t site clustersite -i installdir
Object name: clustersite
installdir=/install
#. Backup these two xCAT directories: ::
~/.xcat
/etc/xcat
**Notes**: 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: ::
lsdef -t osimage customized_rhels7.4-x86_64-install-compute -i otherpkgdir,pkgdir,pkglist,template
Object name: customized_rhels7.4-x86_64-install-compute
otherpkgdir=/<customized_dir>/post/otherpkgs/rhels7.4/x86_64
pkgdir=/<customized_pkgdir>/rhels7.4/x86_64
pkglist=/<customized_pkglist_dir>/compute.rhels7.pkglist
template=/<customized_temp_dir>/compute.rhels7.tmpl
1.2 Backup ssh related files: ::
/etc/ssh
~/.ssh
1.3 Backup host files: ::
/etc/resolv.conf
/etc/hosts
/etc/passwd
/etc/group
1.4 Backup yum resource files: ::
/etc/yum.repos.d
1.5 Backup conserver conf files: ::
/etc/conserver.cf
1.6 Backup DNS related files: ::
/etc/named
/etc/named.conf
/etc/named.iscdlv.key
/etc/named.root.key
/etc/rndc.key
/etc/sysconfig/named
/var/named
1.7 Backup dhcp files: ::
/etc/dhcp
/var/lib/dhcpd
/etc/sysconfig/dhcpd
/etc/sysconfig/dhcpd6
1.8 Backup apache: ::
/etc/httpd
/var/www
1.9 Backup tftp files: ::
/tftpboot
1.10 Backup NTP configure file: ::
/etc/ntp.conf
1.11 Backup database configure files (optional):
* **[PostgreSQL]** ::
/var/lib/pgsql/data/pg_hba.conf
/var/lib/pgsql/data/postgresql.conf
1.12 Backup NFS (optional): ::
/etc/exports
/var/lib/nfs
/etc/sysconfig/nfs
1.13 (optional)
Besides the files mentioned above, there may be some additional customization files and production files that need to be backup, depending on your local unique requirements. Here are some example files that can be considered: ::
/.profile
/.rhosts
/etc/auto_master
/etc/auto/maps/auto.u
/etc/motd
/etc/security/limits
/etc/netscvc.conf
/etc/inetd.conf
/etc/security/passwd
/etc/security/group
/etc/services
/etc/inittab(andmore)
1.14 Backup the xCAT database tables for the current configuration, using command: ::
dumpxCATdb -p <your_backup_dir>
1.15 Save all installed xCAT RPM names into a file: ::
rpm -qa|grep -i xCAT > xcat_rpm_names
1.16 (Optional) Find customization made to files installed from packages, backup these files. For example ::
rpm -q --verify -a conserver-xcat
rpm -q --verify -a xCAT-server
rpm -q --verify -a syslinux-xcat
rpm -q --verify -a xCAT-client
rpm -q --verify -a xCAT
Restore xCAT management node
----------------------------
2.1 Power off old xCAT management server before configuring new xCAT management server
2.2 Configure new xCAT management server using the same ip and hostname as old xCAT management server. Configure the same additional network for hardware management network if needed, for example, bmc network or hmc network. xCAT management server setup refer to :doc:`Prepare the Management Node <../../guides/install-guides/yum/prepare_mgmt_node>`
2.3 Overwrite files/directories methioned in above 1.2, 1.3, 1.4 from backup server to new xCAT management server
2.4 Download xcat-core and xcat-dep tar ball, then install xCAT in new xCAT management server, refer to :doc:`install xCAT <../../guides/install-guides/yum/install>`
2.5 Use ``rpm -qa|grep -i xCAT`` to list all xCAT RPMs in new xCAT management node, compare these RPMs base name with those in ``xcat_rpm_names`` from above 1.15. If some RPMs are missing, use ``yum install <rpm_package_basename>`` to install missing RPMs.
2.6 If use ``MySQL``/``MariaDB``/``PostgreSQL``, migrate xCAT to use ``MySQL/MariaDB/PostgreSQL`` refer to :doc:`Configure a Database <../hierarchy/databases/index>`
2.7 To restore the xCAT database
a. Restore xCAT database from the ``/dbbackup/db`` directory without ``auditlog`` and ``eventlog``, enter: ::
restorexCATdb -p /dbbackup/db
b. Restore the xCAT database including ``auditlog`` and ``eventlog`` from the ``/dbbackup/db`` directory, enter: ::
restorexCATdb -a -p /dbbackup/db
c. (optinal) Overwrite files in above 1.11, restart ``PostgreSQL``: ::
service postgresql restart
2.8 Overwrite remaining files/directories methioned in above 1.1, 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.12; If needed, check if files exist based on above 1.13 and 1.16.
2.9 Verify xCAT: ::
tabdump site
2.10 Restart ``named``, use ``nslookup`` to check ``DNS``: ::
service named restart
nslookup <cn1>
2.11 Restart ``conserver``, use ``rcons`` to check console: ::
service conserver restart
rcons <cn1>
2.12 Configure DHCP: ::
makedhcp -n
makedhcp -a
2.13 Restart ``httpd`` for REST API, for more information refer to :doc:`Rest API<../../../advanced/restapi/index>`: ::
service httpd restart
@@ -2,7 +2,7 @@ Manage Virtual Machine (VM)
============================
Now the MowerKVM hypervisor "kvmhost1" is ready, this section introduces the VM management in xCAT, including examples on how to create, remove and clone VMs.
Now the PowerKVM hypervisor "kvmhost1" is ready, this section introduces the VM management in xCAT, including examples on how to create, remove and clone VMs.
Create Virtual Machine
----------------------
@@ -82,7 +82,27 @@ After the VM object is created, several key attributes need to be specified with
chtab node=vm1 vm.vidpassword=abc123
10. Set **netboot** attribute
10. (optional)For assigning PCI devices to the VM, set **othersettings** value: ::
chtab node=vm1 vm.othersettings="devpassthrough:0000:01:00.2"
Or: ::
chtab node=vm1 vm.othersettings="devpassthrough:pci_0000_01_00_2"
Take assigning SR-IOV VFs to the VM as an example:
* Use ``lspci`` to get VFs PCI from hypervisor: ::
lspci|grep -i "Virtual Function"
0000:01:00.1 Infiniband controller: Mellanox Technologies MT27700 Family [ConnectX-4 Virtual Function]
0000:01:00.2 Infiniband controller: Mellanox Technologies MT27700 Family [ConnectX-4 Virtual Function]
* Set the VFs PCI into ``vm`` table on MN: ::
chtab node=vm1 vm.othersettings="devpassthrough:0000:01:00.1,0000:01:00.2"
11. Set **netboot** attribute
* **[x86_64]** ::
@@ -93,6 +93,9 @@ The BMC IP address is obtained by the open range dhcp server and the plan in thi
serial=10112CA
ip=10.1.2.1
#. Define the compute nodes into xCAT: ::
cat predefined.stanzas | mkdef -z
#. Set the chain table to run the ``bmcsetup`` script, this will set the BMC IP to static. ::
@@ -110,9 +113,6 @@ The BMC IP address is obtained by the open range dhcp server and the plan in thi
chdef cn01 bmc=172.20.2.1
#. Define the compute nodes into xCAT: ::
cat predefined.stanzas | mkdef -z
#. Add the compute node IP information to ``/etc/hosts``: ::
@@ -23,7 +23,7 @@ SYNOPSIS
\ **bmcdiscover**\ [\ **-v | -**\ **-version**\ ]
\ **bmcdiscover**\ [\ **-s**\ \ *scan_method*\ ] [\ **-u**\ \ *bmc_user*\ ] [\ **-p**\ \ *bmc_passwd*\ ] [\ **-z**\ ] [\ **-w**\ ] \ **-**\ **-range**\ \ *ip_ranges*\
\ **bmcdiscover**\ [\ **-**\ **-sn**\ \ *SN_nodename*\ ] [\ **-s**\ \ *scan_method*\ ] [\ **-u**\ \ *bmc_user*\ ] [\ **-p**\ \ *bmc_passwd*\ ] [\ **-z**\ ] [\ **-w**\ ] \ **-**\ **-range**\ \ *ip_ranges*\
\ **bmcdiscover**\ \ **-u**\ \ *bmc_user*\ \ **-p**\ \ *bmc_passwd*\ \ **-i**\ \ *bmc_ip*\ \ **-**\ **-check**\
@@ -56,6 +56,12 @@ OPTIONS
\ **-**\ **-sn**\
Specify one or more service nodes on which bmcdiscover will run. In hierarchical cluster, the MN may not be able to access the BMC of CN directly, but SN can. With this option, bmcdiscover will be dispatched to the specified SNs. Then, the nodename of the service node that 'bmcdiscover' is running on will be set to the 'servicenode' attribute of the discovered BMC node.
\ **-s**\
Scan method (The only supported scan method at this time is \ **nmap**\ )
@@ -142,7 +148,7 @@ EXAMPLES
Note: Input for IP range can be in the form: scanme.nmap.org, microsoft.com/24, 192.168.0.1; 10.0.0-255.1-254.
2. To get all BMSs in IP range "10.4.22-23.100-254", displayed in xCAT stanza format:
2. To get all BMCs in IP range "10.4.22-23.100-254", displayed in xCAT stanza format:
.. code-block:: perl
@@ -150,7 +156,30 @@ Note: Input for IP range can be in the form: scanme.nmap.org, microsoft.com/24,
bmcdiscover -s nmap --range "10.4.22-23.100-254" -z
3. Discover the BMCs and write the discovered-node definitions into the xCAT database and write out the stanza foramt to the console:
3. To discover BMCs through sn01:
.. code-block:: perl
bmcdiscover --sn sn01 -s nmap --range "10.4.22-23.100-254" -z
Output is similar to:
.. code-block:: perl
node-70e28414291b:
objtype=node
groups=all
bmc=10.4.22.101
cons=openbmc
mgt=openbmc
servicenode=sn01
conserver=sn01
4. Discover the BMCs and write the discovered-node definitions into the xCAT database and write out the stanza foramt to the console:
.. code-block:: perl
@@ -158,7 +187,7 @@ Note: Input for IP range can be in the form: scanme.nmap.org, microsoft.com/24,
bmcdiscover -s nmap --range "10.4.22-23.100-254" -w -z
4. To check if the username or password is correct against the BMC:
5. To check if the username or password is correct against the BMC:
.. code-block:: perl
@@ -166,7 +195,7 @@ Note: Input for IP range can be in the form: scanme.nmap.org, microsoft.com/24,
bmcdiscover -i 10.4.23.254 -u USERID -p PASSW0RD --check
5. Get BMC IP Address source, DHCP Address or static Address
6. Get BMC IP Address source, DHCP Address or static Address
.. code-block:: perl
@@ -50,14 +50,20 @@ OpenPOWER BMC specific (using IPMI):
====================================
\ **rflash**\ \ *noderange*\ [\ *hpm_file_path*\ | \ **-d=**\ \ *data_directory*\ ] [\ **-c | -**\ **-check**\ ] [\ **-**\ **-retry=**\ \ *count*\ ] [\ **-V**\ ]
\ **rflash**\ \ *noderange*\ [\ *hpm_file_path*\ | \ **-d**\ \ *data_directory*\ ] [\ **-c | -**\ **-check**\ ] [\ **-**\ **-retry=**\ \ *count*\ ] [\ **-V**\ ]
\ **rflash**\ \ *noderange*\ \ **-**\ **-recover**\ \ *bmc_file_path*\
OpenPOWER OpenBMC specific :
============================
\ **rflash**\ \ *noderange*\ [\ *tar_file_path*\ | \ *image_id*\ ] [\ **-c | -**\ **-check**\ ] [\ **-a | -**\ **-activate**\ ] [\ **-l | -**\ **-list**\ ] [\ **-u | -**\ **-upload**\ ] [\ **-d | -**\ **-delete**\ ]
\ **rflash**\ \ *noderange*\ {[\ **-c | -**\ **-check**\ ] | [\ **-l | -**\ **-list**\ ]}
\ **rflash**\ \ *noderange*\ \ *tar_file_path*\ {[\ **-c | -**\ **-check**\ ] | [\ **-a | -**\ **-activate**\ ] | [\ **-u | -**\ **-upload**\ ]}
\ **rflash**\ \ *noderange*\ \ *image_id*\ {[\ **-a | -**\ **-activate**\ ] | [\ **-d | -**\ **-delete**\ ]}
@@ -168,11 +174,11 @@ The command will update firmware for OpenPOWER OpenBMC when given an OpenPOWER n
\ **-d**\ \ *data_directory*\
PPC (without HMC, using Direct FSP Management) specific:
Specifies the directory where the raw data from rpm packages for each CEC/Frame are located. The default directory is /tmp. The option is only used in Direct FSP/BPA Management.
\ **-d=**\ \ *data_directory*\
OpenPOWER BMC specific (using IPMI):
Used for IBM Power S822LC for Big Data systems only. Specifies the directory where the \ **pUpdate**\ utility and at least one of BMC or PNOR update files are located. The utility and update files can be downloaded from FixCentral.
@@ -192,8 +198,14 @@ The command will update firmware for OpenPOWER OpenBMC when given an OpenPOWER n
\ **-**\ **-recover**\
PPC (with HMC) and PPC (without HMC, using Direct FSP Management) specific:
Used to recover the flash image in the permanent side of the chip to the temporary side for both managed systems and power subsystems.
OpenPOWER BMC specific (using IPMI):
Used for IBM Power S822LC for Big Data systems only. Used to recover the BMC with a BMC image downloaded from FixCentral.
\ **-**\ **-retry=**\ \ *count*\
@@ -204,7 +216,7 @@ The command will update firmware for OpenPOWER OpenBMC when given an OpenPOWER n
\ **-a|-**\ **-activate**\
Activate update image. Image id must be specified.
Activate update image. Image id or update file must be specified.
@@ -318,7 +330,17 @@ The command will update firmware for OpenPOWER OpenBMC when given an OpenPOWER n
.. code-block:: perl
rflash briggs01 -d=/root/supermicro/OP825
rflash briggs01 -d /root/supermicro/OP825
7. To update the firmware on the OpenBMC machine, specify the firmare update file to upload and activate:
.. code-block:: perl
rflash p9euh02 -a /tmp/witherspoon.pnor.squashfs.tar
@@ -11,7 +11,7 @@ SYNOPSIS
********
\ **rsetboot**\ \ *noderange*\ {\ **hd | net | cd | default | stat**\ } [\ **-u**\ ] [\ **-p**\ ]
\ **rsetboot**\ \ *noderange*\ [\ **hd | net | cd | default | stat**\ ] [\ **-u**\ ] [\ **-p**\ ]
\ **rsetboot**\ [\ **-h | -**\ **-help | -v | -**\ **-version**\ ]
@@ -21,7 +21,7 @@ DESCRIPTION
***********
\ **rsetboot**\ sets the boot media and boot mode that should be used on the next boot of the specified nodes. After the nodes are booted with the specified device and boot mode (e.g. via rpower(1)|rpower.1), the nodes will return to using the default boot device specified in the BIOS. Currently this command is only supported for IPMI nodes.
\ **rsetboot**\ sets the boot media and boot mode that should be used on the next boot of the specified nodes. After the nodes are booted with the specified device and boot mode (e.g. via rpower(1)|rpower.1), the nodes will return to using the default boot device specified in the BIOS.
*******
@@ -101,6 +101,14 @@ EXAMPLES
rsetboot node[14-56],node[70-203] stat
Or:
.. code-block:: perl
rsetboot node[14-56],node[70-203]
3.
@@ -47,7 +47,7 @@ OpenBMC specific:
=================
\ **rspconfig**\ \ *noderange*\ {\ **ip | netmask | gateway | vlan | sshcfg**\ }
\ **rspconfig**\ \ *noderange*\ {\ **ip | netmask | gateway | hostname | vlan | sshcfg**\ }
MPA specific:
@@ -394,6 +394,12 @@ OPTIONS
\ **hostname**\
Get or set hostname on the service processor.
\ **vlan**\
Get or set vlan ID. For get vlan ID, if vlan is not enabled, 'BMC VLAN disabled' will be outputed. For set vlan ID, the valid value are [1-4096].
@@ -59,7 +59,11 @@ Name
conveniently specify a list of nodes. The result is that the command will
be applied to a range of nodes, often in parallel.
To avoid shell expansion, \ **noderange**\ should better be quoted with single quotes('') or double quotes("").
If you invoke xCAT \ **noderange**\ from a shell you may need to quote the
\ **noderange**\ if the shell would otherwise treat the punctuation marks in
the \ **noderange**\ as control operators. The affected punctuation marks may
include Asterisk (\`*'), Left Square Bracket (\`[') , Right Square Bracket
(\`]'), Circumflex Accent (\`^'), and Overline (\`~').
\ **noderange**\ is a comma-separated list. Each token (text between commas)
in the list can be any of the forms listed below:
@@ -359,6 +363,14 @@ Example of \ **xCAT Node Name Format**\ node/group names:
************
\ **Bugs**\
************
The special characters used by xCAT \ **noderange**\ are also special characters
to many shell programs. In particular, the characters \`*', \`[', \`]', \`^',
and \`~' may have to be escaped from the shell.
****************
\ **SEE ALSO**\
****************
@@ -129,7 +129,7 @@ nics Attributes:
\ **nicsadapter**\
Comma-separated list of extra parameters that will be used for each NIC configuration.
<nic1>!<param1=value1 param2=value2>|<param3=value3>,<nic2>!<param4=value4 param5=value5>|<param6=value6>, for example, eth0!MTU=1500|MTU=1460,ib0!MTU=65520 CONNECTED_MODE=yes.
<nic1>!<param1=value1 param2=value2>,<nic2>!<param4=value4 param5=value5>, for example, enP3p3s0f1!mac=98:be:94:59:fa:cd linkstate=DOWN,enP3p3s0f2!mac=98:be:94:59:fa:ce candidatename=enP3p3s0f2/enx98be9459face
@@ -390,6 +390,18 @@ site Attributes:
hierarchicalattrs: Table attributes(e.g. postscripts, postbootscripts) that will be
included hierarchically. Attribute values for all the node's groups
will be applied to the node in the groups' order except the repeat one.
dbtracelevel: The trace level for the database access log. To activate this setting, please.
restart xcatd or send HUP signal to the 'xcatd: DB Access' process, Like: .
ps -ef | grep 'xcatd: DB Access' | grep -v grep | awk '{print $2}' | xargs kill -HUP
Currrent support values:
0: disable the trace log for db
1: trace the calls of database subroutines
2: Besides the log from level 1, trace the event to build the cache for the table
3: Besides the log from level 2, trace the event with cache hit
4: Besides the log from level 3, trace the SQL statement for the db access
With this configuration, xcat will send the log to syslog very frequently, some of the
log may be lost if imjournal is enabled by rsyslog.
Please see https://github.com/xcat2/xcat-core/issues/3910 for the detail.
-----------------------
VIRTUALIZATION ATTRIBUTES
@@ -157,6 +157,27 @@ Before you panic, let me explain each column:
See http://www.perl.com/doc/manual/html/pod/perlre.html for information on perl regular expressions.
Regular Expression Helper Functions
============================
xCAT provides several functions that can simplify regular expressions.
\ **a2idx(character) **\
Turns a single character into a 1-indexed index. a maps to 1 and z maps to 26.
\ **a2zidx(character) **\
Turns a single character into a 0-indexed index. a maps to 0 and z maps to 25.
\ **dim2idx(value, [count, value...]) **\
Converts dimensions (such as row, column, chassis, etc) into an index. If each rack has 18 nodes, use dim2idx(racknum, 18, nodenum). Additional dimensions should be added at the beginning. All values are 1-indexed.
\ **skip(index, skiplist) **\
Return an index with certain values skipped. The skip list uses the format start[:count][,start[:count]...]
\ **ipadd(octet1, octet2, octet3, octet4, toadd, skipstart, skipend) **\
Add to an IP address. Generally only necessary when you cross octets. Optionally skip addresses at the start and end of octets (like .0 or .255). Technically those are valid IP addresses, but sometimes software makes poor assumptions about which broadcast and gateway addresses.
Easy Regular Expressions
========================
@@ -41,7 +41,7 @@ group Attributes:
\ **addkcmdline**\ (bootparams.addkcmdline)
User specified one or more parameters to be passed to the kernel. For the kernel options need to be persistent after installation, specify them with prefix "R::"
User specified kernel options for os provision process(no prefix) or the provisioned os(with prefix "R::"). The options should be delimited with spaces(" ")
@@ -669,7 +669,7 @@ group Attributes:
\ **nicsadapter**\ (nics.nicsadapter)
Comma-separated list of extra parameters that will be used for each NIC configuration.
<nic1>!<param1=value1 param2=value2>|<param3=value3>,<nic2>!<param4=value4 param5=value5>|<param6=value6>, for example, eth0!MTU=1500|MTU=1460,ib0!MTU=65520 CONNECTED_MODE=yes.
<nic1>!<param1=value1 param2=value2>,<nic2>!<param4=value4 param5=value5>, for example, enP3p3s0f1!mac=98:be:94:59:fa:cd linkstate=DOWN,enP3p3s0f2!mac=98:be:94:59:fa:ce candidatename=enP3p3s0f2/enx98be9459face
@@ -41,7 +41,7 @@ node Attributes:
\ **addkcmdline**\ (bootparams.addkcmdline)
User specified one or more parameters to be passed to the kernel. For the kernel options need to be persistent after installation, specify them with prefix "R::"
User specified kernel options for os provision process(no prefix) or the provisioned os(with prefix "R::"). The options should be delimited with spaces(" ")
@@ -669,7 +669,7 @@ node Attributes:
\ **nicsadapter**\ (nics.nicsadapter)
Comma-separated list of extra parameters that will be used for each NIC configuration.
<nic1>!<param1=value1 param2=value2>|<param3=value3>,<nic2>!<param4=value4 param5=value5>|<param6=value6>, for example, eth0!MTU=1500|MTU=1460,ib0!MTU=65520 CONNECTED_MODE=yes.
<nic1>!<param1=value1 param2=value2>,<nic2>!<param4=value4 param5=value5>, for example, enP3p3s0f1!mac=98:be:94:59:fa:cd linkstate=DOWN,enP3p3s0f2!mac=98:be:94:59:fa:ce candidatename=enP3p3s0f2/enx98be9459face
@@ -41,7 +41,7 @@ osimage Attributes:
\ **addkcmdline**\ (linuximage.addkcmdline)
User specified arguments to be passed to the kernel. The user arguments are appended to xCAT.s default kernel arguments. For the kernel options need to be persistent after installation, specify them with prefix "R::". This attribute is ignored if linuximage.boottarget is set.
User specified kernel options for os provision process(no prefix) or the provisioned os(with prefix "R::"). The options should be delimited with spaces(" "). This attribute is ignored if linuximage.boottarget is set.
+2
View File
@@ -145,6 +145,8 @@ function makexcat {
cp xcat.conf $RPMROOT/SOURCES
cp xcat.conf.apach24 $RPMROOT/SOURCES
cp xCATSN $RPMROOT/SOURCES
cp -a ../xCAT/etc/rsyslog.d $RPMROOT/
cp -a ../xCAT/etc/logrotate.d $RPMROOT/
cd - >/dev/null
elif [ "$RPMNAME" = "xCAT-buildkit" ]; then
ARCH="noarch"
+10 -7
View File
@@ -184,7 +184,7 @@ sub updateUserInfo {
# update the merge file
my $mergefile = $cfmdir . "/" . $file . ".merge";
my @diff = xCAT::CFMUtils->arrayops("D", \@newrecords, \@oldrecords);
my @diff = xCAT::CFMUtils->arrayops("D", \@newrecords, \@oldrecords, 1);
# output the diff to merge files
my $fp;
@@ -865,6 +865,7 @@ sub trim {
$flag - "U"/"I"/"D"
\@array1 - reference to an arrary
\@array2 - reference to an arrary
$odered - flag to keep pervious order
Returns:
@union/@intersection/@difference
Globals:
@@ -878,7 +879,7 @@ sub trim {
#-----------------------------------------------------------------------------
sub arrayops {
my ($class, $ops, $array1, $array2) = @_;
my ($class, $ops, $array1, $array2, $ordered) = @_;
my @union = ();
my @intersection = ();
@@ -886,21 +887,23 @@ sub arrayops {
my %count = ();
foreach my $element (@$array1, @$array2)
{
$count{$element}++
$count{$element}++;
push @union, $element unless ( $count{$element} > 1 );
}
foreach my $element (keys %count) {
push @union, $element;
unless( defined($ordered) and $ordered ) {
@union = keys %count;
}
foreach my $element (@union) {
push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element;
}
if ($ops eq "U") { return @union; }
if ($ops eq "I") { return @intersection; }
if ($ops eq "D") { return @difference; }
#return (\@union, \@intersection, \@difference);
}
+92 -9
View File
@@ -225,7 +225,7 @@ sub rvlan {
my $switchestab = xCAT::Table->new('switches', -create => 0);
my @switchesents;
if ($switchestab) {
foreach (values %{ $switchestab->getNodesAttribs($switches, [qw(switch snmpversion username password privacy auth)]) }) {
foreach (values %{ $switchestab->getNodesAttribs($switches, [qw(switch snmpversion username password privacy auth switchtype)]) }) {
push @switchesents, @$_;
}
}
@@ -309,7 +309,7 @@ sub dump_mac_info {
}
}
my $switchestab = xCAT::Table->new('switches', -create => 0);
my @switchesents = $switchestab->getAllNodeAttribs([qw(switch snmpversion username password privacy auth)]);
my @switchesents = $switchestab->getAllNodeAttribs([qw(switch snmpversion username password privacy auth switchtype)]);
$self->fill_switchparms(community => $community, switchesents => \@switchesents);
my $switchtab = xCAT::Table->new('switch', -create => 0);
my @entries = ();
@@ -337,7 +337,12 @@ sub dump_mac_info {
if ($self->{show_verbose_info}) {
xCAT::MsgUtils->message("I", { data => ["<INFO>$switch: Attempting to refresh switch information..."] }, $self->{callback});
}
my $probestart = time;
$self->refresh_switch(undef, $community, $switch);
my $probestop = time;
my $probeduration = $probestop - $probestart;
xCAT::MsgUtils->message("S", "xcatprobe refresh_switch $switch ElapsedTime:$probeduration sec");
if ($self->{show_verbose_info}) {
xCAT::MsgUtils->message("I", { data => ["<INFO>$switch: Finished refreshing switch information."] }, $self->{callback});
}
@@ -403,7 +408,13 @@ sub find_mac {
#If requesting a cache only check or the cache is a mere 20 seconds old
#don't bother querying switches
if ($cachedonly or ($self->{timestamp} > (time() - 20))) { return undef; }
my $runstart = time;
$self->refresh_table($discover_switch); #not cached or stale cache, refresh
my $runstop = time;
my $diffduration = $runstop - $runstart;
xCAT::MsgUtils->message("S", "refresh_table ElapsedTime:$diffduration sec");
if ($self->{mactable}->{ lc($mac) }) {
return $self->{mactable}->{ lc($mac) };
}
@@ -419,6 +430,7 @@ sub fill_switchparms {
foreach (@switchentries) {
my $curswitch = $_->{switch};
$self->{switchparmhash}->{$curswitch} = $_;
$self->{switchparmhash}->{$curswitch}->{switchtype}=$_->{switchtype};
if ($_->{snmpversion}) {
if ($_->{snmpversion} =~ /3/) { #clean up to accept things like v3 or ver3 or 3, whatever.
$self->{switchparmhash}->{$curswitch}->{snmpversion} = 3;
@@ -444,7 +456,7 @@ sub refresh_table {
$self->{mactable} = {};
$self->{switchtab} = xCAT::Table->new('switch', -create => 1);
$self->{switchestab} = xCAT::Table->new('switches', -create => 1);
my @switchentries = $self->{switchestab}->getAllNodeAttribs([qw(switch snmpversion username password privacy auth)]);
my @switchentries = $self->{switchestab}->getAllNodeAttribs([qw(switch snmpversion username password privacy auth switchtype)]);
my $community = "public";
#$self->{sitetab} = xCAT::Table->new('site');
@@ -477,6 +489,9 @@ sub refresh_table {
unless (defined $_->{password}) { #if no password set, inherit the community
$self->{switchparmhash}->{$curswitch}->{password} = $community;
}
if (defined $_->{switchtype}){
$self->{switchparmhash}->{$curswitch}->{switchtype} =$_->{switchtype};
}
}
my %checked_pairs;
my @entries = $self->{switchtab}->getAllNodeAttribs([ 'node', 'port', 'switch' ]);
@@ -497,7 +512,7 @@ sub refresh_table {
my $ntype = $typehash->{$entry->{node}}->[0]->{nodetype};
if ( (($discover_switch) and ( $ntype ne "switch"))
or ( !($discover_switch) and ( $ntype eq "switch")) ){
xCAT::MsgUtils->message("S", "refresh_table: skip $entry->{node} and $entry->{switch}");
xCAT::MsgUtils->message("S", "refresh_table: skip $entry->{node} and $entry->{switch}, $discover_switch , $ntype\n");
next;
}
if (defined($entry->{switch}) and $entry->{switch} ne "" and defined($entry->{port}) and $entry->{port} ne "") {
@@ -534,7 +549,11 @@ sub refresh_table {
if ($cpid == 0) {
close($child);
my $runstart = time;
$self->refresh_switch($parent, $community, $entry->{switch});
my $runstop = time;
my $diffduration = $runstop - $runstart;
xCAT::MsgUtils->message("S", "refresh_switch $entry->{switch} ElapsedTime:$diffduration sec");
exit(0);
}
close($parent);
@@ -615,6 +634,9 @@ sub walkoid {
return $retmap;
}
sub getsnmpsession {
#gets an snmp v3 session appropriate for a switch using the switches table for guidance on the hows
@@ -688,7 +710,54 @@ sub refresh_switch {
my $community = shift;
my $switch = shift;
#if ($error) { die $error; }
unless($self->{collect_mac_info})
{
if($self->{switchparmhash}->{$switch}->{switchtype} eq 'onie'){
#for cumulus switch, the MAC table can be retrieved with ssh
#which is much faster than snmp
my $mymac;
my $myport;
my @res=xCAT::Utils->runcmd("ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no $switch 'bridge fdb show|grep -i -v permanent|tr A-Z a-z 2>/dev/null' 2>/dev/null",-1);
unless (@res) {
xCAT::MsgUtils->message("S", "Failed to get mac table with ssh to $switch, fall back to snmp! To obtain mac table with ssh, please make sure the passwordless root ssh to $switch is available");
}else{
foreach (@res){
if($_ =~ m/^([0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}) dev swp([0-9]+) .*/){
$mymac=$1;
$myport=$2;
$myport=sprintf("%d",$myport);
#try all the possible port number formats
#e.g, "5","swp5","05","swp05"
unless(exists $self->{switches}->{$switch}->{$myport}){
if(exists $self->{switches}->{$switch}->{"swp".$myport}){
$myport="swp".$myport;
}else{
$myport=sprintf("%02d",$myport);
unless(exists $self->{switches}->{$switch}->{$myport}){
if(exists $self->{switches}->{$switch}->{"swp".$myport}){
$myport="swp".$myport;
}else{
$myport="";
}
}
}
}
if($myport){
if($output){
printf $output "$mymac|%s\n", $self->{switches}->{$switch}->{$myport};
}
}
}
}
return;
}
}
}
my $session = $self->getsnmpsession('community' => $community, 'switch' => $switch);
unless ($session) {
xCAT::MsgUtils->message("S", "Failed to communicate with $switch");
@@ -734,6 +803,9 @@ sub refresh_switch {
xCAT::MsgUtils->message("I", "MTU information is not availabe for this switch $switch");
}
# get port state
my $mactostate = walkoid($session, '.1.3.6.1.2.1.17.7.1.2.2.1.3', silentfail => 1, verbose => $self->{show_verbose_info}, switch => $switch, callback => $self->{callback});
#Above is valid without community string indexing, on cisco, we need it on the next one and onward
my $iftovlanmap = walkoid($session, '.1.3.6.1.4.1.9.9.68.1.2.2.1.2', silentfail => 1, verbose => $self->{show_verbose_info}, switch => $switch, callback => $self->{callback}); #use cisco vlan membership mib to ascertain vlan
my $trunktovlanmap = walkoid($session, '.1.3.6.1.4.1.9.9.46.1.6.1.1.5', silentfail => 1, verbose => $self->{show_verbose_info}, switch => $switch, callback => $self->{callback}); #for trunk ports, we are interested in the native vlan, so we need cisco vtp mib too
@@ -762,6 +834,10 @@ sub refresh_switch {
$self->{nodeinfo}->{ $self->{switches}->{$switch}->{$portname} }->{vlans}->{$portname} = $trunktovlanmap->{$portid};
}
}
#still needs output if there are no switchport defined on the nodes
if (not defined $portname) {
$vlans_to_check{'NA'} = 1;
}
}
} else {
$vlans_to_check{'NA'} = 1;
@@ -784,9 +860,11 @@ sub refresh_switch {
my $bridgetoifmap = walkoid($session, '.1.3.6.1.2.1.17.1.4.1.2', ciscowarn => $iscisco, verbose => $self->{show_verbose_info}, switch => $switch, callback => $self->{callback}); # Good for all switches
if (not ref $bridgetoifmap or !keys %{$bridgetoifmap}) {
xCAT::MsgUtils->message("S", "Error communicating with " . $session->{DestHost} . ": failed to get a valid response to BRIDGE-MIB request");
if ($self->{collect_mac_info}) {
$self->{macinfo}->{$switch}->{ErrorStr} = "Failed to get a valid response to BRIDGE-MIB request";
}
return;
}
# my $mactoindexmap = walkoid($session,'.1.3.6.1.2.1.17.4.3.1.2');
my $mactoindexmap = walkoid($session, '.1.3.6.1.2.1.17.7.1.2.2.1.2', silentfail => 1, verbose => $self->{show_verbose_info}, switch => $switch, callback => $self->{callback});
unless (defined($mactoindexmap)) { #if no qbridge defined, try bridge mib, probably cisco
@@ -795,9 +873,11 @@ sub refresh_switch {
} #Ok, time to process the data
if (not ref $mactoindexmap or !keys %{$mactoindexmap}) {
xCAT::MsgUtils->message("S", "Error communicating with " . $session->{DestHost} . ": Unable to get MAC entries via either BRIDGE or Q-BRIDE MIB");
if ($self->{collect_mac_info}) {
$self->{macinfo}->{$switch}->{ErrorStr} = "Unable to get MAC entries via either BRIDGE or Q-BRIDE MIB";
}
return;
}
if (defined($self->{collect_mac_info})) {
my %index_to_mac = ();
my %index_to_vlan = ();
@@ -807,8 +887,11 @@ sub refresh_switch {
my $vlan = @tmp[0];
my @mac = @tmp[ -6 .. -1 ];
my $macstring = sprintf("%02x:%02x:%02x:%02x:%02x:%02x", @mac);
push @{ $index_to_mac{$index} }, $macstring;
push @{ $index_to_vlan{$index} }, $vlan;
# Skip "permanent" ports
if (!defined($mactostate->{$_}) || $mactostate->{$_} != 4) {
push @{ $index_to_mac{$index} }, $macstring;
push @{ $index_to_vlan{$index} }, $vlan;
}
}
foreach my $boid (keys %$bridgetoifmap) {
my $port_index = $boid;
+31
View File
@@ -2778,4 +2778,35 @@ sub gen_net_boot_params
return $net_params;
}
#--------------------------------------------------------------------------------
=head3 send_tcp_msg
establish a tcp socket to the specified IP address and port, then send the specifid message via the socket
Arguments:
$destip : the destination IP address
$destport: the destination TCP port
$msg : the message to send
Returns:
0 on success, 1 on fail
=cut
#--------------------------------------------------------------------------------
sub send_tcp_msg {
my $self=shift;
my $destip=shift;
my $destport=shift;
my $msg=shift;
my $sock = new IO::Socket::INET(
PeerAddr => $destip,
PeerPort => $destport,
Timeout => '1',
Proto => 'tcp'
);
if ($sock) {
print $sock $msg;
close($sock);
return 0;
}else{
return 1;
}
}
1;
+14 -2
View File
@@ -226,7 +226,7 @@ qq{ link,ro - The file is readonly, and will be placed in tmpfs on the booted no
'vncport' => 'Tracks the current VNC display port (currently not meant to be set',
'textconsole' => 'Tracks the Psuedo-TTY that maps to the serial port or console of a VM',
'powerstate' => "This flag is used by xCAT to track the last known power state of the VM.",
'othersettings' => "This allows specifying a semicolon delimited list of key->value pairs to include in a vmx file of VMware or KVM. For partitioning on normal power machines, this option is used to specify the hugepage and/or bsr information, the value is like:'hugepage:1,bsr=2'. For KVM cpu pinning, this option is used to specify the physical cpu set on the host, the value is like:\"vcpupin:'0-15,^8'\",Its syntax is a comma separated list and a special markup using '-' and '^' (ex. '0-4', '0-3,^2') can also be allowed, the '-' denotes the range and the '^' denotes exclusive. For KVM memory binding, the value is like:'membind:0', restrict a guest to allocate memory from the specified set of NUMA nodes. For PCI passthrough, the value is like:'devpassthrough:pci_0001_01_00_0,pci_0000_03_00_0',the PCI devices are assigned to a virtual machine, and the virtual machine can use this I/O exclusively, the devices list are a list of PCI device names delimited with comma, the PCI device names can be obtained by running B<virsh nodedev-list> on the host.",
'othersettings' => "This allows specifying a semicolon delimited list of key->value pairs to include in a vmx file of VMware or KVM. For partitioning on normal power machines, this option is used to specify the hugepage and/or bsr information, the value is like:'hugepage:1,bsr=2'. For KVM cpu pinning, this option is used to specify the physical cpu set on the host, the value is like:\"vcpupin:'0-15,^8'\",Its syntax is a comma separated list and a special markup using '-' and '^' (ex. '0-4', '0-3,^2') can also be allowed, the '-' denotes the range and the '^' denotes exclusive. For KVM memory binding, the value is like:'membind:0', restrict a guest to allocate memory from the specified set of NUMA nodes. For PCI passthrough, the value is like:'devpassthrough:pci_0001_01_00_0,pci_0000_03_00_0', the value for PCI device format also can be like:'devpassthrough:0001:01:00.1', the PCI devices are assigned to a virtual machine, and the virtual machine can use this I/O exclusively, the devices list are a list of PCI device names delimited with comma, the PCI device names can be obtained by running B<virsh nodedev-list> on the host.",
'guestostype' => "This allows administrator to specify an identifier for OS to pass through to virtualization stack. Normally this should be ignored as xCAT will translate from nodetype.os rather than requiring this field be used\n",
'beacon' => "This flag is used by xCAT to track the state of the identify LED with respect to the VM.",
'datacenter' => "Optionally specify a datacenter for the VM to exist in (only applicable to VMWare)",
@@ -1243,7 +1243,19 @@ passed as argument rather than by table value',
" Qualified Domain Name). Otherwise, the original behavior will be performed.\n\n" .
" hierarchicalattrs: Table attributes(e.g. postscripts, postbootscripts) that will be\n" .
" included hierarchically. Attribute values for all the node's groups\n" .
" will be applied to the node in the groups' order except the repeat one.\n\n" .
" will be applied to the node in the groups' order except the repeat one.\n" .
" dbtracelevel: The trace level for the database access log. To activate this setting, please. \n".
" restart xcatd or send HUP signal to the 'xcatd: DB Access' process, Like: .\n".
" ps -ef | grep 'xcatd: DB Access' | grep -v grep | awk '{print \$2}' | xargs kill -HUP \n".
" Currrent support values: \n" .
" 0: disable the trace log for db \n" .
" 1: trace the calls of database subroutines \n" .
" 2: Besides the log from level 1, trace the event to build the cache for the table \n" .
" 3: Besides the log from level 2, trace the event with cache hit \n" .
" 4: Besides the log from level 3, trace the SQL statement for the db access \n" .
" With this configuration, xcat will send the log to syslog very frequently, some of the \n".
" log may be lost if imjournal is enabled by rsyslog. \n".
" Please see https://github.com/xcat2/xcat-core/issues/3910 for the detail.\n\n" .
" -----------------------\n" .
"VIRTUALIZATION ATTRIBUTES\n" .
" -----------------------\n" .
+353 -6
View File
@@ -71,6 +71,9 @@ require xCAT::Schema;
require xCAT::NodeRange;
use Text::Balanced qw(extract_bracketed);
require xCAT::NotifHandler;
use Time::HiRes qw/time/;
use JSON;
#The process id of the database worker
# -1 db process has not been started, access db in direct access mode.
@@ -82,7 +85,19 @@ my $dbsockpath = "/var/run/xcat/dbworker.sock." . $$;
my $exitdbthread;
my $dbobjsforhandle;
my $intendedpid;
my $dbtracelevel;
my %elapsed;
use constant BUILD_CACHE_TYPE => "build_cache";
use constant CACHE_HIT_TYPE => "cache_hit";
use constant START_TYPE => "start";
use constant END_TYPE => "end";
use constant START_SQL_TYPE => "start_sql";
use constant END_SQL_TYPE => "end_sql";
use constant INFO_TYPE => "info";
my %trace_level_mapping = (START_TYPE() => 1, END_TYPE() => 1, BUILD_CACHE_TYPE() => 2,
CACHE_HIT_TYPE() => 3, START_SQL_TYPE() => 4, END_SQL_TYPE() => 4, INFO_TYPE() => 5);
sub dbc_call {
my $self = shift;
@@ -155,6 +170,99 @@ sub dbc_submit {
}
}
#--------------------------------------------------------------------------------
=head3 _trace_log
Private helper function to write log message in json format
Arguments:
$type: the type of the log content.
$msg: the message content
Returns:
none
Error:
none
=cut
#--------------------------------------------------------------------------------
sub _trace_log
{
my ($type, $msg) = @_;
if( $type eq START_TYPE || $type eq START_SQL_TYPE) {
$elapsed{$trace_level_mapping{$type}} = time();
}
my %hash = ("type" => $type, "msg" => $msg);
if($type eq END_TYPE || $type eq END_SQL_TYPE) {
if (!$elapsed{$trace_level_mapping{$type}}) {
return;
}
$hash{"elapsed"} = sprintf("%.5fs", time() - $elapsed{$trace_level_mapping{$type}});
}
xCAT::MsgUtils->message("S", "[DB Trace]: ".encode_json(\%hash));
}
#--------------------------------------------------------------------------------
=head3 trace_db
Add log entries to trace db acccess
Arguments:
$type: the type of the log content. If it is "start", "start_sq"l, "end", "end_sql",
a timer will be used to help calculate the elapsed time. Note, "start" and "end"
or "start_sql" and "end_sql" must be used in pairs.
$addon: the addon message.
Returns:
none
Error:
none
Example:
$self->trace_db("start"); # timer started.
......
$self->trace_db("end"); # print elapsed time.
$self->trace_db("start_sql"); # timer started.
...... # statement to run the sql
$self->trace_db("end_sql"); # print elapsed time.
=cut
#--------------------------------------------------------------------------------
sub trace_db {
my $self = shift;
my ($type, $addon) = @_;
if (!$dbtracelevel) {
return;
}
if($dbworkerpid > 0) {
return;
}
$type = INFO_TYPE if (!$type);
if (!exists($trace_level_mapping{$type})) {
xCAT::MsgUtils->message("S", "Unsupported db trace type $type");
return;
}
if (($trace_level_mapping{$type} == 1) && (caller(2))[3] ne "xCAT::Table::handle_dbc_request") {
# ignore internal calls
return;
}
if ($trace_level_mapping{$type} <= $dbtracelevel) {
my $msg;
$msg->{"table"} = $self->{tabname};
$msg->{"method"} = (caller(1))[3];
$msg->{"addon"} = $addon if $addon;
_trace_log($type, $msg);
}
}
sub shut_dbworker {
$dbworkerpid = -1; #For now, just turn off usage of the db worker
#This was created as the monitoring framework shutdown code otherwise seems to have a race condition
@@ -188,6 +296,7 @@ sub init_dbworker {
}
unless ($dbworkerpid) {
$intendedpid = $$;
$dbtracelevel = xCAT::TableUtils->get_site_attribute("dbtracelevel");
$SIG{CHLD} = sub { while (waitpid(-1, WNOHANG) > 0) { } }; #avoid zombies from notification framework
#This process is the database worker, it's job is to manage database queries to reduce required handles and to permit cross-process caching
$0 = "xcatd: DB Access";
@@ -199,6 +308,13 @@ sub init_dbworker {
$SIG{ALRM} = sub { exit 0; };
alarm(10);
};
$SIG{HUP} = sub {
$dbtracelevel = xCAT::TableUtils->get_site_attribute("dbtracelevel");
xCAT::MsgUtils->message("S", "dbtracelevel has been reloaded, current value is $dbtracelevel");
foreach my $item ( keys %elapsed) {
$elapsed{$item} = undef;
}
};
unlink($dbsockpath);
umask(0077);
$dbworkersocket = IO::Socket::UNIX->new(Local => $dbsockpath, Type => SOCK_STREAM, Listen => 8192);
@@ -1453,8 +1569,10 @@ sub addAttribs
$qstring = $qstring . "?,";
}
$qstring =~ s/,$/)/;
$self->trace_db(START_SQL_TYPE, $qstring);
my $sth = $self->{dbh}->prepare($qstring);
$sth->execute(@bind);
$self->trace_db(END_SQL_TYPE);
#$self->{dbh}->commit;
@@ -1604,6 +1722,7 @@ sub setAttribs
if ($dbworkerpid > 0) {
return dbc_call($self, 'setAttribs', @_);
}
$self->trace_db(START_TYPE);
my $pKeypairs = shift;
my %keypairs = ();
if ($pKeypairs != undef) { %keypairs = %{$pKeypairs}; }
@@ -1646,8 +1765,10 @@ sub setAttribs
$qstring =~ s/ AND \z//;
#print "this is qstring1: $qstring\n";
$self->trace_db(START_SQL_TYPE, $qstring);
$query = $self->{dbh}->prepare($qstring);
$query->execute(@qargs);
$self->trace_db(END_SQL_TYPE);
#get the first row
$data = $query->fetchrow_arrayref();
@@ -1720,13 +1841,17 @@ sub setAttribs
}
}
$cmd =~ s/ AND \z//;
$self->trace_db(START_SQL_TYPE, $qstring);
my $sth = $self->{dbh}->prepare($cmd);
unless ($sth) {
$self->trace_db(END_TYPE, "LINE ".__LINE__.": Error attempting requested DB operation");
return (undef, "Error attempting requested DB operation");
}
my $err = $sth->execute(@bind);
$self->trace_db(END_SQL_TYPE);
if (not defined($err))
{
$self->trace_db(END_TYPE, "LINE ".__LINE__.": ".$sth->errstr);
return (undef, $sth->errstr);
}
$sth->finish;
@@ -1781,10 +1906,13 @@ sub setAttribs
$qstring = $qstring . "?,";
}
$qstring =~ s/,$/)/;
$self->trace_db(START_SQL_TYPE, $qstring);
my $sth = $self->{dbh}->prepare($qstring);
my $err = $sth->execute(@bind);
$self->trace_db(END_SQL_TYPE, $qstring);
if (not defined($err))
{
$self->trace_db(END_TYPE, "LINE ".__LINE__.": ". $sth->errstr);
return (undef, $sth->errstr);
}
$sth->finish;
@@ -1803,6 +1931,7 @@ sub setAttribs
xCAT::NotifHandler->notify($action, $self->{tabname},
\@notif_data, \%new_notif_data);
}
$self->trace_db(END_TYPE);
return 0;
}
@@ -1850,6 +1979,7 @@ sub setAttribsWhere
if ($dbworkerpid > 0) {
return dbc_call($self, 'setAttribsWhere', @_);
}
$self->trace_db(START_TYPE);
my $where_clause = shift;
my $elems = shift;
my $cols = "";
@@ -1864,8 +1994,10 @@ sub setAttribsWhere
}
my $qstring = "SELECT * FROM " . $self->{tabname} . " WHERE " . $where_clause;
my @qargs = ();
$self->trace_db(START_SQL_TYPE, $qstring);
my $query = $self->{dbh}->prepare($qstring);
$query->execute(@qargs);
$self->trace_db(END_SQL_TYPE);
#get the first row
my $data = $query->fetchrow_arrayref();
@@ -1903,10 +2035,13 @@ sub setAttribsWhere
}
chop($cols);
my $cmd = "UPDATE " . $self->{tabname} . " set $cols where " . $where_clause;
$self->trace_db(START_SQL_TYPE, $qstring);
my $sth = $self->{dbh}->prepare($cmd);
my $err = $sth->execute(@bind);
$self->trace_db(END_SQL_TYPE);
if (not defined($err))
{
$self->trace_db(END_TYPE, "LINE ".__LINE__.": ".$sth->errstr);
return (undef, $sth->errstr);
}
@@ -1923,6 +2058,7 @@ sub setAttribsWhere
\@notif_data, \%new_notif_data);
}
$sth->finish;
$self->trace_db(END_TYPE);
return 0;
}
@@ -1968,6 +2104,7 @@ sub setNodesAttribs {
if ($dbworkerpid > 0) {
return dbc_call($self, 'setNodesAttribs', @_);
}
$self->trace_db(START_TYPE);
my $nodelist = shift;
my $keyset = shift;
my %cols = ();
@@ -2025,6 +2162,7 @@ sub setNodesAttribs {
}
$self->{dbh}->commit; #commit pending transactions
$self->{dbh}->{AutoCommit} = $oldac; #restore autocommit semantics
$self->trace_db(END_TYPE);
return;
}
@@ -2066,8 +2204,10 @@ sub setNodesAttribs {
$qstring = "SELECT * FROM " . $self->{tabname} . " WHERE $dnodekey in (";
$qstring .= '?, ' x scalar(@currnodes);
$qstring =~ s/, $/)/;
$self->trace_db(START_SQL_TYPE, $qstring);
my $query = $self->{dbh}->prepare($qstring);
$query->execute(@currnodes);
$self->trace_db(END_SQL_TYPE);
my $rec;
while ($rec = $query->fetchrow_hashref()) {
$updatenodes{ $rec->{$nodekey} } = 1;
@@ -2093,7 +2233,7 @@ sub setNodesAttribs {
$bindhooks =~ s/, $//;
$columns =~ s/, $//;
my $instring = "INSERT INTO " . $self->{tabname} . " ($columns) VALUES ($bindhooks)";
$self->trace_db(START_SQL_TYPE, $instring);
#print $instring;
$insertsth = $self->{dbh}->prepare($instring);
}
@@ -2105,7 +2245,9 @@ sub setNodesAttribs {
foreach my $col (@orderedcols) {
push @args, $hashrec->{$node}->{$col};
}
$insertsth->execute(@args);
$self->trace_db(END_SQL_TYPE);
}
if (not $upsth and keys %updatenodes) { #prepare an insert statement since one will be needed
my $upstring = "UPDATE " . $self->{tabname} . " set ";
@@ -2127,7 +2269,9 @@ sub setNodesAttribs {
push @args, $hashrec->{$node}->{$col};
}
push @args, $node;
$self->trace_db(START_SQL_TYPE, $upstring);
$upsth->execute(@args);
$self->trace_db(END_SQL_TYPE);
}
}
@currnodes = splice(@$nodelist, 0, $nodesatatime);
@@ -2135,6 +2279,7 @@ sub setNodesAttribs {
$self->{dbh}->commit; #commit pending transactions
$self->{dbh}->{AutoCommit} = $oldac; #restore autocommit semantics
$self->_refresh_cache(); #cache is invalid, refresh
$self->trace_db(END_TYPE);
}
#--------------------------------------------------------------------------
@@ -2170,6 +2315,7 @@ sub getNodesAttribs {
if ($dbworkerpid > 0) {
return dbc_call($self, 'getNodesAttribs', @_);
}
$self->trace_db(START_TYPE);
my $nodelist = shift;
unless ($nodelist) { $nodelist = []; } #common to be invoked with undef seemingly
my %options = ();
@@ -2216,6 +2362,7 @@ sub getNodesAttribs {
if ($self->{tabname} ne 'nodelist') {
$self->{nodelist}->{_use_cache} = 0;
}
$self->trace_db(END_TYPE);
return $rethash;
}
@@ -2293,6 +2440,7 @@ sub _build_cache { #PRIVATE FUNCTION, PLEASE DON'T CALL DIRECTLY
unless (grep /^$nodekey$/, @$attriblist) {
push @$attriblist, $nodekey;
}
$self->trace_db(BUILD_CACHE_TYPE);
my @tabcache = $self->getAllAttribs(@$attriblist);
$self->{_tablecache} = \@tabcache;
$self->{_nodecache} = {};
@@ -2316,7 +2464,153 @@ sub mknum {
return $number;
}
#--------------------------------------------------------------------------------
=head3 a2idx
Description:
Turns a character into a 1-indexed index
Arguments:
character: The character to convert
Returns:
The index
Example:
a2zidx('a') returns 1
a2zidx('b') returns 2
=cut
#--------------------------------------------------------------------------------
sub a2idx {
return ord(lc(shift)) - 96;
}
#--------------------------------------------------------------------------------
=head3 a2zidx
Description:
Turns a character into a 0-indexed index
Arguments:
character: The character to convert
Returns:
The index
Example:
a2zidx('a') returns 0
a2zidx('b') returns 1
=cut
#--------------------------------------------------------------------------------
sub a2zidx {
return ord(lc(shift)) - 97;
}
#--------------------------------------------------------------------------------
=head3 dim2idx
Description:
Converts dimensions into an index
Arguments:
dim_value: the value of the current dimension
dim_total: the total number of elements in that dimension
Returns:
The index
Example:
A cluster has 4 rows
A row has 10 racks
A rack has 8 chassis
A chassis has 8 nodes
Row 2, rack 3, chassis 4, node 5
dim2idx(2, 10, 3, 8, 4, 8, 5) returns 797
Note the highest dimension is not needed and all values are 1-indexed
=cut
#--------------------------------------------------------------------------------
sub dim2idx {
my $val = 0; # value to return
my $fn = 0; # math function to apply, 0 is add, 1 is multiply
while (defined(my $element = shift)) {
$val += $element - 1 if !$fn;
$val *= $element if $fn;
$fn = 1 - $fn;
}
return $val + 1;
}
#--------------------------------------------------------------------------------
=head3 skip
Description:
Return an index with certain values skipped
Arguments:
index: The initial index
skips: Index values to skip
format start[:count][,start[:count]...]
Returns:
The updated index
Example:
skip(10, '3') returns 9
skip(10, '3:2') returns 8
skip(10, '3:2,6') returns 7
=cut
#--------------------------------------------------------------------------------
sub skip {
my $idx = my $val = shift;
my $skips = shift;
foreach my $element (split /,/, $skips) {
my ($start, $count) = split /:/, $element;
$count = 1 if ! defined($count);
if ($idx >= $start) {
if ($idx < $start + $count) {return -1;}
$val-= $count;
} else {
last;
}
}
return $val;
}
#--------------------------------------------------------------------------------
=head3 ipadd
Description:
Add to an IP address. Useful when you cross octets.
Optionally skip addresses at the start and end of octets (like .0 or .255).
Technically those are valid IP addresses, but sometimes software makes
poor assumptions about which broadcast and gateway addresses.
Arguments:
b1: Starting IP address first octet
b2: Starting IP address second octet
b3: Starting IP address third octet
b4: Starting IP address fourth octet
toadd: Value to add to the starting address
skipstart: Number of addresses to skip at the start of the last octet
skipend: Number of addresses to skip at the end of the last octet
Returns:
The new IP address
Example:
ipadd(10, 10, 10, 10, 0, 0, 0) returns 10.10.10.10
ipadd(10, 10, 10, 10, 10, 0, 0) returns 10.10.10.20
ipadd(10, 10, 10, 10, 245, 0, 0) returns 10.10.10.255
ipadd(10, 10, 10, 10, 246, 0, 0) returns 10.10.11.0
=cut
#--------------------------------------------------------------------------------
sub ipadd {
use integer;
my ($b1, $b2, $b3, $b4, $toadd, $skipstart, $skipend) = @_;
my $offset = ($b4 >= $skipstart) ? $b4 - $skipstart : 0;
$b3 += ($offset + $toadd) / (256-$skipstart-$skipend);
$b4 = ($offset + $toadd) % (256-$skipstart-$skipend) + $skipstart;
return join('.', $b1, $b2, $b3, $b4);
}
$evalcpt->share('&mknum');
$evalcpt->share('&a2idx');
$evalcpt->share('&a2zidx');
$evalcpt->share('&dim2idx');
$evalcpt->share('&skip');
$evalcpt->share('&ipadd');
$evalcpt->permit('require');
#--------------------------------------------------------------------------
@@ -2443,6 +2737,7 @@ sub getNodeAttribs
#db worker scope
return dbc_call($self, 'getNodeAttribs', @_);
}
$self->trace_db(START_TYPE);
if (!defined($self->{dbh})) {
xCAT::MsgUtils->message("S", "xcatd: DBI is missing, Please check the db access process.");
@@ -2521,6 +2816,7 @@ sub getNodeAttribs
}
}
}
$self->trace_db(END_TYPE);
return wantarray ? @data : $data[0];
}
@@ -2862,7 +3158,6 @@ sub getNodeAttribs_nosub_returnany
}
}
}
return @results;
}
@@ -2901,6 +3196,7 @@ sub getAllEntries
if ($dbworkerpid > 0) {
return dbc_call($self, 'getAllEntries', @_);
}
$self->trace_db(START_TYPE);
if (!defined($self->{dbh})) {
xCAT::MsgUtils->message("S", "xcatd: DBI is missing, Please check the db access process.");
@@ -2915,12 +3211,15 @@ sub getAllEntries
my $disable = &delimitcol("disable");
if ($allentries) { # get all lines
$query = $self->{dbh}->prepare('SELECT * FROM ' . $self->{tabname});
$self->trace_db(START_SQL_TYPE, 'SELECT * FROM ' . $self->{tabname});
} else { # get only enabled lines
my $qstring = 'SELECT * FROM ' . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
$query = $self->{dbh}->prepare($qstring);
$self->trace_db(START_SQL_TYPE, $qstring);
}
$query->execute();
$self->trace_db(END_SQL_TYPE);
while (my $data = $query->fetchrow_hashref())
{
foreach (keys %$data)
@@ -2933,6 +3232,7 @@ sub getAllEntries
push @rets, $data;
}
$query->finish();
$self->trace_db(END_TYPE);
return \@rets;
}
@@ -2995,6 +3295,7 @@ sub getAllAttribsWhere
if ($dbworkerpid > 0) {
return dbc_call($self, 'getAllAttribsWhere', @_);
}
$self->trace_db(START_TYPE);
my $clause = shift;
my $whereclause;
my @attribs = @_;
@@ -3011,8 +3312,10 @@ sub getAllAttribsWhere
# delimit the disable column based on the DB
my $disable = &delimitcol("disable");
$query2 = 'SELECT * FROM ' . $self->{tabname} . ' WHERE (' . $whereclause . ") and ($disable is NULL or $disable in ('0','no','NO','No','nO'))";
$self->trace_db(START_SQL_TYPE, $query2);
$query = $self->{dbh}->prepare($query2);
$query->execute();
$self->trace_db(END_SQL_TYPE);
while (my $data = $query->fetchrow_hashref())
{
my %newrow = ();
@@ -3040,6 +3343,7 @@ sub getAllAttribsWhere
}
}
$query->finish();
$self->trace_db(END_TYPE);
return @results;
}
@@ -3078,6 +3382,7 @@ sub getAllNodeAttribs
if ($dbworkerpid > 0) {
return dbc_call($self, 'getAllNodeAttribs', @_);
}
$self->trace_db(START_TYPE);
my $attribq = shift;
my $hashretstyle = shift;
my %options = @_;
@@ -3098,8 +3403,10 @@ sub getAllNodeAttribs
my $qstring = 'SELECT ' . $dnodekey . ' FROM '
. $self->{tabname}
. " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
$self->trace_db(START_SQL_TYPE, $qstring);
$query = $self->{dbh}->prepare($qstring);
$query->execute();
$self->trace_db(END_SQL_TYPE);
xCAT::NodeRange::retain_cache(1);
unless ($options{prefetchcache}) {
@@ -3171,6 +3478,7 @@ sub getAllNodeAttribs
$self->{_use_cache} = 0;
$self->{nodelist}->{_use_cache} = 0;
$query->finish();
$self->trace_db(END_TYPE);
if ($hashretstyle) {
return $rethash;
} else {
@@ -3212,9 +3520,10 @@ sub getAllAttribs
if ($dbworkerpid > 0) {
return dbc_call($self, 'getAllAttribs', @_);
}
$self->trace_db(START_TYPE);
if (!defined($self->{dbh})) {
xCAT::MsgUtils->message("S", "xcatd: DBI is missing, Please check the db access process.");
$self->trace_db(END_TYPE, "LINE ".__LINE__.": DBI is missing");
return undef;
}
@@ -3244,8 +3553,10 @@ sub getAllAttribs
}
if (@results)
{
$self->trace_db(END_TYPE);
return @results; #return wantarray ? @results : $results[0];
}
$self->trace_db(END_TYPE);
return undef;
}
@@ -3254,10 +3565,12 @@ sub getAllAttribs
my $query;
my $qstring = "SELECT * FROM " . $self->{tabname}
. " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
$self->trace_db(START_SQL_TYPE, $qstring);
$query = $self->{dbh}->prepare($qstring);
#print $query;
$query->execute();
$self->trace_db(END_SQL_TYPE, $qstring);
while (my $data = $query->fetchrow_hashref())
{
my %newrow = ();
@@ -3274,6 +3587,7 @@ sub getAllAttribs
}
}
$query->finish();
$self->trace_db(END_TYPE);
return @results;
}
@@ -3317,6 +3631,7 @@ sub delEntries
if ($dbworkerpid > 0) {
return dbc_call($self, 'delEntries', @_);
}
$self->trace_db(START_TYPE);
my $keyref = shift;
my @all_keyparis;
my %keypairs;
@@ -3361,10 +3676,10 @@ sub delEntries
$qstring =~ s/\(\)//;
$qstring =~ s/ OR \z//;
$self->trace_db(START_SQL_TYPE, $qstring);
my $query = $self->{dbh}->prepare($qstring);
$query->execute(@qargs);
$self->trace_db(END_SQL_TYPE);
#prepare the notification data
#put the column names at the very front
push(@notif_data, $query->{NAME});
@@ -3399,8 +3714,10 @@ sub delEntries
}
$delstring =~ s/\(\)//;
$delstring =~ s/ OR \z//;
$self->trace_db(START_SQL_TYPE, $delstring);
my $stmt = $self->{dbh}->prepare($delstring);
$stmt->execute(@stargs);
$self->trace_db(END_SQL_TYPE);
$stmt->finish;
$self->_refresh_cache(); #cache is invalid, refresh
@@ -3411,7 +3728,7 @@ sub delEntries
}
@pieces = splice(@all_keyparis, 0, $record_num);
}
$self->trace_db(END_TYPE);
}
#--------------------------------------------------------------------------
@@ -3450,6 +3767,7 @@ sub getAttribs
if ($dbworkerpid > 0) {
return dbc_call($self, 'getAttribs', @_);
}
$self->trace_db(START_TYPE);
#my $key = shift;
#my $keyval = shift;
@@ -3510,8 +3828,11 @@ sub getAttribs
}
if (@results)
{
$self->trace_db(END_TYPE);
$self->trace_db(CACHE_HIT_TYPE);
return wantarray ? @results : $results[0];
}
$self->trace_db(END_TYPE);
return undef;
}
@@ -3544,11 +3865,14 @@ sub getAttribs
$statement .= "(" . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO'))";
#print "This is my statement: $statement \n";
$self->trace_db(START_SQL_TYPE, $statement);
my $query = $self->{dbh}->prepare($statement);
unless (defined $query) {
$self->trace_db(END_TYPE, "LINE ".__LINE__.": undef");
return undef;
}
$query->execute(@exeargs);
$self->trace_db(END_SQL_TYPE);
my $data;
while ($data = $query->fetchrow_hashref())
{
@@ -3569,8 +3893,10 @@ sub getAttribs
$query->finish();
if (@return)
{
$self->trace_db(END_TYPE);
return wantarray ? @return : $return[0];
}
$self->trace_db(END_TYPE);
return undef;
}
@@ -3610,10 +3936,13 @@ sub getTable
if ($dbworkerpid > 0) {
return dbc_call($self, 'getTable', @_);
}
$self->trace_db(START_TYPE);
my @return;
my $statement = 'SELECT * FROM ' . $self->{tabname};
$self->trace_db(START_SQL_TYPE, $statement);
my $query = $self->{dbh}->prepare($statement);
$query->execute();
$self->trace_db(END_SQL_TYPE);
my $data;
while ($data = $query->fetchrow_hashref())
{
@@ -3631,8 +3960,10 @@ sub getTable
$query->finish();
if (@return)
{
$self->trace_db(END_TYPE);
return @return;
}
$self->trace_db(END_TYPE);
return undef;
}
@@ -4089,6 +4420,7 @@ sub writeAllEntries
if ($dbworkerpid > 0) {
return dbc_call($self, 'writeAllEntries', @_);
}
$self->trace_db(START_TYPE);
my $filename = shift;
my $fh;
my $rc = 0;
@@ -4097,6 +4429,7 @@ sub writeAllEntries
unless (open($fh, " > $filename")) {
my $msg = "Unable to open $filename for write \n.";
`logger -p local4.err -t xcat $msg`;
$self->trace_db(END_TYPE, "LINE ".__LINE__.": ".$msg);
return 1;
}
my $query;
@@ -4112,9 +4445,11 @@ sub writeAllEntries
# delimit the disable column based on the DB
my $disable = &delimitcol("disable");
$self->trace_db(START_SQL_TYPE, 'SELECT * FROM ' . $self->{tabname});
$query = $self->{dbh}->prepare('SELECT * FROM ' . $self->{tabname});
$query->execute();
$self->trace_db(END_SQL_TYPE);
while (my $data = $query->fetchrow_hashref())
{
foreach (keys %$data)
@@ -4128,6 +4463,7 @@ sub writeAllEntries
}
$query->finish();
CORE::close($fh);
$self->trace_db(END_TYPE);
return $rc;
}
@@ -4170,6 +4506,7 @@ sub writeAllAttribsWhere
if ($dbworkerpid > 0) {
return dbc_call($self, 'writeAllAttribsWhere', @_);
}
$self->trace_db(START_TYPE);
my $clause = shift;
my $filename = shift;
my $whereclause;
@@ -4184,6 +4521,7 @@ sub writeAllAttribsWhere
unless (open($fh, " > $filename")) {
my $msg = "Unable to open $filename for write \n.";
`logger -p local4.err -t xcat $msg`;
$self->trace_db(END_TYPE, "LINE ".__LINE__.": ".$msg);
return 1;
}
my $header;
@@ -4201,8 +4539,10 @@ sub writeAllAttribsWhere
# delimit the disable column based on the DB
my $disable = &delimitcol("disable");
$query2 = 'SELECT * FROM ' . $self->{tabname} . ' WHERE (' . $whereclause . ") and ($disable is NULL or $disable in ('0','no','NO','No','nO'))";
$self->trace_db(START_SQL_TYPE, $query2);
$query = $self->{dbh}->prepare($query2);
$query->execute();
$self->trace_db(END_SQL_TYPE);
while (my $data = $query->fetchrow_hashref())
{
foreach (keys %$data) {
@@ -4216,6 +4556,7 @@ sub writeAllAttribsWhere
}
$query->finish();
CORE::close($fh);
$self->trace_db(END_TYPE);
return $rc;
}
@@ -4291,6 +4632,7 @@ sub getMAXMINEntries
if ($dbworkerpid > 0) {
return dbc_call($self, 'getMAXMINEntries', @_);
}
$self->trace_db(START_TYPE);
my $attr = shift;
my $rets;
my $query;
@@ -4304,9 +4646,11 @@ sub getMAXMINEntries
} else {
$qstring = "SELECT MAX($attr) FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
}
$self->trace_db(START_SQL_TYPE, $qstring);
$query = $self->{dbh}->prepare($qstring);
$query->execute();
$self->trace_db(END_SQL_TYPE);
while (my $data = $query->fetchrow_hashref())
{
foreach (keys %$data)
@@ -4328,9 +4672,11 @@ sub getMAXMINEntries
} else {
$qstring = "SELECT MIN($attr) FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
}
$self->trace_db(START_SQL_TYPE, $qstring);
$query = $self->{dbh}->prepare($qstring);
$query->execute();
$self->trace_db(END_SQL_TYPE);
while (my $data = $query->fetchrow_hashref())
{
foreach (keys %$data)
@@ -4344,6 +4690,7 @@ sub getMAXMINEntries
last; # better be only one value for min
}
}
$self->trace_db(END_TYPE);
return $rets;
}
1;
+11 -6
View File
@@ -85,7 +85,9 @@ my %usage = (
OpenPOWER (OpenBMC) specific:
rvitals noderange [temp|voltage|wattage|fanspeed|power|altitude|all]
MIC specific:
rvitals noderange {thermal|all}",
rvitals noderange {thermal|all}
pdu specific:
rvitals noderange ",
"reventlog" =>
"Usage: reventlog <noderange> [all [-s]|clear|<number of entries to retrieve> [-s]] [-V|--verbose]
reventlog [-h|--help|-v|--version]",
@@ -143,7 +145,7 @@ my %usage = (
rspconfig <noderange> [garp=<number of 1/2 second>]
rspconfig <noderange> [userid=<userid> username=<username> password=<password>]
OpenBMC specific:
rspconfig <noderange> [ip|netmask|gateway|vlan]
rspconfig <noderange> [ip|netmask|gateway|hostname|vlan]
iDataplex specific:
rspconfig <noderange> [thermprofile]
rspconfig <noderange> [thermprofile=<two digit number from chassis>]
@@ -342,10 +344,13 @@ my %usage = (
rflash <noderange> -p <rpm_directory> [--activate {disruptive|deferred}] [-d <data_directory>]
rflash <noderange> [--commit | --recover] [-V|--verbose]
rflash <noderange> [--bpa_acdl]
PPC64LE (using IPMI Management) specific:
rflash <noderange> [-c|--check] [--retry=<count>] [-V] [<hpm_file>|-d=<data_directory>]
PPC64LE (using OpenBMC Management) specific:
rflash <noderange> [-c|--check] [-l|--list] [-a|--activate] [-u|--upload] [-d|--delete] [<tar_file>|<image_id>]",
OpenPOWER BMC specific (using IPMI):
rflash <noderange> [<hpm_file_path>|-d <data_directory>] [-c|--check] [--retry=<count>] [-V]
rflash <noderange> --recover <bmc_file_path>
OpenPOWER OpenBMC specific:
rflash <noderange> {[-c|--check] | [-l|--list]}
rflash <noderange> <tar_file_path> {[-c|--check] | [-a|--activate] | [-u|--upload]}
rflash <noderange> <image_id> {[-a|--activate] | [-d|--delete]}",
"mkhwconn" =>
"Usage:
mkhwconn [-h|--help]
+9 -1
View File
@@ -19,6 +19,7 @@ use lib "$::XCATROOT/lib/perl";
# needing it to avoid reprocessing of user tables ( ExtTab.pm) for each command call
use POSIX qw(ceil);
use File::Path;
#use Data::Dumper;
use Socket;
use strict;
use Symbol;
@@ -42,7 +43,6 @@ require xCAT::InstUtils;
#require xCAT::NetworkUtils;
require xCAT::Schema;
#require Data::Dumper;
require xCAT::NodeRange;
require xCAT::Version;
require DBI;
@@ -575,6 +575,13 @@ sub isLinux
sub Version
{
my $version = shift;
#force reload the xCAT::Version in case the perl-xcat is upgraded but xcatd is not restarted
if($INC{'xCAT/Version.pm'}){
delete $INC{'xCAT/Version.pm'};
}
require xCAT::Version;
$version = xCAT::Version->Version();
return $version;
}
@@ -4903,4 +4910,5 @@ sub acquire_lock_imageop {
return (0,$lock);
}
1;
-7
View File
@@ -21,7 +21,6 @@ use Getopt::Long;
use xCAT::MsgUtils;
use xCAT::Utils;
use xCAT::Client;
use xCAT::NodeRange;
use Cwd;
use strict;
@@ -72,12 +71,6 @@ if(grep m/^-c|--console$/,@ARGV){
}
my $noderange = $cmdref->{noderange}->[0]; # save the noderange
my @noderange=xCAT::NodeRange::noderange($noderange);
if($bname eq "rinstall" and $startconsole==1 and scalar @noderange!=1 ){
xCAT::MsgUtils->message("E", "Error: rinstall -c/--console can only be run against one node! Please use winstall -c/--console for multiple nodes.");
exit 1;
}
# Allow to print server information when -V/--verbose
foreach (reverse(@ARGV)) {
+24 -5
View File
@@ -8,7 +8,7 @@ B<bmcdiscover> [B<-?>|B<-h>|B<--help>]
B<bmcdiscover> [B<-v>|B<--version>]
B<bmcdiscover> [B<-s> I<scan_method>] [B<-u> I<bmc_user>] [B<-p> I<bmc_passwd>] [B<-z>] [B<-w>] B<--range> I<ip_ranges>
B<bmcdiscover> [B<--sn> I<SN_nodename>] [B<-s> I<scan_method>] [B<-u> I<bmc_user>] [B<-p> I<bmc_passwd>] [B<-z>] [B<-w>] B<--range> I<ip_ranges>
B<bmcdiscover> B<-u> I<bmc_user> B<-p> I<bmc_passwd> B<-i> I<bmc_ip> B<--check>
@@ -33,6 +33,10 @@ Note: The scan method currently support is B<nmap>.
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.
=item B<--sn>
Specify one or more service nodes on which bmcdiscover will run. In hierarchical cluster, the MN may not be able to access the BMC of CN directly, but SN can. With this option, bmcdiscover will be dispatched to the specified SNs. Then, the nodename of the service node that 'bmcdiscover' is running on will be set to the 'servicenode' attribute of the discovered BMC node.
=item B<-s>
Scan method (The only supported scan method at this time is B<nmap>)
@@ -90,19 +94,34 @@ Display version information
Note: Input for IP range can be in the form: scanme.nmap.org, microsoft.com/24, 192.168.0.1; 10.0.0-255.1-254.
2. To get all BMSs in IP range "10.4.22-23.100-254", displayed in xCAT stanza format:
2. To get all BMCs in IP range "10.4.22-23.100-254", displayed in xCAT stanza format:
bmcdiscover -s nmap --range "10.4.22-23.100-254" -z
3. Discover the BMCs and write the discovered-node definitions into the xCAT database and write out the stanza foramt to the console:
3. To discover BMCs through sn01:
bmcdiscover --sn sn01 -s nmap --range "10.4.22-23.100-254" -z
Output is similar to:
node-70e28414291b:
objtype=node
groups=all
bmc=10.4.22.101
cons=openbmc
mgt=openbmc
servicenode=sn01
conserver=sn01
4. Discover the BMCs and write the discovered-node definitions into the xCAT database and write out the stanza foramt to the console:
bmcdiscover -s nmap --range "10.4.22-23.100-254" -w -z
4. To check if the username or password is correct against the BMC:
5. To check if the username or password is correct against the BMC:
bmcdiscover -i 10.4.23.254 -u USERID -p PASSW0RD --check
5. Get BMC IP Address source, DHCP Address or static Address
6. Get BMC IP Address source, DHCP Address or static Address
bmcdiscover -i 10.4.23.254 -u USERID -p PASSW0RD --ipsource
+24 -5
View File
@@ -24,11 +24,17 @@ B<rflash> I<noderange> I<http_directory>
=head2 OpenPOWER BMC specific (using IPMI):
B<rflash> I<noderange> [I<hpm_file_path> | B<-d=>I<data_directory>] [B<-c>|B<--check>] [B<--retry=>I<count>] [B<-V>]
B<rflash> I<noderange> [I<hpm_file_path> | B<-d> I<data_directory>] [B<-c>|B<--check>] [B<--retry=>I<count>] [B<-V>]
B<rflash> I<noderange> B<--recover> I<bmc_file_path>
=head2 OpenPOWER OpenBMC specific :
B<rflash> I<noderange> [I<tar_file_path> | I<image_id>] [B<-c>|B<--check>] [B<-a>|B<--activate>] [B<-l>|B<--list>] [B<-u>|B<--upload>] [B<-d>|B<--delete>]
B<rflash> I<noderange> {[B<-c>|B<--check>] | [B<-l>|B<--list>]}
B<rflash> I<noderange> I<tar_file_path> {[B<-c>|B<--check>] | [B<-a>|B<--activate>] | [B<-u>|B<--upload>]}
B<rflash> I<noderange> I<image_id> {[B<-a>|B<--activate>] | [B<-d>|B<--delete>]}
=head1 B<Description>
@@ -111,9 +117,11 @@ Specifies the directory where the packages are located.
=item B<-d> I<data_directory>
PPC (without HMC, using Direct FSP Management) specific:
Specifies the directory where the raw data from rpm packages for each CEC/Frame are located. The default directory is /tmp. The option is only used in Direct FSP/BPA Management.
=item B<-d=>I<data_directory>
OpenPOWER BMC specific (using IPMI):
Used for IBM Power S822LC for Big Data systems only. Specifies the directory where the B<pUpdate> utility and at least one of BMC or PNOR update files are located. The utility and update files can be downloaded from FixCentral.
@@ -127,15 +135,21 @@ Used to commit the flash image in the temporary side of the chip to the permanen
=item B<--recover>
PPC (with HMC) and PPC (without HMC, using Direct FSP Management) specific:
Used to recover the flash image in the permanent side of the chip to the temporary side for both managed systems and power subsystems.
OpenPOWER BMC specific (using IPMI):
Used for IBM Power S822LC for Big Data systems only. Used to recover the BMC with a BMC image downloaded from FixCentral.
=item B<--retry=>I<count>
Specify number of times to retry the update if failure is detected. Default value is 2. Value of 0 can be used to indicate no retries.
=item B<-a|--activate>
Activate update image. Image id must be specified.
Activate update image. Image id or update file must be specified.
=item B<-l|--list>
@@ -201,7 +215,12 @@ Print verbose message to rflash log file (/var/log/xcat/rflash/fs3.log) when upd
=item 6.
To update the firmware on IBM Power S822LC for Big Data machine specify the node name and the file path of the data directory containing pUpdate utility and BMC and/or PNOR update files:
rflash briggs01 -d=/root/supermicro/OP825
rflash briggs01 -d /root/supermicro/OP825
=item 7.
To update the firmware on the OpenBMC machine, specify the firmare update file to upload and activate:
rflash p9euh02 -a /tmp/witherspoon.pnor.squashfs.tar
=back
+6 -2
View File
@@ -5,14 +5,14 @@ B<rsetboot> - Sets the boot device to be used for BMC-based servers for the next
=head1 SYNOPSIS
B<rsetboot> I<noderange> {B<hd>|B<net>|B<cd>|B<default>|B<stat>} [B<-u>] [B<-p>]
B<rsetboot> I<noderange> [B<hd>|B<net>|B<cd>|B<default>|B<stat>] [B<-u>] [B<-p>]
B<rsetboot> [B<-h>|B<--help>|B<-v>|B<--version>]
=head1 DESCRIPTION
B<rsetboot> sets the boot media and boot mode that should be used on the next boot of the specified nodes. After the nodes are booted with the specified device and boot mode (e.g. via L<rpower(1)|rpower.1>), the nodes will return to using the default boot device specified in the BIOS. Currently this command is only supported for IPMI nodes.
B<rsetboot> sets the boot media and boot mode that should be used on the next boot of the specified nodes. After the nodes are booted with the specified device and boot mode (e.g. via L<rpower(1)|rpower.1>), the nodes will return to using the default boot device specified in the BIOS.
=head1 OPTIONS
@@ -64,6 +64,10 @@ Display the next-boot value for nodes 14-56 and 70-203:
rsetboot node[14-56],node[70-203] stat
Or:
rsetboot node[14-56],node[70-203]
=item 3.
Restore the next-boot value for these nodes back to their default set in the BIOS:
+5 -1
View File
@@ -24,7 +24,7 @@ B<rspconfig> I<noderange> B<garp>=I<time>
=head2 OpenBMC specific:
B<rspconfig> I<noderange> {B<ip>|B<netmask>|B<gateway>|B<vlan>|B<sshcfg>}
B<rspconfig> I<noderange> {B<ip>|B<netmask>|B<gateway>|B<hostname>|B<vlan>|B<sshcfg>}
=head2 MPA specific:
@@ -300,6 +300,10 @@ Set CEC/BPA system names to the names in xCAT DB or the input name.
Select the policy for I/O Adapter Enlarged Capacity. This option controls the size of PCI memory space allocated to each PCI slot.
=item B<hostname>
Get or set hostname on the service processor.
=item B<vlan>
Get or set vlan ID. For get vlan ID, if vlan is not enabled, 'BMC VLAN disabled' will be outputed. For set vlan ID, the valid value are [1-4096].
+10 -1
View File
@@ -36,7 +36,11 @@ B<noderange> is a syntax that can be used in most xCAT commands to
conveniently specify a list of nodes. The result is that the command will
be applied to a range of nodes, often in parallel.
To avoid shell expansion, B<noderange> should better be quoted with single quotes('') or double quotes("").
If you invoke xCAT B<noderange> from a shell you may need to quote the
B<noderange> if the shell would otherwise treat the punctuation marks in
the B<noderange> as control operators. The affected punctuation marks may
include Asterisk (`*'), Left Square Bracket (`[') , Right Square Bracket
(`]'), Circumflex Accent (`^'), and Overline (`~').
B<noderange> is a comma-separated list. Each token (text between commas)
in the list can be any of the forms listed below:
@@ -233,6 +237,11 @@ Generate a list of nodes in the 1st two frames:
=back
=head1 B<Bugs>
The special characters used by xCAT B<noderange> are also special characters
to many shell programs. In particular, the characters `*', `[', `]', `^',
and `~' may have to be escaped from the shell.
=head1 B<SEE ALSO>
+16 -7
View File
@@ -13,13 +13,16 @@ DIR=`dirname $0`
DIR=`readlink -f $DIR`
BUILDARCH=`uname -m`
#For Openpower
if [ $BUILDARCH = "ppc64le" ]; then
BUILDARCH="ppc64"
fi
rpmdev-setuptree
#For Openpower
if [ -z $1 ]; then
HOSTOS="fedora26"
if [ $BUILDARCH = "ppc64le" ]; then
HOSTOS="Pegas1.0"
BUILDARCH="ppc64"
else
HOSTOS="fedora26"
fi
fi
# get the input files for dracut in the right place
@@ -42,7 +45,7 @@ if [ $BUILDARCH = "x86_64" ]; then
sed -i 's/\/lib64\/libpanel.so.5//' $DRACUTMODDIR/install
sed -i 's/\/lib64\/libmenu.so.5//' $DRACUTMODDIR/install
sed -i 's/\/lib64\/libsysfs.so.2//' $DRACUTMODDIR/install
sed -i 's/\/usr\/sbin\/iprconfig//' $DRACUTMODDIR/install
sed -i '/\/usr\/sbin\/iprconfig/ d' $DRACUTMODDIR/install
sed -i '/hwdb.bin/ d' $DRACUTMODDIR/install
sed -i 's/instmods ipr//' $DRACUTMODDIR/installkernel
fi
@@ -54,7 +57,7 @@ if [ "$HOSTOS" = "mcp" ]; then
sed -i 's/dmidecode//' $DRACUTMODDIR/install
sed -i 's/\/lib\/ld-linux.so.2/\/usr\/lib64\/ld-2.17.so/' $DRACUTMODDIR/install
sed -i 's/\/lib64\/libsysfs.so.2//' $DRACUTMODDIR/install
sed -i 's/\/usr\/sbin\/iprconfig//' $DRACUTMODDIR/install
sed -i '/\/usr\/sbin\/iprconfig/ d' $DRACUTMODDIR/install
else
sed -i 's/\/lib\/ld-linux.so.2/\/usr\/lib64\/ld-linux-x86-64.so.2/' $DRACUTMODDIR/install
fi
@@ -105,6 +108,12 @@ if [ "$HOSTOS" = "mcp" ]; then
# For ppc64 platform, needs to remove some files,
# # and some files are in different directories
elif [ $BUILDARCH = "ppc64" ]; then
if [ "$HOSTOS" = "Pegas1.0" ]; then
sed -i 's/ mkreiserfs//' $DRACUTMODDIR/install
sed -i 's/ reiserfstune//' $DRACUTMODDIR/install
sed -i 's/ vconfig//' $DRACUTMODDIR/install
sed -i 's/ ntp-wait//' $DRACUTMODDIR/install
fi
sed -i 's/ efibootmgr//' $DRACUTMODDIR/install
sed -i 's/ dmidecode//' $DRACUTMODDIR/install
sed -i 's/\/lib\/terminfo\/l\/linux/\/usr\/share\/terminfo\/l\/linux/g' $DRACUTMODDIR/install
@@ -4,7 +4,7 @@ Version: %{?version:%{version}}%{!?version:%(cat Version)}
Release: %{?release:%{release}}%{!?release:%(cat Release)}
Epoch: 1
AutoReq: false
Requires: ipmitool screen btrfs-progs lldpad rpm-build compat-libstdc++-33 mstflint xfsprogs nc reiserfs-utils
Requires: ipmitool screen btrfs-progs lldpad rpm-build mstflint xfsprogs nc rpmdevtools libstdc++-devel pciutils bridge-utils ntp ntp-perl iprutils psmisc mdadm bind-utils dosfstools usbutils libusbx
Prefix: /opt/xcat
AutoProv: false
+23 -28
View File
@@ -293,9 +293,6 @@ logger -s -t $log_label -p local4.info "Detected LAN channel $LANCHAN"
let idev=NUMBMCS
if [ $IPCFGMETHOD="static" ]; then
if [ ! -z "$ISOPENBMC" ]; then
let idev=0
fi
while [ $idev -gt 0 ]; do
let idev=idev-1
TRIES=0
@@ -370,45 +367,43 @@ else
done
fi
let idev=0
for b in $BMCVLAN; do
if [ "$BMCVLAN" = off ]; then
TRIES=0
# Set VLAN for the current channel
while ! ipmitool -d $idev lan set $LANCHAN vlan id $b; do
while ! ipmitool raw 0xc 1 $LANCHAN 0x14 0 0; do
snooze
let TRIES=TRIES+1
if [ $TRIES -gt $TIMEOUT ]; then
if [ $TRIES -gt $TIMEOUT ]; then
break;
fi
done
let idev=idev+1
done
else
let idev=0
for b in $BMCVLAN; do
TRIES=0
# Set VLAN for the current channel
while ! ipmitool -d $idev lan set $LANCHAN vlan id $b; do
snooze
let TRIES=TRIES+1
if [ $TRIES -gt $TIMEOUT ]; then
break;
fi
done
let idev=idev+1
done
fi
# update the node status to 'bmcready' for openbmc, no more configuration is needed.
if [ ! -z "$ISOPENBMC" ]; then
# To enable network configuration for openbmc
TRIES=0
bmc_config_rc=0
# Set Channel Access to apply network setting
#while ! ipmitool -d 0 lan set $LANCHAN access on; do
while ! ipmitool -d 0 raw 0x06 0x40 $LANCHAN 0x42 0x44 > /dev/null; do
snooze
let TRIES=TRIES+1
if [ $TRIES -gt $TIMEOUT ]; then
bmc_config_rc=1
break;
fi
done
ipmitool -d 0 lan set $LANCHAN access on
# update the node status to 'bmcready'
if [ ! -z "$XCATMASTER" ]; then
if [ "$bmc_config_rc" = "0" ]; then
# Wait for some time for the new network setting is ready
snooze
# Wait for some time for the new network setting is ready
snooze
if ipmitool lan print 1 | grep $BMCIP >/dev/null; then
updateflag.awk $XCATMASTER 3002 "installstatus bmcready"
else
else
updateflag.awk $XCATMASTER 3002 "installstatus failed"
fi
fi
+7 -15
View File
@@ -99,13 +99,17 @@ if [ -r /sys/devices/virtual/dmi/id/product_name ]; then #x86
if [ -z "$MTM" ]; then
FRU=`ipmitool fru print 0`
if [ $? -eq 0 ]; then
MTM=`echo "$FRU" | awk -F': ' '/Product Manufacturer/ {m=$2} /Product Name/ {n=$2} END {print m":"n}'`
m=`echo "$FRU" | awk -F': ' '/Product Manufacturer/ {print $2}'`
n=`echo "$FRU" | awk -F': ' '/Product Name/ {print $2}'`
if [ -z "$n" -o "$n" == "NONE" ]; then
n=`echo "$FRU" | awk -F': ' '/Product Part Number/ {print $2}'`
fi
else
logger -s -t $log_label -p local4.warning "Couldn't find MTM information in FRU, falling back to DMI (MTMS-based discovery may fail)"
m=`cat /sys/devices/virtual/dmi/id/sys_vendor`
n=`cat /sys/devices/virtual/dmi/id/product_name`
MTM="$m:$n"
fi
MTM="$m:$n"
fi
SERIAL=`cat /sys/devices/virtual/dmi/id/product_serial`
fi
@@ -117,7 +121,6 @@ if [ -r /sys/devices/virtual/dmi/id/product_name ]; then #x86
UUID=`sed -e 's/\(..\)\(..\)\(..\)\(..\)-\(..\)\(..\)-\(..\)\(..\)/\4\3\2\1-\6\5-\8\7/' /sys/devices/virtual/dmi/id/product_uuid`
elif [ -r /proc/device-tree/model ]; then #POWER
#MTM=`cat /proc/device-tree/model |awk -F, '{print $2}'`
MTM=`cat /proc/device-tree/model -vT | sed -e 's/^.*,//' | sed -e 's/^[\t ]*//'| sed -e 's/[\t ]*\^@//'`
CPUCOUNT=`cat /proc/cpuinfo |grep -e "^cpu\s*:"|wc -l`
PLATFORM=`cat /proc/cpuinfo | grep -e "^platform\s*:" | awk '{print \$3}'`
@@ -131,25 +134,14 @@ elif [ -r /proc/device-tree/model ]; then #POWER
UUID=unknown
fi
#CPUCOUNT=`cat /proc/cpuinfo |grep "model name"|wc -l`
# The MEMORY will look like this: 32868920
MEMORY=`cat /proc/meminfo |grep MemTotal|awk '{printf "%.0fMB\n", $2/1024}'`
# The MEMORY will look like this: 32GiB
#MEMORY=`lshw -C memory -short |grep "System Memory"|awk -F' ' '{print $3}'`
# The DISKSIZE will look like this: /dev/sda:250GB,/dev/sdb:250GB
#DISKSIZE=`lshw -C disk -short |grep disk |awk -F' ' '{print $2":"$4}'|sed 'N;s/\n/,/'`
# The DISKSIZE will look like this: sdb:250GB,sda:250GB
DISKSIZE=`cat /proc/partitions |grep -e "sd.\>" |awk -F' ' '{printf "%s:%.0fGB\n", $4, $3*0.000001024}' |sed 'N;s/\n/,/'`
#UUID=`sed -e 's/\(..\)\(..\)\(..\)\(..\)-\(..\)\(..\)-\(..\)\(..\)/\4\3\2\1-\6\5-\8\7/' /sys/devices/virtual/dmi/id/product_uuid`
#grep "model name" /proc/cpuinfo | while read line; do #to avoid pulling in tail, we do a goofy thing
# echo $line > /tmp/cpumod
#done
#CPUTYPE=`cat /tmp/cpumod|awk -F':' '{print $2}'|sed -e 's/^ //'`
logger -s -t $log_label -p local4.info "Beginning echo infomation to discovery packet file..."
logger -s -t $log_label -p local4.info "Beginning echo information to discovery packet file..."
echo '<xcatrequest>' > /tmp/discopacket
echo "<command>findme</command>" >> /tmp/discopacket
echo "<sequential>1</sequential>" >> /tmp/discopacket
+4 -2
View File
@@ -8,8 +8,6 @@ log_label="xcat.genesis.doxcat"
# Start rsyslogd and log into a local file specified in /etc/rsyslog.conf
# Later, once xCAT MN is known, dhclient-script will change
# rsyslog.conf file to send log entries to xCAT MN
logger -s -t $log_label -p local4.info "Starting syslog..."
ls /var/run/
RSYSLOGD_VERSION=`rsyslogd -v | grep "rsyslogd" | cut -d" " -f2 | cut -d"." -f1`
# if syslog is running and there's a pid file, kill it before restarting syslogd
@@ -357,6 +355,10 @@ while :; do
logger -s -t $log_label -p local4.info "Running nextdestiny $XCATMASTER:$XCATPORT..."
/bin/nextdestiny $XCATMASTER:$XCATPORT
logger -s -t $log_label -p local4.info "nextdestiny - Complete."
elif [ "$dest" = osimage ]; then
logger -s -t $log_label -p local4.info "Running nextdestiny $XCATMASTER:$XCATPORT..."
destiny=`/bin/nextdestiny $XCATMASTER:$XCATPORT`
logger -s -t $log_label -p local4.info "nextdestiny - Complete."
elif [ "$dest" = runcmd ]; then
logger -s -t $log_label -p local4.info "Running nextdestiny $XCATMASTER:$XCATPORT..."
destiny=`/bin/nextdestiny $XCATMASTER:$XCATPORT`
+1 -1
View File
@@ -182,7 +182,7 @@ sub is_static_ip {
if ($os =~ /redhat/) {
my $output1 = `cat /etc/sysconfig/network-scripts/ifcfg-$nic 2>&1 |grep -i IPADDR`;
my $output2 = `cat /etc/sysconfig/network-scripts/ifcfg-$nic 2>&1 |grep -i BOOTPROTO`;
$rst = 1 if (($output1 =~ /$ip/) && ($output2 =~ /static/i));
$rst = 1 if (($output1 =~ /$ip/) && ($output2 =~ /static|none/i));
} elsif ($os =~ /sles/) {
my $output1 = `cat /etc/sysconfig/network/ifcfg-$nic 2>&1 |grep -i IPADDR`;
my $output2 = `cat /etc/sysconfig/network/ifcfg-$nic 2>&1 |grep -i BOOTPROTO`;
+354
View File
@@ -0,0 +1,354 @@
# -*- encoding: utf-8 -*-
# !/usr/bin/python
from __future__ import print_function
import argparse
import json
import os
import sys
import time
BUF_SIZE = 8192
class Reader(object):
def __init__(self, file):
self.f_size = os.stat(file).st_size
self.f_pos = self.f_size
self.file = file
self.buf_list = []
self.remain = None
self.f = None
def open(self):
if self.f is None:
self.f = open(self.file)
def close(self):
if self.f is not None:
self.f.close()
self.f = None
def __enter__(self):
self.open()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
def _read(self):
if self.f_pos == 0:
return None
size = BUF_SIZE
if self.f_pos - BUF_SIZE >= 0:
self.f.seek(self.f_pos - BUF_SIZE)
else:
self.f.seek(0)
size = self.f_pos - 0
buf = self.f.read(size)
if self.remain is not None:
self.buf_list = (buf + self.remain).split('\n')
else:
self.buf_list = buf.split('\n')
if size == BUF_SIZE:
self.remain = self.buf_list[0]
self.buf_list = self.buf_list[1:]
else:
self.remain = None
self.f_pos -= size
return self.buf_list
def get_next(self):
ret = self._get_next()
if ret is not None:
return ret
while self._read() is not None:
ret = self._get_next()
if ret is not None:
return ret
return None
class CommandReader(Reader):
def __init__(self, file):
super(CommandReader, self).__init__(file)
self.cmd = {}
def _get_next(self):
""" Extract data from the commands log file of xcat
Format::
[Date] 2017-09-04 17:52:10
[ClientType] cli
[Request] xdsh c910f04x35v07 'echo "nameserver 9.0.2.1" >> /etc/resolv.conf'
[Response]
[ElapsedTime] 0 s
:return: command dict if found, None if not found
"""
for i, b in enumerate(self.buf_list[::-1]):
if b.find('[ElapsedTime]') == 0:
self.cmd['elapsed'] = float(b.split(' ')[1])
elif b.find('[Request]') == 0:
self.cmd['request'] = " ".join(
b.rstrip().split(' ')[1:]).strip().replace(',', ' ')
elif b.find('[Date]') == 0:
temp = b.split(' ')
self.cmd['date'] = '%s %s' % (temp[-2], temp[-1])
if all(k in self.cmd for k in ('date', 'request', 'elapsed')):
cmd = self.cmd
self.cmd = {}
self.buf_list = self.buf_list[0:len(self.buf_list) - i - 1]
return cmd
return None
class DBTraceReader(Reader):
def __init__(self, file):
super(DBTraceReader, self).__init__(file)
self.year = str(time.localtime().tm_year)
def _get_next(self):
"""Extract information from syslog file of xcat
Format::
Sep 4 22:16:38 c910f04x12v02 xcat[6692]: [DB Trace]: {"msg":{"table":"nodegroup","method":"xCAT::Table::getAllEntries"},"type":"end_sql","elapsed":"0.00042s"}
:return: A dict contains the time stamp and db dict if db trace log is
found. None if nothing about db trace log found.
"""
for i, b in enumerate(self.buf_list[::-1]):
pos = b.find('[DB Trace]:')
if pos == -1:
continue
date = b[0:15]
conv = time.strptime('%s %s' % (self.year, date),
"%Y %b %d %H:%M:%S")
# TODO: the year value is not included in the current syslog
try:
ret = {'stamp': int(time.mktime(conv)),
'db': json.loads(b[pos + 12:])}
except ValueError:
if b.find('message repeated') != -1:
# syslog will add [ ] around the json message.
ret = {'stamp': int(time.mktime(conv)),
'db': json.loads(b[pos + 12:-1])}
else:
raise
self.buf_list = self.buf_list[0:len(self.buf_list) - i - 1]
return ret
return None
class TimeStamp(object):
def __init__(self, kwargs):
if 'date' in kwargs:
a = time.strptime(kwargs['date'], "%Y-%m-%d %H:%M:%S")
self.start = int(time.mktime(a))
else:
raise
if 'elapsed' in kwargs:
self.end = self.start + int(kwargs['elapsed']) + 1
else:
raise
class Analysis(object):
def __init__(self, command_log_file, cluster_log_file):
self.command_log_file = command_log_file
self.cluster_log_file = cluster_log_file
def _stat(self, record, data):
elapsed = 0
if 'elapsed' in data:
# elapsed = float('%.3f' % float(data['elapsed'][:-1]))
elapsed = float(data['elapsed'][:-1])
if data['type'] == 'end_sql':
if data['msg']['method'].startswith('xCAT::Table::get'):
record['get_sql_time'] += elapsed
elif data['msg']['method'].startswith('xCAT::Table::set'):
record['set_sql_time'] += elapsed
elif data['msg']['method'].startswith('xCAT::Table::del'):
record['del_sql_time'] += elapsed
elif data['type'] == 'end':
if data['msg']['method'].startswith('xCAT::Table::get'):
record['get_sub_time'] += elapsed
elif data['msg']['method'].startswith('xCAT::Table::set'):
record['set_sub_time'] += elapsed
elif data['msg']['method'].startswith('xCAT::Table::del'):
record['del_sub_time'] += elapsed
elif data['type'] == 'start_sql':
if data['msg']['method'].startswith('xCAT::Table::get'):
if data['msg']['table'] not in record['get_tables']:
record['get_tables'][data['msg']['table']] = 1
else:
record['get_tables'][data['msg']['table']] += 1
elif data['msg']['method'].startswith('xCAT::Table::set'):
if data['msg']['table'] not in record['set_tables']:
record['set_tables'][data['msg']['table']] = 1
else:
record['set_tables'][data['msg']['table']] += 1
elif data['msg']['method'].startswith('xCAT::Table::del'):
if data['msg']['table'] not in record['del_tables']:
record['del_tables'][data['msg']['table']] = 1
else:
record['del_tables'][data['msg']['table']] += 1
elif data['type'] == 'build_cache':
if data['msg']['table'] not in record['build_cache']:
record['build_cache'][data['msg']['table']] = 1
else:
record['build_cache'][data['msg']['table']] += 1
elif data['type'] == 'cache_hit':
if data['msg']['table'] not in record['cache_hit']:
record['cache_hit'][data['msg']['table']] = 1
else:
record['cache_hit'][data['msg']['table']] += 1
def process(self, latest, specific_cmd):
if specific_cmd is not None:
latest = None
self._print_header()
with CommandReader(self.command_log_file) as cmd_reader:
cmd = cmd_reader.get_next()
trace = None
index = 0
db_reader = DBTraceReader(self.cluster_log_file)
db_reader.open()
while cmd is not None:
if specific_cmd is not None and not cmd['request'].startswith(
specific_cmd):
cmd = cmd_reader.get_next()
continue
stamp = TimeStamp(cmd)
if trace is None:
trace = db_reader.get_next()
while trace and trace['stamp'] > stamp.end:
trace = db_reader.get_next()
key = '%s(%s)' % (cmd['request'], cmd['date'])
record = {'command': key,
'elapsed': cmd['elapsed'],
'get_sql_time': float(0),
'set_sql_time': float(0),
'del_sql_time': float(0),
'set_sub_time': float(0),
'get_sub_time': float(0),
'del_sub_time': float(0),
'get_tables': {},
'set_tables': {},
'del_tables': {},
'build_cache': {},
'cache_hit': {}}
while trace and trace['stamp'] >= stamp.start:
self._stat(record, trace['db'])
trace = db_reader.get_next()
self._print_csv(record)
index += 1
if latest is not None and index == latest:
break
cmd = cmd_reader.get_next()
db_reader.close()
def _print_header(self):
print("command,elapsed(precision: 1s),"
"get_sub_time(s),set_sub_time(s),del_sub_time(s),"
"get_sql_time(s),set_sql_time(s),del_sql_time(s),"
"build_cache(times),cache_hit(times),"
"get_tables(times),set_tables(times),del_tables(times)")
def _print_csv(self, record):
print("%(command)s,%(elapsed)f,"
"%(get_sub_time)f,%(set_sub_time)f,%(del_sub_time)f,"
"%(get_sql_time)f,%(set_sql_time)f,%(del_sql_time)f,"
"%(build_cache)s,%(cache_hit)s,"
"%(get_tables)s,%(set_tables)s,%(del_tables)s\n" %
{'command': record['command'],
'elapsed': record['elapsed'],
'get_sub_time': float('%.3f' % record['get_sub_time']),
'set_sub_time': float('%.3f' % record['set_sub_time']),
'del_sub_time': float('%.3f' % record['del_sub_time']),
'get_sql_time': float('%.3f' % record['get_sql_time']),
'set_sql_time': float('%.3f' % record['set_sql_time']),
'del_sql_time': float('%.3f' % record['del_sql_time']),
'build_cache': self._format_dict(record['build_cache']),
'cache_hit': self._format_dict(record['cache_hit']),
'get_tables': self._format_dict(record['get_tables']),
'set_tables': self._format_dict(record['set_tables']),
'del_tables': self._format_dict(record['del_tables'])})
def _format_list(self, a):
return " ".join(a)
def _format_dict(self, d):
ret = []
for k, v in d.items():
if type(v) is list:
ret.append('%s:[%s]', k, " ".join(v))
elif type(v) is str or type(v) is int:
ret.append('%s:%s' % (k, str(v)))
return " ".join(ret)
class StatsShell(object):
def get_base_parser(self):
parser = argparse.ArgumentParser(
prog='dbstats',
add_help=False,
formatter_class=HelpFormatter,
)
parser.add_argument('-h', '--help',
action='store_true',
help=argparse.SUPPRESS,
)
parser.add_argument('--clusterlog',
help="The syslog file of xcat.",
default='/var/log/xcat/cluster.log',
type=str)
parser.add_argument('--commandlog',
help="The command log file of xcat.",
default='/var/log/xcat/commands.log',
type=str)
parser.add_argument('-n', '--num',
help="The recent count of commands to analyze",
type=int,
default=10)
parser.add_argument('-c', '--command',
help="The specified command to track",
type=str,
default=None)
return parser
def do_help(self, args):
self.parser.print_help()
def main(self, argv):
self.parser = self.get_base_parser()
(options, args) = self.parser.parse_known_args(argv)
if options.help:
self.do_help(options)
return 0
a = Analysis(options.commandlog, options.clusterlog)
a.process(options.num, options.command)
class HelpFormatter(argparse.HelpFormatter):
def start_section(self, heading):
# Title-case the headings
heading = '%s%s' % (heading[0].upper(), heading[1:])
super(HelpFormatter, self).start_section(heading)
if __name__ == "__main__":
StatsShell().main(sys.argv[1:])
+211 -13
View File
@@ -14,25 +14,70 @@ use warnings;
my $program_name = basename("$0");
my $help;
my $noderange = "compute";
my $noderange = undef;
my $test;
my $output = "stdout";
my $verbose = 0;
my $rst = 0;
my $interval = 5;
my $terminal = 0;
my $timeout = 0;
my $start_time;
#-----------------------------
# To store the node number of a specified type
# May like this:
# $type_nodesnum{pdu} = 2;
# {switch} = 3;
# {node} = 10;
#-----------------------------
my %type_nodesnum = ();
#-----------------------------
# To store the type, state hash
# May like this:
# $state_node_hash{pdu}{state1}{pdu1} = 1;
# $state_node_hash{pdu}{state1}{pdu2} = 1;
# $state_node_hash{pdu}{state2}{pdu3} = 1;
# $state_node_hash{pdu}{state3}{pdu4} = 1;
# The state include but not limited to below:
# matching --> matched --> configured (For PDU/Switch)
# matching --> matched --> installing --> booting --> booted
# matching --> matched --> booting --> installing --> xxx --> booted
# The terminal state is configured(For PDU/Switch) or booted(for Node)
#-----------------------------
my %state_node_hash = ();
# $state_node_hash{pdu}{state1}{number} = xx;
my %state_node_number = ();
#----------------------------
# To store the node based current state
# May like this:
# $node_info{node1}{state} = "install";
# $node_info{node1}{type} = "node";
#----------------------------
my %node_info = ();
#---------------------------
# To store nodes who haven't finished the status
#---------------------------
my %unfinished_nodes = ();
my %unmatched_nodes = ();
$::USAGE = "Usage:
$program_name -h
$program_name {-d|-g} [-n noderange] [-V|--verbose]
$program_name [-n noderange] [-V|--verbose] [-i|--interval <seconds>] [--timeout <seconds>]
Description:
Use this command to get a summary of the cluster.
Options:
-h : Get usage information of $program_name
-n : Range of nodes to check. Default is \"compute\".
-d : Discovery. Display count of discovered nodes.
-g : Group count. Display count of nodes in each group.
-n : Range of nodes to check. All node objects will be used if not specified.
-i : The interval for screen refreshing, unit is second(s), 5 seconds by default.
-V : To print additional debug information.
--timeout: The timout if not all nodes finish, unit is second(s), no timeout by default.
";
#-------------------------------------
@@ -44,6 +89,8 @@ if (
"V|verbose" => \$VERBOSE,
"d|discovery" => \$DISCOVERY,
"g|groupcount" => \$GROUPCOUNT,
"i|interval=s" => \$interval,
"timeout=s" => \$timeout,
"n=s" => \$noderange))
{
probe_utils->send_msg("$output", "f", "Invalid parameter for $program_name");
@@ -65,12 +112,6 @@ if ($test) {
exit 0;
}
if ((!$DISCOVERY) and (!$GROUPCOUNT)) {
probe_utils->send_msg("$output", "f", "Discovery or groupcount option is required for $program_name");
probe_utils->send_msg("$output", "d", "$::USAGE");
exit 1;
}
if (scalar(@ARGV) >= 1) {
# After processing all the expected flags and arguments,
@@ -79,10 +120,42 @@ if (scalar(@ARGV) >= 1) {
probe_utils->send_msg("$output", "d", "$::USAGE");
exit 1;
}
if (!$DISCOVERY and !$GROUPCOUNT) {
if(!defined($noderange)) {
$noderange = "all";
}
} else {
if (!defined($noderange)) {
$noderange = "compute";
}
check_for_discovered_nodes() if ($DISCOVERY);
groupcount_nodes() if ($GROUPCOUNT);
exit 0;
}
check_for_discovered_nodes() if ($DISCOVERY);
groupcount_nodes() if ($GROUPCOUNT);
$SIG{TERM} = $SIG{INT} = sub {
$terminal = 1;
};
unless ($interval) {
$interval = 5;
}
&check_nodes_attributes();
$start_time = time;
while (1) {
update_nodes_info();
alarm_output(1);
if ($terminal) {
alarm_output(0);
last;
}
if ($timeout and (time() - $start_time > $timeout)) {
alarm_output(0);
last;
}
sleep $interval;
}
exit 0;
# Check for node definitions with MAC address defined
sub check_for_discovered_nodes {
my $na = "N/A";
@@ -132,3 +205,128 @@ sub groupcount_nodes {
probe_utils->send_msg("$output", "w", "Group count function is not yet implemented.");
return $rc;
}
sub alarm_output {
my $flag = shift;
if ($flag) {
probe_utils->send_msg("$output", "xx", `clear`);
my $time_elapsed = time - $start_time;
probe_utils->send_msg("$output", "xx", "====".localtime()."($time_elapsed seconds Elapsed)");
} else {
probe_utils->send_msg("$output", "xx", "\nThe cluster state===============================");
}
foreach my $type (keys(%state_node_hash)) {
unless ($type_nodesnum{$type}) {
probe_utils->send_msg("$output", "w", "$type Total number: $type_nodesnum{$type}");
next;
}
probe_utils->send_msg("$output", "xx", "$type(Total: $type_nodesnum{$type})--------------------------");
foreach my $state (keys(%{$state_node_hash{$type}})) {
my $node_number = scalar(keys %{$state_node_hash{$type}{$state}});
if ($flag) {
my $number = sprintf("%.2f", $node_number * 100.0/ $type_nodesnum{$type});
probe_utils->send_msg("$output", "xx", "\t$state : $node_number($number%)");
} else {
probe_utils->send_msg("$output", "xx", "\t$state($node_number): ". join(",",keys %{$state_node_hash{$type}{$state}}) );
}
}
}
}
sub update_nodes_info {
if (keys(%unmatched_nodes)) {
my $unmatched_noderange = join(",", keys(%unmatched_nodes));
my @unmatched_nodes_attributes = `lsdef -i mac -c $unmatched_noderange 2> /dev/null`;
foreach (@unmatched_nodes_attributes) {
if (/^(.*):\s*mac=(.*)$/) {
if ($2) {
update_node_info($1, "Matched");
}
}
}
}
if (keys(%unfinished_nodes)) {
my $unfinished_noderange = join(",", keys(%unfinished_nodes));
my @unfinished_nodes_attributes = `lsdef -i status -c $unfinished_noderange 2> /dev/null`;
foreach (@unfinished_nodes_attributes) {
if (/^(.*):\s*status=(.*)$/) {
if ($2) {
update_node_info($1, "$2");
}
}
}
}
unless(scalar keys(%unfinished_nodes)) {
$terminal = 1;
}
}
sub update_node_info {
my $node = shift;
my $state = shift;
my $node_type = $node_info{$node}{type};
my $node_state = $node_info{$node}{state};
if ($state and $state ne '') {
if (exists($unmatched_nodes{$node})) {
delete($unmatched_nodes{$node});
$unfinished_nodes{$node} = 1;
}
}
if ($state eq $node_state) {
return;
}
if (exists($state_node_hash{$node_type}{$node_state}{$node})) {
delete($state_node_hash{$node_type}{$node_state}{$node});
}
unless (scalar keys ($state_node_hash{$node_type}{$node_state})) {
delete($state_node_hash{$node_type}{$node_state});
}
$state_node_hash{$node_type}{$state}{$node} = 1;
$node_info{$node}{state} = $state;
if ($state eq 'booted' or $state eq 'configured') {
delete $unfinished_nodes{$node};
}
}
sub check_nodes_attributes {
my @nodes_attributes = `lsdef -i status,mac,mgt -c $noderange 2> /dev/null`;
my %nodehash = ();
foreach (@nodes_attributes) {
if (/^(.*):\s*([^=]*)=(.*)$/) {
$nodehash{$1}{$2}=$3;
}
}
foreach (keys %nodehash) {
if (!defined($nodehash{$_}{mgt})) {
probe_utils->send_msg("$output", "w", "No 'mgt' set for node:$_");
next;
}
if ($nodehash{$_}{status}) {
$node_info{$_}{state} = $nodehash{$_}{status};
$unfinished_nodes{$_} = 1;
} elsif ($nodehash{$_}{mac}) {
$node_info{$_}{state} = "Matched";
$unfinished_nodes{$_} = 1;
} else {
$node_info{$_}{state} = "matching";
$unmatched_nodes{$_} = 1;
}
if ($nodehash{$_}{mgt} eq 'pdu') {
$node_info{$_}{type} = 'pdu';
} elsif($nodehash{$_}{mgt} eq 'switch') {
$node_info{$_}{type} = 'switch';
} else {
$node_info{$_}{type} = 'node';
}
my $node_type = $node_info{$_}{type};
if (!exists($type_nodesnum{$node_type})) {
$type_nodesnum{$node_type} = 1;
} else {
$type_nodesnum{$node_type} += 1;
}
$state_node_hash{$node_type}{$node_info{$_}{state}}{$_} = 1;
}
}
exit 0;
+27 -48
View File
@@ -242,12 +242,19 @@ sub check_pre_defined_node {
$vpd_line =~ s/"//g;
my @split_vpd = split(",", $vpd_line);
if (($split_vpd[1] ne "") and ($split_vpd[2] ne "")) {
my $mtmsvpd = "$split_vpd[2]*$split_vpd[1]";
push @{ $mtms_node{$mtmsvpd} }, $split_vpd[0];
my $mtms = uc ("$split_vpd[2]*$split_vpd[1]");
my $tmp_node = $split_vpd[0];
my $tmp_type = `lsdef $tmp_node -i hwtype,nodetype -c`;
if ($tmp_type =~ /hwtype=bmc/ and $tmp_type =~ /nodetype=mp/) {
push @{ $mtms_node{$mtms}{bmc} }, $tmp_node;
} else {
push @{ $mtms_node{$mtms}{node} }, $tmp_node;
}
}
}
my @error_mtms;
my @error_mtms_bmc;
foreach my $node (keys %nodecheckrst) {
# check pre-define node whether has mtm and serial
@@ -259,26 +266,13 @@ sub check_pre_defined_node {
# check if there is one or more node has the same mtms with current node
my $mtms = "$nodecheckrst{$node}{\"mtm\"}*$nodecheckrst{$node}{\"serial\"}";
my $mtms_num = @{$mtms_node{$mtms}};
if ($mtms_num > 2) {
my $mtms_node_num = @{ $mtms_node{$mtms}{node} };
my $mtms_bmc_num = @{ $mtms_node{$mtms}{bmc} };
if ($mtms_node_num >= 2) {
push @error_mtms, $mtms if (!grep {$_ eq $mtms} @error_mtms);
} elsif ($mtms_num == 2) {
foreach my $mtmsnode (@{$mtms_node{$mtms}}) {
next if ($mtmsnode eq $node);
if (exists($nodecheckrst{$mtmsnode})) {
if (($nodecheckrst{$mtmsnode}{"nodetype"} eq $nodecheckrst{$node}{"nodetype"}) and ($nodecheckrst{$mtmsnode}{"hwtype"} eq $nodecheckrst{$node}{"hwtype"})) {
push @error_mtms, $mtms if (!grep {$_ eq $mtms} @error_mtms);
}
} else {
my $nodetype = `lsdef $mtmsnode -i nodetype -c |awk -F"=" '{print \$2}'`;
my $hwtype = `lsdef $mtmsnode -i hwtype -c |awk -F"=" '{print \$2}'`;
chomp($nodetype);
chomp($hwtype);
if (($nodetype eq $nodecheckrst{$node}{"nodetype"}) and ($hwtype eq $nodecheckrst{$node}{"hwtype"})) {
push @error_mtms, $mtms if (!grep {$_ eq $mtms} @error_mtms);
}
}
}
}
if ($mtms_bmc_num >= 2) {
push @error_mtms_bmc, $mtms if (!grep {$_ eq $mtms} @error_mtms_bmc);
}
}
}
@@ -291,11 +285,20 @@ sub check_pre_defined_node {
if (@error_mtms) {
foreach (@error_mtms) {
my $errornode = join(",", @{$mtms_node{$_}});
my $errornode = join(",", @{$mtms_node{$_}{node}});
probe_utils->send_msg("stdout", "f", "[$errornode] : Duplicate node definition found for the same mtms $_.");
$rst = 1;
}
}
if (@error_mtms_bmc) {
foreach (@error_mtms_bmc) {
my $errorbmcnode = join(",", @{$mtms_node{$_}{bmc}});
my $errornode = join(",", @{$mtms_node{$_}{node}});
probe_utils->send_msg("stdout", "f", "[$errornode] : Duplicate BMC node ($errorbmcnode) definition found for the same mtms $_.");
$rst = 1;
}
}
}
if ($discovery_type eq "switch") {
@@ -356,7 +359,7 @@ sub check_pre_defined_node {
next;
}
if (!(exists($nodecheckrst{$node}{"switchport"})) or $nodecheckrst{$node}{"switchport"} !~ /^\w/ or $valid_nodes !~ $node) {
if (!(exists($nodecheckrst{$node}{"switchport"})) or $nodecheckrst{$node}{"switchport"} !~ /^\d+$/ or $valid_nodes !~ $node) {
push @error_attribute, "switchport";
}
@@ -378,18 +381,6 @@ sub check_pre_defined_node {
$keystring = "Missing definition for related switch $nodecheckrst{$node}{\"switch\"}";
last;
}
if ($tmpoutput !~ /snmpversion=/) {
$keystring = "Missing attribute 'snmpversion' definition for related switch $nodecheckrst{$node}{\"switch\"}";
last;
}
if ($tmpoutput !~ /username=/) {
$keystring = "Missing attribute 'username' definition for related switch $nodecheckrst{$node}{\"switch\"}";
last;
}
if ($tmpoutput !~ /password=/) {
$keystring = "Missing attribute 'password' definition for related switch $nodecheckrst{$node}{\"switch\"}";
last;
}
}
if ($keystring) {
@@ -533,7 +524,6 @@ sub check_genesis_file {
my $rst = 0;
my @warn_msg;
my $genesis_v;
my $os = probe_utils->get_os();
if ($os =~ "unknown") {
probe_utils->send_msg("stdout", "f", $msg);
@@ -549,7 +539,6 @@ sub check_genesis_file {
probe_utils->send_msg("stdout", "d", "xCAT-genesis is not installed.");
return 1;
}
$genesis_v = `dpkg -s xcat-genesis-base-ppc64`;
} else {
my $genesis_output = `rpm -qa | grep -i "xcat-genesis"`;
unless (($genesis_output =~ /base/ and $genesis_output =~ /ppc64/) and
@@ -560,15 +549,6 @@ sub check_genesis_file {
probe_utils->send_msg("stdout", "d", "xCAT-genesis is not installed.");
return 1;
}
$genesis_v = `rpm -qi xCAT-genesis-base-ppc64`;
}
if ($genesis_v =~ /Built in environment .+fc(\d*).+ on (.+)\./) {
my $ver = $1;
my $arch = $2;
push @warn_msg, "xcat-genesis-base-ppc64 is not built in environment fedora 26 or higher version on $arch." if ($ver < 26);
} else {
push @warn_msg, "xcat-genesis-base-ppc64 is not built in environment fedora.";
}
my $genesis_update_flag_p;
@@ -649,14 +629,13 @@ sub check_genesis_file {
$rst = 1;
}
if ($initrd_path =~ /http.+($tftpdir\/.+)/) {
if ($initrd_path =~ /http:\/\/.+:80(\/.+)/) {
my $initrd_file = $1;
my $initrd_time = `stat $initrd_file | grep Modify | cut -d ' ' -f 2-3`;
if ($genesis_time and $initrd_time < $genesis_time) {
$genesis_update_flag_p = 1;
}
}
}
if ($genesis_line =~ /^kernel/) {
+3 -3
View File
@@ -92,10 +92,10 @@ sub check_for_duplicate_mtms_sn {
chomp($all_nodes_mtm_serial);
my @all_nodes_mtm_serial_lines = split("[\n\r]", $all_nodes_mtm_serial);
if ($all_nodes_mtm_serial =~ /Usage:/) {
if ($all_nodes_mtm_serial =~ /Usage:|Could not find any object definitions to display/) {
# lsdef command displayed a Usage message. Must be some noderange formatting problem.
# Issue a warning and exit.
# lsdef command displayed a Usage message. Must be some noderange formatting problem,
# or no nodes defined at all. Issue a warning and exit.
probe_utils->send_msg("$output", "w", "Can not get a list of nodes from specified noderange.");
return 1;
}
+4 -1
View File
@@ -120,6 +120,7 @@ foreach (<$fd>) {
}
}
close($fd);
my $rc = 0;
if (-f $normal_file) {
unlink($normal_file);
}
@@ -129,8 +130,10 @@ if (-f $error_file) {
if (@error_nodes) {
my $error_node = join(",", @error_nodes);
probe_utils->send_msg("$output", "d", "[$error_node] : Error, switch-macmap can only be run against xCAT objects that have 'nodetype=switch'");
$rc = 1;
}
foreach (@fails) {
probe_utils->send_msg("$output", "f", "$_");
$rc = 1;
}
exit 0;
exit $rc;
+1
View File
@@ -44,6 +44,7 @@ mkdir -p $RPM_BUILD_ROOT/%{prefix}/probe/
cp xcatprobe $RPM_BUILD_ROOT/%{prefix}/bin
cp -r subcmds $RPM_BUILD_ROOT/%{prefix}/probe/
cp -r lib $RPM_BUILD_ROOT/%{prefix}/probe/
cp -r scripts $RPM_BUILD_ROOT/%{prefix}/probe/
%clean
# This step does not happen until *after* the %files packaging below
+14 -15
View File
@@ -82,9 +82,9 @@ sub subvars {
close($inh);
#the logic to determine the $ENV{XCATMASTER} confirm to the following priority(from high to low):
#the "xcatmaster" attribute of the node
#the site.master
#the ip address of the mn facing the compute node
## 1, the "xcatmaster" attribute of the node
## 2, the ip address of the mn/sn facing the compute node
## 3, the site.master
my $master;
#the "xcatmaster" attribute of the node
@@ -94,16 +94,6 @@ sub subvars {
$master = $et->{'xcatmaster'};
}
unless ($master) {
#the site.master
my @masters = xCAT::TableUtils->get_site_attribute("master");
my $tmp = $masters[0];
if (defined($tmp)) {
$master = $tmp;
}
}
unless ($master) {
#the ip address of the mn facing the compute node
@@ -115,14 +105,23 @@ sub subvars {
}
}
unless ($master) {
#the site.master
my @masters = xCAT::TableUtils->get_site_attribute("master");
my $tmp = $masters[0];
if (defined($tmp)) {
$master = $tmp;
}
}
unless ($master) {
$tmplerr = "Unable to identify master for $node";
return;
}
$ENV{XCATMASTER} = $master;
my ($host, $ipaddr) = xCAT::NetworkUtils->gethostnameandip($master);
my $ipaddr = xCAT::NetworkUtils->getipaddr($master);
if ($ipaddr) {
$ENV{MASTER_IP} = "$ipaddr";
}
+89 -1
View File
@@ -1693,7 +1693,6 @@ sub defmk
{
my $type = $::FINALATTRS{$obj}{objtype};
# check to make sure we have type
if (!$type)
{
@@ -1714,10 +1713,30 @@ sub defmk
my @nets = xCAT::DBobjUtils->getObjectsOfType('network');
my %objhash;
foreach my $n (@nets) {
# netname is duplicate
if ( $obj eq $n ) {
my $rsp;
$rsp->{data}->[0] = "A network definition called \'$n\' already exists. Cannot create a definition for \'$obj\'.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
$error = 1;
delete $::FINALATTRS{$obj};
next OBJ;
}
$objhash{$n} = $type;
}
# When adding a new network entry, net and mask cannot be empty
if (!($::FINALATTRS{$obj}{net} && $::FINALATTRS{$obj}{mask}))
{
my $rsp;
$rsp->{data}->[0] = "Net or mask value should not be empty for xCAT network object \'$obj\'.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
$error = 1;
delete $::FINALATTRS{$obj};
next OBJ;
}
my %nethash = xCAT::DBobjUtils->getobjdefs(\%objhash);
foreach my $o (keys %nethash) {
# there is a network entry contains the same net and mask
if (($nethash{$o}{net} eq $::FINALATTRS{$obj}{net}) && ($nethash{$o}{mask} eq $::FINALATTRS{$obj}{mask})) {
my $rsp;
$rsp->{data}->[0] = "A network definition called \'$o\' already exists that contains the same net and mask values. Cannot create a definition for \'$obj\'.";
@@ -1727,6 +1746,7 @@ sub defmk
next OBJ;
}
}
}
# if object already exists
@@ -2370,6 +2390,74 @@ sub defch
$isDefined = 1;
}
if ($type eq 'network')
{
my $isInvalid = 0;
# When adding a new network entry, net and mask cannot be empty
if (!$isDefined && !($::FINALATTRS{$obj}{'net'} && $::FINALATTRS{$obj}{'mask'}))
{
my $rsp;
$rsp->{data}->[0] = "Net or mask value should not be empty for xCAT network object \'$obj\'.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
$error = 1;
$isInvalid = 1;
delete($::FINALATTRS{$obj});
next;
}
my @nets = xCAT::DBobjUtils->getObjectsOfType('network');
my %objhash;
foreach my $n (@nets) {
$objhash{$n} = $type;
}
# get original networks data
my %nethash = xCAT::DBobjUtils->getobjdefs(\%objhash);
foreach my $o (keys %nethash) {
# the netname already exists
if ($isDefined)
{
# when net is empty, chdef command should add net value, $::FINALATTRS{$obj}{net} should have value
if ((!$nethash{$o}{net}) && (!$::FINALATTRS{$obj}{net}))
{
$isInvalid=1;
my $rsp;
$rsp->{data}->[0] = "Attribute \'net\' is not specified for network entry \'$obj\', skipping.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
$error = 1;
last;
}
# when mask is empty, chdef command should add mask value, $::FINALATTRS{$obj}{mask} should have value
if ((!$nethash{$o}{mask}) && (!$::FINALATTRS{$obj}{mask}))
{
$isInvalid=1;
my $rsp;
$rsp->{data}->[0] = "Attribute \'mask\' is not specified for network entry \'$obj\', skipping.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
$error = 1;
last;
}
}
# the netname does not exist
else {
# there is a network definition already contains the same net and mask, it is duplicate
if (($nethash{$o}{net} eq $::FINALATTRS{$obj}{net}) && ($nethash{$o}{mask} eq $::FINALATTRS{$obj}{mask}))
{
$isInvalid=1;
my $rsp;
$rsp->{data}->[0] = "A network definition called \'$o\' already exists that contains the same net and mask values. Cannot create a definition for \'$obj\'.";
xCAT::MsgUtils->message("E", $rsp, $::callback);
$error = 1;
last;
}
}
}
if($isInvalid)
{
delete($::FINALATTRS{$obj});
next;
}
}
if (!$isDefined && ($type eq 'node') && (!defined($::FINALATTRS{$obj}{'groups'}) || !$::FINALATTRS{$obj}{'groups'}))
{
my $rsp;
@@ -28,21 +28,6 @@ sub process_request {
}
my $client_ip = $req->{'_xcat_clientip'};
#now, notify the node that its findme request is under processing
xCAT::MsgUtils->message("S", "Notify $client_ip that its findme request is processing\n");
my $sock = new IO::Socket::INET(
PeerAddr => $client_ip,
PeerPort => '3001',
Timeout => '1',
Proto => 'tcp'
);
if ($sock) {
print $sock "processing";
close($sock);
}else{
xCAT::MsgUtils->message("S", "Failed to notify $client_ip that its findme request is processing.");
}
my $arptable;
if (-x "/usr/sbin/arp") {
$arptable = `/usr/sbin/arp -n`;
+4 -4
View File
@@ -141,16 +141,16 @@ sub process_request {
$clipassword = $password;
}
unless (defined $bmc) {
xCAT::MsgUtils->message('S', "Received request from host=$node but unable to determine $bmc_mgmt_type.bmc value for the node. Verify mgt attribute is configured correctly for the node and the BMC is defined.");
$callback->({ error => ["Unable to detect BMC configuration value for bmcconfig"], errorcode => [1] });
xCAT::MsgUtils->message('S', "Received request from host=$node but unable to determine the $bmc_mgmt_type.bmc value for the node. Verify the node.mgt attribute is configured and the node.bmc is defined.");
$callback->({ error => ["No value specified for '$node.bmc'. Unable to configure the BMC, check the node definition."], errorcode => [1] });
return 1;
}
my $bmcport_counter = 0;
foreach my $sbmc (split /,/, $bmc) {
(my $ip, my $mask, my $gw) = net_parms($sbmc);
unless ($ip and $mask and $username and $password) {
xCAT::MsgUtils->message('S', "Unable to determine IP, netmask, username, and/or pasword for $sbmc, ensure that host resolution is working. Best guess parameters would have been: IP: '$ip', netmask: '$mask', username: '$username', password: '$password'",);
$callback->({ error => ["Invalid table configuration for bmcconfig"], errorcode => [1] });
xCAT::MsgUtils->message('S', "Unable to determine IP, Netmask, Username, or Password for $sbmc. Ensure that hostname resolution is working. [IP=$ip Netmask=$mask User=$username Pass=$password]",);
$callback->({ error => ["Invalid/Missing BMC related attributes in the node defintion (IP=$ip Netmask=$mask User=$username Pass=$password). Unable to configure the BMC, check the node definition."], errorcode => [1] });
return 1;
}
if ($request->{command}->[0] eq 'remoteimmsetup') {
+53 -67
View File
@@ -125,14 +125,6 @@ sub process_request
my $request_command = shift;
$::CALLBACK = $callback;
#$::args = $request->{arg};
if (ref($request->{environment}) eq 'ARRAY' and ref($request->{environment}->[0]->{XCAT_DEV_WITHERSPOON}) eq 'ARRAY') {
$::XCAT_DEV_WITHERSPOON = $request->{environment}->[0]->{XCAT_DEV_WITHERSPOON}->[0];
} elsif (ref($request->{environment}) eq 'ARRAY') {
$::XCAT_DEV_WITHERSPOON = $request->{environment}->[0]->{XCAT_DEV_WITHERSPOON};
} else {
$::XCAT_DEV_WITHERSPOON = $request->{environment}->{XCAT_DEV_WITHERSPOON};
}
if ($request->{sn}) {
my $dhcpservers = $request->{dhcpservers};
if (!defined($dhcpservers) or ref($dhcpservers) ne 'ARRAY') {
@@ -191,7 +183,7 @@ sub bmcdiscovery_usage {
push @{ $rsp->{data} }, "Usage:";
push @{ $rsp->{data} }, "\tbmcdiscover [-?|-h|--help]";
push @{ $rsp->{data} }, "\tbmcdiscover [-v|--version]";
push @{ $rsp->{data} }, "\tbmcdiscover [-s scan_method] [-u bmc_user] [-p bmc_passwd] [-z] [-w] --range ip_range\n";
push @{ $rsp->{data} }, "\tbmcdiscover [--sn <SN_nodename>] [-s scan_method] [-u bmc_user] [-p bmc_passwd] [-z] [-w] --range ip_range\n";
push @{ $rsp->{data} }, "\tCheck BMC administrator User/Password:\n";
push @{ $rsp->{data} }, "\t\tbmcdiscover -u bmc_user -p bmc_password -i bmc_ip --check\n";
@@ -566,7 +558,7 @@ sub scan_process {
my $children; # The number of child process
my %sp_children; # Record the pid of child process
my $bcmd;
my $sub_fds = new IO::Select; # Record the parent fd for each child process
if (!defined($method))
{
@@ -617,7 +609,7 @@ sub scan_process {
my $live_ip = split_comma_delim_str($ip_list);
my $live_mac = split_comma_delim_str($mac_list);
my %pipe_map;
if (scalar(@{$live_ip}) > 0) {
foreach (@{$live_ip}) {
@@ -651,6 +643,9 @@ sub scan_process {
if ($sp_children{$cpid}) {
delete $sp_children{$cpid};
$children--;
forward_data($callback, $pipe_map{$cpid});
close($pipe_map{$cpid});
delete $pipe_map{$cpid};
}
}
};
@@ -680,7 +675,7 @@ sub scan_process {
} else {
bmcdiscovery_ipmi(${$live_ip}[$i], $opz, $opw, $request_command);
}
close($parent_fd);
exit 0;
} else {
@@ -688,23 +683,15 @@ sub scan_process {
# the main process will check all the parent fd and receive response
$sp_children{$child} = 1;
close($parent_fd);
$sub_fds->add($cfd);
$pipe_map{$child} = $cfd;
}
do {
while ($children >= 32) {
sleep(1);
} until ($children < 32);
}
}
#################################################
# receive data from child processes
################################################
while ($sub_fds->count > 0 or $children > 0) {
forward_data($callback, $sub_fds);
}
while (forward_data($callback, $sub_fds)) {
while($children > 0) {
sleep(1);
}
}
else
@@ -832,26 +819,14 @@ sub send_rep {
sub forward_data {
my $callback = shift;
my $fds = shift;
my @ready_fds = $fds->can_read(1);
my $rfh;
my $rc = @ready_fds;
foreach $rfh (@ready_fds) {
my $data;
my $responses;
eval {
$responses = fd_retrieve($rfh);
};
if ($@ and $@ =~ /^Magic number checking on storable file/) { #this most likely means we ran over the end of available input
$fds->remove($rfh);
close($rfh);
} else {
eval { print $rfh "ACK\n"; }; #Ignore ack loss due to child giving up and exiting, we don't actually explicitly care about the acks
$callback->($responses);
}
my $cfd = shift;
my $responses;
eval {
$responses = fd_retrieve($cfd);
};
if (!($@ and $@ =~ /^Magic number checking on storable file/)) { #this most likely means we ran over the end of available input
$callback->($responses);
}
yield; #Try to avoid useless iterations as much as possible
return $rc;
}
@@ -1107,19 +1082,8 @@ sub bmcdiscovery_ipmi {
xCAT::MsgUtils->message("W", { data => ["BMC password is incorrect for $ip"] }, $::CALLBACK);
return;
}
if (defined($opz) || defined($opw))
{
format_stanza($node, $node_data, "ipmi");
if (defined($opw))
{
write_to_xcatdb($node, $node_data, "ipmi", $request_command);
}
}
else {
my $rsp = {};
push @{ $rsp->{data} }, "$node_data";
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
}
display_output($opz,$opw,$node,$node_data,"ipmi",$request_command);
}
}
@@ -1180,12 +1144,8 @@ sub bmcdiscovery_openbmc{
my $serial;
if (defined($response->{data})) {
if (defined($response->{data}->{PartNumber}) and defined($response->{data}->{SerialNumber})) {
$mtm = $response->{data}->{PartNumber};
if (defined($::XCAT_DEV_WITHERSPOON) && ($::XCAT_DEV_WITHERSPOON eq "TRUE")) {
xCAT::MsgUtils->message("I", { data => ["XCAT_DEV_WITHERSPOON=TRUE, forcing MTM to empty string for $ip (Original MTM=$mtm)"] }, $::CALLBACK);
$mtm = "";
}
if (defined($response->{data}->{Model}) and defined($response->{data}->{SerialNumber})) {
$mtm = $response->{data}->{Model};
$serial = $response->{data}->{SerialNumber};
}
@@ -1234,12 +1194,38 @@ sub bmcdiscovery_openbmc{
}
return;
}
display_output($opz,$opw,$node,$node_data,"openbmc",$request_command);
}
if (defined($opz) || defined($opw)) {
format_stanza($node, $node_data, "openbmc");
if (defined($opw)) {
write_to_xcatdb($node, $node_data, "openbmc", $request_command);
#-----------------------------------------------------------------------------
=head3 display_output
Common code to print output of bmcdiscover
=cut
#-----------------------------------------------------------------------------
sub display_output {
my $opz = shift;
my $opw = shift;
my $node = shift;
my $node_data = shift;
my $mgttype = shift;
my $request_command = shift;
if (defined($opw)) {
my $rsp = {};
push @{ $rsp->{data} }, "Writing $node ($node_data) to database...";
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
if (defined($opz)) {
format_stanza($node, $node_data, $mgttype);
}
write_to_xcatdb($node, $node_data, $mgttype, $request_command);
}
elsif (defined($opz)) {
format_stanza($node, $node_data, $mgttype);
} else {
my $rsp = {};
push @{ $rsp->{data} }, "$node_data";
+4 -2
View File
@@ -957,6 +957,8 @@ sub mknetboot
my $xcatdport = "3001";
my $xcatiport = "3002";
my $nodestatus = "y";
my @myself = xCAT::NetworkUtils->determinehostname();
my $myname = $myself[ (scalar @myself) - 1 ];
if ($sitetab)
{
@@ -1170,7 +1172,7 @@ sub mknetboot
if ($statelite) {
unless (-r "$rootimgdir/kernel") {
$callback->({
error => [qq{Did you run "genimage" before running "liteimg"? kernel cannot be found...}],
error => [qq{Did you run "genimage" before running "liteimg"? kernel cannot be found at $rootimgdir/kernel on $myname}],
errorcode => [1]
});
next;
@@ -1197,7 +1199,7 @@ sub mknetboot
} else {
unless (-r "$rootimgdir/kernel") {
$callback->({
error => [qq{Did you run "genimage" before running "packimage"? kernel cannot be found}],
error => [qq{Did you run "genimage" before running "packimage"? kernel cannot be found at $rootimgdir/kernel on $myname}],
errorcode => [1]
});
next;
+2 -1
View File
@@ -655,8 +655,8 @@ sub setdestiny {
if ($reststates) {
$updates->{$_}->{'currchain'} = $reststates;
}
$chaintab->setNodesAttribs($updates);
}
$chaintab->setNodesAttribs($updates);
return getdestiny($flag + 1);
}
@@ -784,6 +784,7 @@ sub getdestiny {
@nodes = ($node);
}
my $node;
xCAT::MsgUtils->trace(0, "d", "destiny->process_request: getdestiny...");
$restab = xCAT::Table->new('noderes');
my $chaintab = xCAT::Table->new('chain');
my $chainents = $chaintab->getNodesAttribs(\@nodes, [qw(currstate chain)]);
+1 -1
View File
@@ -816,7 +816,7 @@ sub process_request {
if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: issue makedhcp request");
$sub_req->({ command => ['makedhcp'],
node => \@{ $osimagenodehash{$osimage} } }, $callback);
node => \@{ $osimagenodehash{$osimage} }, arg => ['-l'] }, $callback);
} else {
xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: issue makedhcp request");
$sub_req->({ command => ['makedhcp'],
+84 -22
View File
@@ -20,6 +20,7 @@ use xCAT_monitoring::monitorctrl;
use xCAT::SPD qw/decode_spd/;
use xCAT::IPMI;
use xCAT::PasswordUtils;
use File::Basename;
my %needbladeinv;
use POSIX qw(ceil floor);
@@ -33,6 +34,7 @@ use xCAT::SvrUtils;
use xCAT::NetworkUtils;
use xCAT::Usage;
use File::Path;
use File::Spec;
use Thread qw(yield);
use LWP 5.64;
@@ -1612,8 +1614,8 @@ sub isopenpower {
if ($sessdata->{prod_id} == 43707 and $sessdata->{mfg_id} == 0) {
# mft_id 0 and prod_id 43707 is for Firestone,Minsky
return 1;
} elsif (($sessdata->{prod_id} == 0 or $sessdata->{prod_id} == 2355) and $sessdata->{mfg_id} == 10876) {
# mfg_id 10876 is for IBM Power S822LC for Big Data (Supermicro), prod_id 2355 for B&S, and 0 for Boston
} elsif (($sessdata->{prod_id} =~ /0|2355|2437/) and $sessdata->{mfg_id} == 10876) {
# mfg_id 10876 is for IBM Power S822LC for Big Data (Supermicro), prod_id 2355 for B&S, and 0 or 2437 for Boston
return 1;
} else {
return 0;
@@ -1929,6 +1931,13 @@ sub do_firmware_update {
$buffer_size = "15000";
}
my $directory_name;
if (@{ $sessdata->{extraargs} } > 1) {
@ARGV = @{ $sessdata->{extraargs} };
use Getopt::Long;
GetOptions('d:s' => \$directory_name);
}
# check verbose, buffersize, and retry options
for my $opt (@{$sessdata->{'extraargs'}}) {
if ($opt =~ /-V{1,4}/) {
@@ -1961,40 +1970,46 @@ sub do_firmware_update {
}
}
}
if ($opt =~ /-d=/) {
my ($attribute, $directory_name) = split(/=/, $opt);
if (defined $directory_name) {
# directory was passed in, verify it is valid
if (-d $directory_name) {
# Passed in directory name exists
$pUpdate_directory = $directory_name;
}
else {
$exit_with_error_func->($sessdata->{node}, $callback,
"Can not access data directory $directory_name");
}
if (defined $directory_name) {
unless (File::Spec->file_name_is_absolute($directory_name)) {
# Directory name was passed in as relative path, prepend current working dir
$directory_name = xCAT::Utils->full_path($directory_name, $::cwd);
}
# directory was passed in, verify it is valid
if (-d $directory_name) {
# Passed in directory name exists
$pUpdate_directory = $directory_name;
}
else {
$exit_with_error_func->($sessdata->{node}, $callback,
"Data directory must be specified.");
$exit_with_error_func->($sessdata->{node}, $callback, "Can not access data directory $directory_name");
}
}
else {
$exit_with_error_func->($sessdata->{node}, $callback, "Data directory must be specified.");
}
}
# For IBM Power S822LC for Big Data (Supermicro) machines such as P9 Boston (9006-22C) or P8 Briggs (8001-22C)
# For IBM Power S822LC for Big Data (Supermicro) machines such as
# P9 Boston (9006-22C, 9006-12) or P8 Briggs (8001-22C)
# firmware update is done using pUpdate utility expected to be in the
# specified data directory along with the update files .bin for BMC or .pnor for Host
if ($output =~ /8001-22C|9006-22C/) {
if ($output =~ /8001-22C|9006-22C|9006-12C/) {
# Verify valid data directory was specified
unless ($pUpdate_directory) {
$exit_with_error_func->($sessdata->{node}, $callback,
"Directory name is required to update Boston or Briggs machines.");
}
# Verify specified directory contains pUpdate utility
unless (-e "$pUpdate_directory/pUpdate") {
$exit_with_error_func->($sessdata->{node}, $callback,
"Can not find pUpdate utility in data directory $pUpdate_directory.");
}
# Verify specified directory contains executable pUpdate utility
unless (-x "$pUpdate_directory/pUpdate") {
$exit_with_error_func->($sessdata->{node}, $callback,
"Can not find executable pUpdate utility in data directory $pUpdate_directory.");
"Execute permission is not set for pUpdate utility in data directory $pUpdate_directory.");
}
# Verify there is at least one of update files inside data directory - .bin or .pnor
@@ -2383,6 +2398,7 @@ RETRY_UPGRADE:
sub rflash {
my $sessdata = shift;
my $directory_flag = 0;
if (isopenpower($sessdata)) {
# Do firmware update for firestone here.
@@ -2391,10 +2407,16 @@ sub rflash {
if ($opt =~ /^(-c|--check)$/i) {
$sessdata->{subcommand} = "check";
# support verbose options for ipmitool command
} elsif ($opt !~ /.*\.hpm$/i && $opt !~ /^-V{1,4}$|^--buffersize=|^--retry=|^-d=/) {
$callback->({ error => "The option $opt is not supported or invalid update file specified",
} elsif ($opt =~ /^-d$/) {
# special handling if -d option which can be followed by a directory name
$directory_flag = 1; # set a flag that directory option was given
} elsif ($opt !~ /.*\.hpm$/i && $opt !~ /^-V{1,4}$|^--buffersize=|^--retry=/) {
# An unexpected flag was passed, but it could be a directory name. Display error only if not -d option
unless ($directory_flag) {
$callback->({ error => "The option $opt is not supported or invalid update file specified",
errorcode => 1 });
return;
return;
}
}
}
@@ -2473,6 +2495,46 @@ sub do_rflash_process {
$callback, $node, %allerrornodes);
exit(1);
}
my $recover_image;
if (grep(/^(--recover)$/, @{ $extra })) {
if (@{ $extra } != 2) {
xCAT::SvrUtils::sendmsg([ 1, "The command format for recovery is invalid. Only support 'rflash <noderange> --recover <bmc_file_path>'" ],
$callback, $node);
exit(1);
}
my @argv = @{ $extra };
if ($argv[0] eq "--recover") {
$recover_image = $argv[1];
} elsif ($argv[1] eq "--recover") {
$recover_image = $argv[0];
}
}
if (defined($recover_image)) {
if ($recover_image !~ /^\//) {
$recover_image = xCAT::Utils->full_path($recover_image, $::cwd);
}
unless(-x "/usr/bin/tftp") {
$callback->({ error => "Could not find executable file /usr/bin/tftp, please setup tftp client.",
errorcode => 1 });
exit(1);
}
my $bmcip = $_[0];
my $cmd = "/usr/bin/tftp $bmcip -m binary -c put $recover_image ".basename($recover_image);
my $output = xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
$callback->({ error => "Running tftp command \'$cmd\' failed. Error Code: $::RUNCMD_RC. Output: $output.",
errorcode => 1 });
exit(1);
}
# Sometimes tftp command retrun error message but without nonzero error code
if($output) {
$callback->({ error => "Running tftp command \'$cmd\' failed. Output: $output",
errorcode => 1 });
exit(1);
}
$callback->({ data => "$node: Successfully updated recovery image. BMC is restarting and will not be reachable for 5-10 minutes."});
exit(0);
}
donode($node, @_);
while (xCAT::IPMI->waitforrsp()) { yield }
xCAT::Utils->release_lock($lock, $NON_BLOCK);
+16 -5
View File
@@ -783,6 +783,15 @@ sub build_xmldesc {
#prepare the xml hash for pci passthrough
my @prdevarray;
foreach my $devname (@passthrudevices) {
#This is for SR-IOV vfio
#Change vfio format 0000:01:00.2 to pci_0000_01_00_2
if ( $devname =~ m/(\w:)+(\w)+.(\w)/ ){
$devname =~ s/[:|.]/_/g;
if ( $devname !~ /^pci_/ ) {
$devname ="pci_".$devname
}
}
my $devobj = $hypconn->get_node_device_by_name($devname);
unless ($devobj) {
return -1;
@@ -1397,12 +1406,14 @@ sub makedom {
}
my $parseddom = $parser->parse_string($xml);
my ($graphics) = $parseddom->findnodes("//graphics");
if ($confdata->{vm}->{$node}->[0]->{vidpassword}) {
$graphics->setAttribute("passwd", $confdata->{vm}->{$node}->[0]->{vidpassword});
} else {
$graphics->setAttribute("passwd", genpassword(20));
if (defined($graphics)) {
if ($confdata->{vm}->{$node}->[0]->{vidpassword}) {
$graphics->setAttribute("passwd", $confdata->{vm}->{$node}->[0]->{vidpassword});
} else {
$graphics->setAttribute("passwd", genpassword(20));
}
$graphics->setAttribute("listen", '0.0.0.0');
}
$graphics->setAttribute("listen", '0.0.0.0');
$xml = $parseddom->toString();
eval {
if ($::XCATSITEVALS{persistkvmguests}) {
+12 -3
View File
@@ -325,7 +325,6 @@ sub donets
# - compare net and mask values
my $foundmatch = 0;
foreach my $netn (@netlist) {
# split definition mask
my ($dm1, $dm2, $dm3, $dm4) = split('\.', $nethash{$netn}{'mask'});
@@ -359,7 +358,7 @@ sub donets
if ($foundmatch) {
next;
}
# add new network def
$nettab->setAttribs({ 'net' => $net, 'mask' => $netmask }, { 'netname' => $netname, 'gateway' => $gateway, 'mgtifname' => $i });
}
@@ -450,6 +449,7 @@ sub donets
{ #should be the lines to think about, do something with U, and something else with UG
my $foundmatch = 0;
my $netnamematch = 0;
my $rsp;
my $net;
my $mask;
@@ -504,7 +504,11 @@ sub donets
my ($n1, $n2, $n3, $n4) = split('\.', $net);
foreach my $netn (@netlist) {
# check if this netname is already defined
if ( $netname eq $netn ) {
$netnamematch = 1;
last;
}
# split definition mask
my ($dm1, $dm2, $dm3, $dm4) = split('\.', $nethash{$netn}{'mask'});
@@ -544,6 +548,11 @@ sub donets
push @{ $rsp->{data} }, " mtu=$mtu";
}
} else {
# if this net entry exists, go to next line in networks table
if ($netnamematch) {
$callback->({ warning => "The network entry \'$netname\' already exists in xCAT networks table. Cannot create a definition for \'$netname\'" });
next;
}
if (!$foundmatch) {
$nettab->setAttribs({ 'net' => $net, 'mask' => $mask }, { 'netname' => $netname, 'mgtifname' => $mgtifname, 'gateway' => $gw, 'mtu' => $mtu });
}
+3 -2
View File
@@ -312,6 +312,9 @@ sub process_request {
$hosttag = "$node-$ifinfo[1]";
push @hostnames_to_update, $hosttag;
}
elsif (!inet_aton($node)) {
xCAT::MsgUtils->message("S", "xcat.discovery.nodediscover: Can not resolve IP for the matching node:$node. Make sure \"makehosts\" and \"makedns\" have been run for $node.");
}
}
#print Dumper($hosttag) . "\n";
if ($hosttag) {
@@ -474,8 +477,6 @@ sub process_request {
print $sock $restartstring;
close($sock);
# sleep 2 seconds for genesis to complete the disocvery process
sleep(2);
#Update the discoverydata table to indicate the successful discovery
xCAT::DiscoveryUtils->update_discovery_data($request);
+263 -107
View File
@@ -19,6 +19,7 @@ use JSON;
use HTTP::Async;
use HTTP::Cookies;
use File::Basename;
use File::Spec;
use Data::Dumper;
use Getopt::Long;
use xCAT::OPENBMC;
@@ -42,6 +43,7 @@ $::POWER_STATE_QUIESCED = "quiesced";
$::POWER_STATE_RESET = "reset";
$::POWER_STATE_REBOOT = "reboot";
$::UPLOAD_FILE = "";
$::UPLOAD_FILE_VERSION = "";
$::NO_ATTRIBUTES_RETURNED = "No attributes returned from the BMC.";
@@ -135,8 +137,8 @@ my %status_info = (
},
REVENTLOG_CLEAR_REQUEST => {
method => "POST",
init_url => "$openbmc_url/records/events/action/clear",
data => "",
init_url => "$openbmc_project_url/logging//action/delete",
data => '{ "data": [] }',
},
REVENTLOG_CLEAR_RESPONSE => {
process => \&reventlog_response,
@@ -171,6 +173,13 @@ my %status_info = (
RFLASH_UPDATE_CHECK_STATE_RESPONSE => {
process => \&rflash_response,
},
RFLASH_UPDATE_CHECK_ID_REQUEST => {
method => "GET",
init_url => "$openbmc_project_url/software/enumerate",
},
RFLASH_UPDATE_CHECK_ID_RESPONSE => {
process => \&rflash_response,
},
RFLASH_SET_PRIORITY_REQUEST => {
method => "PUT",
init_url => "$openbmc_project_url/software",
@@ -270,13 +279,21 @@ my %status_info = (
process => \&rspconfig_response,
},
RSPCONFIG_SET_REQUEST => {
method => "POST",
init_url => "",
data => "",
method => "PUT",
init_url => "$openbmc_project_url/network",
data => "[]",
},
RSPCONFIG_SET_RESPONSE => {
process => \&rspconfig_response,
},
RSPCONFIG_DHCP_REQUEST => {
method => "POST",
init_url => "$openbmc_project_url/network/action/Reset",
data => "[]",
},
RSPCONFIG_DHCP_RESPONSE => {
process => \&rspconfig_response,
},
RSPCONFIG_SSHCFG_REQUEST => {
method => "GET",
init_url => "",
@@ -419,6 +436,7 @@ sub process_request {
my $command = $request->{command}->[0];
my $noderange = $request->{node};
my $extrargs = $request->{arg};
$::cwd = $request->{cwd}->[0];
my @exargs = ($request->{arg});
if (ref($extrargs)) {
@exargs = @$extrargs;
@@ -461,7 +479,10 @@ sub process_request {
$handle_id = xCAT::OPENBMC->new($async, $login_url, $content);
$handle_id_node{$handle_id} = $node;
$node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
xCAT::SvrUtils::sendmsg("$flag_debug POST $login_url -d $content", $callback, $node) if ($xcatdebugmode);
if ($xcatdebugmode) {
my $debug_info = "curl -k -c cjar -H \"Content-Type: application/json\" -d '{ \"data\": [\"$node_info{$node}{username}\", \"xxxxxx\"] }' $login_url";
process_debug_info($node, $debug_info);
}
}
}
@@ -541,10 +562,6 @@ sub parse_args {
return ([ 1, "Unsupported command: $command $subcommand" ]);
}
} elsif ($command eq "reventlog") {
#
# disable function until fully tested
#
$check = unsupported($callback); if (ref($check) eq "ARRAY") { return $check; }
my $option_s = 0;
unless (GetOptions("s" => \$option_s,)) {
return ([1, "Error parsing arguments." ]);
@@ -554,30 +571,33 @@ sub parse_args {
return ([ 1, "Unsupported command: $command $subcommand" ]);
}
} elsif ($command eq "rspconfig") {
#
# disable function until fully tested
#
$check = unsupported($callback); # Check later for each subcommand: if (ref($check) eq "ARRAY") { return $check; }
my $setorget;
foreach $subcommand (@ARGV) {
if ($subcommand =~ /^(\w+)=(.*)/) {
return ([ 1, "Can not configure and display nodes' value at the same time" ]) if ($setorget and $setorget eq "get");
my $key = $1;
my $value = $2;
return ([ 1, "Unsupported command: $command $key" ]) unless ($key =~ /^ip$|^netmask$|^gateway$|^vlan$/);
return ([ 1, "Unsupported command: $command $key" ]) unless ($key =~ /^ip$|^netmask$|^gateway$|^hostname$|^vlan$/);
my $nodes_num = @$noderange;
return ([ 1, "Invalid parameter for option $key" ]) unless ($value);
return ([ 1, "Invalid parameter for option $key: $value" ]) unless (xCAT::NetworkUtils->isIpaddr($value));
return ([ 1, "Invalid parameter for option $key: $value" ]) if ($key =~ /^netmask$|^gateway$/ and !xCAT::NetworkUtils->isIpaddr($value));
if ($key eq "ip") {
return ([ 1, "Can not configure more than 1 nodes' ip at the same time" ]) if ($nodes_num >= 2);
return ([ 1, "Can not configure more than 1 nodes' ip at the same time" ]) if ($nodes_num >= 2 and $value ne "dhcp");
if ($value ne "dhcp" and !xCAT::NetworkUtils->isIpaddr($value)) {
return ([ 1, "Invalid parameter for option $key: $value" ]);
}
}
$setorget = "set";
if (ref($check) eq "ARRAY") { return $check; }
} elsif ($subcommand =~ /^ip$|^netmask$|^gateway$|^vlan$/) {
#
# disable function until fully tested
#
unless (($key eq "ip" and $value eq "dhcp") or $key eq "hostname") {
$check = unsupported($callback); if (ref($check) eq "ARRAY") { return $check; }
}
} elsif ($subcommand =~ /^ip$|^netmask$|^gateway$|^hostname$|^vlan$/) {
return ([ 1, "Can not configure and display nodes' value at the same time" ]) if ($setorget and $setorget eq "set");
$setorget = "get";
if (ref($check) eq "ARRAY") { return $check; }
} elsif ($subcommand =~ /^sshcfg$/) {
$setorget = ""; # SSH Keys are copied using a RShellAPI, not REST API
} else {
@@ -590,11 +610,6 @@ sub parse_args {
return ([ 1, "Unsupported command: $command $subcommand" ]);
}
} elsif ($command eq "rflash") {
#
# disable function until fully supported by openbmc
# Currently waiting for issue https://github.com/openbmc/openbmc/issues/2074 to be fixed
#
$check = unsupported($callback); if (ref($check) eq "ARRAY") { return $check; }
my $filename_passed = 0;
my $updateid_passed = 0;
my $option_flag;
@@ -616,7 +631,7 @@ sub parse_args {
}
if ($filename_passed) {
# Filename was passed, check flags allowed with file
if ($option_flag !~ /^-c$|^--check$|^-d$|^--delete$|^-u$|^--upload$/) {
if ($option_flag !~ /^-c$|^--check$|^-u$|^--upload$|^-a$|^--activate$/) {
return ([ 1, "Invalid option specified when a file is provided: $option_flag" ]);
}
}
@@ -655,7 +670,7 @@ sub parse_command_status {
my $subcommands = shift;
my $subcommand;
if ($$subcommands[-1] =~ /V|verbose/) {
if ($$subcommands[-1] and $$subcommands[-1] =~ /V|verbose/) {
$::VERBOSE = 1;
pop(@$subcommands);
}
@@ -731,7 +746,11 @@ sub parse_command_status {
}
if ($command eq "rsetboot") {
$subcommand = $$subcommands[0];
if (defined($$subcommands[0])) {
$subcommand = $$subcommands[0];
} else {
$subcommand = "stat";
}
if ($subcommand =~ /^hd$|^net$|^cd$|^default$|^def$/) {
$next_status{LOGIN_RESPONSE} = "RSETBOOT_SET_REQUEST";
$next_status{RSETBOOT_SET_REQUEST} = "RSETBOOT_SET_RESPONSE";
@@ -754,7 +773,7 @@ sub parse_command_status {
if ($command eq "reventlog") {
my $option_s = 0;
if ($$subcommands[-1] eq "-s") {
if ($$subcommands[-1] and $$subcommands[-1] eq "-s") {
$option_s = 1;
pop(@$subcommands);
}
@@ -781,7 +800,7 @@ sub parse_command_status {
if ($command eq "rspconfig") {
my @options = ();
foreach $subcommand (@$subcommands) {
if ($subcommand =~ /^ip$|^netmask$|^gateway$|^vlan$/) {
if ($subcommand =~ /^ip$|^netmask$|^gateway$|^hostname$|^vlan$/) {
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_GET_REQUEST";
$next_status{RSPCONFIG_GET_REQUEST} = "RSPCONFIG_GET_RESPONSE";
push @options, $subcommand;
@@ -795,15 +814,33 @@ sub parse_command_status {
} elsif ($subcommand =~ /^(\w+)=(.+)/) {
my $key = $1;
my $value = $2;
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_SET_REQUEST";
$next_status{RSPCONFIG_SET_REQUEST} = "RSPCONFIG_SET_RESPONSE";
$next_status{RSPCONFIG_SET_RESPONSE} = "RSPCONFIG_GET_REQUEST";
$next_status{RSPCONFIG_GET_REQUEST} = "RSPCONFIG_GET_RESPONSE";
if ($key eq "ip") {
$status_info{RSPCONFIG_SET_RESPONSE}{ip} = $value;
if ($key eq "ip" and $value eq "dhcp") {
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_DHCP_REQUEST";
$next_status{RSPCONFIG_DHCP_REQUEST} = "RSPCONFIG_DHCP_RESPONSE";
$next_status{RSPCONFIG_DHCP_RESPONSE} = "RPOWER_BMCREBOOT_REQUEST";
$next_status{RPOWER_BMCREBOOT_REQUEST} = "RPOWER_RESET_RESPONSE";
$status_info{RPOWER_RESET_RESPONSE}{argv} = "bmcreboot";
} elsif ($key =~ /^hostname$/) {
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_SET_REQUEST";
$next_status{RSPCONFIG_SET_REQUEST} = "RSPCONFIG_SET_RESPONSE";
$next_status{RSPCONFIG_SET_RESPONSE} = "RSPCONFIG_GET_REQUEST";
$next_status{RSPCONFIG_GET_REQUEST} = "RSPCONFIG_GET_RESPONSE";
$status_info{RSPCONFIG_SET_REQUEST}{data} = "$value";
$status_info{RSPCONFIG_SET_REQUEST}{init_url} .= "/config/attr/HostName";
push @options, $key;
} else {
$next_status{LOGIN_RESPONSE} = "RSPCONFIG_SET_REQUEST";
$next_status{RSPCONFIG_SET_REQUEST} = "RSPCONFIG_SET_RESPONSE";
$next_status{RSPCONFIG_SET_RESPONSE} = "RSPCONFIG_GET_REQUEST";
$next_status{RSPCONFIG_GET_REQUEST} = "RSPCONFIG_GET_RESPONSE";
if ($key eq "ip") {
$status_info{RSPCONFIG_SET_RESPONSE}{ip} = $value;
}
$status_info{RSPCONFIG_SET_REQUEST}{data} = ""; # wait for interface, ip/netmask/gateway is $value
push @options, $key;
}
$status_info{RSPCONFIG_SET_REQUEST}{data} = ""; # wait for interface, ip/netmask/gateway is $value
push @options, $key;
}
}
$status_info{RSPCONFIG_GET_RESPONSE}{argv} = join(",", @options);
@@ -828,6 +865,7 @@ sub parse_command_status {
my $upload = 0;
my $activate = 0;
my $update_file;
my $upload_and_activate = 0;
foreach $subcommand (@$subcommands) {
if ($subcommand =~ /-c|--check/) {
@@ -845,33 +883,51 @@ sub parse_command_status {
}
}
my $filename = undef;
my $file_id = undef;
my $grep_cmd = "/usr/bin/grep -a";
my $version_tag = '"version=IBM"';
my $version_tag = '"^version="';
my $purpose_tag = '"purpose="';
my $purpose_value;
my $version_value;
if (defined $update_file) {
# Filename or file id was specified
if ($update_file =~ /.*\.tar$/) {
# Filename ending on .tar was specified
$filename = $update_file;
$::UPLOAD_FILE = $update_file; # Save filename to upload
if (File::Spec->file_name_is_absolute($update_file)) {
$::UPLOAD_FILE = $update_file;
}
else {
# If relative file path was given, convert it to absolute
$::UPLOAD_FILE = xCAT::Utils->full_path($update_file, $::cwd);
}
# Verify file exists and is readable
unless (-r $filename) {
xCAT::SvrUtils::sendmsg([1,"Cannot access $filename"], $callback);
unless (-r $::UPLOAD_FILE) {
xCAT::SvrUtils::sendmsg([1,"Cannot access $::UPLOAD_FILE"], $callback);
return 1;
}
if ($check_version) {
# Display firmware version of the specified .tar file
my $firmware_version_in_file = `$grep_cmd $version_tag $filename`;
my $purpose_version_in_file = `$grep_cmd $purpose_tag $filename`;
if ($activate) {
# Activate flag was specified together with a update file. We want to
# upload the file and activate it.
$upload_and_activate = 1;
$activate = 0;
}
if ($check_version | $upload_and_activate) {
# Extract Host version for the update file
my $firmware_version_in_file = `$grep_cmd $version_tag $::UPLOAD_FILE`;
my $purpose_version_in_file = `$grep_cmd $purpose_tag $::UPLOAD_FILE`;
chomp($firmware_version_in_file);
chomp($purpose_version_in_file);
my ($purpose_string,$purpose_value) = split("=", $purpose_version_in_file);
my ($version_string,$version_value) = split("=", $firmware_version_in_file);
(my $purpose_string,$purpose_value) = split("=", $purpose_version_in_file);
(my $version_string,$version_value) = split("=", $firmware_version_in_file);
if ($purpose_value =~ /host/) {
$purpose_value = "Host";
}
$::UPLOAD_FILE_VERSION = $version_value;
}
if ($check_version) {
# Display firmware version of the specified .tar file
xCAT::SvrUtils::sendmsg("TAR $purpose_value Firmware Product Version\: $version_value", $callback);
}
}
@@ -919,9 +975,15 @@ sub parse_command_status {
$next_status{"RFLASH_SET_PRIORITY_REQUEST"} = "RFLASH_SET_PRIORITY_RESPONSE";
$next_status{"RFLASH_SET_PRIORITY_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST";
}
if ($upload_and_activate) {
# Upload specified update file to BMC
$next_status{LOGIN_RESPONSE} = "RFLASH_FILE_UPLOAD_REQUEST";
$next_status{"RFLASH_FILE_UPLOAD_REQUEST"} = "RFLASH_FILE_UPLOAD_RESPONSE";
$next_status{"RFLASH_FILE_UPLOAD_RESPONSE"} = "RFLASH_UPDATE_CHECK_ID_REQUEST";
$next_status{"RFLASH_UPDATE_CHECK_ID_REQUEST"} = "RFLASH_UPDATE_CHECK_ID_RESPONSE";
}
}
print Dumper(\%next_status) . "\n";
return;
}
@@ -984,8 +1046,6 @@ sub parse_node_info {
}
}
print Dumper(\%node_info) ."\n";
return $rst;
}
@@ -1042,19 +1102,20 @@ sub gen_send_request {
$handle_id_node{$handle_id} = $node;
$node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
my $debug_info;
if ($method eq "GET") {
$debug_info = "$method $request_url";
} else {
if ($::UPLOAD_FILE) {
# Slightly different debug message when doing a file upload
$debug_info = "$method $request_url -T " . $::UPLOAD_FILE;
}
else {
$debug_info = "$method $request_url -d $content";
if ($xcatdebugmode) {
my $debug_info;
if ($method eq "GET") {
$debug_info = "curl -k -b cjar -X $method -H \"Content-Type: application/json\" $request_url";
} else {
if ($::UPLOAD_FILE) {
# Slightly different debug message when doing a file upload
$debug_info = "curl -k -b cjar -X $method -H \"Content-Type: application/json\" -T $::UPLOAD_FILE $request_url";
} else {
$debug_info = "curl -k -b cjar -X $method -H \"Content-Type: application/json\" -d '$content' $request_url";
}
}
process_debug_info($node, $debug_info);
}
xCAT::SvrUtils::sendmsg("$flag_debug $debug_info", $callback, $node) if ($xcatdebugmode);
return;
}
@@ -1078,8 +1139,10 @@ sub deal_with_response {
delete $handle_id_node{$handle_id};
my $debug_info = lc ($node_info{$node}{cur_status}) . " " . $response->status_line;
xCAT::SvrUtils::sendmsg("$flag_debug $debug_info", $callback, $node) if ($xcatdebugmode);
if ($xcatdebugmode) {
my $debug_info = lc ($node_info{$node}{cur_status}) . " " . $response->status_line;
process_debug_info($node, $debug_info);
}
if ($response->status_line ne $::RESPONSE_OK) {
my $error;
@@ -1119,6 +1182,26 @@ sub deal_with_response {
#-------------------------------------------------------
=head3 process_debug_info
print debug info and add to log
Input:
$node: nodename which want to process ingo
$debug_msg: Info for debug
=cut
#-------------------------------------------------------
sub process_debug_info {
my $node = shift;
my $debug_msg = shift;
xCAT::SvrUtils::sendmsg("$flag_debug $debug_msg", $callback, $node);
xCAT::MsgUtils->trace(0, "D", "$flag_debug $node $debug_msg");
}
#-------------------------------------------------------
=head3 login_response
Deal with response of login
@@ -1178,8 +1261,7 @@ sub rpower_response {
if ($node_info{$node}{cur_status} eq "RPOWER_RESET_RESPONSE") {
if ($response_info->{'message'} eq $::RESPONSE_OK) {
if (defined $status_info{RPOWER_RESET_RESPONSE}{argv} and $status_info{RPOWER_RESET_RESPONSE}{argv} =~ /bmcreboot$/) {
my $bmc_node = "$node BMC";
xCAT::SvrUtils::sendmsg("$::POWER_STATE_REBOOT", $callback, $bmc_node);
xCAT::SvrUtils::sendmsg("BMC $::POWER_STATE_REBOOT", $callback, $node);
} else {
xCAT::SvrUtils::sendmsg("$::POWER_STATE_RESET", $callback, $node);
}
@@ -1210,18 +1292,10 @@ sub rpower_response {
$host_transition_state = $response_info->{'data'}->{$type}->{RequestedHostTransition};
}
}
xCAT::SvrUtils::sendmsg("$flag_debug State CurrentBMCState=$bmc_state", $callback, $node) if ($xcatdebugmode);
xCAT::SvrUtils::sendmsg("$flag_debug State RequestedBMCTransition=$bmc_transition_state", $callback, $node) if ($xcatdebugmode);
xCAT::SvrUtils::sendmsg("$flag_debug State CurrentPowerState=$chassis_state", $callback, $node) if ($xcatdebugmode);
xCAT::SvrUtils::sendmsg("$flag_debug State RequestedPowerTransition=$chassis_transition_state", $callback, $node) if ($xcatdebugmode);
xCAT::SvrUtils::sendmsg("$flag_debug State CurrentHostState=$host_state", $callback, $node) if ($xcatdebugmode);
xCAT::SvrUtils::sendmsg("$flag_debug State RequestedHostTransition=$host_transition_state", $callback, $node) if ($xcatdebugmode);
if (defined $status_info{RPOWER_STATUS_RESPONSE}{argv} and $status_info{RPOWER_STATUS_RESPONSE}{argv} =~ /bmcstate$/) {
my $bmc_node = "$node BMC";
my $bmc_short_state = (split(/\./, $bmc_state))[-1];
xCAT::SvrUtils::sendmsg($bmc_short_state, $callback, $bmc_node);
xCAT::SvrUtils::sendmsg("BMC $bmc_short_state", $callback, $node);
} else {
if ($chassis_state =~ /Off$/) {
xCAT::SvrUtils::sendmsg("$::POWER_STATE_OFF", $callback, $node);
@@ -1229,9 +1303,10 @@ sub rpower_response {
if ($host_state =~ /Off$/) {
# State is off, but check if it is transitioning
if ($host_transition_state =~ /On$/) {
xCAT::SvrUtils::sendmsg("$::POWER_STATE_POWERING_ON", $callback, $node);
}
else {
#xCAT::SvrUtils::sendmsg("$::POWER_STATE_POWERING_ON", $callback, $node);
# ignore transition state until get stable firmware
xCAT::SvrUtils::sendmsg("$::POWER_STATE_OFF", $callback, $node);
} else {
xCAT::SvrUtils::sendmsg("$::POWER_STATE_OFF", $callback, $node);
}
} elsif ($host_state =~ /Quiesced$/) {
@@ -1239,9 +1314,10 @@ sub rpower_response {
} elsif ($host_state =~ /Running$/) {
# State is on, but check if it is transitioning
if ($host_transition_state =~ /Off$/) {
xCAT::SvrUtils::sendmsg("$::POWER_STATE_POWERING_OFF", $callback, $node);
}
else {
#xCAT::SvrUtils::sendmsg("$::POWER_STATE_POWERING_OFF", $callback, $node);
# ignore transition state until get stable firmware
xCAT::SvrUtils::sendmsg("$::POWER_STATE_ON", $callback, $node);
} else {
xCAT::SvrUtils::sendmsg("$::POWER_STATE_ON", $callback, $node);
}
} else {
@@ -1310,15 +1386,23 @@ sub rinv_response {
my $purpose_value = uc ((split(/\./, $content{Purpose}))[-1]);
$purpose_value = "[$sw_id]$purpose_value";
my $activation_value = (split(/\./, $content{Activation}))[-1];
my $priority_value = -1;
if (defined($content{Priority})) {
$priority_value = $content{Priority};
}
#
# For 'rinv firm', only print Active software, unless verbose is specified
#
if ($activation_value =~ "Active" or $::VERBOSE) {
if (($activation_value =~ "Active" and $priority_value == 0) or $::VERBOSE) {
#
# The space below between "Firmware Product Version:" and $content{Version} is intentional
# to cause the sorting of this line before any additional info lines
#
$content_info = "$purpose_value Firmware Product: $content{Version} ($activation_value)";
if ($priority_value == 0) {
# For now, indicate priority 0 software levels with an '*'
$content_info .= "*";
}
push (@sorted_output, $content_info);
if (defined($content{ExtendedVersion}) and $content{ExtendedVersion} ne "") {
@@ -1334,8 +1418,8 @@ sub rinv_response {
}
} else {
if (! defined $content{Present}) {
# This should never happen, but if we find this, contact firmware team to fix...
xCAT::SvrUtils::sendmsg("ERROR: Invalid data for $key_url, contact firmware team!", $callback, $node);
# If the Present field is not part of the attribute, then it's most likely a callout
# Do not print as part of the inventory response
next;
}
@@ -1525,29 +1609,38 @@ sub reventlog_response {
} else {
my ($entry_string, $option_s) = split(",", $status_info{REVENTLOG_RESPONSE}{argv});
my $content_info;
my %output_s = () if ($option_s);
my %output = ();
my $entry_num = 0;
$entry_string = "all" if ($entry_string eq "0");
$entry_num = 0 + $entry_string if ($entry_string ne "all");
foreach my $key_url (keys %{$response_info->{data}}) {
my %content = %{ ${ $response_info->{data} }{$key_url} };
my $timestamp = $content{Timestamp};
my $id_num = 0 + $content{Id} if ($content{Id});
if (($entry_string eq "all" or ($id_num and ($entry_num ge $id_num))) and $content{Message}) {
my $content_info = $content{Timestamp} . " " . $content{Message};
if ($option_s) {
$output_s{$id_num} = $content_info;
$entry_num = $id_num if ($entry_num < $id_num);
} else {
xCAT::SvrUtils::sendmsg("$content_info", $callback, $node);
}
if ($content{Message}) {
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($content{Timestamp}/1000);
$mon += 1;
$year += 1900;
my $UTC_time = sprintf ("%02d/%02d/%04d %02d:%02d:%02d", $mon, $mday, $year, $hour, $min, $sec);
my $content_info = $UTC_time . " [$content{Id}] " . $content{Message};
$output{$timestamp} = $content_info;
}
}
if (%output_s) {
for (my $key = $entry_num; $key >= 1; $key--) {
xCAT::SvrUtils::sendmsg("$output_s{$key}", $callback, $node) if ($output_s{$key});
}
my $count = 0;
if ($option_s) {
foreach my $key ( sort { $b <=> $a } keys %output) {
xCAT::MsgUtils->message("I", { data => [$output{$key}] }, $callback, $node) if ($output{$key});
$count++;
last if ($entry_string ne "all" and $count >= $entry_num);
}
} else {
foreach my $key (sort keys %output) {
xCAT::MsgUtils->message("I", { data => [$output{$key}] }, $callback, $node) if ($output{$key});
$count++;
last if ($entry_string ne "all" and $count >= $entry_num);
}
}
}
@@ -1582,6 +1675,7 @@ sub rspconfig_response {
my $gateway = "n/a";
my $prefix = "n/a";
my $vlan = "n/a";
my $hostname = "";
my $default_gateway = "n/a";
my $adapter_id = "n/a";
my $error;
@@ -1595,6 +1689,9 @@ sub rspconfig_response {
if (defined($content{DefaultGateway}) and $content{DefaultGateway}) {
$default_gateway = $content{DefaultGateway};
}
if (defined($content{HostName}) and $content{HostName}) {
$hostname = $content{HostName};
}
}
@@ -1640,11 +1737,25 @@ sub rspconfig_response {
if ($grep_string =~ "vlan") {
push @output, "BMC VLAN ID enabled: $vlan";
}
if ($grep_string =~ "hostname") {
push @output, "BMC Hostname: $hostname";
}
}
xCAT::SvrUtils::sendmsg("$_", $callback, $node) foreach (@output);
}
if ($node_info{$node}{cur_status} eq "RSPCONFIG_SET_RESPONSE") {
if ($response_info->{'message'} eq $::RESPONSE_OK) {
xCAT::SvrUtils::sendmsg("BMC Setting Hostname (requires bmcreboot to take effect)...", $callback, $node);
}
}
if ($node_info{$node}{cur_status} eq "RSPCONFIG_DHCP_RESPONSE") {
if ($response_info->{'message'} eq $::RESPONSE_OK) {
xCAT::SvrUtils::sendmsg("BMC Setting IP to DHCP...", $callback, $node);
}
}
if ($next_status{ $node_info{$node}{cur_status} }) {
$node_info{$node}{cur_status} = $next_status{ $node_info{$node}{cur_status} };
gen_send_request($node);
@@ -1692,6 +1803,15 @@ sub rspconfig_sshcfg_response {
if (@$output[0] == 1) {
xCAT::SvrUtils::sendmsg("Error copying ssh keys to $bmcip:\n" . @$output[1], $callback, $node);
}
# For unknown reason, "echo" command above can fail (1 in 5), but return code 0 still returned.
# There is nothing we can do but to just test if authorized_keys file was not created
# and ask the user to rerun the command
my $file_test_output = xCAT::RShellAPI::run_remote_shell_api($bmcip, $userid, $userpw, 0, 0, "[ ! -f ~/.ssh/authorized_keys ] && uptime");
if (@$file_test_output[1] =~ "load average") {
# If file was not there, we run "uptime" command and then look for "load average" in the output.
# If file was there, "uptime" command is not executed
xCAT::SvrUtils::sendmsg("Error copying ssh keys to $bmcip Rerun rspconfig command.", $callback, $node);
}
else {
xCAT::SvrUtils::sendmsg("ssh keys copied to $bmcip", $callback, $node);
}
@@ -1725,9 +1845,6 @@ sub rvitals_response {
my $src;
my $content_info;
my @sorted_output;
xCAT::SvrUtils::sendmsg("$flag_debug Processing command: rvitals $grep_string", $callback, $node) if ($xcatdebugmode);
print Dumper(%{$response_info->{data}});
foreach my $key_url (keys %{$response_info->{data}}) {
my %content = %{ ${ $response_info->{data} }{$key_url} };
@@ -1809,8 +1926,6 @@ sub rflash_response {
my $response_info = decode_json $response->content;
print Dumper(%{$response_info->{data}});
my $update_id;
my $update_activation = "Unknown";
my $update_purpose;
@@ -1829,6 +1944,10 @@ sub rflash_response {
if (defined($content{Version}) and $content{Version}) {
$update_version = $content{Version};
}
else {
# Entry has no Version attribute, skip listing it
next;
}
if (defined($content{Activation}) and $content{Activation}) {
$update_activation = (split(/\./, $content{Activation}))[ -1 ];
}
@@ -1860,18 +1979,19 @@ sub rflash_response {
# curl commands
my $curl_login_cmd = "curl -c cjar -k -H 'Content-Type: application/json' -X POST $request_url/login -d '" . $content_login . "'";
my $curl_logout_cmd = "curl -b cjar -k -H 'Content-Type: application/json' -X POST $request_url/logout -d '" . $content_logout . "'";
my $curl_upload_cmd = "curl -b cjar -k -H 'Content-Type: application/octet-stream' -X PUT -T $::UPLOAD_FILE $request_url/upload/image/";
my $curl_upload_cmd = "curl -b cjar -k -H 'Content-Type: application/octet-stream' -X PUT -T " . $::UPLOAD_FILE . " $request_url/upload/image/";
# Try to login
my $curl_login_result = `$curl_login_cmd`;
my $h = from_json($curl_login_result); # convert command output to hash
if ($h->{message} eq $::RESPONSE_OK) {
# Login successfull, upload the file
xCAT::SvrUtils::sendmsg("Uploading $::UPLOAD_FILE ...", $callback, $node);
my $curl_upload_result = `$curl_upload_cmd`;
$h = from_json($curl_upload_result); # convert command output to hash
if ($h->{message} eq $::RESPONSE_OK) {
# Upload successfull
xCAT::SvrUtils::sendmsg("Update file $::UPLOAD_FILE successfully uploaded", $callback, $node);
xCAT::SvrUtils::sendmsg("Successful, use -l option to list.", $callback, $node);
# Try to logoff, no need to check result, as there is nothing else to do if failure
my $curl_logout_result = `$curl_logout_cmd`;
}
@@ -1921,7 +2041,7 @@ sub rflash_response {
}
else {
# Activation state of active and priority of non 0 - need to just set priority to 0 to activate
print "Update is already active, just need to set priority to 0";
print "Update is already active, just need to set priority to 0\n";
$next_status{ $node_info{$node}{cur_status} } = "RFLASH_SET_PRIORITY_REQUEST";
}
}
@@ -1936,6 +2056,42 @@ sub rflash_response {
}
if ($node_info{$node}{cur_status} eq "RFLASH_UPDATE_CHECK_ID_RESPONSE") {
my $activation_state;
my $progress_state;
my $priority_state;
# Look through all the software entries and find the id of the one that matches
# the version of the uploaded file. Once found, set up request/response hash entries
# to activate that image.
foreach my $key_url (keys %{$response_info->{data}}) {
my %content = %{ ${ $response_info->{data} }{$key_url} };
$update_id = (split(/\//, $key_url))[ -1 ];
if (defined($content{Version}) and $content{Version}) {
$update_version = $content{Version};
}
if ($update_version eq $::UPLOAD_FILE_VERSION) {
# Found a match of uploaded file version with the image in software/enumerate
# Set the image id for the activation request
$status_info{RFLASH_UPDATE_ACTIVATE_REQUEST}{init_url} .= "/$update_id/attr/RequestedActivation";
$status_info{RFLASH_UPDATE_CHECK_STATE_REQUEST}{init_url} .= "/$update_id";
$status_info{RFLASH_SET_PRIORITY_REQUEST}{init_url} .= "/$update_id/attr/Priority";
# Set next steps to activate the image
$next_status{ $node_info{$node}{cur_status} } = "RFLASH_UPDATE_ACTIVATE_REQUEST";
$next_status{"RFLASH_UPDATE_ACTIVATE_REQUEST"} = "RFLASH_UPDATE_ACTIVATE_RESPONSE";
$next_status{"RFLASH_UPDATE_ACTIVATE_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST";
$next_status{"RFLASH_UPDATE_CHECK_STATE_REQUEST"} = "RFLASH_UPDATE_CHECK_STATE_RESPONSE";
$next_status{"RFLASH_SET_PRIORITY_REQUEST"} = "RFLASH_SET_PRIORITY_RESPONSE";
$next_status{"RFLASH_SET_PRIORITY_RESPONSE"} = "RFLASH_UPDATE_CHECK_STATE_REQUEST";
last;
}
}
}
if ($node_info{$node}{cur_status} eq "RFLASH_DELETE_IMAGE_RESPONSE") {
xCAT::SvrUtils::sendmsg("Firmware update successfully removed", $callback, $node);
}
+2 -3
View File
@@ -484,7 +484,7 @@ sub process_request {
unlink glob("$destdir/rootimg.*");
if ($method =~ /cpio/) {
if (!$exlistloc) {
if (!$excludestr) {
$excludestr = "find . -xdev -print0 | cpio -H newc -o -0 | $compress -c - > ../rootimg.$suffix";
} else {
chdir("$rootimg_dir");
@@ -505,7 +505,7 @@ sub process_request {
if ($checkoption2 !~ /unrecognized/) {
$option .= "--selinux ";
}
if (!$exlistloc) {
if (!$excludestr) {
$excludestr = "find . -xdev -print0 | tar $option --no-recursion --use-compress-program=$compress --null -T - -cf ../rootimg.$suffix";
} else {
chdir("$rootimg_dir");
@@ -526,7 +526,6 @@ sub process_request {
}
$excludestr = "cat $xcat_packimg_tmpfile|cpio -dump $temppath";
}
chdir("$rootimg_dir");
my $outputmsg = `$excludestr 2>&1`;
unless($?){
+245 -29
View File
@@ -7,6 +7,7 @@
Supported command:
rpower
rinv
rvitals
=cut
@@ -63,6 +64,7 @@ sub handled_commands
return {
rpower => ["nodehm:mgt","pduoutlet:pdu=\.\*"],
rinv => ["nodehm:mgt"],
rvitals => ["nodehm:mgt"],
nodeset => ["nodehm:mgt"],
rspconfig => ["nodehm:mgt"],
pdudiscover => "pdu",
@@ -138,11 +140,13 @@ sub process_request
#fill in the total outlet count for each pdu
$pdutab = xCAT::Table->new('pdu');
@pduents = $pdutab->getAllNodeAttribs(['node', 'outlet']);
fill_outletCount(\@pduents, $callback);
#fill_outletCount(\@pduents, $callback);
if( $command eq "rinv") {
#for higher performance, handle node in batch
return powerstat($noderange, $callback);
return showMFR($noderange, $callback);
}elsif ($command eq "rvitals") {
return showMonitorData($noderange, $callback);
}elsif ($command eq "rpower") {
my $subcmd = $exargs[0];
if (($subcmd eq 'pduoff') || ($subcmd eq 'pduon') || ($subcmd eq 'pdustat')|| ($subcmd eq 'pdureset') ){
@@ -177,6 +181,8 @@ sub process_request
my $subcmd = $exargs[0];
if ($subcmd eq 'sshcfg') {
process_sshcfg($noderange, $subcmd, $callback);
}elsif ($subcmd =~ /ip|netmask|hostname/) {
process_netcfg($request, $subreq, $subcmd, $callback);
} else {
$callback->({ errorcode => [1],error => "The input $command $subcmd is not support for pdu"});
}
@@ -467,14 +473,130 @@ sub connectTopdu {
}
#-------------------------------------------------------
=head3 process_netcfg
Config hostname of PDU
Config ip/netmask of PDU via PduManager command
PduManager is a tool for CoralPdu to manager the PDU.
* /dev/shm/bin/PduManager -h
'-i' set PDU system IP
'-n' set system ip netmask. e.g.:PduManager -i xxx.xxx.xxx.xxx -n xxx.xxx.xxx.xxx
example: rspconfig coralpdu hostname=coralpdu
rspconfig coralpdu ip=1.1.1.1 netmask=255.0.0.0
=cut
#-------------------------------------------------------
sub process_netcfg {
my $request = shift;
my $subreq = shift;
my $subcmd = shift;
my $callback = shift;
my $hostname;
my $ip;
my $netmask;
my $args;
my $exp;
my $errstr;
my $extrargs = $request->{arg};
my @exargs = ($request->{arg});
if (ref($extrargs)) {
@exargs = @$extrargs;
}
my $nodes = $request->{node};
my $node_number = @$nodes;
if ($node_number gt "1") {
xCAT::SvrUtils::sendmsg("Can not configure more than 1 nodes", $callback);
return;
}
my $pdu = @$nodes[0];
my $rsp = {};
my $nodetab = xCAT::Table->new('hosts');
my $nodehash = $nodetab->getNodesAttribs($nodes,['ip','otherinterfaces']);
# connect to PDU
my $static_ip = $nodehash->{$pdu}->[0]->{ip};
my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces};
($exp, $errstr) = session_connect($static_ip, $discover_ip);
if (defined $errstr) {
xCAT::SvrUtils::sendmsg("Failed to connect", $callback);
return;
}
foreach my $cmd (@exargs) {
my ($key, $value) = split(/=/, $cmd);
if ($key =~ /hostname/) {
$hostname = $value;
my ($ret, $err) = session_exec($exp, "echo $hostname > /etc/hostname;/etc/init.d/hostname.sh");
if (defined $err) {
xCAT::SvrUtils::sendmsg("Failed to set hostname", $callback);
}
}elsif ($key =~ /ip/) {
$ip = $value;
} elsif ($key =~ /netmask/) {
$netmask = $value;
} else {
xCAT::SvrUtils::sendmsg("rspconfig $cmd is not support yet, ignored", $callback);
}
}
$args = "/dev/shm/bin/PduManager ";
my $opt;
if ($ip) {
$opt = "-i $ip ";
}
if ($netmask) {
$opt = $opt . "-n $netmask";
}
if ($opt) {
my $dshcmd = $args . $opt ;
my ($ret, $err) = session_exec($exp, $dshcmd);
if (defined $err) {
#session will be hung if ip address changed
my $p = Net::Ping->new();
if ( ($p->ping($ip)) && ($err =~ /TIMEOUT/) ) {
xCAT::SvrUtils::sendmsg("$ip is reachable", $callback);
} else {
xCAT::SvrUtils::sendmsg("Failed to run $dshcmd, error=$err", $callback);
return;
}
}
xCAT::SvrUtils::sendmsg("$dshcmd ran successfully", $callback);
xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$pdu,"ip=$ip","otherinterfaces="] }, $subreq, 0, 1);
xCAT::Utils->runxcmd({ command => ['makehosts'], node => [$pdu] }, $subreq, 0, 1);
}
if (defined $exp) {
$exp->hard_close();
}
}
#-------------------------------------------------------
=head3 process_sshcfg
Config passwordless for coralpdu
example: rspconfig coralpdu sshcfg
=cut
#-------------------------------------------------------
sub process_sshcfg {
my $noderange = shift;
my $subcmd = shift;
my $callback = shift;
#this is default password for CoralPDU
my $password = "password8";
my $userid = "root";
my $timeout = 10;
my $timeout = 30;
my $keyfile = "/root/.ssh/id_rsa.pub";
my $rootkey = `cat /root/.ssh/id_rsa.pub`;
my $cmd;
@@ -492,20 +614,7 @@ sub process_sshcfg {
my $static_ip = $nodehash->{$pdu}->[0]->{ip};
my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces};
my $ssh_ip;
my $p = Net::Ping->new();
if ($p->ping($static_ip)) {
$ssh_ip = $static_ip;
} elsif ($p->ping($discover_ip)) {
$ssh_ip = $discover_ip;
} else {
$msg = " is not reachable";
xCAT::SvrUtils::sendmsg($msg, $callback, $pdu, %allerrornodes);
next;
}
my ($exp, $errstr) = session_connect($ssh_ip, $userid, $password, $timeout);
my ($exp, $errstr) = session_connect($static_ip, $discover_ip);
if (!defined $exp) {
$msg = " Failed to connect $errstr";
xCAT::SvrUtils::sendmsg($msg, $callback, $pdu, %allerrornodes);
@@ -519,10 +628,6 @@ sub process_sshcfg {
($ret, $err) = session_exec($exp, "chmod 700 /home/root/.ssh");
($ret, $err) = session_exec($exp, "echo \"$rootkey\" >/home/root/.ssh/authorized_keys");
($ret, $err) = session_exec($exp, "chmod 644 /home/root/.ssh/authorized_keys");
#config dhcp ip address to static
if ($ssh_ip eq $discover_ip) {
# ($ret, $err) = session_exec($exp, "ifconfig eth0 $static_ip");
}
$exp->hard_close();
}
@@ -531,14 +636,27 @@ sub process_sshcfg {
}
sub session_connect {
my $server = shift;
my $userid = shift;
my $password = shift;
my $timeout = shift;
my $static_ip = shift;
my $discover_ip = shift;
my $ssh = Expect->new;
my $command = 'ssh';
my @parameters = ($userid . "@" . $server);
#default password for coral pdu
my $password = "password8";
my $userid = "root";
my $timeout = 30;
my $ssh_ip;
my $p = Net::Ping->new();
if ($p->ping($static_ip)) {
$ssh_ip = $static_ip;
} elsif ($p->ping($discover_ip)) {
$ssh_ip = $discover_ip;
} else {
return(undef, " is not reachable\n");
}
my $ssh = Expect->new;
my $command = 'ssh';
my @parameters = ($userid . "@" . $ssh_ip);
$ssh->debug(0);
$ssh->log_stdout(0); # suppress stdout output..
@@ -571,7 +689,7 @@ sub session_exec {
my $timeout = shift;
my $prompt = shift;
$timeout = 10 unless defined $timeout;
$timeout = 30 unless defined $timeout;
$prompt = qr/.*#/ unless defined $prompt;
@@ -585,6 +703,18 @@ sub session_exec {
return($mbmatch);
}
#-----------------------------------------------------------------
=head3 process_pdudiscover
Discover the pdu for a given range of DHCP ip address
it will call switchdiscover command with -s snmp --pdu options
example: pdudiscover --range iprange -w
=cut
#------------------------------------------------------------------
sub process_pdudiscover {
my $request = shift;
my $sub_req = shift;
@@ -615,10 +745,96 @@ sub process_pdudiscover {
my $rsp = {};
push @{ $rsp->{data} }, "$result";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
#-------------------------------------------------------
=head3 showMFR
show MFR information of PDU via PduManager command
PduManager is a tool for CoralPdu to manager the PDU.
* /dev/shm/bin/PduManager -h
'-m' show MFR info
example: rinv coralpdu
=cut
#-------------------------------------------------------
sub showMFR {
my $noderange = shift;
my $callback = shift;
my $output;
my $nodetab = xCAT::Table->new('hosts');
my $nodehash = $nodetab->getNodesAttribs($noderange,['ip','otherinterfaces']);
foreach my $pdu (@$noderange) {
# connect to PDU
my $static_ip = $nodehash->{$pdu}->[0]->{ip};
my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces};
my ($exp, $errstr) = session_connect($static_ip, $discover_ip);
if (defined $errstr) {
xCAT::SvrUtils::sendmsg("Failed to connect: $errstr", $callback);
}
my ($ret, $err) = session_exec($exp, "/dev/shm/bin/PduManager -m");
if (defined $err) {
xCAT::SvrUtils::sendmsg("Failed to list MFR information: $err", $callback);
}
if (defined $ret) {
xCAT::SvrUtils::sendmsg("$ret", $callback);
}
$exp->hard_close();
}
}
#-------------------------------------------------------
=head3 showMonitorData
Show realtime monitor data(input voltage, current, power)
of PDU via PduManager command
PduManager is a tool for CoralPdu to manager the PDU.
* /dev/shm/bin/PduManager -h
'-d' show realtime monitor data(input voltage, current, power)
example: rvitals coralpdu
=cut
#-------------------------------------------------------
sub showMonitorData {
my $noderange = shift;
my $callback = shift;
my $output;
my $nodetab = xCAT::Table->new('hosts');
my $nodehash = $nodetab->getNodesAttribs($noderange,['ip','otherinterfaces']);
foreach my $pdu (@$noderange) {
# connect to PDU
my $static_ip = $nodehash->{$pdu}->[0]->{ip};
my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces};
my ($exp, $errstr) = session_connect($static_ip, $discover_ip);
my $ret;
my $err;
($ret, $err) = session_exec($exp, "/dev/shm/bin/PduManager -d");
if (defined $err) {
xCAT::SvrUtils::sendmsg("Failed to show monitor data: $err", $callback);
}
if (defined $ret) {
xCAT::SvrUtils::sendmsg("$ret", $callback,$pdu);
}
$exp->hard_close();
}
}
1;
+1 -1
View File
@@ -656,7 +656,7 @@ sub process_request {
}
if ($do_dhcpsetup) {
my @parameter;
push @parameter, '-l' if ($::request->{'_disparatetftp'}->[0]);
push @parameter, '-l' if ($request->{'_disparatetftp'}->[0]);
xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue makedhcp request");
$sub_req->({ command => ['makedhcp'],
+8
View File
@@ -166,6 +166,14 @@ sub rinstall {
return 1;
}
if($command eq "rinstall" and scalar(@nodes) > 1 and $CONSOLE){
my $rsp;
$rsp->{errorcode}->[0]=1;
$rsp->{error}->[0]="rinstall -c/--console can only be run against one node! Please use winstall -c/--console for multiple nodes.";
xCAT::MsgUtils->message("E",$rsp,$callback);
return 1;
}
my $rc = 0;
my @parameter;
+4 -2
View File
@@ -100,6 +100,8 @@ sub mknetboot
$nodestatus = $t_entry;
}
my @myself = xCAT::NetworkUtils->determinehostname();
my $myname = $myself[ (scalar @myself) - 1 ];
#}
my $ntents = $ostab->getNodesAttribs($req->{node}, [ 'os', 'arch', 'profile', 'provmethod' ]);
@@ -333,7 +335,7 @@ sub mknetboot
if ($statelite) {
unless (-r "$rootimgdir/kernel") {
$callback->({
error => [qq{Did you run "genimage" before running "liteimg"? kernel cannot be found}],
error => [qq{Did you run "genimage" before running "liteimg"? kernel cannot be found at $rootimgdir/kernel on $myname}],
errorcode => [1]
});
next;
@@ -362,7 +364,7 @@ sub mknetboot
} else {
unless (-r "$rootimgdir/kernel") {
$callback->({
error => [qq{Did you run "genimage" before running "packimage"? kernel cannot be found}],
error => [qq{Did you run "genimage" before running "packimage"? kernel cannot be found at $rootimgdir/kernel on $myname}],
errorcode => [1]
});
next;
+1 -1
View File
@@ -251,7 +251,7 @@ sub process_request {
$cb->({ node => [ { name => $switch, data => ["PASS"] } ] });
next;
}
foreach my $port (sort keys %{ $macinfo->{$switch} }) {
foreach my $port (map{$_->[0]}sort{$a->[1] cmp $b->[1] || $a->[2] <=> $b->[2]}map{[$_, /^(.*?)(\d+)?$/]} keys %{ $macinfo->{$switch} }) {
my $node = '';
if (defined($macinfo->{$switch}->{$port}->{Node})) {
$node = $macinfo->{$switch}->{$port}->{Node};
+35 -3
View File
@@ -407,7 +407,7 @@ sub process_request {
}
if (!($result)) {
send_msg( \%request, 0, " No switch found ");
send_msg( \%request, 0, " No $device found ");
return;
}
@@ -1404,15 +1404,18 @@ sub matchPredefineSwitch {
}
my $stype = get_switchtype($vendor);
if (exists($globalopt{pdu})) {
$stype="pdu";
}
send_msg($request, 0, "$device discovered and matched: $dswitch to $node" );
# only write to xcatdb if -w or --setup option specified
if ( (exists($globalopt{w})) || (exists($globalopt{setup})) ) {
if (exists($globalopt{pdu})) {
xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$node,"otherinterfaces=$ip",'status=Matched',"mac=$mac","switchtype=$stype","usercomment=$vendor"] }, $sub_req, 0, 1);
xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$node,"otherinterfaces=$ip",'status=Matched',"mac=$mac","usercomment=$vendor"] }, $sub_req, 0, 1);
} else {
xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$node,"otherinterfaces=$ip",'status=Matched',"mac=$mac","switchtype=$stype","usercomment=$vendor","switchtype=$stype"] }, $sub_req, 0, 1);
xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$node,"otherinterfaces=$ip",'status=Matched',"mac=$mac","switchtype=$stype","usercomment=$vendor"] }, $sub_req, 0, 1);
}
}
@@ -1436,6 +1439,35 @@ sub switchsetup {
my $request = shift;
my $sub_req = shift;
if (exists($globalopt{pdu})) {
my $mytype = "pdu";
my $nodetab = xCAT::Table->new('hosts');
my $nodehash = $nodetab->getNodesAttribs(\@{${nodes_to_config}->{$mytype}},['ip','otherinterfaces']);
# get netmask from network table
my $nettab = xCAT::Table->new("networks");
my @nets;
if ($nettab) {
@nets = $nettab->getAllAttribs('net','mask');
}
foreach my $pdu(@{${nodes_to_config}->{$mytype}}) {
my $cmd = "rspconfig $pdu sshcfg";
xCAT::Utils->runcmd($cmd, 0);
my $ip = $nodehash->{$pdu}->[0]->{ip};
my $mask;
foreach my $net (@nets) {
if (xCAT::NetworkUtils::isInSameSubnet( $net->{'net'}, $ip, $net->{'mask'}, 0)) {
$mask=$net->{'mask'};
}
}
$cmd = "rspconfig $pdu hostname=$pdu ip=$ip netmask=$mask";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC == 0) {
xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$pdu,"ip=$ip","otherinterfaces="] }, $sub_req, 0, 1);
} else {
send_msg($request, 0, "Failed to run rspconfig command to set ip/netmask\n");
}
}
return;
}
@@ -1791,11 +1791,17 @@ sub updatenodesyncfiles
if ($request->{SNFileSyncing}->[0] eq "yes") {
my $rsp = {};
$rsp->{data}->[0] = "File synchronization has completed for service nodes.";
if (@::FAILEDNODES) {
$rsp->{errorcode}->[0] = 1;
}
$callback->($rsp);
}
if ($request->{FileSyncing}->[0] eq "yes") {
my $rsp = {};
$rsp->{data}->[0] = "File synchronization has completed for nodes.";
if (@::FAILEDNODES) {
$rsp->{errorcode}->[0] = 1;
}
$callback->($rsp);
}
}
+1 -1
View File
@@ -711,7 +711,7 @@ sub process_request {
}
if ($do_dhcpsetup) {
my @parameter;
push @parameter, '-l' if ($::request->{'_disparatetftp'}->[0]);
push @parameter, '-l' if ($::XNBA_request->{'_disparatetftp'}->[0]);
xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue makedhcp request");
$sub_req->({ command => ['makedhcp'],
+7 -12
View File
@@ -7,6 +7,8 @@ BEGIN
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use xCAT::NetworkUtils;
sub handled_commands {
return {
@@ -28,18 +30,11 @@ sub process_request {
#now, notify the node that its findme request has been processed
my $client_ip = $req->{'_xcat_clientip'};
xCAT::MsgUtils->message("S","Notify $client_ip that its findme request has been processed");
my $sock = new IO::Socket::INET(
PeerAddr => $client_ip,
PeerPort => '3001',
Timeout => '1',
Proto => 'tcp'
);
if ($sock) {
print $sock "processed";
close($sock);
}else{
xCAT::MsgUtils->message("S", "Failed to notify $client_ip that its findme request has been processed");
xCAT::MsgUtils->message("S","xcat.discovery.zzzdiscovery: Notify $client_ip that its findme request has been processed");
#notify the client that its request is been processing
my $ret=xCAT::NetworkUtils->send_tcp_msg($client_ip,3001,"processed");
if($ret){
xCAT::MsgUtils->message("S", "xcat.discovery.zzzdiscovery: Failed to notify $client_ip that its findme request has been processed");
}
}else{
xCAT::MsgUtils->message("S", "xcat.discovery.zzzdiscovery: ($req->{_xcat_clientmac}->[0]) Successfully discovered the node using $req->{discoverymethod}->[0] discovery method.");
+36 -54
View File
@@ -636,25 +636,9 @@ sub do_discovery_process {
$vintage = time();
} # site table reread every 15 second
my $data;
my $client;
my $clientn;
my $clientip;
if (ref $msg eq 'HASH') { $data = $msg->{data}; } else { die "incorrect code to disco"; }
my $saddr = $msg->{sockaddr};
if ($inet6support) {
($client, $sport) = Socket6::getnameinfo($saddr);
($clientip, $sport) = Socket6::getnameinfo($saddr, Socket6::NI_NUMERICHOST());
if ($clientip =~ /::ffff:.*\..*\./) {
$clientip =~ s/^::ffff://;
}
if ($client =~ /::ffff:.*\..*\./) {
$client =~ s/^::ffff://;
}
} else {
($sport, $clientn) = sockaddr_in($saddr);
$clientip = inet_ntoa($clientn);
$client = gethostbyaddr($clientn, AF_INET);
}
my $clientip = $msg->{sockaddr};
$sport=$msg->{sport};
if ($data =~ /^\037\213/) { # per rfc 1952, these two bytes are gzip, and they are invalid for
# xcatrequest xml, so go ahead and decompress it
my $bigdata;
@@ -663,12 +647,10 @@ sub do_discovery_process {
}
my $req = eval { XMLin($data, SuppressEmpty => undef, ForceArray => 1) };
if ($req and $req->{command} and ($req->{command}->[0] eq "findme" and $sport < 1000)) { # only consider priveleged port requests to start with
$req->{'_xcat_clienthost'} = $client;
$req->{'_xcat_clientip'} = $clientip;
$req->{'_xcat_clientport'} = $sport;
if (defined($cmd_handlers{"findme"}) and xCAT::NetworkUtils->nodeonmynet($clientip)) { # only discover from ips that appear to be on a managed network
xCAT::MsgUtils->message("S", "xcatd: Processing discovery request from " . $req->{'_xcat_clientip'});
# Using cacheonly will cause the discovery processing running 2 times, cacheonly seems useless for switch.pm, so remove it
#$req->{cacheonly}->[0] = 1;
#plugin_command($req,undef,\&build_response);
@@ -678,7 +660,7 @@ sub do_discovery_process {
#}
} else {
xCAT::MsgUtils->message("S", "xcatd: Skipping discovery from " . $client . " because we either have no discovery plugins or the client address does not match an IP network that xCAT is managing");
xCAT::MsgUtils->message("S", "xcatd: Skipping discovery from " . $clientip . " because we either have no discovery plugins or the client address does not match an IP network that xCAT is managing");
}
}
}
@@ -801,10 +783,33 @@ sub do_udp_service { # This function opens up a UDP port
foreach my $pkey (keys %packets) {
my $saddr = $packets{$pkey}->[0];
$data = $packets{$pkey}->[1];
my $sport;
my $clientip;
my $clientn;
if ($inet6support) {
($clientip, $sport) = Socket6::getnameinfo($saddr, Socket6::NI_NUMERICHOST());
if ($clientip =~ /::ffff:.*\..*\./) {
$clientip =~ s/^::ffff://;
}
} else {
($sport, $clientn) = sockaddr_in($saddr);
$clientip = inet_ntoa($clientn);
}
if ($data =~ /^\037\213/) { # per rfc 1952, these two bytes are gzip, and they are invalid for
store_fd({ data => $data, sockaddr => $saddr }, $discoctl); # for now, punt the gunzip to the worker process
store_fd({ data => $data, sockaddr => $clientip, sport => $sport }, $discoctl); # for now, punt the gunzip to the worker process
#notify the client that its request is been processing
my $ret=xCAT::NetworkUtils->send_tcp_msg($clientip,3001,"processing");
if($ret){
xCAT::MsgUtils->message("S", "INFO xcatd: fail to notify $clientip that its 'findme' request is been processing");
}
} elsif ($data =~ /^<xcat/) { # xml format
store_fd({ data => $data, sockaddr => $saddr }, $discoctl);
store_fd({ data => $data, sockaddr => $clientip, sport => $sport }, $discoctl);
#notify the client that its request is been processing
my $ret=xCAT::NetworkUtils->send_tcp_msg($clientip,3001,"processing");
if($ret){
xCAT::MsgUtils->message("S", "INFO xcatd: fail to notify $clientip that its 'findme' request is been processing");
}
} else { # for *now*, we'll do a tiny YAML subset
if ($data =~ /^resourcerequest: xcatd$/) {
$socket->send("ackresourcerequest\n", 0, $packets{$pkey}->[0]);
@@ -2436,35 +2441,12 @@ sub convey_response {
# sanitize the response, to avoid being killed by non-printable bytes
#$resp =~ tr/\011-\177/?/c;
# seeing if using utf-8 offloads potential issues to client terminal, it didn't
store_fd($resp, $parent_fd);
yield; # parent must get timeslice anyway before an ack could possibly return
my $parsel = new IO::Select;
$parsel->add($parent_fd);
my $selbits = $parsel->bits;
my $rsp;
while ($selbits && ($rsp = select($selbits, undef, undef, 5))) { # block up to five seconds
if ($quit) { # Obey quit flag
xexit 0;
}
if ($rsp == 0) { # This means the filedescriptor was removed
last;
}
if ($rsp < 0) { # A signal caused select to skip out, do-over
next;
}
# At this point, the only possibility is a positive return, meaning parent_fd requires attention of some sort
$rsp = <$parent_fd>;
if ($rsp) { # If data actually came in, last, otherwise, remove it from the IO::Select, but both should amount to the same thing
last;
} else {
$parsel->remove($parent_fd);
last;
}
eval {
store_fd($resp, $parent_fd);
};
if ($@) {
xCAT::MsgUtils->message("S", "Failed to store into socketpair: $@");
}
yield; # If still around, it means a peer process still hasn't gotten to us, so might as well yield
$selbits = $parsel->bits;
}
sub build_response {
@@ -2831,8 +2813,7 @@ sub service_connection {
my $myxcatver=xCAT::Version->Version();
if($req->{'_xcatver'}->[0] ne $myxcatver){
my $myhostname=Sys::Hostname::hostname;
my $resp = { warning => ["xCAT Version mismatch! \"$myxcatver\" on $myhostname does not match \"$req->{'_xcatver'}->[0]\" on $peerhost!"]};
$resp->{serverdone} = [undef];
my $resp = { warning => ["xCAT Version mismatch! \n $myhostname: $myxcatver\n $peerhost: $req->{'_xcatver'}->[0]\n"]};
send_response($resp, $sock);
}
}
@@ -2987,9 +2968,10 @@ sub relay_fds { # Relays file descriptors from pipes to children to the SSL sock
if ($@ and $@ =~ /^Magic number checking on storable file/) { # this most likely means we ran over the end of available input
$fds->remove($rfh);
close($rfh);
} elsif ($@) {
xCAT::MsgUtils->message("S", "Failed to retrieve from socketpair: $@");
} else {
push @$replyqueue, $resp;
print $rfh "nfin\n";
}
}
foreach my $rin ($clientselect->can_read(0)) {
+10 -2
View File
@@ -91,7 +91,15 @@ if ($ENV{SSHCONSOLEPORT}) {
$sshport= $ENV{SSHCONSOLEPORT};
}
print "If the console cannot connect, please verify whether ssh keys has been configured on the bmc for $username user\n";
# To automatically connect to the console without the need to send over the ssh keys,
# ensure sshpass is installed on the Management and/or Service Nodes.
if (-x '/usr/bin/sshpass') {
exec "/usr/bin/sshpass -p $password ssh -p $sshport -l $username $bmcip";
} else {
# This will prompt the user to enter the password for the BMC
# if ssh keys are not sent and sshpass is not being used
exec "ssh -p $sshport -l $username $bmcip";
}
exec "ssh -p $sshport -l $username $bmcip";
@@ -34,3 +34,7 @@ perl-DBD-Pg
wget
util-linux-ng
net-tools
pciutils
bind-utils
strace
tcpdump
@@ -59,7 +59,7 @@ do
mv $i/postscripts /xcatpost
rm -rf $i
chmod +x /xcatpost/*
/xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' | sed -e 's/&lt;/</g' -e 's/&gt;/>/g' -e 's/&amp;/\&/g' -e 's/&quot;/"/g' -e "s/&apos;/'/g" > /xcatpost/mypostscript
/xcatpost/getpostscript.awk |egrep '<data>' |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' | sed -e 's/&lt;/</g' -e 's/&gt;/>/g' -e 's/&amp;/\&/g' -e 's/&quot;/"/g' -e "s/&apos;/'/g" > /xcatpost/mypostscript
MYCONT=`grep MASTER /xcatpost/mypostscript`
MAX_RETRIES=10
RETRY=0
@@ -72,12 +72,12 @@ do
let SLI=$RANDOM%10+10
sleep $SLI
/xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' | sed -e 's/&lt;/</g' -e 's/&gt;/>/g' -e 's/&amp;/\&/g' -e 's/&quot;/"/g' -e "s/&apos;/'/g" > /xcatpost/mypostscript
/xcatpost/getpostscript.awk |egrep '<data>'|sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' | sed -e 's/&lt;/</g' -e 's/&gt;/>/g' -e 's/&amp;/\&/g' -e 's/&quot;/"/g' -e "s/&apos;/'/g" > /xcatpost/mypostscript
MYCONT=`grep MASTER /xcatpost/mypostscript`
done
chmod +x /xcatpost/mypostscript
chmod 700 /xcatpost/mypostscript
GOTIT=1
break
fi
@@ -47,7 +47,7 @@ do
chmod +x /xcatpost/*
# Get postscript to run on this node from xcat server
/xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /xcatpost/mypostscript
/xcatpost/getpostscript.awk |egrep '<data>'|sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /xcatpost/mypostscript
MYCONT=`grep MASTER /xcatpost/mypostscript`
MAX_RETRIES=10
RETRY=0
@@ -63,12 +63,12 @@ do
sleep $SLI
# Get postscript to run on this node from xcat server
/xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /xcatpost/mypostscript
/xcatpost/getpostscript.awk |egrep '<data>'|sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /xcatpost/mypostscript
MYCONT=`grep MASTER /xcatpost/mypostscript`
done
# Make executable
chmod +x /xcatpost/mypostscript
chmod 700 /xcatpost/mypostscript
GOTIT=1
break
fi
@@ -47,7 +47,7 @@ do
chmod +x /xcatpost/*
# Get postscript to run on this node from xcat server
/xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /xcatpost/mypostscript
/xcatpost/getpostscript.awk |egrep '<data>'|sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /xcatpost/mypostscript
MYCONT=`grep MASTER /xcatpost/mypostscript`
MAX_RETRIES=10
RETRY=0
@@ -63,12 +63,12 @@ do
sleep $SLI
# Get postscript to run on this node from xcat server
/xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /xcatpost/mypostscript
/xcatpost/getpostscript.awk |egrep '<data>'|sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /xcatpost/mypostscript
MYCONT=`grep MASTER /xcatpost/mypostscript`
done
# Make executable
chmod +x /xcatpost/mypostscript
chmod 700 /xcatpost/mypostscript
GOTIT=1
break
fi
@@ -52,7 +52,7 @@ do
chmod +x /xcatpost/*
# Get postscript to run on this node from xcat server
/xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript
/xcatpost/getpostscript.awk |egrep '<data>'|sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript
MYCONT=`grep MASTER /tmp/mypostscript`
MAX_RETRIES=10
RETRY=0
@@ -67,12 +67,12 @@ do
sleep $SLI
# Get postscript to run on this node from xcat server
/xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript
/xcatpost/getpostscript.awk |egrep '<data>'|sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript
MYCONT=`grep MASTER /tmp/mypostscript`
done
# Make executable
chmod +x /tmp/mypostscript
chmod 700 /tmp/mypostscript
GOTIT=1
break
fi
@@ -53,7 +53,7 @@ do
chmod +x /xcatpost/*
# Get postscript to run on this node from xcat server
/xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript
/xcatpost/getpostscript.awk |egrep '<data>'|sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript
MYCONT=`grep MASTER /tmp/mypostscript`
MAX_RETRIES=10
RETRY=0
@@ -68,12 +68,12 @@ do
sleep $SLI
# Get postscript to run on this node from xcat server
/xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript
/xcatpost/getpostscript.awk |egrep '<data>'|sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript
MYCONT=`grep MASTER /tmp/mypostscript`
done
# Make executable
chmod +x /tmp/mypostscript
chmod 700 /tmp/mypostscript
GOTIT=1
break
fi
@@ -116,7 +116,7 @@ if [ "$?" = "0" ]; then
msgutil_r "$MASTER_IP" "debug" "precreated mypostscript downloaded successfully" "/var/log/xcat/xcat.log"
fi
mv /xcatpost/mypostscript.$NODE /xcatpost/mypostscript
chmod +x /xcatpost/mypostscript
chmod 700 /xcatpost/mypostscript
fi
USEOPENSSLFORXCAT=1 #Though this is the only method going forward, flag to allow backward compatibility with 2.2 generated netboot images
@@ -138,7 +138,7 @@ if [ ! -x /xcatpost/mypostscript ]; then
/tmp/updateflag $MASTER $XCATIPORT "installstatus failed"
sleep 36500d
fi
/xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' | sed -e 's/&lt;/</g' -e 's/&gt;/>/g' -e 's/&amp;/\&/g' -e 's/&quot;/"/g' -e "s/&apos;/'/g" > /xcatpost/mypostscript
/xcatpost/getpostscript.awk |egrep '<data>'|sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' | sed -e 's/&lt;/</g' -e 's/&gt;/>/g' -e 's/&amp;/\&/g' -e 's/&quot;/"/g' -e "s/&apos;/'/g" > /xcatpost/mypostscript
MYCONT=`grep ^MASTER= /xcatpost/mypostscript`
RETRY=0
@@ -150,7 +150,7 @@ if [ ! -x /xcatpost/mypostscript ]; then
let SLI=$RANDOM%10+10
sleep $SLI
/xcatpost/getpostscript.awk |sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' | sed -e 's/&lt;/</g' -e 's/&gt;/>/g' -e 's/&amp;/\&/g' -e 's/&quot;/"/g' -e "s/&apos;/'/g" > /xcatpost/mypostscript
/xcatpost/getpostscript.awk |egrep '<data>'|sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' | sed -e 's/&lt;/</g' -e 's/&gt;/>/g' -e 's/&amp;/\&/g' -e 's/&quot;/"/g' -e "s/&apos;/'/g" > /xcatpost/mypostscript
MYCONT=`grep ^MASTER= /xcatpost/mypostscript`
done
@@ -404,7 +404,7 @@ if [ \"\$return_value\" -ne \"0\" ]; then
fi
" >> /xcatpost/mypostscript
chmod 755 /xcatpost/mypostscript
chmod 700 /xcatpost/mypostscript
export ARCH=#TABLE:nodetype:THISNODE:arch#
export CONSOLEPORT=#TABLEBLANKOKAY:nodehm:THISNODE:serialport#
@@ -148,6 +148,25 @@ export CFGMGR
CFGSERVER=#TABLE:cfgmgt:$NODE:cfgserver#
export CFGSERVER
## Switch relate attributes for this node
SWITCHNAME=#TABLE:switches:$NODE:switch#
export SWITCHNAME
SNMPVERSION=#TABLE:switches:$NODE:snmpversion#
export SNMPVERSION
SNMPUSER=#TABLE:switches:$NODE:username#
export SNMPUSER
SNMPPASSWD=#TABLE:switches:$NODE:password#
export SNMPPASSWD
SNMPPRIV=#TABLE:switches:$NODE:privacy#
export SNMPPRIV
SNMPAUTH=#TABLE:switches:$NODE:auth#
export SNMPAUTH
#CFGMGTINFO_EXPORT#
#INCLUDE:/opt/xcat/share/xcat/mypostscript/mypostscript_cloud.tmpl#
@@ -0,0 +1,35 @@
./boot*
./usr/share/wallpapers/RHEL6/contents/images*
./usr/include*
./usr/lib/locale*
./usr/lib64/perl5/Encode/CN*
./usr/lib64/perl5/Encode/JP*
./usr/lib64/perl5/Encode/TW*
./usr/lib64/perl5/Encode/KR*
./lib/kbd/keymaps/i386*
./lib/kbd/keymaps/mac*
./lib/kdb/keymaps/include*
./usr/local/include*
./usr/local/share/man*
./usr/share/man*
./usr/share/cracklib*
./usr/share/doc*
./usr/share/doc/packages/cyrus-sasl/doc*
./usr/share/gnome*
./usr/share/i18n*
+./usr/share/i18n/en_US*
./usr/share/info*
./usr/share/locale/*
+./usr/share/locale/en_US*
+./usr/share/locale/C*
+./usr/share/locale/locale.alias
+./usr/lib/locale/locale-archive
+./usr/lib/locale/en*
./usr/share/man*
./usr/share/omf*
./usr/share/vim/site/doc*
./usr/share/vim/vim74/doc*
./usr/share/zoneinfo*
./var/cache/man*
./var/lib/yum*
./tmp*
@@ -0,0 +1,4 @@
xcat/xcat-core/xCATsn
xcat/xcat-dep/rh7/ppc64le/conserver-xcat
xcat/xcat-dep/rh7/ppc64le/perl-Net-Telnet
xcat/xcat-dep/rh7/ppc64le/perl-Expect
@@ -0,0 +1,48 @@
bash
bc
bind
bind-utils
busybox
bzip2
cronie
dhclient
dhcp
dracut
dracut-network
e2fsprogs
expect
gzip
httpd
iputils
irqbalance
kernel
ksh
lsvpd
mysql-connector-odbc
net-snmp-perl
nfs-utils
ntp
openssh-clients
openssh-server
openssl
parted
perl-DBD-MySQL
perl-DBD-Pg
perl-IO-Socket-SSL
perl-Net-Telnet
perl-XML-Parser
perl-XML-Simple
postgresql
postgresql-server
ppc64-utils
procps
rootfiles
rpm
rsync
tar
unixODBC
vim-minimal
vsftpd
wget
xz
rsyslog
@@ -0,0 +1,45 @@
#!/bin/sh
#-- Do not remove following line if you want to make use of CVS version tracking
#-- $Id: service.postinstall,v 1.21 2008/09/04 12:05:45 sikorsky Exp $
#-- jurij.sikorsky@t-systems.cz
#--
#-- this script is run after all packages from $profile.pkglist are installed
#--
#-- it gets these arguments:
#--
#-- $1 = install root (chroot directory for profile)
#-- $2 = OS version
#-- $3 = architecture
#-- $4 = profile name
#-- $5 = work dir (where genimage is located)
#--
#--
installroot=$1
osver=$2
arch=$3
profile=$4
workdir=$5
#-- Example how /etc/fstab can be automatically generated during image generation:
#cat <<END >$installroot/etc/fstab
#proc /proc proc rw 0 0
#sysfs /sys sysfs rw 0 0
#devpts /dev/pts devpts rw,gid=5,mode=620 0 0
#${profile}_${arch} / tmpfs rw 0 1
#none /tmp tmpfs defaults,size=10m 0 2
#none /var/tmp tmpfs defaults,size=10m 0 2
#END
#-- Uncomment the line contains "cons" in /etc/inittab
#cons:12345:respawn:/sbin/smart_agetty -L 38400 console
echo "co:2345:respawn:/sbin/agetty -L 38400 console" >> $installroot/etc/inittab
#-- Example of booted image versioning
#-- We want to know, with what configuration (version of the image) each node was booted.
#-- Hence, we keep image definition files and postscripts in CVS. During image generation we create file /etc/IMGVERSION and fill it with CVS "$Id$" of files with image definition (.pkglist, .exlist, .repolist, .postinstall). Then, during boot, each "CVS enabled" postscript (see /install/postscripts/cvs_template.sh and /install/postscripts/cvs_template.pl) adds one line to /etc/IMGVERSION. Then you can determine in any time what image you are running and what postscipts in which versions were run.
#cat /dev/null > $installroot/etc/IMGVERSION
#for ext in pkglist exlist postinstall repolist; do
# [ -r $workdir/$profile.$ext ] && cat $workdir/$profile.$ext | grep -E '^[[:space:]]*#.*[[:space:]]\$Id' >> $installroot/etc/IMGVERSION
#done
@@ -0,0 +1,35 @@
./boot*
./usr/share/wallpapers/RHEL6/contents/images*
./usr/include*
./usr/lib/locale*
./usr/lib64/perl5/Encode/CN*
./usr/lib64/perl5/Encode/JP*
./usr/lib64/perl5/Encode/TW*
./usr/lib64/perl5/Encode/KR*
./lib/kbd/keymaps/i386*
./lib/kbd/keymaps/mac*
./lib/kdb/keymaps/include*
./usr/local/include*
./usr/local/share/man*
./usr/share/man*
./usr/share/cracklib*
./usr/share/doc*
./usr/share/doc/packages/cyrus-sasl/doc*
./usr/share/gnome*
./usr/share/i18n*
+./usr/share/i18n/en_US*
./usr/share/info*
./usr/share/locale/*
+./usr/share/locale/en_US*
+./usr/share/locale/C*
+./usr/share/locale/locale.alias
+./usr/lib/locale/locale-archive
+./usr/lib/locale/en*
./usr/share/man*
./usr/share/omf*
./usr/share/vim/site/doc*
./usr/share/vim/vim74/doc*
./usr/share/zoneinfo*
./var/cache/man*
./var/lib/yum*
./tmp*
@@ -0,0 +1,4 @@
xcat/xcat-core/xCATsn
xcat/xcat-dep/rh7/x86_64/conserver-xcat
xcat/xcat-dep/rh7/x86_64/perl-Net-Telnet
xcat/xcat-dep/rh7/x86_64/perl-Expect
@@ -0,0 +1,47 @@
bash
bc
bind
bind-utils
busybox
bzip2
cronie
dhclient
dhcp
dracut
dracut-network
e2fsprogs
expect
gzip
httpd
iputils
irqbalance
kernel
ksh
lsvpd
mysql-connector-odbc
net-snmp-perl
nfs-utils
ntp
openssh-clients
openssh-server
openssl
parted
perl-DBD-MySQL
perl-DBD-Pg
perl-IO-Socket-SSL
perl-Net-Telnet
perl-XML-Parser
perl-XML-Simple
postgresql
postgresql-server
procps
rootfiles
rpm
rsync
tar
unixODBC
vim-minimal
vsftpd
wget
xz
rsyslog
@@ -0,0 +1,45 @@
#!/bin/sh
#-- Do not remove following line if you want to make use of CVS version tracking
#-- $Id: service.postinstall,v 1.21 2008/09/04 12:05:45 sikorsky Exp $
#-- jurij.sikorsky@t-systems.cz
#--
#-- this script is run after all packages from $profile.pkglist are installed
#--
#-- it gets these arguments:
#--
#-- $1 = install root (chroot directory for profile)
#-- $2 = OS version
#-- $3 = architecture
#-- $4 = profile name
#-- $5 = work dir (where genimage is located)
#--
#--
installroot=$1
osver=$2
arch=$3
profile=$4
workdir=$5
#-- Example how /etc/fstab can be automatically generated during image generation:
#cat <<END >$installroot/etc/fstab
#proc /proc proc rw 0 0
#sysfs /sys sysfs rw 0 0
#devpts /dev/pts devpts rw,gid=5,mode=620 0 0
#${profile}_${arch} / tmpfs rw 0 1
#none /tmp tmpfs defaults,size=10m 0 2
#none /var/tmp tmpfs defaults,size=10m 0 2
#END
#-- Uncomment the line contains "cons" in /etc/inittab
#cons:12345:respawn:/sbin/smart_agetty -L 38400 console
echo "co:2345:respawn:/sbin/agetty -L 38400 console" >> $installroot/etc/inittab
#-- Example of booted image versioning
#-- We want to know, with what configuration (version of the image) each node was booted.
#-- Hence, we keep image definition files and postscripts in CVS. During image generation we create file /etc/IMGVERSION and fill it with CVS "$Id$" of files with image definition (.pkglist, .exlist, .repolist, .postinstall). Then, during boot, each "CVS enabled" postscript (see /install/postscripts/cvs_template.sh and /install/postscripts/cvs_template.pl) adds one line to /etc/IMGVERSION. Then you can determine in any time what image you are running and what postscipts in which versions were run.
#cat /dev/null > $installroot/etc/IMGVERSION
#for ext in pkglist exlist postinstall repolist; do
# [ -r $workdir/$profile.$ext ] && cat $workdir/$profile.$ext | grep -E '^[[:space:]]*#.*[[:space:]]\$Id' >> $installroot/etc/IMGVERSION
#done
+19 -3
View File
@@ -120,12 +120,19 @@ if ($::VLAN)
sub config_ssh {
my $password = "CumulusLinux!";
my $userid = "cumulus";
my $timeout = 10;
my $timeout = 30;
my $keyfile = "/root/.ssh/id_rsa.pub";
my $rootkey = `cat /root/.ssh/id_rsa.pub`;
my $cmd;
my @config_switches;
# get netmask from network table
my $nettab = xCAT::Table->new("networks");
my @nets;
if ($nettab) {
@nets = $nettab->getAllAttribs('net','mask');
}
my $nodetab = xCAT::Table->new('hosts');
my $nodehash = $nodetab->getNodesAttribs(\@nodes,['ip','otherinterfaces']);
@@ -160,9 +167,18 @@ sub config_ssh {
($ret, $err) = cumulus_exec($exp, "chmod 700 /root/.ssh");
($ret, $err) = cumulus_exec($exp, "echo \"$rootkey\" >/root/.ssh/authorized_keys");
($ret, $err) = cumulus_exec($exp, "chmod 644 /root/.ssh/authorized_keys");
#config dhcp ip address to static
if ($ssh_ip eq $discover_ip) {
($ret, $err) = cumulus_exec($exp, "ifconfig eth0 $static_ip");
#get netmask
my $mask;
foreach my $net (@nets) {
if (xCAT::NetworkUtils::isInSameSubnet( $net->{'net'}, $static_ip, $net->{'mask'}, 0)) {
$mask=$net->{'mask'};
last;
}
}
($ret, $err) = cumulus_exec($exp, "ifconfig eth0 $static_ip netmask $mask");
}
$exp->hard_close();
@@ -176,7 +192,7 @@ sub config_ssh {
$rc= xCAT::Utils->runcmd($cmd, 0);
print "ssh configured for $csw\n";
if ($::ALL) {
$cmd = "updatenode $csw -P hardeths,enablesnmp,configinterface";
$cmd = "updatenode $csw -P hardeths,syslog,enablesnmp,configinterface";
$rc= xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E","Failed to run updatenode, please check the switch");
+3 -1
View File
@@ -76,7 +76,9 @@ for i in $*; do
delim="|"
for u in $removeusers
do
userlist=$userlist$u$delim
# For special char +/-, need to escape
[[ "${u:0:1}x" =~ ^\+|\-x ]] && uu="\\$u" || uu="$u"
userlist=$userlist$uu$delim
done
# remove the last delimiter
userlisttmp="${userlist%?}"
@@ -11,3 +11,4 @@ rpower_errorcommand_OpenpowerBmc
rpower_softoff_OpenpowerBmc
rpower_suspend_OpenpowerBmc
rpower_wake_OpenpowerBmc
rpower_wrongpasswd
@@ -28,3 +28,4 @@ rspconfig_netmask_invalid
rspconfig_gateway
rspconfig_gateway_invalid
rspconfig_node_invalid
rpower_wrongpasswd
@@ -17,6 +17,7 @@ updatenode_diskful_syncfiles_P_script1
updatenode_script3
updatenode_P_script1_script2
updatenode_without_flag
confignetwork_static_installnic
confignetwork_secondarynic_nicnetworks_updatenode_false
confignetwork_secondarynic_nicips_updatenode_false
confignetwork_secondarynic_nictype_updatenode_false
@@ -32,6 +33,7 @@ chdef_dynamic_group
chdef_multiple_keys
chdef_n
chdef_t_o_error
chdef_site_check
chtab_null
chtab_d
chtab_modify_node
@@ -295,6 +297,30 @@ run_command_with_XCATBYPASS
disable_root_permission_in_policy_table
assign_certain_command_permission
xcatconfig_u_check_xcatsslversion_rhels_sles
xcatconfig_c
bmcdiscover_help
bmcdiscover_q
bmcdiscover_version
chdef_nicips
encrypted_passwd_md5_diskfull
encrypted_passwd_openssl_diskfull
encrypted_passwd_sha256_diskfull
encrypted_passwd_sha512_diskfull
makedhcp_remote_network
makedns_n_noderange
makeknownhosts_node_d
mkdef_regex_bmc
mkdef_regex_ip
mkdef_regex_kvm
mkdef_regex_nicsip
nodeset_errorcommand
nodeset_grub2
nodeset_yaboot
nodestat_usage
rmimage_diskless
updatenode_diskful_syncfiles_failing
xdcp_nonroot_user
xdsh_permission_denied
reg_linux_diskless_installation_flat
packimage_m_cpio_c_gzip
packimage_m_cpio_c_xz
@@ -8,6 +8,7 @@ makehost_n_r
chdef_null
chdef_z
chdef_t_o_error
chdef_site_check
chtab_null
chtab_d
chtab_modify_node
@@ -205,11 +206,40 @@ switchdiscover_range_r
switchdiscover_range_x
switchdiscover_range_z
switchdiscover_range_z_V
nodeset_shell
nodeset_cmdline
nodeset_runimg
nodeset_check_warninginfo
xcatconfig_u_check_xcatsslversion_rhels_sles
xcatconfig_c
bmcdiscover_help
bmcdiscover_q
bmcdiscover_version
chdef_nicips
confignetwork_static_installnic
confignetwork_2eth_bridge_br0
confignetwork_2eth_bridge_br22_br33
confignetwork_bond_eth2_eth3
confignetwork_bond_false
confignetwork_installnic_2eth_bridge_br22_br33
confignetwork_vlan_bond
confignetwork_vlan_eth0
encrypted_passwd_md5_diskfull
encrypted_passwd_openssl_diskfull
encrypted_passwd_sha256_diskfull
encrypted_passwd_sha512_diskfull
makedhcp_remote_network
makedns_n_noderange
makeknownhosts_node_d
mkdef_regex_bmc
mkdef_regex_ip
mkdef_regex_kvm
mkdef_regex_nicsip
nodeset_errorcommand
nodeset_shell_incorrectmasterip
nodeset_xnba
nodestat_usage
rmimage_diskless
updatenode_diskful_syncfiles_failing
xdcp_nonroot_user
xdsh_permission_denied
reg_linux_diskless_installation_flat
packimage_m_cpio_c_gzip
packimage_m_cpio_c_xz
@@ -217,6 +247,11 @@ packimage_m_tar_c_gzip
packimage_m_tar_c_xz
packimage_m_invalid_archive_method
packimage_m_invalid_compress_method
confignetwork_vlan_false
confignetwork__bridge_false
nodeset_shell
nodeset_cmdline
nodeset_runimg
reg_linux_statelite_installation_flat
SN_setup_case
reg_linux_diskfull_installation_hierarchy
@@ -32,6 +32,7 @@ chdef_dynamic_group
chdef_multiple_keys
chdef_n
chdef_t_o_error
chdef_site_check
chtab_null
chtab_d
chtab_modify_node
@@ -296,6 +297,39 @@ run_command_with_XCATBYPASS
disable_root_permission_in_policy_table
assign_certain_command_permission
xcatconfig_u_check_xcatsslversion_rhels_sles
bmcdiscover_help
bmcdiscover_q
bmcdiscover_version
chdef_nicips
confignetwork_2eth_bridge_br0
confignetwork_2eth_bridge_br22_br33
confignetwork_bond_eth2_eth3
confignetwork_bond_false
confignetwork__bridge_false
confignetwork_installnic_2eth_bridge_br22_br33
confignetwork_vlan_bond
confignetwork_vlan_eth0
confignetwork_vlan_false
encrypted_passwd_md5_diskfull
encrypted_passwd_openssl_diskfull
encrypted_passwd_sha256_diskfull
encrypted_passwd_sha512_diskfull
makedhcp_remote_network
makedns_n_noderange
makeknownhosts_node_d
mkdef_regex_bmc
mkdef_regex_ip
mkdef_regex_kvm
mkdef_regex_nicsip
mkdef_rhels73
nodeset_errorcommand
nodeset_grub2
nodeset_yaboot
nodestat_usage
rmimage_diskless
updatenode_diskful_syncfiles_failing
xdcp_nonroot_user
xdsh_permission_denied
reg_linux_diskless_installation_flat
packimage_m_cpio_c_gzip
packimage_m_cpio_c_xz
@@ -43,6 +43,7 @@ chdef_dynamic_group
chdef_multiple_keys
chdef_n
chdef_t_o_error
chdef_site_check
chtab_null
chtab_d
chtab_modify_node
@@ -293,6 +294,39 @@ run_command_with_XCATBYPASS
disable_root_permission_in_policy_table
assign_certain_command_permission
xcatconfig_u_check_xcatsslversion_rhels_sles
bmcdiscover_help
bmcdiscover_q
bmcdiscover_version
chdef_nicips
confignetwork_2eth_bridge_br0
confignetwork_2eth_bridge_br22_br33
confignetwork_bond_eth2_eth3
confignetwork_bond_false
confignetwork__bridge_false
confignetwork_installnic_2eth_bridge_br22_br33
confignetwork_vlan_bond
confignetwork_vlan_eth0
confignetwork_vlan_false
encrypted_passwd_md5_diskfull
encrypted_passwd_openssl_diskfull
encrypted_passwd_sha256_diskfull
encrypted_passwd_sha512_diskfull
makedhcp_remote_network
makedns_n_noderange
makeknownhosts_node_d
mkdef_regex_bmc
mkdef_regex_ip
mkdef_regex_kvm
mkdef_regex_nicsip
mkdef_rhels73
nodeset_errorcommand
nodeset_grub2
nodeset_petitboot
nodestat_usage
rmimage_diskless
updatenode_diskful_syncfiles_failing
xdcp_nonroot_user
xdsh_permission_denied
packimage_m_cpio_c_gzip
packimage_m_cpio_c_xz
packimage_m_tar_c_gzip
@@ -19,6 +19,7 @@ confignetwork_secondarynic_nictype_updatenode_false
chdef_null
chdef_z
chdef_t_o_error
chdef_site_check
chtab_null
chtab_d
chtab_modify_node
@@ -227,6 +228,38 @@ nodeset_shell
nodeset_cmdline
nodeset_runimg
xcatconfig_u_check_xcatsslversion_rhels_sles
bmcdiscover_help
bmcdiscover_q
bmcdiscover_version
chdef_nicips
confignetwork_2eth_bridge_br0
confignetwork_2eth_bridge_br22_br33
confignetwork_bond_eth2_eth3
confignetwork_bond_false
confignetwork__bridge_false
confignetwork_installnic_2eth_bridge_br22_br33
confignetwork_vlan_bond
confignetwork_vlan_eth0
confignetwork_vlan_false
encrypted_passwd_md5_diskfull
encrypted_passwd_openssl_diskfull
encrypted_passwd_sha256_diskfull
encrypted_passwd_sha512_diskfull
makedhcp_remote_network
makedns_n_noderange
makeknownhosts_node_d
mkdef_regex_bmc
mkdef_regex_ip
mkdef_regex_kvm
mkdef_regex_nicsip
mkdef_rhels73
nodeset_errorcommand
nodeset_xnba
nodestat_usage
rmimage_diskless
updatenode_diskful_syncfiles_failing
xdcp_nonroot_user
xdsh_permission_denied
reg_linux_diskless_installation_flat
reg_linux_statelite_installation_flat
SN_setup_case
@@ -17,6 +17,7 @@ updatenode_diskful_syncfiles_P_script1
updatenode_script3
updatenode_P_script1_script2
updatenode_without_flag
confignetwork_static_installnic
confignetwork_secondarynic_nicnetworks_updatenode_false
confignetwork_secondarynic_nicips_updatenode_false
confignetwork_secondarynic_nictype_updatenode_false
@@ -32,6 +33,7 @@ chdef_dynamic_group
chdef_multiple_keys
chdef_n
chdef_t_o_error
chdef_site_check
chtab_null
chtab_d
chtab_modify_node
@@ -296,6 +298,31 @@ run_command_with_XCATBYPASS
disable_root_permission_in_policy_table
assign_certain_command_permission
xcatconfig_u_check_xcatsslversion_rhels_sles
xcatconfig_c
bmcdiscover_help
bmcdiscover_q
bmcdiscover_version
chdef_nicips
encrypted_passwd_md5_diskfull
encrypted_passwd_openssl_diskfull
encrypted_passwd_sha256_diskfull
encrypted_passwd_sha512_diskfull
makedhcp_remote_network
makedns_n_noderange
makeknownhosts_node_d
mkdef_regex_bmc
mkdef_regex_ip
mkdef_regex_kvm
mkdef_regex_nicsip
mkdef_rhels73
nodeset_errorcommand
nodeset_grub2
nodeset_yaboot
nodestat_usage
rmimage_diskless
updatenode_diskful_syncfiles_failing
xdcp_nonroot_user
xdsh_permission_denied
reg_linux_diskless_installation_flat
packimage_m_cpio_c_gzip
packimage_m_cpio_c_xz
@@ -20,6 +20,7 @@ updatenode_diskful_syncfiles_P_script1
updatenode_script3
updatenode_P_script1_script2
updatenode_without_flag
confignetwork_static_installnic
confignetwork_s_installnic_secondarynic_updatenode
confignetwork_secondarynic_updatenode
confignetwork_secondarynic_nicaliases_updatenode
@@ -43,6 +44,7 @@ chdef_dynamic_group
chdef_multiple_keys
chdef_n
chdef_t_o_error
chdef_site_check
chtab_null
chtab_d
chtab_modify_node
@@ -147,6 +149,7 @@ noderm_null
noderm_err_node
nodeset_stat
nodeset_noderange
nodeset_shell_incorrectmasterip
nodestat_err_node
rinv_noderange_err
rmdef_null
@@ -268,9 +271,6 @@ switchdiscover_range_r
switchdiscover_range_x
switchdiscover_range_z
switchdiscover_range_z_V
nodeset_shell
nodeset_cmdline
nodeset_runimg
makentp_v
makentp_h
nodeset_check_warninginfo
@@ -293,18 +293,56 @@ run_command_with_XCATBYPASS
disable_root_permission_in_policy_table
assign_certain_command_permission
xcatconfig_u_check_xcatsslversion_rhels_sles
xcatconfig_c
bmcdiscover_help
bmcdiscover_q
bmcdiscover_version
chdef_nicips
confignetwork_2eth_bridge_br0
confignetwork_2eth_bridge_br22_br33
confignetwork_bond_eth2_eth3
confignetwork_bond_false
confignetwork_installnic_2eth_bridge_br22_br33
confignetwork_vlan_bond
confignetwork_vlan_eth0
encrypted_passwd_md5_diskfull
encrypted_passwd_openssl_diskfull
encrypted_passwd_sha256_diskfull
encrypted_passwd_sha512_diskfull
makedhcp_remote_network
makedns_n_noderange
makeknownhosts_node_d
mkdef_regex_bmc
mkdef_regex_ip
mkdef_regex_kvm
mkdef_regex_nicsip
mkdef_rhels73
nodeset_errorcommand
nodeset_grub2
nodeset_petitboot
nodestat_usage
rmimage_diskless
updatenode_diskful_syncfiles_failing
xdcp_nonroot_user
xdsh_permission_denied
packimage_m_cpio_c_gzip
packimage_m_cpio_c_xz
packimage_m_tar_c_gzip
packimage_m_tar_c_xz
packimage_m_invalid_archive_method
packimage_m_invalid_compress_method
confignetwork_vlan_false
confignetwork__bridge_false
nodeset_shell
nodeset_cmdline
nodeset_runimg
reg_linux_statelite_installation_flat
SN_setup_case
reg_linux_diskfull_installation_hierarchy
reg_linux_diskless_installation_hierarchy
reg_linux_statelite_installation_hierarchy_by_ramdisk
reg_linux_statelite_installation_hierarchy_by_nfs
nodeset_disjointdhcps_petitboot
redhat_migration1
redhat_migration2
clean_up_env
@@ -5,6 +5,7 @@ makehosts_help
makehosts_n
makehosts_n_noderange
makehost_n_r
confignetwork_static_installnic
confignetwork_s_installnic_secondarynic_updatenode
confignetwork_secondarynic_updatenode
confignetwork_secondarynic_nicaliases_updatenode
@@ -16,9 +17,17 @@ confignetwork_secondarynic_thirdnic_multiplevalue_updatenode
confignetwork_secondarynic_nicnetworks_updatenode_false
confignetwork_secondarynic_nicips_updatenode_false
confignetwork_secondarynic_nictype_updatenode_false
confignetwork_2eth_bridge_br0
confignetwork_2eth_bridge_br22_br33
confignetwork_bond_eth2_eth3
confignetwork_bond_false
confignetwork_installnic_2eth_bridge_br22_br33
confignetwork_vlan_bond
confignetwork_vlan_eth0
chdef_null
chdef_z
chdef_t_o_error
chdef_site_check
chtab_null
chtab_d
chtab_modify_node
@@ -122,6 +131,7 @@ noderm_h
noderm_null
noderm_err_node
nodeset_stat
nodeset_shell_incorrectmasterip
nodeset_noderange
nodestat_noderange
nodestat_err_node
@@ -223,10 +233,36 @@ switchdiscover_range_x
switchdiscover_range_z
switchdiscover_range_z_V
nodeset_check_warninginfo
xcatconfig_u_check_xcatsslversion_rhels_sles
xcatconfig_c
bmcdiscover_help
bmcdiscover_q
bmcdiscover_version
chdef_nicips
encrypted_passwd_md5_diskfull
encrypted_passwd_openssl_diskfull
encrypted_passwd_sha256_diskfull
encrypted_passwd_sha512_diskfull
makedhcp_remote_network
makedns_n_noderange
makeknownhosts_node_d
mkdef_regex_bmc
mkdef_regex_ip
mkdef_regex_kvm
mkdef_regex_nicsip
mkdef_rhels73
nodeset_errorcommand
nodeset_xnba
nodestat_usage
rmimage_diskless
updatenode_diskful_syncfiles_failing
xdcp_nonroot_user
xdsh_permission_denied
confignetwork_vlan_false
confignetwork__bridge_false
nodeset_shell
nodeset_cmdline
nodeset_runimg
xcatconfig_u_check_xcatsslversion_rhels_sles
reg_linux_diskless_installation_flat
reg_linux_statelite_installation_flat
SN_setup_case
@@ -11,6 +11,7 @@ chdef_dynamic_group
chdef_multiple_keys
chdef_n
chdef_t_o_error
chdef_site_check
chtab_null
chtab_d
chtab_modify_node
@@ -224,6 +225,7 @@ noderange_XCAT_NODE_PREFIX
noderange_XCAT_NODE_SUFFIX
noderange_exclusion
noderange_group_intersection
confignetwork_static_installnic
confignetwork_secondarynic_nicnetworks_updatenode_false
confignetwork_secondarynic_nicips_updatenode_false
confignetwork_secondarynic_nictype_updatenode_false
@@ -259,6 +261,30 @@ makentp_v
makentp_h
nodeset_check_warninginfo
xcatconfig_u_check_xcatsslversion_rhels_sles
xcatconfig_c
bmcdiscover_help
bmcdiscover_q
bmcdiscover_version
chdef_nicips
encrypted_passwd_md5_diskfull
encrypted_passwd_openssl_diskfull
encrypted_passwd_sha256_diskfull
encrypted_passwd_sha512_diskfull
makedhcp_remote_network
makedns_n_noderange
makeknownhosts_node_d
mkdef_regex_bmc
mkdef_regex_ip
mkdef_regex_kvm
mkdef_regex_nicsip
nodeset_errorcommand
nodeset_grub2
nodeset_yaboot
nodestat_usage
rmimage_diskless
updatenode_diskful_syncfiles_failing
xdcp_nonroot_user
xdsh_permission_denied
reg_linux_diskless_installation_flat
packimage_m_cpio_c_gzip
packimage_m_cpio_c_xz
@@ -8,6 +8,7 @@ makehost_n_r
chdef_null
chdef_z
chdef_t_o_error
chdef_site_check
chtab_null
chtab_d
chtab_modify_node
@@ -16,6 +17,7 @@ chtab_err_symble
chtab_err_table
chtab_h
chtab_v
confignetwork_static_installnic
packimage_o_p_a_m
packimage_imagename
packimage_h
@@ -209,9 +211,6 @@ switchdiscover_range_r
switchdiscover_range_x
switchdiscover_range_z
switchdiscover_range_z_V
nodeset_shell
nodeset_cmdline
nodeset_runimg
nodeset_check_warninginfo
xcatd_start
xcatd_stop
@@ -220,6 +219,30 @@ run_command_with_XCATBYPASS
disable_root_permission_in_policy_table
assign_certain_command_permission
xcatconfig_u_check_xcatsslversion_rhels_sles
xcatconfig_c
bmcdiscover_help
bmcdiscover_q
bmcdiscover_version
chdef_nicips
encrypted_passwd_md5_diskfull
encrypted_passwd_openssl_diskfull
encrypted_passwd_sha256_diskfull
encrypted_passwd_sha512_diskfull
makedhcp_remote_network
makedns_n_noderange
makeknownhosts_node_d
mkdef_regex_bmc
mkdef_regex_ip
mkdef_regex_kvm
mkdef_regex_nicsip
nodeset_errorcommand
nodeset_xnba
nodeset_shell_incorrectmasterip
nodestat_usage
rmimage_diskless
updatenode_diskful_syncfiles_failing
xdcp_nonroot_user
xdsh_permission_denied
reg_linux_diskless_installation_flat
packimage_m_cpio_c_gzip
packimage_m_cpio_c_xz
@@ -227,6 +250,9 @@ packimage_m_tar_c_gzip
packimage_m_tar_c_xz
packimage_m_invalid_archive_method
packimage_m_invalid_compress_method
nodeset_shell
nodeset_cmdline
nodeset_runimg
reg_linux_statelite_installation_flat
SN_setup_case
reg_linux_diskfull_installation_hierarchy

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