2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-30 01:26:38 +00:00
Gᴏɴɢ Jie 4507a038ba Accumulated go-xcat updates (#4991)
* Fix vim modelines

* [go-xcat] Fix --long-help

* [go-xcat] Add curl support

* [go-xcat] Better tarball support

* [go-xcat] Explaination of --xcat-version argument in help message

* [go-xcat] Disable xCAT-core.repo and xCAT-dep.repo if they exist

* [go-xcat] Add change logs
2018-03-28 17:47:44 +08:00

1821 lines
46 KiB
Bash
Executable File

#!/bin/bash
#
# go-xcat - Install xCAT automatically.
#
# Version 1.0.27
#
# Copyright (C) 2016, 2017, 2018 International Business Machines
# Eclipse Public License, Version 1.0 (EPL-1.0)
# <http://www.eclipse.org/legal/epl-v10.html>
#
# 2016-06-16 GONG Jie <gongjie@linux.vnet.ibm.com>
# - Draft
# 2016-06-20 GONG Jie <gongjie@linux.vnet.ibm.com>
# - Released to the field
# 2016-09-20 GONG Jie <gongjie@linux.vnet.ibm.com>
# - Bug fix
# 2018-03-28 GONG Jie <gongjie@linux.vnet.ibm.com>
# - Use curl when it is available. Otherwise fall back to use wget
# - Improved tarball file extension handling
# - Disable xCAT-core.repo and xCAT-dep.repo if they exist
#
function usage()
{
local script="${0##*/}"
local version="$(version)"
while read -r ; do echo "${REPLY}" ; done <<-EOF
${script} version ${version}
Usage: ${script} [OPTION]... [ACTION]
Install xCAT automatically
Options:
Mandatory arguments to long options are mandatory for short options too.
-h, --help display this help and exit
--xcat-core=[URL] use a different URL or path for the xcat-core
repository
--xcat-dep=[URL] use a different URL or path for the xcat-dep
repository
-x, --xcat-version=[VERSION] specify the version of xCAT; imply the subdirectory
of corresponding xCAT version under
http://xcat.org/files/xcat/repos/yum/ or
http://xcat.org/files/xcat/repos/apt/
cannot use with --xcat-core
-y, --yes answer yes for all questions
Actions:
install installs all the latest versions of xcat-core
and xcat-dep packages from the repository
update updates installed xcat-core packages to the
latest version from the repository
Examples:
${script}
${script} install
${script} update
${script} --yes install
${script} -x 2.12 -y install
${script} --xcat-version=devel install
${script} --xcat-core=/path/to/xcat-core.tar.bz2 \\
--xcat-dep=/path/to/xcat-dep.tar.bz2 install
${script} --xcat-core=http://xcat.org/path/to/xcat-core.tar.bz2 \\
--xcat-dep=http://xcat.org/path/to/xcat-dep.tar.bz2 install
xCAT (Extreme Cloud/Cluster Administration Toolkit): <http://xcat.org/>
Full documentation at: <http://xcat-docs.readthedocs.io/en/stable/>
EOF
}
#
# verbose_usage This function be will be called when user run
# `go-xcat --long-help'.
# Including a bunch of secert usage.
#
function verbose_usage()
(
local script="${0##*/}"
exec 42< <(usage)
function println()
{
local -i i
for (( i = 0 ; i < "$1" ; ++i ))
do
read -r -u 42
[[ "$?" -ne "0" ]] && break
echo "${REPLY}"
done
}
println 7
println 1 >/dev/null # Drop a line
while read -r ; do echo "${REPLY}" ; done <<-EOF
-h, --help display a simply version of help and exit
--long-help display this help and exit
EOF
println 12
while read -r ; do echo "${REPLY}" ; done <<-EOF
check check the version of the installed packages
of xCAT and packages in the repository
EOF
println 2
while read -r ; do echo "${REPLY}" ; done <<-EOF
smoke-test preform basic tests of the xCAT installation
EOF
println 10
while read -r ; do echo "${REPLY}" ; done <<-EOF
${script} --xcat-core=/path/to/xcat-core.repo install
${script} --xcat-core=/path/to/xcat-core install
${script} --xcat-core=/path/to/xcat-core.tar install
${script} --xcat-core=/path/to/xcat-core.tar.Z install
${script} --xcat-core=/path/to/xcat-core.tar.gz install
${script} --xcat-core=/path/to/xcat-core.tar.bz2 install
${script} --xcat-core=/path/to/xcat-core.tar.xz install
${script} --xcat-core=http://xcat.org/path/to/xcat-core.repo install
${script} --xcat-core=http://xcat.org/path/to/xcat-core install
${script} --xcat-core=http://xcat.org/path/to/xcat-core.tar.bz2 install
${script} --xcat-core=/path/to/xcat-core.repo \\
--xcat-dep=/path/to/xcat-dep.repo install
${script} --xcat-core=/path/to/xcat-core \\
--xcat-dep=/path/to/xcat-dep install
EOF
println 999999 # Print out all the rest of lines
exec 42<&-
)
#
# version Print out the version number.
#
function version()
{
# Read the first ten lines of this script
for i in {0..9}
do
read -r
[[ ${REPLY} =~ \#\ +[Vv]ersion ]] && echo "${REPLY##* }" && return 0
done <"$0"
return 1
}
GO_XCAT_DEFAULT_BASE_URL="http://xcat.org/files/xcat/repos"
GO_XCAT_DEFAULT_INSTALL_PATH="/install/xcat"
# The package list of xcat-core
GO_XCAT_CORE_PACKAGE_LIST=()
GO_XCAT_DEP_PACKAGE_LIST=()
# The package list of all the packages should be installed
GO_XCAT_INSTALL_LIST=(perl-xCAT xCAT xCAT-buildkit xCAT-client
xCAT-genesis-scripts-ppc64 xCAT-genesis-scripts-x86_64 xCAT-server
conserver-xcat elilo-xcat grub2-xcat ipmitool-xcat syslinux-xcat
xCAT-genesis-base-ppc64 xCAT-genesis-base-x86_64 xnba-undi yaboot-xcat)
# For Debian/Ubuntu, it will need a sight different package list
type dpkg >/dev/null 2>&1 &&
GO_XCAT_INSTALL_LIST=(perl-xcat xcat xcat-buildkit xcat-client
xcat-genesis-scripts-amd64 xcat-genesis-scripts-ppc64 xcat-server
conserver-xcat elilo-xcat grub2-xcat ipmitool-xcat syslinux-xcat
xcat-genesis-base-amd64 xcat-genesis-base-ppc64 xnba-undi)
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
export PATH
#
# warn_if_bad Put out warning message(s) if $1 has bad RC.
#
# $1 0 (pass) or non-zero (fail).
# $2+ Remaining arguments printed only if the $1 is non-zero.
#
# Incoming $1 is returned unless it is 0
#
function warn_if_bad()
{
local -i rc="$1"
local script="${0##*/}"
# Ignore if no problems
[ "${rc}" -eq "0" ] && return 0
# Broken
shift
echo "${script}: $@" >&2
return "${rc}"
}
#
# exit_if_bad Put out error message(s) if $1 has bad RC.
#
# $1 0 (pass) or non-zero (fail).
# $2+ Remaining arguments printed only if the $1 is non-zero.
#
# Exits with 1 unless $1 is 0
#
function exit_if_bad()
{
warn_if_bad "$@" || exit 1
return 0
}
#
# check_root_or_exit
#
# Breaks the script if not running as root.
#
# If this returns 1, the invoker MUST abort the script.
#
# Returns 0 if running as root
# Returns 1 if not (and breaks the script)
#
function check_root_or_exit()
{
[ "${UID}" -eq "0" ]
exit_if_bad "$?" "Must be run by UID=0. Actual UID=${UID}."
return 0
}
#
# check_executes Check for executable(s)
#
# Returns 0 if true.
# Returns 1 if not.
#
function check_executes()
{
local cmd
local all_ok="yes"
for cmd in "$@"
do
if ! type "${cmd}" &>/dev/null
then
echo "Command \"${cmd}\" not found." >&2
all_ok="no"
fi
done
[ "${all_ok}" = "yes" ]
}
#
# check_exec_or_exit Check for required executables.
#
# Exits (not returns) if commands listed on command line do not exist.
#
# Returns 0 if true.
# Exits with 1 if not.
#
function check_exec_or_exit()
{
check_executes "$@"
exit_if_bad "$?" "Above listed required command(s) not found."
return 0
}
TMP_DIR=""
#
# internal_setup Script setup
#
# Returns 0 on success.
# Exits (not returns) with 1 on failure.
#
function internal_setup()
{
shopt -s extglob
# Trap exit for internal_cleanup function.
trap "internal_cleanup" EXIT
check_exec_or_exit mktemp rm
umask 0077
TMP_DIR="$(mktemp -d "/tmp/${0##*/}.XXXXXXXX" 2>/dev/null)"
[ -d "${TMP_DIR}" ]
exit_if_bad "$?" "Make temporary directory failed."
custom_setup
}
#
# internal_cleanup Script cleanup (reached via trap 0)
#
# Destory any temporarily facility created by internal_setup.
#
function internal_cleanup()
{
custom_cleanup
[ -d "${TMP_DIR}" ] && rm -rf "${TMP_DIR}"
}
#
# custom_setup
#
function custom_setup()
{
check_exec_or_exit awk cat comm grep printf sleep tee
check_root_or_exit
}
#
# custom_cleanup
#
function custom_cleanup()
{
:
}
#
# cleanup_n_exec Do the cleanup, then execute the command
#
# $1+ The command to execute
#
function cleanup_n_exec()
{
internal_cleanup
exec "$@"
}
internal_setup
# Check operating system
function check_os()
{
case "${OSTYPE}" in
"aix"*) # AIX
echo "aix"
;;
"darwin"*) # OS X
echo "darwin"
;;
"linux"*) # Linux
echo "linux"
;;
*)
# Unknown
echo "${OSTYPE}"
;;
esac
}
# Check instruction set architecture
function check_arch()
{
case "${HOSTTYPE}" in
"powerpc64")
echo "ppc64"
;;
"powerpc64le")
echo "ppc64le"
;;
"mipsel")
echo "mips"
;;
"i"?"86")
echo "i386"
;;
*)
echo "${HOSTTYPE}"
;;
esac
}
function check_linux_distro()
{
local distro="$(source /etc/os-release >/dev/null 2>&1 &&
echo "${ID}")"
[[ -z "${distro}" && -f /etc/redhat-release ]] && distro="rhel"
[[ -z "${distro}" && -f /etc/SuSE-release ]] && distro="sles"
echo "${distro}"
}
function check_linux_version()
{
local ver="$(source /etc/os-release >/dev/null 2>&1 &&
echo "${VERSION_ID}")"
[[ -z "${ver}" && -f /etc/redhat-release ]] &&
# Need gawk to do this trick
ver="$(awk '{ match($0, /([.0-9]+)/, a); print substr($0, a[1, "start"], a[1, "length"]); }' \
/etc/redhat-release)"
[[ -z "${ver}" && -f /etc/SuSE-release ]] &&
ver="$(awk '/VERSION/ { print $NF }' /etc/SuSE-release)"
echo "${ver}"
}
function function_dispatch()
{
local base="$1"
local cmd=""
local ret=""
shift
for cmd in $(compgen -A function "${base}_")
do
"${cmd}" "$@"
ret="$?"
[[ "${ret}" -ne "255" ]] && break
done
[[ "${ret}" -ne "255" ]]
exit_if_bad "$?" "${base}: unsupported function"
return "${ret}"
}
# $@ package names
function check_package_version_rpm()
{
type rpm >/dev/null 2>&1 || return 255
local ver=""
while read -r ver
do
if [[ -z "${ver}" || "${ver}" =~ not\ installed ]]
then
echo "(not installed)"
else
echo "${ver}"
fi
done < <(rpm -q --qf '%{version}-%{release}\n' "$@" 2>/dev/null)
return 0
}
# $@ package names
function check_package_version_deb()
{
type dpkg-query >/dev/null 2>&1 || return 255
local name=""
local ver=""
while read -r name ver
do
name+=("${name}")
ver+=("${ver}")
done < <(dpkg-query --show '--showformat=${Package} ${Version}\n' \
"$@" 2>/dev/null)
local -i i
while [[ -n "$1" ]]
do
for i in "${!name[@]}"
do
if [[ "$1" = "${name[i]}" ]]
then
echo "${ver[i]}"
unset "name[${i}]" "ver[${i}]"
shift && continue 2
fi
done
echo "(not installed)"
shift
done
return 0
}
function check_package_version()
{
function_dispatch "${FUNCNAME}" "$@"
}
# $@ package names
function check_repo_version_dnf()
{
type dnf >/dev/null 2>&1 || return 255
local -a name=()
local -a ver=()
while read -r name ver
do
name+=("${name}")
ver+=("${ver}")
done < <(dnf repoquery -q --qf '%{name} %{version}-%{release}' "$@" 2>/dev/null)
local -i i
while [[ -n "$1" ]]
do
for i in "${!name[@]}"
do
if [[ "$1" = "${name[i]}" ]]
then
echo "${ver[i]}"
unset "name[${i}]" "ver[${i}]"
shift && continue 2
fi
done
echo "(not found)"
shift
done
return 0
}
# $@ package names
function check_repo_version_yum()
{
type yum >/dev/null 2>&1 || return 255
check_executes repoquery
exit_if_bad "$?" "Install the \`yum-utils' package and rerun."
local -a name=()
local -a ver=()
while read -r name ver
do
name+=("${name}")
ver+=("${ver}")
done < <(repoquery --qf '%{name} %{version}-%{release}' "$@" 2>/dev/null)
local -i i
while [[ -n "$1" ]]
do
for i in "${!name[@]}"
do
if [[ "$1" = "${name[i]}" ]]
then
echo "${ver[i]}"
unset "name[${i}]" "ver[${i}]"
shift && continue 2
fi
done
echo "(not found)"
shift
done
return 0
}
# $@ package names
function check_repo_version_zypper()
{
type zypper >/dev/null 2>&1 || return 255
local -a name=()
local -a ver=()
while read -r name ver
do
name+=("${name}")
ver+=("${ver}")
done < <(zypper --no-gpg-checks -n search --match-exact -C -t package \
-s "$@" 2>/dev/null |
awk -F ' +\\| +' '/ package / { if ("(" != substr($6, 0, 1)) print $2, $4 }')
local -i i
while [[ -n "$1" ]]
do
for i in "${!name[@]}"
do
if [[ "$1" = "${name[i]}" ]]
then
echo "${ver[i]}"
unset "name[${i}]" "ver[${i}]"
shift && continue 2
fi
done
echo "(not found)"
shift
done
return 0
}
# $@ package names
function check_repo_version_apt()
{
type apt-cache >/dev/null 2>&1 || return 255
local name=""
local ver=""
while read -r name ver
do
if [[ "${name}" =~ ^[a-z] ]]
then
while [[ -n "$1" ]]
do
[[ "${name}" = "${1}:" ]] && break
echo "(not found)"
shift
done
fi
if [[ "${name}" = "Candidate:" ]]
then
echo "$ver"
shift
fi
done < <(apt-cache policy "$@" 2>/dev/null)
while [[ -n "$1" ]]
do
echo "(not found)"
shift
done
return 0
}
function check_repo_version()
{
function_dispatch "${FUNCNAME}" "$@"
}
# $1 repo id
function get_package_list_dnf()
{
type dnf >/dev/null 2>&1 || return 255
local repo_id="$1"
[[ -z "${repo_id}" ]] && return 1
dnf repoquery -q "--repoid=${repo_id}" --qf "%{name}" 2>/dev/null
}
# $1 repo id
function get_package_list_yum()
{
type yum >/dev/null 2>&1 || return 255
check_executes repoquery
exit_if_bad "$?" "Install the \`yum-utils' package and rerun."
local repo_id="$1"
[[ -z "${repo_id}" ]] && return 1
repoquery -qa "--repoid=${repo_id}" --qf "%{name}" 2>/dev/null
}
# $1 repo id
function get_package_list_zypper()
{
type zypper >/dev/null 2>&1 || return 255
local repo_id="$1"
[[ -z "${repo_id}" ]] && return 1
zypper --no-gpg-checks -n search -r "${repo_id}" 2>/dev/null |
awk -F ' +\\| +' '/ package$/ { print $2 }'
}
# $1 repo id
function get_package_list_apt()
{
[[ -d /var/lib/apt/lists ]] || return 255
local repo_id="$1"
[[ -z "${repo_id}" ]] && return 1
local -i rc=0
awk '/^Package: / { print $2 }' \
"/var/lib/apt/lists/"*"_${repo_id}_dists"*"_main_binary-"*"_Packages" \
2>/dev/null
# This is a dirty hack, and use recursion.
# For the `devel' branch of the online repo for apt, it has the
# subdirectory name of `core-snap' instead of `xcat-core'.
rc="$?"
if [[ "${rc}" -ne "0" && "${repo_id}" = "xcat-core" ]]
then
"${FUNCNAME}" "core-snap"
rc="$?"
fi
return "${rc}"
}
# $1 repo id
function get_package_list()
{
function_dispatch "${FUNCNAME}" "$@"
}
function download_file_curl()
{
local script="${0##*/}"
local version="$(version)"
local user_agent="${script}/${version} (${GO_XCAT_OS}; ${GO_XCAT_ARCH}; ${GO_XCAT_LINUX_DISTRO} ${GO_XCAT_LINUX_VERSION})"
type curl >/dev/null 2>&1 || return 255
local url="$1"
local local_file="$2"
local log_file="${TMP_DIR}/curl.log.${RANDOM}"
local -i rc=0
curl -A "${user_agent}" "${url}" -f -o "${local_file}" -S -s >"${log_file}" 2>&1
rc="$?"
if [[ "${rc}" -ne "0" ]]
then
while read -r ; do echo "${REPLY}" ; done <"${log_file}"
echo -n "${script}: \`curl' exited with an error: (exit code ${rc}, "
case "${rc}" in
1) echo -n "unsupported protocol" ;;
2) echo -n "failed to initialize" ;;
3) echo -n "URL malformed" ;;
4) echo -n "you probably need another build of libcurl!" ;;
5) echo -n "couldn't resolve proxy" ;;
6) echo -n "couldn't resolve host" ;;
7) echo -n "failed to connect to host" ;;
8) echo -n "weird server reply" ;;
9) echo -n "FTP access denied" ;;
10) echo -n "FTP accept failed" ;;
11) echo -n "FTP weird PASS reply" ;;
12) echo -n "During an active FTP session while waiting for the server to connect back to curl, the timeout expired." ;;
13) echo -n "FTP weird PASV reply" ;;
14) echo -n "FTP weird 227 format" ;;
15) echo -n "FTP can't get host" ;;
16) echo -n "HTTP/2 error" ;;
17) echo -n "FTP couldn't set binary" ;;
18) echo -n "Partial file" ;;
19) echo -n "FTP couldn't download/access the given file" ;;
21) echo -n "FTP quote error" ;;
22) echo -n "HTTP page not retrieved" ;;
23) echo -n "write error" ;;
25) echo -n "FTP couldn't STOR file" ;;
26) echo -n "read error" ;;
27) echo -n "out of memory" ;;
28) echo -n "operation timeout" ;;
30) echo -n "FTP PORT failed" ;;
31) echo -n "FTP couldn't use REST" ;;
33) echo -n "HTTP range error" ;;
34) echo -n "HTTP post error" ;;
35) echo -n "SSL connect error" ;;
36) echo -n "bad download resume" ;;
37) echo -n "FILE couldn't read file" ;;
38) echo -n "LDAP cannot bind" ;;
39) echo -n "LDAP search failed." ;;
41) echo -n "function not found" ;;
42) echo -n "aborted by callback" ;;
43) echo -n "internal error" ;;
45) echo -n "interface error" ;;
47) echo -n "too many redirects" ;;
48) echo -n "unknown option specified to libcurl" ;;
49) echo -n "malformed telnet option" ;;
51) echo -n "the peer's SSL certificate or SSH MD5 fingerprint was not OK" ;;
52) echo -n "the server didn't reply anything, which here is considered an error" ;;
53) echo -n "SSL crypto engine not found" ;;
54) echo -n "cannot set SSL crypto engine as default" ;;
55) echo -n "failed sending network data" ;;
56) echo -n "failure in receiving network data" ;;
58) echo -n "problem with the local certificate" ;;
59) echo -n "couldn't use specified SSL cipher" ;;
60) echo -n "peer certificate cannot be authenticated with known CA certificates" ;;
61) echo -n "unrecognized transfer encoding." ;;
62) echo -n "invalid LDAP URL" ;;
63) echo -n "maximum file size exceeded" ;;
64) echo -n "requested FTP SSL level failed" ;;
65) echo -n "sending the data requires a rewind that failed" ;;
66) echo -n "failed to initialise SSL Engine" ;;
67) echo -n "the user name, password, or similar was not accepted and curl failed to log in" ;;
68) echo -n "file not found on TFTP server" ;;
69) echo -n "permission problem on TFTP server" ;;
70) echo -n "out of disk space on TFTP server" ;;
71) echo -n "illegal TFTP operation" ;;
72) echo -n "unknown TFTP transfer ID" ;;
73) echo -n "file already exists (TFTP)" ;;
74) echo -n "no such user (TFTP)" ;;
75) echo -n "character conversion failed" ;;
76) echo -n "character conversion functions required" ;;
77) echo -n "problem with reading the SSL CA cert" ;;
78) echo -n "the resource referenced in the URL does not exist" ;;
79) echo -n "an unspecified error occurred during the SSH session" ;;
80) echo -n "failed to shut down the SSL connection" ;;
82) echo -n "could not load CRL file, missing or wrong format" ;;
83) echo -n "issuer check failed" ;;
84) echo -n "the FTP PRET command failed" ;;
85) echo -n "RTSP: mismatch of CSeq numbers" ;;
86) echo -n "RTSP: mismatch of Session Identifiers" ;;
87) echo -n "unable to parse FTP file list" ;;
88) echo -n "FTP chunk callback reported error" ;;
89) echo -n "no connection available, the session will be queued" ;;
90) echo -n "SSL public key does not matched pinned public key" ;;
*) echo -n "unknown error" ;;
esac
echo ")"
echo " ... while downloading \`${url}'"
fi >&2
[[ "${rc}" -eq "0" ]]
}
function download_file_wget()
{
local script="${0##*/}"
local version="$(version)"
local user_agent="${script}/${version} (${GO_XCAT_OS}; ${GO_XCAT_ARCH}; ${GO_XCAT_LINUX_DISTRO} ${GO_XCAT_LINUX_VERSION})"
type wget >/dev/null 2>&1 || return 255
local url="$1"
local local_file="$2"
local log_file="${TMP_DIR}/wget.log.${RANDOM}"
local -i rc=0
wget -U "${user_agent}" -nv "${url}" -O "${local_file}" -o "${log_file}"
rc="$?"
if [[ "${rc}" -ne "0" ]]
then
while read -r ; do echo "${REPLY}" ; done <"${log_file}"
echo -n "${script}: \`wget' exited with an error: (exit code ${rc}, "
case "${rc}" in
1) echo -n "generic error" ;;
2) echo -n "parse error" ;;
3) echo -n "file I/O error" ;;
4) echo -n "network failure" ;;
5) echo -n "SSL verification failure" ;;
6) echo -n "username/password authentication failure" ;;
7) echo -n "protocol errors" ;;
8) echo -n "server issued an error response" ;;
*) echo -n "unknown error" ;;
esac
echo ")"
echo " ... while downloading \`${url}'"
fi >&2
[[ "${rc}" -eq "0" ]]
}
function download_file()
{
function_dispatch "${FUNCNAME}" "$@"
}
# $1 repo file
# $2 repo id
function add_repo_by_file_yum()
{
[[ -d /etc/yum.repos.d ]] || return 255
local repo_file="$1"
local repo_id="$2"
[[ -f "${repo_file}" ]]
exit_if_bad "$?" "${repo_file}: no such file"
[[ -r "${repo_file}" ]]
exit_if_bad "$?" "${repo_file}: permission denied"
[[ -n "${repo_id}" ]]
exit_if_bad "$?" "empty repo id"
[[ "${repo_id}" =~ ^[a-zA-Z][0-9a-zA-Z-]*$ ]]
exit_if_bad "$?" "${repo_id} illegal character in repo id"
local tmp="${TMP_DIR}/tmp_repo_file_${repo_id}.repo"
{
echo "[${repo_id}]"
grep -v '^\[' "${repo_file}"
} >"${tmp}"
remove_repo_yum "${repo_id}" &&
cp "${tmp}" "/etc/yum.repos.d/${repo_id}.repo"
}
# $1 repo file
# $2 repo id
function add_repo_by_file_zypper()
{
type zypper >/dev/null 2>&1 || return 255
local repo_file="$1"
local repo_id="$2"
[[ -f "${repo_file}" ]]
exit_if_bad "$?" "${repo_file}: no such file"
[[ -r "${repo_file}" ]]
exit_if_bad "$?" "${repo_file}: permission denied"
[[ -n "${repo_id}" ]]
exit_if_bad "$?" "empty repo id"
[[ "${repo_id}" =~ ^[a-zA-Z][0-9a-zA-Z-]*$ ]]
exit_if_bad "$?" "${repo_id} illegal character in repo id"
local tmp="${TMP_DIR}/tmp_repo_file_${repo_id}.repo"
{
echo "[${repo_id}]"
grep -v '^\[' "${repo_file}"
} >"${tmp}"
remove_repo_zypper "${repo_id}" &&
zypper addrepo "${tmp}" >/dev/null 2>&1
}
# $1 repo file
# $2 repo id
function add_repo_by_file_apt()
{
[[ -d /etc/apt/sources.list.d/ ]] || return 255
local repo_file="$1"
local repo_id="$2"
[[ -f "${repo_file}" ]]
exit_if_bad "$?" "${repo_file}: no such file"
[[ -r "${repo_file}" ]]
exit_if_bad "$?" "${repo_file}: permission denied"
[[ -n "${repo_id}" ]]
exit_if_bad "$?" "empty repo id"
[[ "${repo_id}" =~ ^[a-zA-Z][0-9a-zA-Z-]*$ ]]
exit_if_bad "$?" "${repo_id} illegal character in repo id"
cp "${repo_file}" "/etc/apt/sources.list.d/${repo_id}.list"
}
function add_repo_by_file()
{
function_dispatch "${FUNCNAME}" "$@"
}
# $1 archive
# $2 repo id
# $3 install path
function extract_archive()
{
local archive="$1"
local repo_id="$2"
local install_path="$3"
local umask="$(umask)"
local -i ret=0
[[ -f "${archive}" ]]
warn_if_bad "$?" "${archive}: archive file not found!" || return 1
umask 0022
mkdir -p "${install_path}" 2>/dev/null
ret="$?"
umask "${umask}"
warn_if_bad "${ret}" "Failed to create directory \`${install_path}'" ||
return 1
case "${archive##*/}" in
*".tar.Z")
check_executes uncompress tar grep || return 1
uncompress -c "${archive}" | tar -t -f - | grep -v "^${repo_id}/"
[[ "${PIPESTATUS[0]}" -eq 0 && "${PIPESTATUS[1]}" -eq 0 &&
"${PIPESTATUS[2]}" -eq 1 ]]
warn_if_bad "$?" "${archive}: bad compressed tarball" || return 1
rm -rf "${install_path}/${repo_id}"
uncompress -c "${archive}" | ( cd "${install_path}" && tar -x -f - )
;;
*".tz"|*".tgz"|*".tar.gz")
check_executes gzip tar grep || return 1
gzip -d -c "${archive}" | tar -t -f - | grep -v "^${repo_id}/"
[[ "${PIPESTATUS[0]}" -eq 0 && "${PIPESTATUS[1]}" -eq 0 &&
"${PIPESTATUS[2]}" -eq 1 ]]
exit_if_bad "$?" "${archive}: bad gzipped tarball"
rm -rf "${install_path}/${repo_id}"
gzip -d -c "${archive}" | ( cd "${install_path}" && tar -x -f - )
;;
*".tbz"|*".tbz2"|*".tar.bz"|*".tar.bz2")
check_executes bzip2 tar grep || return 1
bzip2 -d -c "${archive}" | tar -t -f - | grep -v "^${repo_id}/"
[[ "${PIPESTATUS[0]}" -eq 0 && "${PIPESTATUS[1]}" -eq 0 &&
"${PIPESTATUS[2]}" -eq 1 ]]
warn_if_bad "$?" "${archive}: bad bzipped tarball" || return 1
rm -rf "${install_path}/${repo_id}"
bzip2 -d -c "${archive}" | ( cd "${install_path}" && tar -x -f - )
;;
*".txz"|*".tar.xz")
check_executes xz tar grep || return 1
xz -d -c "${archive}" | tar -t -f - | grep -v "^${repo_id}/"
[[ "${PIPESTATUS[0]}" -eq 0 && "${PIPESTATUS[1]}" -eq 0 &&
"${PIPESTATUS[2]}" -eq 1 ]]
warn_if_bad "$?" "${archive}: bad xzed tarball" || return 1
rm -rf "${install_path}/${repo_id}"
xz -d -c "${archive}" | ( cd "${install_path}" && tar -x -f - )
;;
*".tar")
check_executes tar grep || return 1
tar -t -f "${archive}" | grep -v "^${repo_id}/"
[[ "${PIPESTATUS[0]}" -eq 0 && "${PIPESTATUS[1]}" -eq 1 ]]
warn_if_bad "$?" "${archive}: bad tarball" || return 1
rm -rf "${install_path}/${repo_id}"
( cd "${install_path}" && tar -x -f - ) <"${archive}"
;;
*)
warn_if_bad "1" "${archive}: unknown archive file"
return 1
;;
esac
[[ -d "${install_path}/${repo_id}" ]]
warn_if_bad "$?" "${install_path}/${repo_id}: no such directory"
}
# $1 URL
# $2 repo id
function add_repo_by_url_yum_or_zypper()
{
local -a yes=()
[[ "$1" = "-y" ]] && yes=("-y") && shift
local url="$1"
local repo_id="$2"
local tmp=""
local install_path="${GO_XCAT_DEFAULT_INSTALL_PATH}"
case "${url%%://*}" in
"ftp"|"http"|"https")
case "${url##*/}" in
*".repo"|*".tar"|*".tar.Z"|*".tar.bz"|*".tar.bz2"|*".tar.gz"|*".tar.xz"|*".tbz"|*".tbz2"|*".tgz"|*".tz"|*".txz")
# an online repo or tarball
tmp="${TMP_DIR}/tmp_${url##*/}"
download_file "${url}" "${tmp}"
warn_if_bad "$?" \
"download ${repo_id} resource failed" ||
return 1
url="${tmp}"
;;
*) # assume it is the base url of the repo
tmp="${TMP_DIR}/tmp_repo.repo"
while read -r ; do echo "${REPLY}" ; done >"${tmp}" <<-EOF
[${repo_id}]
name=${repo_id}
baseurl=${url}
enabled=1
gpgcheck=0
EOF
add_repo_by_file "${tmp}" "${repo_id}"
return "$?"
;;
esac
;;
"file")
url="${url#file://}"
;;
esac
if [[ -f "${url}" ]]
then
case "${url##*.}" in
"repo") # local repo file
add_repo_by_file "${url}" "${repo_id}"
return "$?"
;;
esac
extract_archive "${url}" "${repo_id}" "${install_path}"
warn_if_bad "$?" "extract ${repo_id} archive file failed" ||
return 1
url="${install_path}/${repo_id}"
fi
if [[ -d "${url}" ]]
then
# make sure it is an absolute pathname.
[[ "${url:0:1}" = "/" ]] || url="${PWD}/${url}"
# directory
tmp="${TMP_DIR}/tmp_repo.repo"
while read -r ; do echo "${REPLY}" ; done >"${tmp}" <<-EOF
[${repo_id}]
name=${repo_id}
baseurl=file://${url}
enabled=1
gpgcheck=0
EOF
add_repo_by_file "${tmp}" "${repo_id}"
return "$?"
fi
warn_if_bad "1" "invalid ${repo_id} URL"
}
# $1 URL
# $2 repo id
function add_repo_by_url_apt()
{
[[ -d /etc/apt/sources.list.d/ ]] || return 255
local -a yes=()
[[ "$1" = "-y" ]] && yes=("-y") && shift
local url="$1"
local repo_id="$2"
local tmp=""
local install_path="${GO_XCAT_DEFAULT_INSTALL_PATH}"
local codename="$(source /etc/lsb-release >/dev/null 2>&1 &&
echo "${DISTRIB_CODENAME}")"
[[ -n "${codename}" ]]
warn_if_bad "$?" "unknown debian/ubuntu codename" || return 1
case "${url%%://*}" in
"ftp"|"http"|"https"|"ssh")
case "${url##*/}" in
*".tar"|*".tar.Z"|*".tar.bz"|*".tar.bz2"|*".tar.gz"|*".tar.xz"|*".tbz"|*".tbz2"|*".tgz"|*".tz"|*".txz")
# an online tarball
tmp="${TMP_DIR}/tmp_${url##*/}"
download_file "${url}" "${tmp}"
warn_if_bad "$?" \
"download ${repo_id} resource failed" ||
return 1
url="${tmp}"
;;
*) # assume it is the base url of the repo
tmp="${TMP_DIR}/tmp_repo.list"
echo "deb [arch=$(dpkg --print-architecture)] ${url} ${codename} main" >"${tmp}"
add_repo_by_file_apt "${tmp}" "${repo_id}"
return "$?"
;;
esac
;;
"file")
url="${url#file://}"
;;
esac
if [[ -f "${url}" ]]
then
extract_archive "${url}" "${repo_id}" "${install_path}"
warn_if_bad "$?" "extract ${repo_id} archive file failed" ||
return 1
url="${install_path}/${repo_id}"
fi
if [[ -d "${url}" ]]
then
# make sure it is an absolute pathname.
[[ "${url:0:1}" = "/" ]] || url="${PWD}/${url}"
# directory
tmp="${TMP_DIR}/tmp_repo.list"
echo "deb [arch=$(dpkg --print-architecture)] file://${url} ${codename} main" >"${tmp}"
add_repo_by_file_apt "${tmp}" "${repo_id}"
return "$?"
fi
warn_if_bad "1" "invalid ${repo_id} URL"
}
function add_repo_by_url()
{
function_dispatch "${FUNCNAME}" "$@"
}
# $1 repo id
function remove_repo_yum()
{
type yum >/dev/null 2>&1 || return 255
local repo_id="$1"
# This deleting method is not good enough. Since there could be more
# than one repository definitions in a single repo file.
# This is a quick and dirty method.
rm -f $(grep -l "^\[${repo_id}\]$" "/etc/yum.repos.d/"*".repo" 2>/dev/null)
case "${repo_id}" in
"xcat-core")
mv /etc/yum.repos.d/xCAT-core.repo{,.nouse} 2>/dev/null
;;
"xcat-dep")
mv /etc/yum.repos.d/xCAT-dep.repo{,.nouse} 2>/dev/null
;;
esac
yum clean metadata
:
}
# $1 repo id
function remove_repo_zypper()
{
type zypper >/dev/null 2>&1 || return 255
local repo_id="$1"
zypper removerepo "${repo_id}"
case "${repo_id}" in
"xcat-core")
mv /etc/zypp/repos.d/xCAT-core.repo{,.nouse} 2>/dev/null
;;
"xcat-dep")
mv /etc/zypp/repos.d/xCAT-dep.repo{,.nouse} 2>/dev/null
;;
esac
:
}
# $1 repo id
function remove_repo_apt()
{
[[ -d "/etc/apt/sources.list.d" ]] || return 255
local repo_id="$1"
rm -f "/etc/apt/sources.list.d/${repo_id}.list"
}
function remove_repo()
{
function_dispatch "${FUNCNAME}" "$@"
}
# $1 URL
# $2 version
# can be "2.10", "2.11", "2.12", "latest" or "devel"
function add_xcat_core_repo_yum_or_zypper()
{
type yum >/dev/null 2>&1 || type zypper >/dev/null 2>&1 || return 255
local -a yes=()
[[ "$1" = "-y" ]] && yes=("-y") && shift
local url="$1"
local ver="$2"
local tmp=""
[[ -z "${ver}" ]] && ver="latest"
if [[ -z "${url}" ]]
then
case "${ver}" in
"devel")
url="${GO_XCAT_DEFAULT_BASE_URL}/yum/devel/core-snap"
;;
*)
url="${GO_XCAT_DEFAULT_BASE_URL}/yum/${ver}/xcat-core"
;;
esac
fi
add_repo_by_url_yum_or_zypper "${url}" "xcat-core"
}
# $1 URL
# $2 version
# can be "2.10", "2.11", "2.12", "latest" or "devel"
function add_xcat_core_repo_apt()
{
[[ -d "/etc/apt/sources.list.d" ]] || return 255
local -a yes=()
[[ "$1" = "-y" ]] && yes=("-y") && shift
local url="$1"
local ver="$2"
local tmp=""
[[ -z "${ver}" ]] && ver="latest"
if [[ -z "${url}" ]]
then
# get the apt.key
local url="${GO_XCAT_DEFAULT_BASE_URL}/apt/apt.key"
local tmp="${TMP_DIR}/tmp_xcat.key"
download_file "${url}" "${tmp}"
warn_if_bad "$?" "download xcat apt key failed" || return 1
apt-key add "${tmp}" >/dev/null 2>&1
warn_if_bad "$?" "import xcat apt key failed" || return 1
case "${ver}" in
"devel")
url="${GO_XCAT_DEFAULT_BASE_URL}/apt/devel/core-snap"
;;
*)
url="${GO_XCAT_DEFAULT_BASE_URL}/apt/${ver}/xcat-core"
;;
esac
fi
add_repo_by_url_apt "${url}" "xcat-core"
}
function add_xcat_core_repo()
{
function_dispatch "${FUNCNAME}" "$@"
}
function add_xcat_dep_repo_yum_or_zypper()
{
type yum >/dev/null 2>&1 || type zypper >/dev/null 2>&1 || return 255
local -a yes=()
[[ "$1" = "-y" ]] && yes=("-y") && shift
local url="$1"
local ver="$2"
[[ -z "${ver}" ]] && ver="latest"
local tmp=""
local install_path="${GO_XCAT_DEFAULT_INSTALL_PATH}"
local distro="${GO_XCAT_LINUX_DISTRO}${GO_XCAT_LINUX_VERSION%%.*}"
case "${distro}" in
"centos"*) distro="rh${distro#centos}" ;;
"fedora10"|"fedora11") distro="fedora9" ;;
"fedora1"[678]) distro="rh6" ;;
"fedora19"|"fedora2"?) distro="rh7" ;;
"rhel"*) distro="rh${distro#rhel}" ;;
"sles"*) ;;
*) warn_if_bad 1 "${distro}: unsupported Linux distro" || return 1
esac
[[ -z "${url}" ]] &&
url="${GO_XCAT_DEFAULT_BASE_URL}/yum/${ver}/xcat-dep"
case "${url##*.}" in
"repo") # local repo file
add_repo_by_url_yum_or_zypper "${url}" "xcat-dep"
return "$?"
;;
esac
case "${url%%://*}" in
"ftp"|"http"|"https")
case "${url##*/}" in
*".tar"|*".tar.Z"|*".tar.bz"|*".tar.bz2"|*".tar.gz"|*".tar.xz"|*".tbz"|*".tbz2"|*".tgz"|*".tz"|*".txz")
# an online archive file
tmp="${TMP_DIR}/tmp_${url##*/}"
download_file "${url}" "${tmp}"
warn_if_bad "$?" "download xcat-dep archive file failed" \
|| return 1
url="${tmp}"
;;
*)
url="${url}/${distro}/${GO_XCAT_ARCH}"
add_repo_by_url_yum_or_zypper "${url}" "xcat-dep"
return "$?"
;;
esac
;;
"file")
url="${url#file://}"
;;
esac
if [[ -f "${url}" ]]
then
extract_archive "${url}" "xcat-dep" "${install_path}"
warn_if_bad "$?" "extract xcat-dep archive file failed" ||
return 1
url="${install_path}/xcat-dep"
fi
if [[ -d "${url}" ]]
then
# make sure it is an absolute pathname.
[[ "${url:0:1}" = "/" ]] || url="${PWD}/${url}"
url="${url}/${distro}/${GO_XCAT_ARCH}"
add_repo_by_url_yum_or_zypper "${url}" "xcat-dep"
return "$?"
fi
warn_if_bad "1" "invalid xcat-dep URL"
}
function add_xcat_dep_repo_apt()
{
[[ -d "/etc/apt/sources.list.d" ]] || return 255
local -a yes=()
[[ "$1" = "-y" ]] && yes=("-y") && shift
local url="$1"
local ver="$2"
[[ -z "${ver}" ]] && ver="latest"
[[ -z "${url}" ]] &&
url="${GO_XCAT_DEFAULT_BASE_URL}/apt/${ver}/xcat-dep"
add_repo_by_url_apt "${url}" "xcat-dep"
}
function add_xcat_dep_repo()
{
function_dispatch "${FUNCNAME}" "$@"
}
function update_repo_dnf()
{
type dnf >/dev/null 2>&1 || return 255
dnf --nogpgcheck updateinfo
}
function update_repo_yum()
{
type yum >/dev/null 2>&1 || return 255
# Check if `yum' support `updateinfo' command.
yum --help 2>/dev/null | grep -q "^updateinfo" >/dev/null 2>&1
warn_if_bad "$?" "Lacking support of \`updateinfo' command for \`yum'."
warn_if_bad "$?" "Please rerun after install package \`yum-plugin-security'."
exit_if_bad "$?" "And please update package \`yum' to at least version 3.2.29-17."
yum --nogpgcheck updateinfo
}
function update_repo_zypper()
{
type zypper >/dev/null 2>&1 || return 255
zypper --gpg-auto-import-keys -n refresh
}
function update_repo_apt()
{
type apt-get >/dev/null 2>&1 || return 255
apt-get --allow-unauthenticated update
}
function update_repo()
{
function_dispatch "${FUNCNAME}" "$@"
}
function install_packages_dnf()
{
type dnf >/dev/null 2>&1 || return 255
local -a yes=()
[[ "$1" = "-y" ]] && yes=("-y") && shift
dnf --nogpgcheck "${yes[@]}" install "$@"
}
function install_packages_yum()
{
type yum >/dev/null 2>&1 || return 255
local -a yes=()
[[ "$1" = "-y" ]] && yes=("-y") && shift
yum --nogpgcheck "${yes[@]}" install "$@"
}
function install_packages_zypper()
{
type zypper >/dev/null 2>&1 || return 255
local -a yes=()
[[ "$1" = "-y" ]] && yes=("-n") && shift
zypper --no-gpg-checks "${yes[@]}" install --force-resolution "$@"
}
function install_packages_apt()
{
type apt-get >/dev/null 2>&1 || return 255
local -a yes=()
[[ "$1" = "-y" ]] && yes=("-y") && shift
apt-get --allow-unauthenticated install "${yes[@]}" "$@"
}
function install_packages()
{
function_dispatch "${FUNCNAME}" "$@"
}
# $1 -y
function install_xcat()
{
install_packages "$@" "${GO_XCAT_INSTALL_LIST[@]}"
}
# $1 -y
function update_xcat()
{
local -i i=0
local ver=""
local -a xcat_core_package_list
xcat_core_package_list=($(get_package_list xcat-core))
exit_if_bad "$?" "Failed to get package list from repository \`xcat-core'."
local -a install_list=($(
comm <(echo "${GO_XCAT_INSTALL_LIST[@]}") \
<(echo "${xcat_core_package_list[@]}")
))
for i in "${!install_list[@]}"
do
read -r ver
[[ "${ver}" = "(not installed)" ]] &&
unset "install_list[${i}]"
done < <(check_package_version "${install_list[@]}")
[[ "${#install_list[@]}" -gt "0" ]]
warn_if_bad "$?" "xCAT is not installed."
exit_if_bad "$?" "In order to install xCAT, please rerun with \`${0##*/} install'."
install_packages "$@" "${install_list[@]}"
}
function list_xcat_packages()
{
GO_XCAT_CORE_PACKAGE_LIST=($(get_package_list xcat-core))
exit_if_bad "$?" "Failed to get package list from repository \`xcat-core'."
GO_XCAT_DEP_PACKAGE_LIST=($(get_package_list xcat-dep))
exit_if_bad "$?" "Failed to get package list from repository \`xcat-dep'."
local -i cols="$(type tput >/dev/null 2>&1 && tput cols)"
[[ "${cols}" -lt 80 ]] && cols=80
[[ "${cols}" -gt 90 ]] && cols=90
[[ -t 1 ]] || cols=90
local -i first_col=27
local -i second_col=$(( ( cols - 30 ) / 2 ))
local -i third_col=${second_col}
local pkg=""
echo
echo "xCAT Core Packages"
echo "=================="
echo
printf "%-${first_col}s %-${second_col}s %-${third_col}s\n" \
"Package Name" "Installed" "In Repository"
printf "%-${first_col}s %-${second_col}s %-${third_col}s\n" \
"------------" "---------" "-------------"
for pkg in "${GO_XCAT_CORE_PACKAGE_LIST[@]}"
do
read -r i_ver && read -u 42 -r r_ver
printf "%-${first_col}s %-${second_col}s %-${third_col}s\n" \
"${pkg:0:${first_col}}" \
"${i_ver:0:${second_col}}" \
"${r_ver:0:${third_col}}"
done < <(check_package_version "${GO_XCAT_CORE_PACKAGE_LIST[@]}") \
42< <(check_repo_version "${GO_XCAT_CORE_PACKAGE_LIST[@]}")
echo
echo "xCAT Dependency Packages"
echo "========================"
echo
printf "%-${first_col}s %-${second_col}s %-${third_col}s\n" \
"Package Name" "Installed" "In Repository"
printf "%-${first_col}s %-${second_col}s %-${third_col}s\n" \
"------------" "---------" "-------------"
for pkg in "${GO_XCAT_DEP_PACKAGE_LIST[@]}"
do
read -r i_ver
read -u 42 -r r_ver
printf "%-${first_col}s %-${second_col}s %-${third_col}s\n" \
"${pkg:0:${first_col}}" \
"${i_ver:0:${second_col}}" \
"${r_ver:0:${third_col}}"
done < <(check_package_version "${GO_XCAT_DEP_PACKAGE_LIST[@]}") \
42< <(check_repo_version "${GO_XCAT_DEP_PACKAGE_LIST[@]}")
}
# Test case 000
# Check if all the xcat-core packages are on the same version
function test_case_000_version()
{
local ver=""
local -i ret=0
while read -r
do
[[ "${REPLY}" = "(not installed)" ]] && continue
[[ -z "${ver}" ]] && ver="${REPLY%%-*}"
[[ "${ver}" = "${REPLY%%-*}" ]]
(( ret += $? ))
done < <(check_package_version "${GO_XCAT_CORE_PACKAGE_LIST[@]}")
return "${ret}"
}
# Test case 001
# Check if xcatd is running
function test_case_001_xcatd()
{
local f=""
local -i ret=0
for f in /var/run/xcat/{main,install,udp}service.pid
do
kill -0 "$(<"${f}")"
(( ret += $? ))
done
for f in /var/run/xcat/cmdlogservice.pid
do
[[ -f "${f}" ]] || continue
kill -0 "$(<"${f}")"
(( ret += $? ))
done
return "${ret}"
}
# Test case 002
# Check if command lsdef can be run
function test_case_002_lsdef()
{
(source /etc/profile.d/xcat.sh && lsdef)
}
# Perform basic smoke test
function perform_smoke_test()
{
local test_case=""
local -i ret=0
for test_case in $(compgen -A function "test_case_")
do
"${test_case}" >"${TMP_DIR}/${test_case}.stdout" \
2>"${TMP_DIR}/${test_case}.stderr"
ret="$?"
if [[ "${ret}" -ne "0" || -s "${TMP_DIR}/${test_case}.stderr" ]]
then
# Something went wrong
echo "-- 8< -- -- -- -- -- -- -- -- -- -- -- -- -- -- --"
echo "==== ${test_case} failed with exit code ${ret} ===="
echo "-- 8< ${test_case} stdout -- --"
while read -r ; do echo "${REPLY}" ; done \
<"${TMP_DIR}/${test_case}.stdout"
echo "-- 8< ${test_case} stderr -- --"
while read -r ; do echo "${REPLY}" ; done \
<"${TMP_DIR}/${test_case}.stderr"
echo "-- 8< -- -- -- -- -- -- -- -- -- -- -- -- -- -- --"
# skip all the remain test cases
return "${ret}"
fi >&2
done
echo "It seems everything went well. :)"
return 0
}
GO_XCAT_METERS=""
function show_progress_meters()
{
[[ -t 2 ]] || return 0
# Show the progress meters
(
declare -i length=0
while :
do
for bar in \
"...... " \
".o..o. " \
"oOooOo " \
"OoUUoO " \
"ooUUoo " \
"oOooOo " \
"Oo..oO " \
"o....o "
#12345678901234567890123456789012345678901
do
msg="${bar}"
for (( i = 0; i < length; ++i ))
do
echo -ne "\b"
done
length=${#msg}
echo -n "${msg}"
sleep 0.1 2>/dev/null || sleep 1
kill -0 "$$" >/dev/null 2>&1 || break 2
done
done
) >&2 &
GO_XCAT_METERS="$!"
disown "${GO_XCAT_METERS}"
}
function stop_progress_meters()
{
if [[ -t 2 ]]
then
kill "${GO_XCAT_METERS}" >/dev/null 2>&1
echo -ne "\b\b\b\b\b\b\b" >&2
fi
echo -n "...... "
}
#
# |\/| _.o._ ._ .__ _ .__.._ _ _ _ _ _ |_ _ .__
# | |(_||| | |_)|(_)(_||(_|| | | (_|(_)(/__> | |(/_|(/_ o
# | _| _|
#
# Main program goes here.
declare -a GO_XCAT_YES=()
GO_XCAT_ACTION=""
GO_XCAT_CORE_URL=""
GO_XCAT_DEP_URL=""
GO_XCAT_VERSION="latest"
while [ "$#" -gt "0" ]
do
case "$1" in
"-h"|"--help")
usage
exit 0
;;
"--long-help")
verbose_usage
exit 0
;;
"--xcat-core")
shift
GO_XCAT_CORE_URL="$1"
;;
"--xcat-core="*)
GO_XCAT_CORE_URL="${1##--xcat-core=}"
;;
"--xcat-dep")
shift
GO_XCAT_DEP_URL="$1"
;;
"--xcat-dep="*)
GO_XCAT_DEP_URL="${1##--xcat-dep=}"
;;
"--xcat-version")
shift
GO_XCAT_VERSION="$1"
;;
"--xcat-version="*)
GO_XCAT_VERSION="${1##--xcat-version=}"
;;
"-x")
shift
GO_XCAT_VERSION="$1"
;;
"-y"|"--yes")
GO_XCAT_YES=("-y")
;;
"-"*)
warn_if_bad 1 "invalid option -- \`$1'"
exit_if_bad 1 "Try \`$0 --help' for more information"
;;
*)
[ "$1" == "--" ] && shift
[ -z "${GO_XCAT_ACTION}" ]
warn_if_bad "$?" "redundancy action -- \`$1'"
exit_if_bad "$?" "Try \`$0 --help' for more information"
GO_XCAT_ACTION="$1"
;;
esac
shift
done
case "${GO_XCAT_ACTION}" in
"check"|"install"|"update")
;;
"smoke-test")
perform_smoke_test
exit "$?"
;;
"")
usage
exit 1
;;
*)
warn_if_bad 1 "invalid action -- \`${GO_XCAT_ACTION}'"
exit_if_bad 1 "Try \`$0 --help' for more information"
;;
esac
GO_XCAT_OS="$(check_os)"
GO_XCAT_ARCH="$(check_arch)"
while read -r ; do echo "${REPLY}" ; echo "${REPLY}" >&2
done 2>"${TMP_DIR}/go-xcat.log.000" <<EOF
Operating system: ${GO_XCAT_OS}
Architecture: ${GO_XCAT_ARCH}
EOF
case "${GO_XCAT_OS}" in
"linux")
;;
*)
exit_if_bad 1 "${GO_XCAT_OS}: unsupported operating system"
;;
esac
case "${GO_XCAT_ARCH}" in
"ppc64"|"ppc64le"|"x86_64")
;;
*)
exit_if_bad 1 "${GO_XCAT_ARCH}: unsupported instruction set architecture"
;;
esac
GO_XCAT_LINUX_DISTRO="$(check_linux_distro)"
GO_XCAT_LINUX_VERSION="$(check_linux_version)"
while read -r ; do echo "${REPLY}" ; echo "${REPLY}" >&2
done 2>"${TMP_DIR}/go-xcat.log.001" <<EOF
Linux Distribution: ${GO_XCAT_LINUX_DISTRO}
Version: ${GO_XCAT_LINUX_VERSION}
EOF
case "${GO_XCAT_LINUX_DISTRO}" in
"centos"|"fedora"|"rhel"|"sles"|"ubuntu")
;;
*)
warn_if_bad 1 "${GO_XCAT_LINUX_DISTRO}: unsupported Linux distro"
;;
esac
echo
echo -n "Reading repositories "
show_progress_meters
ERR_MSG="$({
if add_xcat_core_repo -y "${GO_XCAT_CORE_URL}" "${GO_XCAT_VERSION}"
then
if add_xcat_dep_repo -y "${GO_XCAT_DEP_URL}" "${GO_XCAT_VERSION}"
then
update_repo && exit 0
remove_repo "xcat-dep"
fi
remove_repo "xcat-core"
fi
exit 1
} 2>&1)"
RET="$?"
stop_progress_meters
if [[ "${RET}" -ne 0 ]]
then
echo "failed"
echo "${ERR_MSG}" >&2
exit "${RET}"
fi
echo "done"
case "${GO_XCAT_ACTION}" in
"check")
list_xcat_packages
;;
"install"|"update")
GO_XCAT_INSTALLER="${GO_XCAT_ACTION}_xcat"
if [[ "${#GO_XCAT_YES[@]}" -eq "0" ]]
then
echo
echo "xCAT is going to be ${GO_XCAT_ACTION/%e/}ed."
while true; do
read -r -p "Continue? [y/n] "
case "${REPLY}" in
"Y"*|"y"*)
break
;;
"N"*|"n"*)
echo "Good-bye!"
exit 0
;;
*)
echo "Invalid response!"
;;
esac
done
fi
# Use `-y' here. Since the STDOUT is redirect to tee.
# `yum' does not display the prompt message properly when
# working with tee.
"${GO_XCAT_INSTALLER}" -y \
> >(tee "${TMP_DIR}/${GO_XCAT_INSTALLER}.stdout") \
2> >(tee "${TMP_DIR}/${GO_XCAT_INSTALLER}.stderr" >&2)
RET="$?"
{
# Creating logs
echo "-- 8< -- -- -- -- -- -- -- -- -- -- -- -- -- -- --"
echo "==== ${GO_XCAT_INSTALLER} exited with exit code ${RET} ===="
echo "-- 8< ${GO_XCAT_INSTALLER} stdout -- --"
while read -r ; do echo "${REPLY}" ; done \
<"${TMP_DIR}/${GO_XCAT_INSTALLER}.stdout"
echo "-- 8< ${GO_XCAT_INSTALLER} stderr -- --"
while read -r ; do echo "${REPLY}" ; done \
<"${TMP_DIR}/${GO_XCAT_INSTALLER}.stderr"
echo "-- 8< -- -- -- -- -- -- -- -- -- -- -- -- -- -- --"
} >"${TMP_DIR}/go-xcat.log.005"
if [[ "${RET}" -eq "0" && ! -s "${TMP_DIR}/${GO_XCAT_INSTALLER}.stderr" ]]
then
# xCAT has been installed and so far so good
perform_smoke_test >"${TMP_DIR}/perform_smoke_test.stdout" \
2>"${TMP_DIR}/perform_smoke_test.stderr"
RET="$?"
if [[ "${RET}" -ne "0" || -s "${TMP_DIR}/perform_smoke_test.stderr" ]]
then
# Smoke test failed
echo "-- 8< -- -- -- -- vv -- -- -- vv -- -- -- -- 8< --"
echo "==== perform_smoke_test failed with exit code ${RET} ===="
echo "-- 8< perform_smoke_test stdout -- --"
while read -r ; do echo "${REPLY}" ; done \
<"${TMP_DIR}/perform_smoke_test.stdout"
echo "-- 8< perform_smoke_test stderr -- --"
while read -r ; do echo "${REPLY}" ; done \
<"${TMP_DIR}/perform_smoke_test.stderr"
echo "-- 8< -- -- -- -- ^^ -- -- -- ^^ -- -- -- -- 8< --"
fi
fi >"${TMP_DIR}/go-xcat.log.008"
if [[ "${RET}" -ne "0" ]]
then
GO_XCAT_LOG="/tmp/go-xcat.log"
cat "${TMP_DIR}/go-xcat.log."* >"${GO_XCAT_LOG}" 2>/dev/null
while read -r ; do echo "${REPLY}" ; done >&2 <<-EOF
Boo-boo
=======
Something went wrong. :(
Please check log file \`${GO_XCAT_LOG}' for more details.
EOF
exit "${RET}"
fi
case "${GO_XCAT_ACTION}" in
"install")
# Only print out this message on install
while read -r ; do echo "${REPLY}" ; done <<-EOF
xCAT has been installed!
========================
If this is the very first time xCAT has been installed, run the following
commands to set environment variables into your PATH:
For sh:
source /etc/profile.d/xcat.sh
For csh:
source /etc/profile.d/xcat.csh
EOF
;;
"update")
while read -r ; do echo "${REPLY}" ; done <<-EOF
xCAT has been successfully updated!
EOF
;;
esac
;;
*)
exit 1
;;
esac # case "${GO_XCAT_ACTION}" in
exit 0
# vim: filetype=sh
# vim: noautoindent
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# End of file