Compare commits

..

5 Commits

Author SHA1 Message Date
Jarrod Johnson 6c6b43f60f Fix problem where tc grants always were sent to the last peer to send traffic 2013-04-08 13:35:17 -04:00
Jarrod Johnson d569677196 Fix issue where TC requests would be remembered not at all and then forever 2013-04-08 10:33:50 -04:00
Jarrod Johnson f17024abe5 Fix output to have a newline in packet 2013-04-08 14:29:46 +00:00
Jarrod Johnson ec114e2fde Implement udp request (but no reply yet) 2013-04-08 14:29:46 +00:00
Jarrod Johnson 7a33da03de Step one of traffic control, have SSL inform UDP process of current client count 2013-04-08 14:29:46 +00:00
1090 changed files with 55876 additions and 89710 deletions
+241
View File
@@ -0,0 +1,241 @@
#!/bin/sh
# Update GSA Ubuntu Repositories or create a local repository
#
# Author: Leonardo Tonetto (tonetto@linux.vnet.ibm.com)
# Revisor: Arif Ali (aali@ocf.co.uk)
#
# After running this script, add the following line to
# /etc/apt/sources.list for local repository
# deb file://<core_repo_path>/xcat-core/ maverick main
# deb file://<dep_repo_path>/xcat-dep/ maverick main
#
# For the purpose of getting the distribution name
# Supported distributions
dists="squeeze"
a_flag= # automatic flag - only update if repo was updated
c_flag= # xcat-core (trunk-delvel) path
d_flag= # xcat-dep (trunk) path
local_flag= # build the repository localy
while getopts 'c:d:u:p:l:a' OPTION
do
case $OPTION in
c) c_flag=1
xcat_core_path="$OPTARG"
;;
d) d_flag=1
xcat_dep_path="$OPTARG"
;;
l) local_flag=1
local_repo_path="$OPTARG"
;;
a) a_flag=1
;;
?) printf "Usage: %s -c <core_trunk_path> [-d <dep_trunk_path>] -l <local-repo_path> [-a]\n" $(basename $0) >&2
echo "-a Automatic: update only if there's any update on repo"
exit 2
;;
esac
done
shift $(($OPTIND - 1))
if [ -z "$c_flag" -a -z "$d_flag" ]
then
printf "Usage: %s -c <core_trunk_path> [-d <dep_trunk_path>] { -l <local-repo_path> | [-u <gsa_id> -p <gsa_passwd>] } [-a]\n" $(basename $0) >&2
echo "-a Automatic: update only if there's any update on repo"
exit 2
fi
if [ ! -d $xcat_core_path ]
then
printf "%s: No such directory\n" "$xcat_core_path" >&2
exit 2
fi
if [ "$d_flag" ]
then
if [ ! -d $xcat_dep_path ]
then
printf "%s: No such directory\n" "$xcat_dep_path" >&2
exit 2
fi
fi
if [ "$local_flag" ]
then
repo_xcat_core_path=$local_repo_path"/xcat-core"
repo_xcat_dep_path=$local_repo_path"/xcat-dep"
else
printf "Usage: %s -c <core_trunk_path> [-d <dep_trunk_path>] -l <local-repo_path> [-a]\n" $(basename $0) >&2
echo "-a Automatic: update only if there's any update on repo"
exit 2
fi
if [ "$a_flag" ]
then
touch svcupdate.trace
SVCUP='svcupdate.trace'
svn update $xcat_core_path 1> $SVCUP 2>&1
if ! grep 'Tree is up to date' $SVCUP
then
update_core=1
else
update_core=
fi
rm -f $SVCUP
else
update_core=1
fi
if [ "$c_flag" -a "$update_core" ]
then
echo "###############################"
echo "# Building xcat-core packages #"
echo "###############################"
CMD_PATH=`pwd`
cd $xcat_core_path
./build-debs-all "snap" "Nightly_Builds"
echo "#################################"
echo "# Creating xcat-core repository #"
echo "#################################"
if [ -d $repo_xcat_core_path ]; then
rm -rf $repo_xcat_core_path
fi
mkdir -p $repo_xcat_core_path/conf
find . -iname '*.deb' -exec mv {} $repo_xcat_core_path \;
rm -rf debs/
cd $CMD_PATH
rm -rf $repo_xcat_core_path/conf/distributions
for dist in $dists; do
cat << __EOF__ >> $repo_xcat_core_path/conf/distributions
Origin: xCAT internal repository
Label: xcat-core bazaar repository
Codename: $dist
Architectures: amd64
Components: main
Description: Repository automatically genereted conf
__EOF__
done
cat << __EOF__ > $repo_xcat_core_path/conf/options
verbose
basedir .
__EOF__
for dist in $dists; do
for file in `ls $repo_xcat_core_path/*.deb`; do
reprepro -b $repo_xcat_core_path includedeb $dist $file;
done
done
mv $xcat_core_path/latest_version $repo_xcat_core_path/xcat-core_latest-build
cat << '__EOF__' > $repo_xcat_core_path/mklocalrepo.sh
codename=`lsb_release -a 2>null | grep Codename | awk '{print $2}'`
cd `dirname $0`
echo deb file://"`pwd`" $codename main > /etc/apt/sources.list.d/xcat-core.list
__EOF__
chmod 775 $repo_xcat_core_path/mklocalrepo.sh
rm -rf $repo_xcat_core_path/*.deb
if [ -z "$local_flag" ]
then
echo "###############################"
echo "# Updating GSA xcat-core repo #"
echo "###############################"
lftp -e "mirror -R --delete-first $repo_xcat_core_path /projects/i/ipl-xcat/ubuntu/; exit;" -u $gsa_id,$gsa_passwd -p 22 sftp://ausgsa.ibm.com
fi ### if [ -z "$local_flag" ]
fi ### if [ "$a_flag" ]
if [ "$a_flag" -a "$d_flag" ]
then
touch svcupdate.trace
SVCUP='svcupdate.trace'
svn update $xcat_dep_path 1> $SVCUP 2>&1
if ! grep 'Tree is up to date' $SVCUP
then
update_dep=1
else
update_dep=
fi
rm -f $SVCUP
else
update_dep=1
fi
if [ "$d_flag" -a "$update_dep" ]
then
echo "##############################"
echo "# Building xcat-dep packages #"
echo "##############################"
CMD_PATH=`pwd`
cd $xcat_dep_path
./build-debs-all "snap" "Nightly_Builds"
echo "################################"
echo "# Creating xcat-dep repository #"
echo "################################"
rm -rf $repo_xcat_dep_path
mkdir -p $repo_xcat_dep_path/conf
find $xcat_dep_path -iname '*.deb' -exec cp {} $repo_xcat_dep_path \;
rm -rf $repo_xcat_core_path/conf/distributions
for dist in $dists; do
cat << __EOF__ >> $repo_xcat_dep_path/conf/distributions
Origin: xCAT internal repository
Label: xcat-dep bazaar repository
Codename: $dist
Architectures: i386 amd64
Components: main
Description: Repository automatically genereted conf
__EOF__
done
cat << __EOF__ > $repo_xcat_dep_path/conf/options
verbose
basedir .
__EOF__
for dist in $dists; do
for file in `ls $repo_xcat_dep_path/*.deb`; do
reprepro -b $repo_xcat_dep_path includedeb $dist $file;
done
done
cat << '__EOF__' > $repo_xcat_dep_path/mklocalrepo.sh
codename=`lsb_release -a 2>null | grep Codename | awk '{print $2}'`
cd `dirname $0`
echo deb file://"`pwd`" $codename main > /etc/apt/sources.list.d/xcat-dep.list
__EOF__
chmod 775 $repo_xcat_dep_path/mklocalrepo.sh
rm -rf $repo_xcat_dep_path/*.deb
if [ -z "$local_flag" ]
then
echo "##############################"
echo "# Updating GSA xcat-dep repo #"
echo "##############################"
lftp -e "mirror -R --delete-first $repo_xcat_dep_path /projects/i/ipl-xcat/ubuntu/; exit;" -u $gsa_id,$gsa_passwd -p 22 sftp://ausgsa.ibm.com
fi ### if [ -z "$local_flag" ]
fi ### if [ "$d_flag" -a "$a_flag"]
if [ -z "$local_flag" ] # delete the temp repo after upload is done
then
rm -rf ./gsa-repo_temp
fi
exit 0
+80 -183
View File
@@ -41,19 +41,8 @@ printusage()
# For the purpose of getting the distribution name
. /etc/lsb-release
# Process cmd line variable assignments, assigning each attr=val pair to a variable of same name
for i in $*; do
echo $i | grep '='
if [ $? != 0 ];then
continue
fi
# upper case the variable name
varstring=`echo "$i"|cut -d '=' -f 1|tr '[a-z]' '[A-Z]'`=`echo "$i"|cut -d '=' -f 2`
export $varstring
done
# Supported distributions
dists="saucy trusty utopic"
dists="maverick natty oneiric precise"
c_flag= # xcat-core (trunk-delvel) path
d_flag= # xcat-dep (trunk) path
@@ -86,7 +75,7 @@ if [ "$c_flag" -a "$d_flag" ];then
exit 2
fi
uploader="ligc"
uploader="bp-sawyers"
# Find where this script is located to set some build variables
old_pwd=`pwd`
cd `dirname $0`
@@ -102,6 +91,14 @@ local_dep_repo_path="$curdir/../../../xcat-dep/xcat-dep"
sf_repo_url="https://sourceforge.net/projects/xcat/files/ubuntu"
sf_dir="/home/frs/project/x/xc/xcat"
if [ "$PROMOTE" = 1 ]; then
upload_dir="xcat-core"
tar_name="xcat-core-$ver.tar.bz2"
else
upload_dir="core-snap"
tar_name="core-debs-snap.tar.bz2"
fi
#use flock to only one person build at the same time
# Get a lock, so can not do 2 builds at once
exec 8>/var/lock/xcatbld.lock
@@ -131,124 +128,69 @@ then
REL=`basename $t`
fi
#get the version
echo "svn --quiet update Version"
svn --quiet up Version
ver=`cat Version`
if [ "$PROMOTE" != 1 ]; then
code_change=0
update_log=''
#get the version
if [ "$REL" = "xcat-core" ];then
git_flag=1
REL=`git rev-parse --abbrev-ref HEAD`
if [ "$REL" = "master" ]; then
REL="devel"
fi
if [ -z "$GITUP" ];then
update_log=../coregitup
echo "git pull > $update_log"
git pull > $update_log
else
update_log=$GITUP
fi
short_ver=`cat Version|cut -d. -f 1,2`
short_short_ver=`cat Version|cut -d. -f 1`
if ! grep -q 'Already up-to-date' $update_log; then
code_change=1
fi
else
git_flag=0
if [ -z "$SVNUP" ]; then
update_log=../coresvnup
echo "svn up > $update_log"
svn up > $update_log
else
update_log=$SVNUP
fi
#TODO: define the core path and tarball name
tarball_name="core-debs-snap.tar.bz2"
if ! grep -q 'At revision' $update_log;then
code_change=1
fi
fi
ver=`cat Version`
short_ver=`cat Version|cut -d. -f 1,2`
short_short_ver=`cat Version|cut -d. -f 1`
#update the code from svn
svn_up_log="../coresvnup"
echo "svn update > $svn_up_log"
svn update > $svn_up_log
package_dir_name=debs$REL
#TODO: define the core path and tarball name
tarball_name="core-debs-snap.tar.bz2"
#makesure the code change status
code_change=0
if ! grep -q 'At revision' $svn_up_log;then
code_change=1
fi
if [ $code_change == 0 -a "$UP" != 1 -a "$BUILDALL" != 1 ]; then
echo "Nothing new detected"
exit 0
fi
if [ $code_change == 0 -a "$UP" != 1 -a "$BUILDALL" != 1 ]; then
echo "Nothing new detected"
exit 0
fi
echo "###############################"
echo "# Building xcat-core packages #"
echo "###############################"
echo "###############################"
echo "# Building xcat-core packages #"
echo "###############################"
#the package type: local | snap | alpha
#the build introduce stirng
pkg_type="snap"
build_string="Snap_Build"
cur_date=`date +%Y%m%d`
pkg_version="${short_ver}-${pkg_type}${cur_date}"
#the package type: local | snap | alpha
#the build introduce stirng
pkg_type="snap"
build_string="Snap_Build"
cur_date=`date +%Y%m%d`
pkg_version="${short_ver}-${pkg_type}${cur_date}"
if [ ! -d ../../$package_dir_name ];then
mkdir -p "../../$package_dir_name"
fi
#packages="xCAT-client xCAT-genesis-scripts perl-xCAT xCAT-server xCAT-UI xCAT xCATsn xCAT-test xCAT-OpenStack xCAT-OpenStack-baremetal xCAT-buildkit"
packages="xCAT-client xCAT-genesis-scripts perl-xCAT xCAT-server xCAT xCATsn xCAT-test xCAT-buildkit"
target_archs=(amd64 ppc64el)
for file in `echo $packages`
do
file_low=`echo $file | tr '[A-Z]' '[a-z]'`
if [ "$file" = "xCAT" -o "$file" = "xCAT-genesis-scripts" ]; then
target_archs="amd64 ppc64el"
else
target_archs="all"
fi
for target_arch in `echo $target_archs`
do
if grep -q $file $update_log || [ "$BUILDALL" == 1 -o "$file" = "perl-xCAT" ]; then
rm -f ../../$package_dir_name/${file_low}_*.$target_arch.deb
#genesis scripts package, don't remove genesis amd64 files
#rm -f ../../$package_dir_name/${file_low}-amd64_*.deb
cd $file
dch -v $pkg_version -b -c debian/changelog $build_string
if [ "$target_arch" = "all" ]; then
dpkg-buildpackage -uc -us
else
dpkg-buildpackage -uc -us -a$target_arch
fi
rc=$?
if [ $rc -gt 0 ]; then
echo "Error: $file build package failed exit code $rc"
fi
cd -
find $file -maxdepth 3 -type d -name "${file_low}*" | grep debian | xargs rm -rf
find $file -maxdepth 3 -type f -name "files" | grep debian | xargs rm -rf
mv ${file_low}* ../../$package_dir_name/
fi
done
done
find ../../$package_dir_name/* ! -name *.deb | xargs rm -f
else
if [ "$REL" = "xcat-core" ];then
git_flag=1
REL=`git rev-parse --abbrev-ref HEAD`
if [ "$REL" = "master" ]; then
REL="devel"
fi
fi
package_dir_name=debs$REL
if [ ! -d ../../debs ];then
mkdir -p "../../debs"
fi
packages="xCAT-client xCAT-genesis-scripts perl-xCAT xCAT-server xCAT-UI xCAT xCATsn xCAT-test"
if [ "$PROMOTE" = 1 ]; then
upload_dir="xcat-core"
tar_name="xcat-core-$ver.tar.bz2"
else
upload_dir="core-snap"
tar_name="core-debs-snap.tar.bz2"
fi
for file in `echo $packages`
do
file_low=`echo $file | tr '[A-Z]' '[a-z]'`
if grep -q $file $svn_up_log || [ "$BUILDALL" == 1 ]; then
rm -f ../../debs/${file_low}_*.deb
#only for genesis package
rm -f ../../debs/${file_low}-amd64_*.deb
cd $file
dch -v $pkg_version -b -c debian/changelog $build_string
dpkg-buildpackage -uc -us
rc=$?
if [ $rc -gt 0 ]; then
echo "Error: $file build package failed exit code $rc"
fi
cd -
find $file -maxdepth 3 -type d -name "${file_low}*" | grep debian | xargs rm -rf
find $file -maxdepth 3 -type f -name "files" | grep debian | xargs rm -rf
mv ${file_low}* ../../debs/
fi
done
find ../../debs/* ! -name *.deb | xargs rm -f
echo "#################################"
echo "# Creating xcat-core repository #"
@@ -263,16 +205,11 @@ then
mkdir conf
for dist in $dists; do
if [ "$dist" = "trusty" ] || [ "$dist" = "utopic" ]; then
tmp_out_arch="amd64 ppc64el"
else
tmp_out_arch="amd64"
fi
cat << __EOF__ >> conf/distributions
Origin: xCAT internal repository
Label: xcat-core bazaar repository
Codename: $dist
Architectures: $tmp_out_arch
Architectures: amd64 i386
Components: main
Description: Repository automatically genereted conf
SignWith: yes
@@ -287,29 +224,17 @@ basedir .
__EOF__
#import the deb packages into the repo
amd_files=`ls ../$package_dir_name/*.deb | grep -v "ppc64el"`
all_files=`ls ../$package_dir_name/*.deb`
for dist in $dists; do
if [ "$dist" = "trusty" ] || [ "$dist" = "utopic" ]; then
deb_files=$all_files
else
deb_files=$amd_files
fi
for file in $deb_files; do
for file in `ls ../debs/*.deb`; do
reprepro -b ./ includedeb $dist $file;
done
done
#create the mklocalrepo script
cat << '__EOF__' > mklocalrepo.sh
cat << __EOF__ > mklocalrepo.sh
. /etc/lsb-release
cd `dirname $0`
host_arch=`uname -m`
if [ "$host_arch" != "ppc64le" ];then
host_arch="amd64"
else
host_arch="ppc64el"
fi
echo deb [arch=$host_arch] file://"`pwd`" $DISTRIB_CODENAME main > /etc/apt/sources.list.d/xcat-core.list
echo deb file://"`pwd`" $DISTRIB_CODENAME main > /etc/apt/sources.list.d/xcat-core.list
__EOF__
chmod 775 mklocalrepo.sh
@@ -322,12 +247,12 @@ __EOF__
groupadd xcat
fi
chgrp -R root xcat-core
chgrp -R xcat xcat-core
chmod -R g+w xcat-core
#build the tar ball
tar -hjcf $tar_name xcat-core
chgrp root $tar_name
chgrp xcat $tar_name
chmod g+w $tar_name
if [ ! -e core-snap ]; then
@@ -335,7 +260,7 @@ __EOF__
fi
# Decide whether to upload or not
if [ -n "$UP" ] && [ "$UP" == 0 ]; then
if [ "$UP" != 1 ]; then
echo "No need to upload"
cd $old_pwd
exit 0
@@ -350,13 +275,8 @@ __EOF__
fi
#upload the tar ball
#for the GA build, upload to https://sourceforge.net/projects/xcat/files/xcat/<version>.x_Ubuntu/
#for other scenario, upload to https://sourceforge.net/projects/xcat/files/ubuntu/<version>
if [ "$PROMOTE" = 1 -a "$REL" != "devel" -a "$PREGA" != 1 ]; then
i=0
echo "Uploading $tar_name to ${sf_dir}/xcat/${REL}.x_Ubuntu/ ..."
while [ $((i+=1)) -le 5 ] && ! rsync -v $tar_name ${uploader},xcat@web.sourceforge.net:${sf_dir}/xcat/${REL}.x_Ubuntu/
do : ; done
echo "";
else
i=0
echo "Uploading $tar_name to ${sf_dir}/ubuntu/${REL}/ ..."
@@ -383,16 +303,11 @@ then
#create the conf/distributions file
for dist in $dists; do
if [ "$dist" = "trusty" ] || [ "$dist" = "utopic" ]; then
tmp_out_arch="amd64 ppc64el"
else
tmp_out_arch="amd64"
fi
cat << __EOF__ >> conf/distributions
Origin: xCAT internal repository
Label: xcat-dep bazaar repository
Codename: $dist
Architectures: $tmp_out_arch
Architectures: i386 amd64
Components: main
Description: Repository automatically genereted conf
SignWith: yes
@@ -406,16 +321,8 @@ ask-passphrase
basedir .
__EOF__
#import the deb packages into the repo
amd_files=`ls ../debs/*.deb | grep -v "ppc64el"`
all_files=`ls ../debs/*.deb`
for dist in $dists; do
if [ "$dist" = "trusty" ] || [ "$dist" = "utopic" ]; then
deb_files=$all_files
else
deb_files=$amd_files
fi
for file in $deb_files; do
for file in `ls ../debs/*.deb`; do
reprepro -b ./ includedeb $dist $file;
done
done
@@ -423,13 +330,7 @@ __EOF__
cat << '__EOF__' > mklocalrepo.sh
. /etc/lsb-release
cd `dirname $0`
host_arch=`uname -m`
if [ "$host_arch" != "ppc64le" ];then
host_arch="amd64"
else
host_arch="ppc64el"
fi
echo deb [arch=$host_arch] file://"`pwd`" $DISTRIB_CODENAME main > /etc/apt/sources.list.d/xcat-dep.list
echo deb file://"`pwd`" $DISTRIB_CODENAME main > /etc/apt/sources.list.d/xcat-dep.list
__EOF__
chmod 775 mklocalrepo.sh
@@ -441,16 +342,16 @@ __EOF__
groupadd xcat
fi
chgrp -R root xcat-dep
chgrp -R xcat xcat-dep
chmod -R g+w xcat-dep
#create the tar ball
dep_tar_name=xcat-dep-ubuntu-snap`date +%Y%m%d`.tar.bz
dep_tar_name=xcat-dep-ubuntu.tar.bz
tar -hjcf $dep_tar_name xcat-dep
chgrp root $dep_tar_name
chgrp xcat $dep_tar_name
chmod g+w $dep_tar_name
if [ -n "$UP" ] && [ "$UP" == 0 ];then
if [ "$UP" != 1 ];then
echo "No need to upload the dep packages"
cd $old_pwd
exit 0
@@ -462,10 +363,6 @@ __EOF__
while [ $((i+=1)) -le 5 ] && ! rsync -urLv --delete xcat-dep ${uploader},xcat@web.sourceforge.net:${sf_dir}/ubuntu/
do : ; done
#upload the tarball
i=0
echo "Uploading $dep_tar_name to ${sf_dir}/xcat-dep/2.x_Ubuntu/ ..."
while [ $((i+=1)) -le 5 ] && ! rsync -v $dep_tar_name ${uploader},xcat@web.sourceforge.net:${sf_dir}/xcat-dep/2.x_Ubuntu/
do : ; done
cd $old_pwd
fi
exit 0
+65 -113
View File
@@ -19,7 +19,6 @@
# directories that are needed.
# Usage: buildcore.sh [attr=value attr=value ...]
# Before running buildcore.sh, you must change the local git repo to the branch you want built, using: git checkout <branch>
# PROMOTE=1 - if the attribute "PROMOTE" is specified, means an official dot release. This does not
# actually build xcat, just uploads the most recent snap build to https://sourceforge.net/projects/xcat/files/xcat/ .
# If not specified, a snap build is assumed, which uploads to https://sourceforge.net/projects/xcat/files/yum/
@@ -32,7 +31,7 @@
# BUILDALL=1 - build all rpms, whether they changed or not. Should be used for snap builds that are in prep for a release.
# UP=0 or UP=1 - override the default upload behavior
# SVNUP=<filename> - control which rpms get built by specifying a coresvnup file
# GITUP=<filename> - control which rpms get built by specifying a coregitup file
# FRSYUM=0 - put the yum repo and snap builds in the old project web area instead of the FRS area.
# EMBED=<embedded-environment> - the environment for which a minimal version of xcat should be built, e.g. zvm or flex
# VERBOSE=1 - to see lots of verbose output
@@ -41,15 +40,11 @@ UPLOADUSER=bp-sawyers
FRS=/home/frs/project/x/xc/xcat
# These are the rpms that should be built for each kind of xcat build
#ALLBUILD="perl-xCAT xCAT-client xCAT-server xCAT-IBMhpc xCAT-rmc xCAT-UI xCAT-test xCAT-buildkit xCAT xCATsn xCAT-genesis-scripts xCAT-OpenStack xCAT-SoftLayer xCAT-OpenStack-baremetal"
ALLBUILD="perl-xCAT xCAT-client xCAT-server xCAT-test xCAT-buildkit xCAT xCATsn xCAT-genesis-scripts xCAT-SoftLayer"
ALLBUILD="perl-xCAT xCAT-client xCAT-server xCAT-IBMhpc xCAT-rmc xCAT-UI xCAT-test xCAT-buildkit xCAT xCATsn xCAT-genesis-scripts"
ZVMBUILD="perl-xCAT xCAT-server xCAT-UI"
ZVMLINK="xCAT-client xCAT xCATsn"
# xCAT and xCATsn have PCM specific configuration - conserver-xcat, syslinux-xcat
# xCAT-server has PCM specific configuration - RESTAPI(perl-JSON)
# xCAT-client has PCM specific configuration - getxcatdocs(perl-JSON)
PCMBUILD="xCAT xCAT-server xCAT-client xCATsn"
PCMLINK="perl-xCAT xCAT-buildkit xCAT-genesis-scripts-x86_64"
PCMBUILD="xCAT"
PCMLINK="perl-xCAT xCAT-client xCAT-server xCAT-buildkit xCAT-genesis-scripts-x86_64"
# Note: for FSM, the FlexCAT rpm is built separately from gsa/git
FSMBUILD="perl-xCAT xCAT-client xCAT-server"
FSMLINK=""
@@ -89,24 +84,15 @@ if [ "$OSNAME" != "AIX" ]; then
export HOME=/root # This is so rpm and gpg will know home, even in sudo
fi
# for the git case, query the current branch and set REL (changing master to devel if necessary)
function setbranch {
#git checkout $BRANCH
#REL=`git rev-parse --abbrev-ref HEAD`
REL=`git name-rev --name-only HEAD`
if [ "$REL" = "master" ]; then
REL="devel"
fi
}
if [ "$REL" = "xcat-core" ]; then # using git
GIT=1
setbranch # this changes the REL variable
# this is needed only when we are transitioning the yum over to frs
if [ "$FRSYUM" != 0 ]; then
YUMDIR=$FRS
YUMREPOURL="https://sourceforge.net/projects/xcat/files/yum"
else
YUMDIR=htdocs
YUMREPOURL="http://xcat.sourceforge.net/yum"
fi
YUMDIR=$FRS
YUMREPOURL="https://sourceforge.net/projects/xcat/files/yum"
# Set variables based on which type of build we are doing
if [ -n "$EMBED" ]; then
EMBEDDIR="/$EMBED"
@@ -130,38 +116,38 @@ else
fi
XCATCORE="xcat-core" # core-snap is a sym link to xcat-core
if [ "$GIT" = "1" ]; then # using git - need to include REL in the path where we put the built rpms
DESTDIR=../../$REL$EMBEDDIR/$XCATCORE
echo "svn --quiet up Version"
svn --quiet up Version
VER=`cat Version`
SHORTVER=`cat Version|cut -d. -f 1,2`
SHORTSHORTVER=`cat Version|cut -d. -f 1`
if [ "$PROMOTE" = 1 ]; then
CORE="xcat-core"
if [ "$OSNAME" = "AIX" ]; then
TARNAME=core-aix-$VER.tar.gz
else
TARNAME=xcat-core-$VER.tar.bz2
fi
else
DESTDIR=../..$EMBEDDIR/$XCATCORE
CORE="core-snap"
if [ "$OSNAME" = "AIX" ]; then
TARNAME=core-aix-snap.tar.gz
else
TARNAME=core-rpms-snap.tar.bz2
fi
fi
DESTDIR=../..$EMBEDDIR/$XCATCORE
SRCD=core-snap-srpms
# currently aix builds ppc rpms, but someday it should build noarch
if [ "$OSNAME" = "AIX" ]; then
NOARCH=ppc
SYSGRP=system
else
NOARCH=noarch
SYSGRP=root
fi
function setversionvars {
VER=`cat Version`
SHORTVER=`cat Version|cut -d. -f 1,2`
SHORTSHORTVER=`cat Version|cut -d. -f 1`
}
if [ "$PROMOTE" != 1 ]; then # very long if statement to not do builds if we are promoting
# we are doing a snap build
CORE="core-snap"
if [ "$OSNAME" = "AIX" ]; then
TARNAME=core-aix-snap.tar.gz
else
TARNAME=core-rpms-snap.tar.bz2
fi
mkdir -p $DESTDIR
SRCDIR=$DESTDIR/../$SRCD
mkdir -p $SRCDIR
@@ -182,37 +168,16 @@ else
#echo "source=$source"
fi
# If they have not given us a premade update file, do an svn update or git pull and capture the results
SOMETHINGCHANGED=0
if [ "$GIT" = "1" ]; then # using git
if [ -z "$GITUP" ]; then
GITUP=../coregitup
echo "git pull > $GITUP"
git pull > $GITUP
if [[ $? != 0 ]]; then
# do not continue so we do not build with old files
echo "The 'git pull' command failed. Exiting the build."
exit 3
fi
fi
if ! $GREP 'Already up-to-date' $GITUP; then
SOMETHINGCHANGED=1
fi
else # using svn
GIT=0
if [ -z "$SVNUP" ]; then
SVNUP=../coresvnup
echo "svn up > $SVNUP"
svn up > $SVNUP
fi
if ! $GREP 'At revision' $SVNUP; then
SOMETHINGCHANGED=1
fi
# copy the SVNUP variable to GITUP so the rest of the script doesnt have to worry whether we did svn or git
GITUP=$SVNUP
# If they have not given us a premade update file, do an svn update and capture the results
if [ -z "$SVNUP" ]; then
SVNUP=../coresvnup
echo "svn up > $SVNUP"
svn up > $SVNUP
fi
SOMETHINGCHANGED=0
if ! $GREP 'At revision' $SVNUP; then
SOMETHINGCHANGED=1
fi
setversionvars
# Function for making the noarch rpms
function maker {
@@ -229,7 +194,7 @@ function maker {
}
# If anything has changed, we should always rebuild perl-xCAT
if [ $SOMETHINGCHANGED == 1 -o "$BUILDALL" == 1 ]; then # Use to be: $GREP perl-xCAT $GITUP; then
if [ $SOMETHINGCHANGED == 1 -o "$BUILDALL" == 1 ]; then # Use to be: $GREP perl-xCAT $SVNUP; then
if [[ " $EMBEDBUILD " = *\ perl-xCAT\ * ]]; then
UPLOAD=1
maker perl-xCAT
@@ -241,12 +206,11 @@ if [ "$OSNAME" = "AIX" ]; then
fi
# Build the rest of the noarch rpms
for rpmname in xCAT-client xCAT-server xCAT-IBMhpc xCAT-rmc xCAT-UI xCAT-test xCAT-buildkit xCAT-SoftLayer; do
for rpmname in xCAT-client xCAT-server xCAT-IBMhpc xCAT-rmc xCAT-UI xCAT-test xCAT-buildkit; do
#if [ "$EMBED" = "zvm" -a "$rpmname" != "xCAT-server" -a "$rpmname" != "xCAT-UI" ]; then continue; fi # for zvm embedded env only need to build server and UI
if [[ " $EMBEDBUILD " != *\ $rpmname\ * ]]; then continue; fi
if [ "$OSNAME" = "AIX" -a "$rpmname" = "xCAT-buildkit" ]; then continue; fi # do not build xCAT-buildkit on aix
if [ "$OSNAME" = "AIX" -a "$rpmname" = "xCAT-SoftLayer" ]; then continue; fi # do not build xCAT-softlayer on aix
if $GREP $rpmname $GITUP || [ "$BUILDALL" == 1 ]; then
if $GREP $rpmname $SVNUP || [ "$BUILDALL" == 1 ]; then
UPLOAD=1
maker $rpmname
fi
@@ -261,13 +225,11 @@ done
# The mknb cmd combines them at install time.
if [ "$OSNAME" != "AIX" ]; then
if [[ " $EMBEDBUILD " = *\ xCAT-genesis-scripts\ * ]]; then
if $GREP xCAT-genesis-scripts $GITUP || [ "$BUILDALL" == 1 ]; then
if $GREP xCAT-genesis-scripts $SVNUP || [ "$BUILDALL" == 1 ]; then
UPLOAD=1
ORIGFAILEDRPMS="$FAILEDRPMS"
./makerpm xCAT-genesis-scripts x86_64 "$EMBED"
if [ $? -ne 0 ]; then FAILEDRPMS="$FAILEDRPMS xCAT-genesis-scripts-x86_64"; fi
./makerpm xCAT-genesis-scripts ppc64 "$EMBED"
if [ $? -ne 0 ]; then FAILEDRPMS="$FAILEDRPMS xCAT-genesis-scripts-ppc64"; fi
if [ "$FAILEDRPMS" = "$ORIGFAILEDRPMS" ]; then # all succeeded
rm -f $DESTDIR/xCAT-genesis-scripts*rpm
rm -f $SRCDIR/xCAT-genesis-scripts*rpm
@@ -279,19 +241,17 @@ if [ "$OSNAME" != "AIX" ]; then
fi
# Build the xCAT and xCATsn rpms for all platforms
for rpmname in xCAT xCATsn xCAT-OpenStack xCAT-OpenStack-baremetal; do
for rpmname in xCAT xCATsn; do
#if [ "$EMBED" = "zvm" ]; then break; fi
if [[ " $EMBEDBUILD " != *\ $rpmname\ * ]]; then continue; fi
if [ $SOMETHINGCHANGED == 1 -o "$BUILDALL" == 1 ]; then # used to be: if $GREP -E "^[UAD] +$rpmname/" $GITUP; then
if [ $SOMETHINGCHANGED == 1 -o "$BUILDALL" == 1 ]; then # used to be: if $GREP -E "^[UAD] +$rpmname/" $SVNUP; then
UPLOAD=1
ORIGFAILEDRPMS="$FAILEDRPMS"
if [ "$OSNAME" = "AIX" ]; then
if [ "$rpmname" = "xCAT-OpenStack" ] || [ "$rpmname" = "xCAT-OpenStack-baremetal" ]; then continue; fi # do not bld openstack on aix
./makerpm $rpmname "$EMBED"
if [ $? -ne 0 ]; then FAILEDRPMS="$FAILEDRPMS $rpmname"; fi
else
for arch in x86_64 ppc64 ppc64le s390x; do
if [ "$rpmname" = "xCAT-OpenStack" -a "$arch" != "x86_64" ] || [ "$rpmname" = "xCAT-OpenStack-baremetal" -a "$arch" != "x86_64" ] ; then continue; fi # only bld openstack for x86_64 for now
for arch in x86_64 i386 ppc64 s390x; do
./makerpm $rpmname $arch "$EMBED"
if [ $? -ne 0 ]; then FAILEDRPMS="$FAILEDRPMS $rpmname-$arch"; fi
done
@@ -362,10 +322,10 @@ if [ "$OSNAME" != "AIX" ]; then
echo '%_gpg_name Jarrod Johnson' >> $MACROS
fi
echo "Signing RPMs..."
build-utils/rpmsign.exp `find $DESTDIR -type f -name '*.rpm'` | grep -v -E '(already contains identical signature|was already signed|rpm --quiet --resign|WARNING: standard input reopened)'
build-utils/rpmsign.exp $SRCDIR/*rpm | grep -v -E '(already contains identical signature|was already signed|rpm --quiet --resign|WARNING: standard input reopened)'
createrepo --checksum sha $DESTDIR # specifying checksum so the repo will work on rhel5
createrepo --checksum sha $SRCDIR
build-utils/rpmsign.exp `find $DESTDIR -type f -name '*.rpm'` | grep -v -E '(was already signed|rpm --quiet --resign|WARNING: standard input reopened)'
build-utils/rpmsign.exp $SRCDIR/*rpm | grep -v -E '(was already signed|rpm --quiet --resign|WARNING: standard input reopened)'
createrepo $DESTDIR
createrepo $SRCDIR
rm -f $SRCDIR/repodata/repomd.xml.asc
rm -f $DESTDIR/repodata/repomd.xml.asc
gpg -a --detach-sign $DESTDIR/repodata/repomd.xml
@@ -378,26 +338,23 @@ if [ "$OSNAME" != "AIX" ]; then
fi
fi
# set group and permissions correctly on the built rpms
# make everything have a group of xcat, so anyone can manage them once they get on SF
if [ "$OSNAME" = "AIX" ]; then
if ! lsgroup xcat >/dev/null 2>&1; then
mkgroup xcat
fi
chmod +x $DESTDIR/instxcat
fi
chgrp -R $SYSGRP $DESTDIR
chmod -R g+w $DESTDIR
chgrp -R $SYSGRP $SRCDIR
chmod -R g+w $SRCDIR
else # end of very long if-not-promote
# we are only promoting (not building)
setversionvars
setbranch
CORE="xcat-core"
if [ "$OSNAME" = "AIX" ]; then
TARNAME=core-aix-$VER.tar.gz
else
TARNAME=xcat-core-$VER.tar.bz2
else # linux
if ! $GREP xcat /etc/group; then
groupadd xcat
fi
fi
chgrp -R xcat $DESTDIR
chmod -R g+w $DESTDIR
chgrp -R xcat $SRCDIR
chmod -R g+w $SRCDIR
fi # end of very long if-not-promote
cd $DESTDIR
@@ -437,17 +394,14 @@ else
verboseflag=""
fi
echo "Creating $TARNAME ..."
if [[ -e $TARNAME ]]; then
mkdir -p previous
mv -f $TARNAME previous
fi
if [ "$OSNAME" = "AIX" ]; then
tar $verboseflag -hcf ${TARNAME%.gz} $XCATCORE
rm -f $TARNAME
gzip ${TARNAME%.gz}
else
tar $verboseflag -hjcf $TARNAME $XCATCORE
fi
chgrp $SYSGRP $TARNAME
chgrp xcat $TARNAME
chmod g+w $TARNAME
# Decide whether to upload or not
@@ -502,8 +456,6 @@ if [ "$OSNAME" != "AIX" -a "$REL" = "devel" -a "$PROMOTE" != 1 -a -z "$EMBED" ];
rpm2cpio ../$XCATCORE/perl-xCAT-*.$NOARCH.rpm | cpio -id '*.html'
rpm2cpio ../$XCATCORE/xCAT-test-*.$NOARCH.rpm | cpio -id '*.html'
rpm2cpio ../$XCATCORE/xCAT-buildkit-*.$NOARCH.rpm | cpio -id '*.html'
rpm2cpio ../$XCATCORE/xCAT-OpenStack-*.x86_64.rpm | cpio -id '*.html'
rpm2cpio ../$XCATCORE/xCAT-SoftLayer-*.$NOARCH.rpm | cpio -id '*.html'
i=0
while [ $((i+=1)) -le 5 ] && ! rsync $verboseflag -r opt/xcat/share/doc/man1 opt/xcat/share/doc/man3 opt/xcat/share/doc/man5 opt/xcat/share/doc/man7 opt/xcat/share/doc/man8 $UPLOADUSER,xcat@web.sourceforge.net:htdocs/
do : ; done
+29 -41
View File
@@ -97,15 +97,15 @@ if [ "$OSNAME" != "AIX" ]; then
# Sign the rpms that are not already signed. The "standard input reopened" warnings are normal.
echo "Signing RPMs..."
$XCATCOREDIR/build-utils/rpmsign.exp `find . -type f -name '*.rpm'` | grep -v -E '(already contains identical signature|was already signed|rpm --quiet --resign|WARNING: standard input reopened)'
$XCATCOREDIR/build-utils/rpmsign.exp `find . -type f -name '*.rpm'` | grep -v -E '(was already signed|rpm --quiet --resign|WARNING: standard input reopened)'
# Create the repodata dirs
echo "Creating repodata directories..."
for i in `find -mindepth 2 -maxdepth 2 -type d `; do
if [ -n "$VERBOSEMODE" ]; then
createrepo --checksum sha $i # specifying checksum so the repo will work on rhel5
createrepo $i
else
createrepo --checksum sha $i >/dev/null
createrepo $i >/dev/null
fi
rm -f $i/repodata/repomd.xml.asc
gpg -a --detach-sign $i/repodata/repomd.xml
@@ -138,21 +138,8 @@ if [ "$PERLVER" == "v5.8.2" ]; then
OSVER='5.3'
elif [ "$PERLVER" == "v5.8.8" ]; then
OSVER='6.1'
aixver=`lslpp -lc|grep 'bos.rte:'|head -1|cut -d: -f3`
if [[ $aixver < '6.1.9.0' ]]; then
AIX61Y=0
else
AIX61Y=1
fi
elif [ "$PERLVER" == "v5.10.1" ]; then
OSVER='7.1'
aixver=`lslpp -lc|grep 'bos.rte:'|head -1|cut -d: -f3`
if [[ $aixver < '7.1.3.0' ]]; then
AIX71L=0
else
AIX71L=1
fi
else
echo "Error: the perl version of '$PERLVER' is not one that instoss understands. Exiting..."
exit 2
@@ -162,37 +149,33 @@ cd $OSVER
# The only interdependency between the dep rpms so far is that net-snmp requires bash, and
# pyodbc requires unixODBC. (The bash dependency is taken care of automatically because it
# comes earlier in the alphabet.)
# first run /usr/sbin/updtvpkg to make sure any installp software is
# registered with RPM.
echo "Running updtvpkg. This could take a few minutes."
/usr/sbin/updtvpkg
echo "updtvpkg has completed."
# unixODBC is required by pyodbc, so install it first
rpm -Uvh unixODBC*
# Now install the bulk of the rpms, one at a time, in case some are already installed
for i in `ls *.rpm|grep -v -E '^tcl-|^tk-|^expect-|^unixODBC-|^xCAT-UI-deps|^perl-DBD-DB2Lite|^net-snmp'`; do
for i in `ls *.rpm|grep -v -E '^tcl-|^tk-|^expect-|^unixODBC-|^xCAT-UI-deps|^perl-DBD-DB2Lite'`; do
if [ "$i" == "perl-Net-DNS-0.66-1.aix5.3.ppc.rpm" ]; then
opts="--nodeps"
else
opts=""
fi
# On 7.1L and 6.1Y we need a newer version of perl-Net_SSLeay.pm
if [[ $AIX71L -eq 1 || $AIX61Y -eq 1 ]]; then
if [[ $i == perl-Net_SSLeay.pm-1.30-* ]]; then continue; fi # skip the old rpm
else
if [[ $i == perl-Net_SSLeay.pm-1.55-* ]]; then continue; fi # skip the new rpm
fi
# just in case we need it sometime, this next if stmt would mean: if it does not start with perl-DBD-DB2
#if [ "${i#perl-DBD-DB2}" == "$i" ]; then
echo rpm -Uvh $opts $i
rpm -Uvh $opts $i
done
# Have to upgrade all of the net-snmp rpms together because they depend on each other.
# Also, they require bash, so do it after the loop, rather than before
rpm -Uvh net-snmp*
# don't try to install tcl, tk, or expect if they are already installed!
# this section about expect/tcl/tk can be removed once 2.8 releases, because 2.8 no longer requires expect
lslpp -l | grep expect.base > /dev/null 2>&1
if [ $? -gt 0 ]; then
if [ "$OSVER" == "5.3" ]; then
for i in tcl-*.rpm tk-*.rpm expect-*.rpm; do
echo rpm -Uvh $i
rpm -Uvh $i
done
else
echo "The expect.base, tcl.base, and tk.base filesets must also be installed before installing the xCAT RPMs from xcat-core."
fi
fi
EOF
# end of instoss file content ---------------------------------------------
@@ -200,13 +183,18 @@ EOF
chmod +x instoss
fi
# Get the permissions and group correct
# Get the permissions correct. Have to have all dirs/files with a group of xcat
# and have them writeable by group, so any member of the xcat can build.
if [ "$OSNAME" == "AIX" ]; then
SYSGRP=system
if ! lsgroup xcat >/dev/null 2>&1; then
mkgroup xcat
fi
else
SYSGRP=root
if ! $GREP xcat /etc/group; then
groupadd xcat
fi
fi
chgrp -R -h $SYSGRP *
chgrp -R xcat *
chmod -R g+w *
# Build the tarball
-163
View File
@@ -1,163 +0,0 @@
#######################################################################
#build script for local usage
#used for Linux/AIX/Ubuntu
#
###########################################################################
OSNAME=$(uname)
NAMEALL=$(uname -a)
for i in $*; do
# upper case the variable name
varstring=`echo "$i"|cut -d '=' -f 1|tr '[a-z]' '[A-Z]'`=`echo "$i"|cut -d '=' -f 2`
export $varstring
done
if [ -z "$CURDIR" ]; then
echo "get current directory!"
CURDIR=$(pwd)
fi
echo "CURDIR is $CURDIR"
echo "OSNAME is $OSNAME!"
echo "NAMEALL is $NAMEALL"
grep -i 'SUSE' /etc/issue
if [ $? -eq 0 ]; then
echo "This is a SUSE system!"
OS="SUSE";
fi
ls $CURDIR/makerpm
if [ $? -gt 0 ]; then
echo "Error:no repo exist, exit 1."
exit 1
fi
# Get a lock, so can not do 2 builds at once
exec 8>/var/lock/xcatbld.lock
if ! flock -n 8; then
echo "Can't get lock /var/lock/xcatbld.lock. Someone else must be doing a build right now. Exiting...."
exit 1
fi
#delete old package if there is
rm -rf $CURDIR/build/
cd $CURDIR
echo "==============================================="
echo $NAMEALL | egrep "Ubuntu"
#Check if it is an Ubuntu system
if [ $? -eq 0 ]; then
echo "This is an Ubuntu system"
pkg_type="snap"
build_string="Snap_Build"
cur_date=`date +%Y%m%d`
short_ver=`cat Version|cut -d. -f 1,2`
pkg_version="${short_ver}-${pkg_type}${cur_date}"
mkdir -p $CURDIR/build
for rpmname in xCAT-client xCAT-genesis-scripts perl-xCAT xCAT-server xCAT xCATsn xCAT-test; do
rpmname_low=`echo $rpmname | tr '[A-Z]' '[a-z]'`
echo "============================================"
echo "$rpmname_low"
cd $rpmname
dch -v $pkg_version -b -c debian/changelog $build_string
dpkg-buildpackage -uc -us
rc=$?
if [ $rc -gt 0 ]; then
echo "Error: $rpmname build package failed exit code $rc"
fi
cd -
mv ${rpmname_low}* $CURDIR/build
done
#delete all files except .deb file
find $CURDIR/build/* ! -name *.deb | xargs rm -f
else
#This is not an Ubuntu system
echo "This is an $OSNAME system"
if [ "$OS" = "SUSE" ]; then
rm -rf /usr/src/packages/RPMS/noarch/*
rm -rf /usr/src/packages/RPMS/x86_64/*
rm -rf /usr/src/packages/RPMS/ppc64/*
else
rm -rf /root/rpmbuild/RPMS/noarch/*
rm -rf /root/rpmbuild/RPMS/x86_64/*
rm -rf /root/rpmbuild/RPMS/ppc64/*
fi
mkdir -p $CURDIR/build/
#always build perl-xCAT
$CURDIR/makerpm perl-xCAT
# Build the rest of the noarch rpms
for rpmname in xCAT-client xCAT-server xCAT-IBMhpc xCAT-rmc xCAT-test xCAT-buildkit; do
if [ "$OSNAME" = "AIX" -a "$rpmname" = "xCAT-buildkit" ]; then continue; fi
$CURDIR/makerpm $rpmname
done
#build xCAT-genesis-scripts if it is x86_64 platform
ARCH=$(uname -p)
if [ "$ARCH" = "x64_64" ]; then
$CURDIR/makerpm xCAT-genesis-scripts x86_64
else
$CURDIR/makerpm xCAT-genesis-scripts ppc64
fi
# Build the xCAT and xCATsn rpms for all platforms
for rpmname in xCAT xCATsn; do
if [ "$OSNAME" = "AIX" ]; then
$CURDIR/makerpm $rpmname
if [ $? -ne 0 ]; then FAILEDRPMS="$FAILEDRPMS $rpmname"; fi
else
for arch in x86_64 ppc64 s390x; do
$CURDIR/makerpm $rpmname $arch
if [ $? -ne 0 ]; then FAILEDRPMS="$FAILEDRPMS $rpmname-$arch"; fi
done
fi
done
if [ "$OS" = "SUSE" ]; then
cp /usr/src/packages/RPMS/noarch/* $CURDIR/build/
cp /usr/src/packages/RPMS/x86_64/* $CURDIR/build/
cp /usr/src/packages/RPMS/ppc64/* $CURDIR/build/
else
cp /root/rpmbuild/RPMS/noarch/* $CURDIR/build/
cp /root/rpmbuild/RPMS/x86_64/* $CURDIR/build/
cp /root/rpmbuild/RPMS/ppc64/* $CURDIR/build/
fi
#begin to create repo for redhat platform
grep -i 'Red' /etc/issue;
if [ "$OSNAME" != "AIX" -a $? -eq 0 ]; then
cat >$CURDIR/build/xCAT-core.repo << EOF
[xcat-2-core]
name=xCAT 2 Core packages
baseurl=file://$CURDIR/build
enabled=1
gpgcheck=0
EOF
cp $CURDIR/build/xCAT-core.repo /etc/yum.repos.d/
createrepo $CURDIR/build
else
rm -f /etc/zypp/repos.d/xCAT-core.repo
zypper ar file://$CURDIR/build xCAT-core
fi
fi
+3
View File
@@ -10,6 +10,9 @@
<packagereq type="required">xCAT-server</packagereq>
<packagereq type="required">xCAT-client</packagereq>
<packagereq type="required">perl-xCAT</packagereq>
<packagereq type="required">xCAT-nbroot-core-x86_64</packagereq>
<packagereq type="required">xCAT-nbroot-core-x86</packagereq>
<packagereq type="optional">xCAT-nbroot-core-ppc64</packagereq>
</packagelist>
</group>
</comps>
+4 -27
View File
@@ -32,7 +32,7 @@ function makenoarch {
# Make one of the following rpms: xCAT, xCATsn, xCAT-buildkit, xCAT-OpenStack
# Make one of the following rpms: xCAT, xCATsn, xCAT-buildkit
function makexcat {
if [ "$OSNAME" != "AIX" -a "$1" != "xCAT-buildkit" -a -z "$2" ]; then
echo 'Usage: makerpm <RPMname> <arch> [<embedded-system>]'
@@ -53,7 +53,6 @@ function makexcat {
tar -X /tmp/xcat-excludes -cf $RPMROOT/SOURCES/templates.tar templates
gzip -f $RPMROOT/SOURCES/templates.tar
cp xcat.conf $RPMROOT/SOURCES
cp xcat.conf.apach24 $RPMROOT/SOURCES
cp xCATMN $RPMROOT/SOURCES
else # xCATsn
tar -X /tmp/xcat-excludes -cf $RPMROOT/SOURCES/license.tar LICENSE.html
@@ -76,24 +75,19 @@ function makexcat {
tar --exclude .svn --exclude upflag -czf $RPMROOT/SOURCES/postscripts.tar.gz postscripts LICENSE.html
tar --exclude .svn -czf $RPMROOT/SOURCES/prescripts.tar.gz prescripts
tar --exclude .svn -czf $RPMROOT/SOURCES/templates.tar.gz templates
tar --exclude .svn -czf $RPMROOT/SOURCES/winpostscripts.tar.gz winpostscripts
cp xcat.conf $RPMROOT/SOURCES
cp xcat.conf.apach24 $RPMROOT/SOURCES
cp xCATMN $RPMROOT/SOURCES
cd - >/dev/null
elif [ "$RPMNAME" = "xCATsn" ]; then
cd `dirname $0`/$RPMNAME
tar --exclude .svn -czf $RPMROOT/SOURCES/license.tar.gz LICENSE.html
cp xcat.conf $RPMROOT/SOURCES
cp xcat.conf.apach24 $RPMROOT/SOURCES
cp xCATSN $RPMROOT/SOURCES
cd - >/dev/null
elif [ "$RPMNAME" = "xCAT-buildkit" ]; then
ARCH="noarch"
TARGET=""
tar --exclude .svn --exclude xCAT-buildkit.spec -czf $RPMROOT/SOURCES/$RPMNAME-$VER.tar.gz $RPMNAME
elif [ "$RPMNAME" = "xCAT-OpenStack" ]; then
tar --exclude .svn --exclude xCAT-OpenStack.spec -czf $RPMROOT/SOURCES/$RPMNAME-$VER.tar.gz $RPMNAME
else # do not recognize rpm
echo "Unrecognized rpm: $RPMNAME"
exit 2
@@ -106,23 +100,7 @@ function makexcat {
fi
}
# make ironic rpm for ironic baremetal driver
function makeironic {
RPMNAME="$1"
ARCH="$2"
cd `dirname $0`/$RPMNAME
cp -rf ironic_baremetal /tmp/
cd /tmp/ironic_baremetal
git init
git add *
git commit -a -m "generate rpm"
python setup.py bdist_rpm
rm -rf $RPMROOT/RPMS/$ARCH/
mkdir -p $RPMROOT/RPMS/$ARCH/
cp -rf dist/*.rpm $RPMROOT/RPMS/$ARCH/
rm -rf /tmp/ironic_baremetal
}
# Make the xCAT-nbroot-core rpm
function makenbroot {
@@ -222,7 +200,8 @@ else # linux
fi
fi
if [ "$1" = "xCAT" -o "$1" = "xCATsn" -o "$1" = "xCAT-buildkit" -o "$1" = "xCAT-OpenStack" ]; then
if [ "$1" = "xCAT" -o "$1" = "xCATsn" -o "$1" = "xCAT-buildkit" ]; then
exportEmbed $3
makexcat $1 $2
elif [ "$1" = "xCAT-nbroot" -o "$1" = "xCAT-nbroot-core" ]; then
@@ -234,8 +213,6 @@ elif [ "$1" = "xCAT-genesis-builder" ]; then
elif [ "$1" = "xCAT-genesis-scripts" ]; then
exportEmbed $3
makegenesisscripts $1 $2
elif [ "$1" = "xCAT-OpenStack-ironic" ]; then
makeironic $1 $2
else # must be one of the noarch rpms
exportEmbed $2
makenoarch $1
-6
View File
@@ -262,12 +262,6 @@ expression B<($1-1)%14+1> will evaluate to B<6>.
See http://www.perl.com/doc/manual/html/pod/perlre.html for information on perl regular expressions.
=head2 Easy Regular Expressions
As of xCAT 2.8.1, you can use a modified version of the regular expression support described in the previous section. You do not need to enter the node information (1st part of the expression), it will be derived from the input nodename. You only need to supply the 2nd part of the expression to determine the value to give the attribute. For examples, see
https://sourceforge.net/p/xcat/wiki/Listing_and_Modifying_the_Database/#easy-regular-expressions
=head1 OBJECT DEFINITIONS
Because it can get confusing what attributes need to go in what tables, the xCAT database can also
+1 -1
View File
@@ -1,7 +1,7 @@
Source: perl-xcat
Section: libs
Priority: extra
Maintainer: xCAT <xcat-user@lists.sourceforge.net>
Maintainer: Arif Ali <aali@ocf.co.uk>
Build-Depends: debhelper (>= 5), libsoap-lite-perl, libdbi-perl
Standards-Version: 3.7.2
+1 -1
View File
@@ -14,6 +14,7 @@ export DH_COMPAT=5
build:
dh_testdir
./modifyUtils `cat ../Version` `svn info | grep Revision | cut -d" " -f 2`
./db2man
clean:
@@ -48,7 +49,6 @@ binary-arch: build install
chmod 644 `pwd`/debian/perl-xcat/opt/xcat/share/doc/man5/*
chmod 644 `pwd`/debian/perl-xcat/opt/xcat/share/man/man7/*
chmod 644 `pwd`/debian/perl-xcat/opt/xcat/share/doc/man7/*
./modifyUtils `cat ../Version` `git log -n 1 | head -n 1 | cut -f 2 -d ' '`
# dh_installmenu
# dh_installdebconf
# dh_installlogrotate
+17 -10
View File
@@ -3,25 +3,32 @@
if [ -z "$2" ]
then
echo "modifyUtils: Error: must specify the xCAT version as an argument" >&2
echo "modifyUtils: Error: must specify the xCAT version and svn revision number as arguments" >&2
exit
fi
VER=$1
GITREF="git commit $2, "
SVNREF="svn r$2, "
#SVNINFO=`svn info 2>/dev/null|grep Revision`
#/bin/echo -e $SVNINFO
#if [ $? -ne 0 -a -f .svninfo ]; then
# SVNINFO=`cat .svninfo 2>/dev/null|grep Revision`
#fi
#if [ $? -eq 0 ]
# then
# SVNREF="svn r"`echo $SVNINFO|awk '{print $2}'`", "
# else
# SVNREF=""
# fi
BUILDDATE=`date`
#echo ". '(built $BUILDDATE)'"
#echo ". '(${SVNREF}built $BUILDDATE)'"
if [ "$(uname)" = "AIX" ]
then
sed -e s/"#XCATVERSIONSUBHERE"/". '$VER'"/ -e s/"#XCATSVNBUILDSUBHERE"/". ' (${GITREF}built $BUILDDATE)'"/ xCAT/Version.pm >xCAT/Version.pm.new
sed -e s/"#XCATVERSIONSUBHERE"/". '$VER'"/ -e s/"#XCATSVNBUILDSUBHERE"/". ' (${SVNREF}built $BUILDDATE)'"/ xCAT/Version.pm >xCAT/Version.pm.new
mv xCAT/Version.pm.new xCAT/Version.pm
else
if [ -f "/etc/debian_version" ];then
FILENAME="debian/perl-xcat/opt/xcat/lib/perl/xCAT/Version.pm"
else
FILENAME="xCAT/Version.pm"
fi
sed -i -e s/"#XCATVERSIONSUBHERE"/". '$VER'"/ -e s/"#XCATSVNBUILDSUBHERE"/". ' (${GITREF}built $BUILDDATE)'"/ $FILENAME
sed -i -e s/"#XCATVERSIONSUBHERE"/". '$VER'"/ -e s/"#XCATSVNBUILDSUBHERE"/". ' (${SVNREF}built $BUILDDATE)'"/ xCAT/Version.pm
fi
+2 -3
View File
@@ -23,10 +23,9 @@ Provides: perl-xCAT = %{epoch}:%{version}
Provides perl xCAT libraries for core functionality. Required for all xCAT installations.
Includes xCAT::Table, xCAT::NodeRange, among others.
%define gitinfo %(git log -n 1 | head -n 1 | cut -f 2 -d ' ')
%define zvm %(if [ "$zvm" = "1" ];then echo 1; else echo 0; fi)
%define fsm %(if [ "$fsm" = "1" ];then echo 1; else echo 0; fi)
%define svninfo %(svn info | grep Revision | awk '{print $2}')
%prep
%setup -q -n perl-xCAT
@@ -38,7 +37,7 @@ Includes xCAT::Table, xCAT::NodeRange, among others.
%if %fsm
%else
# Modify the Version() function in xCAT/Utils.pm to automatically have the correct version
./modifyUtils %{version} %{gitinfo}
./modifyUtils %{version} %{svninfo}
# Build the pod version of the man pages for each DB table. It puts them in the man5 and man7 subdirs.
# Then convert the pods to man pages and html pages.
+20 -138
View File
@@ -191,12 +191,7 @@ sub updateUserInfo {
{
for my $record (@diff)
{
# skip to add ROOT relative records into MERGE file
if ($record =~ /^root/)
{
next;
}
print $fp "$record\n";
print $fp "$record\n";
}
}
close ($fp);
@@ -235,13 +230,24 @@ sub setCFMSynclistFile {
# get the cfmdir and synclists attributes
my $osimage_t = xCAT::Table->new('osimage');
my $records = $osimage_t->getAttribs({imagename=>$img}, 'cfmdir', 'synclists');
if (defined ($records->{'cfmdir'}))
if ($records)
{
$cfmdir = $records->{'cfmdir'};
if (defined ($records->{'synclists'})) {$synclists = $records->{'synclists'}}
if ($records->{'cfmdir'}) {$cfmdir = $records->{'cfmdir'}}
if ($records->{'synclists'}) {$synclists = $records->{'synclists'}}
} else {
# no cfmdir defined, return directly
return 0;
if ($::VERBOSE)
{
my $rsp = {};
$rsp->{data}->[0] = "There are no records for cfmdir and synclists attribute in the osimage:$img. There is nothing to process.";
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
}
return;
}
# no cfmdir defined, return directly
if (!$cfmdir)
{
return;
}
my $found = 0;
@@ -363,8 +369,7 @@ sub updateCFMSynclistFile {
# recursively list the files under cfm directory
my @files = ();
find ( { wanted => sub { push @files, $File::Find::name if -f }, follow => 1 }, $cfmdir);
find ( sub { push @files, $File::Find::name if (! -d) }, $cfmdir);
if (!@files) # not files under cfm directory, skip to next loop
{
next;
@@ -500,7 +505,6 @@ sub setCFMPkglistFile {
Arguments:
$imagename - the specified linuximage name
@curospkgs - the currently selected OS packages list
$mode - using Fuzzy Matching or Exact Matching to check packages
Returns:
0 - update successfully
1 - update failed
@@ -510,22 +514,13 @@ sub setCFMPkglistFile {
none
Example:
my $ret = CAT::CFMUtils->updateCFMPkglistFile($imagename, @cur_selected_pkgs);
my $ret = CAT::CFMUtils->updateCFMPkglistFile($imagename, @cur_selected_pkgs, 1);
=cut
#-----------------------------------------------------------------------------
sub updateCFMPkglistFile {
my ($class, $img, $ospkgs, $mode) = @_;
if(defined($mode)){
# Exact Matching
$mode = 1;
}else {
# Fuzzy Matching
$mode = 0;
}
my ($class, $img, $ospkgs) = @_;
my @cur_selected = @$ospkgs;
my $cfmpkglist = "/install/osimages/$img/pkglist.cfm";
@@ -559,14 +554,6 @@ sub updateCFMPkglistFile {
my @selected = @$selected_ref;
@basepkgs = xCAT::CFMUtils->arrayops("U", \@basepkgs, \@selected);
}
# Fuzzy Matching
if (not $mode){
my ($ref1, $ref2, $ref3) = xCAT::CFMUtils->updateSelectedPkgs(\@pre_selected, \@pre_removed, \@cur_selected);
@pre_selected = @$ref1;
@pre_removed = @$ref2;
@cur_selected = @$ref3;
}
# get diff between previous and current selected OS packages lists
my @diff = xCAT::CFMUtils->getPkgsDiff(\@pre_selected, \@cur_selected);
@@ -679,48 +666,6 @@ sub getPreOSpkgsList {
return (\@selected, \@removed);
}
#-----------------------------------------------------------------------------
=head3 getPreBaseOSpkgsList
Get previously selected and removed base OS packages lists from pkglist file. Packages named with "example.xxx" should be the base name "example"
Arguments:
$ospkglist - the path for ospkglist file
Returns:
refs for selected and removed OS packages arrays
Globals:
none
Error:
none
Example:
my $pre_selected_ref = xCAT::CFMUtils->getPreOSpkgsList($ospkglist);
=cut
#-----------------------------------------------------------------------------
sub getPreBaseOSpkgsList {
my ($class, $pkglist) = @_;
my ($pre_selected_ref, $pre_removed_ref) = xCAT::CFMUtils->getPreOSpkgsList($pkglist);
my %pre_selected_hash = ();
foreach (@$pre_selected_ref) {
my @names = split(/\./, $_);
my $basename = $names[0];
if ($_ =~ /^$basename\.([^\.]+)$/) {
$pre_selected_hash{$basename} = 1;
}else {
$pre_selected_hash{$_} = 1;
}
}
my @pre_selected = keys %pre_selected_hash;
return \@pre_selected;
}
#-----------------------------------------------------------------------------
=head3 getPkgsDiff
@@ -879,66 +824,3 @@ sub arrayops {
#return (\@union, \@intersection, \@difference);
}
#-----------------------------------------------------------------------------
=head3 updateSelectedPkgs
Update previous selected, previous removed and current selected packages based on fuzzy matching rules. Packages named with "example.i686" should be same with package "example"
Arguments:
\@pre_selected - reference to previous selected packages
\@pre_removed - reference to previous removed packages
\@cur_selected - reference to current selected packages
Returns:
new previous selected, previous removed, current selected packages
Globals:
none
Error:
none
Example:
my ($ref1, $ref2, $ref3) = xCAT::CFMUtils->arrayops(\@pre_selected, \@pre_removed, \@cur_selected);
=cut
#-----------------------------------------------------------------------------
sub updateSelectedPkgs() {
my ($class, $pre_selected_ref, $pre_removed_ref, $cur_selected_ref) = @_;
my %pre_selected_hash = map{$_ => 1} @$pre_selected_ref;
my %pre_removed_hash = map{$_ => 1} @$pre_removed_ref;
my %cur_selected_hash = map{$_ => 1} @$cur_selected_ref;
my %new_pre_selected_hash = %pre_selected_hash;
my %new_pre_removed_hash = %pre_removed_hash;
my %new_cur_selected_hash = %cur_selected_hash;
foreach (keys %cur_selected_hash) {
my $father = $_;
my $flag = 0;
foreach (keys %pre_selected_hash) {
my $child = $_;
if ($child =~ /^$father\.([^\.]+)$/) {
$new_cur_selected_hash{$child} = 1;
$flag = 1;
}
}
if ($flag and not exists $pre_selected_hash{$father}){
delete $new_cur_selected_hash{$father} if exists $new_cur_selected_hash{$father};
}
foreach (keys %pre_removed_hash) {
my $child = $_;
if ($child =~ /^$father\.([^\.]+)$/) {
delete $new_pre_removed_hash{$child} if exists $new_pre_removed_hash{$child};
}
}
}
my @new_cur_selected = keys %new_cur_selected_hash;
my @new_pre_selected = keys %new_pre_selected_hash;
my @new_pre_removed = keys %new_pre_removed_hash;
return (\@new_pre_selected, \@new_pre_removed, \@new_cur_selected);
}
+13 -113
View File
@@ -8,11 +8,9 @@ BEGIN
# if AIX - make sure we include perl 5.8.2 in INC path.
# Needed to find perl dependencies shipped in deps tarball.
use Storable qw/nstore_fd fd_retrieve/;
if ($^O =~ /^aix/i) {
unshift(@INC, qw(/usr/opt/perl5/lib/5.8.2/aix-thread-multi /usr/opt/perl5/lib/5.8.2 /usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi /usr/opt/perl5/lib/site_perl/5.8.2));
}
use IO::Handle;
my $inet6support;
if ($^O =~ /^aix/i) { # disable AIX IPV6 TODO fix
@@ -29,7 +27,7 @@ if ($inet6support) {
if ($^O =~ /^linux/i) {
# Is IPv6 enabled on the MN or xcat client node at all?
my $ipv6enabled = `ip addr 2> /dev/null | grep inet6`;
my $ipv6enabled = `ip addr | grep inet6`;
if (!$ipv6enabled) {
$inet6support = 0;
}
@@ -79,23 +77,6 @@ sub rspclean {
}
return 0;
}
sub send_request {
my $request = shift;
my $sock = shift;
my $encode = shift;
if ($encode eq "xml") {
my $msg=XMLout($request,RootName=>'xcatrequest',NoAttr=>1,KeyAttr=>[]);
if ($ENV{XCATXMLTRACE}) { print $msg; }
if($ENV{XCATXMLWARNING}) {
validateXML($msg);
}
print $sock $msg;
$sock->flush();
} else {
nstore_fd($request,$sock);
$sock->flush();
}
}
#################################
# submit_request will take an xCAT command and pass it to the xCAT
# server for execution.
@@ -198,28 +179,11 @@ if (ref($request) eq 'HASH') { # the request is an array, not pure XML
if ($ENV{XCATHOST}) {
$xcathost=$ENV{XCATHOST};
}
my %connargs=();
if ($xcathost =~ s/%([^\]|:]*)//) {
$connargs{PeerScope} = $1;
}
$connargs{PeerAddr} = $xcathost;
$connargs{Timeout} = 15;
if ($connargs{PeerScope} and $connargs{PeerScope} =~ /[a-zA-Z]/) { #non-numeric, need to translate...
my @ipdata = `ip link`;
@ipdata = grep(/[^@]$connargs{PeerScope}(:|@)/,@ipdata);
if (scalar(@ipdata) != 1) {
print STDERR "Unable to identify scope ".$connargs{PeerScope}."\n";
exit(1);
}
$connargs{PeerScope} = $ipdata[0];
$connargs{PeerScope} =~ s/:.*//;
}
my $pclient;
if ($inet6support) {
$pclient = IO::Socket::INET6->new(
%connargs,
PeerAddr => $xcathost,
Timeout => 15,
);
} else {
$pclient = IO::Socket::INET->new(
@@ -242,7 +206,6 @@ if (ref($request) eq 'HASH') { # the request is an array, not pure XML
SSL_key_file => $keyfile,
SSL_cert_file => $certfile,
SSL_ca_file => $cafile,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_use_cert => 1,
Timeout => 0,
);
@@ -251,37 +214,21 @@ if (ref($request) eq 'HASH') { # the request is an array, not pure XML
Timeout => 0,
);
}
unless ($client) {
print "Unable to open socket connection to xcatd daemon on $xcathost.\n";
print "Verify that the xcatd daemon is running and that your SSL setup is correct.\n";
if ($@ =~ /SSL Timeout/) {
die "Connection failure: SSL Timeout or incorrect certificates in ~/.xcat";
} else {
die "Connection failure: $@"
}
}
my $msg;
my $encode = "xml";
#storable encoding is unsafe, carry on with the unsafe xml scheme
#perhaps one day will support faster schemes
#my $encode = "storable";
#my $straightprint=0;
#if ($ENV{XCATXMLTRACE} or $ENV{XCATXMLWARNING}) { $encode="xml"; }
if (ref($request) eq 'HASH') { # the request is an array, not pure XML
#print $client "xcatencoding: $encode\n";
#my $encok=<$client>;
send_request($request,$client,$encode);
$msg=XMLout($request,RootName=>'xcatrequest',NoAttr=>1,KeyAttr=>[]);
} else { #XML
$straightprint=1;
$msg=$request;
print $client $msg;
}
$SIG{TERM} = $SIG{INT} = sub { send_request({abortcommand=>[1]},$client,$encode); exit 0; };
if ($ENV{XCATXMLTRACE}) { print $msg; }
if($ENV{XCATXMLWARNING}) {
validateXML($msg);
}
$SIG{TERM} = $SIG{INT} = sub { print $client XMLout({abortcommand=>1},RootName=>'xcatrequest',NoAttr=>1,KeyAttr=>[]); exit 0; };
print $client $msg;
my $response;
my $rsp;
my $cleanexit=0;
if ($encode eq 'xml') {
my $massresponse="<massresponse>";
my $nextcoalescetime=time()+1;
my $coalescenow=0;
@@ -335,31 +282,9 @@ if (ref($request) eq 'HASH') { # the request is an array, not pure XML
$massresponse .= "</massresponse>";
$cleanexit = rspclean($massresponse,$callback);
}
} else { #storable encode
my $rsp;
eval { $rsp = fd_retrieve($client); };
SERVERINPUT: while ($rsp) {
my @rsps;
if (ref $rsp eq 'ARRAY') {
@rsps = @$rsp;
} else {
@rsps = ($rsp);
}
foreach (@rsps) {
$callback->($_);
if ($_->{serverdone}) {
$cleanexit=1;
last SERVERINPUT;
}
}
$rsp = undef;
eval { $rsp = fd_retrieve($client); };
}
}
$massresponse="";
unless ($cleanexit) {
print STDERR "ERROR/WARNING: communication with the xCAT server seems to have been ended prematurely\n";
$xCAT::Client::EXITCODE = 1;
}
sub validateXML {
@@ -672,10 +597,7 @@ sub plugin_command {
no strict "refs";
# eval { #REMOVEEVALFORDEBUG
# if ($dispatch_requests) {
# backup the original req and recover it after the a run
my $org_req = {%$req};
dispatch_request($req,$callback,$modname);
$req = {%$org_req};
dispatch_request($req,$callback,$modname);
# } else {
# $SIG{CHLD}='DEFAULT';
# ${"xCAT_plugin::".$modname."::"}{process_request}->($req,$callback,\&do_request);
@@ -1159,12 +1081,7 @@ sub handle_response {
#print "printing node\n";
my $node;
foreach $node (@$nodes) {
my $desc;
if (ref($node->{name}) eq 'ARRAY') {
$desc=$node->{name}->[0];
} else {
$desc=$node->{name};
}
my $desc=$node->{name}->[0];
if ($node->{errorcode}) {
if (ref($node->{errorcode}) eq 'ARRAY') {
foreach my $ecode (@{$node->{errorcode}}) {
@@ -1184,24 +1101,7 @@ sub handle_response {
$errflg=1;
}
if ($node->{data}) {
if (ref(\($node->{data})) eq 'SCALAR') {
$desc=$desc.": ".$node->{data};
} elsif (ref($node->{data}) eq 'HASH') {
if ($node->{data}->{desc}) {
if (ref($node->{data}->{desc}) eq 'ARRAY') {
$desc=$desc.": ".$node->{data}->{desc}->[0];
} else {
$desc=$desc.": ".$node->{data}->{desc};
}
}
if ($node->{data}->{contents}) {
if (ref($node->{data}->{contents}) eq 'ARRAY') {
$desc="$desc: ".$node->{data}->{contents}->[0];
} else {
$desc="$desc: ".$node->{data}->{contents};
}
}
} elsif (ref(\($node->{data}->[0])) eq 'SCALAR') {
if (ref(\($node->{data}->[0])) eq 'SCALAR') {
$desc=$desc.": ".$node->{data}->[0];
} else {
if ($node->{data}->[0]->{desc}) {
Executable → Regular
+7 -22
View File
@@ -57,7 +57,7 @@ sub getObjectsOfType
# The database may be changed between getObjectsOfType calls
# do not use cache %::saveObjList if --nocache is specified
if ($::saveObjList{$type} && !$::opt_nc)
if ($::saveObjList{$type} && !$::opt_c)
{
@objlist = @{$::saveObjList{$type}};
}
@@ -200,8 +200,7 @@ sub getobjattrs
# list of object names
foreach my $table (keys %tableattrs) {
# open the table
# with autocommit => 0, it does not work on Ubuntu running mysql
my $thistable = xCAT::Table->new($table, -create => 1, -autocommit => 1);
my $thistable = xCAT::Table->new($table, -create => 1, -autocommit => 0);
if (!$thistable) {
my $rsp;
$rsp->{data}->[0] = "Could not open the \'$table\' table.";
@@ -607,7 +606,7 @@ sub getDBtable
# save this table info - in case this subr gets called multiple times
# --nocache flag specifies not to use cahe
if (grep(/^$table$/, @::foundTableList) && !$::opt_nc)
if (grep(/^$table$/, @::foundTableList) && !$::opt_c)
{
# already have this
@@ -618,7 +617,7 @@ sub getDBtable
{
# need to get info from DB
my $thistable = xCAT::Table->new($table, -create => 1);
my $thistable = xCAT::Table->new($table, -create => 1, -autocommit => 0);
if (!$thistable)
{
return undef;
@@ -1680,14 +1679,7 @@ sub readFileInput
$look_for_colon = 0; # ok - we have a colon
# Remove any trailing whitespace
$l =~ s/\s*$//;
# IPv6 network names could be something like fd59::/64
# Use all the characters before the last ":" as the object name
# .* means greedy regular expression
$l =~ /^(.*):(.*?)$/;
($objectname, $junk2) = ($1, $2);
($objectname, $junk2) = split(/:/, $l);
# if $junk2 is defined or there's an =
if ($junk2 || grep(/=/, $objectname))
@@ -2007,14 +1999,7 @@ sub getNetwkInfo
my @nodes = ("$node");
my $sn = xCAT::ServiceNodeUtils->get_ServiceNode(\@nodes,"xcat","Node");
my $snkey = (keys %{$sn})[0];
my $gw = xCAT::NetworkUtils->getipaddr($snkey);
# two possible cases when this code is run:
# 1. flat cluster: ip forwarding is not enabled on MN
# 2. hw ctrl in hierarchy cluster, in which HCP SN is not set
# in either case, MN itself should not be the gateway
if (xCAT::NetworkUtils->thishostisnot($gw)) {
$nethash{$node}{'gateway'} = $gw;
}
$nethash{$node}{'gateway'} = xCAT::NetworkUtils->getipaddr($snkey);
}
}
@@ -2747,7 +2732,7 @@ sub collapsenicsattr()
# e.g nicips.eth0
# do not need to handle nic attributes without the postfix .ethx,
# it will be overwritten by the attributes with the postfix .ethx,
if ($nodeattr =~ /^(nic\w+)\.(.*)$/)
if ($nodeattr =~ /^(nic\w+)\.(\w+)$/)
{
if ($1 && $2)
{
+89 -160
View File
@@ -598,7 +598,7 @@ sub _execute_dsh
}
else
{
# HERE: This is where the output shows up
# LKV: This is where the output shows up
#print STDOUT @{$output_buffers{$user_target}};
#print STDERR @{$error_buffers{$user_target}};
chomp(@{$output_buffers{$user_target}});
@@ -1019,19 +1019,11 @@ sub fork_fanout_dsh
}
}
}
# save the original exports, we are going to add the unique node name below
my $firstpass=0;
while (@$targets_waiting
&& (keys(%$targets_active) < $$options{'fanout'}))
{
my $user_target = shift @$targets_waiting;
# now add export NODE=nodename to the pre-command, if not a device;
my $exportnode;
if (($$options{'devicetype'})) {
$exportnode="";
} else{
$exportnode="export NODE=$user_target; ";
}
my $target_properties = $$resolved_targets{$user_target};
my @commands;
my $localShell =
@@ -1045,9 +1037,9 @@ sub fork_fanout_dsh
$$options{'post-command'} = "";
$dsh_cmd_background = 1;
}
if ($$options{'environment'})
{
if ($firstpass ==0) { # do the servicenode stuff only once
# if we are on a servicenode need to get the environment file
# from the SNsyncfiledir, not local
if (xCAT::Utils->isServiceNode()) {
@@ -1070,17 +1062,14 @@ sub fork_fanout_dsh
$rsp->{error}->[0] = "File $$options{'environment'} does not exist";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
}
$firstpass=1;
}
# build the xdsh command
push @dsh_command,
"$exportnode$$options{'pre-command'} . $$options{'environment'} ; $$options{'command'}$$options{'post-command'}";
push @dsh_command,
"$$options{'pre-command'} . $$options{'environment'} ; $$options{'command'}$$options{'post-command'}";
}
else
{
push @dsh_command,
"$exportnode$$options{'pre-command'}$$options{'command'}$$options{'post-command'}";
"$$options{'pre-command'}$$options{'command'}$$options{'post-command'}";
}
if ($$target_properties{'localhost'})
@@ -1148,7 +1137,7 @@ sub fork_fanout_dsh
#eval "require RemoteShell::$rsh_extension";
eval "require xCAT::$rsh_extension";
$rsh_config{'command'} = "$exportnode$$options{'pre-command'}";
$rsh_config{'command'} = "$$options{'pre-command'}";
my $tmp_env_file;
# for the -E flag here we build and copy the -E env variable
# file to the nodes
@@ -2349,14 +2338,10 @@ sub config_dsh
}
}
else
{
# if not Mellanox, it does not need a config file
if (!($$options{'devicetype'} =~ /Mellanox/i)) {
my $rsp = {};
$rsp->{error}->[0] = "The config file: $devicepath is missing";
xCAT::MsgUtils->message('E', $rsp, $::CALLBACK);
}
$rsp->{error}->[0] = "EMsgMISSING_DEV_CFG";
xCAT::MsgUtils->message('E', $rsp, $::CALLBACK);
}
}
@@ -3241,17 +3226,7 @@ sub bld_resolve_nodes_hash
# find out if we have an MN in the list, local cp and sh will be used
# not remote shell
# find out the names for the Management Node
my @MNnodeinfo = xCAT::NetworkUtils->determinehostname;
my $mname = pop @MNnodeinfo; # hostname
my $cmd="hostname";
my $localhostname = xCAT::Utils->runcmd($cmd,0);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{info}->[0] = "Command: $cmd failed. Continuing...";
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
}
my $mname = xCAT::Utils->noderangecontainsMn(@target_list);
foreach my $target (@target_list)
{
@@ -3260,9 +3235,11 @@ sub bld_resolve_nodes_hash
my $localhost;
my $user;
my $context = "XCAT";
# check to see if this node is the Management Node we are on, can run local commands (sh,cp)
if (($mname eq $target) || ($localhostname eq $target)){
# check to see if this node is the Management Node
if ($mname) {
if ($mname eq $target) {
$localhost=$target;
}
}
my %properties = (
'hostname' => $hostname,
@@ -3997,7 +3974,8 @@ sub parse_and_run_dsh
{
$options{'user'} = $ENV{'DSH_TO_USERID'};
}
if ((!(defined($nodes))) && (!(defined($options{'rootimg'}))))
if ((!(defined(@$nodes))) && (!(defined($options{'rootimg'}))))
{ # no nodes and not -i option, error
my $rsp = ();
$rsp->{error}->[0] = "Unless using -i option, noderange is required.";
@@ -4036,7 +4014,7 @@ sub parse_and_run_dsh
{ # from sinv, discard this name
undef @$nodes;
}
if (@$nodes[0])
if (defined(@$nodes))
{
my $rsp = {};
$rsp->{error}->[0] =
@@ -4090,12 +4068,11 @@ sub parse_and_run_dsh
# check if any node in the noderange is the Management Node and exit
# with error, if the Management Node is in the Database and in the
# noderange
my @mname = xCAT::Utils->noderangecontainsMn(@nodelist);
if (@mname) { # MN in the nodelist
my $nodes=join(',', @mname);
my $mname = xCAT::Utils->noderangecontainsMn(@nodelist);
if ($mname) { # MN in the nodelist
my $rsp = {};
$rsp->{error}->[0] =
"You must not run -K option against the Management Node:$nodes.";
"You must not run -K option against the Management Node:$mname.";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
return;
}
@@ -4197,7 +4174,7 @@ sub parse_and_run_dsh
#
# setup ssh keys on the nodes or ib switch
#
my $rc = xCAT::TableUtils->setupSSH($options{'nodes'},$options{'timeout'});
my $rc = xCAT::TableUtils->setupSSH($options{'nodes'});
my @results = "return code = $rc";
return (@results);
}
@@ -4407,16 +4384,8 @@ sub parse_and_run_dcp
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
return;
}
if (@$nodes[0])
{
my $rsp = {};
$rsp->{error}->[0] =
"Input noderange:@$nodes and any other xdsh flags or environment variables are not valid with -i flag.";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
return;
}
}
if ((!(defined($nodes))) && (!(defined($options{'rootimg'}))))
if ((!(defined(@$nodes))) && (!(defined($options{'rootimg'}))))
{ # no nodes and not -i option, error
my $rsp = {};
$rsp->{error}->[0] = "Unless using -i option, noderange is required.";
@@ -4513,7 +4482,7 @@ sub parse_and_run_dcp
#
# build list of nodes
my @nodelist;
if (@$nodes[0])
if (defined(@$nodes))
{ # there are nodes
@nodelist = @$nodes;
$options{'nodes'} = join(',', @nodelist);
@@ -4717,42 +4686,21 @@ sub parse_and_run_dcp
my $ranpostscripts;
my $ranappendscripts;
my $ranmergescripts;
# if we were called with runxcmd, like by updatenode
# need to save the runxcmd buffer
# $::xcmd_outref
my $save_xcmd_outref;
if ($::xcmd_outref) { # this means we were called with runxcmd
$save_xcmd_outref = $::xcmd_outref;
}
if ((@::postscripts) && ($::SYNCSN == 0)) {
@results2 = &run_rsync_postscripts(\@results,$synfiledir,\%options);
@results2 = &run_rsync_postscripts(\@results,$synfiledir);
$ranpostscripts=1;
}
if ((@::alwayspostscripts) && ($::SYNCSN == 0)) {
@results3 = &run_always_rsync_postscripts(\@nodelist,$synfiledir,\%options);
@results3 = &run_always_rsync_postscripts(\@nodelist,$synfiledir);
}
if (($::appendscript) && ($::SYNCSN == 0)) {
@results4 = &bld_and_run_append(\@nodelist,\@results,$synfiledir,$nodesyncfiledir,\%options);
@results4 = &bld_and_run_append(\@nodelist,\@results,$synfiledir,$nodesyncfiledir);
$ranappendscripts=1;
}
if (($::mergescript) && ($::SYNCSN == 0)) {
@results5 = &bld_and_run_merge(\@nodelist,\@results,$synfiledir,$nodesyncfiledir,\%options);
@results5 = &bld_and_run_merge(\@nodelist,\@results,$synfiledir,$nodesyncfiledir);
$ranmergescripts=1;
}
# restore the runxcmd buffer
if ($save_xcmd_outref) { # this means we were called with runxcmd
$::xcmd_outref = $save_xcmd_outref;
}
# TODO, will we ever need to merge
# if we ran a postscript and we were run
# using runxcmd, and there was previous output in the
# runxcmd buffer and we have output from the postscript
# then we have to merge the outputs
#if (($ranaps == 1) && ($save_xcmd_outref) && ($::xcmd_outref) ) {
# &mergeoutput($save_xcmd_outref);
#}
my @newresults;
if (@results2) {
@newresults = (@results2);
@@ -4767,14 +4715,9 @@ sub parse_and_run_dcp
@newresults = (@newresults,@results3,@results4,@results5);
}
if (@newresults) {
if ($save_xcmd_outref) { # this means we were called with runxcmd
foreach my $line (@newresults) {
push @$::xcmd_outref,$line;
}
}
return (@newresults);
} else {
# don't report other results for postscripts,appendscripts,mergescripts because
# don't report results for postscripts,appendscripts,mergescripts because
# you get all the rsync returned lines
if (($ranpostscripts == 0 ) && ($ranappendscripts == 0)
&& ($ranmergescripts == 0)) {
@@ -4983,8 +4926,7 @@ sub parse_rsync_input_file_on_MN
$::process_line = 0;
my $destfileisdir;
my $clause=0;
my $addmergescript =0;
my $addappendscript =0;
open(INPUTFILE, "< $input_file") || die "File $input_file does not exist\n";
while (my $line = <INPUTFILE>)
{
@@ -5025,16 +4967,12 @@ sub parse_rsync_input_file_on_MN
# this triggers the running of the appendscript
$::appendscript ="/opt/xcat/share/xcat/scripts/xdcpappend.sh";
}
# add the append script to the sync
if ($addappendscript == 0) { # only add once
my $appscript ="/opt/xcat/share/xcat/scripts/xdcpappend.sh";
my $appendscriptline = "$appscript -> $appscript";
$syncappendscript=1; # syncing the xdcpappend.sh script
&build_append_rsync($appendscriptline,$nodes, $options, $input_file,$rsyncSN, $syncdir,$nodesyncfiledir,$onServiceNode,$syncappendscript);
$addappendscript=1;
}
} # end APPEND clause
my $appscript ="/opt/xcat/share/xcat/scripts/xdcpappend.sh";
my $appendscriptline = "$appscript -> $appscript";
$syncappendscript=1; # syncing the xdcpappend.sh script
&build_append_rsync($appendscriptline,$nodes, $options, $input_file,$rsyncSN, $syncdir,$nodesyncfiledir,$onServiceNode,$syncappendscript);
}
if ($clause =~ /MERGE:/) {
# location of the base merge script
# for MERGE we have to sync the mergescript and the
@@ -5046,16 +4984,12 @@ sub parse_rsync_input_file_on_MN
# this triggers the running of the mergescript
$::mergescript ="/opt/xcat/share/xcat/scripts/xdcpmerge.sh";
}
# add the merge script to the sync
if ($addmergescript == 0) { # only add once
my $mergescript ="/opt/xcat/share/xcat/scripts/xdcpmerge.sh";
my $mergescriptline = "$mergescript -> $mergescript";
$syncmergescript=1; # syncing the xdcpmerge.sh script
&build_merge_rsync($mergescriptline,$nodes, $options, $input_file,$rsyncSN, $syncdir,$nodesyncfiledir,$onServiceNode,$syncmergescript);
$addmergescript=1;
}
} # end MERGE clause
my $mergescript ="/opt/xcat/share/xcat/scripts/xdcpmerge.sh";
my $mergescriptline = "$mergescript -> $mergescript";
$syncmergescript=1; # syncing the xdcpmerge.sh script
&build_merge_rsync($mergescriptline,$nodes, $options, $input_file,$rsyncSN, $syncdir,$nodesyncfiledir,$onServiceNode,$syncmergescript);
}
}
} else { # not processing EXECUTE, EXECUTEALWAYS or APPEND
@@ -5219,7 +5153,6 @@ sub build_append_rsync
push @::appendlines,$line;
}
my $src_file = $1; # append file left of arror
my $orig_src_file = $1; # append file left of arror
# it will be sync'd to $nodesyncfiledir/$append_file
my $dest_file = $nodesyncfiledir;
$dest_file .= $src_file;
@@ -5248,7 +5181,7 @@ sub build_append_rsync
# to pick up files from /var/xcat/syncfiles...
if ($onServiceNode == 1) {
my $newsrcfile = $syncdir; # add SN syndir on front
$newsrcfile .= $orig_src_file;
$newsrcfile .= $src_file;
$src_file=$newsrcfile;
}
# destination file name
@@ -5331,8 +5264,7 @@ sub build_merge_rsync
if ($syncmergescript == 0) { # don't add the xdcpmerge.sh line
push @::mergelines,$line;
}
my $src_file = $1; # merge file left of arrow
my $orig_src_file = $1;
my $src_file = $1; # merge file left of arror
# it will be sync'd to $nodesyncfiledir/$merge_file
my $dest_file = $nodesyncfiledir;
$dest_file .= $src_file;
@@ -5361,7 +5293,7 @@ sub build_merge_rsync
# to pick up files from /var/xcat/syncfiles...
if ($onServiceNode == 1) {
my $newsrcfile = $syncdir; # add SN syndir on front
$newsrcfile .= $orig_src_file;
$newsrcfile .= $src_file;
$src_file=$newsrcfile;
}
# destination file name
@@ -5660,7 +5592,7 @@ sub parse_rsync_input_file_on_SN
sub run_rsync_postscripts
{
my ($rsyncoutput,$syncdir,$options) = @_;
my ($rsyncoutput,$syncdir) = @_;
my @rsync_output = @$rsyncoutput;
my @newoutput= ();
my $dshparms;
@@ -5703,26 +5635,27 @@ sub run_rsync_postscripts
# now if we have postscripts to run, run xdsh
my $out;
# if we were called with runxcmd, like by updatenode
# need to save the runxcmd buffer
# $::xcmd_outref
my $save_xcmd_outref;
if ($::xcmd_outref) { # this means we were called with runxcmd
$save_xcmd_outref = $::xcmd_outref;
}
# my $ranaps=0; # did we run a postscript
foreach my $ps ( keys %{$$dshparms{'postscripts'}}) {
my @nodes;
push (@nodes, @{$$dshparms{'postscripts'}{$ps}});
my @args=();
if ($$options{'nodestatus'}) {
push @args,"--nodestatus" ;
}
push @args,"-e";
# if on the service node need to add the $syncdir directory
# to the path
if (xCAT::Utils->isServiceNode()) {
my $tmpp=$syncdir . $ps;
$ps=$tmpp;
}
push @args,$ps;
$out=xCAT::Utils->runxcmd( { command => ['xdsh'],
$out=xCAT::Utils->runxcmd( { command => ['xdsh'],
node => \@nodes,
arg => \@args,
arg => [ "-e", $ps ]
}, $::SUBREQ, 0,1);
foreach my $r (@$out){
push(@newoutput, $r);
@@ -5730,6 +5663,18 @@ sub run_rsync_postscripts
}
# $ranaps=1;
}
# restore the runxcmd buffer
if ($save_xcmd_outref) { # this means we were called with runxcmd
$::xcmd_outref = $save_xcmd_outref;
}
# TODO, will we ever need to merge
# if we ran a postscript and we were run
# using runxcmd, and there was previous output in the
# runxcmd buffer and we have output from the postscript
# then we have to merge the outputs
#if (($ranaps == 1) && ($save_xcmd_outref) && ($::xcmd_outref) ) {
# &mergeoutput($save_xcmd_outref);
#}
return @newoutput;
}
#-------------------------------------------------------------------------------
@@ -5767,7 +5712,7 @@ sub run_rsync_postscripts
sub bld_and_run_append
{
my ($hostnames,$rsyncoutput,$syncdir,$nodesyncfiledir,$options) = @_;
my ($hostnames,$rsyncoutput,$syncdir,$nodesyncfiledir) = @_;
my @hosts = @$hostnames;
my @rsync_output = @$rsyncoutput;
my @newoutput= ();
@@ -5817,10 +5762,8 @@ sub bld_and_run_append
# that were rsyn'd to at least one node
if ($tmpappendfile eq $ps) {
my $parm="$appendfile:$filetoappend ";
# check to see if the parameter is already in the list
if (!($::xdcpappendparms =~ /$parm/)) {
$::xdcpappendparms .= $parm;
}
$::xdcpappendparms .= $parm;
$processappend=1;
}
@@ -5841,16 +5784,10 @@ sub bld_and_run_append
foreach my $ps ( keys %{$$dshparms{'appendscripts'}}) {
my @nodes;
push (@nodes, @{$$dshparms{'appendscripts'}{$ps}});
my @args=();
if ($$options{'nodestatus'}) {
push @args,"--nodestatus" ;
}
push @args,$ps;
push @args,$::xdcpappendparms;
$out=xCAT::Utils->runxcmd( { command => ['xdsh'],
node => \@nodes,
arg => \@args,
arg => [ $ps , $::xdcpappendparms ]
}, $::SUBREQ, 0,1);
foreach my $r (@$out){
push(@newoutput, $r);
@@ -5897,7 +5834,7 @@ sub bld_and_run_append
sub bld_and_run_merge
{
my ($hostnames,$rsyncoutput,$syncdir,$nodesyncfiledir,$options) = @_;
my ($hostnames,$rsyncoutput,$syncdir,$nodesyncfiledir) = @_;
my @hosts = @$hostnames;
my @rsync_output = @$rsyncoutput;
my @newoutput= ();
@@ -5956,10 +5893,8 @@ sub bld_and_run_merge
# that were rsyn'd to at least one node
if ($tmpmergefile eq $ps) {
my $parm="$mergefile:$filetomerge ";
# check to see if the parameter is already in the list
if (!($::xdcpmergeparms =~ /$parm/)) {
$::xdcpmergeparms .= $parm;
}
$::xdcpmergeparms .= $parm;
$processmerge=1;
}
@@ -5981,17 +5916,9 @@ sub bld_and_run_merge
my @nodes;
push (@nodes, @{$$dshparms{'mergescripts'}{$ps}});
# build the argument list
my @args=();
if ($$options{'nodestatus'}) {
push @args,"--nodestatus" ;
}
push @args, $ps;
push @args, $::xdcpmergeparms;
$out=xCAT::Utils->runxcmd( { command => ['xdsh'],
node => \@nodes,
arg => \@args,
arg => [ $ps , $::xdcpmergeparms ]
}, $::SUBREQ, 0,1);
foreach my $r (@$out){
push(@newoutput, $r);
@@ -6017,7 +5944,7 @@ sub bld_and_run_merge
sub run_always_rsync_postscripts
{
my ($hostnames,$syncdir,$options) = @_;
my ($hostnames,$syncdir) = @_;
my @hosts = @$hostnames;
my @newoutput= ();
my $dshparms;
@@ -6039,28 +5966,26 @@ sub run_always_rsync_postscripts
# now if we have postscripts to run, run xdsh
my $out;
# if we were called with runxcmd, like by updatenode
# need to save the runxcmd buffer
# $::xcmd_outref
my $save_xcmd_outref;
if ($::xcmd_outref) { # this means we were called with runxcmd
$save_xcmd_outref = $::xcmd_outref;
}
foreach my $ps ( keys %{$$dshparms{'postscripts'}}) {
my @nodes;
# build the argument list
my @args=();
if ($$options{'nodestatus'}) {
push @args,"--nodestatus" ;
}
push @args,"-e";
push (@nodes, @{$$dshparms{'postscripts'}{$ps}});
# if on the service node need to add the $syncdir directory
# to the path
if (xCAT::Utils->isServiceNode()) {
my $tmps=$syncdir . $ps;
push @args, $tmps;
} else{
push @args, $ps;
my $tmpp=$syncdir . $ps;
$ps=$tmpp;
}
push (@nodes, @{$$dshparms{'postscripts'}{$ps}});
$out=xCAT::Utils->runxcmd( { command => ['xdsh'],
$out=xCAT::Utils->runxcmd( { command => ['xdsh'],
node => \@nodes,
arg => \@args,
arg => [ "-e", $ps ]
}, $::SUBREQ, 0,1);
foreach my $r (@$out){
push(@newoutput, $r);
@@ -6068,6 +5993,10 @@ sub run_always_rsync_postscripts
}
}
# restore the runxcmd buffer
if ($save_xcmd_outref) { # this means we were called with runxcmd
$::xcmd_outref = $save_xcmd_outref;
}
return @newoutput;
}
+59 -13
View File
@@ -253,6 +253,64 @@ use strict;
#---------------------------------------------------------------------------
=head3
ifconfig_inet
Builds a list of all IP Addresses bound to the local host and
stores them in a global list
Arguments:
None
Returns:
None
Globals:
@local_inet
Error:
None
Example:
xCAT::DSHCore->ifconfig_inet;
Comments:
Internal routine only
=cut
#---------------------------------------------------------------------------
sub ifconfig_inet
{
my @local_inet = ();
if ($^O eq 'aix')
{
my @ip_address = ();
my @output = `/usr/sbin/ifconfig -a`;
foreach my $line (@output)
{
($line =~ /inet ((\d{1,3}?\.){3}(\d){1,3})\s/o)
&& (push @local_inet, $1);
}
}
elsif ($^O eq 'linux')
{
my @ip_address = ();
my @output = `/sbin/ifconfig -a`;
foreach my $line (@output)
{
($line =~ /inet addr:((\d{1,3}?\.){3}(\d){1,3})\s/o)
&& (push @local_inet, $1);
}
}
}
#---------------------------------------------------------------------------
@@ -696,20 +754,8 @@ sub pping_hostnames
my ($class, @hostnames) = @_;
my $hostname_list = join ",", @hostnames;
# read site table, usefping attribute
# if set then run pping -f to use fping
# this fixes a broken nmap in Redhat 6.2 with ip alias (3512)
my $cmd="$::XCATROOT/bin/pping $hostname_list"; # default
my @usefping=xCAT::TableUtils->get_site_attribute("usefping");
if ((defined($usefping[0])) && ($usefping[0] eq "1")) {
$cmd = "$::XCATROOT/bin/pping -f $hostname_list";
}
#my $rsp={};
#$rsp->{data}->[0] = "running command $cmd";
#xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
my @output =
xCAT::Utils->runcmd($cmd, -1);
xCAT::Utils->runcmd("$::XCATROOT/bin/pping $hostname_list", -1);
if ($::RUNCMD_RC !=0) {
my $rsp={};
$rsp->{error}->[0] = "Error from pping";
+1 -1
View File
@@ -39,7 +39,7 @@ sub update_discovery_data {
$disdata{'discoverytime'} = $currtime;
foreach my $attr (keys %$request) {
if ($attr =~ /^(command|discoverymethod|_xcat|cacheonly|noderange|environment|method|discoverytime|updateswitch)/) {
if ($attr =~ /^(command|discoverymethod|_xcat|cacheonly|noderange|environment)/) {
next;
} elsif ($attr =~ /^(node|uuid|arch|cpucount|cputype|memory|mtm|serial)$/) {
$disdata{$attr} = $request->{$attr}->[0];
+2 -13
View File
@@ -67,7 +67,7 @@ sub getHcpAttribs
}
}
my @ps = $tabs->{ppc}->getAllNodeAttribs(['node','parent','nodetype','hcp','id']);
my @ps = $tabs->{ppc}->getAllNodeAttribs(['node','parent','nodetype','hcp']);
for my $entry ( @ps ) {
my $tmp_parent = $entry->{parent};
my $tmp_node = $entry->{node};
@@ -79,9 +79,6 @@ sub getHcpAttribs
if (defined($tmp_node) && defined($tmp_type) && ($tmp_type eq "blade") && defined($entry->{hcp})) {
push @{$ppchash{$tmp_node}{children}}, $entry->{hcp};
}
if (defined($tmp_node) && defined($entry->{id}) && defined($tmp_parent) && defined($tmp_type) && ($tmp_type eq "lpar")) {
$ppchash{$tmp_parent}{mapping}{$tmp_node} = $entry->{id};
}
#if(exists($ppchash{$tmp_node})) {
# if( defined($tmp_type) ) {
@@ -371,19 +368,11 @@ sub fsp_api_action {
} elsif( $parameter !=0 && $action =~ /^(on|reset)$/ ) {
#powerinterval for lpars power on
$cmd = "$fsp_api -a $action -i $parameter -T $tooltype -t $type:$fsp_ip:$id:$node_name:";
} elsif ($action =~ /^part_set_lpar_def_state$/) {
$cmd = "$fsp_api -a $action -T $tooltype -s $parameter -t $type:$fsp_ip:$id:$node_name:";
} elsif (exists($request->{opt}->{vios})) {
$cmd = "$fsp_api -a $action -T $tooltype -s 1 -t $type:$fsp_ip:$id:$node_name:$parameter";
} else {
$cmd = "$fsp_api -a $action -T $tooltype -t $type:$fsp_ip:$id:$node_name:$parameter";
}
} else {
if (exists($request->{opt}->{vios})) {
$cmd = "$fsp_api -a $action -T $tooltype -s 1 -t $type:$fsp_ip:$id:$node_name:";
} else {
$cmd = "$fsp_api -a $action -T $tooltype -t $type:$fsp_ip:$id:$node_name:";
}
$cmd = "$fsp_api -a $action -T $tooltype -t $type:$fsp_ip:$id:$node_name:";
}
}
xCAT::MsgUtils->verbose_message($request, "fsp_api_action cmd:$cmd.");
+6 -8
View File
@@ -517,14 +517,12 @@ sub getmacs {
$data.= "\n$_\n";
push @$value, "\n$_\n";
} elsif ( /^ent\s+/ || /^hfi-ent\s+/ ) {
#my @fields = split /\s+/, $_;
#my $mac = $fields[2];
#$mac = format_mac( $mac );
#$fields[2] = $mac;
#$data .= join(" ",@fields)."\n";
#push @$value, join(" ",@fields)."\n";
$data .= "$_\n";
push @$value, "$_\n";
my @fields = split /\s+/, $_;
my $mac = $fields[2];
$mac = format_mac( $mac );
$fields[2] = $mac;
$data .= join(" ",@fields)."\n";
push @$value, join(" ",@fields)."\n";
}
}
push @$res,[$node,$data,0];
+5 -34
View File
@@ -13,7 +13,6 @@ use xCAT::GlobalDef;
use xCAT::Usage;
use xCAT::NetworkUtils;
use xCAT::FSPUtils;
require xCAT::data::ibmhwtypes;
#use Data::Dumper;
##############################################
@@ -260,8 +259,7 @@ sub format_output {
# Strip errors for results
#######################################
my @val = grep( !/^#.*: ERROR /, @$values );
#xCAT::PPCdb::add_ppc( $hwtype, \@val );
$values = xCAT::PPCdb::update_lpar( $hwtype, \@val, "write");
xCAT::PPCdb::add_ppc( $hwtype, \@val );
}
###########################################
@@ -272,8 +270,7 @@ sub format_output {
# Strip errors for results
#######################################
my @val = grep( !/^#.*: ERROR /, @$values );
#$values = xCAT::PPCdb::update_ppc( $hwtype, \@val );
$values = xCAT::PPCdb::update_lpar( $hwtype, \@val );
$values = xCAT::PPCdb::update_ppc( $hwtype, \@val );
if ( exists( $opt->{x} ) or exists( $opt->{z} ))
{
unshift @$values, "hmc";
@@ -394,7 +391,6 @@ sub format_stanza {
#################################
# Add each attribute
#################################
my $mtm = undef;
foreach ( @attribs ) {
my $d = $data[$i++];
@@ -405,8 +401,7 @@ sub format_stanza {
} elsif ( /^hwtype$/ ) {
$d = $globalhwtype{$type};
} elsif ( /^groups$/ ) {
next;
#$d = "$type,all";
$d = "$type,all";
} elsif ( /^mgt$/ ) {
$d = $hwtype;
} elsif ( /^cons$/ ) {
@@ -419,9 +414,7 @@ sub format_stanza {
} elsif ( /^(mtm|serial)$/ ) {
if ( $type eq "lpar" ) {
$d = undef;
} elsif (/^mtm$/) {
$mtm = $d;
}
}
} elsif (/^side$/) {
unless ( $type =~ /^fsp|bpa$/ ) {
next;
@@ -429,15 +422,6 @@ sub format_stanza {
}
$result .= "\t$_=$d\n";
}
my $tmp_groups = "$type,all";
if (defined($mtm)) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($mtm);
if (defined($tmp_pre)) {
$tmp_groups .= ",$tmp_pre";
}
}
$result .= "\tgroups=$tmp_groups\n";
}
return( $result );
}
@@ -480,7 +464,6 @@ sub format_xml {
#################################
# Add each attribute
#################################
my $mtm = undef;
foreach ( @attribs ) {
my $d = $data[$i++];
@@ -489,8 +472,7 @@ sub format_xml {
} elsif ( /^hwtype$/ ) {
$d = $globalhwtype{$type};
} elsif ( /^groups$/ ) {
next;
#$d = "$type,all";
$d = "$type,all";
} elsif ( /^mgt$/ ) {
$d = $hwtype;
} elsif ( /^cons$/ ) {
@@ -502,8 +484,6 @@ sub format_xml {
} elsif ( /^(mtm|serial)$/ ) {
if ( $type eq "lpar" ) {
$d = undef;
} elsif (/^mtm$/) {
$mtm = $d;
}
} elsif (/^side$/) {
unless ( $type =~ /^fsp|bpa$/ ) {
@@ -512,15 +492,6 @@ sub format_xml {
}
$href->{Node}->{$_} = $d;
}
my $tmp_groups = "$type,all";
if (defined($mtm)) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($mtm);
if (defined($tmp_pre)) {
$tmp_groups .= ",$tmp_pre";
}
}
$href->{Node}->{groups}=$tmp_groups;
#print Dumper($href);
#################################
# XML encoding
+4 -4
View File
@@ -264,7 +264,7 @@ sub temp {
# No frame commands for IVM
#################################
if ( $hwtype eq "ivm" ) {
push @result, [$name,"$prefix Not available (No BPA)",0];
push @result, [$name,"$prefix Not available (No BPA)",1];
next;
}
#################################
@@ -272,14 +272,14 @@ sub temp {
#################################
if ( @$d[4] !~ /^(fsp|lpar|cec)$/ ) {
my $text = "$prefix Only available for CEC/LPAR";
push @result, [$name,$text,0];
push @result, [$name,$text,1];
next;
}
#################################
# Error - No frame
#################################
if ( $mtms eq "0" ) {
push @result, [$name,"$prefix Not available (No BPA)",0];
push @result, [$name,"$prefix Not available (No BPA)",1];
next;
}
#################################
@@ -352,7 +352,7 @@ sub rackenv {
#################################
if ( @$d[4] !~ /^(bpa|frame)$/ ) {
my $text = "$prefix Only available for BPA/Frame";
push @result, [$name,$text,0];
push @result, [$name,$text,1];
next;
}
+58 -1166
View File
File diff suppressed because it is too large Load Diff
-3
View File
@@ -37,7 +37,6 @@ $::NODETYPE_MP="mp";
$::STATUS_SYNCING="syncing";
$::STATUS_OUT_OF_SYNC="out-of-sync";
$::STATUS_SYNCED="synced";
$::STATUS_FAILED="failed";
# valid values for nodelist.status columns or other status
@@ -56,7 +55,6 @@ $::STATUS_SHELL="shell";
$::STATUS_DEFINED="defined";
$::STATUS_UNKNOWN="unknown";
$::STATUS_FAILED="failed";
$::STATUS_BMCREADY="bmcready";
%::VALID_STATUS_VALUES = (
$::STATUS_ACTIVE=>1,
$::STATUS_INACTIVE=>1,
@@ -73,7 +71,6 @@ $::STATUS_BMCREADY="bmcready";
$::STATUS_DEFINED=>1,
$::STATUS_UNKNOWN=>1,
$::STATUS_FAILED=>1,
$::STATUS_BMCREADY=>1,
$::STATUS_SYNCING=>1,
$::STATUS_OUT_OF_SYNC=>1,
Executable → Regular
+12 -34
View File
@@ -217,23 +217,14 @@ sub is_me
#my ($b1, $b2, $b3, $b4) = split /\./, $nameIP;
# get all the possible IPs for the node I'm running on
# this is a common subroutine for both AIX and Linux,
# AIX does not have ip command
my $ipcmd;
if ( -f "/sbin/ip" )
{
$ipcmd = "ip addr | grep 'inet'";
}
else
{
$ipcmd = "ifconfig -a | grep 'inet'";
}
my $result = xCAT::Utils->runcmd($ipcmd, -1, 1);
my $ifcmd = "ifconfig -a | grep 'inet'";
my $result = xCAT::Utils->runcmd($ifcmd, -1, 1);
if ($::RUNCMD_RC != 0)
{
my $str="Error running ipcmd";
xCAT::MsgUtils->message("S", $str);
$::VERBOSE = $verb;
my $rsp;
# push @{$rsp->{data}}, "Could not run $ifcmd.\n";
# xCAT::MsgUtils->message("E", $rsp, $callback);
$::VERBOSE = $verb;
return 0;
}
@@ -241,6 +232,7 @@ sub is_me
{
my ($inet, $myIP, $str) = split(" ", $int);
chomp $myIP;
$myIP =~ s/addr://;
$myIP =~ s/\/.*//; # ipv6 address 4000::99/64
$myIP =~ s/\%.*//; # ipv6 address ::1%1/128
@@ -901,12 +893,12 @@ sub dolitesetup
}
}
if (-e $litetreetable) {
my $rc = xCAT::Utils->runcmd("rm $litetreetable", -1);
if (-e $litetreetab) {
my $rc = xCAT::Utils->runcmd("rm $litetreetab", -1);
if ($::RUNCMD_RC != 0)
{
my $rsp;
push @{$rsp->{data}}, "Could not remove existing $litetreetable file.";
push @{$rsp->{data}}, "Could not remove existing $litetreetab file.";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
@@ -1031,7 +1023,7 @@ sub dolitesetup
$nrange = join(',',@nodel);
}
@flist = xCAT::Utils->runcmd("/opt/xcat/bin/litefile $nrange", -1);
my @flist = xCAT::Utils->runcmd("/opt/xcat/bin/litefile $nrange", -1);
if (scalar(@flist) > 0) {
foreach my $l (@flist) {
my ($j1, $j2, $file) = split /\s+/, $l;
@@ -1140,11 +1132,7 @@ sub dolitesetup
# $file could be full path file name or dir name
# ex. /foo/bar/ or /etc/lppcfg
my ($node, $option, $file) = split (/\|/, $line);
if (!$file) {
next;
}
# ex. .../inst_root/foo/bar/ or .../inst_root/etc/lppcfg
my $instrootfile = $instrootloc . $file;
@@ -1361,16 +1349,6 @@ sub dolitesetup
return 1;
}
# also copy $instrootloc/.statelite contents
$ccmd = "/usr/bin/cp -p -r $instrootloc/.statelite $SRloc";
$out = xCAT::Utils->runcmd("$ccmd", -1);
if ($::RUNCMD_RC != 0)
{
my $rsp;
push @{$rsp->{data}}, "Could not copy $instrootloc/.statelite to $SRloc.";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
}
}
}
Executable → Regular
+26 -159
View File
@@ -629,8 +629,7 @@ sub get_adap_prop {
$cmd[0] = "\" supported-network-types\" " . $phandle . " get-package-property\r";
$msg[0] = "Status: rc and all supported network types now on stack\n";
#$pattern[0] = "(.*)3 >(.*)";
#$pattern[0] = "3 >";
$pattern[0] = "ok";
$pattern[0] = "3 >";
$newstate[0] = 1;
# state 1, return code and string on stack
@@ -638,8 +637,7 @@ sub get_adap_prop {
$cmd[1] = ".\r";
$msg[1] = "Status: All supported network types now on stack\n";
#$pattern[1] = "(.*)2 >(.*)";
#$pattern[1] = "2 >";
$pattern[1] = "ok";
$pattern[1] = "2 >";
$newstate[1] = 2;
# state 2, data ready to decode
@@ -693,16 +691,6 @@ sub get_adap_prop {
$timeout,
[ qr/$pattern[$state]/i,
sub {
if ($state eq 1) {
if ($rconsole->before() =~ /-\d+/) {
nc_msg($verbose, "Status: Error getting adapter property for phandle=$phandle.\n");
$state = 7;
$rconsole->clear_accum();
$rc = 1;
return 1;
}
}
nc_msg($verbose, $msg[$state]);
$state = $newstate[$state];
$rconsole->clear_accum();
@@ -839,7 +827,7 @@ sub get_mac_addr {
$done[0] = 0;
$cmd[0] = "\" local-mac-address\" ". $phandle . " get-package-property\r";
$msg[0] = "Status: return code and mac-address now on stack\n";
$pattern[0] = "local-mac-address.*ok";#"\s*3 >";
$pattern[0] = "ok";#"\s*3 >";
$newstate[0] = 1;
# cmd(1) is a dot (.). This is a stack manipulation command that removes one
@@ -890,15 +878,6 @@ sub get_mac_addr {
$timeout,
[qr/$pattern[$state]/=>
sub {
if ($state eq 1) {
if ($rconsole->before() =~ /-\d+/) {
nc_msg($verbose, "Status: Error getting MAC address for phandle=$phandle.\n");
$rconsole->clear_accum();
$state = 4;
$rc = 1;
return undef;
}
}
nc_msg($verbose, $msg[$state]);
$state = $newstate[$state];
$rconsole->clear_accum();
@@ -1040,8 +1019,7 @@ sub get_mac_addr {
$cmd[0] = "\" ibm,loc-code\" $phandle get-package-property\r";
$msg[0] = "Status: return code and loc-code now on stack\n";
#$pattern[0] = "(.*)3 >(.*)";
#$pattern[0] = "3 >";
$pattern[0] = "ok";
$pattern[0] = "3 >";
$newstate[0] = 1;
# cmd(1) is a dot (.). This is a stack manipulation command that removes one
@@ -1074,16 +1052,6 @@ sub get_mac_addr {
$timeout,
[qr/$pattern[$state]/=>
sub {
if ($state eq 1) {
if ($rconsole->before() =~ /-\d+/) {
nc_msg($verbose, "Status: Error getting adapter location for phandle=$phandle.");
$rconsole->clear_accum();
$state = 3;
$rc = 1;
return undef;
}
}
nc_msg($verbose, $msg[$state]);
$rconsole->clear_accum();
$state = $newstate[$state];
@@ -1157,19 +1125,10 @@ sub get_mac_addr {
return undef if ($rc eq 1);
}
# Did we find one or more adapters?
my @loc_array = split /\n/,$result[3];
my $found = 0;
$loc_code = '';
foreach my $line ( @loc_array ) {
if ($line =~ /(\w*):(.*):([\w|\.|-]*):/) {
$loc_code .= $3;
$found = 1;
}
}
if ($found) {
$loc_code =~ s/\.$//;
return $loc_code;
} else {
if ($result[3] =~ /(\w*):(.*):(\w*\.\w*\.\w*):/) {
$loc_code = $3;
}else {
return undef;
}
}
@@ -1272,8 +1231,8 @@ sub ping_server{
$done[2] = 0;
$cmd[2] = "dev /packages/net\r";
$msg[2] = "Status: selected the /packages/net node as the active package\n";
$pattern[2] = ".*dev.*packages.*net(.*)ok(.*)0 >(.*)";
#$pattern[2] = "ok";
#$pattern[2] = ".*dev(.*)ok(.*)0 >(.*)";
$pattern[2] = "ok";
$newstate[2]= 3;
# state 3, ping the server
@@ -1281,12 +1240,6 @@ sub ping_server{
$msg[3] = "Status: ping return code now on stack\n";
$newstate[3] = 4;
# get the timeout for ping test
my $to4pt;
if ( $ENV{TIMEOUT4PINGTEST} =~ /^\d+$/ ) {
$to4pt = ",$ENV{TIMEOUT4PINGTEST}";
}
#IPv6
if ( $server_ip =~ /:/ ) {
#::1, calculate link local address
@@ -1296,9 +1249,9 @@ sub ping_server{
} else {
$linklocal_ip = $client_ip;
}
$cmd[3] = "ping $full_path_name:ipv6,$server_ip,$linklocal_ip,$gateway_ip$to4pt\r";
$cmd[3] = "ping $full_path_name:ipv6,$server_ip,$linklocal_ip,$gateway_ip\r";
} else {
$cmd[3] = "ping $full_path_name:$server_ip,$client_ip,$gateway_ip$to4pt\r";
$cmd[3] = "ping $full_path_name:$server_ip,$client_ip,$gateway_ip\r";
}
$pattern[3] = ".*ping(.*)ok(.*)0 >(.*)";
@@ -1313,7 +1266,6 @@ sub ping_server{
# state 5, all done
$done[5] = 1;
# for ping, only need to set speed and duplex for ethernet adapters
#
if ( $list_type eq "ent" ) {
@@ -1371,10 +1323,8 @@ sub ping_server{
$timeout = 300;
while ( $done[$state] eq 0 ) {
send_command($verbose, $rconsole, $cmd[$state]);
@result = $rconsole->expect(
$timeout,
[qr/$pattern[$state]/s=>
sub {
@@ -1412,9 +1362,7 @@ sub ping_server{
}
],
);
return 1 if ($rc eq 1);
return 1 if ($rc eq 1);
if ( $state eq 1 ) {
$adap_conn = $adap_conn_list[$j];
$cmd[1] = "\" ethernet,$adap_speed,$adap_conn,$adap_duplex\" encode-string \" chosen-network-type\" property\r";
@@ -1901,14 +1849,6 @@ sub boot_network {
$state = $newstate[$state];
}
],
# For some old firmware, does not output "----"
[qr/BOOTP/=>
sub {
nc_msg ($verbose, $msg[$state]);
$rconsole->clear_accum();
$state = $newstate[$state];
}
],
[qr/]/=>
sub {
nc_msg($verbose, "Unexpected prompt\n");
@@ -1977,28 +1917,7 @@ sub Boot {
#],
[qr/BOOTP/=> #-ex
sub {
nc_msg($verbose, "# Network boot proceeding - matched BOOTP, exiting.\n");
$rconsole->clear_accum();
}
],
# Welcome to AIX - some old firmware does not output BOOTP or ----
[qr/Welcome/=> #-ex
sub {
nc_msg($verbose, "# Network boot proceeding - matched Welcome, exiting.\n");
$rconsole->clear_accum();
}
],
# tftp file download - some old firmware does not output BOOTP or ----
[qr/FILE/=> #-ex
sub {
nc_msg($verbose, "# Network boot proceeding - matched FILE.\n");
$rconsole->clear_accum();
}
],
# some old firmware does not output BOOTP or ----
[qr/Elapsed/=> #-ex
sub {
nc_msg($verbose, "# Network boot proceeding - matched Elapsed, exiting.\n");
nc_msg($verbose, "# Network boot proceeding, exiting.\n");
$rconsole->clear_accum();
}
],
@@ -2102,46 +2021,14 @@ sub multiple_open_dev {
; \r";
send_command($verbose, $rconsole, $command);
$timeout = 30;
$rconsole->expect(
$timeout,
[qr/new-open-dev(.*)ok/=>
#[qr/>/=>
sub {
nc_msg($verbose, "Status: at End of multiple_open_dev \n");
$rconsole->clear_accum();
}
],
[qr/]/=>
sub {
nc_msg($verbose, "Unexpected prompt\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[timeout =>
sub {
send_user(2, "Timeout\n");
$rconsole->clear_accum();
$rc = 1;
}
],
[eof =>
sub {
send_user(2, "Cannot connect to $node\n");
$rconsole->clear_accum();
$rc = 1;
}
],
);
$command = "patch new-open-dev open-dev net-ping \r";
send_command($verbose, $rconsole, $command);
$timeout = 30;
$rconsole->expect(
$timeout,
[qr/patch new-open-dev(.*)ok/=>
#[qr/>/=>
#[qr/patch new-open-dev(.*)>/=>
[qr/>/=>
sub {
nc_msg($verbose, "Status: at End of multiple_open_dev \n");
$rconsole->clear_accum();
@@ -2170,7 +2057,6 @@ sub multiple_open_dev {
}
],
);
return $rc;
}
###################################################################
@@ -2654,7 +2540,7 @@ sub lparnetbootexp
####################################
nc_msg($verbose, "Connecting to the $node.\n");
sleep 3;
$timeout = 10;
$timeout = 2;
$rconsole->expect(
$timeout,
[ qr/Enter.* for help.*/i =>
@@ -2675,7 +2561,7 @@ sub lparnetbootexp
sub {
$rc = 2;
$rconsole->clear_accum();
nc_msg(1, "Please make sure rcons $node works.\n");
nc_msg($verbose, "Please make sure rcons $node works.\n");
}
],
);
@@ -2863,8 +2749,6 @@ sub lparnetbootexp
$done = 0;
$retry_count = 0;
$timeout = 10;
while (!$done) {
my @result = $rconsole->expect(
$timeout,
@@ -2972,7 +2856,6 @@ sub lparnetbootexp
}
}
##############################
# Call multiple_open_dev to
# circumvent firmware OPEN-DEV
@@ -3007,7 +2890,6 @@ sub lparnetbootexp
$match_pat = ".*";
}
if($colon) {
nc_msg($verbose, "#Type:Location_Code:MAC_Address:Full_Path_Name:Ping_Result:Device_Type:Size_MB:OS:OS_Version:\n");
$outputarrayindex++; # start from 1, 0 is used to set as 0
@@ -3047,21 +2929,6 @@ sub lparnetbootexp
$device_type = "physical";
}
if (defined($mac_address)) {
my @newmacs = ();
my @allmacs = split /\|/,$mac_address;
if ( !xCAT::Utils->isAIX() ) {
foreach my $mac_a ( @allmacs ) {
$mac_a = lc($mac_a);
$mac_a =~ s/(\w{2})/$1:/g;
$mac_a =~ s/:$//;
push @newmacs, $mac_a;
}
$mac_address = join("|",@newmacs);
}
}
if($colon) {
nc_msg($verbose, "$adap_type[$i]\:$loc_code\:$mac_address\:$full_path_name_array[$i]\:$ping_result\:$device_type\:\:\:\:\n");
$outputarrayindex++;
@@ -3076,7 +2943,7 @@ sub lparnetbootexp
} else {
for( $i = 0; $i < $adapter_found; $i++) {
if ($adap_type[$i] =~ /$match_pat/) {
if (!($adap_type[$i] eq "hfi-ent")) {
if ($adap_type[$i] eq "hfi-ent") {
$mac_address = get_mac_addr($phandle_array[$i], $rconsole, $node, $verbose);
$loc_code = get_adaptr_loc($phandle_array[$i], $rconsole, $node, $verbose);
}
@@ -3281,12 +3148,12 @@ sub lparnetbootexp
}
],
);
return [1] if ($rc eq 1);
nc_msg($verbose, "# bootp sent over network.\n");
$rc = Boot($rconsole, $node, $verbose);#, @expect_out);
unless ($rc eq 0) {
nc_msg($verbose, "Can't boot here. \n");
}
return [1] if ($rc eq 1);
}
nc_msg($verbose, "# bootp sent over network.\n");
$rc = Boot($rconsole, $node, $verbose);#, @expect_out);
unless ($rc eq 0) {
nc_msg($verbose, "Can't boot here. \n");
}
}
+30 -41
View File
@@ -10,7 +10,7 @@ if ($^O =~ /^aix/i) {
}
use strict;
use Sys::Syslog;
use Sys::Syslog qw (:DEFAULT setlogsock);
use xCAT::Utils;
#use locale;
use Socket;
@@ -138,9 +138,8 @@ This program module file, supports the xcat messaging and logging
N - Node informational goes to STDOUT
S - Message will be logged to syslog ( severe error)
Note S can be combined with other flags for example
SE logs message to syslog and is sent to STDERR.
SA logs message to syslog and to the auditlog DB table. (only xcatd)
A logs message auditlog DB table only. (only for xcatd)
SE logs message to syslog and is sent to STDERR.
SA logs message to syslog and to the auditlog DB table
V - verbose. This flag is not valid, the calling routine
should check for verbose mode before calling the message
@@ -176,7 +175,7 @@ This program module file, supports the xcat messaging and logging
# Message to Syslog
xCAT::MsgUtils->message('S', "Host $host not responding\n");
# Message to Syslog and auditlog table (only used by xcatd)
# Message to Syslog and auditlog table
# see tabdump -d auditlog
my $rsp = {};
$rsp->{syslogdata}->[0] = "$host not responding\n"; # for syslog
@@ -190,18 +189,6 @@ This program module file, supports the xcat messaging and logging
$rsp->{status} -> [0] = $status;
xCAT::MsgUtils->message('SA', $rsp);
# Message to only auditlog table (only used by xcatd)
# see tabdump -d auditlog
my $rsp = {};
$rsp->{userid} ->[0] = $user;
$rsp->{clientname} -> [0] = $client;
$rsp->{clienttype} -> [0] = $clienttype;
$rsp->{command} -> [0] = $command;
$rsp->{noderange} -> [0] = $noderange;
$rsp->{args} -> [0] = $arguments;
$rsp->{status} -> [0] = $status;
xCAT::MsgUtils->message('A', $rsp);
# Message to Log and Syslog
xCAT::MsgUtils->message('LS', "Host $host not responding\n");
@@ -210,44 +197,44 @@ This program module file, supports the xcat messaging and logging
Use with callback
# Message to callback
my $rsp = {};
my $rsp = {};
$rsp->{data}->[0] = "Job did not run. \n";
xCAT::MsgUtils->message("D", $rsp, $::CALLBACK);
my $rsp = {};
my $rsp = {};
$rsp->{error}->[0] = "No hosts in node list\n";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
my $rsp = {};
$rsp->{node}->[0]->{name}->[0] ="mynode";
$rsp->{node}->[0]->{data}->[0] ="mydata";
xCAT::MsgUtils->message("N", $rsp, $callback);
my $rsp = {};
$rsp->{node}->[0]->{name}->[0] ="mynode";
$rsp->{node}->[0]->{data}->[0] ="mydata";
xCAT::MsgUtils->message("N", $rsp, $callback);
my $rsp = {};
my $rsp = {};
$rsp->{info}->[0] = "No hosts in node list\n";
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
my $rsp = {};
my $rsp = {};
$rsp->{sinfo}->[0] = "No hosts in node list\n";
xCAT::MsgUtils->message("IS", $rsp, $::CALLBACK);
my $rsp = {};
my $rsp = {};
$rsp->{warning}->[0] = "No hosts in node list\n";
xCAT::MsgUtils->message("W", $rsp, $::CALLBACK);
my $rsp = {};
my $rsp = {};
$rsp->{error}->[0] = "Host not responding\n";
xCAT::MsgUtils->message("S", $rsp, $::CALLBACK);
# Message to Syslog and callback
my $rsp = {};
my $rsp = {};
$rsp->{error}->[0] = "Host not responding\n";
xCAT::MsgUtils->message("SE", $rsp, $::CALLBACK);
# Message to Syslog and callback
my $rsp = {};
my $rsp = {};
$rsp->{info}->[0] = "Host not responding\n";
xCAT::MsgUtils->message("SI", $rsp, $::CALLBACK);
@@ -287,19 +274,17 @@ sub message
my $call_back = shift; # optional
my $exitcode = shift; # optional
# should be I,IS, D, E, S, SA,A ,LS, W , L,N
# should be I,IS, D, E, S, SA ,LS, W , L,N
# or S(I, D, E, S, W, L,N)
#
# if SA option need to split syslog messages from auditlog entry
# if new SA option need to split syslog messages from auditlog entry
#
my $newrsp;
if (($sev eq 'SA') || ($sev eq 'A'))
{ # if SA ( syslog and auditlog) or A ( only auditlog)then need to pull first entry from $rsp
# for syslog, to preserve old interface
if ($sev eq 'SA')
{ # if SA then need to pull first entry from $rsp
# for syslog, to preserve old interface
$newrsp = $rsp;
if ($sev eq 'SA'){ # syslog and auditlog
$rsp = $newrsp->{syslogdata}->[0];
}
}
my $stdouterrf = \*STDOUT;
my $stdouterrd = '';
@@ -464,13 +449,15 @@ sub message
}
}
# is syslog option requested
# is syslog requested
if ($sev =~ /S/)
{
# If they want this msg to also go to syslog, do that now
eval {
openlog("xCAT", "nofatal,pid", "local4");
openlog("xCAT", '', 'local4');
setlogsock(["tcp", "unix", "stream"]);
if ($sev eq 'SE') {
syslog("err", $rsp);
} else {
@@ -488,7 +475,7 @@ sub message
# if write to auditlog table requested, if not on service node
if (xCAT::Utils->isMN()){
if (($sev eq 'SA') || ($sev eq 'A'))
if ($sev eq 'SA')
{
require xCAT::Table;
my $auditlogentry;
@@ -516,7 +503,8 @@ sub message
{
print $stdouterrf "Unable to open auditlog\n";
eval {
openlog("xCAT", "nofatal,pid", "local4");
openlog("xCAT", '', 'local4');
setlogsock(["tcp", "unix", "stream"]);
syslog("err", "Unable to write to auditlog");
closelog();
};
@@ -533,7 +521,8 @@ sub message
{ # error
print $stdouterrf "Unable to open auditlog\n";
eval {
openlog("xCAT", "nofatal,pid", "local4");
openlog("xCAT", '', 'local4');
setlogsock(["tcp", "unix", "stream"]);
syslog("err", "Unable to open auditlog");
closelog();
};
+271
View File
@@ -0,0 +1,271 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT::NameRange;
require xCAT::Table;
require Exporter;
use strict;
#Perl implementation of namerange
# NOTE: This is identical to xCAT::NodeRange except that no
# database access occurs, no nodes are verified, and
# no nodegroups are expanded.
# Made a new utility since NodeRange is used EVERYWHERE in
# xCAT code and did not want to risk de-stabilizing existing code.
our @ISA = qw(Exporter);
our @EXPORT = qw(namerange);
my $recurselevel=0;
sub subnodes (\@@) {
#Subtract set of nodes from the first list
my $nodes = shift;
my $node;
foreach $node (@_) {
@$nodes = (grep(!/^$node$/,@$nodes));
}
}
sub expandatom {
my $atom = shift;
my @nodes= ();
if ($atom =~ /^\(.*\)$/) { # handle parentheses by recursively calling namerange()
$atom =~ s/^\((.*)\)$/$1/;
$recurselevel++;
return namerange($atom);
}
if ($atom =~ /@/) {
$recurselevel++;
return namerange($atom);
}
if ($atom =~ m/^\//) { # A regular expression - not supported in namerange
return ($atom);
}
if ($atom =~ m/(.*)\[(.*)\](.*)/) { # square bracket range
#for the time being, we are only going to consider one [] per atom
#xcat 1.2 does no better
my @subelems = split(/([\,\-\:])/,$2);
my $subrange="";
while (my $subelem = shift @subelems) {
my $subop=shift @subelems;
$subrange=$subrange."$1$subelem$3$subop";
}
foreach (split /,/,$subrange) {
my @newnodes=expandatom($_);
@nodes=(@nodes,@newnodes);
}
return @nodes;
}
if ($atom =~ m/\+/) { # process the + operator
$atom =~ m/^([^0-9]*)([0-9]+)([^\+]*)\+([0-9]+)/;
my $pref=$1;
my $startnum=$2;
my $suf=$3;
my $end=$4+$startnum;
my $endnum = sprintf("%d",$end);
if (length ($startnum) > length ($endnum)) {
$endnum = sprintf("%0".length($startnum)."d",$end);
}
foreach ("$startnum".."$endnum") {
my @addnodes=expandatom($pref.$_.$suf);
@nodes=(@nodes,@addnodes);
}
return (@nodes);
}
if ($atom =~ m/[-:]/) { # process the minus range operator
my $left;
my $right;
if ($atom =~ m/:/) {
($left,$right)=split /:/,$atom;
} else {
my $count= ($atom =~ tr/-//);
if (($count % 2)==0) { #can't understand even numbers of - in range context
# we might not really be in range context
return ($atom);
}
my $expr="([^-]+?".("-[^-]*"x($count/2)).")-(.*)";
$atom =~ m/$expr/;
$left=$1;
$right=$2;
}
if ($left eq $right) { #if they said node1-node1 for some strange reason
return expandatom($left);
}
my @leftarr=split(/(\d+)/,$left);
my @rightarr=split(/(\d+)/,$right);
if (scalar(@leftarr) != scalar(@rightarr)) { #Mismatch formatting..
# guess it's meant to be a nodename
return ($atom);
}
my $prefix = "";
my $suffix = "";
foreach (0..$#leftarr) {
my $idx = $_;
if ($leftarr[$idx] =~ /^\d+$/ and $rightarr[$idx] =~ /^\d+$/) { #pure numeric component
if ($leftarr[$idx] ne $rightarr[$idx]) { #We have found the iterator (only supporting one for now)
my $prefix = join('',@leftarr[0..($idx-1)]); #Make a prefix of the pre-validated parts
my $luffix; #However, the remainder must still be validated to be the same
my $ruffix;
if ($idx eq $#leftarr) {
$luffix="";
$ruffix="";
} else {
$ruffix = join('',@rightarr[($idx+1)..$#rightarr]);
$luffix = join('',@leftarr[($idx+1)..$#leftarr]);
}
if ($luffix ne $ruffix) { #the suffixes mismatched..
return ($atom);
}
foreach ($leftarr[$idx]..$rightarr[$idx]) {
my @addnodes=expandatom($prefix.$_.$luffix);
@nodes=(@nodes,@addnodes);
}
return (@nodes); #the return has been built, return, exiting loop and all
}
} elsif ($leftarr[$idx] ne $rightarr[$idx]) {
return ($atom);
}
$prefix .= $leftarr[$idx]; #If here, it means that the pieces were the same, but more to come
}
#I cannot conceive how the code could possibly be here, but whatever it is, it must be questionable
return ($atom);
}
return ($atom);
}
sub namerange {
#We for now just do left to right operations
my $range=shift;
my %nodes = ();
my %delnodes = ();
my $op = ",";
my @elems = split(/(,(?![^[]*?])(?![^\(]*?\)))/,$range); # commas outside of [] or ()
if (scalar(@elems)==1) {
@elems = split(/(@(?![^\(]*?\)))/,$range); # only split on @ when no , are present (inner recursion)
}
while (my $atom = shift @elems) {
if ($atom =~ /^-/) { # if this is an exclusion, strip off the minus, but remember it
$atom = substr($atom,1);
$op = $op."-";
}
if ($atom =~ /^\^(.*)$/) { # get a list of nodes from a file
open(NRF,$1);
while (<NRF>) {
my $line=$_;
unless ($line =~ m/^[\^#]/) {
$line =~ m/^([^: ]*)/;
my $newrange = $1;
chomp($newrange);
$recurselevel++;
my @filenodes = namerange($newrange);
foreach (@filenodes) {
$nodes{$_}=1;
}
}
}
close(NRF);
next;
}
my %newset = map { $_ =>1 } expandatom($atom); # expand the atom and make each entry in the resulting array a key in newset
if ($op =~ /@/) { # compute the intersection of the current atom and the node list we have received before this
foreach (keys %nodes) {
unless ($newset{$_}) {
delete $nodes{$_};
}
}
} elsif ($op =~ /,-/) { # add the nodes from this atom to the exclude list
foreach (keys %newset) {
$delnodes{$_}=1; #delay removal to end
}
} else { # add the nodes from this atom to the total node list
foreach (keys %newset) {
$nodes{$_}=1;
}
}
$op = shift @elems;
} # end of main while loop
# Now remove all the exclusion nodes
foreach (keys %nodes) {
if ($delnodes{$_}) {
delete $nodes{$_};
}
}
if ($recurselevel) {
$recurselevel--;
}
return sort (keys %nodes);
}
1;
=head1 NAME
xCAT::NameRange - Perl module for xCAT namerange expansion
=head1 SYNOPSIS
use xCAT::NameRange;
my @nodes=namerange("storage@rack1,node[1-200],^/tmp/nodelist,node300-node400,node401+10,500-550");
=head1 DESCRIPTION
namerange interprets xCAT noderange formatted strings and returns a list of
names. The following two operations are supported on elements, and interpreted
left to right:
, union next element with everything to the left.
@ take intersection of element to the right with everything on the left
(i.e. mask out anything to the left not belonging to what is described to
the right)
Each element can be a number of things:
A node name, i.e.:
=item * node1
A hyphenated node range (only one group of numbers may differ between the left and right hand side, and those numbers will increment in a base 10 fashion):
node1-node200 node1-compute-node200-compute
node1:node200 node1-compute:node200-compute
A namerange denoted by brackets:
node[1-200] node[001-200]
A regular expression describing the namerange:
/d(1.?.?|200)
A node plus offset (this increments the first number found in nodename):
node1+199
And most of the above substituting groupnames.
3C
3C
NameRange tries to be intelligent about detecting padding, so you can:
node001-node200
And it will increment according to the pattern.
=head1 COPYRIGHT
Copyright 2007 IBM Corp. All rights reserved.
=cut
+191 -306
View File
@@ -19,7 +19,6 @@ use File::Path;
use Math::BigInt;
use Socket;
use xCAT::GlobalDef;
#use Data::Dumper;
use strict;
use warnings "all";
my $socket6support = eval { require Socket6 };
@@ -69,14 +68,14 @@ This program module file, is a set of network utilities used by xCAT commands.
#-------------------------------------------------------------------------------
sub getNodeDomains()
{
my $class = shift;
my $class = shift;
my $nodes = shift;
my @nodelist = @$nodes;
my %nodedomains;
# Get the network info for each node
my %nethash = xCAT::DBobjUtils->getNetwkInfo(\@nodelist);
my %nethash = xCAT::DBobjUtils->getNetwkInfo(\@nodelist);
# get the site domain value
my @domains = xCAT::TableUtils->get_site_attribute("domain");
@@ -85,13 +84,12 @@ sub getNodeDomains()
# for each node - set hash value to network domain or default
# to site domain
foreach my $node (@nodelist) {
unless (defined($node)) {next;}
if (defined($nethash{$node}) && $nethash{$node}{domain}) {
$nodedomains{$node} = $nethash{$node}{domain};
} else {
$nodedomains{$node} = $sitedomain;
}
}
if ($nethash{$node}{domain}) {
$nodedomains{$node} = $nethash{$node}{domain};
} else {
$nodedomains{$node} = $sitedomain;
}
}
return \%nodedomains;
}
@@ -424,6 +422,11 @@ sub ishostinsubnet {
if ($ip =~ /:/) {#ipv6
$numbits=128;
}
# IPv6 subnet with netmask postfix like /64
if ($subnet && ($subnet =~ /\//))
{
$subnet =~ s/\/.*$//;
}
if ($mask) {
if ($mask =~ /\//) {
$mask =~ s/^\///;
@@ -439,10 +442,6 @@ sub ishostinsubnet {
die "ishostinsubnet must either be called with a netmask or CIDR /bits notation";
}
}
if ($subnet && ($subnet =~ /\//)) #remove CIDR suffix from subnet
{
$subnet =~ s/\/.*$//;
}
$ip = getipaddr($ip,GetNumber=>1);
$subnet = getipaddr($subnet,GetNumber=>1);
$ip &= $mask;
@@ -644,11 +643,16 @@ sub get_nic_ip
{
my $nic;
my %iphash;
my $cmd = "ifconfig -a";
my $result = `$cmd`;
my $mode = "MULTICAST";
my $payingattention=0;
my $interface;
my $keepcurrentiface;
#############################################
# Error running command
#############################################
if ( !$result ) {
return undef;
}
if (xCAT::Utils->isAIX()) {
##############################################################
@@ -660,14 +664,6 @@ sub get_nic_ip
# en1: ...
#
##############################################################
my $cmd = "ifconfig -a";
my $result = `$cmd`;
#############################################
# Error running command
#############################################
if ( !$result ) {
return undef;
}
my @adapter = split /(\w+\d+):\s+flags=/, $result;
foreach ( @adapter ) {
if ($_ =~ /^(en\d)/) {
@@ -687,39 +683,37 @@ sub get_nic_ip
}
}
}
else { # linux
my @ipoutput = `ip addr`;
#############################################
# Error running command
#############################################
if ( !@ipoutput ) {
return undef;
}
foreach my $line (@ipoutput) {
if ($line =~ /^\d/) { # new interface, new context..
if ($interface and not $keepcurrentiface) {
#don't bother reporting unusable nics
delete $iphash{$interface};
else {
##############################################################
# Should look like this for Linux:
# eth0 Link encap:Ethernet HWaddr 00:02:55:7B:06:30
# inet addr:9.114.154.193 Bcast:9.114.154.223
# inet6 addr: fe80::202:55ff:fe7b:630/64 Scope:Link
# UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
# RX packets:1280982 errors:0 dropped:0 overruns:0 frame:0
# TX packets:3535776 errors:0 dropped:0 overruns:0 carrier:0
# collisions:0 txqueuelen:1000
# RX bytes:343489371 (327.5 MiB) TX bytes:870969610 (830.6 MiB)
# Base address:0x2600 Memory:fbfe0000-fc0000080
#
# eth1 ...
#
##############################################################
my @adapter= split /\n{2,}/, $result;
foreach ( @adapter ) {
if ( !($_ =~ /LOOPBACK / ) and
$_ =~ /UP / and
$_ =~ /$mode / ) {
my @ip = split /\n/;
for my $ent ( @ip ) {
if ($ent =~ /^(eth\d|ib\d|hf\d)\s+/) {
$nic = $1;
}
if ( $ent =~ /^\s*inet addr:\s*(\d+\.\d+\.\d+\.\d+)/ ) {
$iphash{$nic} = $1;
next;
}
}
$keepcurrentiface=0;
if ( !($line =~ /LOOPBACK/ ) and
$line =~ /UP( |,|>)/ and
$line =~ /$mode/ ) {
$payingattention=1;
$line =~ /^([^:]*): ([^:]*):/;
$interface=$2;
} else {
$payingattention=0;
next;
}
}
unless ($payingattention) { next; }
if ($line =~ /inet/) {
$keepcurrentiface=1;
}
if ( $line =~ /^\s*inet \s*(\d+\.\d+\.\d+\.\d+)/ ) {
$iphash{$interface} = $1;
}
}
}
@@ -1602,124 +1596,56 @@ sub thishostisnot
=cut
#-----------------------------------------------------------------------------
#sub gethost_ips1
#{
# my ($class) = @_;
# my $cmd;
# my @ipaddress;
# $cmd = "ifconfig" . " -a";
# $cmd = $cmd . "| grep \"inet\"";
# my @result = xCAT::Utils->runcmd($cmd, 0);
# if ($::RUNCMD_RC != 0)
# {
# xCAT::MsgUtils->message("S", "Error from $cmd\n");
# exit $::RUNCMD_RC;
# }
# foreach my $addr (@result)
# {
# my @ip;
# if (xCAT::Utils->isLinux())
# {
# if ($addr =~ /inet6/)
# {
# #TODO, Linux ipv6
# }
# else
# {
# my ($inet, $addr1, $Bcast, $Mask) = split(" ", $addr);
# #@ip = split(":", $addr1);
# #push @ipaddress, $ip[1];
# $addr1 =~ s/.*://;
# push @ipaddress, $addr1;
# }
# }
# else
# { #AIX
# if ($addr =~ /inet6/)
# {
# $addr =~ /\s*inet6\s+([\da-fA-F:]+).*\/(\d+)/;
# my $v6ip = $1;
# my $v6mask = $2;
# if ($v6ip)
# {
# push @ipaddress, $v6ip;
# }
# }
# else
# {
# my ($inet, $addr1, $netmask, $mask1, $Bcast, $bcastaddr) =
# split(" ", $addr);
# push @ipaddress, $addr1;
# }
#
# }
# }
# my @names = @ipaddress;
# foreach my $ipaddr (@names)
# {
# my $hostname = xCAT::NetworkUtils->gethostname($ipaddr);
# if ($hostname)
# {
# my @shorthost = split(/\./, $hostname);
# push @ipaddress, $shorthost[0];
# }
# }
#
# return @ipaddress;
#}
sub gethost_ips
{
my ($class) = @_;
my $cmd;
my @ipaddress;
if (xCAT::Utils->isLinux())
$cmd = "ifconfig" . " -a";
$cmd = $cmd . "| grep \"inet\"";
my @result = xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{
$cmd="ip -4 --oneline addr show |awk -F ' ' '{print \$4}'|awk -F '/' '{print \$1}'";
my @result =xCAT::Utils->runcmd($cmd);
if ($::RUNCMD_RC != 0)
{
xCAT::MsgUtils->message("S", "Error from $cmd\n");
exit $::RUNCMD_RC;
}
push @ipaddress, @result;
xCAT::MsgUtils->message("S", "Error from $cmd\n");
exit $::RUNCMD_RC;
}
else
{ #AIX
$cmd = "ifconfig" . " -a";
$cmd = $cmd . "| grep \"inet\"";
my @result = xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{
xCAT::MsgUtils->message("S", "Error from $cmd\n");
exit $::RUNCMD_RC;
}
foreach my $addr (@result)
{
if ($addr =~ /inet6/)
{
$addr =~ /\s*inet6\s+([\da-fA-F:]+).*\/(\d+)/;
my $v6ip = $1;
my $v6mask = $2;
if ($v6ip)
{
push @ipaddress, $v6ip;
}
}
else
{
my ($inet, $addr1, $netmask, $mask1, $Bcast, $bcastaddr) =
split(" ", $addr);
push @ipaddress, $addr1;
}
foreach my $addr (@result)
{
my @ip;
if (xCAT::Utils->isLinux())
{
if ($addr =~ /inet6/)
{
#TODO, Linux ipv6
}
else
{
my ($inet, $addr1, $Bcast, $Mask) = split(" ", $addr);
@ip = split(":", $addr1);
push @ipaddress, $ip[1];
}
}
else
{ #AIX
if ($addr =~ /inet6/)
{
$addr =~ /\s*inet6\s+([\da-fA-F:]+).*\/(\d+)/;
my $v6ip = $1;
my $v6mask = $2;
if ($v6ip)
{
push @ipaddress, $v6ip;
}
}
else
{
my ($inet, $addr1, $netmask, $mask1, $Bcast, $bcastaddr) =
split(" ", $addr);
push @ipaddress, $addr1;
}
}
}
}
my @names = @ipaddress;
foreach my $ipaddr (@names)
{
@@ -1730,9 +1656,9 @@ sub gethost_ips
push @ipaddress, $shorthost[0];
}
}
return @ipaddress;
}
#-------------------------------------------------------------------------------
=head3 get_subnet_aix
@@ -1908,6 +1834,102 @@ sub validate_ip
}
return([0]);
}
#-------------------------------------------------------------------------------
=head3 getFacingIP
Gets the ip address of the adapter of the localhost that is facing the
the given node.
Assume it is the same as my_ip_facing...
Arguments:
The name of the node that is facing the localhost.
Returns:
The ip address of the adapter that faces the node.
=cut
#-------------------------------------------------------------------------------
sub getFacingIP
{
my ($class, $node) = @_;
my $ip;
my $cmd;
my @ipaddress;
my $nodeip = inet_ntoa(inet_aton($node));
unless ($nodeip =~ /\d+\.\d+\.\d+\.\d+/)
{
return 0; #Not supporting IPv6 here IPV6TODO
}
$cmd = "ifconfig" . " -a";
$cmd = $cmd . "| grep \"inet \"";
my @result = xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{
xCAT::MsgUtils->message("S", "Error from $cmd\n");
exit $::RUNCMD_RC;
}
# split node address
my ($n1, $n2, $n3, $n4) = split('\.', $nodeip);
foreach my $addr (@result)
{
my $ip;
my $mask;
if (xCAT::Utils->isLinux())
{
my ($inet, $addr1, $Bcast, $Mask) = split(" ", $addr);
if ((!$addr1) || (!$Mask)) { next; }
my @ips = split(":", $addr1);
my @masks = split(":", $Mask);
$ip = $ips[1];
$mask = $masks[1];
}
else
{ #AIX
my ($inet, $addr1, $netmask, $mask1, $Bcast, $bcastaddr) =
split(" ", $addr);
if ((!$addr1) && (!$mask1)) { next; }
$ip = $addr1;
$mask1 =~ s/0x//;
$mask =
`printf "%d.%d.%d.%d" \$(echo "$mask1" | sed 's/../0x& /g')`;
}
if ($ip && $mask)
{
# split interface IP
my ($h1, $h2, $h3, $h4) = split('\.', $ip);
# split mask
my ($m1, $m2, $m3, $m4) = split('\.', $mask);
# AND this interface IP with the netmask of the network
my $a1 = ((int $h1) & (int $m1));
my $a2 = ((int $h2) & (int $m2));
my $a3 = ((int $h3) & (int $m3));
my $a4 = ((int $h4) & (int $m4));
# AND node IP with the netmask of the network
my $b1 = ((int $n1) & (int $m1));
my $b2 = ((int $n2) & (int $m2));
my $b3 = ((int $n3) & (int $m3));
my $b4 = ((int $n4) & (int $m4));
if (($b1 == $a1) && ($b2 == $a2) && ($b3 == $a3) && ($b4 == $a4))
{
return $ip;
}
}
}
xCAT::MsgUtils->message("S", "Cannot find master for the node $node\n");
return 0;
}
#-------------------------------------------------------------------------------
=head3 isIpaddr
@@ -1960,108 +1982,6 @@ sub isIpaddr
}
}
#-------------------------------------------------------------------------------
=head3 getNodeNameservers
Description:
Get nameservers of specified nodes.
The priority: noderes.nameservers > networks.nameservers > site.nameservers
Arguments:
node: node name list
Returns:
Return a hash ref, of the $nameservers{$node}
undef - Failed to get the nameservers
Globals:
none
Error:
none
Example:
my $nameservers = xCAT::NetworkUtils::getNodeNameservers(\@node);
Comments:
none
=cut
#-------------------------------------------------------------------------------
sub getNodeNameservers{
my $nodes=shift;
if( $nodes =~ /xCAT::NetworkUtils/)
{
$nodes=shift;
}
my @nodelist = @$nodes;
my %nodenameservers;
my $nrtab = xCAT::Table->new('noderes',-create=>0);
my %nrhash = %{$nrtab->getNodesAttribs(\@nodelist,['nameservers'])};
my $nettab = xCAT::Table->new("networks");
my %nethash = xCAT::DBobjUtils->getNetwkInfo( \@nodelist );
my @nameservers = xCAT::TableUtils->get_site_attribute("nameservers");
my $sitenameservers=$nameservers[0];
foreach my $node (@nodelist){
if ($nrhash{$node} and $nrhash{$node}->[0] and $nrhash{$node}->[0]->{nameservers})
{
$nodenameservers{$node}=$nrhash{$node}->[0]->{nameservers};
}elsif($nethash{$node}{nameservers})
{
$nodenameservers{$node}=$nethash{$node}{nameservers};
}elsif($sitenameservers)
{
$nodenameservers{$node}=$sitenameservers;
}
}
return \%nodenameservers;
}
#-------------------------------------------------------------------------------
=head3 getNodeGateway
Description:
Get gateway from the networks table of the node.
Arguments:
ip: the ip address of the node
Returns:
Return a string, of the gateway
undef - Failed to get the gateway
Globals:
none
Error:
none
Example:
my $gateway = xCAT::NetworkUtils::getNodeGateway('192.168.1.0');
Comments:
none
=cut
#-------------------------------------------------------------------------------
sub getNodeGateway
{
my $ip=shift;
if( $ip =~ /xCAT::NetworkUtils/)
{
$ip=shift;
}
my $gateway=undef;
my $nettab = xCAT::Table->new("networks");
if ($nettab) {
my @nets = $nettab->getAllAttribs('net','mask','gateway');
foreach my $net (@nets) {
if (xCAT::NetworkUtils::isInSameSubnet( $net->{'net'}, $ip, $net->{'mask'}, 0)) {
$gateway=$net->{'gateway'};
}
}
}
return $gateway;
}
#-------------------------------------------------------------------------------
=head3 getNodeNetworkCfg
@@ -2088,27 +2008,19 @@ sub getNodeGateway
sub getNodeNetworkCfg
{
my $node = shift;
if( $node =~ /xCAT::NetworkUtils/)
{
$node =shift;
}
my $nets = xCAT::NetworkUtils::my_nets();
my $ip = xCAT::NetworkUtils->getipaddr($node);
my $mask = undef;
my $gateway = undef;
for my $net (keys %$nets)
{
my $netname;
($netname,$mask) = split /\//, $net;
last if ( xCAT::NetworkUtils::isInSameSubnet( $netname, $ip, $mask, 1));
}
$gateway=xCAT::NetworkUtils::getNodeGateway($ip);
return ($ip, $node, $gateway, xCAT::NetworkUtils::formatNetmask($mask,1,0));
return ($ip, $node, undef, xCAT::NetworkUtils::formatNetmask($mask,1,0));
}
#-------------------------------------------------------------------------------
=head3 get_hdwr_ip
@@ -2182,13 +2094,7 @@ sub pingNodeStatus {
foreach (@mon_nodes) {
$deadnodes{$_}=1;
}
# get additional options from site table
my @nmap_options = xCAT::TableUtils->get_site_attribute("nmapoptions");
my $more_options = $nmap_options[0];
#call namp
open (NMAP, "nmap -PE --system-dns --send-ip -sP $more_options ". $nodes . " 2> /dev/null|") or die("Cannot open nmap pipe: $!");
open (NMAP, "nmap -PE --system-dns --send-ip -sP ". $nodes . " 2> /dev/null|") or die("Cannot open nmap pipe: $!");
my $node;
while (<NMAP>) {
if (/Host (.*) \(.*\) appears to be up/) {
@@ -2290,7 +2196,6 @@ sub isValidHostname
return 0;
}
#-------------------------------------------------------------------------------
=head3 isValidFQDN
@@ -2349,26 +2254,6 @@ sub int_to_ip
#-------------------------------------------------------------------------------
=head3 getBroadcast
Description : Get the broadcast ips
Arguments : ipstr - the IPv4 string ip.
netmask - the subnet mask of network
Returns : bcipint - the IPv4 string of broadcast ip.
=cut
#-------------------------------------------------------------------------------
sub getBroadcast
{
my ($class, $ipstr, $netmask) = @_;
my $ipint = xCAT::NetworkUtils->ip_to_int($ipstr);
my $maskint = xCAT::NetworkUtils->ip_to_int($netmask);
my $tmp = sprintf("%d", ~$maskint);
my $bcnum = sprintf("%d", ($ipint | $tmp) & hex('0x00000000FFFFFFFF'));
return xCAT::NetworkUtils->int_to_ip($bcnum);
}
#-------------------------------------------------------------------------------
=head3 get_allips_in_range
Description : Get all IPs in a IP range, return in a list.
Arguments : $startip - start IP address
+33 -99
View File
@@ -1,6 +1,5 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT::NodeRange;
use Text::Balanced qw/extract_bracketed/;
require xCAT::Table;
require Exporter;
use strict;
@@ -149,7 +148,7 @@ sub nodesbycriteria {
}
if ($neednewcache) {
if ($nodelist) {
#$nodelist->_clear_cache();
$nodelist->_clear_cache();
$nodelist->_build_cache(\@cachedcolumns);
}
}
@@ -181,14 +180,7 @@ sub nodesbycriteria {
return \%critnodes;
}
# Expand one part of the noderange from the noderange() function. Initially, one part means the
# substring between commas in the noderange. But expandatom also calls itself recursively to
# further expand some parts.
# Input args:
# - atom to expand
# - verify: whether or not to require that the resulting nodenames exist in the nodelist table
# - options: genericrange - a purely syntactical expansion of the range, not using the db at all, e.g not expanding group names
sub expandatom {
sub expandatom { #TODO: implement table selection as an atom (nodetype.os==rhels5.3)
my $atom = shift;
if ($recurselevel > 4096) { die "NodeRange seems to be hung on evaluating $atom, recursion limit hit"; }
unless (scalar(@allnodeset) and (($allnodesetstamp+5) > time())) { #Build a cache of all nodes, some corner cases will perform worse, but by and large it will do better. We could do tests to see where the breaking points are, and predict how many atoms we have to evaluate to mitigate, for now, implement the strategy that keeps performance from going completely off the rails
@@ -197,28 +189,25 @@ sub expandatom {
@allnodeset = $nodelist->getAllAttribs('node','groups');
%allnodehash = map { $_->{node} => 1 } @allnodeset;
}
my $verify = (scalar(@_) >= 1 ? shift : 1);
my %options = @_; # additional options
my $verify = (scalar(@_) == 1 ? shift : 1);
my @nodes= ();
#TODO: these env vars need to get passed by the client to xcatd
my $nprefix=(defined ($ENV{'XCAT_NODE_PREFIX'}) ? $ENV{'XCAT_NODE_PREFIX'} : 'node');
my $nsuffix=(defined ($ENV{'XCAT_NODE_SUFFIX'}) ? $ENV{'XCAT_NODE_SUFFIX'} : '');
if (not $options{genericrange} and $allnodehash{$atom}) { #The atom is a plain old nodename
if ($allnodehash{$atom}) { #The atom is a plain old nodename
return ($atom);
}
if ($atom =~ /^\(.*\)$/) { # handle parentheses by recursively calling noderange()
$atom =~ s/^\((.*)\)$/$1/;
$recurselevel++;
return noderange($atom,$verify,1,%options);
return noderange($atom);
}
if ($atom =~ /@/) {
$recurselevel++;
return noderange($atom,$verify,1,%options);
return noderange($atom);
}
# Try to match groups?
unless ($options{genericrange}) {
unless ($grptab) {
$grptab = xCAT::Table->new('nodegroup');
}
@@ -280,9 +269,7 @@ sub expandatom {
}
}
}
}
# node selection based on db attribute values (nodetype.os==rhels5.3)
if ($atom =~ m/[=~]/) { #TODO: this is the clunky, slow code path to acheive the goal. It also is the easiest to write, strange coincidence. Aggregating multiples would be nice
my @nodes;
foreach (@allnodeset) {
@@ -300,7 +287,7 @@ sub expandatom {
}
if ($atom =~ m/^[0-9]+\z/) { # if only numbers, then add the prefix
my $nodename=$nprefix.$atom.$nsuffix;
return expandatom($nodename,$verify,%options);
return expandatom($nodename,$verify);
}
my $nodelen=@nodes;
if ($nodelen > 0) {
@@ -308,7 +295,7 @@ sub expandatom {
}
if ($atom =~ m/^\//) { # A regular expression
if ($verify==0 or $options{genericrange}) { # If not in verify mode, regex makes zero possible sense
unless ($verify) { # If not in verify mode, regex makes zero possible sense
return ($atom);
}
#TODO: check against all groups
@@ -322,29 +309,25 @@ sub expandatom {
}
if ($atom =~ m/(.+?)\[(.+?)\](.*)/) { # square bracket range
# if there is more than 1 set of [], we picked off just the 1st. If there more sets of [], we will expand
# the 1st set and create a new set of atom by concatenating each result in the 1st expandsion with the rest
# of the brackets. Then call expandatom() recursively on each new atom.
my @subelems = split(/([\,\-\:])/,$2); # $2 is the range inside the 1st set of brackets
# if there are more than 1 [], we picked off just the 1st. if there is another, we will process it later
my @subelems = split(/([\,\-\:])/,$2);
my $subrange="";
my $subelem;
my $start = $1; # the text before the 1st set of brackets
my $ending = $3; # the text after the 1st set of brackets (could contain more brackets)
my $morebrackets = $ending =~ /\[.+?\]/; # if there are more brackets, we have to expand just the 1st part, then add the 2nd part later
while (scalar @subelems) { # this while loop turns something like a[1-3] into a1-a3 because another section of expand atom knows how to expand that
my $subelem = shift @subelems;
my $subelem;
my $start = $1;
my $ending = $3;
my $morebrackets = $ending =~ /\[.+?\]/; # if there are more brackets, we have to expand just the 1st part, then add the 2nd part later
while (scalar @subelems) {
my $subelem = shift @subelems;
my $subop=shift @subelems;
$subrange=$subrange."$start$subelem" . ($morebrackets?'':$ending) . "$subop";
}
foreach (split /,/,$subrange) { # this foreach is in case there were commas inside the brackets originally, e.g.: a[1,3,5]b[1-2]
# this expandatom just expands the part of the noderange that contains the 1st set of brackets
# e.g. if noderange is a[1-2]b[1-2] it will create newnodes of a1 and a2
my @newnodes=expandatom($_, ($morebrackets?0:$verify), genericrange=>($morebrackets||$options{genericrange}));
foreach (split /,/,$subrange) {
my @newnodes=expandatom($_, ($morebrackets?0:$verify));
if (!$morebrackets) { push @nodes,@newnodes; }
else {
# for each of the new nodes (prefixes), add the rest of the brackets and then expand recursively
# for each of the new nodes, add the 2nd brackets and then expand
foreach my $n (@newnodes) {
push @nodes, expandatom("$n$ending", $verify, %options);
push @nodes, expandatom("$n$ending", $verify);
}
}
}
@@ -366,7 +349,7 @@ sub expandatom {
$suf=$nsuffix;
}
foreach ("$startnum".."$endnum") {
my @addnodes=expandatom($pref.$_.$suf,$verify,%options);
my @addnodes=expandatom($pref.$_.$suf,$verify);
@nodes=(@nodes,@addnodes);
}
return (@nodes);
@@ -393,7 +376,7 @@ sub expandatom {
$right=$2;
}
if ($left eq $right) { #if they said node1-node1 for some strange reason
return expandatom($left,$verify,%options);
return expandatom($left,$verify);
}
my @leftarr=split(/(\d+)/,$left);
my @rightarr=split(/(\d+)/,$right);
@@ -430,7 +413,7 @@ sub expandatom {
}
}
foreach ($leftarr[$idx]..$rightarr[$idx]) {
my @addnodes=expandatom($prefix.$_.$luffix,$verify,%options);
my @addnodes=expandatom($prefix.$_.$luffix,$verify);
push @nodes,@addnodes;
}
return (@nodes); #the return has been built, return, exiting loop and all
@@ -478,7 +461,7 @@ sub retain_cache { #A semi private operation to be used *ONLY* in the interestin
%allgrphash=();
}
}
sub extnoderange { #An extended noderange function. Needed by the GUI as the more straightforward function return format too simple for this.
sub extnoderange { #An extended noderange function. Needed as the more straightforward function return format too simple for this.
my $range = shift;
my $namedopts = shift;
my $verify=1;
@@ -504,7 +487,7 @@ sub extnoderange { #An extended noderange function. Needed by the GUI as the mo
return $return;
}
sub abbreviate_noderange {
#takes a list of nodes or a string and reduces it by replacing a list of nodes that make up a group with the group name itself
#takes a list of nodes or a string and abbreviates
my $nodes=shift;
my %grouphash;
my %sizedgroups;
@@ -550,40 +533,16 @@ sub abbreviate_noderange {
return (join ',',keys %targetelems,keys %nodesleft);
}
sub set_arith {
my $operand = shift;
my $op = shift;
my $newset = shift;
if ($op =~ /@/) { # compute the intersection of the current atom and the node list we have received before this
foreach (keys %$operand) {
unless ($newset->{$_}) {
delete $operand->{$_};
}
}
} elsif ($op =~ /,-/) { # add the nodes from this atom to the exclude list
foreach (keys %$newset) {
delete $operand->{$_}
}
} else { # add the nodes from this atom to the total node list
foreach (keys %$newset) {
$operand->{$_}=1;
}
}
}
# Expand the given noderange
# Input args:
# - noderange to expand
# - verify: whether or not to require that the resulting nodenames exist in the nodelist table
# - exsitenode: whether or not to honor site.excludenodes to automatically exclude those nodes from all noderanges
# - options: genericrange - a purely syntactical expansion of the range, not using the db at all, e.g not expanding group names
sub noderange {
$missingnodes=[];
#We for now just do left to right operations
my $range=shift;
$range =~ s/['"]//g;
my $verify = (scalar(@_) >= 1 ? shift : 1);
my $exsitenode = (scalar(@_) >= 1 ? shift : 1); # if 1, honor site.excludenodes
my %options = @_; # additional options
#excludenodes attribute in site table,
#these nodes should be excluded for any xCAT commands
my $exsitenode = (scalar(@_) >= 1 ? shift : 1);
unless ($nodelist) {
$nodelist =xCAT::Table->new('nodelist',-create =>1);
@@ -594,45 +553,20 @@ sub noderange {
}
my %nodes = ();
my %delnodes = ();
if ($range =~ /\(/) {
my ($middle, $end, $start) =
extract_bracketed($range, '()', qr/[^()]*/);
unless ($middle) { die "Unbalanced parentheses in noderange" }
$middle = substr($middle,1,-1);
my $op = ",";
if ($start =~ m/-$/) { #subtract the parenthetical
$op .= "-"
} elsif ($start =~ m/\@$/) {
$op = "@"
}
$start =~ s/,-$//;
$start =~ s/,$//;
$start =~ s/\@$//;
%nodes = map { $_ => 1 } noderange($start,$verify,$exsitenode,%options);
my %innernodes = map { $_ => 1 } noderange($middle,$verify,$exsitenode,%options);
set_arith(\%nodes,$op,\%innernodes);
$range = $end;
}
my $op = ",";
my @elems = split(/(,(?![^[]*?])(?![^\(]*?\)))/,$range); # commas outside of [] or ()
if (scalar(@elems)==1) {
@elems = split(/(@(?![^\(]*?\)))/,$range); # only split on @ when no , are present (inner recursion)
}
while (defined(my $atom = shift @elems)) {
if ($atom eq '') { next; }
while (my $atom = shift @elems) {
if ($atom eq ',') {
next;
}
if ($atom =~ /^-/) { # if this is an exclusion, strip off the minus, but remember it
$atom = substr($atom,1);
$op = $op."-";
} elsif ($atom =~ /^\@/) { # if this is an exclusion, strip off the minus, but remember it
$atom = substr($atom,1);
$op = "@";
}
if ($atom eq '') { next; }
if ($atom =~ /^\^(.*)$/) { # get a list of nodes from a file
open(NRF,$1);
@@ -643,7 +577,7 @@ sub noderange {
my $newrange = $1;
chomp($newrange);
$recurselevel++;
my @filenodes = noderange($newrange,$verify,$exsitenode,%options);
my @filenodes = noderange($newrange);
foreach (@filenodes) {
$nodes{$_}=1;
}
@@ -653,7 +587,7 @@ sub noderange {
next;
}
my %newset = map { $_ =>1 } expandatom($atom,$verify,%options); # expand the atom and make each entry in the resulting array a key in newset
my %newset = map { $_ =>1 } expandatom($atom,$verify); # expand the atom and make each entry in the resulting array a key in newset
if ($op =~ /@/) { # compute the intersection of the current atom and the node list we have received before this
foreach (keys %nodes) {
@@ -680,7 +614,7 @@ sub noderange {
my $badnoderange = 0;
my @badnodes = ();
if ($::XCATSITEVALS{excludenodes}) {
@badnodes = noderange($::XCATSITEVALS{excludenodes}, 1, 0, %options);
@badnodes = noderange($::XCATSITEVALS{excludenodes}, 1, 0);
foreach my $bnode (@badnodes) {
if (!$delnodes{$bnode}) {
$delnodes{$bnode} = 1;
+5 -1
View File
@@ -311,6 +311,9 @@ sub notify {
my ($modname, $path, $suffix) = fileparse($_, ".pm");
# print "modname=$modname, path=$path, suffix=$suffix\n";
if ($suffix =~ /.pm/) { #it is a perl module
my $pid;
if ($pid=xCAT::Utils->xfork()) { }
elsif (defined($pid)) {
my $fname;
if (($path eq "") || ($path eq ".\/")) {
#default path is /opt/xcat/lib/perl/xCAT_monitoring/ if there is no path specified
@@ -325,7 +328,8 @@ sub notify {
else {
${"xCAT_monitoring::".$modname."::"}{processTableChanges}->($action, $tablename, $old_data, $new_data);
}
return 0;
exit 0;
}
}
else { #it is a command
my $pid;
+2 -23
View File
@@ -21,6 +21,7 @@ sub parse_args {
my %opt = ();
my $cmd = $request->{command};
my $args = $request->{arg};
my @VERSION = qw( 2.1 );
#############################################
# Responds with usage statement
@@ -59,8 +60,7 @@ sub parse_args {
# Option -v for version
####################################
if ( exists( $opt{v} )) {
my $version = xCAT::Utils->Version();
return ([$version]);
return( \@VERSION );
}
if ( exists( $opt{s} ) ){
@@ -350,27 +350,6 @@ sub do_rnetboot {
last;
}
}
# Set the boot mode to norm from 'of' (open firmware)
# NOW, only necessary for IVM
my $hwtype = @$exp[2];
if ($hwtype eq "ivm") {
my $server = @$exp[3];
# creat connection first
my @newexp = xCAT::PPCcli::connect( $request, $hwtype, $server );
if (ref($newexp[0]) eq "Expect" ) {
my $cfg = "lpar_id=@$d[0],boot_mode=norm";
# change the boot mode to 'norm'
xCAT::PPCcli::chsyscfg(\@newexp, "prof", $d, $cfg);
xCAT::PPCcli::disconnect(\@newexp);
} else {
my $rsp;
$rsp->{data} = ["Failed to set the boot mode to normal. For rnetboot command, you have to rpower off and then on the node after finishing the OS deployment."];
xCAT::MsgUtils->message("E", $rsp, $request->{callback});
}
}
return $result;
}
+3 -3
View File
@@ -436,9 +436,9 @@ sub sshcfg {
#####################################
# userid@host not found in key file
#####################################
#if ( $sshkey !~ /\s+(\S+\@\S+$)/ ) {
# return( [[$server,"Cannot find userid\@host in '$fname'",RC_ERROR]] );
#}
if ( $sshkey !~ /\s+(\S+\@\S+$)/ ) {
return( [[$server,"Cannot find userid\@host in '$fname'",RC_ERROR]] );
}
my $logon = $1;
#####################################
+4 -4
View File
@@ -139,7 +139,7 @@ sub connect {
my $timeout = $req->{ppctimeout};
my $verbose = $req->{verbose};
my $ssh;
my $expect_log = "/dev/null";
my $expect_log;
my $errmsg;
if ($req->{command} eq 'rflash') {
@@ -156,7 +156,7 @@ sub connect {
# Shell prompt regexp based on HW Type
##################################################
my %prompt = (
hmc => "~>\\s*\$",
hmc => "~> \$",
ivm => "\\\$ \$"
);
##################################################
@@ -170,7 +170,7 @@ sub connect {
##################################################
if ( $verbose ) {
close STDERR;
if ( !open( STDERR, '>', $expect_log )) {
if ( !open( STDERR, '>', \$expect_log )) {
return( "Unable to redirect STDERR: $!" );
}
}
@@ -179,7 +179,7 @@ sub connect {
##################################################
if ( $verbose ) {
close STDOUT;
if ( !open( STDOUT, '>', $expect_log )) {
if ( !open( STDOUT, '>', \$expect_log )) {
return( "Unable to redirect STDOUT: $!" );
}
}
-3
View File
@@ -490,9 +490,6 @@ sub mkhwconn
my $ntype = $$d[4];
if ($ntype =~ /^(cec|frame|blade)$/)
{
if ($ntype eq "blade") {
delete $opt->{port};
}
$cnode = xCAT::DBobjUtils::getchildren($node_name, $opt->{port});
} else {
$cnode = $node_name;
+6 -119
View File
@@ -7,7 +7,6 @@ use xCAT::GlobalDef;
use xCAT::Utils;
use xCAT::TableUtils;
use xCAT::NetworkUtils;
require xCAT::data::ibmhwtypes;
###########################################
# Factory defaults
@@ -75,7 +74,6 @@ sub add_ppc {
my $values = shift;
my $not_overwrite = shift;
my $otherinterfaces = shift;
my $callfile = shift;
my @tabs = qw(ppc vpd nodehm nodelist nodetype hosts mac);
my %db = ();
###################################
@@ -102,6 +100,7 @@ sub add_ppc {
$parent,
$ips,
$mac ) = split /,/;
###############################
# Update nodetype table
###############################
@@ -120,12 +119,7 @@ sub add_ppc {
# Specify CEC and Frame's mgt as fsp and bpa
if ( $type =~ /^cec$/) {
if ( $callfile eq "PPC" ) {
$mgt = "hmc";
}
if ( $callfile eq "FSP" ) {
$mgt = "fsp";
}
$mgt = "fsp";
}
if ( $type =~ /^frame$/) {
$mgt = "bpa";
@@ -174,10 +168,6 @@ sub add_ppc {
# Update nodelist table
###########################
updategroups( $name, $db{nodelist}, $type );
my $tmp_group = xCAT::data::ibmhwtypes::parse_group($model);
if (defined($tmp_group)) {
updategroups($name, $db{nodelist}, $tmp_group);
}
if ( $type =~ /^(fsp|bpa)$/ ) {
$db{nodelist}->setNodeAttribs( $name, {hidden => '1'});
} else {
@@ -246,97 +236,6 @@ sub add_ppc {
}
return undef;
}
##########################################################################
# Update lpar information in the xCAT databases
##########################################################################
sub update_lpar {
my $hwtype = shift;
my $values = shift;
my $write = shift;
my @tabs = qw(ppc vpd nodehm nodelist nodetype ppcdirect hosts mac);
my %db = ();
my @update_list = ();
my @write_list = ();
###################################
# Open database needed
###################################
foreach ( @tabs ) {
$db{$_} = xCAT::Table->new( $_, -create=>1, -autocommit=>0 );
if ( !$db{$_} ) {
return( "Error opening '$_'" );
}
}
my @vpdlist = $db{vpd}->getAllNodeAttribs(['node','serial','mtm','side']);
my @ppclist = $db{ppc}->getAllNodeAttribs(['node','hcp','id',
'pprofile','parent','nodetype',
'comments', 'disable']);
# 'cec,cec1,,8246-L1D,100A9DA,,cec1,,cec1',
# 'lpar,10-0A9DA,1,8246-L1D,100A9DA,,cec1,,cec1'
my %ppchash = ();
my %vpdhash = ();
foreach my $ppcent (@ppclist) {
if ($ppcent->{id} and $ppcent->{nodetype} and $ppcent->{nodetype} eq "lpar") {
my $key = $ppcent->{node};
$ppchash{$key}{id} = $ppcent->{id};
$ppchash{$key}{parent} = $ppcent->{parent};
}
}
foreach my $vpdent (@vpdlist)
{
my $key = $vpdent->{node};
$vpdhash{$key}{mtm} = $vpdent->{mtm};
$vpdhash{$key}{serial} = $vpdent->{serial};
}
my @ppc_lpars = keys %ppchash;
foreach my $value ( @$values ) {
my ($ttype,
$tname,
$tid,
$tmtm,
$tsn,
$tside,
$server,
$pprofile,
$parent) = split /,/, $value;
if ($ttype ne "lpar") {
push @update_list, $value;
next;
}
my $find_node = undef;
foreach my $tmp_node (@ppc_lpars) {
if ($ppchash{$tmp_node}{id} eq $tid) {
if (exists($ppchash{$tmp_node}{parent}) and $ppchash{$tmp_node}{parent} eq $parent) {
$find_node = $tmp_node;
last;
} elsif ($vpdhash{$tmp_node}{mtm} eq $tmtm and $vpdhash{$tmp_node}{serial} eq $tsn) {
$find_node = $tmp_node;
last;
}
}
}
if (defined($find_node)) {
if ( update_node_attribs($hwtype, $ttype, $find_node, $tid, $tmtm, $tsn, $tside,
$server, $pprofile, $parent, "", \%db, $tname, \@ppclist))
{
$value =~ s/^$ttype,$tname,/$ttype,$find_node,/;
push @update_list, $value;
}
} elsif (defined($write)) {
push @write_list, $value;
}
}
if (defined($write)) {
&add_ppc($hwtype, \@write_list,'','',"FSP");
return ([@update_list,@write_list]);
} else {
foreach ( @tabs ) {
if ( exists( $db{$_}{commit} )) {
$db{$_}->commit;
}
}
return \@update_list;
}
}
##########################################################################
# Update nodes in the xCAT databases
@@ -379,6 +278,7 @@ sub update_ppc {
$pprofile,
$parent,
$ips ) = split /,/, $value;
if ( $ttype eq 'cec' )
{
my $hostname = get_host($tname, "FSP", $tmtm, $tsn, "", "", $tid, "","");
@@ -429,7 +329,9 @@ sub update_ppc {
$pprofile,
$parent,
$ips ) = split /,/, $value;
next if ( $type ne 'cec' );
my $predefined_node = undef;
foreach my $vpdent (@vpdlist)
{
@@ -623,10 +525,6 @@ sub update_node_attribs
if ( $namediff)
{
updategroups( $name, $db->{nodelist}, $type );
my $tmp_group = xCAT::data::ibmhwtypes::parse_group($model);
if (defined($tmp_group)) {
updategroups($name, $db->{nodelist}, $tmp_group);
}
$db->{nodelist}->setNodeAttribs( $name, {status=>$nodelisthash->{status},
appstatus=>$nodelisthash->{appstatus},
primarysn=>$nodelisthash->{primarysn},
@@ -990,18 +888,6 @@ sub get_usr_passwd {
} else {
($ent) = $passwdtab->getNodeAttribs($key, qw(username password));
}
if (!$ent) {
if ($key eq "cec") {
$key = "fsp";
} elsif ($key eq "frame") {
$key = "bpa";
}
if ($user) {
($ent) = $passwdtab->getAttribs({key => $key, username => $user}, qw(password cryptmethod));
} else {
($ent) = $passwdtab->getNodeAttribs($key, qw(username password));
}
}
if (!$ent or !$ent->{password}) {
my $hash = $default_passwd_accounts{$key};
if (!$hash or ($user and !defined($hash->{$user}))) {
@@ -1072,6 +958,7 @@ sub get_host {
# get the information of existed nodes to do the migration
read_from_table() unless (%::OLD_DATA_CACHE);
foreach my $oldnode ( keys %::OLD_DATA_CACHE )
{
my $tmpmtm = @{$::OLD_DATA_CACHE{$oldnode}}[0];
+22 -21
View File
@@ -14,7 +14,7 @@ use xCAT::Usage;
use xCAT::NodeRange;
use xCAT::DBobjUtils;
use xCAT::FSPUtils;
use xCAT::TableUtils;
use xCAT::TableUtils qw(get_site_Master);
%::QUERY_ATTRS = (
'savingstatus' => 1,
'dsavingstatus' => 1,
@@ -223,6 +223,7 @@ sub renergy {
my ($node, $attrs) = %$nodehash;
my $cec_name = @$attrs[2];
my $hw_type = @$attrs[4];
if (!$cec_name) {
return ([[$node, "ERROR: Cannot find the cec name, check the attributes: vpd.serial, vpd.mtm.", 1]]);
@@ -294,43 +295,43 @@ sub renergy {
foreach (@hcps_ip) {
$deadnodes{$_}=1;
}
# get additional options from site table
my @nmap_options = xCAT::TableUtils->get_site_attribute("nmapoptions");
my $more_options = $nmap_options[0];
open (NMAP, "nmap -PE --system-dns --send-ip -sP $more_options ". join(' ',@hcps_ip) . " 2> /dev/null|") or die("Cannot open nmap pipe: $!");
my $node;
open (NMAP, "nmap -PE --system-dns --send-ip -sP ". join(' ',@hcps_ip) . " 2> /dev/null|") or die("Cannot open nmap pipe: $!");
my $node1;
my $msg1;
while (<NMAP>) {
#print "$_\n";
if (/Host (.*) \((.*)\) appears to be up/) {
$node=$2;
unless ($deadnodes{$node}) {
$node1=$2;
unless ($deadnodes{$node1}) {
foreach (keys %deadnodes) {
if ($node =~ /^$_\./) {
$node = $_;
if ($node1 =~ /^$_\./) {
$node1 = $_;
last;
}
}
}
delete $deadnodes{$node};
delete $deadnodes{$node1};
if ($verbose) {
push @return_msg, [$node, $_, 0];
}
push(@pingable_hcp, $node);
} elsif (/Nmap scan report for ([^ ]*)/) {
$node=$1;
push(@pingable_hcp, $node1);
} elsif (/Nmap scan report for ([^ ]*) \((.*)\)/) {
$node1=$2;
$msg1=$_;
} elsif (/Host is up./) {
unless ($deadnodes{$node}) {
unless ($deadnodes{$node1}) {
foreach (keys %deadnodes) {
if ($node =~ /^$_\./) {
$node = $_;
if ($node1 =~ /^$_\./) {
$node1 = $_;
last;
}
}
}
delete $deadnodes{$node};
push(@pingable_hcp, $node);
delete $deadnodes{$node1};
if ($verbose) {
push @return_msg, [$node, "$msg1$_", 0];
}
push(@pingable_hcp, $node1);
}
}
} else {
+6 -10
View File
@@ -144,16 +144,12 @@ sub connect {
##################################
# Set options
##################################
#my $hosttab = xCAT::Table->new( 'hosts' );
#if ( $hosttab) {
# my $hostshash = $hosttab->getNodeAttribs( $server, [qw(ip otherinterfaces)]);
# if ( $hostshash ) {
# $server = $hostshash->{ip};
# }
#}
$server = xCAT::NetworkUtils::getNodeIPaddress( $server );
unless ($server) {
return( "Unable to get IP address for $server" );
my $hosttab = xCAT::Table->new( 'hosts' );
if ( $hosttab) {
my $hostshash = $hosttab->getNodeAttribs( $server, [qw(ip otherinterfaces)]);
if ( $hostshash ) {
$server = $hostshash->{ip};
}
}
# my $serverip = inet_ntoa(inet_aton($server));
my $url = "https://$server/cgi-bin/cgi?form=2";
+3 -14
View File
@@ -5,8 +5,6 @@ use strict;
use Getopt::Long;
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
use xCAT::Usage;
use xCAT::TableUtils;
require xCAT::data::ibmhwtypes;
##########################################
@@ -61,7 +59,7 @@ sub parse_args {
$Getopt::Long::ignorecase = 0;
Getopt::Long::Configure( "bundling" );
if ( !GetOptions( \%opt, qw(V|verbose t) )) {
if ( !GetOptions( \%opt, qw(V|verbose) )) {
return( usage() );
}
####################################
@@ -77,9 +75,6 @@ sub parse_args {
if ( !defined( $cmd )) {
return(usage( "Invalid command: $ARGV[0]" ));
}
if (exists($opt{t}) and $cmd ne "model") {
return(["Option 't' can only work with 'model'."]);
}
####################################
# Check for an extra argument
####################################
@@ -347,7 +342,7 @@ sub bus {
#################################
# Output header
#################################
push @result, [$name,"I/O Bus Information", 0];
push @result, [$name,"I/O Bus Information"];
#################################
# Output error
@@ -416,12 +411,6 @@ sub vpd {
#############################
# Output value
#############################
if ($_ eq 'model' and exists($request->{opt}->{t})) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_args($data->{$_});
if (defined($tmp_pre)) {
xCAT::TableUtils->updatenodegroups($name, $tmp_pre);
}
}
my $value = "@{$prefix{$_}}[0]: $data->{$_}";
push @result, [$name,$value,$Rc];
}
@@ -532,7 +521,7 @@ sub config {
#################################
# Output header
#################################
push @result, [$name,"Machine Configuration Info", 0];
push @result, [$name,"Machine Configuration Info"];
my $i;
foreach ( @prefix ) {
+10 -37
View File
@@ -555,9 +555,6 @@ sub getmacs {
} else {
$type = "virtualio";
}
if ($mac_addr) {
$mac_addr = format_mac($mac_addr);
}
my %att = ();
$att{'MAC_Address'} = ($mac_addr) ? $mac_addr : "N/A";
@@ -630,9 +627,9 @@ sub getmacs {
}
foreach ( @$value ) {
if ( /^#\s?Type/ ) {
$data.= "\n$_\n";
$data.= "\n$_\n";
} else {
$data.= "$_\n";
$data.= format_mac( $_ );
}
}
@@ -759,7 +756,7 @@ sub getmacs {
if ( /^#\s?Type/ ) {
$data.= "\n$_\n";
} elsif ( /^ent\s+/ or /^hfi-ent\s+/ ) {
$data.= "$_\n";
$data.= format_mac( $_ );
}
}
#####################################
@@ -804,8 +801,10 @@ sub cal_mac {
##########################################################################
sub format_mac {
my $mac = shift;
my $data = shift;
$data =~ /^(\S+\s+\S+\s+)(\S+)(\s+.*)$/;
my $mac = $2;
#####################################
# Get adapter mac
#####################################
@@ -814,10 +813,6 @@ sub format_mac {
if ( !xCAT::Utils->isAIX() ) {
foreach my $mac_a ( @macs ) {
if (&checkmac($mac_a)) {
push @newmacs, $mac_a;
next;
}
#################################
# Delineate MAC with colons
#################################
@@ -826,30 +821,14 @@ sub format_mac {
$mac_a =~ s/:$//;
push @newmacs, $mac_a;
}
$mac = join("|",@newmacs);
my $newmac = join("|",@newmacs);
$data =~ s/$mac/$newmac/;
}
return( "$mac\n" );
return( "$data\n" );
}
##########################################################################
# checkmac format
##########################################################################
sub checkmac {
my $mac = shift;
if ( !xCAT::Utils->isAIX()) {
if ($mac =~ /\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2}/) {
return 1;
} else {
return 0;
}
} else {
return 1;
}
}
##########################################################################
# Write first valid adapter MAC to database
@@ -868,9 +847,6 @@ sub writemac {
# Find first valid adapter
#####################################
foreach ( @$data ) {
unless (&checkmac($_)) {
next;
}
if ( /^ent\s+/ or /^hfi-ent\s+/ ) {
$value = $_;
#####################################
@@ -893,9 +869,6 @@ sub writemac {
#####################################
if ( $pingret ne "successful" ) {
foreach ( @$data ) {
unless (&checkmac($_)) {
next;
}
if ( /^ent\s+/ or /^hfi-ent\s+/ ) {
$value = $_;
$ping_test = 0;
@@ -917,7 +890,7 @@ sub writemac {
#####################################
# Get adapter mac
#####################################
#$value = format_mac( $value );
$value = format_mac( $value );
@fields = split /\s+/, $value;
$mac = $fields[2];
+5 -29
View File
@@ -11,7 +11,7 @@ use xCAT::PPCdb;
use xCAT::GlobalDef;
use xCAT::Usage;
use xCAT::NetworkUtils;
require xCAT::data::ibmhwtypes;
##############################################
# Globals
@@ -411,7 +411,7 @@ sub format_output {
# Strip errors for results
#######################################
my @val = grep( !/^#.*: ERROR /, @$values );
xCAT::PPCdb::add_ppc( $hwtype, \@val ,'','',"PPC");
xCAT::PPCdb::add_ppc( $hwtype, \@val );
}
###########################################
@@ -545,7 +545,6 @@ sub format_stanza {
#################################
# Add each attribute
#################################
my $mtm = undef;
foreach ( @attribs ) {
my $d = $data[$i++];
@@ -556,8 +555,7 @@ sub format_stanza {
} elsif ( /^hwtype$/ ) {
$d = $globalhwtype{$type};
} elsif ( /^groups$/ ) {
next;
#$d = "$type,all";
$d = "$type,all";
} elsif ( /^mgt$/ ) {
$d = $hwtype;
} elsif ( /^cons$/ ) {
@@ -570,9 +568,7 @@ sub format_stanza {
} elsif ( /^(mtm|serial)$/ ) {
if ( $type eq "lpar" ) {
$d = undef;
} elsif (/^mtm$/) {
$mtm = $d;
}
}
} elsif (/^side$/) {
unless ( $type =~ /^fsp|bpa$/ ) {
next;
@@ -580,14 +576,6 @@ sub format_stanza {
}
$result .= "\t$_=$d\n";
}
my $tmp_groups = "$type,all";
if (defined($mtm)) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($mtm);
if (defined($tmp_pre)) {
$tmp_groups .= ",$tmp_pre";
}
}
$result .= "\tgroups=$tmp_groups\n";
}
return( $result );
}
@@ -635,7 +623,6 @@ sub format_xml {
#################################
# Add each attribute
#################################
my $mtm = undef;
foreach ( @attribs ) {
my $d = $data[$i++];
@@ -644,8 +631,7 @@ sub format_xml {
} elsif ( /^hwtype$/ ) {
$d = $globalhwtype{$type};
} elsif ( /^groups$/ ) {
next;
#$d = "$type,all";
$d = "$type,all";
} elsif ( /^mgt$/ ) {
$d = $hwtype;
} elsif ( /^cons$/ ) {
@@ -657,8 +643,6 @@ sub format_xml {
} elsif ( /^(mtm|serial)$/ ) {
if ( $type eq "lpar" ) {
$d = undef;
} elsif (/^mtm$/){
$mtm = $d;
}
} elsif (/^side$/) {
unless ( $type =~ /^fsp|bpa$/ ) {
@@ -667,14 +651,6 @@ sub format_xml {
}
$href->{Node}->{$_} = $d;
}
my $tmp_groups = "$type,all";
if (defined($mtm)) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($mtm);
if (defined($tmp_pre)) {
$tmp_groups .= ",$tmp_pre";
}
}
$href->{Node}->{groups}=$tmp_groups;
#################################
# XML encoding
#################################
+4 -4
View File
@@ -203,7 +203,7 @@ sub voltage {
# Voltages available in frame
#################################
if ( @$d[4] ne "bpa" ) {
push @result, [$name,"$text Only available for BPA",0];
push @result, [$name,"$text Only available for BPA",1];
next;
}
my $volt = enumerate_volt( $exp, $d );
@@ -256,7 +256,7 @@ sub temp {
# No frame commands for IVM
#################################
if ( $hwtype eq "ivm" ) {
push @result, [$name,"$prefix Not available (No BPA)",0];
push @result, [$name,"$prefix Not available (No BPA)",1];
next;
}
#################################
@@ -264,14 +264,14 @@ sub temp {
#################################
if ( @$d[4] !~ /^(fsp|cec|lpar)$/ ) {
my $text = "$prefix Only available for CEC/LPAR";
push @result, [$name,$text,0];
push @result, [$name,$text,1];
next;
}
#################################
# Error - No frame
#################################
if ( $mtms eq "0" ) {
push @result, [$name,"$prefix Not available (No BPA)",0];
push @result, [$name,"$prefix Not available (No BPA)",1];
next;
}
#################################
+1 -1
View File
@@ -1913,7 +1913,7 @@ sub xCATdB {
$profile,
$parent );
return( xCAT::PPCdb::add_ppc( $hwtype, [$values],'','',"PPC" ));
return( xCAT::PPCdb::add_ppc( $hwtype, [$values] ));
}
return undef;
}
+18 -314
View File
@@ -52,21 +52,14 @@ sub get_allocable_staticips_innet
my $netentry = ($networkstab->getAllAttribsWhere("netname = '$netname'", 'ALL'))[0];
my ($startip, $endip) = split('-', $netentry->{'staticrange'});
my $incremental = $netentry->{'staticrangeincrement'};
my $netmask = $netentry->{'mask'};
my $gateway = $netentry->{'gateway'};
my $validipsref;
if ($incremental and $startip and $endip){
$validipsref = xCAT::NetworkUtils->get_allips_in_range($startip, $endip, $incremental);
}
my $broadcastip = xCAT::NetworkUtils->getBroadcast($startip, $netmask);
foreach (@$validipsref){
#Remove ip which is broadcast ip, exclude ip, ips ended with 0, gateway ip
if (exists($iphash{$_}) or $_ eq $broadcastip or $_ eq $gateway
or $_ =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(0)$/){
next;
if (! exists($iphash{$_})){
push @allocableips, $_;
}
push @allocableips, $_;
}
return \@allocableips;
}
@@ -265,7 +258,6 @@ sub rackformat_to_numricformat{
values are attributes of a specific nic, like:
type : nic type
hostnamesuffix: hostname suffix
hostnameprefix: hostname prefix
customscript: custom script for this nic
network: network name for this nic
ip: ip address of this nic.
@@ -277,7 +269,7 @@ sub get_nodes_nic_attrs{
my $nodes = shift;
my $nicstab = xCAT::Table->new( 'nics');
my $entry = $nicstab->getNodesAttribs($nodes, ['nictypes', 'nichostnamesuffixes', 'nichostnameprefixes', 'niccustomscripts', 'nicnetworks', 'nicips']);
my $entry = $nicstab->getNodesAttribs($nodes, ['nictypes', 'nichostnamesuffixes', 'niccustomscripts', 'nicnetworks', 'nicips']);
my %nicsattrs;
my @nicattrslist;
@@ -309,20 +301,6 @@ sub get_nodes_nic_attrs{
}
}
if($entry->{$node}->[0]->{'nichostnameprefixes'}){
@nicattrslist = split(",", $entry->{$node}->[0]->{'nichostnameprefixes'});
foreach (@nicattrslist){
my @nicattrs;
if ($_ =~ /!/) {
@nicattrs = split("!", $_);
} else {
@nicattrs = split(":", $_);
}
$nicsattrs{$node}{$nicattrs[0]}{'hostnameprefix'} = $nicattrs[1];
}
}
if($entry->{$node}->[0]->{'niccustomscripts'}){
@nicattrslist = split(",", $entry->{$node}->[0]->{'niccustomscripts'});
foreach (@nicattrslist){
@@ -563,129 +541,6 @@ sub get_allnode_singleattrib_hash
return \%allrecords;
}
#-------------------------------------------------------------------------------
=head3 get_db_swtiches
Description : Get all records of switch config from a table, then return a string list.
Arguments : $tabname - the table name.
Returns : Reference of the records hash.
=cut
#-------------------------------------------------------------------------------
sub get_db_switches
{
my $class = shift;
my $table = xCAT::Table->new("switches");
my @attribs = ("switch");
my @entries = $table->getAllAttribs(@attribs);
$table->close();
my %allrecords;
foreach (@entries)
{
if ($_->{'switch'}){
$allrecords{$_->{'switch'}} = 0;
}
}
return \%allrecords;
}
#-------------------------------------------------------------------------------
=head3 get_db_swtichports
Description : Get all records of switch config from a table, then return a string list.
Arguments : $tabname - the table name.
Returns : Reference of the records hash.
=cut
#-------------------------------------------------------------------------------
sub get_db_switchports
{
my $class = shift;
my $table = xCAT::Table->new("switch");
my @attribs = ("switch", "port");
my @entries = $table->getAllAttribs(@attribs);
$table->close();
my %allrecords;
foreach (@entries)
{
$allrecords{$_->{'switch'} . "_" . $_->{'port'}} = 0;
}
return \%allrecords;
}
#-------------------------------------------------------------------------------
=head3 get_all_cecs
Description : Get all CEC objects name in system.
Arguments : hashref: if not set, return a array ref.
if set, return a hash ref.
Returns : ref for CECs list.
Example :
my $arrayref = xCAT::ProfiledNodeUtils->get_all_cecs();
my $hashref = xCAT::ProfiledNodeUtils->get_all_cecs(1);
=cut
#-------------------------------------------------------------------------------
sub get_all_cecs
{
my $hashref = shift;
my %cecshash;
my @cecslist;
my $ppctab = xCAT::Table->new('ppc');
my @cecs = $ppctab->getAllAttribsWhere("nodetype = 'cec'", 'node');
foreach (@cecs) {
if($_->{'node'}) {
if ($hashref) {
$cecshash{$_->{'node'}} = 1;
} else {
push @cecslist, $_->{'node'};
}
}
}
$ppctab->close();
# Return the ref accordingly
if ($hashref) {
return \%cecshash;
} else {
return \@cecslist;
}
}
#-------------------------------------------------------------------------------
=head3 get_all_lparids
Description : Get all LPAR ids in system.
Arguments : ref of all cecs
Returns : ref for LPAR ids hash.
Example :
my $arrayref = xCAT::ProfiledNodeUtils->get_all_lparids(\%allcecs);
=cut
#-------------------------------------------------------------------------------
sub get_all_lparids
{
my $class= shift;
my $cecsref = shift;
my %allcecs = %$cecsref;
my %lparids;
my $ppctab = xCAT::Table->new('ppc');
foreach my $cec (keys %allcecs) {
my @ids = $ppctab->getAllAttribsWhere("hcp = '$cec'", 'id');
foreach (@ids) {
if ( $_->{'id'} ){
$lparids{$cec}{$_->{'id'}} = 0;
}
}
}
$ppctab->close();
return \%lparids;
}
#-------------------------------------------------------------------------------
=head3 is_discover_started
@@ -723,7 +578,6 @@ sub get_nodes_profiles
{
my $class = shift;
my $nodelistref = shift;
my $groupnamemode = shift;
my %profile_dict;
my $nodelisttab = xCAT::Table->new('nodelist');
@@ -743,12 +597,8 @@ sub get_nodes_profiles
if ( $idx == 2 ){
# The group string will like @NetworkProfile_<profile name>
# So, index should +3, 2 for '__', 1 for _.
if ($groupnamemode) {
$profile_dict{$_}{$profile} = $group;
} else{
my $append_index = length($profile) + 3;
$profile_dict{$_}{$profile} = substr $group, $append_index;
}
my $append_index = length($profile) + 3;
$profile_dict{$_}{$profile} = substr $group, $append_index;
last;
}
}
@@ -777,7 +627,7 @@ sub get_imageprofile_prov_method
my $nodetypestab = xCAT::Table->new('nodetype');
my $entry = ($nodetypestab->getAllAttribsWhere("node = '$imgprofilename'", 'ALL' ))[0];
return $entry->{'provmethod'};
my $osimgname = $entry->{'provmethod'};
#my $osimgtab = xCAT::Table->new('osimage');
#my $osimgentry = ($osimgtab->getAllAttribsWhere("imagename = '$osimgname'", 'ALL' ))[0];
@@ -786,27 +636,6 @@ sub get_imageprofile_prov_method
#-------------------------------------------------------------------------------
=head3 get_imageprofile_prov_osvers
Description : Get A node's provisioning os version and profile from its imageprofile attribute.
Arguments : $imgprofilename - imageprofile name
Returns : node's osversion and profile
=cut
#-------------------------------------------------------------------------------
sub get_imageprofile_prov_osvers
{
my $class = shift;
my $imgprofilename = shift;
my $osimgtab = xCAT::Table->new('osimage');
my $osimgentry = ($osimgtab->getAllAttribsWhere("imagename = '$imgprofilename'", 'ALL' ))[0];
my $osversion = $osimgentry->{'osvers'};
my $profile = $osimgentry->{'profile'};
return ($osversion, $profile);
}
#-------------------------------------------------------------------------------
=head3 check_profile_consistent
Description : Check if three profile consistent
Arguments : $imageprofile - image profile name
@@ -838,10 +667,13 @@ sub check_profile_consistent{
}
}
# Profile consistent keys, arch=>netboot, mgt=>nictype
my %profile_dict = ('x86' => 'xnba','x86_64' => 'xnba', 'ppc64' => 'yaboot',
'fsp' => 'FSP', 'ipmi' => 'BMC');
# Get Imageprofile arch
my $nodetypetab = xCAT::Table->new('nodetype');
my $nodetypeentry = $nodetypetab->getNodeAttribs($imageprofile, ['os','arch']);
my $os = $nodetypeentry->{'os'};
my $nodetypeentry = $nodetypetab->getNodeAttribs($imageprofile, ['arch']);
my $arch = $nodetypeentry->{'arch'};
$nodetypetab->close();
@@ -869,27 +701,12 @@ sub check_profile_consistent{
my $mgt = undef;
$mgt = $mgtentry->{'mgt'} if ($mgtentry->{'mgt'});
$nodehmtab->close();
#Get hardwareprofile nodetype
my $ppctab = xCAT::Table->new('ppc');
my $ntentry = $ppctab->getNodeAttribs($hardwareprofile, ['nodetype']);
my $nodetype = undef;
$nodetype = $ntentry->{'nodetype'} if ($ntentry->{'nodetype'});
$ppctab->close();
# Check if exists provision network
if (not ($installnic and exists $netprofile_nicshash{$installnic}{"network"})){
return 0, "Provisioning network not defined for network profile."
}
# Profile consistent keys, arch=>netboot, mgt=>nictype
my $ppc_netboot = 'yaboot';
if( $os =~ /rhels7/ ){
$ppc_netboot = 'grub2';
}
my %profile_dict = ('x86' => 'xnba','x86_64' => 'xnba', 'ppc64' => $ppc_netboot,
'ppc64el' => $ppc_netboot,
'fsp' => 'FSP', 'ipmi' => 'BMC');
# Check if imageprofile is consistent with networkprofile
if ($profile_dict{$arch} ne $netboot) {
return 0, "Imageprofile's arch is not consistent with networkprofile's netboot."
@@ -903,29 +720,17 @@ sub check_profile_consistent{
return 0, "$nictype networkprofile must use with hardwareprofile.";
}
}
if ($mgt eq 'vm')
{
return 1, "";
}
# For nodetype is lpar node, not need to check the nictype as it is not required for lpar node
if (not $nictype and $mgt and $nodetype ne 'lpar' ) {
# define hardwareprofile, not define fsp or bmc networkprofile, and the node type is not lpar
if (not $nictype and $mgt) {
# define hardwareprofile, not define fsp or bmc networkprofile
return 0, "$profile_dict{$mgt} hardwareprofile must use with $profile_dict{$mgt} networkprofile.";
}
if ($profile_dict{$mgt} ne $nictype and $nodetype ne 'lpar') {
# Networkprofile's nictype is not consistent with hadrwareprofile's mgt, and the node type is not lpar
if ($profile_dict{$mgt} ne $nictype) {
# Networkprofile's nictype is not consistent with hadrwareprofile's mgt
return 0, "Networkprofile's nictype is not consistent with hardwareprofile's mgt.";
}
if ($nodetype eq 'lpar' and $nictype eq 'FSP')
{
# can not associate FSP network if the node type is lpar
return 0, "The node with hardware type $nodetype can not use with $nictype networkprofile.";
}
return 1, "";
}
@@ -1084,40 +889,6 @@ sub parse_nodeinfo_file
return 1, "";
}
#-------------------------------------------------------
=head3 update the table prodkey, in order to support windows
per node license key
Returns: $retcode.
$retcode = 1. update failed, the value is undef
$retcode = 0. save into db is OK..
=cut
#-------------------------------------------------------
sub update_windows_prodkey
{
my $class = shift;
my $node = shift;
my $product = shift;
my $key = shift;
unless(defined($node) && defined($product) && defined($key))
{
return 1;
}
# please notice this db usage
my %keyhash;
my %updates;
$keyhash{'node'} = $node;
$updates{'product'} = $product;
$updates{'key'} = $key;
my $tab = xCAT::Table->new('prodkey', -create=>1, -autocommit=>0);
$tab->setAttribs( \%keyhash,\%updates );
$tab->commit;
$tab->close;
return 0;
}
#-------------------------------------------------------------------------------
=head3 check_nicips
Description: Check if the nicips defined in MAC file is correct
@@ -1187,70 +958,3 @@ sub check_nicips{
return (0, \%nics_hash, "");
}
#-------------------------------------------------------------------------------
=head3 gen_chain_for_profiles
Description: Generate a chain string based on Network/Hardware/Image profiles.
Arguments: $profiles_hash: The reference for profiles hash.
For example:
$profiles_hash = { 'HardwareProfile' => 'IBM_NeXtScale_M4',
'ImageProfile' => 'rhels6.5-x86_64-stateful-compute',
'NetworkProfile' => 'default_network_profile',
}
$hw_reconfig: the flag shows whether we need re-configure all hardware
relative settings or not: like runcmds, runimg...etc
Returns: ($retcode, $chain)
$retcode = 1. Generate chain failed, $chain stands for error message.
$retcode = 0. Generate chain OK. $chain stands for the chain string.
=cut
#-------------------------------------------------------------------------------
sub gen_chain_for_profiles{
my $class = shift;
my $profiles_hashref = shift;
my $hw_reconfig = shift;
my $final_chain = "";
if (! $profiles_hashref){
return (1, "Missing parameter for gen_chain_for_profiles.");
}
# A node must have at least imageprofile and network profile.
unless (defined $profiles_hashref->{'ImageProfile'}){
return (1, "No imageprofile specified in profiles hash.");
}
unless (defined $profiles_hashref->{'NetworkProfile'}){
return (1, "No networkprofile specified in profiles hash.");
}
my $hwprofile = $profiles_hashref->{'HardwareProfile'};
my $imgprofile = $profiles_hashref->{'ImageProfile'};
my $netprofile = $profiles_hashref->{'NetworkProfile'};
# Get node's provisioning method
my $provmethod = xCAT::ProfiledNodeUtils->get_imageprofile_prov_method($imgprofile);
unless ($provmethod ){
return (1, "Can not get provisioning method for image profile $imgprofile");
}
my $netprofileattr = xCAT::ProfiledNodeUtils->get_nodes_nic_attrs([$netprofile])->{$netprofile};
unless ($netprofileattr){
return (1, "Can not get attributes for network profile $netprofile");
}
$final_chain = 'osimage='.$provmethod.":--noupdateinitrd";
# get the chain attribute from hardwareprofile and insert it to node.
if (defined $hwprofile and $hwprofile and $hw_reconfig){
my $chaintab = xCAT::Table->new('chain');
my $chain = $chaintab->getNodeAttribs($hwprofile, ['chain']);
if (exists $chain->{'chain'}) {
my $hw_chain = $chain->{'chain'};
$final_chain = $hw_chain.',osimage='.$provmethod.":--noupdateinitrd";
}
}
#run bmcsetups.
if ((exists $netprofileattr->{"bmc"}) and $hw_reconfig){
if (index($final_chain, "runcmd=bmcsetup") == -1){
$final_chain = 'runcmd=bmcsetup,'.$final_chain.':reboot4deploy';
}
else{
$final_chain = $final_chain.':reboot4deploy';
}
}
return (0, $final_chain);
}
+31 -47
View File
@@ -35,22 +35,21 @@ package xCAT::RemoteShellExp;
node.
DSH_TO_USERID - The userid on the node where the ssh keys will be updated.
DSH_ENABLE_SSH - Node to node root passwordless ssh will be setup.
DSH_ZONE_SSHKEYS - directory containing the zones root .ssh keys
Usage: remoteshellexp
[-t node list] test ssh connection to the node
[-k] Generates the ssh keys needed , for the user on the MN.
[-s node list] copies the ssh keys to the nodes
optional $timeout = timeout value for the expect. Usually from the xdsh -t flag
default timeout is 10 seconds
exit 0 - good
exit 1 - abort
exit 2 - usage error
Examples:
$rc=xCAT::RemoteShellExp->remoteshellexp("k",$callback,$remoteshellcmd,$nodes,$timeout);
$rc=xCAT::RemoteShellExp->remoteshellexp("s",$callback,$remoteshellcmd,$nodes,$timeout);
$rc=xCAT::RemoteShellExp->remoteshellexp("t",$callback,$remoteshellcmd,$nodes,$timeout);
$rc=xCAT::RemoteShellExp->remoteshellexp("k",$callback,$remoteshellcmd);
$rc=xCAT::RemoteShellExp->remoteshellexp("s",$callback,$remoteshellcmd,$nodes);
$rc=xCAT::RemoteShellExp->remoteshellexp("t",$callback,$remoteshellcmd,$nodes);
=cut
@@ -71,7 +70,7 @@ use strict;
#-----------------------------------------------------------------------------
sub remoteshellexp
{
my ($class, $flag, $callback, $remoteshell, $nodes, $timeout) = @_;
my ($class, $flag, $callback, $remoteshell, $nodes) = @_;
my $rc=0;
$::CALLBACK = $callback;
if (!($flag))
@@ -91,10 +90,6 @@ sub remoteshellexp
return 2;
}
my $expecttimeout=10; # default
if (defined($timeout)) { # value supplied
$expecttimeout=$timeout;
}
# for -s flag must have nodes and a $to_userid password
my $to_user_password;
@@ -144,7 +139,7 @@ sub remoteshellexp
} else {
$from_userid="root";
}
# set User on the node where we will send the keys
# set User on the node where we will send the keys
# this id can be a local id as well as root
if ($ENV{'DSH_TO_USERID'}) {
$to_userid=$ENV{'DSH_TO_USERID'};
@@ -154,19 +149,18 @@ sub remoteshellexp
# set User home directory to find the ssh public key to send
# For non-root ids information may not be in /etc/passwd
# but elsewhere like LDAP
if ($ENV{'DSH_FROM_USERID_HOME'}) {
$home=$ENV{'DSH_FROM_USERID_HOME'};
$home=$ENV{'DSH_FROM_USERID_HOME'};
} else {
$home=xCAT::Utils->getHomeDir($from_userid);
$home=xCAT::Utils->getHomeDir($from_userid);
}
# This indicates we will generate new ssh keys for the user,
# if they are not already there
# unless using zones
my $key="$home/.ssh/id_rsa";
my $key2="$home/.ssh/id_rsa.pub";
# Check to see if empty
if (-z $key) {
my $key="$home/.ssh/id_rsa";
my $key2="$home/.ssh/id_rsa.pub";
# Check to see if empty
if (-z $key) {
my $rsp = {};
$rsp->{error}->[0] =
"The $key file is empty. Remove it and rerun the command.";
@@ -184,8 +178,9 @@ sub remoteshellexp
}
if (($flag eq "k") && (!(-e $key)))
{
# updating keys and the key file does not exist
$rc=xCAT::RemoteShellExp->gensshkeys($expecttimeout);
# if the file size of the id_rsa key is 0, tell them to remove it
# and run the command again
$rc=xCAT::RemoteShellExp->gensshkeys;
}
# send ssh keys to the nodes/devices, to setup passwordless ssh
if ($flag eq "s")
@@ -198,18 +193,15 @@ sub remoteshellexp
return 1;
}
if ($ssh_setup_cmd) { # setup ssh on devices
$rc=xCAT::RemoteShellExp->senddeviceskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$ssh_setup_cmd,$nodes, $expecttimeout);
$rc=xCAT::RemoteShellExp->senddeviceskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$ssh_setup_cmd,$nodes);
} else { #setup ssh on nodes
if ($ENV{'DSH_ZONE_SSHKEYS'}) { # if using zones the override the location of the keys
$home= $ENV{'DSH_ZONE_SSHKEYS'};
}
$rc=xCAT::RemoteShellExp->sendnodeskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$nodes, $expecttimeout);
$rc=xCAT::RemoteShellExp->sendnodeskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$nodes);
}
}
# test ssh setup on the node
if ($flag eq "t")
{
$rc=xCAT::RemoteShellExp->testkeys($remoteshell,$to_userid,$nodes,$expecttimeout);
$rc=xCAT::RemoteShellExp->testkeys($remoteshell,$to_userid,$nodes);
}
return $rc;
}
@@ -228,9 +220,9 @@ sub remoteshellexp
sub gensshkeys
{
my ($class, $expecttimeout) = @_;
my ($class) = @_;
my $keygen;
my $timeout = $expecttimeout; # sets Expect default timeout, 0 accepts immediately
my $timeout = 10; # sets Expect default timeout, 0 accepts immediately
my $keygen_sent = 0;
my $prompt1 = 'Generating public/private rsa';
my $prompt2 = 'Enter file.*:';
@@ -355,9 +347,9 @@ sub gensshkeys
sub testkeys
{
my ($class,$remoteshell,$to_userid,$nodes, $expecttimeout) = @_;
my ($class,$remoteshell,$to_userid,$nodes) = @_;
my $testkeys;
my $timeout = $expecttimeout; # sets Expect default timeout
my $timeout = 10; # sets Expect default timeout, 0 accepts immediately
my $testkeys_sent = 0;
my $prompt1 = 'Are you sure you want to continue connecting (yes/no)?';
my $prompt2 = 'ssword:';
@@ -477,9 +469,9 @@ sub testkeys
sub sendnodeskeys
{
my ($class,$remoteshell,$remotecopy,$to_userid,$to_userpassword,$home,$nodes, $expecttimeout) = @_;
my ($class,$remoteshell,$remotecopy,$to_userid,$to_userpassword,$home,$nodes) = @_;
my $sendkeys;
my $timeout = $expecttimeout; # sets Expect default timeout, 0 accepts immediately
my $timeout = 10; # sets Expect default timeout, 0 accepts immediately
my $sendkeys_sent = 0;
my $prompt1 = 'Are you sure you want to continue connecting (yes/no)?';
my $prompt2 = 'ssword:';
@@ -498,15 +490,11 @@ sub sendnodeskeys
# in $HOME/.ssh/tmp/authorized_keys
# copy to the node to the temp directory
# scp $HOME/.ssh/tmp/authorized_keys to_userid@<node>:/tmp/$to_userid/.ssh
# scp $HOME/.ssh/id_rsa.pub to_userid@<node>:/tmp/$to_userid/.ssh
# Note if using zones, the keys do not come from ~/.ssh but from the
# zone table, sshkeydir attribute. For zones the userid is always root
# If you are going to enable ssh to ssh between nodes, then
# scp $HOME/.ssh/id_rsa to that temp directory on the node
# copy the script $HOME/.ssh/copy.sh to the node, it will do the
# the work of setting up the user's ssh keys and clean up
# ssh (run) copy.sh on the node
my @nodelist=split(/,/,$nodes);
foreach my $node (@nodelist) {
$sendkeys = new Expect;
@@ -614,11 +602,11 @@ sub sendnodeskeys
my $spawncopyfiles;
if ($ENV{'DSH_ENABLE_SSH'}) { # we will enable node to node ssh
$spawncopyfiles=
"$remotecopy $home/.ssh/id_rsa $home/.ssh/id_rsa.pub $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ";
"$remotecopy $home/.ssh/id_rsa $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ";
} else { # no node to node ssh ( don't send private key)
$spawncopyfiles=
"$remotecopy $home/.ssh/id_rsa.pub $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ";
"$remotecopy $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ";
}
# send copy command
unless ($sendkeys->spawn($spawncopyfiles))
@@ -771,7 +759,7 @@ sub sendnodeskeys
=head3 senddeviceskeys
Setup the ssh keys on the switches
Setup the ssh keys on the nodes
=cut
@@ -780,9 +768,9 @@ sub sendnodeskeys
sub senddeviceskeys
{
my ($class,$remoteshell,$remotecopy,$to_userid,$to_userpassword,$home,$ssh_setup_cmd,$nodes, $expecttimeout) = @_;
my ($class,$remoteshell,$remotecopy,$to_userid,$to_userpassword,$home,$ssh_setup_cmd,$nodes) = @_;
my $sendkeys;
my $timeout = $expecttimeout; # sets Expect default timeout, 0 accepts immediately
my $timeout = 10; # sets Expect default timeout, 0 accepts immediately
my $sendkeys_sent = 0;
my $prompt1 = 'Are you sure you want to continue connecting (yes/no)?';
my $prompt2 = 'ssword:';
@@ -810,10 +798,6 @@ sub senddeviceskeys
# add to the command
$setupcmd .=$key;
$setupcmd .="\"";
# Special case for vios
if ($ENV{DEVICETYPE} eq 'vios') {
$setupcmd = "\"echo $key | tee -a ~/.ssh/authorized_keys2\"";
}
# For each input device
my @nodelist=split(/,/,$nodes);
foreach my $node (@nodelist) {
+14 -32
View File
@@ -202,11 +202,9 @@ sub parse_and_run_sinv
#
my @nodelist = ();
my @cmdparts = ();
my $devicecommand =0;
if ($options{'devicetype'}) {
# must split different because devices have commands with spaces
@cmdparts = split(' ', $cmd,3);
$devicecommand =1;
} else {
@cmdparts = split(' ', $cmd);
}
@@ -505,7 +503,7 @@ sub parse_and_run_sinv
);
# write the results to the tempfile after running through xdshcoll
$rc = &storeresults($callback,$devicecommand);
$rc = &storeresults($callback);
}
$processflg = "node";
@@ -536,7 +534,7 @@ sub parse_and_run_sinv
# write the results to the tempfile after running through xdshcoll
$rc = &storeresults($callback,$devicecommand);
$rc = &storeresults($callback);
# Build report and write to output file
# if file exist and has something in it
@@ -1453,11 +1451,12 @@ sub rinvoutput
sub storeresults
{
my $callback = shift;
my $devicecommand= shift;
# open file to write results of xdsh or rinv command
my $newtempfile = $tempfile;
$newtempfile .= "temp";
unless (open(NEWTMPFILE, ">$newtempfile"))
open(FILE, ">$newtempfile");
if ($? > 0)
{
my $rsp = {};
$rsp->{data}->[0] = "Could not open $newtempfile\n";
@@ -1466,9 +1465,9 @@ sub storeresults
}
foreach my $line (@cmdresult)
{
print NEWTMPFILE $line;
print FILE $line;
}
close NEWTMPFILE;
close FILE;
my $outputfile;
if ($processflg eq "seednode")
{ # cmd to seednode
@@ -1480,7 +1479,8 @@ sub storeresults
}
# open file to put results of xdshcoll
unless (open(NEWOUTFILE, ">$outputfile"))
open(FILE, ">$outputfile");
if ($? > 0)
{
my $rsp = {};
$rsp->{data}->[0] = "Could not open $outputfile\n";
@@ -1489,7 +1489,8 @@ sub storeresults
}
my $cmd = " $::XCATROOT/sbin/xdshcoll <$newtempfile |";
unless (open(XCOLL, "$cmd"))
open(XCOLL, "$cmd");
if ($? > 0)
{
my $rsp = {};
$rsp->{data}->[0] = "Could not call xdshcoll \n";
@@ -1502,37 +1503,18 @@ sub storeresults
while (<XCOLL>)
{
$line = $_;
print NEWOUTFILE $line
print FILE $line
}
close(XCOLL);
close NEWOUTFILE;
close FILE;
system("/bin/rm $newtempfile");
# is device command, we get false errors from the Switch, check for
# blank error output lines and remove them. If there is nothing left
# then there really were no errors
my @newerrresult=();
my $processerrors =1;
if ($devicecommand==1) {
foreach my $line (@errresult)
{
my @newline = (split(/:/, $line));
if ($newline[1] !~ /^\s*$/) { # Not blank, then save it
push @newerrresult,$line;
}
}
my $arraysize=@newerrresult;
if ($arraysize < 1) {
$processerrors =0;
}
}
# capture errors
#
if ((@errresult) && ($processerrors ==1))
if (@errresult)
{ # if errors
my $rsp = {};
my $i = 0;
Executable → Regular
+428 -593
View File
File diff suppressed because it is too large Load Diff
+12 -84
View File
@@ -650,8 +650,7 @@ sub decode_spd {
8 => "DDR2 SDRAM",
9 => "DDR2 SDRAM FB-DIMM",
10 => "DDR2 SDRAM FB-DIMM PROBE",
11 => "DDR3 SDRAM",
12 => "DDR4 SDRAM",
11 => "DDR3 SDRAM"
);
my %modtypes = (
@@ -668,36 +667,31 @@ sub decode_spd {
1066 => 8500,
1333 => 10600,
1600 => 12800,
1867 => 14900,
2132 => 17000,
2133 => 17000,
2134 => 17000,
);
my %ddrmodcap = (
my %ddr3modcap = (
0 => 256,
1 => 512,
2 => 1024,
3 => 2048,
4 => 4096,
5 => 8192,
6 => 16384,
7 => 32768,
6 => 16384
);
my %ddrdevwidth = (
my %ddr3devwidth = (
0 => 4,
1 => 8,
2 => 16,
3 => 32
);
my %ddrranks = (
my %ddr3ranks = (
0 => 1,
1 => 2,
2 => 3,
3 => 4
);
my %ddrbuswidth = (
my %ddr3buswidth = (
0 => 8,
1 => 16,
2 => 32,
@@ -713,28 +707,17 @@ sub decode_spd {
}
$rethash->{product}->{name}=$memtypes{$spd[2]};
if ($spd[2] == 11) { #DDR3 spec applies
my $ftbdividend = $spd[9] >> 4;
my $ftbdivisor = $spd[9] & 0xf;
my $ftb = $ftbdividend/$ftbdivisor;
my $fineoffset = $spd[34];
if ($fineoffset & 0b10000000) {
#negative value, twos complement
$fineoffset = 0-(($fineoffset ^ 0xff) + 1);
}
$fineoffset = ($ftb * $fineoffset) * 10**-3;
my $mtb = $spd[10]/$spd[11];
my $clock = int(2/(($mtb*$spd[12]+$fineoffset)*10**-3));
my $speed = $speedfromclock{$clock};
unless ($speed) { $speed = "UNKNOWN"; }
$rethash->{product}->{name}="PC3-".$speed." ($clock MT/s)";
my $speed = $speedfromclock{int(2/($mtb*$spd[12]*10**-3))};
$rethash->{product}->{name}="PC3-".$speed;
if ($spd[8]&0b11000) {
$rethash->{product}->{name} .= " ECC";
}
$rethash->{product}->{name}.=" ".$modtypes{$spd[3]&0x0f};
my $sdramcap=$ddrmodcap{$spd[4]&0xf};
my $buswidth=$ddrbuswidth{$spd[8]&0b111};
my $sdramwidth=$ddrdevwidth{$spd[7]&0b111};
my $ranks = $ddrranks{($spd[7]&0b111000)>>3};
my $sdramcap=$ddr3modcap{$spd[4]&0xf};
my $buswidth=$ddr3buswidth{$spd[8]&0b111};
my $sdramwidth=$ddr3devwidth{$spd[7]&0b111};
my $ranks = $ddr3ranks{($spd[7]&0b111000)>>3};
my $capacity = $sdramcap/8*$buswidth/$sdramwidth*$ranks;
@@ -772,61 +755,6 @@ sub decode_spd {
# $rawspd .= sprintf("%02X ",$_);
#}
#push @{$rethash->{product}->{extra}},$rawspd;
} elsif ($spd[2] == 12) { #DDR4 spec applies
# spd[125] spd[18] spd[18is sdram min cycle time .. spd125 is fine offset for min time
# mtb and ftb are fixed in ddr4 spd spec.. mtb is always 0.125 ns and ftb is always 0.001 ns
my $speed;
my $clock;
if ($spd[17] == 0) {
my $fineoffset = $spd[125];
if ($fineoffset & 0b10000000) {
#negative value, twos complement
$fineoffset = 0-(($fineoffset ^ 0xff) + 1);
}
$clock = int(2/((0.125*$spd[18] + $fineoffset*0.001)*0.001));
$speed = $speedfromclock{$clock};
unless ($speed) { $speed = "UNKNOWN"; }
} else { # this would mean a different MTB and FTB than spec indicated..
$clock = "UNKNOWN";
$speed = "UNKNOWN";
}
$rethash->{product}->{name}="PC4-".$speed." ($clock MT/s)";
if ($spd[13]&0b11000 == 0b1000) {
$rethash->{product}->{name} .= " ECC";
}
$rethash->{product}->{name}.=" ".$modtypes{$spd[3]&0x0f};
my $sdramcap=$ddrmodcap{$spd[4]&0xf};
my $buswidth=$ddrbuswidth{$spd[13]&0b111};
my $sdramwidth=$ddrdevwidth{$spd[12]&0b111};
my $ranks = $ddrranks{($spd[12]&0b111000)>>3};
my $capacity = $sdramcap/8*$buswidth/$sdramwidth*$ranks;
if ($capacity < 1024) {
$capacity = $capacity."MB";
} else {
$capacity = ($capacity/1024)."GB";
}
$rethash->{product}->{name} = $capacity." ".$rethash->{product}->{name};
$rethash->{product}->{manufacturer} = decode_manufacturer($spd[320],$spd[321]);
$rethash->{product}->{buildlocation} = sprintf("%02x",$spd[322]);
if ($spd[120] != 0 or $spd[121] != 0) {
$rethash->{product}->{builddate} = sprintf("Week %x of 20%02x",$spd[323],$spd[324]);
}
foreach (@spd[329..348]) {
if ($_ > 126 or $_ < 32) {
$rethash->{product}->{model}="Malformed SPD";
}
}
unless ($rethash->{product}->{model}) {
$rethash->{product}->{model}=pack("C*",@spd[329..348]);
}
#my $rawspd="SPD Dump: ";
#foreach (@spd) {
# $rawspd .= sprintf("%02X ",$_);
#}
#push @{$rethash->{product}->{extra}},$rawspd;
} else {
$rethash->{product}->{model}="Unrecognized SPD";
}
Executable → Regular
+135 -571
View File
File diff suppressed because it is too large Load Diff
+24 -27
View File
@@ -10,8 +10,12 @@ BEGIN
# if AIX - make sure we include perl 5.8.2 in INC path.
# Needed to find perl dependencies shipped in deps tarball.
if ($^O =~ /^aix/i) {
unshift(@INC, qw(/usr/opt/perl5/lib/5.8.2/aix-thread-multi /usr/opt/perl5/lib/5.8.2 /usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi /usr/opt/perl5/lib/site_perl/5.8.2));
}
use lib "/usr/opt/perl5/lib/5.8.2/aix-thread-multi";
use lib "/usr/opt/perl5/lib/5.8.2";
use lib "/usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi";
use lib "/usr/opt/perl5/lib/site_perl/5.8.2";
}
use lib "$::XCATROOT/lib/perl";
use strict;
#-----------------------------------------------------------------------------
@@ -26,6 +30,7 @@ use strict;
Example:
my $retdata = xCAT::ServiceNodeUtils->readSNInfo;
=cut
#-----------------------------------------------------------------------------
sub readSNInfo
{
@@ -97,17 +102,13 @@ sub isServiceReq
require xCAT::Table;
my ($class, $servicenodename, $serviceip) = @_;
# get list of all services from service node table ( actually all defined attributes)
# read the schema
my $schema = xCAT::Table->getTableSchema("servicenode");
my @services; # list of only the actual service attributes from the servicenode table
my @servicesattrs; # building second copy for call to getAllNodeAttribs, which modifies the array
foreach my $c (@{$schema->{cols}}) {
if (($c ne "node") && ($c ne "comments") && ($c ne "disable")) {
push @servicesattrs,$c;
push @services,$c;
}
}
# list of all services from service node table
# note this must be updated if more services added
my @services = (
"nameserver", "dhcpserver", "tftpserver", "nfsserver",
"conserver", "monserver", "ldapserver", "ntpserver",
"ftpserver", "ipforward"
);
my @ips = @$serviceip; # list of service node ip addresses and names
my $rc = 0;
@@ -138,11 +139,10 @@ sub isServiceReq
}
my $servicehash;
# read all the nodes from the table, all the service attributes
my @snodelist= $servicenodetab->getAllNodeAttribs(\@servicesattrs);
foreach my $service (@services) # check list of services
# read all the nodes from the table, for each service
foreach my $service (@services)
{
my @snodelist = $servicenodetab->getAllNodeAttribs([$service]);
foreach $serviceip (@ips) # check the table for this servicenode
{
@@ -159,8 +159,6 @@ sub isServiceReq
if (($value eq "1") || ($value eq "YES"))
{
$servicehash->{$service} = "1";
} elsif ($value eq "2") {
$servicehash->{$service} = "2";
} else {
$servicehash->{$service} = "0";
}
@@ -240,13 +238,12 @@ sub getAllSN
# if did not input "ALL" and there is a MN, remove it
my @newservicenodes;
if ((!defined($options)) || ($options ne "ALL")) {
my @mname = xCAT::Utils->noderangecontainsMn(@servicenodes);
if (@mname) { # if there is a MN
foreach my $node (@servicenodes) {
# check to see if node in MN list
if (!(grep(/^$node$/, @mname))) { # if node not in the MN array
push @newservicenodes, $node;
}
my $mname = xCAT::Utils->noderangecontainsMn(@servicenodes);
if ($mname) { # if there is a MN
foreach my $nodes (@servicenodes) {
if ($mname ne ($nodes)){
push @newservicenodes, $nodes;
}
}
$servicenodetab->close;
return @newservicenodes; # return without the MN in the array
@@ -354,7 +351,7 @@ sub getSNList
$servicenodetab->close;
foreach my $node (@nodes)
{
if (! defined ($service) || ($service eq "")) # want all the service nodes
if ($service eq "") # want all the service nodes
{
push @servicenodes, $node->{node};
}
+73 -115
View File
@@ -70,7 +70,7 @@ require xCAT::NotifHandler;
my $dbworkerpid; #The process id of the database worker
my $dbworkersocket;
my $dbsockpath = "/var/run/xcat/dbworker.sock.".$$;
my $dbsockpath = "/tmp/xcat/dbworker.sock.".$$;
my $exitdbthread;
my $dbobjsforhandle;
my $intendedpid;
@@ -159,7 +159,7 @@ sub init_dbworker {
#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";
use File::Path;
mkpath('/var/run/xcat/');
mkpath('/tmp/xcat/');
use IO::Socket;
$SIG{TERM} = $SIG{INT} = sub {
$exitdbthread=1;
@@ -179,10 +179,6 @@ sub init_dbworker {
#setup signal in NotifHandler so that the cache can be updated
xCAT::NotifHandler::setup($$, 0);
# NOTE: There's a bug that sometimes the %SIG is cleaned up by accident, but we cannot figure out when and why
# this happens. The temporary fix is to backup the %SIG and recover it when necessary.
my %SIGbakup = %SIG;
while (not $exitdbthread) {
eval {
my @ready_socks = $clientset->can_read;
@@ -195,7 +191,6 @@ sub init_dbworker {
} else {
eval {
handle_dbc_conn($currcon,$clientset);
unless (%SIG && defined ($SIG{USR1})) { %SIG = %SIGbakup; }
};
if ($@) {
my $err=$@;
@@ -220,9 +215,6 @@ sub init_dbworker {
exit(0);
}
}
# sleep a while to make sure the client process has done
sleep 1.5;
close($dbworkersocket);
unlink($dbsockpath);
exit 0;
@@ -331,8 +323,6 @@ sub handle_dbc_request {
return $opentables{$tablename}->{$autocommit}->getAllNodeAttribs(@args);
} elsif ($functionname eq 'getAllEntries') {
return $opentables{$tablename}->{$autocommit}->getAllEntries(@args);
} elsif ($functionname eq 'getMAXMINEntries') {
return $opentables{$tablename}->{$autocommit}->getMAXMINEntries(@args);
} elsif ($functionname eq 'writeAllEntries') {
return $opentables{$tablename}->{$autocommit}->writeAllEntries(@args);
} elsif ($functionname eq 'getAllAttribsWhere') {
@@ -1613,7 +1603,7 @@ sub setAttribs
# delimit the columns of the table
my $delimitedcol = &delimitcol($col);
$cols = $cols . $delimitedcol . " = ?,";
push @bind, (($$elems{$col} eq "NULL") ? undef: $$elems{$col});
push @bind, (($$elems{$col} =~ /NULL/) ? undef: $$elems{$col});
}
chop($cols);
my $cmd ;
@@ -1796,7 +1786,7 @@ sub setAttribsWhere
# delimit the columns of the table
my $delimitedcol = &delimitcol($col);
$cols = $cols . $delimitedcol . " = ?,";
push @bind, (($$elems{$col} eq "NULL") ? undef: $$elems{$col});
push @bind, (($$elems{$col} =~ /NULL/) ? undef: $$elems{$col});
}
chop($cols);
my $cmd = "UPDATE " . $self->{tabname} . " set $cols where " . $where_clause;
@@ -2359,6 +2349,71 @@ sub getNodeAttribs
#--------------------------------------------------------------------------
=head3 getNodeSpecAttribs
Description: Retrieves the requested attributes which matching the specified options for a node
Arguments:
Noderange
The specified options
List of attributes
Return:
Attribute hash
Example:
my $tab = xCAT::Table->new('ppcdirect');
my $ent = $tab->getNodeSpecAttribs($node, {username=>'HMC'}, qw/password/);
Comments:
The keys of the specified options can be given in the list of attributes or not,
this routine will deal with them.
=cut
#--------------------------------------------------------------------------
#sub getNodeSpecAttribs {
# my $self = shift;
# my $node = shift;
# my %options = ();
# my @attribs = ();
# my @keys = ();
# if (ref $_[0] eq 'HASH') {
# %options = %{shift()};
# @attribs = @_;
# foreach my $key (keys %options) {
# if (!grep(/^$key$/, @attribs)) {
# push @attribs, $key;
# }
# }
# } else {
# @attribs = @_;
# }
# if ((keys (%options)) == 0) {
# my $ent = $self->getNodeAttribs($node, \@attribs);
# return $ent;
# } else {
# my $nodekey = "node";
# if (defined $xCAT::Schema::tabspec{$self->{tabname}}->{nodecol}) {
# $nodekey = $xCAT::Schema::tabspec{$self->{tabname}}->{nodecol};
# }
# $options{$nodekey} = $node;
# my $ent = $self->getAttribs(\%options, \@attribs);
# if ($ent) {
# return $ent;
# }
# my ($nodeghash) = $self->{nodelist}->getAttribs({node=>$node}, "groups");
# unless(defined($nodeghash) && defined($nodeghash->{groups})) {
# return undef;
# }
# my @nodegroups = split(/,/, $nodeghash->{groups});
# foreach my $group (@nodegroups) {
# $options{$nodekey} = $group;
# my $g_ret = $self->getAttribs(\%options, \@attribs);
# if ($g_ret) {
# return $g_ret;
# }
# }
# }
# return undef;
#}
#--------------------------------------------------------------------------
=head3 getNodeAttribs_nosub
Description:
@@ -2912,14 +2967,10 @@ sub getAllNodeAttribs
$self->{nrcache}->{$data->{$nodekey}}->{tstamp} = time();
}
@nodes = @{$self->{nrcache}->{$data->{$nodekey}}->{value}}; #expand node entry, to make groups expand
#If node not in nodelist do not add to the hash (SF 3580)
#unless (@nodes) { #in the event of an entry not in nodelist, use entry value verbatim
# @nodes = ($data->{$nodekey});
#} end SF 3580
unless (@nodes) { #in the event of an entry not in nodelist, use entry value verbatim
@nodes = ($data->{$nodekey});
}
#my $localhash = $self->getNodesAttribs(\@nodes,$attribq); #NOTE: This is stupid, rebuilds the cache for every entry, FIXME
foreach (@nodes)
{
if ($donenodes{$_}) { next; }
@@ -3842,7 +3893,7 @@ sub writeAllEntries
}
my $filename = shift;
my $fh;
my $rc = 0;
my $rc;
# open the file for write
unless (open($fh," > $filename")) {
my $msg="Unable to open $filename for write \n.";
@@ -3998,98 +4049,5 @@ sub output_table {
print $fh "\n";
return 0;
}
#--------------------------------------------------------------------------
=head3 getMAXMINEntries
Description: Select the rows in the Table which has the MAX and the row with the
Min value for the input attribute.
Currently only the auditlog and evenlog are setup to have such an attribute (recid).
Arguments:
Table handle
attribute name ( e.g. recid)
Returns:
HASH
max=> max value
min=> min value
Globals:
Error:
Example:
my $tabh = xCAT::Table->new($table);
my $recs=$tabh->getEntries("recid"); # returns row with recid max value in database
# and the row with the min value.
Comments:
none
=cut
#--------------------------------------------------------------------------------
sub getMAXMINEntries
{
my $self = shift;
if ($dbworkerpid) {
return dbc_call($self,'getMAXMINEntries',@_);
}
my $attr = shift;
my $rets;
my $query;
my $xcatcfg=get_xcatcfg();
# delimit the disable column based on the DB
my $disable= &delimitcol("disable");
my $qstring;
if ($xcatcfg =~ /^DB2:/) { # for DB2
$qstring = "SELECT MAX (\"$attr\") FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
} else {
$qstring = "SELECT MAX($attr) FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
}
$query = $self->{dbh}->prepare($qstring);
$query->execute();
while (my $data = $query->fetchrow_hashref())
{
foreach (keys %$data)
{
if ($data->{$_} =~ /^$/)
{
$rets->{"max"} = undef;
} else {
$rets->{"max"} = $data->{$_};
}
last; # better only be one value for max
}
}
$query->finish();
if ($xcatcfg =~ /^DB2:/) { # for DB2
$qstring = "SELECT MIN (\"$attr\") FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
} else {
$qstring = "SELECT MIN($attr) FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
}
$query = $self->{dbh}->prepare($qstring);
$query->execute();
while (my $data = $query->fetchrow_hashref())
{
foreach (keys %$data)
{
if ($data->{$_} =~ /^$/)
{
$rets->{"min"} = undef;
} else {
$rets->{"min"} = $data->{$_};
}
last; # better be only one value for min
}
}
return $rets;
}
1;
Executable → Regular
+62 -461
View File
@@ -10,13 +10,15 @@ BEGIN
# if AIX - make sure we include perl 5.8.2 in INC path.
# Needed to find perl dependencies shipped in deps tarball.
if ($^O =~ /^aix/i) {
unshift(@INC, qw(/usr/opt/perl5/lib/5.8.2/aix-thread-multi /usr/opt/perl5/lib/5.8.2 /usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi /usr/opt/perl5/lib/site_perl/5.8.2));
}
use lib "/usr/opt/perl5/lib/5.8.2/aix-thread-multi";
use lib "/usr/opt/perl5/lib/5.8.2";
use lib "/usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi";
use lib "/usr/opt/perl5/lib/site_perl/5.8.2";
}
use lib "$::XCATROOT/lib/perl";
use strict;
require xCAT::Table;
require xCAT::Zone;
use File::Path;
#-----------------------------------------------------------------------
@@ -255,7 +257,6 @@ sub bldnonrootSSHFiles
Arguments:
Array of nodes
Timeout for expect call (optional)
Returns:
Env Variables: $DSH_FROM_USERID, $DSH_TO_USERID, $DSH_REMOTE_PASSWORD
@@ -269,7 +270,7 @@ sub bldnonrootSSHFiles
Error:
0=good, 1=error
Example:
xCAT::TableUtils->setupSSH(@target_nodes,$expecttimeout);
xCAT::TableUtils->setupSSH(@target_nodes);
Comments:
Does not setup known_hosts. Assumes automatically
setup by SSH ( ssh config option StrictHostKeyChecking no should
@@ -280,7 +281,7 @@ sub bldnonrootSSHFiles
#--------------------------------------------------------------------------------
sub setupSSH
{
my ($class, $ref_nodes,$expecttimeout) = @_;
my ($class, $ref_nodes) = @_;
my @nodes = $ref_nodes;
my @badnodes = ();
my $n_str = $nodes[0];
@@ -333,24 +334,23 @@ sub setupSSH
$::REMOTE_SHELL = "/usr/bin/ssh";
my $rsp = {};
# Get the home directory
my $home = xCAT::Utils->getHomeDir($from_userid);
$ENV{'DSH_FROM_USERID_HOME'} = $home;
if ($from_userid eq "root")
{
# make the directory to hold keys to transfer to the nodes
if (!-d $SSHdir)
{
mkpath("$SSHdir", { mode => 0755 });
}
# generates new keys for root, if they do not already exist ~/.ssh
# nodes not used on this option but in there to preserve the interface
# generates new keys for root, if they do not already exist
my $rc=
xCAT::RemoteShellExp->remoteshellexp("k",$::CALLBACK,$::REMOTE_SHELL,$n_str,$expecttimeout);
xCAT::RemoteShellExp->remoteshellexp("k",$::CALLBACK,$::REMOTE_SHELL);
if ($rc != 0) {
$rsp->{data}->[0] = "remoteshellexp failed generating keys.";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
@@ -372,10 +372,7 @@ else
fi
mkdir -p \$dest_dir
cat /tmp/$to_userid/.ssh/authorized_keys >> \$home/.ssh/authorized_keys 2>&1
cat /tmp/$to_userid/.ssh/id_rsa.pub >> \$home/.ssh/authorized_keys 2>&1
rm -f \$home/.ssh/id_rsa 2>&1
cp /tmp/$to_userid/.ssh/id_rsa \$home/.ssh/id_rsa 2>&1
cp /tmp/$to_userid/.ssh/id_rsa.pub \$home/.ssh/id_rsa.pub 2>&1
chmod 0600 \$home/.ssh/id_* 2>&1
rm -f /tmp/$to_userid/.ssh/* 2>&1
rmdir \"/tmp/$to_userid/.ssh\"
@@ -387,7 +384,6 @@ rmdir \"/tmp/$to_userid\" \n";
my $auth_key2=0;
if ($from_userid eq "root")
{
# this will put the root/.ssh/id_rsa.pub key in the authorized keys file to put on the node
my $rc = xCAT::TableUtils->cpSSHFiles($SSHdir);
if ($rc != 0)
{ # error
@@ -420,49 +416,53 @@ rmdir \"/tmp/$to_userid\" \n";
xCAT::TableUtils->bldnonrootSSHFiles($from_userid);
}
# send the keys
# send the keys to the nodes for root or some other id
#
# This environment variable determines whether to setup
# node to node ssh
# The nodes must be checked against the site.sshbetweennodes attribute
# For root user and not to devices only to nodes
if (($from_userid eq "root") && (!($ENV{'DEVICETYPE'}))) {
# Need to check if nodes are in a zone.
my @zones;
my $tab = xCAT::Table->new("zone");
if ($tab)
my $enablenodes;
my $disablenodes;
my @nodelist= split(",", $n_str);
foreach my $n (@nodelist)
{
# if we have zones, need to send the zone keys to each node in the zone
my @attribs = ("zonename");
@zones = $tab->getAllAttribs(@attribs);
$tab->close();
} else {
$rsp->{data}->[0] = "Could not open zone table.\n";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
return 1;
}
# check for zones, key send is different if zones defined or not
if (@zones) { # we have zones defined
my $rc = xCAT::TableUtils->sendkeysTOzones($ref_nodes,$expecttimeout);
if ($rc != 0)
{
$rsp->{data}->[0] = "Error sending ssh keys to the zones.\n";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
exit 1;
my $enablessh=xCAT::TableUtils->enablessh($n);
if ($enablessh == 1) {
$enablenodes .= $n;
$enablenodes .= ",";
} else {
$disablenodes .= $n;
$disablenodes .= ",";
}
} else { # no zones
# if no zone table defined, do it the old way , keys are in ~/.ssh
my $rc = xCAT::TableUtils->sendkeysNOzones($ref_nodes,$expecttimeout);
}
my $cmd;
if ($enablenodes) { # node on list to setup nodetonodessh
chop $enablenodes; # remove last comma
$ENV{'DSH_ENABLE_SSH'} = "YES";
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$enablenodes);
if ($rc != 0)
{
$rsp->{data}->[0] = "Error sending ssh keys to the nodes.\n";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
{
$rsp->{data}->[0] = "remoteshellexp failed sending keys to enablenodes.";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
}
}
if ($disablenodes) { # node on list to setup nodetonodessh
chop $disablenodes; # remove last comma
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$disablenodes);
if ($rc != 0)
{
$rsp->{data}->[0] = "remoteshellexp failed sending keys to disablenodes.";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
}
}
} else { # from user is not root or it is a device , always send private key
$ENV{'DSH_ENABLE_SSH'} = "YES";
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$n_str,$expecttimeout);
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$n_str);
if ($rc != 0)
{
$rsp->{data}->[0] = "remoteshellexp failed sending keys.";
@@ -476,7 +476,7 @@ rmdir \"/tmp/$to_userid\" \n";
foreach my $n (@testnodes)
{
my $rc=
xCAT::RemoteShellExp->remoteshellexp("t",$::CALLBACK,"/usr/bin/ssh",$n,$expecttimeout);
xCAT::RemoteShellExp->remoteshellexp("t",$::CALLBACK,"/usr/bin/ssh",$n);
if ($rc != 0)
{
push @badnodes, $n;
@@ -501,235 +501,6 @@ rmdir \"/tmp/$to_userid\" \n";
#--------------------------------------------------------------------------------
=head3 sendkeysNOzones
Transfers the ssh keys
for the root id on the nodes no zones
key from ~/.ssh site.sshbetweennodes honored
Arguments:
Array of nodes
Timeout for expect call (optional)
Returns:
Env Variables: $DSH_FROM_USERID, $DSH_TO_USERID, $DSH_REMOTE_PASSWORD
the ssh keys are transferred from the $DSH_FROM_USERID to the $DSH_TO_USERID
on the node(s). The DSH_REMOTE_PASSWORD and the DSH_FROM_USERID
must be obtained by
the calling script or from the xdsh client
Globals:
$::XCATROOT , $::CALLBACK
Error:
0=good, 1=error
Example:
xCAT::TableUtils->sendkeysNOzones($ref_nodes,$expecttimeout);
Comments:
Does not setup known_hosts. Assumes automatically
setup by SSH ( ssh config option StrictHostKeyChecking no should
be set in the ssh config file).
=cut
#--------------------------------------------------------------------------------
sub sendkeysNOzones
{
my ($class, $ref_nodes,$expecttimeout) = @_;
my @nodes=$ref_nodes;
my $enablenodes;
my $disablenodes;
my $n_str = $nodes[0];
my @nodelist= split(",", $n_str);
my $rsp = ();
foreach my $n (@nodelist)
{
my $enablessh=xCAT::TableUtils->enablessh($n);
if ($enablessh == 1) {
$enablenodes .= $n;
$enablenodes .= ",";
} else {
$disablenodes .= $n;
$disablenodes .= ",";
}
}
if ($enablenodes) { # node on list to setup nodetonodessh
chop $enablenodes; # remove last comma
$ENV{'DSH_ENABLE_SSH'} = "YES";
# send the keys to the nodes
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$enablenodes,$expecttimeout);
if ($rc != 0)
{
$rsp->{data}->[0] = "remoteshellexp failed sending keys to enablenodes.";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
}
}
if ($disablenodes) { # node on list to disable nodetonodessh
chop $disablenodes; # remove last comma
# send the keys to the nodes
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$disablenodes,$expecttimeout);
if ($rc != 0)
{
$rsp->{data}->[0] = "remoteshellexp failed sending keys to disablenodes.";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
}
}
}
#--------------------------------------------------------------------------------
=head3 sendkeysTOzones
Transfers the ssh keys
for the root id on the nodes using the zone table.
If in a zone, then root ssh keys for the node will be taken from the zones ssh keys not ~/.ssh
zones are only supported on nodes that are not a service node.
Also for the call to RemoteShellExp, we must group the nodes that are in the same zone
Arguments:
Array of nodes
Timeout for expect call (optional)
Returns:
Env Variables: $DSH_FROM_USERID, $DSH_TO_USERID, $DSH_REMOTE_PASSWORD
the ssh keys are transferred from the $DSH_FROM_USERID to the $DSH_TO_USERID
on the node(s). The DSH_REMOTE_PASSWORD and the DSH_FROM_USERID
must be obtained by
the calling script or from the xdsh client
Globals:
$::XCATROOT , $::CALLBACK
Error:
0=good, 1=error
Example:
xCAT::TableUtils->sendkeysTOzones($ref_nodes,$expecttimeout);
Comments:
Does not setup known_hosts. Assumes automatically
setup by SSH ( ssh config option StrictHostKeyChecking no should
be set in the ssh config file).
=cut
#--------------------------------------------------------------------------------
sub sendkeysTOzones
{
my ($class, $ref_nodes,$expecttimeout) = @_;
my @nodes=$ref_nodes;
my $n_str = $nodes[0];
@nodes= split(",", $n_str);
my $rsp = ();
my $cmd;
my $roothome = xCAT::Utils->getHomeDir("root");
my $zonehash =xCAT::Zone->getzoneinfo($::CALLBACK,\@nodes);
foreach my $zonename (keys %$zonehash) {
# build list of nodes
my $zonenodelist="";
foreach my $node (@{$zonehash->{$zonename}->{nodes}}) {
$zonenodelist .= $node;
$zonenodelist .= ",";
}
$zonenodelist =~ s/,$//; # remove last comma
# if any nodes defined for the zone
if ($zonenodelist) {
# check to see if we enable passwordless ssh between the nodes
if (!(defined($zonehash->{$zonename}->{sshbetweennodes}))||
(($zonehash->{$zonename}->{sshbetweennodes} =~ /^yes$/i )
|| ($zonehash->{$zonename}->{sshbetweennodes} eq "1"))) {
$ENV{'DSH_ENABLE_SSH'} = "YES";
} else {
delete $ENV{'DSH_ENABLE_SSH'}; # do not enable passwordless ssh
}
# point to the ssh keys to send for this zone
my $keydir = $zonehash->{$zonename}->{sshkeydir} ;
# check to see if the id_rsa and id_rsa.pub key is in the directory
my $key="$keydir/id_rsa";
my $key2="$keydir/id_rsa.pub";
# Check to see if empty
if (!(-e $key)) {
my $rsp = {};
$rsp->{error}->[0] =
"The $key file does not exist for $zonename. Need to use chzone to regenerate the keys.";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
return 1;
}
if (!(-e $key2)) {
my $rsp = {};
$rsp->{error}->[0] =
"The $key2 file does not exist for $zonename. Need to use chzone to regenerate the keys.";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
return 1;
}
# now put copy.sh in the zone directory from ~/.ssh
my $rootkeydir="$roothome/.ssh";
if ($rootkeydir ne $keydir) { # the zone keydir is not the same as ~/.ssh.
$cmd="cp $rootkeydir/copy.sh $keydir";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{error}->[0] =
"Could not copy copy.sh to the zone key dir";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
return 1;
}
}
# Also create $keydir/tmp and put root's id_rsa.pub (in authorized_keys) for the transfer
$cmd="mkdir -p $keydir/tmp";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{error}->[0] =
"Could not mkdir the zone $keydir/tmp";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
return 1;
}
# create authorized_keys file
if (xCAT::Utils->isMN()) { # if on Management Node
$cmd = " cp $roothome/.ssh/id_rsa.pub $keydir/tmp/authorized_keys";
} else { # SN
$cmd = " cp $roothome/.ssh/authorized_keys $keydir/tmp/authorized_keys";
}
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{
$rsp->{data}->[0] = "$cmd failed.\n";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
return (1);
}
else
{
chmod 0600, "$keydir/.ssh/tmp/authorized_keys";
}
# strip off .ssh
my ($newkeydir,$ssh) = (split(/\.ssh/, $keydir));
$ENV{'DSH_ZONE_SSHKEYS'} =$newkeydir ;
# send the keys to the nodes
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",
$zonenodelist,$expecttimeout);
if ($rc != 0)
{
$rsp = {};
$rsp->{data}->[0] = "remoteshellexp failed sending keys to $zonename.";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
}
} # end nodes in the zone
} # end for each zone
return (0);
}
#--------------------------------------------------------------------------------
=head3 cpSSHFiles
Builds authorized_keyfiles for root
@@ -1174,9 +945,7 @@ sub getAppStatus
my ($class, $nodes_ref, $application) = @_;
my @nodes = @$nodes_ref;
# FIXME: why autocommit matters for a read-only subroutine getNodesAttribs?
# but could not get the appstatus without the autocommit=0
my $nltab = xCAT::Table->new('nodelist', -autocommit => 0);
my $nltab = xCAT::Table->new('nodelist');
my $nodeappstat = $nltab->getNodesAttribs(\@nodes,['appstatus']);
my $ret_nodeappstat;
@@ -1729,10 +1498,19 @@ sub enablessh
my ($class, $node) = @_;
my $enablessh=1;
if( xCAT::Utils->isSN($node) ) {
if( %::GLOBAL_SN_HASH ) {
if ($::GLOBAL_SN_HASH{$node} == 1) {
$enablessh=1; # service nodes always enabled
}
} else {
if (xCAT::Utils->isSN($node))
{
$enablessh=1; # service nodes always enabled
}
else
{
# if not a service node we need to check, before enabling
my $values;
my @vals = xCAT::TableUtils->get_site_attribute("sshbetweennodes");
@@ -1776,93 +1554,12 @@ sub enablessh
$enablessh=1;
}
}
}
return $enablessh;
}
#-------------------------------------------------------------------------------
=head3 enableSSH
Description:
The function is same as enablessh() above. Before using this function,
the $sn_hash for noderange, and $groups_hash for site.sshbetweennodes should be
got. This is performance improvement.
Arguments:
$node -- node name
$sn_hash -- if the node is one sn, key is the node name, and value is 1.
if the node is not a sn, the key isn't in this hash
$groups_hash -- there are two keys:
1. Each group in the value of site.sshbetweennodes could be the key
2. Each node in the groups from the value of site.sshbetweennodes , if the
value isn't ALLGROUPS or NOGROUPS.
Returns:
1 = enable ssh
0 = do not enable ssh
Globals:
none
Error:
none
Example:
my $enable = xCAT::TableUtils->enableSSH($node);
Comments:
=cut
#-----------------------------------------------------------------------------
sub enableSSH
{
my ($class, $node, $sn_hash, $groups_hash) = @_;
my $enablessh=1;
if( defined($sn_hash) && defined($sn_hash->{node}) && $sn_hash->{$node} == 1 ) {
$enablessh=1; # service nodes always enabled
} else {
# if not a service node we need to check, before enabling
if (keys %$groups_hash) { # not empty
if ($groups_hash->{ALLGROUPS} == 1)
{
$enablessh=1;
}
else
{
if ($groups_hash->{NOGROUPS} == 1)
{
$enablessh=0;
}
else
{ # check to see if the node is a member of a group
my $ismember = 0;
$ismember = $groups_hash->{$node};
if ($ismember == 1)
{
$enablessh=1;
}
else
{
$enablessh=0;
}
}
}
}
else
{ # does not exist, set default
$enablessh=1;
}
}
return $enablessh;
}
#-----------------------------------------------------------------------------
@@ -1966,100 +1663,4 @@ sub getimagenames()
$nodetab->close;
return @imagenames;
}
#-----------------------------------------------------------------------------
=head3 updatenodegroups
Update groups attribute for the specified node
Arguments:
node
tabhd: the handler of 'nodelist' table,
groups: the groups attribute need to be merged.
Can be an array or string.
Globals:
none
Error:
Example:
xCAT::TableUtils->updatenodegroups($node, $tab, $groups);
=cut
#-----------------------------------------------------------------------------
sub updatenodegroups {
my ($class, $node, $tabhd, $groups) = @_;
if (!$groups) {
$groups = $tabhd;
$tabhd = xCAT::Table->new('nodelist');
unless ($tabhd) {
xCAT::MsgUtils->message("E", " Could not read the nodelist table\n");
return;
}
}
my ($ent) = $tabhd->getNodeAttribs($node, ['groups']);
my @list = ();
if (defined($ent) and $ent->{groups}) {
push @list, split(/,/,$ent->{groups});
}
if (ref($groups) eq 'ARRAY') {
push @list, @$groups;
} else {
push @list, split(/,/,$groups);
}
my %saw;
@saw{@list} = ();
@list = keys %saw;
$tabhd->setNodeAttribs($node, {groups=>join(",",@list)});
}
#-----------------------------------------------------------------------------
=head3 rmnodegroups
remove groups from the group attribute for the specified node
Arguments:
node
tabhd: the handler of 'nodelist' table,
groups: the groups that need to be removed.
Can be an array or string.
Globals:
none
Error:
Example:
xCAT::TableUtils->rmnodegroups($node, $tab, $groups);
=cut
#-----------------------------------------------------------------------------
sub rmnodegroups {
my ($class, $node, $tabhd, $groups) = @_;
my ($ent) = $tabhd->getNodeAttribs($node, ['groups']);
my @definedgroups;
my @removegroups;
my @newgroups;
if (defined($ent) and $ent->{groups}) {
push @definedgroups, split(/,/,$ent->{groups});
}
if (ref($groups) eq 'ARRAY') {
push @removegroups, @$groups;
} else {
push @removegroups, split(/,/,$groups);
}
# take out any groups that match the input list of groups to remove
foreach my $dgrp (@definedgroups){
if (grep(/^$dgrp$/, @removegroups)) { # is the group to be removed
next;
} else { # keep this group
push @newgroups,$dgrp;
}
}
my %saw;
@saw{@newgroups} = ();
@newgroups = keys %saw;
$tabhd->setNodeAttribs($node, {groups=>join(",",@newgroups)});
}
1;
+26 -69
View File
@@ -18,9 +18,8 @@ use xCAT::Utils;
my %usage = (
"rnetboot" =>
"Usage: rnetboot <noderange> [-s net|hd] [-F] [-f] [-V|--verbose] [-m table.colum==expectedstatus] [-m table.colum==expectedstatus...] [-r <retrycount>] [-t <timeout>]
rnetboot [-h|--help|-v|--version]
zVM specific:
rnetboot <noderange> [ipl= address]",
rnetboot <noderange> [ipl= address]
rnetboot [-h|--help|-v|--version]",
"rpower" =>
"Usage: rpower <noderange> [--nodeps] [on|onstandby|off|suspend|reset|stat|state|boot] [-V|--verbose] [-m table.colum==expectedstatus][-m table.colum==expectedstatus...] [-r <retrycount>] [-t <timeout>]
rpower [-h|--help|-v|--version]
@@ -28,24 +27,20 @@ my %usage = (
rpower <noderange> [boot] [ -c <path to iso> ]
PPC (with IVM or HMC) specific:
rpower <noderange> [--nodeps] [of] [-V|--verbose]
CEC (with HMC) specific:
rpower <noderange> [on|off|reset|boot|onstandby]
LPAR(with HMC) specific:
rpower <noderange> [on|off|reset|stat|state|boot|of|sms|softoff]
PPC (HMC) specific:
rpower <noderange> [onstandby] [-V|--verbose]
CEC(using Direct FSP Management) specific:
rpower <noderange> [on|onstandby|off|stat|state|resetsp]
rpower <noderange> [on|onstandby|off|stat|state|lowpower|resetsp]
Frame(using Direct FSP Management) specific:
rpower <noderange> [stat|state|rackstandby|exit_rackstandby|resetsp]
LPAR(using Direct FSP Management) specific:
rpower <noderange> [on|off|reset|stat|state|boot|of|sms]
Blade(using Direct FSP Management) specific:
rpower <noderange> [on|onstandby|off|cycle|state|sms]
rpower <noderange> [on|off|cycle|state]
Blade(using AMM) specific:
rpower <noderange> [cycle|softoff] [-V|--verbose]
zVM specific:
rpower noderange [on|off|reset|stat|softoff]
MIC specific:
rpower noderange [stat|state|on|off|reset|boot]
",
"rbeacon" =>
"Usage: rbeacon <noderange> [on|off|stat] [-V|--verbose]
@@ -63,9 +58,7 @@ my %usage = (
Blade specific:
rvitals noderange {temp|wattage|fanspeed|leds|summary|all}
BMC specific:
rvitals noderange {temp|voltage|wattage|fanspeed|power|leds|lcds|summary|all}
MIC specific:
rvitals noderange {thermal|all}",
rvitals noderange {temp|voltage|wattage|fanspeed|power|leds|lcds|summary|all}",
"reventlog" =>
"Usage: reventlog <noderange> [all [-s]|clear|<number of entries to retrieve> [-s]] [-V|--verbose]
reventlog [-h|--help|-v|--version]",
@@ -75,24 +68,22 @@ my %usage = (
rinv <noderange> [all|model|serial] [-V|--verbose]
rinv [-h|--help|-v|--version]
BMC specific:
rinv <noderange> [mprom|deviceid|uuid|guid|vpd [-t]|all [-t]]
rinv <noderange> [vpd|mprom|deviceid|uuid|guid]
MPA specific:
rinv <noderange> [firm|bios|diag|mprom|sprom|mparom|mac|mtm [-t]]
rinv <noderange> [firm|bios|diag|mprom|sprom|mparom|mac|mtm]
PPC specific(with HMC):
rinv <noderange> [all|bus|config|serial|model|firm [-t]]
rinv <noderange> [bus|config|serial|model|firm|all]
PPC specific(using Direct FSP Management):
rinv <noderange> [firm]
rinv <noderange> [deconfig [-x]]
Blade specific:
rinv <noderange> [all|serial|mac|bios|diag|mprom|mparom|firm|mtm [-t]]
rinv <noderange> [mtm|serial|mac|bios|diag|mprom|mparom|firm|all]
IBM Flex System Compute Node specific:
rinv <noderange> [firm]
VMware specific:
rinv <noderange>
zVM specific:
rinv noderange [all|config]
MIC specific:
rinv noderange [system|ver|board|core|gddr|all]",
rinv noderange [all|config]",
"rsetboot" =>
"Usage: rsetboot <noderange> [net|hd|cd|floppy|def|stat] [-V|--verbose]
rsetboot [-h|--help|-v|--version]",
@@ -134,7 +125,7 @@ my %usage = (
textid=<*>|
frame=<*>|
ntp=<[ntp],[ip],[frequency],[v3]>
FSP/CEC (using ASM Interface) Specific:
FSP/BPA Common:
rspconfig <noderange> [autopower|iocap|decfg|memdecfg|procdecfg|time|date|spdump|sysdump|network|hostname]
rspconfig <noderange> autopower=<enable|disable>|
iocap=<enable|disable>|
@@ -202,15 +193,10 @@ my %usage = (
"Usage:
Common:
mkvm [-h|--help|-v|--version]
For PPC(with HMC) specific:
For PPC(with HMC):
mkvm noderange -i id -l singlenode [-V|--verbose]
mkvm noderange -c destcec -p profile [-V|--verbose]
mkvm noderange --full [-V|--verbose]
PPC (using Direct FSP Management) specific:
mkvm noderange [--full]
mkvm noderange [vmcpus=min/req/max] [vmmemory=min/req/max]
[vmphyslots=drc_index1,drc_index2...] [vmothersetting=hugepage:N,bsr:N]
[vmnics=vlan1,vlan2] [vmstorage=<N|viosnode:slotid>] [--vios]
For KVM
mkvm noderange -m|--master mastername -s|--size disksize -f|--force
For zVM
@@ -224,8 +210,7 @@ my %usage = (
PPC (with HMC) specific:
lsvm <noderange> [-a|--all]
PPC (using Direct FSP Management) specific:
lsvm <noderange> [-l|--long] --p775
lsvm <noderange>
lsvm <noderange> [-l|--long]
zVM specific:
lsvm noderange
lsvm noderange --getnetworknames
@@ -240,15 +225,9 @@ my %usage = (
chvm <noderange> [-p profile][-V|--verbose]
chvm <noderange> <attr>=<val> [<attr>=<val>...]
PPC (using Direct FSP Management) specific:
chvm <noderange> --p775 [-p <profile>]
chvm <noderange> --p775 -i <id> [-m <memory_interleaving>] -r <partition_rule>
chvm <noderange> [-p <profile>]
chvm <noderange> [lparname=<*|name>]
chvm <noderange> [vmcpus=min/req/max] [vmmemory=min/req/max]
[vmothersetting=hugepage:N,bsr:N]
[add_physlots=drc_index1,drc_index2...]
[add_vmnics=vlan1,vlan2] [add_vmstorage=<N|viosnode:slotid>] [--vios]
chvm <noderange> [del_physlots=drc_index1,drc_index2...]
chvm <noderange> [del_vadapter=slotid]
chvm <noderange> -i <id> [-m <memory_interleaving>] -r <partition_rule>
VMware specific:
chvm <noderange> [-a size][-d disk][-p disk][--resize disk=size][--cpus count][--mem memory]
zVM specific:
@@ -279,13 +258,11 @@ my %usage = (
"rmvm" =>
"Usage: rmvm <noderange> [--service][-V|--verbose]
rmvm [-h|--help|-v|--version],
rmvm [-p] [-f]
PPC (using Direct FSP Management) specific:
rmvm <noderange>",
rmvm [-p] [-f]",
"lsslp" =>
"Usage: lsslp [-h|--help|-v|--version]
lsslp [<noderange>][-V|--verbose][-i ip[,ip..]][-w][-r|-x|-z][-n][-I][-s FRAME|CEC|MM|IVM|RSA|HMC|CMM|IMM2|FSP]
[-u] [--range IPranges][-t tries][--vpdtable][-C counts][-T timeout]",
[-t tries][--vpdtable][-C counts][-T timeout][--flexdiscover]",
"rflash" =>
"Usage:
rflash [ -h|--help|-v|--version]
@@ -340,31 +317,17 @@ my %usage = (
renergy noderange [-V] { all | { [savingstatus] [dsavingstatus] [cappingstatus] [cappingmaxmin] [cappingvalue] [cappingsoftmin] [averageAC] [averageDC] [ambienttemp] [exhausttemp] [CPUspeed] [syssbpower] [sysIPLtime] [fsavingstatus] [ffoMin] [ffoVmin] [ffoTurbo] [ffoNorm] [ffovalue] } }
renergy noderange [-V] { {savingstatus}={on | off} | {dsavingstatus}={on-norm | on-maxp | off} | {fsavingstatus}={on | off} | {ffovalue}=MHZ | {cappingstatus}={on | off} | {cappingwatt}=watt | {cappingperc}=percentage }
BladeCenter specific :
For Management Modules:
renergy noderange [-V] { all | pd1all | pd2all | [pd1status] [pd2status] [pd1policy] [pd2policy] [pd1powermodule1] [pd1powermodule2] [pd2powermodule1] [pd2powermodule2] [pd1avaiablepower] [pd2avaiablepower] [pd1reservedpower] [pd2reservedpower] [pd1remainpower] [pd2remainpower] [pd1inusedpower] [pd2inusedpower] [availableDC] [averageAC] [thermaloutput] [ambienttemp] [mmtemp] }
For a blade server nodes:
renergy noderange [-V] { all | [averageDC] [capability] [cappingvalue] [CPUspeed] [maxCPUspeed] [savingstatus] [dsavingstatus] }
renergy noderange [-V] { savingstatus={on | off} | dsavingstatus={on-norm | on-maxp | off} }
Flex specific :
For Flex Management Modules:
renergy noderange [-V] { all | [powerstatus] [powerpolicy] [powermodule] [avaiablepower] [reservedpower] [remainpower] [inusedpower] [availableDC] [averageAC] [thermaloutput] [ambienttemp] [mmtemp] }
For Flex node (power and x86):
renergy noderange [-V] { all | [averageDC] [capability] [cappingvalue] [cappingmaxmin] [cappingmax] [cappingmin] [cappingGmin] [CPUspeed] [maxCPUspeed] [savingstatus] [dsavingstatus] }
renergy noderange [-V] { cappingstatus={on | off} | cappingwatt=watt | cappingperc=percentage | savingstatus={on | off} | dsavingstatus={on-norm | on-maxp | off} }
iDataPlex specific :
renergy noderange [-V] [ { cappingmaxmin | cappingmax | cappingmin } ] [cappingstatus] [cappingvalue] [relhistogram]
renergy noderange [-V] { cappingstatus={on | enable | off | disable} | {cappingwatt|cappingvalue}=watt }",
Blade specific :
renergy noderange [-V] { all | pd1all | pd2all | { [pd1status] [pd2status] [pd1policy] [pd2policy] [pd1powermodule1] [pd1powermodule2] [pd2powermodule1] [pd2powermodule2] [pd1avaiablepower] [pd2avaiablepower] [pd1reservedpower] [pd2reservedpower] [pd1remainpower] [pd2remainpower] [pd1inusedpower] [pd2inusedpower] [availableDC] [averageAC] [thermaloutput] [ambienttemp] [mmtemp] } }
renergy noderange [-V] { all | { [averageDC] [capability] [cappingvalue] [CPUspeed] [maxCPUspeed] [savingstatus] [dsavingstatus] } }
renergy noderange [-V] { {savingstatus}={on | off} | {dsavingstatus}={on-norm | on-maxp | off} }",
"updatenode" =>
"Usage:
updatenode [-h|--help|-v|--version | -g|--genmypost]
updatenode [-h|--help|-v|--version]
or
updatenode <noderange> [-V|--verbose] [-k|--security] [-s|--sn] [-t <timeout>]
updatenode <noderange> [-V|--verbose] [-k|--security] [-s|--sn]
or
updatenode <noderange> [-V|--verbose] [-F|--sync | -f|--snsync] [-l|--user[username]] [--fanout=[fanout value]] [-S|--sw] [-t <timeout>]
updatenode <noderange> [-V|--verbose] [-F|--sync | -f|--snsync] [-l|--user[username]] [--fanout=[fanout value]] [-S|--sw]
[-P|--scripts [script1,script2,...]] [-s|--sn]
[-A|--updateallsw] [-c|--cmdlineonly] [-d alt_source_dir]
[attr=val [attr=val...]]
@@ -385,9 +348,6 @@ Options:
[-f|--snsync] Performs File Syncing to the service nodes that service
the nodes in the noderange.
[-g|--genmypost] Will generate a new mypostscript file for the
the nodes in the noderange, if site precreatemypostscripts is 1 or YES.
[-l|--user] User name to run the updatenode command. It overrides the
current user which is the default.
@@ -401,9 +361,6 @@ Options:
[-s|--sn] Set the server information stored on the nodes.
[-t|--timeout] Time out in seconds to allow the command to run. Default is no timeout,
except for updatenode -k which has a 10 second default timeout.
[-A|--updateallsw] Install or update all software contained in the source
directory. (AIX only)
Executable → Regular
+31 -1157
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -26,7 +26,7 @@ sub grab_table_data{ #grab table data relevent to VM guest nodes
if ($vpdtab) {
$cfghash->{vpd} = $vpdtab->getNodesAttribs($noderange,['uuid']);
}
$cfghash->{vm} = $vmtab->getNodesAttribs($noderange,['node','host','migrationdest','cfgstore','storage','storagecache','storageformat','vidmodel','vidproto','vidpassword','storagemodel','memory','cpus','nics','nicmodel','bootorder','virtflags','datacenter','guestostype','othersettings','master']);
$cfghash->{vm} = $vmtab->getNodesAttribs($noderange,['node','host','migrationdest','cfgstore','storage','vidmodel','vidproto','vidpassword','storagemodel','memory','cpus','nics','nicmodel','bootorder','virtflags','datacenter','guestostype','othersettings','master']);
my $mactab = xCAT::Table->new("mac",-create=>1);
my $nrtab= xCAT::Table->new("noderes",-create=>1);
$cfghash->{mac} = $mactab->getAllNodeAttribs(['mac'],1);
-452
View File
@@ -1,452 +0,0 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT::Zone;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
# if AIX - make sure we include perl 5.8.2 in INC path.
# Needed to find perl dependencies shipped in deps tarball.
if ($^O =~ /^aix/i) {
unshift(@INC, qw(/usr/opt/perl5/lib/5.8.2/aix-thread-multi /usr/opt/perl5/lib/5.8.2 /usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi /usr/opt/perl5/lib/site_perl/5.8.2));
}
use lib "$::XCATROOT/lib/perl";
# do not put a use or require for xCAT::Table here. Add to each new routine
# needing it to avoid reprocessing of user tables ( ExtTab.pm) for each command call
use POSIX qw(ceil);
use File::Path;
use Socket;
use strict;
use Symbol;
use warnings "all";
#--------------------------------------------------------------------------------
=head1 xCAT::Zone
=head2 Package Description
This program module file, is a set of Zone utilities used by xCAT *zone commands.
=cut
#--------------------------------------------------------------------------------
=head3 genSSHRootKeys
Arguments:
callback for error messages
directory in which to put the ssh RSA keys
zonename
rsa private key to use for generation ( optional)
Returns:
Error: 1 - key generation failure.
Example:
$rc =xCAT::Zone->genSSHRootKeys($callback,$keydir,$rsakey);
=cut
#--------------------------------------------------------------------------------
sub genSSHRootKeys
{
my ($class, $callback, $keydir,$zonename,$rsakey) = @_;
#
# create /keydir if needed
#
if (!-d $keydir)
{
my $cmd = "/bin/mkdir -m 700 -p $keydir";
my $output = xCAT::Utils->runcmd("$cmd", 0);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{error}->[0] =
"Could not create $keydir directory";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
}
#need to gen a new rsa key for root for the zone
my $pubfile = "$keydir/id_rsa.pub";
my $pvtfile = "$keydir/id_rsa";
# if exists, remove the old files
if (-r $pubfile)
{
my $cmd = "/bin/rm $keydir/id_rsa*";
my $output = xCAT::Utils->runcmd("$cmd", 0);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{error}->[0] = "Could not remove id_rsa files from $keydir directory.";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
}
# gen new RSA keys
my $cmd;
my $output;
# if private key was input use it
if (defined ($rsakey)) {
$cmd="/usr/bin/ssh-keygen -y -f $rsakey > $pubfile";
$output = xCAT::Utils->runcmd("$cmd", 0);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{error}->[0] = "Could not generate $pubfile from $rsakey";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
# now copy the private key into the directory
$cmd="cp $rsakey $keydir";
$output = xCAT::Utils->runcmd("$cmd", 0);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{error}->[0] = "Could not run $cmd";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
} else { # generate all new keys
$cmd = "/usr/bin/ssh-keygen -t rsa -q -b 2048 -N '' -f $pvtfile";
$output = xCAT::Utils->runcmd("$cmd", 0);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{error}->[0] = "Could not generate $pubfile";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
}
#make sure permissions are correct
$cmd = "chmod 644 $pubfile;chown root $pubfile";
$output = xCAT::Utils->runcmd("$cmd", 0);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{error}->[0] = "Could set permission and owner on $pubfile";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
}
#--------------------------------------------------------------------------------
=head3 getdefaultzone
Arguments:
None
Returns:
Name of the current default zone from the zone table
Example:
my $defaultzone =xCAT::Zone->getdefaultzone($callback);
=cut
#--------------------------------------------------------------------------------
sub getdefaultzone
{
my ($class, $callback) = @_;
my $defaultzone;
# read all the zone table and find the defaultzone, if it exists
my $tab = xCAT::Table->new("zone");
if ($tab){
my @zones = $tab->getAllAttribs('zonename','defaultzone');
foreach my $zone (@zones) {
# Look for the defaultzone=yes/1 entry
if ((defined($zone->{defaultzone})) &&
(($zone->{defaultzone} =~ /^yes$/i )
|| ($zone->{defaultzone} eq "1"))) {
$defaultzone = $zone->{zonename};
}
$tab->close();
}
} else {
my $rsp = {};
$rsp->{error}->[0] =
"Error reading the zone table. ";
xCAT::MsgUtils->message("E", $rsp, $callback);
}
return $defaultzone;
}
#--------------------------------------------------------------------------------
=head3 iszonedefined
Arguments:
zonename
Returns:
1 if the zone is already in the zone table.
Example:
xCAT::Zone->iszonedefined($zonename);
=cut
#--------------------------------------------------------------------------------
sub iszonedefined
{
my ($class,$zonename) = @_;
# checks the zone table to see if input zonename already in the table
my $tab = xCAT::Table->new("zone");
$tab->close();
my $zonehash = $tab->getAttribs({zonename => $zonename},'sshkeydir');
if ( keys %$zonehash) {
return 1;
}else{
return 0;
}
}
#--------------------------------------------------------------------------------
=head3 getzonekeydir
Arguments:
zonename
Returns:
path to the root ssh keys for the zone /etc/xcat/sshkeys/<zonename>/.ssh
1 - zone not defined
Example:
xCAT::Zone->getzonekeydir($zonename);
=cut
#--------------------------------------------------------------------------------
sub getzonekeydir
{
my ($class,$zonename) = @_;
my $tab = xCAT::Table->new("zone");
$tab->close();
my $zonehash = $tab->getAttribs({zonename => $zonename},'sshkeydir');
if ( keys %$zonehash) {
my $zonesshkeydir=$zonehash->{sshkeydir};
return $zonesshkeydir;
}else{
return 1; # this is a bad error zone not defined
}
}
#--------------------------------------------------------------------------------
=head3 getmyzonename
Arguments:
$node -one nodename
Returns:
$zonename
Example:
my $zonename=xCAT::Zone->getmyzonename($node);
=cut
#--------------------------------------------------------------------------------
sub getmyzonename
{
my ($class,$node,$callback) = @_;
my @node;
push @node,$node;
my $zonename;
my $nodelisttab = xCAT::Table->new("nodelist");
my $nodehash = $nodelisttab->getNodesAttribs(\@node, ['zonename']);
$nodelisttab->close();
if ( defined ($nodehash->{$node}->[0]->{zonename})) { # it was defined in the nodelist table
$zonename=$nodehash->{$node}->[0]->{zonename};
} else { # get the default zone
$zonename =xCAT::Zone->getdefaultzone($callback);
}
return $zonename;
}
#--------------------------------------------------------------------------------
=head3 enableSSHbetweennodes
Arguments:
zonename
Returns:
1 if the sshbetweennodes attribute is yes/1 or undefined
0 if the sshbetweennodes attribute is no/0
Example:
xCAT::Zone->enableSSHbetweennodes($zonename);
=cut
#--------------------------------------------------------------------------------
sub enableSSHbetweennodes
{
my ($class,$node,$callback) = @_;
# finds the zone of the node
my $enablessh = 1; # default
my $zonename=xCAT::Zone->getmyzonename($node);
# reads the zone table
my $tab = xCAT::Table->new("zone");
$tab->close();
# read both keys, want to know zone is in the zone table. If sshkeydir is not there
# it is either missing or invalid anyway
my $zonehash = $tab->getAttribs({zonename => $zonename},'sshbetweennodes','sshkeydir');
if (! ( keys %$zonehash)) {
my $rsp = {};
$rsp->{error}->[0] =
"$node has a zonename: $zonename that is not define in the zone table. Remove the zonename from the node, or create the zone using mkzone. The generated mypostscript may not reflect the correct setting for ENABLESSHBETWEENNODES";
xCAT::MsgUtils->message("E", $rsp, $callback);
return $enablessh;
}
my $sshbetweennodes=$zonehash->{sshbetweennodes};
if (defined ($sshbetweennodes)) {
if (($sshbetweennodes =~ /^no$/i) || ($sshbetweennodes eq "0")) {
$enablessh = 0;
} else {
$enablessh = 1;
}
} else { # not defined default yes
$enablessh = 1 ; # default
}
return $enablessh;
}
#--------------------------------------------------------------------------------
=head3 usingzones
Arguments:
none
Returns:
1 if the zone table is not empty
0 if empty
Example:
xCAT::Zone->usingzones;
=cut
#--------------------------------------------------------------------------------
sub usingzones
{
my ($class) = @_;
# reads the zonetable
my $tab = xCAT::Table->new("zone");
my @zone = $tab->getAllAttribs('zonename');
$tab->close();
if (@zone) {
return 1;
}else{
return 0;
}
}
#--------------------------------------------------------------------------------
=head3 getzoneinfo
Arguments:
callback
An array of nodes
Returns:
Hash array by zonename point to the nodes in that zonename and sshkeydir
<zonename1> -> {nodelist} -> array of nodes in the zone
-> {sshkeydir} -> directory containing ssh RSA keys
-> {defaultzone} -> is it the default zone
Example:
my %zonehash =xCAT::Zone->getzoneinfo($callback,@nodearray);
Rules:
If the nodes nodelist.zonename attribute is a zonename, it is assigned to that zone
If the nodes nodelist.zonename attribute is undefined:
If there is a defaultzone in the zone table, the node is assigned to that zone
If there is no defaultzone in the zone table, the node is assigned to the ~.ssh keydir
$::GETZONEINFO_RC
0 = good return
1 = error occured
=cut
#--------------------------------------------------------------------------------
sub getzoneinfo
{
my ($class, $callback,$nodes) = @_;
$::GETZONEINFO_RC=0;
my $zonehash;
my $defaultzone;
# read all the zone table
my $zonetab = xCAT::Table->new("zone");
my @zones;
if ($zonetab){
@zones = $zonetab->getAllAttribs('zonename','sshkeydir','sshbetweennodes','defaultzone');
$zonetab->close();
if (@zones) {
foreach my $zone (@zones) {
my $zonename=$zone->{zonename};
$zonehash->{$zonename}->{sshkeydir}= $zone->{sshkeydir};
$zonehash->{$zonename}->{defaultzone}= $zone->{defaultzone};
$zonehash->{$zonename}->{sshbetweennodes}= $zone->{sshbetweennodes};
# find the defaultzone
if ((defined($zone->{defaultzone})) &&
(($zone->{defaultzone} =~ /^yes$/i )
|| ($zone->{defaultzone} eq "1"))) {
$defaultzone = $zone->{zonename};
}
}
}
} else {
my $rsp = {};
$rsp->{error}->[0] =
"Error reading the zone table. ";
xCAT::MsgUtils->message("E", $rsp, $callback);
$::GETZONEINFO_RC =1;
return;
}
my $nodelisttab = xCAT::Table->new("nodelist");
my $nodehash = $nodelisttab->getNodesAttribs(\@$nodes, ['zonename']);
# for each of the nodes, look up it's zone name and assign to the zonehash
# If the nodes nodelist.zonename attribute is a zonename, it is assigned to that zone
# If the nodes nodelist.zonename attribute is undefined:
# If there is a defaultzone in the zone table, the node is assigned to that zone
# If there is no defaultzone error out
foreach my $node (@$nodes) {
my $zonename;
$zonename=$nodehash->{$node}->[0]->{zonename};
if (defined($zonename)) { # zonename explicitly defined in nodelist.zonename
# check to see if defined in the zone table
unless ( xCAT::Zone->iszonedefined($zonename)) {
my $rsp = {};
$rsp->{error}->[0] =
"$node has a zonename: $zonename that is not define in the zone table. Remove the zonename from the node, or create the zone using mkzone.";
xCAT::MsgUtils->message("E", $rsp, $callback);
$::GETZONEINFO_RC =1;
return;
}
push @{$zonehash->{$zonename}->{nodes}},$node;
} else { # no explict zonename
if (defined ($defaultzone)) { # there is a default zone in the zone table, use it
push @{$zonehash->{$defaultzone}->{nodes}},$node;
} else { # if no default, this is an error
my $rsp = {};
$rsp->{error}->[0] =
"There is no default zone defined in the zone table. There must be exactly one default zone. ";
xCAT::MsgUtils->message("E", $rsp, $callback);
$::GETZONEINFO_RC =1;
return;
}
}
}
return $zonehash;
}
#--------------------------------------------------------------------------------
=head3 getnodesinzone
Arguments:
callback
zonename
Returns:
Array of nodes
Example:
my @nodes =xCAT::Zone->getnodesinzone($callback,$zonename);
=cut
#--------------------------------------------------------------------------------
sub getnodesinzone
{
my ($class, $callback,$zonename) = @_;
my @nodes;
my $nodelisttab = xCAT::Table->new("nodelist");
my @nodelist=$nodelisttab->getAllAttribs('node','zonename');
# build the array of nodes in this zone
foreach my $nodename (@nodelist) {
if ((defined($nodename->{'zonename'})) && ($nodename->{'zonename'} eq $zonename)) {
push @nodes,$nodename->{'node'};
}
}
return @nodes;
}
1;
Executable → Regular
+6 -26
View File
@@ -14,11 +14,9 @@ require Exporter;
%distnames = (
"1310229985.226287" => "centos6",
"1323560292.885204" => "centos6.2",
"1341569670.539525" => "centos6.3",#x86
"1362445555.957609" => "centos6.4",#x86_64
"1385726732.061157" => "centos6.5",#x86_64
"1404489053.504589" => "centos7.0",
"1323560292.885204" => "centos6.2",
"1341569670.539525" => "centos6.3",#x86
"1362445555.957609" => "centos6.4",#x86_64
"1176234647.982657" => "centos5",
"1156364963.862322" => "centos4.4",
"1178480581.024704" => "centos4.5",
@@ -29,8 +27,6 @@ require Exporter;
"1237641529.260981" => "centos5.3",
"1272326751.405938" => "centos5.5",
"1330913492.861127" => "centos5.8",#x86_64
"1357930415.252042" => "centos5.9",#x86_64
"1381776971.473332" => "centos5.10",#x86_64
"1195488871.805863" => "centos4.6",
"1195487524.127458" => "centos4.6",
"1301444731.448392" => "centos5.6",
@@ -52,8 +48,6 @@ require Exporter;
"1328205744.315196" => "rhels5.8", #x86_64
"1354216429.587870" => "rhels5.9", #x86_64
"1354214009.518521" => "rhels5.9", #ppc64
"1378846702.129847" => "rhels5.10", #x86_64
"1378845049.643372" => "rhels5.10", #ppc64
"1285193176.460470" => "rhels6", #x86_64
"1285192093.430930" => "rhels6", #ppc64
"1305068199.328169" => "rhels6.1", #x86_64
@@ -65,18 +59,10 @@ require Exporter;
"1339638991.532890" => "rhels6.3", #i386
"1359576752.435900" => "rhels6.4", #x86_64
"1359576196.686790" => "rhels6.4", #ppc64
"1384196515.415715" => "rhels6.5", #x86_64
"1384198011.520581" => "rhels6.5", #ppc64
"1411733344.627228" => "rhels6.6", #x86_64
"1411733344.616389" => "rhels6.6", #ppc64
"1285193176.593806" => "rhelhpc6", #x86_64
"1305067719.718814" => "rhelhpc6.1",#x86_64
"1321545261.599847" => "rhelhpc6.2",#x86_64
"1339640148.070971" => "rhelhpc6.3",#x86_64
"1359576195.413831" => "rhelhpc6.4",#x86_64, RHEL ComputeNode
"1384196516.465862" => "rhelhpc6.5",#x86_64, RHEL ComputeNode
"1411733344.599861" => "rhelhpc6.6",#x86_64, RHEL ComputeNode
"1399449226.140088" => "rhelhpc7.0",#x86_64, RHEL ComputeNode
"1194015916.783841" => "fedora8",
"1194015385.299901" => "fedora8",
"1210112435.291709" => "fedora9",
@@ -88,19 +74,13 @@ require Exporter;
"1273712675.937554" => "fedora13", #x86_64 DVD ISO
"1287685820.403779" => "fedora14", #x86_64 DVD ISO
"1305315870.828212" => "fedora15", #x86_64 DVD ISO
"1372355769.065812" => "fedora19", #x86_64 DVD ISO
"1372402928.663653" => "fedora19", #ppc64 DVD ISO
"1386856788.124593" => "fedora20", #x86_64 DVD ISO
"1194512200.047708" => "rhas4.6",
"1194512327.501046" => "rhas4.6",
"1241464993.830723" => "rhas4.8", #x86-64
"1273608367.051780" => "SL5.5", #x86_64 DVD ISO
"1299104542.844706" => "SL6", #x86_64 DVD ISO
"1390839789.062069" => "SL6.5", #x86_64 DVD ISO Install
"1394111947.452332" => "pkvm2.1", # ppc64, PowerKVM
"1413749127.352649" => "pkvm2.1.1", # ppc64, PowerKVM
"1273608367.051780" => "SL5.5", #x86_64 DVD ISO
"1299104542.844706" => "SL6", #x86_64 DVD ISO
);
my %numdiscs = (
"1156364963.862322" => 4,
-43
View File
@@ -1,43 +0,0 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT::data::ibmhwtypes;
require Exporter;
@EXPORT_OK=qw(parse_group mt2group);
use Data::Dumper;
my %groups2mtm = (
"x3250" => ["2583","4251","4252"],
"x3550" => ["7914","7944","7946"],
"x3650" => ["7915","7945"],
"dx360" => [],
"x220" => ["7906"],
"x240" => ["8737","7863"],
"x440" => ["7917"],
"p260" => ["7895"], #789522X, 789523X
"p460" => [], #789542X
"p470" => ["7954"],
);
%mt2group = ();
foreach my $group (keys %groups2mtm) {
foreach my $mtm (@{$groups2mtm{$group}}) {
$mt2group{$mtm} = $group;
}
}
sub parse_group {
my $mtm = shift;
if ($mtm =~ /xCAT::data/) {
$mtm = shift;
}
if ($mtm =~ /^(\w{4})/) {
$mt = $1;
if ($mt eq "7895" and $mtm =~ /789542X/i) {
return "p460";
}
return $mt2group{$mt};
}
return undef;
}
1;
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -208,7 +208,7 @@ sub getNic {
Arguments : User (root or non-root)
Node
Returns : Network names
Example : my $lans = xCAT::zvmCPUtils->getNetworkNames($user, $node);
Example : my $lans = xCAT::zvmCPUtils->getNetworkNames($node);
=cut
@@ -260,7 +260,7 @@ sub getNetworkNames {
Arguments : User (root or non-root)
Node
Returns : Array of networks names
Example : my @networks = xCAT::zvmCPUtils->getNetworkNamesArray($user, $node);
Example : my @networks = xCAT::zvmCPUtils->getNetworkNamesArray($node);
=cut
+42 -793
View File
@@ -12,8 +12,6 @@ package xCAT::zvmUtils;
use xCAT::MsgUtils;
use xCAT::Utils;
use xCAT::Table;
use xCAT::NetworkUtils;
use File::Basename;
use strict;
use warnings;
1;
@@ -290,7 +288,7 @@ sub printLn {
my $rsp;
my $type = "I";
if ($str =~ m/error/i) { # Set to print error if the string contains error
$type = "E";
$type = "E";
}
$rsp->{data}->[0] = "$str";
@@ -872,36 +870,6 @@ sub checkOutput {
#-------------------------------------------------------
=head3 checkOutputExtractReason
Description : Check the return of given output. If bad, extract the reason.
Arguments : Output string
Reason (passed as a reference)
Returns : 0 Good output
-1 Bad output
Example : my $rtn = xCAT::zvmUtils->checkOutput($callback, $out, \$reason);
=cut
#-------------------------------------------------------
sub checkOutputExtractReason {
my ( $class, $callback, $out, $reason ) = @_;
# Check output string
my @outLn = split("\n", $out);
foreach (@outLn) {
# If output contains 'ERROR: ', return -1 and pass back the reason.
if ($_ =~ /(.*?ERROR: )/) {
$$reason = substr($_, index($_, "ERROR: ") + length("ERROR: "));
return -1;
}
}
return 0;
}
#-------------------------------------------------------
=head3 getDeviceNode
Description : Get the device node for a given address
@@ -924,14 +892,14 @@ sub getDeviceNode {
# Determine device node
my $out = `ssh $user\@$node "$sudo cat /proc/dasd/devices" | grep ".$tgtAddr("`;
my @words = split(' ', $out);
my @words = split( ' ', $out );
my $tgtDevNode;
# /proc/dasd/devices look similar to this:
# 0.0.0100(ECKD) at ( 94: 0) is dasda : active at blocksize: 4096, 1802880 blocks, 7042 MB
# Look for the string 'is'
my $i = 0;
while ($tgtDevNode ne 'is') {
while ( $tgtDevNode ne 'is' ) {
$tgtDevNode = $words[$i];
$i++;
}
@@ -941,39 +909,6 @@ sub getDeviceNode {
#-------------------------------------------------------
=head3 getDeviceNodeAddr
Description : Get the virtual device address for a given device node
Arguments : User (root or non-root)
Node
Device node
Returns : Virtual device address
Example : my $addr = xCAT::zvmUtils->getDeviceNodeAddr($user, $node, $deviceNode);
=cut
#-------------------------------------------------------
sub getDeviceNodeAddr {
my ( $class, $user, $node, $deviceNode ) = @_;
my $sudo = "sudo";
if ($user eq "root") {
$sudo = "";
}
# Find device node and determine virtual address
# /proc/dasd/devices look similar to this:
# 0.0.0100(ECKD) at ( 94: 0) is dasda : active at blocksize: 4096, 1802880 blocks, 7042 MB
my $addr = `ssh $user\@$node "$sudo cat /proc/dasd/devices" | grep -i "is $deviceNode"`;
$addr =~ s/ +/ /g;
$addr =~ s/^0.0.([0-9a-f]*).*/$1/;
chomp($addr);
return $addr;
}
#-------------------------------------------------------
=head3 isAddressUsed
Description : Check if a given address is used
@@ -1155,23 +1090,16 @@ sub createMacAddr {
return -1;
}
# Get USER Prefix
my $prefix = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo /sbin/vmcp q vmlan" | egrep -i "USER Prefix:"`;
$prefix =~ s/(.*?)USER Prefix:(.*)/$2/;
$prefix =~ s/^\s+//;
$prefix =~ s/\s+$//;
# Get MACADDR Prefix instead if USER Prefix is not defined
if (!$prefix) {
$prefix = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo /sbin/vmcp q vmlan" | egrep -i "MACADDR Prefix:"`;
$prefix =~ s/(.*?)MACADDR Prefix:(.*)/$2/;
$prefix =~ s/^\s+//;
$prefix =~ s/\s+$//;
if (!$prefix) {
return -1;
}
}
# Get HCP MAC address
# Get the first MAC address found
my $out = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo /sbin/vmcp q v nic" | grep "MAC:"`;
my @lines = split( "\n", $out );
my @vars = split( " ", $lines[0] );
# Extract MAC prefix
my $prefix = $vars[1];
$prefix = xCAT::zvmUtils->replaceStr( $prefix, "-", "" );
$prefix = substr( $prefix, 0, 6 );
# Generate MAC address of source node
my $mac = $prefix . $suffix;
@@ -1572,7 +1500,7 @@ sub getFreeAddress {
} else {
# When the node is down, use zHCP to get its user directory entry
# Get HCP
my @propNames = ('hcp', 'userid');
my @propNames = ( 'hcp', 'userid' );
my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $node, @propNames );
my $hcp = $propVals->{'hcp'};
@@ -1590,9 +1518,9 @@ sub getFreeAddress {
}
# Get all defined device address
$allUsedAddr = `cat $userDirEntry | awk '$1 ~/^($deviceTypesUserDir)/ {print $2}' | sort`;
$allUsedAddr = `cat $allUsedAddr | awk '$1 ~/^($deviceTypesUserDir)/ {print $2}' | sort`;
# Get all linked device address
$allUsedAddr .= `cat $userDirEntry | awk '$1 ~/^(LINK)/ {print $4}' | sort`;
$allUsedAddr .= `cat $allUsedAddr | awk '$1 ~/^(LINK)/ {print $4}' | sort`;
}
# Loop to get the lowest free address
@@ -1642,7 +1570,7 @@ sub getUsedCpuTime {
$time =~ s/^\s+//;
$time =~ s/\s+$//;
if (!$time) {
$time = 0;
$time = 0;
}
# Not found, return 0
@@ -2136,7 +2064,7 @@ sub smapi4xcat {
my $out = `ssh $user\@$hcp "$sudo $dir/smcli Query_API_Functional_Level -T $hcpUserId"`;
$out = xCAT::zvmUtils->trimStr($out);
if ( !($out =~ m/V6.2/i || $out =~ m/V6.1/i || $out =~ m/V5.4/i) ) {
return 1;
return 1;
}
# Check if SMAPI EXEC exists
@@ -2237,20 +2165,20 @@ sub querySSI {
#-------------------------------------------------------
sub rExecute {
my ( $class, $user, $node, $cmd ) = @_;
my $out;
my $sudo = "sudo";
my ( $class, $user, $node, $cmd ) = @_;
my $out;
my $sudo = "sudo";
if ($user eq "root") {
# Just execute the command if root
# Just execute the command if root
$out = `ssh $user\@$node "$cmd"`;
return $out;
}
# Encapsulate command in single quotes
$cmd = "'" . $cmd . "'";
$out = `ssh $user\@$node "$sudo sh -c $cmd"`;
return $out;
# Encapsulate command in single quotes
$cmd = "'" . $cmd . "'";
$out = `ssh $user\@$node "$sudo sh -c $cmd"`;
return $out;
}
#-------------------------------------------------------
@@ -2267,8 +2195,8 @@ sub rExecute {
#-------------------------------------------------------
sub getUsedFcpDevices {
my ( $class, $user, $hcp ) = @_;
my ( $class, $user, $hcp ) = @_;
# Directory where zFCP pools are
my $pool = "/var/opt/zhcp/zfcp";
@@ -2276,15 +2204,15 @@ sub getUsedFcpDevices {
if ($user eq "root") {
$sudo = "";
}
# Grep the pools for used or allocated zFCP devices
my %usedDevices;
my @args;
my @devices = split("\n", `ssh $user\@$hcp "$sudo cat $pool/*.conf" | egrep -i "used|allocated"`);
foreach (@devices) {
@args = split(",", $_);
# Sample pool configuration file:
# Grep the pools for used or allocated zFCP devices
my %usedDevices;
my @args;
my @devices = split("\n", `ssh $user\@$hcp "$sudo cat $pool/*.conf" | egrep -i "used|allocated"`);
foreach (@devices) {
@args = split(",", $_);
# Sample pool configuration file:
# #status,wwpn,lun,size,range,owner,channel,tag
# used,1000000000000000,2000000000000110,8g,3B00-3B3F,ihost1,1a23,$root_device$
# free,1000000000000000,2000000000000111,,3B00-3B3F,,,
@@ -2293,688 +2221,9 @@ sub getUsedFcpDevices {
# Push used or allocated devices into hash
if ($args[6]) {
$usedDevices{uc($args[6])} = 1;
$usedDevices{uc($args[6])} = 1;
}
}
return %usedDevices;
}
#-------------------------------------------------------
=head3 establishMount
Description : Establish an NFS mount point on a zHCP system.
Arguments : Sudoer user name
Sudo keyword
zHCP hostname
Local directory to remotely mount
Mount access ('ro' for read only, 'rw' for read write)
Directory as known to zHCP (out)
Returns : 0 - Mounted, or zHCP and MN are on the same system
1 - Mount failed
Example : establishMount( $callback, $::SUDOER, $::SUDO, $hcp, "$installRoot/$provMethod", "ro", \$remoteDeployDir );
=cut
#-------------------------------------------------------
sub establishMount {
# Get inputs
my ($class, $callback, $sudoer, $sudo, $hcp, $localDir, $access, $mountedPt) = @_;
my $out;
# If the target system is not on this system then establish the NFS mount point.
my $hcpIP = xCAT::NetworkUtils->getipaddr( $hcp );
if (! defined $hcpIP) {
xCAT::zvmUtils->printLn( $callback, "(Error) Unable to obtain the IP address of the hcp node" );
return 1;
}
my $masterIp = xCAT::TableUtils->get_site_Master();
if (! defined $masterIp) {
xCAT::zvmUtils->printLn( $callback, "$hcp: (Error) Unable to obtain the management node IP address from the site table" );
return 1;
}
if ($masterIp eq $hcpIP) {
# xCAT MN and zHCP are on the same box and will use the same directory without the need for an NFS mount.
$$mountedPt = $localDir;
} else {
# Determine the hostname for this management node
my $masterHostname = Sys::Hostname::hostname();
if (! defined $masterHostname) {
# For some reason, the xCAT MN's hostname is not known. We pass along the IP address instead.
$masterHostname = $masterIp;
}
xCAT::zvmUtils->printSyslog( "establishMount() Preparing the NFS mount point on zHCP ($hcpIP) to xCAT MN $masterHostname($masterIp) for $localDir" );
# Prepare the staging mount point on zHCP, if they need to be established
$$mountedPt = "/mnt/$masterHostname$localDir";
my $rc = `ssh $sudoer\@$hcp "$sudo mkdir -p $$mountedPt && mount -t nfs -o $access $masterIp:$localDir $$mountedPt; echo \\\$?"`;
# Return code = 0 (mount succeeded) or 32 (mount already exists)
if ($rc != '0' && $rc != '32') {
xCAT::zvmUtils->printLn( $callback, "$hcp: (Error) Unable to establish zHCP mount point: $$mountedPt" );
return 1;
}
}
return 0;
}
#-------------------------------------------------------
=head3 getFreeRepoSpace
Description : Get the free space of image repository under /install
Arguments : Node
Returns : The available space for /install
Example : my $free = getFreeRepoSpace($callback, $node);
=cut
#-------------------------------------------------------
sub getFreeRepoSpace {
# Get inputs
my ($class, $user, $node) = @_;
my $sudo = "sudo";
if ($user eq "root") {
$sudo = "";
}
# Check if node is the management node
my @entries = xCAT::TableUtils->get_site_attribute("master");
my $master = xCAT::zvmUtils->trimStr($entries[0]);
my $ip = xCAT::NetworkUtils->getipaddr($node);
$ip = xCAT::zvmUtils->trimStr($ip);
my $mn = 0;
if ($master eq $ip) {
# If the master IP and node IP match, then it is the management node
my $out = `$sudo /bin/df -h /install | sed 1d`;
# causing problems on other platforms $out =~ s/\h+/ /g;$out =~ s/\h+/ /g;
my @results = split(' ', $out);
return ($results[3]);
}
return;
}
#-------------------------------------------------------
=head3 findAndUpdatezFcpPool
Description : Find and update a SCSI/FCP device in a given storage pool.
xCAT will find and update the SCSI/FCP device in all known pools based on the unique WWPN/LUN combo.
Arguments : Message header
User (root or non-root)
zHCP
Storage pool
Criteria hash including:
- Status (free, reserved, or used)
- zFCP channel
- WWPN
- LUN
- Size requested
- Owner
- Tag
Returns : Results hash including:
- Return code (0 = Success, -1 = Failure)
- zFCP device (if one is requested)
- WWPN
- LUN
Example : my $resultsRef = xCAT::zvmUtils->findAndUpdatezFcpPool($callback, $header, $user, $hcp, $pool, $criteriaRef);
=cut
#-------------------------------------------------------
sub findAndUpdatezFcpPool {
# Get inputs
my ($class, $callback, $header, $user, $hcp, $pool, $criteriaRef) = @_;
# Determine if sudo is used
my $sudo = "sudo";
if ($user eq "root") {
$sudo = "";
}
# Directory where executables are on zHCP
my $dir = "/opt/zhcp/bin";
# Directory where FCP disk pools are on zHCP
my $zfcpDir = "/var/opt/zhcp/zfcp";
my %results = ('rc' => -1); # Default to error
# Extract criteria
my %criteria = %$criteriaRef;
my $status = defined($criteria{status}) ? $criteria{status} : "";
my $fcpDevice = defined($criteria{fcp}) ? $criteria{fcp} : "";
my $wwpn = defined($criteria{wwpn}) ? $criteria{wwpn} : "";
my $lun = defined($criteria{lun}) ? $criteria{lun} : "";
my $size = defined($criteria{size}) ? $criteria{size} : "";
my $owner = defined($criteria{owner}) ? $criteria{owner} : "";
my $tag = defined($criteria{tag}) ? $criteria{tag} : "";
# Check required arguments: pool, status
# If you do not know what to update, why update!
if (!$pool && !$status) {
return \%results;
}
# Check status
if ($status !~ m/^(free|used|reserved)$/i) {
xCAT::zvmUtils->printLn($callback, "$header: (Error) Status not recognized. Status can be free, used, or reserved.");
return \%results;
}
# Check FCP device syntax
if ($fcpDevice && ($fcpDevice !~ /^auto/i) && ($fcpDevice =~ /[^0-9a-f]/i)) {
xCAT::zvmUtils->printLn($callback, "$header: (Error) Invalid FCP channel address $fcpDevice.");
return \%results;
}
# Check WWPN and LUN syntax
if ( $wwpn && ($wwpn =~ /[^0-9a-f;"]/i) ) {
xCAT::zvmUtils->printLn( $callback, "$header: (Error) Invalid world wide portname $wwpn." );
return \%results;
} if ( $lun && ($lun =~ /[^0-9a-f]/i) ) {
xCAT::zvmUtils->printLn( $callback, "$header: (Error) Invalid logical unit number $lun." );
return \%results;
}
# Size can be M(egabytes) or G(igabytes). Convert size into MB.
my $originSize = $size;
if ($size) {
if ($size =~ m/G/i) {
# Convert to MegaBytes
$size =~ s/\D//g;
$size = int($size) * 1024
} elsif ($size =~ m/M/i || !$size) {
# Do nothing
} else {
xCAT::zvmUtils->printLn( $callback, "$header: (Error) Size not recognized. Size can be M(egabytes) or G(igabytes)." );
return \%results;
}
}
# Check if WWPN and LUN are given
# WWPN can be given as a semi-colon separated list (multipathing)
my $useWwpnLun = 0;
if ($wwpn && $lun) {
xCAT::zvmUtils->printLn($callback, "$header: Using given WWPN and LUN");
$useWwpnLun = 1;
# Make sure WWPN and LUN do not have 0x prefix
$wwpn = xCAT::zvmUtils->replaceStr($wwpn, "0x", "");
$lun = xCAT::zvmUtils->replaceStr($lun, "0x", "");
}
# Find disk pool (create one if non-existent)
my $out;
if (!(`ssh $user\@$hcp "$sudo test -d $zfcpDir && echo Exists"`)) {
# Create pool directory
$out = `ssh $user\@$hcp "$sudo mkdir -p $zfcpDir"`;
}
# Find if disk pool exists
if (!(`ssh $user\@$hcp "$sudo test -e $zfcpDir/$pool.conf && echo Exists"`)) {
# Return if xCAT is expected to find a FCP device, but no disk pool exists.
xCAT::zvmUtils->printLn($callback, "$header: (Error) FCP storage pool does not exist");
return \%results;
}
# Find a free disk in the pool
# FCP devices are contained in /var/opt/zhcp/zfcp/<pool-name>.conf
my $range = "";
my $sizeFound = "*";
my @info;
if (!$useWwpnLun) {
# Find a suitable pair of WWPN and LUN in device pool based on requested size
# Sample pool configuration file:
# #status,wwpn,lun,size,range,owner,channel,tag
# used,1000000000000000,2000000000000110,8g,3B00-3B3F,ihost1,1a23,$root_device$
# free,1000000000000000,2000000000000111,,3B00-3B3F,,,
# free,1230000000000000;4560000000000000,2000000000000112,,3B00-3B3F,,,
my @devices = split("\n", `ssh $user\@$hcp "$sudo cat $zfcpDir/$pool.conf" | egrep -i ^free`);
$sizeFound = 0;
foreach (@devices) {
@info = split(',', $_);
# Check if the size is sufficient. Convert size into MB.
if ($info[3] =~ m/G/i) {
# Convert to MegaBytes
$info[3] =~ s/\D//g;
$info[3] = int($info[3]) * 1024
} elsif ($info[3] =~ m/M/i) {
# Do nothing
$info[3] =~ s/\D//g;
} else {
next;
}
# Find optimal disk based on requested size
if ($sizeFound && $info[3] >= $size && $info[3] < $sizeFound) {
$sizeFound = $info[3];
$wwpn = $info[1];
$lun = $info[2];
$range = $info[4];
} elsif (!$sizeFound && $info[3] >= $size) {
$sizeFound = $info[3];
$wwpn = $info[1];
$lun = $info[2];
$range = $info[4];
}
}
# Do not continue if no devices can be found
if (!$wwpn && !$lun) {
xCAT::zvmUtils->printLn($callback, "$header: (Error) A suitable device of $size" . "M or larger could not be found");
return \%results;
}
} else {
# Find given WWPN and LUN. Do not continue if device is used
my $select = `ssh $user\@$hcp "$sudo cat $zfcpDir/$pool.conf" | grep -i "$wwpn,$lun"`;
chomp($select);
@info = split(',', $select);
if ($size) {
if ($info[3] =~ m/G/i) {
# Convert to MegaBytes
$info[3] =~ s/\D//g;
$info[3] = int($info[3]) * 1024
} elsif ($info[3] =~ m/M/i) {
# Do nothing
$info[3] =~ s/\D//g;
} else {
next;
}
# Do not continue if specified device does not have enough capacity
if ($info[3] < $size) {
xCAT::zvmUtils->printLn($callback, "$header: (Error) FCP device $wwpn/$lun is not large enough");
return \%results;
}
}
# Find range of the specified disk
$range = $info[4];
}
# If there are multiple paths, take the 1st one
# Handle multi-pathing in postscript because autoyast/kickstart does not support it.
my $origWwpn = $wwpn;
if ($wwpn =~ m/;/i) {
@info = split(';', $wwpn);
$wwpn = xCAT::zvmUtils->trimStr($info[0]);
}
xCAT::zvmUtils->printLn($callback, "$header: Found FCP device 0x$wwpn/0x$lun");
# Find a free FCP device based on the given range
if ($fcpDevice =~ m/^auto/i) {
my @ranges;
my $min;
my $max;
my $found = 0;
if ($range =~ m/;/i) {
@ranges = split(';', $range);
} else {
push(@ranges, $range);
}
if (!$found) {
# If the node has an eligible FCP device, use it
my @deviceList = xCAT::zvmUtils->getDedicates($callback, $user, $owner);
foreach (@deviceList) {
# Check if this devide is eligible (among the range specified for disk $lun)
@info = split(' ', $_);
my $candidate = $info[2];
foreach (@ranges) {
($min, $max) = split('-', $_);
if (hex($candidate) >= hex($min) && hex($candidate) <= hex($max)) {
$found = 1;
$fcpDevice = uc($candidate);
last;
}
}
if ($found) {
xCAT::zvmUtils->printLn($callback, "$header: Found eligible FCP channel $fcpDevice");
last;
}
}
}
if (!$found) {
# If the node has no eligible FCP device, find a free one for it.
my %usedDevices = xCAT::zvmUtils->getUsedFcpDevices($user, $hcp);
my $hcpUserId = xCAT::zvmCPUtils->getUserId($user, $hcp);
$hcpUserId =~ tr/a-z/A-Z/;
# Find a free FCP channel
$out = `ssh $user\@$hcp "$sudo $dir/smcli System_WWPN_Query -T $hcpUserId" | egrep -i "FCP device number|Status"`;
my @devices = split( "\n", $out );
for (my $i = 0; $i < @devices; $i++) {
# Extract the device number and status
$fcpDevice = $devices[$i];
$fcpDevice =~ s/^FCP device number:(.*)/$1/;
$fcpDevice =~ s/^\s+//;
$fcpDevice =~ s/\s+$//;
$i++;
my $fcpStatus = $devices[$i];
$fcpStatus =~ s/^Status:(.*)/$1/;
$fcpStatus =~ s/^\s+//;
$fcpStatus =~ s/\s+$//;
# Only look at free FCP devices
if ($fcpStatus =~ m/free/i) {
# If the device number is within the specified range, exit out of loop
# Range: 3B00-3C00;4B00-4C00;5E12-5E12
foreach (@ranges) {
($min, $max) = split('-', $_);
if (hex($fcpDevice) >= hex($min) && hex($fcpDevice) <= hex($max)) {
$fcpDevice = uc($fcpDevice);
# Used found FCP channel if not in use or allocated
if (!$usedDevices{$fcpDevice}) {
$found = 1;
last;
}
}
}
}
# Break out of loop if FCP channel is found
if ($found) {
xCAT::zvmUtils->printLn($callback, "$header: Found FCP channel within acceptable range $fcpDevice");
last;
}
}
}
# Do not continue if no FCP channel is found
if (!$found) {
xCAT::zvmUtils->printLn($callback, "$header: (Error) A suitable FCP channel could not be found");
return \%results;
}
}
# If there are multiple devices (multipathing), take the 1st one
if ($fcpDevice) {
if ($fcpDevice =~ m/;/i) {
@info = split(';', $fcpDevice);
$fcpDevice = xCAT::zvmUtils->trimStr($info[0]);
}
# Make sure channel has a length of 4
while (length($fcpDevice) < 4) {
$fcpDevice = "0" . $fcpDevice;
}
}
# Mark WWPN and LUN as used, free, or reserved and set the owner/channel appropriately
# This config file keeps track of the owner of each device, which is useful in nodeset
$size = $size . "M";
my $select = `ssh $user\@$hcp "$sudo cat $zfcpDir/$pool.conf" | grep -i "$lun" | grep -i "$wwpn"`;
chomp($select);
if ($select) {
@info = split(',', $select);
if (!$info[3]) {
$info[3] = $size;
}
# Do not update if WWPN/LUN pair is specified but the pair does not exist
if (!($info[1] =~ m/$wwpn/i)) {
xCAT::zvmUtils->printLn($callback, "$header: (Error) FCP device $wwpn/$lun does not exists");
return \%results;
}
# Entry order: status,wwpn,lun,size,range,owner,channel,tag
# The following are never updated: wwpn, lun, size, and range
my $update = "$status,$info[1],$info[2],$info[3],$info[4],$owner,$fcpDevice,$tag";
my $expression = "'s#" . $select . "#" .$update . "#i'";
$out = `ssh $user\@$hcp "$sudo sed --in-place -e $expression $zfcpDir/$pool.conf"`;
} else {
# Insert device entry into file
$out = `ssh $user\@$hcp "$sudo echo \"$status,$origWwpn,$lun,$size,,$owner,$fcpDevice,$tag\" >> $zfcpDir/$pool.conf"`;
}
# Generate results hash
%results = (
'rc' => 0,
'fcp' => $fcpDevice,
'wwpn' => $wwpn,
'lun' => $lun
);
return \%results;
}
#-------------------------------------------------------
=head3 findzFcpDevicePool
Description : Find the zFCP storage pool that contains the given zFCP device
Arguments : User (root or non-root)
zHCP
WWPN
LUN
Returns : Storage pool where zFCP device resides
Example : my $pool = xCAT::zvmUtils->findzFcpDevicePool($user, $hcp, $wwpn, $lun);
=cut
#-------------------------------------------------------
sub findzFcpDevicePool {
# Get inputs
my ( $class, $user, $hcp, $wwpn, $lun ) = @_;
my $sudo = "sudo";
if ($user eq "root") {
$sudo = "";
}
# Directory where FCP disk pools are on zHCP
my $zfcpDir = "/var/opt/zhcp/zfcp";
# Find the pool that contains the SCSI/FCP device
my @pools = split("\n", `ssh $user\@$hcp "$sudo grep -i -l \"$wwpn,$lun\" $zfcpDir/*.conf"`);
my $pool = "";
if (scalar(@pools)) {
$pool = basename($pools[0]);
$pool =~ s/\.[^.]+$//; # Do not use extension
}
return $pool;
}
#-------------------------------------------------------
=head3 findzFcpDeviceAttr
Description : Find the zFCP device attributes
Arguments : User (root or non-root)
zHCP
Storage pool
WWPN
LUN
Returns : Architecture of node
Example : my $deviceRef = xCAT::zvmUtils->findzFcpDeviceAttr($user, $hcp, $wwpn, $lun);
=cut
#-------------------------------------------------------
sub findzFcpDeviceAttr {
# Get inputs
my ( $class, $user, $hcp, $pool, $wwpn, $lun ) = @_;
my $sudo = "sudo";
if ($user eq "root") {
$sudo = "";
}
# Directory where FCP disk pools are on zHCP
my $zfcpDir = "/var/opt/zhcp/zfcp";
# Find the SCSI/FCP device
# Entry order: status,wwpn,lun,size,range,owner,channel,tag
my @info = split("\n", `ssh $user\@$hcp "$sudo grep \"$wwpn,$lun\" $zfcpDir/$pool.conf"`);
my $entry = $info[0];
chomp($entry);
# Do not continue if no device is found
my %attrs = ();
if (!$entry) {
return \%attrs;
}
@info = split(',', $entry);
%attrs = (
'status' => $info[0],
'wwpn' => $info[1],
'lun' => $info[2],
'size' => $info[3],
'range' => $info[4],
'owner' => $info[5],
'fcp' => $info[6],
'tag' => $info[7]
);
return \%attrs;
}
#-------------------------------------------------------
=head3 findUsablezHcpNetwork
Description : Find a useable NIC shared with the zHCP for a given user Id
Arguments : User (root or non-root)
zHCP
User Id to find a useable NIC on
DHCP is used or not (0 or 1)
Returns : NIC, device channel, and layer (2 or 3)
Example : my ($nic, $channel, $layer) = xCAT::zvmUtils->findUsablezHcpNetwork($user, $hcp, $userId, $dhcp);
=cut
#-------------------------------------------------------
sub findUsablezHcpNetwork {
# Get inputs
my ( $class, $user, $hcp, $userId, $dhcp ) = @_;
my $sudo = "sudo";
if ($user eq "root") {
$sudo = "";
}
my $nic = ''; # Usuable NIC on zHCP
my $channel = ''; # Device channel where NIC is attached
my $layer;
my $i;
my @words;
# Get the networks used by the zHCP
my @hcpNetworks = xCAT::zvmCPUtils->getNetworkNamesArray($user, $hcp);
# Search directory entry for network name
my $userEntry = `ssh $user\@$hcp "$sudo $::DIR/smcli Image_Query_DM -T $userId" | sed '\$d'`;
xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() smcli Image_Query_DM -T $userId");
xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() $userEntry");
my $out = `echo "$userEntry" | grep "NICDEF"`;
my @lines = split('\n', $out);
# Go through each line
for ($i = 0; $i < @lines; $i++) {
# Go through each network device attached to zHCP
foreach (@hcpNetworks) {
# If network device is found
if ($lines[$i] =~ m/ $_/i) {
# Get network layer
$layer = xCAT::zvmCPUtils->getNetworkLayer($user, $hcp, $_);
xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() NIC:$_ layer:$layer");
# If template using DHCP, layer must be 2
if ((!$dhcp && $layer != 2) || (!$dhcp && $layer == 2) || ($dhcp && $layer == 2)) {
# Save network name
$nic = $_;
# Get network virtual address
@words = split(' ', $lines[$i]);
# Get virtual address (channel)
# Convert subchannel to decimal
$channel = sprintf('%d', hex($words[1]));
xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() Candidate found NIC:$nic channel:$channel layer:$layer");
return ($nic, $channel, $layer);
} else {
# Go to next network available
$nic = '';
}
}
}
}
# If network device is not found
if (!$nic) {
# Check for user profile
my $profileName = `echo "$userEntry" | grep "INCLUDE"`;
if ($profileName) {
@words = split(' ', xCAT::zvmUtils->trimStr($profileName));
# Get user profile
my $userProfile = xCAT::zvmUtils->getUserProfile($user, $hcp, $words[1]);
xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() $userProfile");
# Get the NICDEF statement containing the HCP network
$out = `echo "$userProfile" | grep "NICDEF"`;
@lines = split('\n', $out);
# Go through each line
for ($i = 0; $i < @lines; $i++) {
# Go through each network device attached to zHCP
foreach (@hcpNetworks) {
# If network device is found
if ($lines[$i] =~ m/ $_/i) {
# Get network layer
$layer = xCAT::zvmCPUtils->getNetworkLayer($user, $hcp, $_);
xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() NIC:$_ layer:$layer");
# If template using DHCP, layer must be 2
if ((!$dhcp && $layer != 2) || (!$dhcp && $layer == 2) || ($dhcp && $layer == 2)) {
# Save network name
$nic = $_;
# Get network virtual address
@words = split(' ', $lines[$i]);
# Get virtual address (channel)
# Convert subchannel to decimal
$channel = sprintf('%d', hex($words[1]));
xCAT::zvmUtils->printSyslog("findUsablezHcpNetwork() Candidate found NIC:$nic channel:$channel layer:$layer");
return ($nic, $channel, $layer);
} else {
# Go to next network available
$nic = '';
}
}
} # End of foreach
} # End of for
} # End of if
}
return;
}
return %usedDevices;
}
+78 -269
View File
@@ -6,275 +6,84 @@
#include <stdlib.h>
#include <errno.h>
#include <netinet/in.h>
#include <signal.h>
#include <syslog.h>
// the chunk size for each alloc
int chunknum = 200;
int doreload = 0;
int verbose = 0;
char logmsg[50];
// the struct to store the winpe configuration for each node
struct nodecfg {
char node[50];
char data[150];
};
char *data = NULL; // the ptr to the array of all node config
int nodenum = 0;
// trigger the main program to reload configuration file
void reload(int sig) {
doreload = 1;
}
// the subroutine which is used to load configuration from
// /var/lib/xcat/proxydhcp.cfg to *data
void loadcfg () {
nodenum = 0;
free(data);
data = NULL;
doreload = 0;
char *dp = NULL;
FILE *fp;
fp = fopen("/var/lib/xcat/proxydhcp.cfg", "r");
if (fp) {
int num = chunknum;
int rtime = 1;
while (num == chunknum) {
// realloc the chunknum size of memory each to save memory usage
data = realloc(data, sizeof(struct nodecfg) * chunknum * rtime);
if (NULL == data) {
fprintf (stderr, "Cannot get enough memory.\n");
free (data);
return;
}
dp = data + sizeof(struct nodecfg) * chunknum * (rtime - 1);
memset(dp, 0, sizeof(struct nodecfg) * chunknum);
num = fread(dp, sizeof (struct nodecfg), chunknum, fp);
nodenum += num;
rtime++;
}
fclose(fp);
}
}
// get the path of winpe from configuration file which is stored in *data
char *getwinpepath(char *node) {
int i;
struct nodecfg *nc = (struct nodecfg *)data;
for (i=0; i<nodenum;i++) {
if (0 == strcmp(nc->node, node)) {
return nc->data;
}
nc++;
}
return NULL;
}
int main(int argc, char *argv[]) {
int i;
for(i = 0; i < argc; i++)
{
if (strcmp(argv[i], "-V") == 0) {
verbose = 1;
setlogmask(LOG_UPTO(LOG_DEBUG));
openlog("proxydhcp", LOG_NDELAY, LOG_LOCAL0);
}
}
// regist my pid to /var/run/xcat/proxydhcp.pid
int pid = getpid();
FILE *pidf = fopen ("/var/run/xcat/proxydhcp.pid", "w");
if (pidf) {
fprintf(pidf, "%d", pid);
fclose (pidf);
} else {
fprintf (stderr, "Cannot open /var/run/xcat/proxydhcp.pid\n");
return 1;
}
// load configuration at first start
loadcfg();
// regist signal SIGUSR1 for triggering reload configuration from outside
struct sigaction sigact;
sigact.sa_handler = &reload;
sigaction(SIGUSR1, &sigact, NULL);
int serverfd,port;
int getpktinfo = 1;
struct addrinfo hint, *res;
char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))];
char clientpacket[1024];
struct sockaddr_in clientaddr;
struct msghdr msg;
struct cmsghdr *cmsgptr;
struct iovec iov[1];
unsigned int myip, clientip;
char *txtptr;
iov[0].iov_base = clientpacket;
iov[0].iov_len = 1024;
memset(&msg,0,sizeof(msg));
memset(&clientaddr,0,sizeof(clientaddr));
msg.msg_name=&clientaddr;
msg.msg_namelen = sizeof(clientaddr);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_control=&cmsg;
msg.msg_controllen = sizeof(cmsg);
char defaultwinpe[20] = "Boot/bootmgfw.efi";
char bootpmagic[4] = {0x63,0x82,0x53,0x63};
int pktsize;
int doexit=0;
port = 4011;
memset(&hint,0,sizeof(hint));
hint.ai_family = PF_INET; /* Would've done UNSPEC, but it doesn't work right and this is heavily v4 specific anyway */
hint.ai_socktype = SOCK_DGRAM;
hint.ai_flags = AI_PASSIVE;
getaddrinfo(NULL,"4011",&hint,&res);
serverfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (!serverfd) { fprintf(stderr,"That's odd...\n"); }
setsockopt(serverfd,IPPROTO_IP,IP_PKTINFO,&getpktinfo,sizeof(getpktinfo));
if (bind(serverfd,res->ai_addr ,res->ai_addrlen) < 0) {
fprintf(stderr,"Unable to bind 4011");
exit(1);
}
while (!doexit) {
// use select to wait for the 4011 request packages coming
fd_set fds;
FD_ZERO(&fds);
FD_SET(serverfd, &fds);
struct timeval timeout;
timeout.tv_sec = 30;
timeout.tv_usec = 0;
int rc;
if ((rc = select(serverfd+1,&fds,0,0, &timeout)) <= 0) {
if (doreload) {
loadcfg();
fprintf(stderr, "load in select\n");
}
if (verbose) {syslog(LOG_DEBUG, "reload /var/lib/xcat/proxydhcp.cfg\n");}
continue;
}
if (doreload) {
loadcfg();
if (verbose) {syslog(LOG_DEBUG, "reload /var/lib/xcat/proxydhcp.cfg\n");}
}
pktsize = recvmsg(serverfd,&msg,0);
if (pktsize < 320) {
continue;
}
if (clientpacket[0] != 1 || memcmp(clientpacket+0xec,bootpmagic,4)) {
continue;
}
for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg,cmsgptr)) {
if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_PKTINFO) {
myip = ((struct in_pktinfo*)(CMSG_DATA(cmsgptr)))->ipi_addr.s_addr;
}
}
// get the ip of dhcp client
clientip = 0;
int i;
for (i = 0; i< 4; i++) {
clientip = clientip << 8;
clientip += (unsigned char)clientpacket[15-i];
}
// get the winpe path
struct hostent *host = gethostbyaddr(&clientip, sizeof(clientip), AF_INET);
char *winpepath = defaultwinpe;
if (host) {
if (host->h_name) {
// remove the domain part from hostname
char *place = strstr(host->h_name, ".");
if (place) {
*place = '\0';
}
winpepath = getwinpepath(host->h_name);
if (winpepath == NULL) {
winpepath = defaultwinpe;
}
if (verbose) {
sprintf(logmsg, "Received proxydhcp request from %s\n", host->h_name);
syslog(LOG_DEBUG, logmsg);
}
}
} else {
winpepath = defaultwinpe;
}
// get the Vendor class identifier
char *arch = NULL;
unsigned char *p = clientpacket + 0xf0;
while (*p != 0xff && p < (unsigned char *)clientpacket + pktsize) {
if (*p == 60) {
arch = p + 0x11;
break;
} else {
p += *(p+1) + 2;
}
}
char winboot[50]; // the bootload of winpe
memset(winboot, 0, 50);
if (0 == memcmp(arch, "00000", 5)) { // bios boot mode
strcpy(winboot, winpepath);
strcat(winboot, "Boot/pxeboot.0");
} else if (0 == memcmp(arch, "00007", 5)) { // uefi boot mode
strcpy(winboot, winpepath);
strcat(winboot, "Boot/bootmgfw.efi");
}
clientpacket[0] = 2; //change to a reply
myip = htonl(myip); //endian neutral change
clientpacket[0x14] = (myip>>24)&0xff; //maybe don't need to do this, maybe assigning the whole int would be better
clientpacket[0x15] = (myip>>16)&0xff;
clientpacket[0x16] = (myip>>8)&0xff;
clientpacket[0x17] = (myip)&0xff;
txtptr = clientpacket+0x6c;
strncpy(txtptr, winboot ,128); // keeping 128 in there just in case someone changes the string
//strncpy(txtptr,"winboot/new/Boot/bootmgfw.efi",128); // keeping 128 in there just in case someone changes the string
//strncpy(txtptr,"Boot/pxeboot.0",128); // keeping 128 in there just in case someone changes the string
clientpacket[0xf0]=0x35; //DHCP MSG type
clientpacket[0xf1]=0x1; // LEN of 1
clientpacket[0xf2]=0x5; //DHCP ACK
clientpacket[0xf3]=0x36; //DHCP server identifier
clientpacket[0xf4]=0x4; //DHCP server identifier length
clientpacket[0xf5] = (myip>>24)&0xff; //maybe don't need to do this, maybe assigning the whole int would be better
clientpacket[0xf6] = (myip>>16)&0xff;
clientpacket[0xf7] = (myip>>8)&0xff;
clientpacket[0xf8] = (myip)&0xff;
char winBCD[50];
strcpy(winBCD, winpepath);
strcat(winBCD, "Boot/BCD");
clientpacket[0xf9] = 0xfc; // dhcp 252 'proxy', but coopeted by bootmgfw, it's actually suggesting the boot config file
clientpacket[0xfa] = strlen(winBCD) + 1; //length of 9
txtptr = clientpacket+0xfb;
strncpy(txtptr, winBCD, strlen(winBCD));
clientpacket[0xfa + strlen(winBCD) + 1] = 0;
clientpacket[0xfa + strlen(winBCD) + 2] = 0xff;
sendto(serverfd,clientpacket,pktsize,0,(struct sockaddr*)&clientaddr,sizeof(clientaddr));
if (verbose) {
sprintf(logmsg, "Path of bootloader:%s. Path of BCD:%s\n", winboot, winBCD);
syslog(LOG_DEBUG, logmsg);
}
}
if (verbose) { closelog();}
int main() {
int serverfd,port;
int getpktinfo = 1;
struct addrinfo hint, *res;
char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))];
char clientpacket[1024];
struct sockaddr_in clientaddr;
struct msghdr msg;
struct cmsghdr *cmsgptr;
struct iovec iov[1];
unsigned int myip;
char *txtptr;
iov[0].iov_base = clientpacket;
iov[0].iov_len = 1024;
memset(&msg,0,sizeof(msg));
memset(&clientaddr,0,sizeof(clientaddr));
msg.msg_name=&clientaddr;
msg.msg_namelen = sizeof(clientaddr);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_control=&cmsg;
msg.msg_controllen = sizeof(cmsg);
char bootpmagic[4] = {0x63,0x82,0x53,0x63};
int pktsize;
int doexit=0;
port = 4011;
memset(&hint,0,sizeof(hint));
hint.ai_family = PF_INET; /* Would've done UNSPEC, but it doesn't work right and this is heavily v4 specific anyway */
hint.ai_socktype = SOCK_DGRAM;
hint.ai_flags = AI_PASSIVE;
getaddrinfo(NULL,"4011",&hint,&res);
serverfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (!serverfd) { fprintf(stderr,"That's odd...\n"); }
setsockopt(serverfd,IPPROTO_IP,IP_PKTINFO,&getpktinfo,sizeof(getpktinfo));
if (bind(serverfd,res->ai_addr ,res->ai_addrlen) < 0) {
fprintf(stderr,"Unable to bind 4011");
exit(1);
}
while (!doexit) {
pktsize = recvmsg(serverfd,&msg,0);
if (pktsize < 320) {
continue;
}
if (clientpacket[0] != 1 || memcmp(clientpacket+0xec,bootpmagic,4)) {
continue;
}
for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg,cmsgptr)) {
if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_PKTINFO) {
myip = ((struct in_pktinfo*)(CMSG_DATA(cmsgptr)))->ipi_addr.s_addr;
}
}
clientpacket[0] = 2; //change to a reply
myip = htonl(myip); //endian neutral change
clientpacket[0x14] = (myip>>24)&0xff; //maybe don't need to do this, maybe assigning the whole int would be better
clientpacket[0x15] = (myip>>16)&0xff;
clientpacket[0x16] = (myip>>8)&0xff;
clientpacket[0x17] = (myip)&0xff;
txtptr = clientpacket+0x6c;
strncpy(txtptr,"Boot/bootmgfw.efi",128); // keeping 128 in there just in case someone changes the string
clientpacket[0xf0]=0x35; //DHCP MSG type
clientpacket[0xf1]=0x1; // LEN of 1
clientpacket[0xf2]=0x5; //DHCP ACK
clientpacket[0xf3]=0x36; //DHCP server identifier
clientpacket[0xf4]=0x4; //DHCP server identifier length
clientpacket[0xf5] = (myip>>24)&0xff; //maybe don't need to do this, maybe assigning the whole int would be better
clientpacket[0xf6] = (myip>>16)&0xff;
clientpacket[0xf7] = (myip>>8)&0xff;
clientpacket[0xf8] = (myip)&0xff;
clientpacket[0xf9] = 0xfc; // dhcp 252 'proxy', but coopeted by bootmgfw, it's actually suggesting the boot config file
clientpacket[0xfa] = 9; //length of 9
txtptr = clientpacket+0xfb;
strncpy(txtptr,"Boot/BCD",8);
clientpacket[0x103]=0;
clientpacket[0x104]=0xff;
sendto(serverfd,clientpacket,pktsize,0,(struct sockaddr*)&clientaddr,sizeof(clientaddr));
}
}
-48
View File
@@ -1,48 +0,0 @@
/* IBM(c) 2013 EPL licens http://www.eclipse.org/legal/epl-v10.html
* Jarrod Johnson - jbjohnso@us.ibm.com
* This program periodically transmits a udp packet to designated xCAT server
* It waits for an 'ok' and then exits
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
int server;
struct addrinfo hints;
struct addrinfo *results,*cur;
struct timeval timeout;
int canread=0;
char buffer[128];
srand(time(NULL));
memset(&hints,0,sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
fd_set selectset;
getaddrinfo(argv[1],argv[2],&hints,&results);
server = socket(AF_UNSPEC,SOCK_DGRAM,17);
for (cur=results; cur != NULL; cur = cur->ai_next) {
server = socket(cur->ai_family,cur->ai_socktype,cur->ai_protocol);
if (server == -1) continue;
if (connect(server,cur->ai_addr,cur->ai_addrlen) != -1) break;
close(server);
}
FD_ZERO(&selectset);
FD_SET(server,&selectset);
while (1) {
timeout.tv_sec = rand() % 120+60;
timeout.tv_usec = rand() % 10000;
write(server,"resourcerequest: xcatd\n",strlen("resourcerequest: xcatd\n"));
canread = select(FD_SETSIZE,&selectset,NULL,NULL,&timeout);
if (canread) {
read(server,buffer,sizeof(buffer));
if (strncmp(buffer,"resourcerequest: ok",strlen("resourcerequest: ok"))==0) {
exit(0);
}
}
}
}
@@ -1,10 +0,0 @@
# AIX Bundle file for compiler runtime packages
I:xlC.aix61
I:xlC.rte
I:xlfrte
I:xlfrte.aix61
I:xlfrte.msg.en_US
I:xlsmp.aix61.rte
I:xlsmp.msg.en_US.rte
I:xlsmp.rte
@@ -14,7 +14,7 @@
# postscript (stateful install) or with the otherpkgs processing of
# genimage (stateless/statelite install). This script will install any
# gpfs update rpms that exist on the xCAT management node in the
# /install/post/otherpkgs/gpfs_updates directory.
# /install/post/gpfs_updates directory.
# This is necessary because the GPFS updates can ONLY be installed
# after the base rpms have been installed, and the update rpms cannot
# exist in any rpm repositories used by xCAT otherpkgs processing
@@ -41,8 +41,8 @@ if [ $OS != "AIX" ]; then
mkdir -p /tmp/gpfs_updates
rm -f -R /tmp/gpfs_updates/*
cd /tmp/gpfs_updates
# wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 10 -T 60 -nH --cut-dirs=3 ftp://$MASTER/$UPDATES_DIR/*.rpm 2> /tmp/wget.log
wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 10 -T 60 -nH --cut-dirs=4 --reject "index.html*" --no-parent http://$MASTER$INSTALL_DIR/$UPDATES_DIR/ 2> /tmp/wget.log
# wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 10 -T 60 -nH --cut-dirs=3 ftp://$SITEMASTER/$UPDATES_DIR/*.rpm 2> /tmp/wget.log
wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 10 -T 60 -nH --cut-dirs=4 --reject "index.html*" --no-parent http://$SITEMASTER$INSTALL_DIR/$UPDATES_DIR/ 2> /tmp/wget.log
if [ -n "`ls *.rpm 2> /dev/null`" ] ; then
rpm -Uvh *.rpm
fi
@@ -103,7 +103,7 @@ else # assume Linux
fi
if [ ! -e $gpfsprofile.sh ]; then
echo 'export PATH=$PATH:/usr/lpp/mmfs/bin' > $gpfsprofile.sh
echo 'setenv PATH ${PATH}:/usr/lpp/mmfs/bin' > $gpfsprofile.csh
echo 'setenv PATH $PATH:/usr/lpp/mmfs/bin' > $gpfsprofile.csh
# Turn off LANG support since we did not install other msg catalogs
echo 'export LC_CTYPE=POSIX' >> $gpfsprofile.sh
echo 'setenv LC_CTYPE POSIX' >> $gpfsprofile.csh
@@ -62,8 +62,7 @@ else
file=$1
fi
#ifconfig -a | grep 'inet ' | awk ' { print $2 } ' | grep -v 127.0.0.1 |
ip -4 -oneline addr show 2>/dev/null |grep inet | sed -ne "s/.*inet //p"|awk -F ' ' '{print $1}'|awk -F '/' '{print $1}'|
ifconfig -a | grep 'inet ' | awk ' { print $2 } ' | grep -v 127.0.0.1 |
while read my_address ; do
##print "checking $my_address"
grep -q " ${my_address}$" $file
@@ -1,6 +0,0 @@
xcat-openstack-baremetal for Debian
-----------------------------------
<possible notes regarding this package - if none, delete this file>
-- root <root@unknown> Wed, 12 Mar 2014 01:47:54 -0700
@@ -1,9 +0,0 @@
xcat-openstack-baremetal for Debian
-----------------------------------
<this file describes information about the source package, see Debian policy
manual section 4.14. You WILL either need to modify or delete this file>
@@ -1,5 +0,0 @@
xcat-openstack-baremetal (2.8.4-1) unstable; urgency=low
* Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP>
-- root <root@unknown> Wed, 12 Mar 2014 01:47:54 -0700
-1
View File
@@ -1 +0,0 @@
8
-14
View File
@@ -1,14 +0,0 @@
Source: xcat-openstack-baremetal
Section: admin
Priority: extra
Maintainer: xCAT <xcat-user@lists.sourceforge.net>
Build-Depends: debhelper (>= 8.0.0)
Standards-Version: 3.9.4
Homepage: http://xcat.sourceforge.net/
#Vcs-Git: git://git.debian.org/collab-maint/xcat-openstack-baremetal.git
#Vcs-Browser: http://git.debian.org/?p=collab-maint/xcat-openstack-baremetal.git;a=summary
Package: xcat-openstack-baremetal
Architecture: all
Depends: xCAT-client
Description: Executables and data of the xCAT baremetal driver for OpenStack
-88
View File
@@ -1,88 +0,0 @@
Eclipse Public License - v 1.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
1. DEFINITIONS
"Contribution" means:
a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
b) in the case of each subsequent Contributor:
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
"Program" means the Contributions distributed in accordance with this Agreement.
"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
2. GRANT OF RIGHTS
a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
3. REQUIREMENTS
A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
a) it complies with the terms and conditions of this Agreement; and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy of the Program.
Contributors may not remove or alter any copyright notices contained within the Program.
Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
6. DISCLAIMER OF LIABILITY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. GENERAL
If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
-7
View File
@@ -1,7 +0,0 @@
opt/xcat/bin
opt/xcat/sbin
opt/xcat/lib/perl/xCAT_plugin
opt/xcat/lib/python/xcat/openstack/baremetal
opt/xcat/share/xcat/openstack/postscripts
opt/xcat/share/man/man1
opt/xcat/share/doc/man1
-6
View File
@@ -1,6 +0,0 @@
lib/* opt/xcat/lib/
share/xcat/openstack/postscripts/* opt/xcat/share/xcat/openstack/postscripts/
share/man/man1/* opt/xcat/share/man/man1/
share/doc/man1/* opt/xcat/share/doc/man1/
-43
View File
@@ -1,43 +0,0 @@
#!/bin/sh
# postinst script for xcat-openstack-baremetal
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
configure)
#copy the postscripts under /installl/postscripts directory on MN only
if [ -f "/etc/xCATMN" ]; then
cp /opt/xcat/share/xcat/openstack/postscripts/* /install/postscripts/
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0
-46
View File
@@ -1,46 +0,0 @@
#!/bin/sh
# prerm script for xcat-openstack-baremetal
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <prerm> `remove'
# * <old-prerm> `upgrade' <new-version>
# * <new-prerm> `failed-upgrade' <old-version>
# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
# * <deconfigured's-prerm> `deconfigure' `in-favour'
# <package-being-installed> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
remove|upgrade|deconfigure)
#remove postscripts under /installl/postscripts directory on MN only
if [ -f "/etc/xCATMN" ]; then
for fn in /opt/xcat/share/xcat/openstack/postscripts/*
do
bn=`basename $fn`
rm /install/postscripts/$bn
done
fi
;;
failed-upgrade)
;;
*)
echo "prerm called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0
-44
View File
@@ -1,44 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
build:
pwd
`pwd`/xpod2man
clean:
dh_testdir
dh_testroot
dh_clean -d
install:
pwd
dh_testdir
dh_testroot
dh_installdirs
dh_install -X".svn"
chmod 444 `pwd`/debian/xcat-openstack-baremetal/opt/xcat/share/man/man1/*
chmod 644 `pwd`/debian/xcat-openstack-baremetal/opt/xcat/share/doc/man1/*
dh_link
binary-indep: build install
pwd
export
dh_installman
dh_compress
dh_installdeb
dh_gencontrol
dh_md5sums
dh_builddeb
binary-arch:
pwd
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure
@@ -1 +0,0 @@
1.0
@@ -1,4 +0,0 @@
opt/xcat/bin/xcatclient opt/xcat/sbin/deploy_ops_bm_node
opt/xcat/bin/xcatclient opt/xcat/sbin/cleanup_ops_bm_node
opt/xcat/bin/xcatclient opt/xcat/bin/opsaddbmnode
opt/xcat/bin/xcatclientnnr opt/xcat/bin/opsaddimage
@@ -1 +0,0 @@
misc:Depends=
@@ -1,965 +0,0 @@
# IBM(c) 2013 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT_plugin::openstack;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use xCAT::Utils;
use xCAT::TableUtils;
use xCAT::SvrUtils;
use xCAT::NetworkUtils;
use xCAT::Table;
use Data::Dumper;
use File::Path;
use File::Copy;
use Getopt::Long;
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("pass_through");
sub handled_commands {
return {
opsaddbmnode => "openstack", #external command
opsaddimage => "openstack", #external command
deploy_ops_bm_node => "openstack", #internal command called from the baremetal driver
cleanup_ops_bm_node => "openstack", #internal command called from the baremetal driver
}
}
sub process_request {
my $request = shift;
my $callback = shift;
my $doreq = shift;
my $command = $request->{command}->[0];
if ($command eq "opsaddbmnode") {
return opsaddbmnode($request, $callback, $doreq);
} elsif ($command eq "opsaddimage") {
return opsaddimage($request, $callback, $doreq);
} elsif ($command eq "deploy_ops_bm_node") {
return deploy_ops_bm_node($request, $callback, $doreq);
} elsif ($command eq "cleanup_ops_bm_node") {
return cleanup_ops_bm_node($request, $callback, $doreq);
} else {
$callback->({error=>["Unsupported command: $command."],errorcode=>[1]});
return 1;
}
}
#-------------------------------------------------------------------------------
=head3 opsaddbmnode
This function takes the xCAT nodes and register them
as the OpenStack baremetal nodes
=cut
#-------------------------------------------------------------------------------
sub opsaddbmnode {
my $request = shift;
my $callback = shift;
my $doreq = shift;
@ARGV = @{$request->{arg}};
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("no_pass_through");
my $help;
my $version;
my $verbose;
my $host;
if(!GetOptions(
'h|help' => \$help,
'v|version' => \$version,
'V|verbose' => \$verbose,
's=s' => \$host,
))
{
&opsaddbmnode_usage($callback);
return 1;
}
# display the usage if -h or --help is specified
if ($help) {
&opsaddbmnode_usage($callback);
return 0;
}
# display the version statement if -v or --verison is specified
if ($version)
{
my $rsp={};
$rsp->{data}->[0]= xCAT::Utils->Version();
$callback->($rsp);
return 0;
}
if (!$request->{node}) {
$callback->({error=>["Please specify at least one node."],errorcode=>[1]});
return 1;
}
if (!$host) {
$callback->({error=>["Please specify the OpenStack compute host name with -s flag."],errorcode=>[1]});
return 1;
}
my $nodes = $request->{node};
#get node mgt
my $nodehmhash;
my $nodehmtab = xCAT::Table->new("nodehm");
if ($nodehmtab) {
$nodehmhash = $nodehmtab->getNodesAttribs($nodes,['power', 'mgt']);
}
#get bmc info for the nodes
my $ipmitab = xCAT::Table->new("ipmi", -create => 0);
my $tmp_ipmi;
if ($ipmitab) {
$tmp_ipmi = $ipmitab->getNodesAttribs($nodes, ['bmc','username', 'password'], prefetchcache=>1);
#print Dumper($tmp_ipmi);
} else {
$callback->({error=>["Cannot open the ipmi table."],errorcode=>[1]});
return 1;
}
#get mac for the nodes
my $mactab = xCAT::Table->new("mac", -create => 0);
my $tmp_mac;
if ($mactab) {
$tmp_mac = $mactab->getNodesAttribs($nodes, ['mac'], prefetchcache=>1);
#print Dumper($tmp_mac);
} else {
$callback->({error=>["Cannot open the mac table."],errorcode=>[1]});
return 1;
}
#get cpu, memory and disk info for the nodes
my $hwinvtab = xCAT::Table->new("hwinv", -create => 0);
my $tmp_hwinv;
if ($hwinvtab) {
$tmp_hwinv = $hwinvtab->getNodesAttribs($nodes, ['cpucount', 'memory', 'disksize'], prefetchcache=>1);
#print Dumper($tmp_hwinv);
} else {
$callback->({error=>["Cannot open the hwinv table."],errorcode=>[1]});
return 1;
}
#get default username and password for bmc
my $d_bmcuser;
my $d_bmcpasswd;
my $passtab = xCAT::Table->new('passwd');
if ($passtab) {
($tmp_passwd)=$passtab->getAttribs({'key'=>'ipmi'},'username','password');
if (defined($tmp_passwd)) {
$d_bmcuser = $tmp_passwd->{username};
$d_bmcpasswd = $tmp_passwd->{password};
}
}
#print "d_bmcuser=$d_bmcuser, d_bmcpasswd=$d_bmcpasswd \n";
foreach my $node (@$nodes) {
#collect the node infomation needed for each node, some info
my $mgt;
my $ref_nodehm = $nodehmhash->{$node}->[0];
if ($ref_nodehm) {
if ($ref_nodehm->{'power'}) {
$mgt = $ref_nodehm->{'power'};
} elsif ($ref_nodehm->{'mgt'}) {
$mgt = $ref_nodehm->{'mgt'};
}
}
my ($bmc, $bmc_user, $bmc_password, $mac, $cpu, $memory, $disk);
if (($mgt) && ($mgt eq 'ipmi')) {
my $ref_ipmi = $tmp_ipmi->{$node}->[0];
if ($ref_ipmi) {
if (exists($ref_ipmi->{bmc})) {
$bmc = $ref_ipmi->{bmc};
}
if (exists($ref_ipmi->{username})) {
$bmc_user = $ref_ipmi->{username};
if (exists($ref_ipmi->{password})) {
$bmc_password = $ref_ipmi->{password};
}
} else { #take the default if they cannot be found on ipmi table
if ($d_bmcuser) { $bmc_user = $d_bmcuser; }
if ($d_bmcpasswd) { $bmc_password = $d_bmcpasswd; }
}
}
} # else { # for hardware control point other than ipmi, just fake it in OpenStack.
#$bmc = "0.0.0.0";
#$bmc_user = "xCAT";
#$bmc_password = "xCAT";
#}
my $ref_mac = $tmp_mac->{$node}->[0];
if ($ref_mac) {
if (exists($ref_mac->{mac})) {
$mac = $ref_mac->{mac};
}
}
$ref_hwinv = $tmp_hwinv->{$node}->[0];
if ($ref_hwinv) {
if (exists($ref_hwinv->{cpucount})) {
$cpu = $ref_hwinv->{cpucount};
}
if (exists($ref_hwinv->{memory})) {
$memory = $ref_hwinv->{memory};
#TODO: what if the unit is not in MB? We need to convert it to MB
$memory =~ s/MB|mb//g;
}
if (exists($ref_hwinv->{disksize})) {
#The format of the the disk size is: sda:250GB,sdb:250GB or just 250GB
#We need to get the size of the first one
$disk = $ref_hwinv->{disksize};
my @a = split(',', $disk);
my @b = split(':', $a[0]);
if (@b > 1) {
$disk = $b[1];
} else {
$disk = $b[0];
}
#print "a=@a, b=@b\n";
#TODO: what if the unit is not in GB? We need to convert it to MB
$disk =~ s/GB|gb//g;
}
}
#some info are mendatory
if (!$mac) {
$callback->({error=>["Mac address is not defined in the mac table for node $node."],errorcode=>[1]});
next;
}
if (!$cpu) {
#default cpu count is 1
$cpu = 1;
}
if (!$memory) {
#default memory size is 1024MB=1GB
$memory = 1024;
}
if (!$disk) {
#default disk size is 1GB
$disk = 1;
}
if ($verbose) {
my $rsp;
push @{$rsp->{data}}, "Attributes gathered from the xCAT database:";
push @{$rsp->{data}}, " bmc=$bmc";
push @{$rsp->{data}}, " bmc_user=$bmc_user";
push @{$rsp->{data}}, " bmc_password=$bmc_password";
push @{$rsp->{data}}, " mac=$mac";
push @{$rsp->{data}}, " cpu=$cpu";
push @{$rsp->{data}}, " memory=$memory";
push @{$rsp->{data}}, " disk=$disk";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
#call OpenStack command to add the node into the OpenStack as
#a baremetal node.
my $cmd_tmp = "nova baremetal-node-create";
if ($bmc) {
#make sure it is an ip address
if (($bmc !~ /\d+\.\d+\.\d+\.\d+/) && ($bmc !~ /:/)) {
$bmc = xCAT::NetworkUtils->getipaddr($bmc);
}
$cmd_tmp .= " --pm_address=$bmc";
}
if ($bmc_user) {
$cmd_tmp .= " --pm_user=$bmc_user";
}
if ($bmc_password) {
$cmd_tmp .= " --pm_password=$bmc_password";
}
$cmd_tmp .= " $host $cpu $memory $disk $mac";
my $cmd = qq~$cmd_tmp~;
if ($verbose) {
my $rsp;
push @{$rsp->{data}}, "The command to run on $host:";
push @{$rsp->{data}}, " $cmd";
push @{$rsp->{data}}, " ";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
#print "cmd=$cmd\n";
my $output =
xCAT::InstUtils->xcmd($callback, $doreq, "xdsh", [$host], $cmd, 0);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "OpenStack creating baremetal node $node:";
push @{$rsp->{data}}, "$output";
push @{$rsp->{data}}, "The command was: $cmd";
xCAT::MsgUtils->message("E", $rsp, $callback);
} else {
if (($verbose) && ($output)) {
my $rsp;
push @{$rsp->{data}}, "$output";
push @{$rsp->{data}}, " ";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
}
}
}
#-------------------------------------------------------------------------------
=head3 opsaddimage
This function takes the xCAT nodes and register them
as the OpenStack baremetal nodes
=cut
#-------------------------------------------------------------------------------
sub opsaddimage {
my $request = shift;
my $callback = shift;
my $doreq = shift;
@ARGV = @{$request->{arg}};
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("no_pass_through");
my $help;
my $version;
my $verbose;
#my $cloud;
my $ops_img_names;
my $controller;
if(!GetOptions(
'h|help' => \$help,
'v|version' => \$version,
'V|verbose' => \$verbose,
'c=s' => \$controller,
'n=s' => \$ops_img_names,
))
{
&opsaddimage_usage($callback);
return 1;
}
# display the usage if -h or --help is specified
if ($help) {
&opsaddimage_usage($callback);
return 0;
}
# display the version statement if -v or --verison is specified
if ($version)
{
my $rsp={};
$rsp->{data}->[0]= xCAT::Utils->Version();
$callback->($rsp);
return 0;
}
if (@ARGV ==0) {
$callback->({error=>["Please specify an image name or a list of image names."],errorcode=>[1]});
return 1;
}
#make sure the input cloud name is valid.
#if (!$cloud) {
# $callback->({error=>["Please specify the name of the cloud with -c flag."],errorcode=>[1]});
# return 1;
#} else {
# my $cloudstab = xCAT::Table->new('clouds', -create => 0);
# my @et = $cloudstab->getAllAttribs('name', 'controller');
# if(@et) {
# foreach my $tmp_et (@et) {
# if ($tmp_et->{name} eq $cloud) {
# if ($tmp_et->{controller}) {
# $controller = $tmp_et->{controller};
# last;
# } else {
# $callback->({error=>["Please specify the controller in the clouds table for the cloud: $cloud."],errorcode=>[1]});
# return 1;
# }
# }
# }
# }
if (!$controller) {
$callback->({error=>["Please specify the OpenStack controller node name with -c."],errorcode=>[1]});
return 1;
}
#}
#make sure that the images from the command are valid image names
@images = split(',', $ARGV[0]);
@new_names = ();
if ($ops_img_names) {
@new_names = split(',', $ops_img_names);
}
#print "images=@images, new image names=@new_names, controller=$controller\n";
my $image_hash = {};
my $osimgtab = xCAT::Table->new('osimage', -create => 0);
my @et = $osimgtab->getAllAttribs('imagename');
if(@et) {
foreach my $tmp_et (@et) {
$image_hash->{$tmp_et->{imagename}}{'xCAT'} = 1;
}
}
my @bad_images;
foreach my $image (@images) {
if (!exists($image_hash->{$image})) {
push @bad_images, $image;
}
}
if (@bad_images > 0) {
$callback->({error=>["The following images cannot be found in xCAT osimage table:\n " . join("\n ", @bad_images) . "\n"],errorcode=>[1]});
return 1;
}
my $index=0;
foreach my $image (@images) {
my $new_name = shift(@new_names);
if (!$new_name) {
$new_name = $image; #the default new name is xCAT image name
}
my $cmd_tmp = "glance image-create --name $new_name --public --disk-format qcow2 --container-format bare --property xcat_image_name=\'$image\' < /tmp/$image.qcow2";
my $cmd = qq~touch /tmp/$image.qcow2;$cmd_tmp~;
if ($verbose) {
my $rsp;
push @{$rsp->{data}}, "The command to run on $controller:";
push @{$rsp->{data}}, " $cmd";
push @{$rsp->{data}}, " ";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
my $output =
xCAT::InstUtils->xcmd($callback, $doreq, "xdsh", [$controller], $cmd, 0);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "OpenStack creating image $new_name:";
push @{$rsp->{data}}, "$output";
push @{$rsp->{data}}, "The command was: $cmd";
xCAT::MsgUtils->message("E", $rsp, $callback);
} else {
if (($verbose) && ($output)) {
my $rsp;
push @{$rsp->{data}}, "$output";
push @{$rsp->{data}}, " ";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
}
my $cmd1 = qq~rm /tmp/$image.qcow2~;
if ($verbose) {
my $rsp;
push @{$rsp->{data}}, "The command to run on $controller:";
push @{$rsp->{data}}, " $cmd1";
push @{$rsp->{data}}, " ";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
my $output1 =
xCAT::InstUtils->xcmd($callback, $doreq, "xdsh", [$controller], $cmd1, 0);
if (($verbose) && ($output1)) {
my $rsp;
push @{$rsp->{data}}, "$output1";
push @{$rsp->{data}}, " ";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
}
}
#-------------------------------------------------------------------------------
=head3 deploy_ops_bm_node
This is a internel command called by OpenStack xCAT-baremetal driver.
It prepares the node by adding the config_ops_bm_node postbootscript
to the postscript table for the node, then call nodeset and then boot
the node up.
=cut
#-------------------------------------------------------------------------------
sub deploy_ops_bm_node {
my $request = shift;
my $callback = shift;
my $doreq = shift;
@ARGV = @{$request->{arg}};
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("no_pass_through");
my $node = $request->{node}->[0];
my $help;
my $version;
my $img_name;
my $hostname;
my $fixed_ip;
my $netmask;
if(!GetOptions(
'h|help' => \$help,
'v|version' => \$version,
'image=s' => \$img_name,
'host=s' => \$hostname,
'ip=s' => \$fixed_ip,
'mask=s' => \$netmask,
))
{
&deploy_ops_bm_node_usage($callback);
return 1;
}
# display the usage if -h or --help is specified
if ($help) {
&deploy_ops_bm_node_usage($callback);
return 0;
}
# display the version statement if -v or --verison is specified
if ($version)
{
my $rsp={};
$rsp->{data}->[0]= xCAT::Utils->Version();
$callback->($rsp);
return 0;
}
#print "node=$node, image=$img_name, host=$hostname, ip=$fixed_ip, mask=$netmask\n";
#validate the image name
my $osimagetab = xCAT::Table->new('osimage', -create=>1);
my $ref = $osimagetab->getAttribs({imagename => $img_name}, 'imagename');
if (!$ref) {
$callback->({error=>["Invalid image name: $img_name."],errorcode=>[1]});
return 1;
}
#check if the fixed ip is within the xCAT management network.
#get the master ip address for the node then check if the master ip and
#the OpenStack fixed_ip are on the same subnet.
#my $same_nw = 0;
#my $master = xCAT::TableUtils->GetMasterNodeName($node);
#my $master_ip = xCAT::NetworkUtils->toIP($master);
#if (xCAT::NetworkUtils::isInSameSubnet($master_ip, $fixed_ip, $netmask, 0)) {
# $same_nw = 1;
#}
#add config_ops_bm_node to the node's postbootscript
my $script = "config_ops_bm_node $hostname $fixed_ip $netmask";
add_postscript($callback, $node, $script);
#run nodeset
my $cmd = qq~osimage=$img_name~;
my $output = xCAT::Utils->runxcmd(
{command => ["nodeset"],
node => [$node],
arg => [$cmd]},
$doreq, -1, 1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "nodeset:";
push @{$rsp->{data}}, "$output";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
#deploy the node now, supported nodehm.mgt values: ipmi, blade,fsp, hmc.
my $hmtab = xCAT::Table->new('nodehm');
my $hment = $hmtab->getNodeAttribs($node,['mgt']);
if ($hment && $hment->{'mgt'}) {
my $mgt = $hment->{'mgt'};
if ($mgt eq 'ipmi') {
deploy_bmc_node($callback, $doreq, $node);
} elsif (($mgt eq 'blade') || ($mgt eq 'fsp')) {
deploy_blade($callback, $doreq, $node);
} elsif ($mgt eq 'hmc') {
deploy_hmc_node($callback, $doreq, $node);
} else {
my $rsp;
push @{$rsp->{data}}, "Node $node: nodehm.mgt=$mgt is not supported in the OpenStack cloud.";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
} else {
#nodehm.mgt must setup for node
my $rsp;
push @{$rsp->{data}}, "Node $node: nodehm.mgt cannot be empty in order to deploy.";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
}
# Deploy a rack-mounted node
sub deploy_bmc_node {
my $callback = shift;
my $doreq = shift;
my $node = shift;
#set boot order
my $cmd = qq~net~;
my $output = xCAT::Utils->runxcmd(
{command => ["rsetboot"],
node => [$node],
arg => [$cmd]},
$doreq, -1, 1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "rsetboot:";
push @{$rsp->{data}}, "$output";
xCAT::MsgUtils->message("E", $rsp, $callback);
}
#reboot the node
my $cmd = qq~boot~;
my $output = xCAT::Utils->runxcmd(
{command => ["rpower"],
node => [$node],
arg => [$cmd]},
$doreq, -1, 1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "rpower:";
push @{$rsp->{data}}, "$output";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
}
# Deploy a blade or fsp controlled node
sub deploy_blade {
my $callback = shift;
my $doreq = shift;
my $node = shift;
#set boot order
my $cmd = qq~net~;
my $output = xCAT::Utils->runxcmd(
{command => ["rbootseq"],
node => [$node],
arg => [$cmd]},
$doreq, -1, 1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "rbootseq:";
push @{$rsp->{data}}, "$output";
xCAT::MsgUtils->message("E", $rsp, $callback);
}
#reboot the node
my $cmd = qq~boot~;
my $output = xCAT::Utils->runxcmd(
{command => ["rpower"],
node => [$node],
arg => [$cmd]},
$doreq, -1, 1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "rpower:";
push @{$rsp->{data}}, "$output";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
}
# Deploy a node controlled by HMC
sub deploy_hmc_node {
my $callback = shift;
my $doreq = shift;
my $node = shift;
my $output = xCAT::Utils->runxcmd(
{command => ["rnetboot"],
node => [$node]},
$doreq, -1, 1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "rnetboot:";
push @{$rsp->{data}}, "$output";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
}
#-------------------------------------------------------------------------------
=head3 cleanup_ops_bm_node
This is a internel command called by OpenStack xCAT-baremetal driver.
It undoes all the changes made by deploy_ops_bm_node command. It removes
the config_ops_bmn_ode postbootscript from the postscript table for the
node, removes the alias ip and then power off the node.
=cut
#-------------------------------------------------------------------------------
sub cleanup_ops_bm_node {
my $request = shift;
my $callback = shift;
my $doreq = shift;
@ARGV = @{$request->{arg}};
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("no_pass_through");
my $node = $request->{node}->[0];
my $help;
my $version;
my $fixed_ip;
if(!GetOptions(
'h|help' => \$help,
'v|version' => \$version,
'ip=s' => \$fixed_ip,
))
{
&cleanup_ops_bm_node_usage($callback);
return 1;
}
# display the usage if -h or --help is specified
if ($help) {
&cleanup_ops_bm_node_usage($callback);
return 0;
}
# display the version statement if -v or --verison is specified
if ($version)
{
my $rsp={};
$rsp->{data}->[0]= xCAT::Utils->Version();
$callback->($rsp);
return 0;
}
#print "node=$node, ip=$fixed_ip\n";
#removes the config_ops_bm_node postbootscript from the postscripts table
remove_postscript($callback, $node, "config_ops_bm_node");
#run updatenode to remove the ip alias
my $cmd = qq~-P deconfig_ops_bm_node $fixed_ip~;
my $output = xCAT::Utils->runxcmd(
{command => ["updatenode"],
node => [$node],
arg => [$cmd]},
$doreq, -1, 1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "updatenode:";
push @{$rsp->{data}}, "$output";
xCAT::MsgUtils->message("E", $rsp, $callback);
}
#turn the node power off
$ssh_ok = 0;
my $cmd = qq~stat~;
my $output = xCAT::Utils->runxcmd(
{command => ["rpower"],
node => [$node],
arg => [$cmd]},
$doreq, -1, 1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "rpower:";
push @{$rsp->{data}}, "$output";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
} else {
if ($output !~ /: off/) {
#power off the node
my $cmd = qq~off~;
my $output = xCAT::Utils->runxcmd(
{command => ["rpower"],
node => [$node],
arg => [$cmd]},
$doreq, -1, 1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "rpower:";
push @{$rsp->{data}}, "$output";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
}
}
}
#-------------------------------------------------------
=head3 add_postscript
It adds the 'config_ops_bm_node' postbootscript to the
postscript table for the given node.
=cut
#-------------------------------------------------------
sub add_postscript {
my $callback=shift;
my $node=shift;
my $script=shift;
#print "script=$script\n";
my $posttab=xCAT::Table->new("postscripts", -create =>1);
my %setup_hash;
my $ref = $posttab->getNodeAttribs($node,[qw(postscripts postbootscripts)]);
my $found=0;
if ($ref) {
if (exists($ref->{postscripts})) {
my @a = split(/,/, $ref->{postscripts});
if (grep(/^config_ops_bm_node/, @a)) {
$found = 1;
if (!grep(/^$script$/, @a)) {
#not exact match, must replace it with the new script
for (@a) {
s/^config_ops_bm_node.*$/$script/;
}
my $new_post = join(',', @a);
$setup_hash{$node}={postscripts=>"$new_post"};
}
}
}
if (exists($ref->{postbootscripts})) {
my $post=$ref->{postbootscripts};
my @old_a=split(',', $post);
if (grep(/^config_ops_bm_node/, @old_a)) {
if (!grep(/^$script$/, @old_a)) {
#not exact match, will replace it with new script
for (@old_a) {
s/^config_ops_bm_node.*$/$script/;
}
my $new_postboot = join(',', @old_a);
$setup_hash{$node}={postbootscripts=>"$new_postboot"};
}
} else {
if (! $found) {
$setup_hash{$node}={postbootscripts=>"$post,$script"};
}
}
} else {
if (! $found) {
$setup_hash{$node}={postbootscripts=>"$script"};
}
}
} else {
$setup_hash{$node}={postbootscripts=>"$script"};
}
if (keys(%setup_hash) > 0) {
$posttab->setNodesAttribs(\%setup_hash);
}
return 0;
}
#-------------------------------------------------------
=head3 remove_postscript
It removes the 'config_ops_bm_node' postbootscript from
the postscript table for the given node.
=cut
#-------------------------------------------------------
sub remove_postscript {
my $callback=shift;
my $node=shift;
my $script=shift;
my $posttab=xCAT::Table->new("postscripts", -create =>1);
my %setup_hash;
my $ref = $posttab->getNodeAttribs($node,[qw(postscripts postbootscripts)]);
my $found=0;
if ($ref) {
if (exists($ref->{postscripts})) {
my @old_a = split(/,/, $ref->{postscripts});
my @new_a = grep(!/^$script/, @old_a);
if (scalar(@new_a) != scalar(@old_a)) {
my $new_post = join(',', @new_a);
$setup_hash{$node}={postscripts=>"$new_post"};
}
}
if (exists($ref->{postbootscripts})) {
my @old_b = split(/,/, $ref->{postbootscripts});
my @new_b = grep(!/^$script/, @old_b);
if (scalar(@new_b) != scalar(@old_b)) {
my $new_post = join(',', @new_b);
$setup_hash{$node}={postbootscripts=>"$new_post"};
}
}
}
if (keys(%setup_hash) > 0) {
$posttab->setNodesAttribs(\%setup_hash);
}
return 0;
}
#-------------------------------------------------------------------------------
=head3 opsaddbmnode_usage
The usage text for opsaddbmnode command.
=cut
#-------------------------------------------------------------------------------
sub opsaddbmnode_usage {
my $cb=shift;
my $rsp={};
$rsp->{data}->[0]= "Usage: opsaddbmnode -h";
$rsp->{data}->[1]= " opsaddbmnode -v";
$rsp->{data}->[2]= " opsaddbmnode <noderange> -s <service_host> [-V]";
$cb->($rsp);
}
#-------------------------------------------------------------------------------
=head3 opsaddimage_usage
The usage text for opsaddimage command.
=cut
#-------------------------------------------------------------------------------
sub opsaddimage_usage {
my $cb=shift;
my $rsp={};
$rsp->{data}->[0]= "Usage: opsaddimage -h";
$rsp->{data}->[1]= " opsaddimage -v";
$rsp->{data}->[2]= " opsaddimage <image1,image2...> [-n <new_name1,new_name2...> -c <controller> [-V]";
$cb->($rsp);
}
#-------------------------------------------------------------------------------
=head3 deploy_ops_bm_node_usage
The usage text for deploy_ops_bm_node command.
=cut
#-------------------------------------------------------------------------------
sub deploy_ops_bm_node_usage {
my $cb=shift;
my $rsp={};
$rsp->{data}->[0]= "Usage: deploy_ops_bm_node -h";
$rsp->{data}->[1]= " deploy_ops_bm_node -v";
$rsp->{data}->[2]= " deploy_ops_bm_node <node> --image <image_name> --host <ops_hostname> --ip <ops_fixed_ip> --mask <netmask>";
$cb->($rsp);
}
#-------------------------------------------------------------------------------
=head3 cleanup_ops_bm_node_usage
The usage text cleanup_ops_bm_node command.
=cut
#-------------------------------------------------------------------------------
sub cleanup_ops_bm_node_usage {
my $cb=shift;
my $rsp={};
$rsp->{data}->[0]= "Usage: cleanup_ops_bm_node -h";
$rsp->{data}->[1]= " cleanup_ops_bm_node -v";
$rsp->{data}->[2]= " cleanup_ops_bm_node <node> [--ip <ops_fixed_ip>]";
$cb->($rsp);
}
1;
@@ -1,17 +0,0 @@
# Copyright (c) 2012 NTT DOCOMO, INC.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from xcat.openstack.baremetal import driver
BareMetalDriver = driver.xCATBareMetalDriver
@@ -1,256 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# coding=utf-8
"""
A driver for Bare-metal platform.
"""
from oslo.config import cfg
from nova.compute import power_state
from nova import context as nova_context
from nova import exception
from nova.openstack.common import excutils
from nova.openstack.common.gettextutils import _
from nova.openstack.common import importutils
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
from nova.virt.baremetal import baremetal_states
from nova.virt.baremetal import db
from nova.virt.baremetal import driver as bm_driver
from nova.virt.baremetal import utils as bm_utils
from nova.virt import driver
from nova.virt import firewall
from nova.virt.libvirt import imagecache
from xcat.openstack.baremetal import xcat_driver
from xcat.openstack.baremetal import exception as xcat_exception
from xcat.openstack.baremetal import power_states
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
CONF.import_opt('use_ipv6', 'nova.netconf')
class xCATBareMetalDriver(bm_driver.BareMetalDriver):
"""BareMetal hypervisor driver."""
def __init__(self, virtapi, read_only=False):
super(xCATBareMetalDriver, self).__init__(virtapi)
self.xcat = xcat_driver.xCAT()
def _get_xCAT_image_name(self, image_meta):
prop = image_meta.get('properties')
xcat_image_name = prop.get('xcat_image_name')
if xcat_image_name:
return xcat_image_name
else:
raise xcat_exception.xCATInvalidImageError(image=image_meta.get('name'))
def spawn(self, context, instance, image_meta, injected_files,
admin_password, network_info=None, block_device_info=None):
"""
Create a new instance/VM/domain on the virtualization platform.
Once this successfully completes, the instance should be
running (power_state.RUNNING).
If this fails, any partial instance should be completely
cleaned up, and the virtualization platform should be in the state
that it was before this call began.
:param context: security context
:param instance: Instance object as returned by DB layer.
This function should use the data there to guide
the creation of the new instance.
:param image_meta: image object returned by nova.image.glance that
defines the image from which to boot this instance
:param injected_files: User files to inject into instance.
:param admin_password: Administrator password to set in instance.
:param network_info:
:py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
:param block_device_info: Information about block devices to be
attached to the instance.
"""
#import pdb
#pdb.set_trace()
node_uuid = self._require_node(instance)
node = db.bm_node_associate_and_update(context, node_uuid,
{'instance_uuid': instance['uuid'],
'instance_name': instance['hostname'],
'task_state': baremetal_states.BUILDING})
try:
self._plug_vifs(instance, network_info, context=context)
self._attach_block_devices(instance, block_device_info)
self._start_firewall(instance, network_info)
macs = self.macs_for_instance(instance)
nodename = self.xcat.get_xcat_node_name(macs)
imagename = self._get_xCAT_image_name(image_meta)
hostname = instance.get('hostname')
#get the network information for the new node
interfaces = bm_utils.map_network_interfaces(network_info, CONF.use_ipv6)
if CONF.use_ipv6:
fixed_ip = interfaces[0].get('address_v6')
netmask = interfaces[0].get('netmask_v6')
gateway = interfaces[0].get('gateway_v6')
else:
fixed_ip = interfaces[0].get('address')
netmask = interfaces[0].get('netmask')
gateway = interfaces[0].get('gateway')
#convert netmask from IPAddress to unicode string
if netmask:
netmask = unicode(netmask)
#let xCAT install it
bm_driver._update_state(context, node, instance, baremetal_states.DEPLOYING)
self.xcat.deploy_node(nodename, imagename, hostname, fixed_ip, netmask, gateway)
bm_driver._update_state(context, node, instance, baremetal_states.ACTIVE)
except Exception as e:
with excutils.save_and_reraise_exception():
LOG.error(_("Error occured while deploying instance %(instance)s "
"on baremetal node %(node)s: %(error)s") %
{'instance': instance['uuid'],
'node': node['uuid'],
'error':str(e)})
bm_driver._update_state(context, node, instance, baremetal_states.ERROR)
def reboot(self, context, instance, network_info, reboot_type,
block_device_info=None, bad_volumes_callback=None):
"""Reboot the specified instance.
After this is called successfully, the instance's state
goes back to power_state.RUNNING. The virtualization
platform should ensure that the reboot action has completed
successfully even in cases in which the underlying domain/vm
is paused or halted/stopped.
:param instance: Instance object as returned by DB layer.
:param network_info:
:py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
:param reboot_type: Either a HARD or SOFT reboot
:param block_device_info: Info pertaining to attached volumes
:param bad_volumes_callback: Function to handle any bad volumes
encountered
"""
try:
node = bm_driver._get_baremetal_node_by_instance_uuid(instance['uuid'])
macs = self.macs_for_instance(instance)
nodename = self.xcat.get_xcat_node_name(macs)
self.xcat.reboot_node(nodename)
bm_driver._update_state(context, node, instance, baremetal_states.RUNNING)
except xcat_exception.xCATCommandError as e:
with excutils.save_and_reraise_exception():
LOG.error(_("Error occured while rebooting instance %(instance)s "
"on baremetal node %(node)s: %(error)s") %
{'instance': instance['uuid'],
'node': node['uuid'],
'error':str(e)})
bm_driver._update_state(context, node, instance, baremetal_states.ERROR)
def destroy(self, instance, network_info, block_device_info=None,
context=None):
"""Destroy (shutdown and delete) the specified instance.
If the instance is not found (for example if networking failed), this
function should still succeed. It's probably a good idea to log a
warning in that case.
:param context: security context
:param instance: Instance object as returned by DB layer.
:param network_info:
:py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
:param block_device_info: Information about block devices that should
be detached from the instance.
:param destroy_disks: Indicates if disks should be destroyed
"""
#import pdb
#pdb.set_trace()
context = nova_context.get_admin_context()
try:
node = bm_driver._get_baremetal_node_by_instance_uuid(instance['uuid'])
except exception.InstanceNotFound:
LOG.warning(_("Destroy function called on a non-existing instance %s")
% instance['uuid'])
return
try:
macs = self.macs_for_instance(instance)
nodename = self.xcat.get_xcat_node_name(macs)
interfaces = bm_utils.map_network_interfaces(network_info, CONF.use_ipv6)
fixed_ip=None
if interfaces and interfaces[0]:
if CONF.use_ipv6:
fixed_ip = interfaces[0].get('address_v6')
else:
fixed_ip = interfaces[0].get('address')
if fixed_ip:
self.xcat.cleanup_node(nodename, fixed_ip)
else:
self.xcat.cleanup_node(nodename)
except Exception as e:
#just log it and move on
LOG.warning(_("Destroy called with xCAT error:" + str(e)))
try:
self._detach_block_devices(instance, block_device_info)
self._stop_firewall(instance, network_info)
self._unplug_vifs(instance, network_info)
bm_driver._update_state(context, node, None, baremetal_states.DELETED)
except Exception as e:
with excutils.save_and_reraise_exception():
LOG.error(_("Error occurred while destroying instance %s: %s")
% (instance['uuid'], str(e)))
bm_driver._update_state(context, node, instance,
baremetal_states.ERROR)
def power_off(self, instance, node=None):
"""Power off the specified instance."""
macs = self.macs_for_instance(instance)
nodename = self.xcat.get_xcat_node_name(macs)
self.xcat.power_off_node(nodename)
def power_on(self, context, instance, network_info, block_device_info=None,
node=None):
"""Power on the specified instance."""
macs = self.macs_for_instance(instance)
nodename = self.xcat.get_xcat_node_name(macs)
self.xcat.power_on_node(nodename)
def get_console_output(self, instance):
pass
def get_info(self, instance):
"""Get the current status of an instance, by name (not ID!)
Returns a dict containing:
:state: the running state, one of the power_state codes
:max_mem: (int) the maximum memory in KBytes allowed
:mem: (int) the memory in KBytes used by the domain
:num_cpu: (int) the number of virtual CPUs for the domain
:cpu_time: (int) the CPU time used in nanoseconds
"""
node = bm_driver._get_baremetal_node_by_instance_uuid(instance['uuid'])
macs = self.macs_for_instance(instance)
nodename = self.xcat.get_xcat_node_name(macs)
ps = self.xcat.get_node_power_state(nodename)
if ps == power_states.ON:
pstate = power_state.RUNNING
elif ps == power_states.OFF:
pstate = power_state.SHUTDOWN
else:
pstate = power_state.NOSTATE
return {'state': pstate,
'max_mem': node['memory_mb'],
'mem': node['memory_mb'],
'num_cpu': node['cpus'],
'cpu_time': 0}
@@ -1,41 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
"""xCAT baremtal exceptions.
"""
import functools
import sys
from oslo.config import cfg
import webob.exc
from nova.openstack.common import excutils
from nova.openstack.common.gettextutils import _
from nova.openstack.common import log as logging
from nova import safe_utils
from nova import exception as nova_exception
LOG = logging.getLogger(__name__)
class xCATException(Exception):
errmsg = _("xCAT general exception")
def __init__(self, errmsg=None, **kwargs):
if not errmsg:
errmsg = self.errmsg
errmsg = errmsg % kwargs
super(xCATException, self).__init__(errmsg)
class xCATCommandError(xCATException):
errmsg = _("Error returned when calling xCAT command %(cmd)s"
" for node %(node)s:%(error)s")
class xCATInvalidImageError(xCATException):
errmsg = _("The image %(image)s is not an xCAT image")
class xCATDeploymentFailure(xCATException):
errmsg = _("xCAT node deployment failed for node %(node)s:%(error)s")
class xCATRebootFailure(xCATException):
errmsg = _("xCAT node rebooting failed for node %(node)s:%(error)s")
@@ -1,9 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
"""
Possible xCAT node power states.
"""
OFF = 'off'
ON = 'on'
ERROR = 'error'
@@ -1,260 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# coding=utf-8
"""
Baremetal xCAT power manager.
"""
import os
import sys
import stat
from oslo.config import cfg
import datetime
from nova import context as nova_context
from nova.virt.baremetal import baremetal_states
from nova.openstack.common.gettextutils import _
from nova.openstack.common import log as logging
from nova.openstack.common import loopingcall
from nova.openstack.common import timeutils
from nova import paths
from nova import utils
from xcat.openstack.baremetal import exception
from xcat.openstack.baremetal import power_states
LOG = logging.getLogger(__name__)
# register configuration options
xcat_opts = [
cfg.IntOpt('deploy_timeout',
help='Timeout for node deployment. Default: 0 second (unlimited)',
default=0),
cfg.IntOpt('reboot_timeout',
help='Timeout for rebooting a node. Default: 0 second (unlimited)',
default=0),
cfg.IntOpt('deploy_checking_interval',
help='Checking interval for node deployment. Default: 10 seconds',
default=10),
cfg.IntOpt('reboot_checking_interval',
help='Checking interval for rebooting a node. Default: 5 seconds',
default=5),
]
xcat_group = cfg.OptGroup(name='xcat',
title='xCAT Options')
CONF = cfg.CONF
CONF.register_group(xcat_group)
CONF.register_opts(xcat_opts, xcat_group)
class xCAT(object):
"""A driver that calls xCAT funcions"""
def __init__(self):
#setup the path for xCAT commands
#xcatroot = os.getenv('XCATROOT', '/opt/xcat/')
#sys.path.append("%s/bin" % xcatroot)
#sys.path.append("%s/sbin" % xcatroot)
pass
def _exec_xcat_command(self, command):
"""Calls xCAT command."""
args = command.split(" ")
out, err = utils.execute(*args, run_as_root=True)
LOG.debug(_("xCAT command stdout: '%(out)s', stderr: '%(err)s'"),
{'out': out, 'err': err})
return out, err
def get_xcat_node_name(self, macs):
"""Get the xcat node name given mac addressed.
It uses the mac address to search for the node name in xCAT.
"""
for mac in macs:
out, err = self._exec_xcat_command("lsdef -w mac=%s" % mac)
if out:
return out.split(" ")[0]
errstr='No node found in xCAT with the following mac address: ' \
+ ','.join(macs)
LOG.warning(errstr)
raise exception.xCATCommandError(errstr)
def deploy_node(self, nodename, imagename, hostname, fixed_ip, netmask, gateway):
"""
Install the node.
It calls xCAT command deploy_ops_bmnode which prepares the node
by adding the config_ops_bm_node postbootscript to the postscript
table for the node, then call nodeset and then boot the node up.
"""
out, err = self._exec_xcat_command(
"deploy_ops_bm_node %(node)s --image %(image)s"
" --host %(host)s --ip %(ip)s --mask %(mask)s"
% {'node': nodename,
'image': imagename,
'host': hostname,
'ip': fixed_ip,
'mask': netmask,
})
if err:
errstr = _("Error returned when calling xCAT deploy_ops_bm_node"
" command for node %s:%s") % (nodename, err)
LOG.warning(errstr)
raise exception.xCATCommandError(errstr)
self._wait_for_node_deploy(nodename)
def cleanup_node(self, nodename, fixed_ip=None):
"""
Undo all the changes made to the node by deploy_node function.
It calls xCAT command cleanup_ops_bm_node which removes the
config_ops_bm_node postbootscript from the postscript table
for the node, removes the alias ip and then power the node off.
"""
cmd = "cleanup_ops_bm_node %s" % nodename
if fixed_ip:
cmd += " --ip %s" % fixed_ip
out, err = self._exec_xcat_command(cmd)
if err:
errstr = _("Error returned when calling xCAT cleanup_ops_bm_node"
" command for node %s:%s") % (nodename, err)
LOG.warning(errstr)
raise exception.xCATCommandError(errstr)
def power_on_node(self, nodename):
"""Power on the node."""
state = self.get_node_power_state(nodename)
if state == power_states.ON:
LOG.warning(_("Powring on node called, but the node %s "
"is already on") % nodename)
out, err = self._exec_xcat_command("rpower %s on" % nodename)
if err:
errstr = _("Error returned when calling xCAT rpower on"
" for node %s:%s") % (nodename, err)
LOG.warning(errstr)
raise exception.xCATCommandError(errstr)
else:
self._wait_for_node_reboot(nodename)
return power_states.ON
def power_off_node(self, nodename):
"""Power off the node."""
state = self.get_node_power_state(nodename)
if state == power_states.OFF:
LOG.warning(_("Powring off node called, but the node %s "
"is already off") % nodename)
out, err = self._exec_xcat_command("rpower %s off" % nodename)
if err:
errstr = _("Error returned when calling xCAT rpower off"
" for node %s:%s") % (nodename, err)
LOG.warning(errstr)
raise exception.xCATCommandError(errstr)
else:
return power_states.OFF
def reboot_node(self, nodename):
"""Reboot the node."""
out, err = self._exec_xcat_command("rpower %s boot" % nodename)
if err:
errstr = _("Error returned when calling xCAT rpower boot"
" for node %s:%s") % (nodename, err)
LOG.warning(errstr)
raise exception.xCATCommandError(errstr)
self._wait_for_node_reboot(nodename)
return power_states.ON
def get_node_power_state(self, nodename):
out, err = self._exec_xcat_command("rpower %s stat" % nodename)
if err:
errstr = _("Error returned when calling xCAT rpower stat"
" for node %s:%s") % (nodename, err)
LOG.warning(errstr)
raise exception.xCATCommandError(errstr)
else:
state = out.split(":")[1]
if state:
state = state.strip()
if state == 'on':
return power_states.ON
elif state == 'off':
return power_states.OFF
return power_states.ERROR
def _wait_for_node_deploy(self, nodename):
"""Wait for xCAT node deployment to complete."""
locals = {'errstr':''}
def _wait_for_deploy():
out,err = self._exec_xcat_command("nodels %s nodelist.status" % nodename)
if err:
locals['errstr'] = _("Error returned when quering node status"
" for node %s:%s") % (nodename, err)
LOG.warning(locals['errstr'])
raise loopingcall.LoopingCallDone()
if out:
node,status = out.split(": ")
status = status.strip()
if status == "booted":
LOG.info(_("Deployment for node %s completed.")
% nodename)
raise loopingcall.LoopingCallDone()
if (CONF.xcat.deploy_timeout and
timeutils.utcnow() > expiration):
locals['errstr'] = _("Timeout while waiting for"
" deployment of node %s.") % nodename
LOG.warning(locals['errstr'])
raise loopingcall.LoopingCallDone()
expiration = timeutils.utcnow() + datetime.timedelta(
seconds=CONF.xcat.deploy_timeout)
timer = loopingcall.FixedIntervalLoopingCall(_wait_for_deploy)
# default check every 10 seconds
timer.start(interval=CONF.xcat.deploy_checking_interval).wait()
if locals['errstr']:
raise exception.xCATDeploymentFailure(locals['errstr'])
def _wait_for_node_reboot(self, nodename):
"""Wait for xCAT node boot to complete."""
locals = {'errstr':''}
def _wait_for_reboot():
out,err = self._exec_xcat_command("nodestat %s" % nodename)
if err:
locals['errstr'] = _("Error returned when quering node status"
" for node %s:%s") % (nodename, err)
LOG.warning(locals['errstr'])
raise loopingcall.LoopingCallDone()
if out:
node,status = out.split(": ")
status = status.strip()
if status == "sshd":
LOG.info(_("Rebooting node %s completed.")
% nodename)
raise loopingcall.LoopingCallDone()
if (CONF.xcat.reboot_timeout and
timeutils.utcnow() > expiration):
locals['errstr'] = _("Timeout while waiting for"
" rebooting node %s.") % nodename
LOG.warning(locals['errstr'])
raise loopingcall.LoopingCallDone()
expiration = timeutils.utcnow() + datetime.timedelta(
seconds=CONF.xcat.reboot_timeout)
timer = loopingcall.FixedIntervalLoopingCall(_wait_for_reboot)
# default check every 5 seconds
timer.start(interval=CONF.xcat.reboot_checking_interval).wait()
if locals['errstr']:
raise exception.xCATRebootFailure(locals['errstr'])
@@ -1,92 +0,0 @@
=head1 NAME
B<opsaddbmnode> - It adds xCAT baremetal nodes to an OpenStack cloud.
=head1 SYNOPSIS
B<opsaddbmnode> I<noderange> B<-s> I<service_host> [B<-V>|B<--verbose>]
B<opsaddbmnode> [B<-h>|B<--help>]
B<opsaddbmnode> [B<-v>|B<--version>]
=head1 DESCRIPTION
The B<opsaddbmnode> command registers xCAT nodes to an OpenStack cloud. An OpenStack nova baremetal node registration command takes several node attributes:
=over
=item BMC ip addresss, user id and password
=item Name of nova compute host which will control this baremetal node
=item Number of CPUs in the node
=item Memory in the node (MB)
=item Local hard disk in the node (GB)
=item MAC address to provision the node
=back
The opsaddbmnode command pulls the above baremetal node information from xCAT tables and calls "nova baremetal-node-create" to register the baremetal node with the OpenStack cloud.
Please make sure the following xCAT tables are filled with correct information for the given nodes before calling this command.
=over
=item ipmi (for BMC ip addresss, user id and password)
=item mac (for MAC address)
=item hwinv (for CPU, memory and disk info.)
=back
=head1 Parameters
I<noderage> is a comma separated node or node group names.
=head1 OPTIONS
=over 10
=item B<-s> The node name of the OpenStack compute host that hosts the baremetal nodes.
=item B<-h|--help> Display usage message.
=item B<-v|--version> The Command Version.
=item B<-V|--verbose> Verbose output.
=back
=head1 RETURN VALUE
0 The command completed successfully.
1 An error has occurred.
=head1 EXAMPLES
=over 3
=item 1
To register node1, node2 and node3 to OpenStack, sv1 is the compute host.
opsassbmnode node1,node2,node3 -s sv1
=back
=head1 FILES
/opt/xcat/bin/opadddbmnode
=head1 SEE ALSO
L<opsaddimage(1)|opsaddimage.1>
@@ -1,67 +0,0 @@
=head1 NAME
B<opsaddimage> - It adds or removes nodes for the vlan.
=head1 SYNOPSIS
B<opsaddimage> I<image1,image2,...> B<-n> I<new_name1,new_name2,...> [B<-c> I<controller>] [B<-V>|B<--verbose>]
B<opsaddimage> [B<-h>|B<--help>]
B<opsaddimage> [B<-v>|B<--version>]
=head1 DESCRIPTION
The B<opsaddimage> command adds a list of xCAT images into the OpenStack cloud.
Under the cover, it creates a fake image and registers the fake image into OpenStack with command B<glance image-create>. It sets the property in the image to indicate that this is an xCAT image and also stores the original xCAT image name in the property for further reference.
The xCAT image names can be listed using B<lsdef -t osimage> command.
=head1 Parameters
I<image1,image1...> a comma separated xCAT images names.
=head1 OPTIONS
=over 10
=item B<-n> a comma separated new image names in the OpenStack. If omitted, the default is the original xCAT image nanme.
=item B<-c> the node name of the OpenStack controller. This node must be an xCAT managed node.
=item B<-h|--help> Display usage message.
=item B<-v|--version> The Command Version.
=item B<-V|--verbose> Verbose output.
=back
=head1 RETURN VALUE
0 The command completed successfully.
1 An error has occurred.
=head1 EXAMPLES
=over 3
=item 1.
To register xCAT image rhels6.3-x86_64-install-compute into OpenStack.
opsaddimage rhels6.3-x86_64-install-compute -c sv2
=back
=head1 FILES
/opt/xcat/bin/opsaddimage
=head1 SEE ALSO
L<opsaddbmnode(1)|opsaddbmnode.1>
@@ -1,215 +0,0 @@
#!/bin/sh
# IBM(c) 2014 EPL license http://www.eclipse.org/legal/epl-v10.html
# xCAT post script for configuring the openstack baremetal node.
# The format is:
# config_ops_bm_node ops_hostname ops_ip ops_netmask
get_os_type()
{
#get os type
str_os_type=`uname | tr 'A-Z' 'a-z'`
str_temp=''
if [ "$str_os_type" = "linux" ];then
str_temp=`echo $OSVER | grep -E '(sles|suse)'`
if [ -f "/etc/debian_version" ];then
str_os_type="debian"
elif [ -f "/etc/SuSE-release" -o -n "$str_temp" ];then
str_os_type="sles"
else
str_os_type="redhat"
fi
else
str_os_type="aix"
fi
echo "$str_os_type"
}
setup_ip()
{
str_os_type=$1
str_if_name=$2
str_v4ip=$3
str_v4mask=$4
ret=`ifconfig $str_if_name |grep "inet addr" 2>&1`
if [ $? -eq 0 ]; then
old_ip=`echo $ret|cut -d':' -f2 |cut -d' ' -f1`
old_mask=`echo $ret|cut -d':' -f4`
#echo "old ip = $old_ip, old mask=$old_mask"
if [ "$old_ip" == "$str_v4ip" -a "$old_mask" == "$str_v4mask" ]; then
#if nic is up and the address is the same, then donothing
#echo "do nothing"
exit 0
else
#bring down the nic and reconstruct it.
#echo "bring down the old nic"
ifconfig $str_if_name del $old_ip
fi
fi
if [ "$str_os_type" = "sles" ];then
str_conf_file="/etc/sysconfig/network/ifcfg-${str_if_name}"
if [ -f $str_conf_file ]; then
rm $str_conf_file
fi
echo "DEVICE=${str_if_name}" > $str_conf_file
echo "BOOTPROTO=static" >> $str_conf_file
echo "IPADDR=${str_v4ip}" >> $str_conf_file
echo "NETMASK=${str_v4mask}" >> $str_conf_file
echo "NETWORK=''" >> $str_conf_file
echo "STARTMODE=onboot" >> $str_conf_file
echo "USERCONTROL=no" >> $str_conf_file
ifup $str_if_name
#debian ubuntu
elif [ "$str_os_type" = "debian" ];then
str_conf_file="/etc/network/interfaces.d/${str_if_name}"
if [ -f $str_conf_file ]; then
rm $str_conf_file
fi
echo "auto ${str_if_name}" > $str_conf_file
echo "iface ${str_if_name} inet static" >> $str_conf_file
echo " address ${str_v4ip}" >> $str_conf_file
echo " netmask ${str_v4mask}" >> $str_conf_file
ifconfig $str_if_name up
else
# Write the info to the ifcfg file for redhat
str_conf_file="/etc/sysconfig/network-scripts/ifcfg-${str_if_name}"
if [ -f $str_conf_file ]; then
rm $str_conf_file
fi
echo "DEVICE=${str_if_name}" > $str_conf_file
echo "BOOTPROTO=static" >> $str_conf_file
echo "NM_CONTROLLED=no" >> $str_conf_file
echo "IPADDR=${str_v4ip}" >> $str_conf_file
echo "NETMASK=${str_v4mask}" >> $str_conf_file
echo "ONBOOT=yes" >> $str_conf_file
ifup $str_if_name
fi
}
#change hostname permanently
change_host_name()
{
str_os_type=$1
str_hostname=$2
hostname $str_hostname
if [ "$str_os_type" = "sles" ];then
echo "Persistently changing the hostname not implemented yet."
#debian ubuntu and rh7
elif [ -f "/etc/hostname" ];then
conf_file="/etc/hostname"
echo "$str_hostname" > $conf_file
else
conf_file="/etc/sysconfig/network"
if [ ! -f $conf_file ]; then
touch $conf_file
fi
grep 'HOSTNAME' $conf_file 2>&1 > /dev/null
if [ $? -eq 0 ]; then
sed -i "s/HOSTNAME=.*/HOSTNAME=$str_hostname/" $conf_file
else
echo "HOSTNAME=$str_hostname" >> $conf_file
fi
fi
}
str_os_type=$(get_os_type)
echo "os_type=$str_os_type"
if [ "$str_os_type" = "aix" ]; then
logger -t xcat "config_ops_bm_node dose not support AIX."
echo "config_ops_bm_node dose not support AIX."
exit 0
fi
#change the hostname
if [[ -n "$1" ]]; then
change_host_name $str_os_type $1
fi
#Add the openstack ip to the node
if [[ -n $2 ]]; then
ops_ip=$2
if [[ -z $3 ]]; then
logger -t xcat "config_ops_bm_node: Please specify the netmask."
echo "config_ops_bm_node: Please specify the netmask."
exit 1
else
ops_mask=$3
fi
#figure out the install nic
if [[ -n $MACADDRESS ]]; then
pos=0
#mac has the following format: 01:02:03:04:05:0E!node5|01:02:03:05:0F!node6-eth1
for x in `echo "$MACADDRESS" | tr "|" "\n"`
do
node=""
mac=""
pos=$((pos+1))
i=`expr index $x !`
if [[ $i -gt 0 ]]; then
node=`echo ${x##*!}`
mac_tmp=`echo ${x%%!*}`
else
mac_tmp=$x
fi
if [[ $pos -eq 1 ]]; then
mac1=$mac_tmp
fi
if [[ "$PRIMARYNIC" = "$mac_tmp" ]]; then
mac=$mac_tmp
break
fi
if [[ -z "$PRIMARYNIC" ]] || [[ "$PRIMARYNIC" = "mac" ]]; then
if [[ -z $node ]] || [[ "$node" = "$NODE" ]]; then
mac=$mac_tmp
break
fi
fi
done
if [[ -z $mac ]]; then
if [[ -z "$PRIMARYNIC" ]] || [[ "$PRIMARYNIC" = "mac" ]]; then
mac=$mac1 #if nothing mathes, take the first mac
else
nic=$PRIMARYNIC #or the primary nic itself is the nic
fi
fi
else
logger -t xcat "config_ops_bm_node: no mac addresses are defined in the mac table for the node $NODE"
echo "config_ops_bm_node: no mac addresses are defined in the mac table for the node $NODE"
index=$((index+1))
continue
fi
echo "mac=$mac"
#find the nic that has the mac
if [[ -z $nic ]]; then
#go to each nic to match the mac address
ret=`ifconfig |grep -i $mac 2>&1`;
if [ $? -eq 0 ]; then
nic=`echo $ret |head -n1|cut -d' ' -f 1`
else
logger -t xcat "config_ops_bm_node: The mac address for the network for $NODE is not defined."
echo "config_ops_bm_node: The mac address for the network for $NODE is not defined."
fi
fi
echo "nic=$nic"
#now setup the ip alias
setup_ip $str_os_type $nic:0 $ops_ip $ops_mask
fi
@@ -1,94 +0,0 @@
#!/bin/sh
# IBM(c) 2014 EPL license http://www.eclipse.org/legal/epl-v10.html
# xCAT post script for deconfiguring the openstack baremetal node.
# The format is:
# deconfig_ops_bm_node ops_ip
get_os_type()
{
#get os type
str_os_type=`uname | tr 'A-Z' 'a-z'`
str_temp=''
if [ "$str_os_type" = "linux" ];then
str_temp=`echo $OSVER | grep -E '(sles|suse)'`
if [ -f "/etc/debian_version" ];then
str_os_type="debian"
elif [ -f "/etc/SuSE-release" -o -n "$str_temp" ];then
str_os_type="sles"
else
str_os_type="redhat"
fi
else
str_os_type="aix"
fi
echo "$str_os_type"
}
#change hostname permanently
change_host_name()
{
str_os_type=$1
str_hostname=$2
hostname $str_hostname
if [ "$str_os_type" = "sles" ];then
echo "Persistently changing the hostname not implemented yet."
#debian ubuntu and rh7
elif [ -f "/etc/hostname" ];then
conf_file="/etc/hostname"
echo "$str_hostname" > $conf_file
else
conf_file="/etc/sysconfig/network"
if [ ! -f $conf_file ]; then
touch $conf_file
fi
grep 'HOSTNAME' $conf_file 2>&1 > /dev/null
if [ $? -eq 0 ]; then
sed -i "s/HOSTNAME=.*/HOSTNAME=$str_hostname/" $conf_file
else
echo "HOSTNAME=$str_hostname" >> $conf_file
fi
fi
}
str_os_type=$(get_os_type)
echo "os_type=$str_os_type"
if [ $str_os_type == "aix" ]; then
logger -t xcat "deconfig_ops_bm_node dose not support AIX."
echo "deconfig_ops_bm_node dose not support AIX."
exit 0
fi
#change the hostname
#hostname $NODE
change_host_name $str_os_type $NODE
#remove the openstack ip from the node
if [[ -n $1 ]]; then
ops_ip=$1
nic=$(ip addr | grep $ops_ip | awk '{print $NF}')
echo "nic=$nic, ops_ip=$ops_ip"
ifconfig $nic del $ops_ip
#delete the configuration file
if [ "$str_os_type" = "sles" ]; then
str_conf_file="/etc/sysconfig/network/ifcfg-$nic"
elif [ "$str_os_type" = "debian" ]; then #debian ubuntu
str_conf_file="/etc/network/interfaces.d/$nic"
else #redhat
str_conf_file="/etc/sysconfig/network-scripts/ifcfg-$nic"
fi
if [ -f $str_conf_file ]; then
rm $str_conf_file
fi
fi
@@ -1,102 +0,0 @@
Summary: Executables and data of the xCAT baremetal driver for OpenStack
Name: xCAT-OpenStack-baremetal
Version: %(cat Version)
Release: snap%(date +"%Y%m%d%H%M")
Epoch: 4
License: IBM
Group: Applications/System
Source: xCAT-OpenStack-baremetal-%{version}.tar.gz
Packager: IBM Corp.
Vendor: IBM Corp.
Distribution: %{?_distribution:%{_distribution}}%{!?_distribution:%{_vendor}}
Prefix: /opt/xcat
BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root
%ifos linux
BuildArch: noarch
%endif
Provides: xCAT-OpenStack-baremetal = %{epoch}:%{version}
Requires: xCAT-client
%description
xCAT-OpenStack-baremetal provides the baremetal driver for OpenStack.
%prep
%setup -q -n xCAT-OpenStack-baremetal
%build
# Convert pods to man pages and html pages
./xpod2man
%install
# The install phase puts all of the files in the paths they should be in when the rpm is
# installed on a system. The RPM_BUILD_ROOT is a simulated root file system and usually
# has a value like: /var/tmp/xCAT-OpenStack-baremetal-2.0-snap200802270932-root
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/%{prefix}/bin
mkdir -p $RPM_BUILD_ROOT/%{prefix}/sbin
mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_plugin
mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/python/xcat/openstack/baremetal
mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/xcat/openstack/postscripts
mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/man/man1
mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/doc/man1
set +x
cp -R lib/* $RPM_BUILD_ROOT/%{prefix}/lib
cp share/xcat/openstack/postscripts/* $RPM_BUILD_ROOT/%{prefix}/share/xcat/openstack/postscripts
# These were built dynamically in the build phase
cp share/man/man1/* $RPM_BUILD_ROOT/%{prefix}/share/man/man1
chmod 444 $RPM_BUILD_ROOT/%{prefix}/share/man/man1/*
# These were built dynamically during the build phase
cp share/doc/man1/* $RPM_BUILD_ROOT/%{prefix}/share/doc/man1
chmod 644 $RPM_BUILD_ROOT/%{prefix}/share/doc/man1/*
# These links get made in the RPM_BUILD_ROOT/prefix area
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/sbin/deploy_ops_bm_node
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/sbin/cleanup_ops_bm_node
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/opsaddbmnode
ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/opsaddimage
set -x
%clean
# This step does not happen until *after* the %files packaging below
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
#%doc LICENSE.html
# Just package everything that has been copied into RPM_BUILD_ROOT
%{prefix}
%changelog
%post
#copy the postscripts under /installl/postscripts directory on MN only
if [ -f "/etc/xCATMN" ]; then
cp $RPM_INSTALL_PREFIX0/share/xcat/openstack/postscripts/* /install/postscripts/
fi
%preun
#remove postscripts under /installl/postscripts directory on MN only
if [ -f "/etc/xCATMN" ]; then
for fn in $RPM_INSTALL_PREFIX0/share/xcat/openstack/postscripts/*
do
bn=`basename $fn`
rm /install/postscripts/$bn
done
fi
exit 0
-214
View File
@@ -1,214 +0,0 @@
#!/usr/bin/perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
# First builds the xCAT summary man page from Synopsis of each man page.
# Then converts all of the pod man pages into html (including links to each other)
# We assume that this script is run in the xCAT-vlan-2.0 dir, so everything is
# done relative to that.
use strict;
#use lib '.';
use Pod::Man;
use Pod::Html;
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $cachedir = '/tmp';
my @pods = getPodList($poddir);
#foreach (@pods) { print "$_\n"; } exit;
# Build the cmd overview page.
#writesummarypage("$poddir/man1/xcat.1.pod", @pods);
# Build the man page for each pod.
#mkdir($mandir) or die "Error: could not create $mandir.\n";
print "Converting PODs to man pages...\n";
foreach my $podfile (@pods) {
my $manfile = $podfile;
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
my $mdir = $manfile;
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
convertpod2man($podfile, $manfile, $section);
}
my @dummyPods = createDummyPods($poddir, \@pods);
# Build the html page for each pod.
#mkdir($htmldir) or die "Error: could not create $htmldir.\n";
print "Converting PODs to HTML pages...\n";
# have to clear the cache, because old entries can cause a problem
unlink("$cachedir/pod2htmd.tmp", "$cachedir/pod2htmi.tmp");
foreach my $podfile (@pods) {
my $htmlfile = $podfile;
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
my $hdir = $htmlfile;
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
#print "$podfile, $htmlfile, $poddir, $htmldir\n";
convertpod2html($podfile, $htmlfile, $poddir, $htmldir);
}
# Remove the dummy pods
unlink @dummyPods;
rmdir "$poddir/man7";
exit;
# To enable linking between the cmd man pages and the db man pages, need to:
# grep thru the cmd pods searching for references (L<>) to any section 5 man page
# if that pod does not exist, create an empty one that will satisfy pod2html
# keep track of all dummy pods created, so they can be removed later
sub createDummyPods {
my ($poddir, $pods) = @_;
my $cmd = "grep -r -E 'L<.+\\([57]\\)\\|.+\\.[57]>' " . $poddir;
#print "Running cmd: ", $cmd, "\n";
my @lines = `$cmd`;
if ($?) { print "Error running: $cmd\n"; print join('', @lines); }
#my @lines;
#system($cmd);
my @dummyPods;
foreach my $l (@lines) {
#print "$l\n";
my @matches = $l =~ /L<([^\(]+)\(([57])\)\|\1\.[57]>/g; # get all the matches in the line
# The above line should create the array with every other entry being the man page name
# and every other entry is the section # (5 or 7)
my $cmd;
while ($cmd=shift @matches) {
#foreach my $m (@matches) {
my $section = shift @matches;
my $filename = "$poddir/man$section/$cmd.$section.pod";
#print "$filename\n";
if (!(grep /^$filename$/, @$pods) && !(grep /^$filename$/, @dummyPods)) { push @dummyPods, $filename; }
}
}
# Create these empty files
print "Creating empty linked-to files: ", join(', ', @dummyPods), "\n";
mkdir "$poddir/man7";
foreach my $d (@dummyPods) {
if (!open(TMP, ">>$d")) { warn "Could not create dummy pod file $d ($!)\n"; }
else { close TMP; }
}
return @dummyPods;
}
# Recursively get the list of pod man page files.
sub getPodList {
my $poddir = shift;
my @files;
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
}
# Create the xcat man page that gives a summary description of each xcat cmd.
# Not used
sub writesummarypage {
my $file = shift; # relative path file name of the man page
# the rest of @_ contains the pod files that describe each cmd
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
print FILE <<'EOS1';
=head1 NAME
B<xcat> - extreme Cluster Administration Tool.
=head1 DESCRIPTION
Extreme Cluster Administration Toolkit (xCAT). xCAT is a scalable distributed computing management
and provisioning tool that provides a unified interface for hardware control, discovery, and
OS diskful/diskfree deployment.
=head1 XCAT DATABASE
All of the cluster configuration information is in the xCAT database. See L<xcatdb(5)|xcatdb.5> for
descriptions of every table in the database.
=head1 XCAT COMMANDS
What follows is a short description of each xCAT command. To get more information about a particular
command, see its man page. Note that the commands are listed in alphabetical order B<within each section>,
i.e. all the commands in section 1, then the commands in section 3, etc.
=over 12
EOS1
# extract the summary for each cmd from its man page
foreach my $manpage (@_) {
my ($sectionnum) = $manpage =~ /\.(\d+)\.pod$/;
# Suck in the whole file, then we will parse it.
open(MANPAGE, "$manpage") or die "Error: could not open $manpage for reading.\n";
my @contents = <MANPAGE>;
my $wholemanpage = join('', @contents);
close(MANPAGE);
# This regex matches: optional space, =head1, space, title, space, cmd, space, description, newline
my ($cmd, $description) = $wholemanpage =~ /^\s*=head1\s+\S+\s+(\S+)\s+(.+?)\n/si;
if (!defined($cmd)) { print "Warning: $manpage is not in a recognized structure. It will be ignored.\n"; next; }
if (!defined($description)) { print "Warning: $manpage does not have a description for $cmd. It will be ignored.\n"; next; }
$cmd =~ s/^.<(.+)>$/$1/; # if the cmd name has pod formatting around it, strip it off
$description =~ s/^-\s*//; # if the description has a leading hypen, strip it off
print FILE "\n=item L<$cmd($sectionnum)|$cmd.$sectionnum>\n\n".$description."\n";
}
# Artificially add the xcattest cmd, because the xCAT-test rpm will add this
print FILE "\n=item L<xcattest(1)|xcattest.1>\n\nRun automated xCAT test cases.\n";
print FILE <<"EOS3";
=back
EOS3
close FILE;
}
# Create the html page for one pod.
sub convertpod2html {
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man1",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
}
# Create the man page for one pod.
sub convertpod2man {
my ($podfile, $manfile, $section) = @_;
my $parser = Pod::Man->new(section => $section);
$parser->parse_from_file($podfile, $manfile);
}
@@ -1,6 +0,0 @@
include AUTHORS
include ChangeLog
exclude .gitignore
exclude .gitreview
global-exclude *.pyc
@@ -1,44 +0,0 @@
xCAT Driver for ironic x86/64 machine
==================================
xCAT is a Extreme Cluster/Cloud Administration Toolkit. We can use xcat
to do :
1 hardward discoveery
2 remote hardware control
3 remote sonsole
4 hardware inventory
5 firmware flashing
Ironic is a project in Openstack, it will replace the nova-baremetal in juno release. Ironic's design is very flexable, we can add driver to extend function
without change any code in Openstack. Ironic xCAT driver takes the advantage of xcat and openstack, we can use it to deploy the baremetal machine very easily.
Before using this driver, we must setup the openstack environment at least for two nodes( ironic conductor and neutron network node can't setup on the same node)
Ironic conductor and the baremetal node( waiting for deploy) must in the same vlan
Add the follows in the ironic egg-info entry_points.txt file (ironic.drivers section)
pxe_xcat = ironic.drivers.xcat:XCATBaremetalDriver
When the openstack with ironic is ready, just execute command in the ironic_xcat directory as follows:
$ python setup.py install
Restart the ironic-conductor process
Initialize the xcat environment according to http://sourceforge.net/p/xcat/wiki/XCAT_iDataPlex_Cluster_Quick_Start/
Using xCAT baremetal driver need config site table and run copycds to generate image. The node definition is not requirement.
Ironic use neutron as the network service.
Check the openvswitch config on the network node ,make sure brbm bridge connect to the baremetal node.
==================================================================================
Some Example to use the xCAT baremetal driver.
$touch /tmp/rhelhpc6.5-x86_64-install-compute.qcow2;glance image-create --name rhelhpc6.5-x86_64-install-compute --public --disk-format qcow2 --container-format bare --property xcat_image_name='rhels6.4-x86_64-install-compute' < /tmp/rhelhpc6.5-x86_64-install-compute.qcow2
--name rhelhpc6.5-x86_64-install-compute is the image name in xcat. You can use lsdef -t osimage on the ironic-conductor node which xcat is installed.
$ ironic node-create --driver pxe_xcat -i ipmi_address=xxx.xxx.xxx.xxx -i ipmi_username=userid -i ipmi_password=password -i xcat_node=x3550m4n02 -i xcatmaster=10.1.0.241 -i netboot=xnba -i ipmi_terminal_port=0 -p memory_mb=2048 -p cpus=8
$ ironic port-create --address ff:ff:ff:ff:ff:ff --node_uuid <ironic node uuid>
$ nova boot --flavor baremetal --image <image-id> testing --nic net-id=<internal network id>
@@ -1,25 +0,0 @@
"""xCAT baremtal exceptions.
"""
from oslo.config import cfg
import six
from ironic.openstack.common.gettextutils import _
from ironic.openstack.common import log as logging
from ironic.common.exception import IronicException
LOG = logging.getLogger(__name__)
class xCATCmdFailure(IronicException):
message = _("xcat call failed: %(cmd)s %(node)s %(args)s.")
class xCATDeploymentFailure(IronicException):
message = _("xCAT node deployment failed for node %(node)s:%(error)s")
class GetNetworkFixedIPFailure(IronicException):
message = _("get fixed ip failed for mac %(mac_address)s")
class GetNetworkIdFailure(IronicException):
message = _("get node network in failed for mac %(mac_address)s")
class FailedToGetInfoOnPort(IronicException):
message = _("Show info on port: %(port_id)s failed.")
@@ -1,41 +0,0 @@
"""
Get the network from neutron
This is a xcat patch for the ironic/common/neutron.py
"""
from neutronclient.common import exceptions as neutron_client_exc
from ironic.common import exception
from ironic.openstack.common import log as logging
from ironic.common import neutron
from ironic.drivers.modules import xcat_exception
LOG = logging.getLogger(__name__)
def get_vif_port_info(task, port_id):
""" Get detail port info from neutron with a given port id """
api = neutron.NeutronAPI(task.context)
try:
port_info = api.client.show_port(port_id)
except neutron_client_exc.NeutronClientException:
LOG.exception(_("Failed to get port info %s."), port_id)
raise exception.FailedToGetInfoOnPort(port_id=port_id)
return port_info
def get_ports_info_from_neutron(task):
""" Get neutron port info from neutron about this task """
vifs = neutron.get_node_vif_ids(task)
if not vifs:
LOG.warning(_("No VIFs found for node %(node)s when attempting to "
"update Neutron DHCP BOOT options."),
{'node': task.node.uuid})
return
failures = []
vif_ports_info = {}
for port_id, port_vif in vifs.iteritems():
try:
vif_ports_info[port_id] = get_vif_port_info(task,port_vif)
except xcat_exception.FailedToGetInfoOnPort(port_id=port_vif):
failures.append(port_vif)
return vif_ports_info
@@ -1,462 +0,0 @@
"""
pxe procedure for the xcat baremetal driver
use xcat to config dhcp and tftp
"""
import os
import time
import paramiko
import datetime
from oslo.config import cfg
from ironic.common import exception
from ironic.common import image_service as service
from ironic.common import keystone
from ironic.common import states
from ironic.common import utils
from ironic.conductor import task_manager
from ironic.conductor import utils as manager_utils
from ironic.drivers import base
from ironic.drivers import utils as driver_utils
from ironic.openstack.common import log as logging
from ironic.openstack.common import strutils
from ironic.drivers.modules import xcat_neutron
from ironic.drivers.modules import xcat_util
from ironic.openstack.common import loopingcall
from nova.openstack.common import timeutils
from ironic.openstack.common import lockutils
from ironic.drivers.modules import xcat_exception
pxe_opts = [
cfg.StrOpt('pxe_append_params',
default='nofb nomodeset vga=normal',
help='Additional append parameters for baremetal PXE boot.'),
cfg.StrOpt('default_ephemeral_format',
default='ext4',
help='Default file system format for ephemeral partition, '
'if one is created.'),
]
xcat_opts = [
cfg.StrOpt('network_node_ip',
default='127.0.0.1',
help='IP address of neutron network node'),
cfg.StrOpt('ssh_user',
default='root',
help='Username of neutron network node.'),
cfg.StrOpt('ssh_password',
default='cluster',
help='Password of neutron network node'),
cfg.IntOpt('ssh_port',
default=22,
help='ssh connection port for the neutron '),
cfg.StrOpt('host_filepath',
default='/etc/hosts',
help='host file of server'),
cfg.IntOpt('deploy_timeout',
default=3600,
help='max depolyment time(seconds) for the xcat driver'),
cfg.IntOpt('deploy_checking_interval',
default=30,
help='interval time(seconds) to check the xcat deploy state'),
]
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
CONF.register_opts(pxe_opts, group='pxe')
CONF.register_opts(xcat_opts, group='xcat')
CONF.import_opt('use_ipv6', 'ironic.netconf')
REQUIRED_PROPERTIES = {
'pxe_deploy_kernel': _("UUID (from Glance) of the deployment kernel. "
"Required."),
'pxe_deploy_ramdisk': _("UUID (from Glance) of the ramdisk that is "
"mounted at boot time. Required."),
}
COMMON_PROPERTIES = REQUIRED_PROPERTIES
EM_SEMAPHORE = 'xcat_pxe'
def _check_for_missing_params(info_dict, param_prefix=''):
missing_info = []
for label, value in info_dict.items():
if not value:
missing_info.append(param_prefix + label)
if missing_info:
raise exception.InvalidParameterValue(_(
"Can not validate PXE bootloader. The following parameters "
"were not passed to ironic: %s") % missing_info)
def _parse_driver_info(node):
"""Gets the driver specific Node deployment info.
This method validates whether the 'driver_info' property of the
supplied node contains the required information for this driver to
deploy images to the node.
:param node: a single Node.
:returns: A dict with the driver_info values.
"""
info = node.driver_info
d_info = {}
d_info['xcat_node'] = info.get('xcat_node')
return d_info
def _parse_instance_info(node):
"""Gets the instance specific Node deployment info.
This method validates whether the 'instance_info' property of the
supplied node contains the required information for this driver to
deploy images to the node.
:param node: a single Node.
:returns: A dict with the instance_info values.
"""
info = node.instance_info
i_info = {}
i_info['image_source'] = info.get('image_source')
i_info['root_gb'] = info.get('root_gb')
i_info['image_file'] = i_info['image_source']
_check_for_missing_params(i_info)
# Internal use only
i_info['deploy_key'] = info.get('deploy_key')
i_info['swap_mb'] = info.get('swap_mb', 0)
i_info['ephemeral_gb'] = info.get('ephemeral_gb', 0)
i_info['ephemeral_format'] = info.get('ephemeral_format')
err_msg_invalid = _("Can not validate PXE bootloader. Invalid parameter "
"%(param)s. Reason: %(reason)s")
for param in ('root_gb', 'swap_mb', 'ephemeral_gb'):
try:
int(i_info[param])
except ValueError:
reason = _("'%s' is not an integer value.") % i_info[param]
raise exception.InvalidParameterValue(err_msg_invalid %
{'param': param, 'reason': reason})
if i_info['ephemeral_gb'] and not i_info['ephemeral_format']:
i_info['ephemeral_format'] = CONF.pxe.default_ephemeral_format
preserve_ephemeral = info.get('preserve_ephemeral', False)
try:
i_info['preserve_ephemeral'] = strutils.bool_from_string(
preserve_ephemeral, strict=True)
except ValueError as e:
raise exception.InvalidParameterValue(err_msg_invalid %
{'param': 'preserve_ephemeral', 'reason': e})
return i_info
def _parse_deploy_info(node):
"""Gets the instance and driver specific Node deployment info.
This method validates whether the 'instance_info' and 'driver_info'
property of the supplied node contains the required information for
this driver to deploy images to the node.
:param node: a single Node.
:returns: A dict with the instance_info and driver_info values.
"""
info = {}
info.update(_parse_instance_info(node))
info.update(_parse_driver_info(node))
return info
def _validate_glance_image(ctx, deploy_info):
"""Validate the image in Glance.
Check if the image exist in Glance and if it contains the
'kernel_id' and 'ramdisk_id' properties.
:raises: InvalidParameterValue.
"""
image_id = deploy_info['image_source']
if not image_id:
raise exception.ImageNotFound
class PXEDeploy(base.DeployInterface):
"""PXE Deploy Interface: just a stub until the real driver is ported."""
def get_properties(self):
return COMMON_PROPERTIES
def validate(self, task):
"""Validate the deployment information for the task's node.
:param task: a TaskManager instance containing the node to act on.
:raises: InvalidParameterValue.
"""
node = task.node
if not driver_utils.get_node_mac_addresses(task):
raise exception.InvalidParameterValue(_("Node %s does not have "
"any port associated with it.") % node.uuid)
d_info = _parse_deploy_info(node)
# Try to get the URL of the Ironic API
try:
# TODO(lucasagomes): Validate the format of the URL
CONF.conductor.api_url or keystone.get_service_url()
except (exception.CatalogFailure,
exception.CatalogNotFound,
exception.CatalogUnauthorized):
raise exception.InvalidParameterValue(_(
"Couldn't get the URL of the Ironic API service from the "
"configuration file or keystone catalog."))
_validate_glance_image(task.context, d_info)
@task_manager.require_exclusive_lock
def deploy(self, task):
"""Start deployment of the task's node'.
Config host file and xcat dhcp, generate image info for xcat
and issues a reboot request to the power driver.
This causes the node to boot into the deployment ramdisk and triggers
the next phase of PXE-based deployment via
VendorPassthru._continue_deploy().
:param task: a TaskManager instance containing the node to act on.
:returns: deploy state DEPLOYDONE.
"""
d_info = _parse_deploy_info(task.node)
if not task.node.instance_info.get('fixed_ip_address') or not task.node.instance_info.get('image_name'):
raise exception.InvalidParameterValue
self._config_host_file(d_info,task.node.instance_info.get('fixed_ip_address'))
self._make_dhcp()
self._nodeset_osimage(d_info,task.node.instance_info.get('image_name'))
manager_utils.node_set_boot_device(task, 'pxe', persistent=True)
manager_utils.node_power_action(task, states.REBOOT)
try:
self._wait_for_node_deploy(task)
except xcat_exception.xCATDeploymentFailure:
LOG.info(_("xcat deployment failed"))
return states.ERROR
return states.DEPLOYDONE
@task_manager.require_exclusive_lock
def tear_down(self, task):
"""Tear down a previous deployment on the task's node.
Power off the node. All actual clean-up is done in the clean_up()
method which should be called separately.
:param task: a TaskManager instance containing the node to act on.
:returns: deploy state DELETED.
"""
manager_utils.node_power_action(task, states.POWER_OFF)
return states.DELETED
def prepare(self, task):
"""Prepare the deployment environment for this task's node.
Get the image info from glance, config the mac for the xcat
use ssh and iptables to disable dhcp on network node
:param task: a TaskManager instance containing the node to act on.
"""
# TODO(deva): optimize this if rerun on existing files
d_info = _parse_deploy_info(task.node)
i_info = task.node.instance_info
image_id = d_info['image_source']
try:
glance_service = service.Service(version=1, context=task.context)
image_name = glance_service.show(image_id)['name']
i_info['image_name'] = image_name
except (exception.GlanceConnectionFailed,
exception.ImageNotAuthorized,
exception.Invalid):
LOG.warning(_("Failed to connect to Glance to get the properties "
"of the image %s") % image_id)
node_mac_addresses = driver_utils.get_node_mac_addresses(task)
vif_ports_info = xcat_neutron.get_ports_info_from_neutron(task)
try:
network_info = self._get_deploy_network_info(vif_ports_info, node_mac_addresses)
except (xcat_exception.GetNetworkFixedIPFailure,xcat_exception.GetNetworkIdFailure):
LOG.error(_("Failed to get network info"))
return
if not network_info:
LOG.error(_("Failed to get network info"))
return
fixed_ip_address = network_info['fixed_ip_address']
deploy_mac_address = network_info['mac_address']
network_id = network_info['network_id']
i_info['fixed_ip_address'] = fixed_ip_address
i_info['network_id'] = network_id
i_info['deploy_mac_address'] = deploy_mac_address
# use iptables to drop the dhcp mac of baremetal machine
self._ssh_append_dhcp_rule(CONF.xcat.network_node_ip,CONF.xcat.ssh_port,CONF.xcat.ssh_user,
CONF.xcat.ssh_password,network_id,deploy_mac_address)
self._chdef_node_mac_address(d_info,deploy_mac_address)
def clean_up(self, task):
"""Clean up the deployment environment for the task's node.
Unlinks TFTP and instance images and triggers image cache cleanup.
Removes the TFTP configuration files for this node. As a precaution,
this method also ensures the keystone auth token file was removed.
:param task: a TaskManager instance containing the node to act on.
"""
pass
def take_over(self, task):
pass
def _get_deploy_network_info(self, vif_ports_info, valid_node_mac_addrsses):
"""Get network info from mac address of ironic node.
:param vif_ports_info: info collection from neutron ports
:param valid_node_mac_addrsses: mac address from ironic node
:raises: GetNetworkFixedIpFailure if search the fixed ip from mac address failure
:raises: GetNetworkIdFailure if search the network id from mac address failure
"""
network_info = {}
for port_info in vif_ports_info.values():
if(port_info['port']['mac_address'] in valid_node_mac_addrsses ):
network_info['fixed_ip_address'] = port_info['port']['fixed_ips'][0]['ip_address']
if not network_info['fixed_ip_address']:
raise xcat_exception.GetNetworkFixedIPFailure(mac_address=port_info['port']['mac_address'])
network_info['mac_address'] = port_info['port']['mac_address']
network_info['network_id'] = port_info['port']['network_id']
if not network_info['network_id']:
raise xcat_exception.GetNetworkIdFailure(mac_address=port_info['port']['mac_address'])
network_info['port_id'] = port_info['port']['id']
return network_info
return network_info
def _chdef_node_mac_address(self, driver_info, deploy_mac):
""" run chdef command to set mac address"""
cmd = 'chdef'
args = 'mac='+ deploy_mac
try:
out_err = xcat_util.exec_xcatcmd(driver_info, cmd, args)
LOG.info(_("xcat chdef cmd exetute output: %(out_err)s") % {'out_err':out_err})
except xcat_exception.xCATCmdFailure as e:
LOG.warning(_("xcat chdef failed for node %(xcat_node)s with "
"error: %(error)s.")
% {'xcat_node': driver_info['xcat_node'], 'error': e})
raise exception.IPMIFailure(cmd=cmd)
@lockutils.synchronized(EM_SEMAPHORE, 'xcat-hosts-')
def _config_host_file(self, driver_info, deploy_ip):
""" append node and ip infomation to host file"""
with open(CONF.xcat.host_filepath,"r+") as f:
lines = []
for line in f:
temp = line.split('#')
if temp[0].strip():
host_name = xcat_util._tsplit(temp[0].strip(),(' ','\t'))[1]
if driver_info['xcat_node'] not in host_name:
lines.append(line)
# append a new line to host file
line = "%s\t%s\n" %(deploy_ip,driver_info['xcat_node'])
lines.append(line)
f.seek(0)
f.truncate()
for line in lines:
f.write(line)
def _nodeset_osimage(self, driver_info, image_name):
"""run nodeset command to config the image for the xcat node
:param driver_info: xcat node deploy info
:param image_name: image for the xcat deployment
"""
cmd = 'nodeset'
args = 'osimage='+ image_name
try:
xcat_util.exec_xcatcmd(driver_info, cmd, args)
except xcat_exception.xCATCmdFailure as e:
LOG.warning(_("xcat nodeset failed for node %(xcat_node)s with "
"error: %(error)s.")
% {'xcat_node': driver_info['xcat_node'], 'error': e})
def _make_dhcp(self):
"""run makedhcp command to setup dhcp environment for the xcat node"""
cmd = ['makedhcp',
'-n'
]
try:
out, err = utils.execute(*cmd)
LOG.info(_(" excute cmd: %(cmd)s \n output: %(out)s \n. Error: %(err)s \n"),
{'cmd':cmd,'out': out, 'err': err})
except Exception as e:
LOG.error(_("Unable to execute %(cmd)s. Exception: %(exception)s"),
{'cmd': cmd, 'exception': e})
# makedhcp -a
cmd = ['makedhcp',
'-a'
]
try:
out, err = utils.execute(*cmd)
LOG.info(_(" excute cmd: %(cmd)s \n output: %(out)s \n. Error: %(err)s \n"),
{'cmd':cmd,'out': out, 'err': err})
except Exception as e:
LOG.error(_("Unable to execute %(cmd)s. Exception: %(exception)s"),
{'cmd': cmd, 'exception': e})
def _ssh_append_dhcp_rule(self,ip,port,username,password,network_id,mac_address):
""" drop the dhcp package in network node to avoid of confilct of dhcp """
netns = 'qdhcp-%s' %network_id
append_cmd = 'sudo ip netns exec %s iptables -A INPUT -m mac --mac-source %s -j DROP' % \
(netns,mac_address)
cmd = [append_cmd]
xcat_util.xcat_ssh(ip,port,username,password,cmd)
def _ssh_delete_dhcp_rule(self,ip,port,username,password,network_id,mac_address):
""" delete the iptable rule on network node to recover the environment"""
netns = 'qdhcp-%s' %network_id
cancel_cmd = 'sudo ip netns exec %s iptables -D INPUT -m mac --mac-source %s -j DROP' % \
(netns,mac_address)
cmd = [cancel_cmd]
xcat_util.xcat_ssh(ip,port,username,password,cmd)
def _wait_for_node_deploy(self, task):
"""Wait for xCAT node deployment to complete."""
locals = {'errstr':''}
driver_info = _parse_deploy_info(task.node)
node_mac_addrsses = driver_utils.get_node_mac_addresses(task)
i_info = task.node.instance_info
def _wait_for_deploy():
out,err = xcat_util.exec_xcatcmd(driver_info,'nodels','nodelist.status')
if err:
locals['errstr'] = _("Error returned when quering node status"
" for node %s:%s") % (driver_info['xcat_node'], err)
LOG.warning(locals['errstr'])
raise loopingcall.LoopingCallDone()
if out:
node,status = out.split(": ")
status = status.strip()
if status == "booted":
LOG.info(_("Deployment for node %s completed.")
% driver_info['xcat_node'])
raise loopingcall.LoopingCallDone()
if (CONF.xcat.deploy_timeout and
timeutils.utcnow() > expiration):
locals['errstr'] = _("Timeout while waiting for"
" deployment of node %s.") % driver_info['xcat_node']
LOG.warning(locals['errstr'])
raise loopingcall.LoopingCallDone()
expiration = timeutils.utcnow() + datetime.timedelta(
seconds=CONF.xcat.deploy_timeout)
timer = loopingcall.FixedIntervalLoopingCall(_wait_for_deploy)
# default check every 10 seconds
timer.start(interval=CONF.xcat.deploy_checking_interval).wait()
if locals['errstr']:
raise xcat_exception.xCATDeploymentFailure(locals['errstr'])
# deploy end, delete the dhcp rule for xcat
self._ssh_delete_dhcp_rule(CONF.xcat.network_node_ip,CONF.xcat.ssh_port,CONF.xcat.ssh_user,
CONF.xcat.ssh_password,i_info['network_id'],node_mac_addrsses[0])
@@ -1,444 +0,0 @@
"""
IPMI power manager driver.
"""
import contextlib
import os
import stat
import tempfile
import time
from oslo.config import cfg
from ironic.common import exception
from ironic.common import states
from ironic.common import utils
from ironic.conductor import task_manager
from ironic.drivers import base
from ironic.drivers.modules import console_utils
from ironic.openstack.common import excutils
from ironic.openstack.common import log as logging
from ironic.openstack.common import loopingcall
from ironic.openstack.common import processutils
from ironic.drivers.modules import xcat_exception
from ironic.drivers.modules import xcat_util
CONF = cfg.CONF
CONF.import_opt('retry_timeout',
'ironic.drivers.modules.ipminative',
group='ipmi')
CONF.import_opt('min_command_interval',
'ironic.drivers.modules.ipminative',
group='ipmi')
LOG = logging.getLogger(__name__)
VALID_PRIV_LEVELS = ['ADMINISTRATOR', 'CALLBACK', 'OPERATOR', 'USER']
REQUIRED_PROPERTIES = {
'ipmi_address': _("IP address or hostname of the node. Required.")
}
OPTIONAL_PROPERTIES = {
'ipmi_password': _("password. Optional."),
'ipmi_priv_level': _("privilege level; default is ADMINISTRATOR. One of "
"%s. Optional.") % ', '.join(VALID_PRIV_LEVELS),
'ipmi_username': _("username; default is NULL user. Optional.")
}
COMMON_PROPERTIES = REQUIRED_PROPERTIES.copy()
COMMON_PROPERTIES.update(OPTIONAL_PROPERTIES)
CONSOLE_PROPERTIES = {
'ipmi_terminal_port': _("node's UDP port to connect to. Only required for "
"console access.")
}
TIMING_SUPPORT = None
def _is_timing_supported(is_supported=None):
# shim to allow module variable to be mocked in unit tests
global TIMING_SUPPORT
if (TIMING_SUPPORT is None) and (is_supported is not None):
TIMING_SUPPORT = is_supported
return TIMING_SUPPORT
def check_timing_support():
"""Check the installed version of ipmitool for -N -R option support.
Support was added in 1.8.12 for the -N -R options, which enable
more precise control over timing of ipmi packets. Prior to this,
the default behavior was to retry each command up to 18 times at
1 to 5 second intervals.
http://ipmitool.cvs.sourceforge.net/viewvc/ipmitool/ipmitool/ChangeLog?revision=1.37 # noqa
This method updates the module-level TIMING_SUPPORT variable so that
it is accessible by any driver interface class in this module. It is
intended to be called from the __init__ method of such classes only.
:returns: boolean indicating whether support for -N -R is present
:raises: OSError
"""
if _is_timing_supported() is None:
# Directly check ipmitool for support of -N and -R options. Because
# of the way ipmitool processes' command line options, if the local
# ipmitool does not support setting the timing options, the command
# below will fail.
try:
out, err = utils.execute(*['ipmitool', '-N', '0', '-R', '0', '-h'])
except processutils.ProcessExecutionError:
# the local ipmitool does not support the -N and -R options.
_is_timing_supported(False)
else:
# looks like ipmitool supports timing options.
_is_timing_supported(True)
def _console_pwfile_path(uuid):
"""Return the file path for storing the ipmi password for a console."""
file_name = "%(uuid)s.pw" % {'uuid': uuid}
return os.path.join(tempfile.gettempdir(), file_name)
def _parse_driver_info(node):
"""Gets the parameters required for ipmitool to access the node.
:param node: the Node of interest.
:returns: dictionary of parameters.
:raises: InvalidParameterValue if any required parameters are missing.
"""
info = node.driver_info or {}
address = info.get('ipmi_address')
username = info.get('ipmi_username')
password = info.get('ipmi_password')
port = info.get('ipmi_terminal_port')
priv_level = info.get('ipmi_priv_level', 'ADMINISTRATOR')
xcat_node = info.get('xcat_node')
xcatmaster = info.get('xcatmaster')
netboot = info.get('netboot')
if port:
try:
port = int(port)
except ValueError:
raise exception.InvalidParameterValue(_(
"IPMI terminal port is not an integer."))
if not address:
raise exception.InvalidParameterValue(_(
"IPMI address not supplied to xcat driver."))
if priv_level not in VALID_PRIV_LEVELS:
valid_priv_lvls = ', '.join(VALID_PRIV_LEVELS)
raise exception.InvalidParameterValue(_(
"Invalid privilege level value:%(priv_level)s, the valid value"
" can be one of %(valid_levels)s") %
{'priv_level': priv_level, 'valid_levels': valid_priv_lvls})
if not xcat_node:
raise exception.InvalidParameterValue(_(
"xcat node name not supplied to xcat driver"))
if not xcatmaster:
raise exception.InvalidParameterValue(_(
"xcatmaster not supplied to xcat driver"))
if not netboot:
raise exception.InvalidParameterValue(_(
"netboot not supplied to xcat driver"))
return {
'address': address,
'username': username,
'password': password,
'port': port,
'uuid': node.uuid,
'priv_level': priv_level,
'xcat_node': xcat_node,
'xcatmaster': xcatmaster,
'netboot': netboot
}
def chdef_node(driver_info):
"""Run the chdef command in xcat, config the node
:param driver_info: driver_info for the xcat node
"""
cmd = 'chdef'
args = 'mgt=ipmi' + \
' bmc=' + driver_info['address'] + \
' bmcusername=' + driver_info['username'] + \
' bmcpassword=' + driver_info['password'] + \
' xcatmaster=' + driver_info['xcatmaster']+ \
' netboot=' + driver_info['netboot']+ \
' primarynic=mac'+ \
' installnic=mac'+ \
' monserver=' + driver_info['xcatmaster'] + \
' nfsserver=' + driver_info['xcatmaster'] + \
' serialflow=hard'+ \
' serialspeed=115200' + \
' serialport=' + str(driver_info['port']);
try:
xcat_util.exec_xcatcmd(driver_info, cmd, args)
except xcat_exception.xCATCmdFailure as e:
LOG.warning(_("xcat chdef failed for node %(node_id)s with "
"error: %(error)s.")
% {'node_id': driver_info['uuid'], 'error': e})
def _sleep_time(iter):
"""Return the time-to-sleep for the n'th iteration of a retry loop.
This implementation increases exponentially.
:param iter: iteration number
:returns: number of seconds to sleep
"""
if iter <= 1:
return 1
return iter ** 2
def _set_and_wait(target_state, driver_info):
"""Helper function for DynamicLoopingCall.
This method changes the power state and polls the BMCuntil the desired
power state is reached, or CONF.ipmi.retry_timeout would be exceeded by the
next iteration.
This method assumes the caller knows the current power state and does not
check it prior to changing the power state. Most BMCs should be fine, but
if a driver is concerned, the state should be checked prior to calling this
method.
:param target_state: desired power state
:param driver_info: the ipmitool parameters for accessing a node.
:returns: one of ironic.common.states
:raises: IPMIFailure on an error from ipmitool (from _power_status call).
"""
if target_state == states.POWER_ON:
state_name = "on"
elif target_state == states.POWER_OFF:
state_name = "off"
def _wait(mutable):
try:
# Only issue power change command once
if mutable['iter'] < 0:
xcat_util.exec_xcatcmd(driver_info,'rpower',state_name)
else:
mutable['power'] = _power_status(driver_info)
except Exception:
# Log failures but keep trying
LOG.warning(_("xcat rpower %(state)s failed for node %(node)s."),
{'state': state_name, 'node': driver_info['uuid']})
finally:
mutable['iter'] += 1
if mutable['power'] == target_state:
raise loopingcall.LoopingCallDone()
sleep_time = _sleep_time(mutable['iter'])
if (sleep_time + mutable['total_time']) > CONF.ipmi.retry_timeout:
# Stop if the next loop would exceed maximum retry_timeout
LOG.error(_('xcat rpower %(state)s timed out after '
'%(tries)s retries on node %(node_id)s.'),
{'state': state_name, 'tries': mutable['iter'],
'node_id': driver_info['uuid']})
mutable['power'] = states.ERROR
raise loopingcall.LoopingCallDone()
else:
mutable['total_time'] += sleep_time
return sleep_time
# Use mutable objects so the looped method can change them.
# Start 'iter' from -1 so that the first two checks are one second apart.
status = {'power': None, 'iter': -1, 'total_time': 0}
timer = loopingcall.DynamicLoopingCall(_wait, status)
timer.start().wait()
return status['power']
def _power_on(driver_info):
"""Turn the power ON for this node.
:param driver_info: the xcat parameters for accessing a node.
:returns: one of ironic.common.states POWER_ON or ERROR.
:raises: IPMIFailure on an error from ipmitool (from _power_status call).
"""
return _set_and_wait(states.POWER_ON, driver_info)
def _power_off(driver_info):
"""Turn the power OFF for this node.
:param driver_info: the xcat parameters for accessing a node.
:returns: one of ironic.common.states POWER_OFF or ERROR.
:raises: IPMIFailure on an error from ipmitool (from _power_status call).
"""
return _set_and_wait(states.POWER_OFF, driver_info)
def _power_status(driver_info):
"""Get the power status for a node.
:param driver_info: the xcat access parameters for a node.
:returns: one of ironic.common.states POWER_OFF, POWER_ON or ERROR.
:raises: IPMIFailure on an error from ipmitool.
"""
cmd = "rpower"
try:
out_err = xcat_util.exec_xcatcmd(driver_info,cmd,'status')
except Exception as e:
LOG.warning(_("xcat rpower status failed for node %(node_id)s with "
"error: %(error)s.")
% {'node_id': driver_info['uuid'], 'error': e})
if out_err[0].split(' ')[1].strip() == "on":
return states.POWER_ON
elif out_err[0].split(' ')[1].strip() == "off":
return states.POWER_OFF
else:
return states.ERROR
class XcatPower(base.PowerInterface):
def __init__(self):
try:
check_timing_support()
except OSError:
raise exception.DriverLoadError(
driver=self.__class__.__name__,
reason="Unable to locate usable xcat command in "
"the system path when checking xcat version")
def get_properties(self):
return COMMON_PROPERTIES
def validate(self, task):
"""Validate driver_info for xcat driver.
Check that node['driver_info'] contains IPMI credentials.
:param task: a TaskManager instance containing the node to act on.
:raises: InvalidParameterValue if required ipmi parameters are missing.
"""
driver_info = _parse_driver_info(task.node)
try:
chdef_node(driver_info)
except exception:
LOG.error(_("chdef xcat info error!"))
def get_power_state(self, task):
"""Get the current power state of the task's node.
:param task: a TaskManager instance containing the node to act on.
:returns: one of ironic.common.states POWER_OFF, POWER_ON or ERROR.
"""
driver_info = _parse_driver_info(task.node)
return _power_status(driver_info)
@task_manager.require_exclusive_lock
def set_power_state(self, task, pstate):
"""Turn the power on or off.
:param task: a TaskManager instance containing the node to act on.
:param pstate: The desired power state, one of ironic.common.states
POWER_ON, POWER_OFF.
:raises: InvalidParameterValue if required ipmi parameters are missing
or if an invalid power state was specified.
:raises: PowerStateFailure if the power couldn't be set to pstate.
"""
driver_info = _parse_driver_info(task.node)
if pstate == states.POWER_ON:
state = _power_on(driver_info)
elif pstate == states.POWER_OFF:
state = _power_off(driver_info)
else:
raise exception.InvalidParameterValue(_("set_power_state called "
"with invalid power state %s.") % pstate)
if state != pstate:
raise exception.PowerStateFailure(pstate=pstate)
@task_manager.require_exclusive_lock
def reboot(self, task):
"""Cycles the power to the task's node.
:param task: a TaskManager instance containing the node to act on.
:raises: InvalidParameterValue if required ipmi parameters are missing.
:raises: PowerStateFailure if the final state of the node is not
POWER_ON.
"""
driver_info = _parse_driver_info(task.node)
_power_off(driver_info)
state = _power_on(driver_info)
if state != states.POWER_ON:
raise exception.PowerStateFailure(pstate=states.POWER_ON)
class IPMIShellinaboxConsole(base.ConsoleInterface):
"""A ConsoleInterface that uses ipmitool and shellinabox."""
def __init__(self):
try:
check_timing_support()
except OSError:
raise exception.DriverLoadError(
driver=self.__class__.__name__,
reason="Unable to locate usable xcat command in "
"the system path when checking xcat version")
def get_properties(self):
return COMMON_PROPERTIES
def validate(self, task):
"""Validate the Node console info.
:param task: a task from TaskManager.
:raises: InvalidParameterValue
"""
driver_info = _parse_driver_info(task.node)
if not driver_info['xcat_node']:
raise exception.InvalidParameterValue(_(
"xcat node name not supplied to xcat baremetal driver."))
if not driver_info['port']:
raise exception.InvalidParameterValue(_(
"IPMI terminal port not supplied to IPMI driver."))
def start_console(self, task):
"""Start a remote console for the node."""
driver_info = _parse_driver_info(task.node)
path = _console_pwfile_path(driver_info['uuid'])
pw_file = console_utils.make_persistent_password_file(
path, driver_info['password'])
ipmi_cmd = "/:%(uid)s:%(gid)s:HOME:ipmitool -H %(address)s" \
" -I lanplus -U %(user)s -f %(pwfile)s" \
% {'uid': os.getuid(),
'gid': os.getgid(),
'address': driver_info['address'],
'user': driver_info['username'],
'pwfile': pw_file}
if CONF.debug:
ipmi_cmd += " -v"
ipmi_cmd += " sol activate"
console_utils.start_shellinabox_console(driver_info['uuid'],
driver_info['port'],
ipmi_cmd)
def stop_console(self, task):
"""Stop the remote console session for the node."""
driver_info = _parse_driver_info(task.node)
console_utils.stop_shellinabox_console(driver_info['uuid'])
utils.unlink_without_raise(_console_pwfile_path(driver_info['uuid']))
def get_console(self, task):
"""Get the type and connection information about the console."""
driver_info = _parse_driver_info(task.node)
url = console_utils.get_shellinabox_console_url(driver_info['port'])
return {'type': 'shellinabox', 'url': url}
@@ -1,110 +0,0 @@
"""
util for xcat baremetal driver
exec_xcatcmd
xcat_ssh to excute remote cmd
"""
import paramiko
import time
import socket
from ironic.openstack.common import log as logging
from oslo.config import cfg
from ironic.drivers.modules import xcat_exception
from ironic.common import utils
xcat_opts = [
cfg.IntOpt('ssh_session_timeout',
default=10,
help='ssh session time'),
cfg.FloatOpt('ssh_shell_wait',
default=0.5,
help='wait time for the ssh cmd excute'),
cfg.IntOpt('ssh_buf_size',
default=65535,
help='Maximum size (in charactor) of cache for ssh, '
'including those in use'),
cfg.StrOpt('ssh_key',
default=None,
help='ssh private key to login '),
cfg.StrOpt('ssh_key_pass',
default=None,
help='Maximum size (in charactor) of cache for ssh, '
'including those in use'),
]
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
CONF.register_opts(xcat_opts, group='xcat')
LAST_CMD_TIME = {}
def xcat_ssh(ip,port,username,password,cmd):
""" exec remote command with ssh """
key =None
if CONF.xcat.ssh_key:
try:
key=paramiko.RSAKey.from_private_key_file(CONF.xcat.ssh_key)
except paramiko.PasswordRequiredException:
if not CONF.ssh_key_pass:
raise Exception.message("no pubkey password")
key = paramiko.RSAKey.from_private_key_file(
CONF.xcat.ssh_key, CONF.xcat.ssh_key.ssh_key_pass)
s = paramiko.SSHClient()
s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
s.connect(ip,port,username=username,password=password,pkey=key,
timeout=CONF.xcat.ssh_session_timeout)
except socket.timeout as e:
LOG.error(_("Unable to connect to the ssh server Exception: %(exception)s"),
{'exception': e})
chan = s.invoke_shell()
output = chan.recv(CONF.xcat.ssh_buf_size)
while not output.rstrip().endswith('#') and not output.rstrip().endswith('$'):
output = chan.recv(CONF.xcat.ssh_buf_size)
for c in cmd :
_xcat_ssh_exec(chan,c,password)
def _xcat_ssh_exec(chan,cmd,password):
""" exec ssh command """
chan.send(cmd + '\n')
time.sleep(CONF.xcat.ssh_shell_wait)
ret = chan.recv(CONF.xcat.ssh_buf_size)
if 'password' in ret and ret.rstrip().endswith(':'):
chan.send(password + '\n')
output = chan.recv(CONF.xcat.ssh_buf_size)
while not output.rstrip().endswith('#') and not output.rstrip().endswith('$'):
output = chan.recv(CONF.xcat.ssh_buf_size)
return output
def _tsplit(string, delimiters):
""" Behaves str.split but supports multiple delimiters. """
delimiters = tuple(delimiters)
stack = [string,]
for delimiter in delimiters:
for i, substring in enumerate(stack):
substack = substring.split(delimiter)
stack.pop(i)
for j, _substring in enumerate(substack):
stack.insert(i+j, _substring)
return stack
def exec_xcatcmd(driver_info, command, args):
""" excute xcat cmd """
cmd = [command,
driver_info['xcat_node']
]
cmd.extend(args.split(" "))
# NOTE: ensure that no communications are excuted more
# often than once every min_command_interval seconds.
time_till_next_poll = CONF.ipmi.min_command_interval - (
time.time() - LAST_CMD_TIME.get(driver_info['xcat_node'], 0))
if time_till_next_poll > 0:
time.sleep(time_till_next_poll)
try:
out, err = utils.execute(*cmd)
if err:
raise xcat_exception.xCATCmdFailure(cmd=cmd,node=driver_info['xcat_node'],
args=args)
finally:
LAST_CMD_TIME[driver_info['xcat_node']] = time.time()
return out, err
@@ -1,27 +0,0 @@
"""
XCATBaremetalDriver
use xcat to deploy a baremetal machine
"""
from ironic.drivers import base
from ironic.drivers.modules import ipmitool
from ironic.drivers.modules import pxe
from ironic.drivers.modules import xcat_pxe
from ironic.drivers import utils
from ironic.drivers.modules import xcat_rpower
class XCATBaremetalDriver(base.BaseDriver):
"""xCAT driver
This driver implements the `core` functionality, combinding
:class:`ironic.drivers.xcat_rpower.XcatPower` for power on/off and reboot with
:class:`ironic.driver.xcat_pxe.PXEDeploy` for image deployment. Implementations are in
those respective classes; this class is merely the glue between them.
"""
def __init__(self):
self.power = xcat_rpower.XcatPower()
self.console = ipmitool.IPMIShellinaboxConsole()
self.deploy = xcat_pxe.PXEDeploy()
self.management = ipmitool.IPMIManagement()
self.vendor = pxe.VendorPassthru()

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