mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-11 20:16:25 +00:00
01d8de2bc2
The check ran on EL9 only, and only when the version carried a minor number, so CentOS Stream was never checked. On EL10 a management node without EPEL or CRB failed inside dnf install with a dependency error instead of the message that names the missing repository. The CRB message proposed a CentOS Stream repository file with signature checks disabled, on every distribution. The probe used dnf list, which an installed copy of the probe package satisfies with the repository disabled, and which reports a failed query as a missing repository. Check EL9 and EL10, with or without a minor version. Probe the enabled repositories with repoquery for the host architecture and noarch, so a source repository does not stand in for the binary one, and stop with the package manager's own error when the query fails. Name the EPEL release package of the running major version. For CRB, name crb enable from a current epel-release, which handles Red Hat Enterprise Linux under both subscription management and RHUI, Rocky Linux, AlmaLinux and CentOS Stream, and the dnf config-manager command for Oracle Linux.
2623 lines
70 KiB
Bash
Executable File
2623 lines
70 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# go-xcat - Install xCAT automatically.
|
|
#
|
|
# Version 1.0.54
|
|
#
|
|
# Copyright (C) 2016 - 2021 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
|
|
# 2018-09-28 GONG Jie <gongjie@linux.vnet.ibm.com>
|
|
# - Revised debug log
|
|
# - xCAT uninstallation
|
|
# 2019-03-22 GONG Jie <gongjie@linux.vnet.ibm.com>
|
|
# - Better debug log when reading repository failed
|
|
# 2019-08-15 Mark Gurevich <gurevich@us.ibm.com>
|
|
# - Added conserver-xcat to uninstall list
|
|
# 2019-10-23 Mark Gurevich <gurevich@us.ibm.com>
|
|
# - Display a list of packages that could not be uninstalled
|
|
# 2019-11-05 Mark Gurevich <gurevich@us.ibm.com>
|
|
# - Display a list of packages that will be installed before "Continue?"
|
|
# 2020-5-7 Nic Mays <Nicolas.Mays@ibm.com>
|
|
# - Handles 'stable' as a flag to install latest version via the command:
|
|
# go-xcat --xcat-version=stable install
|
|
# 2021-02-18 Mark Gurevich <gurevich@us.ibm.com>
|
|
# - On Ubuntu remove packages one at a time
|
|
# 2021-05-07 Mark Gurevich <gurevich@us.ibm.com>
|
|
# - Add support for Oracle Linux
|
|
# 2021-07-08 Peter Wong <wpeter@us.ibm.com>
|
|
# - Provide correct versions of packages to be installed
|
|
# 2021-07-27 Mark Gurevich <gurevich@us.ibm.com>
|
|
# - Add support for Rocky Linux
|
|
# 2022-11-01 Mark Gurevich <gurevich@us.ibm.com>
|
|
# - Make sure initscripts installed on RH family of OSes
|
|
# 2022-12-06 Mark Gurevich <gurevich@us.ibm.com>
|
|
# - Check for EPEL and CRB repositories on EL9 and EL10 family of OSes
|
|
# 2023-01-19 Mark Gurevich <gurevich@us.ibm.com>
|
|
# - Add support for Alma Linux
|
|
# 2026-07-20 Daniel Hilst <392820+dhilst@users.noreply.github.com>
|
|
# - Drop obsolete yaboot-xcat from the install list (kept in the uninstall
|
|
# list so existing installs are still cleaned up)
|
|
# - Do not let one unavailable package abort the whole EL install: pass
|
|
# `dnf --setopt=strict=0` so missing arch-specific packages are warned
|
|
# and skipped instead of failing the transaction
|
|
#
|
|
|
|
|
|
function usage()
|
|
{
|
|
local script="${0##*/}"
|
|
local -r 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
|
|
uninstall removes xCAT from this system
|
|
completely uninstall removes xCAT from this system and cleans up
|
|
all the traces xCAT made
|
|
|
|
Examples:
|
|
${script}
|
|
${script} install
|
|
${script} update
|
|
${script} --yes install
|
|
${script} -x 2.12 -y install
|
|
${script} --xcat-version=devel install
|
|
${script} --xcat-version=stable 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
|
|
${script} uninstall
|
|
${script} completely uninstall
|
|
|
|
xCAT: 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 secret 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 || 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 16
|
|
while read -r ; do echo "${REPLY}" ; done <<-EOF
|
|
check check the version of the installed packages
|
|
of xCAT and packages in the repository
|
|
smoke test perform basic tests of the xCAT installation
|
|
EOF
|
|
println 11
|
|
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 4
|
|
while read -r ; do echo "${REPLY}" ; done <<-EOF
|
|
${script} check
|
|
${script} smoke test
|
|
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=()
|
|
GO_XCAT_DEP_REPOSITORY_IDS=(xcat-dep)
|
|
|
|
# The package list of all the packages should be installed
|
|
GO_XCAT_INSTALL_LIST=(perl-xCAT xCAT-client xCAT xCAT-buildkit
|
|
xCAT-genesis-scripts-ppc64 xCAT-genesis-scripts-x86_64 xCAT-server
|
|
elilo-xcat grub2-xcat ipmitool-xcat syslinux-xcat
|
|
xCAT-genesis-base-ppc64 xCAT-genesis-base-x86_64 xnba-undi)
|
|
# For Debian/Ubuntu, it will need a slightly different package list
|
|
type dpkg >/dev/null 2>&1 &&
|
|
GO_XCAT_INSTALL_LIST=(perl-xcat xcat-client xcat xcat-buildkit
|
|
xcat-genesis-scripts-amd64 xcat-genesis-scripts-ppc64 xcat-server
|
|
elilo-xcat grub2-xcat ipmitool-xcat syslinux-xcat
|
|
xcat-genesis-base-amd64 xcat-genesis-base-ppc64 xnba-undi)
|
|
# The package list of all the packages should be uninstalled
|
|
GO_XCAT_UNINSTALL_LIST=("${GO_XCAT_INSTALL_LIST[@]}"
|
|
goconserver xCAT-SoftLayer xCAT-confluent xCAT-csm xCAT-genesis-builder
|
|
xCAT-genesis-openembedded-x86 xCAT-genesis-openembedded-x86_64
|
|
xCAT-genesis-openembedded-ppc64 xCAT-genesis-openembedded-ppc64le
|
|
xCAT-genesis-openembedded-armv7hf xCAT-genesis-openembedded-aarch64
|
|
xCAT-genesis-openembedded-riscv64 xCAT-genesis-openembedded-s390x
|
|
xCAT-openbmc-py xCAT-probe xCAT-test xCAT-vlan xCATsn xCAT-UI-deps
|
|
xCAT-buildkit conserver-xcat yaboot-xcat)
|
|
# For Debian/Ubuntu, it will need a slightly different package list
|
|
type dpkg >/dev/null 2>&1 &&
|
|
GO_XCAT_UNINSTALL_LIST=("${GO_XCAT_INSTALL_LIST[@]}"
|
|
goconserver xcat-confluent xcat-probe xcat-test xcat-vlan xcatsn
|
|
xcat-genesis-openembedded-x86 xcat-genesis-openembedded-x86-64
|
|
xcat-genesis-openembedded-ppc64 xcat-genesis-openembedded-ppc64le
|
|
xcat-genesis-openembedded-armv7hf xcat-genesis-openembedded-aarch64
|
|
xcat-genesis-openembedded-riscv64 xcat-genesis-openembedded-s390x
|
|
xcat-buildkit conserver-xcat)
|
|
|
|
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
|
export PATH
|
|
EL_EPEL_TEST_RPM="perl-Crypt-CBC"
|
|
EL_CRB_TEST_RPM="perl-IO-Tty"
|
|
|
|
#
|
|
# 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
|
|
check_root_or_exit
|
|
|
|
debug_log_setup
|
|
}
|
|
|
|
#
|
|
# custom_cleanup
|
|
#
|
|
function custom_cleanup()
|
|
{
|
|
debug_log_cleanup
|
|
}
|
|
|
|
#
|
|
# cleanup_n_exec Do the cleanup, then execute the command
|
|
#
|
|
# $1+ The command to execute
|
|
#
|
|
function cleanup_n_exec()
|
|
{
|
|
internal_cleanup
|
|
|
|
exec "$@"
|
|
}
|
|
|
|
function debug_log_setup()
|
|
{
|
|
local script="${0##*/}"
|
|
local -a argv=()
|
|
|
|
set -- "${BASH_ARGV[@]}"
|
|
while [ "$#" -gt "0" ]
|
|
do
|
|
argv=("$1" "${argv[@]}")
|
|
shift
|
|
done
|
|
|
|
GO_XCAT_DEBUG_LOG="${TMP_DIR}/go-xcat.log"
|
|
GO_XCAT_LOG="/tmp/go-xcat.log"
|
|
# Global debug log file descriptor
|
|
: >"${GO_XCAT_DEBUG_LOG}"
|
|
ln -f "${GO_XCAT_DEBUG_LOG}" "${GO_XCAT_LOG}"
|
|
|
|
# Log all the command line arguments
|
|
{
|
|
echo " ."
|
|
echo " ."
|
|
echo " . :."
|
|
echo " .:"
|
|
echo " ::."
|
|
echo " :.::"
|
|
echo " ::::."
|
|
echo " :::::"
|
|
echo " :::::"
|
|
echo " :::::"
|
|
echo " :::::"
|
|
echo " :::::"
|
|
echo "..:::::.."
|
|
echo " ':::::'"
|
|
echo " ':'"
|
|
echo -n "|->"
|
|
printf " %q" "${script}" "${argv[@]}"
|
|
echo
|
|
echo
|
|
} | debug_logger debug
|
|
}
|
|
|
|
function debug_log_cleanup()
|
|
{
|
|
local rc="$?"
|
|
local script="${0##*/}"
|
|
|
|
if [[ -n "${GO_XCAT_DEBUG_LOG}" && -n "${GO_XCAT_LOG}" ]]
|
|
then
|
|
{
|
|
printf "\n|-> %-24s ... exited with %s\n" "${script}" "${rc}"
|
|
echo " ......"
|
|
echo " :::::"
|
|
echo " ::::::."
|
|
echo " ' ':::::."
|
|
echo " ':::::."
|
|
echo " '::"
|
|
echo " '"
|
|
} | debug_logger debug
|
|
[[ "${rc}" -eq "0" ]] && rm -f "${GO_XCAT_LOG}"
|
|
fi
|
|
}
|
|
|
|
function debug_logger()
|
|
{
|
|
local level="$1"
|
|
|
|
while read -r
|
|
do
|
|
case "${level}" in
|
|
"debug")
|
|
;;
|
|
*)
|
|
echo "${REPLY}"
|
|
;;
|
|
esac
|
|
echo "${REPLY}" >&2
|
|
done 2>>"${GO_XCAT_DEBUG_LOG}"
|
|
}
|
|
|
|
function debug_trace()
|
|
{
|
|
local rc="$?"
|
|
|
|
# Log the function name and all the command line arguments
|
|
{
|
|
echo
|
|
echo -n ".->"
|
|
printf " %q" "$@"
|
|
echo
|
|
echo "'========"
|
|
} | debug_logger debug
|
|
|
|
# BUG - The command "$@" will be run in a subshell
|
|
"$@" 2>&1 | debug_logger
|
|
rc="${PIPESTATUS[0]}"
|
|
|
|
printf ".========\n'-> %-24s ... returned with %s\n" "${1}" "${rc}" |
|
|
debug_logger debug
|
|
|
|
return "${rc}"
|
|
}
|
|
|
|
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 os_release_value()
|
|
{
|
|
local key="$1"
|
|
local file="${2:-/etc/os-release}"
|
|
awk -F= -v key="${key}" '$1 == key {gsub(/"/, "", $2); print $2}' "${file}" 2>/dev/null
|
|
}
|
|
|
|
function check_linux_distro()
|
|
{
|
|
local distro
|
|
distro="$(os_release_value ID)"
|
|
[[ -z "${distro}" && -f /etc/redhat-release ]] && distro="rhel"
|
|
[[ -z "${distro}" && -f /etc/SuSE-release ]] && distro="sles"
|
|
[[ -z "${distro}" && -f /etc/SUSE-brand ]] && distro="sles"
|
|
echo "${distro}"
|
|
}
|
|
|
|
function check_linux_version()
|
|
{
|
|
local ver
|
|
ver="$(os_release_value 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)"
|
|
[[ -z "${ver}" && -f /etc/SUSE-brand ]] &&
|
|
ver="$(awk '/VERSION/ { print $NF }' /etc/SUSE-brand)"
|
|
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 < <(LC_ALL="C" 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
|
|
if [[ -n "${ver[i]}" ]]
|
|
then
|
|
echo "${ver[i]}"
|
|
else
|
|
echo "(not installed)"
|
|
fi
|
|
unset "name[${i}]" "ver[${i}]"
|
|
shift && continue 2
|
|
fi
|
|
done
|
|
echo "(not installed)"
|
|
shift
|
|
done
|
|
return 0
|
|
}
|
|
|
|
function check_package_version()
|
|
{
|
|
function_dispatch "${FUNCNAME[0]}" "$@"
|
|
}
|
|
|
|
# $@ package names
|
|
function check_repo_version_dnf()
|
|
{
|
|
# Note that check_repo_version_dnf must be defined before check_repo_version_yum.
|
|
# "compgen -A function check_repo_version_" returns _dnf before _yum.
|
|
# Since RHEL 8.x distros can run yum as well. If _yum is defined before _dnf,
|
|
# the _dnf function will never be used.
|
|
|
|
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
|
|
|
|
# The above query returns an array of package names and versions. Most "xcat-dep"
|
|
# packages have only one version. However, some do have multiple versions. Note that,
|
|
# given multiple versions for a package, the LATEST version MAY NOT be the right
|
|
# version for older operating systems. In addition, if there are 4 versions (or
|
|
# entires) in the array, the last entry may not be the latest version either
|
|
# due to alphanumeric sorting. Therefore, an additional dnf command is needed to
|
|
# provide the correct version to be installed.
|
|
# Note that dnf is not available before RHEL 8.x distros.
|
|
|
|
# In the following while loop, num_version keeps track on the number of versions
|
|
# of each package as the package list is scanned.
|
|
local num_version=0
|
|
|
|
# The following while loop scans the array entries. last_index points to the last
|
|
# entry of the current package being looked at.
|
|
local last_index=0
|
|
|
|
# Obtain the version of a package currently installed on the system.
|
|
local current_version=0
|
|
|
|
# Has xCAT already installed on the system?
|
|
local is_xcat_installed=0
|
|
|
|
local tmp_result=0
|
|
|
|
while [[ -n "$1" ]]
|
|
do
|
|
num_version=0
|
|
|
|
# Given a package name, locate the beginning entry of that package.
|
|
for i in "${!name[@]}"
|
|
do
|
|
if [[ "$1" = "${name[i]}" ]]
|
|
then
|
|
(( num_version++ ))
|
|
last_index=$i
|
|
fi
|
|
done
|
|
|
|
# If a package has no entry.
|
|
if [[ $num_version == "0" ]]; then
|
|
echo "(not found)"
|
|
# If a package has one version, that version is returned.
|
|
elif [[ $num_version == "1" ]]; then
|
|
echo "${ver[last_index]}"
|
|
# If a package has multiple versions, more work needs to be done.
|
|
else
|
|
# Get the current version of the package.
|
|
current_version=$(rpm -q --qf '%{version}-%{release}\n' "$1")
|
|
|
|
# Is xCAT currently installed?
|
|
is_xcat_installed=$(rpm -qa | grep -i xcat)
|
|
|
|
# If xCAT has not been installed yet.
|
|
if [[ -z $is_xcat_installed ]]
|
|
then
|
|
# Use "dnf install" to gather more data about the package.
|
|
dnf -v install "$1" --assumeno 2> /tmp/"$1"-err 1> /tmp/"$1"-1
|
|
tmp_result=$(grep "$1" /tmp/"$1"-1 | grep -v Installing)
|
|
|
|
# If the output does not have the word "Installing".
|
|
if [[ -z $tmp_result ]]
|
|
then
|
|
# Parse the $1-err file.
|
|
grep "$1" /tmp/"$1"-err | head -1 | awk '{print $9}' > /tmp/"$1"-2
|
|
# The string may have an epoch number at the front and arch at the end.
|
|
# cut, sed and rev are used to get the version only.
|
|
cut -d ":" -f2 /tmp/"$1"-2 | rev | sed s/[.]/:/ | cut -d ":" -f2 | rev
|
|
else
|
|
# If the output has the word "Installing", remove the epoch number as needed.
|
|
grep "$1" /tmp/"$1"-1 | grep -v installed | awk '{print $3}' | cut -d ":" -f2
|
|
fi
|
|
|
|
# Remove temporary files.
|
|
rm -f /tmp/"$1"-1 /tmp/"$1"-2 /tmp/"$1"-err
|
|
# If xCAT has been installed.
|
|
else
|
|
# Use "dnf update" to gather more data about the package.
|
|
dnf -v update "$1" --assumeno 2> /tmp/"$1"-err 1> /tmp/"$1"-1
|
|
grep " $1\." /tmp/"$1"-1 | grep "an upgrade" | grep -v None > /tmp/"$1"-2
|
|
|
|
# If the output has the word "upgrade".
|
|
if [[ -s /tmp/"$1"-2 ]]
|
|
then
|
|
awk '{print $4}' /tmp/"$1"-2 | cut -d ":" -f2
|
|
else
|
|
grep "Nothing to do" /tmp/"$1"-1 > /tmp/"$1"-3
|
|
# If the output has the phrase "Nothing to do", then just return the
|
|
# current version.
|
|
if [[ -s /tmp/"$1"-3 ]]
|
|
then
|
|
echo "$current_version"
|
|
else
|
|
# Else, parse the $1-err file.
|
|
grep "$1" /tmp/"$1"-err | head -1 | awk '{print $10}' > /tmp/"$1"-4
|
|
cut -d ":" -f2 /tmp/"$1"-4 | rev | sed s/[.]/:/ | cut -d ":" -f2 | rev
|
|
fi
|
|
fi
|
|
# Remove temporary files.
|
|
rm -f /tmp/"$1"-1 /tmp/"$1"-2 /tmp/"$1"-3 /tmp/"$1"-4 /tmp/"$1"-err
|
|
fi
|
|
fi
|
|
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' or \`dnf-utils' package and rerun."
|
|
local -a name=()
|
|
local -a ver=()
|
|
while read -r name ver
|
|
do
|
|
name+=("${name}")
|
|
ver+=("${ver}")
|
|
done < <(repoquery -q --qf '%{name} %{version}-%{release}' "$@" 2>/dev/null)
|
|
local -i i
|
|
|
|
# The above query returns an array of package names and versions. Most "xcat-dep"
|
|
# packages have only one version. However, some do have multiple versions. Note that,
|
|
# given multiple versions for a package, the LATEST version MAY NOT be the right
|
|
# version for older operating systems. In addition, if there are 4 versions (or
|
|
# entires) in the array, the last entry may not be the latest version either
|
|
# due to alphanumeric sorting. Therefore, an additional yum command is needed to
|
|
# provide the correct version to be installed.
|
|
|
|
|
|
# In the following while loop, num_version keeps track on the number of versions
|
|
# of each package as the package list is scanned.
|
|
local num_version=0
|
|
|
|
# The following while loop scans the array entries. last_index points to the last
|
|
# entry of the current package being looked at.
|
|
local last_index=0
|
|
|
|
# Obtain the version of a package currently installed on the system.
|
|
local current_version=0
|
|
|
|
# Has xCAT already installed on the system?
|
|
local is_xcat_installed=0
|
|
|
|
local tmp_result=0
|
|
|
|
while [[ -n "$1" ]]
|
|
do
|
|
num_version=0
|
|
|
|
# Given a package name, locate the beginning entry of that package.
|
|
for i in "${!name[@]}"
|
|
do
|
|
if [[ "$1" = "${name[i]}" ]]
|
|
then
|
|
(( num_version++ ))
|
|
last_index=$i
|
|
fi
|
|
done
|
|
|
|
# If a package has no entry.
|
|
if [[ $num_version == "0" ]]; then
|
|
echo "(not found)"
|
|
# If a package has one version, just return that version.
|
|
elif [[ $num_version == "1" ]]; then
|
|
echo "${ver[last_index]}"
|
|
# If a package has multiple versions, more work needs to be done.
|
|
else
|
|
# Get the current version of the package.
|
|
current_version=$(rpm -q --qf '%{version}-%{release}\n' "$1")
|
|
|
|
# Is xCAT currently installed?
|
|
is_xcat_installed=$(rpm -qa | grep -i xcat)
|
|
|
|
# If xCAT has not been installed yet.
|
|
if [[ -z $is_xcat_installed ]]
|
|
then
|
|
# Use "yum install" to gather more data about the package.
|
|
yum -v install "$1" --assumeno 2> /tmp/"$1"-err 1> /tmp/"$1"-1
|
|
tmp_result=$(grep "$1" /tmp/"$1"-1 | grep -v Installing)
|
|
|
|
# If the output does not have the word "Installing".
|
|
if [[ -z $tmp_result ]]
|
|
then
|
|
# Parse the $1-err file.
|
|
grep "$1" /tmp/"$1"-err | head -1 | awk '{print $9}' > /tmp/"$1"-2
|
|
# The string may have an epoch number at the front and arch at the end.
|
|
# cut, sed and rev are used to get the version only.
|
|
cut -d ":" -f2 /tmp/"$1"-2 | rev | sed s/[.]/:/ | cut -d ":" -f2 | rev
|
|
else
|
|
# If the output has the word "Installing", remove the epoch number as needed.
|
|
grep "$1" /tmp/"$1"-1 | grep -v installed | awk '{print $3}' | cut -d ":" -f2
|
|
fi
|
|
|
|
# Remove temporary files.
|
|
rm -f /tmp/"$1"-1 /tmp/"$1"-2 /tmp/"$1"-err
|
|
# If xCAT has been installed.
|
|
else
|
|
# Use "yum update" to gather more data about the package.
|
|
yum -v update "$1" --assumeno 2> /tmp/"$1"-err 1> /tmp/"$1"-1
|
|
grep " $1\." /tmp/"$1"-1 | grep "an upgrade" | grep -v None > /tmp/"$1"-2
|
|
|
|
# If the output has the word "upgrade".
|
|
if [[ -s /tmp/"$1"-2 ]]
|
|
then
|
|
awk '{print $4}' /tmp/"$1"-2 | cut -d ":" -f2
|
|
else
|
|
grep "Nothing to do" /tmp/"$1"-1 > /tmp/"$1"-3
|
|
# If the output has the phrase "Nothing to do", then just return the
|
|
# current version.
|
|
if [[ -s /tmp/"$1"-3 ]]
|
|
then
|
|
echo "$current_version"
|
|
else
|
|
# Else, parse the $1-err file.
|
|
grep "$1" /tmp/"$1"-err | head -1 | awk '{print $10}' > /tmp/"$1"-4
|
|
cut -d ":" -f2 /tmp/"$1"-4 | rev | sed s/[.]/:/ | cut -d ":" -f2 | rev
|
|
fi
|
|
fi
|
|
# Remove temporary files.
|
|
rm -f /tmp/"$1"-1 /tmp/"$1"-2 /tmp/"$1"-3 /tmp/"$1"-4 /tmp/"$1"-err
|
|
fi
|
|
fi
|
|
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[0]}" "$@"
|
|
}
|
|
|
|
# $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
|
|
local -a lists=()
|
|
local -a packages=()
|
|
local p
|
|
local q
|
|
|
|
for p in \
|
|
"/var/lib/apt/lists/"*"_${repo_id}_dists"*"_main_binary-"*"_Packages"
|
|
do
|
|
[[ -f "${p}" && -r "${p}" ]] && lists+=("${p}")
|
|
done
|
|
# For the `devel' branch of the online repo for apt, it has the
|
|
# subdirectory name of `core-snap' instead of `xcat-core'.
|
|
[[ "${repo_id}" == "xcat-core" ]] &&
|
|
for p in \
|
|
"/var/lib/apt/lists/"*"_core-snap_dists"*"_main_binary-"*"_Packages"
|
|
do
|
|
[[ -f "${p}" && -r "${p}" ]] && lists+=("${p}")
|
|
done
|
|
[[ "${#lists[@]}" -eq "0" ]] && return 1
|
|
|
|
while read -r q
|
|
do
|
|
for p in "${packages[@]}"
|
|
do
|
|
[[ "${q}" == "${p}" ]] && continue 2
|
|
done
|
|
packages+=("${q}")
|
|
done < <(awk '/^Package: / { print $2 }' "${lists[@]}" 2>/dev/null)
|
|
|
|
echo "${packages[@]}"
|
|
}
|
|
|
|
# $1 repo id
|
|
function get_package_list()
|
|
{
|
|
function_dispatch "${FUNCNAME[0]}" "$@"
|
|
}
|
|
|
|
function download_file_curl()
|
|
{
|
|
local script="${0##*/}"
|
|
local -r 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" ;;
|
|
91) echo -n "invalid SSL certificate status" ;;
|
|
92) echo -n "stream error in HTTP/2 framing layer" ;;
|
|
*) echo -n "unknown error" ;;
|
|
esac
|
|
echo ")"
|
|
echo " ... while downloading \`${url}'"
|
|
fi >&2
|
|
[[ "${rc}" -eq "0" ]]
|
|
}
|
|
|
|
function download_file_wget()
|
|
{
|
|
local script="${0##*/}"
|
|
local -r 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[0]}" "$@"
|
|
}
|
|
|
|
# $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"
|
|
}
|
|
|
|
# Dirty workaround on SLES11 SP4
|
|
# For SLES11, set gpgcheck=0
|
|
#
|
|
# $1 repo file
|
|
function github_issue_5503_workaround2()
|
|
{
|
|
[[ "${GO_XCAT_LINUX_DISTRO}" = "sles" ]] || return 0
|
|
[[ "${GO_XCAT_LINUX_VERSION}" =~ ^11(\.[0-4]){0,1}$ ]] || return 0
|
|
local repo_file="$1"
|
|
local tmp="${TMP_DIR}/tmp_repo_file_${repo_id}.repo.$$"
|
|
cp "${repo_file}" "${tmp}"
|
|
exit_if_bad "$?" "Copy file failed \`${repo_file}' -> \`${tmp}'"
|
|
while read -r
|
|
do
|
|
case "${REPLY}" in
|
|
"gpgcheck=1")
|
|
echo "gpgcheck=0"
|
|
;;
|
|
*)
|
|
echo "${REPLY}"
|
|
;;
|
|
esac
|
|
done <"${tmp}" >"${repo_file}"
|
|
}
|
|
|
|
# $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}"
|
|
# For SLES11, set gpgcheck=0
|
|
github_issue_5503_workaround2 "${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[0]}" "$@"
|
|
}
|
|
|
|
# $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" || return 1
|
|
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 policy="${3:-}"
|
|
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 <<-EOF
|
|
[${repo_id}]
|
|
name=${repo_id}
|
|
baseurl=${url%/}
|
|
enabled=1
|
|
gpgcheck=1
|
|
gpgkey=${url%/}/repodata/repomd.xml.key
|
|
EOF
|
|
if [[ "${policy}" = "optional" ]]; then
|
|
echo "repo_gpgcheck=1"
|
|
echo "skip_if_unavailable=1"
|
|
fi
|
|
} >"${tmp}"
|
|
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 <<-EOF
|
|
[${repo_id}]
|
|
name=${repo_id}
|
|
baseurl=file://${url%/}
|
|
enabled=1
|
|
EOF
|
|
if [[ "${policy}" = "optional" ]]; then
|
|
echo "skip_if_unavailable=1"
|
|
fi
|
|
} >"${tmp}"
|
|
if [ -f "${url%/}/repodata/repomd.xml.asc" ]
|
|
then
|
|
echo "gpgcheck=1" >>"${tmp}"
|
|
[[ "${policy}" != "optional" ]] \
|
|
|| echo "repo_gpgcheck=1" >>"${tmp}"
|
|
else
|
|
echo "gpgcheck=0" >>"${tmp}"
|
|
fi
|
|
if [ -f "${url%/}/repodata/repomd.xml.key" ]
|
|
then
|
|
echo "gpgkey=file://${url%/}/repodata/repomd.xml.key" >>"${tmp}"
|
|
fi
|
|
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
|
|
codename="$(awk -F= '/^DISTRIB_CODENAME=/{gsub(/"/, "", $2); print $2}' /etc/lsb-release 2>/dev/null)"
|
|
[[ -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 [$([ ! -f "${url}/dists/${codename}/Release.gpg" ] &&
|
|
echo "allow-insecure=yes ")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[0]}" "$@"
|
|
}
|
|
|
|
# $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.
|
|
grep -l "^\[${repo_id}\]$" "/etc/yum.repos.d/"*".repo" 2>/dev/null | xargs -r rm -f
|
|
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
|
|
;;
|
|
"xcat-dep-common")
|
|
mv /etc/yum.repos.d/xCAT-dep-common.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}" 2> /dev/null
|
|
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
|
|
;;
|
|
"xcat-dep-common")
|
|
mv /etc/zypp/repos.d/xCAT-dep-common.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[0]}" "$@"
|
|
}
|
|
|
|
# $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}"
|
|
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[0]}" "$@"
|
|
}
|
|
|
|
function add_xcat_dep_common_repo_yum_or_zypper()
|
|
{
|
|
type yum >/dev/null 2>&1 || type zypper >/dev/null 2>&1 || return 255
|
|
local url="$1"
|
|
local ver="$2"
|
|
local common_url=""
|
|
local metadata=""
|
|
[[ -z "${ver}" ]] && ver="latest"
|
|
|
|
[[ -z "${url}" ]] &&
|
|
url="${GO_XCAT_DEFAULT_BASE_URL}/yum/${ver}/xcat-dep"
|
|
case "${url##*/}" in
|
|
*".repo"|*".tar"|*".tar.Z"|*".tar.bz"|*".tar.bz2"|*".tar.gz"|*".tar.xz"|*".tbz"|*".tbz2"|*".tgz"|*".tz"|*".txz")
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
case "${url%%://*}" in
|
|
"ftp"|"http"|"https")
|
|
common_url="${url%/}/common"
|
|
metadata="${TMP_DIR}/xcat-dep-common-repomd.xml"
|
|
download_file "${common_url}/repodata/repomd.xml" "${metadata}" \
|
|
>/dev/null 2>&1 || return 0
|
|
;;
|
|
"file")
|
|
url="${url#file://}"
|
|
[[ "${url:0:1}" = "/" ]] || url="${PWD}/${url}"
|
|
common_url="${url%/}/common"
|
|
[[ -f "${common_url}/repodata/repomd.xml" ]] || return 0
|
|
;;
|
|
*)
|
|
[[ "${url:0:1}" = "/" ]] || url="${PWD}/${url}"
|
|
common_url="${url%/}/common"
|
|
[[ -f "${common_url}/repodata/repomd.xml" ]] || return 0
|
|
;;
|
|
esac
|
|
|
|
add_repo_by_url_yum_or_zypper \
|
|
"${common_url}" "xcat-dep-common" optional || return 0
|
|
}
|
|
|
|
function xcat_dep_common_repo_configured()
|
|
{
|
|
[[ -f /etc/yum.repos.d/xcat-dep-common.repo \
|
|
|| -f /etc/zypp/repos.d/xcat-dep-common.repo ]]
|
|
}
|
|
|
|
function refresh_xcat_dep_repository_ids()
|
|
{
|
|
GO_XCAT_DEP_REPOSITORY_IDS=(xcat-dep)
|
|
xcat_dep_common_repo_configured \
|
|
&& GO_XCAT_DEP_REPOSITORY_IDS+=(xcat-dep-common)
|
|
:
|
|
}
|
|
|
|
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}" ;;
|
|
"ol"*) distro="rh${distro#ol}" ;;
|
|
"rocky"*) distro="rh${distro#rocky}" ;;
|
|
"alma"*) distro="rh${distro#almalinux}" ;;
|
|
"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}"
|
|
;;
|
|
*)
|
|
local repository_root="${url}"
|
|
url="${repository_root}/${distro}/${GO_XCAT_ARCH}"
|
|
add_repo_by_url_yum_or_zypper "${url}" "xcat-dep" || return "$?"
|
|
add_xcat_dep_common_repo_yum_or_zypper "${repository_root}" "${ver}"
|
|
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}"
|
|
local repository_root="${url}"
|
|
url="${repository_root}/${distro}/${GO_XCAT_ARCH}"
|
|
add_repo_by_url_yum_or_zypper "${url}" "xcat-dep" || return "$?"
|
|
add_xcat_dep_common_repo_yum_or_zypper "${repository_root}" "${ver}"
|
|
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[0]}" "$@"
|
|
}
|
|
|
|
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[0]}" "$@"
|
|
}
|
|
|
|
function install_packages_dnf()
|
|
{
|
|
type dnf >/dev/null 2>&1 || return 255
|
|
el_epel_and_crb_check dnf
|
|
local -a yes=()
|
|
[[ "$1" = "-y" ]] && yes=("-y") && shift
|
|
dnf --nogpgcheck "${yes[@]}" install initscripts
|
|
dnf --nogpgcheck --setopt=strict=0 "${yes[@]}" install "$@"
|
|
}
|
|
|
|
function install_packages_yum()
|
|
{
|
|
type yum >/dev/null 2>&1 || return 255
|
|
el_epel_and_crb_check yum
|
|
local -a yes=()
|
|
[[ "$1" = "-y" ]] && yes=("-y") && shift
|
|
yum --nogpgcheck "${yes[@]}" install initscripts
|
|
yum --nogpgcheck "${yes[@]}" install "$@"
|
|
}
|
|
|
|
# Dirty workaround on SLES 11 SP4
|
|
function github_issue_5503_workaround()
|
|
{
|
|
[[ "${GO_XCAT_LINUX_DISTRO}" = "sles" ]] || return 0
|
|
[[ "${GO_XCAT_LINUX_VERSION}" =~ ^11(\.[0-4]){0,1}$ ]] || return 0
|
|
rpm -e --allmatches gpg-pubkey-ca548a47-5b2c830b >/dev/null 2>&1
|
|
return 0
|
|
}
|
|
|
|
# Workaround for SLES 15 deprecating old initscript commands
|
|
function github_issue_6525_workaround()
|
|
{
|
|
[[ "${GO_XCAT_LINUX_DISTRO}" = "sles" ]] || return 0
|
|
[[ "${GO_XCAT_LINUX_VERSION}" =~ ^15 ]] || return 0
|
|
zypper install net-tools-deprecated insserv-compat
|
|
return 0
|
|
}
|
|
|
|
# Whether an enabled repository carries the package for this architecture. An
|
|
# installed copy and a source repository do not count, so a binary repository
|
|
# that was disabled is still reported. A failed query stops the run with the
|
|
# package manager's own error.
|
|
function repo_carries()
|
|
{
|
|
local rpm="$1"
|
|
local found errors
|
|
errors="$(mktemp)"
|
|
found="$(${action} repoquery -q --arch "${GO_XCAT_ARCH},noarch" --qf '%{name}' "${rpm}" 2>"${errors}")" || {
|
|
cat "${errors}"
|
|
rm -f "${errors}"
|
|
echo "Could not query the package repositories with '${action} repoquery'"
|
|
exit 1
|
|
}
|
|
rm -f "${errors}"
|
|
grep -Fxq -- "${rpm}" <<<"${found}"
|
|
}
|
|
|
|
# Check for EPEL and CRB repositories when installing on RH family of OSes.
|
|
# CentOS Stream reports the major version alone, the others report major.minor.
|
|
function el_epel_and_crb_check()
|
|
{
|
|
action="$*" # Passed parameter will only be 'yum' or 'dnf'
|
|
local major
|
|
if [[ "${GO_XCAT_LINUX_DISTRO}" = "fedora" ]]
|
|
then
|
|
# For Fedora, version 35 is equivalent to EL9
|
|
# But since xCAT currently does not support that version, just
|
|
# return and let 'yum install' fail if needed packages are not
|
|
# found
|
|
return 0
|
|
else
|
|
[[ "${GO_XCAT_LINUX_VERSION}" =~ ^(9|10)(\.[0-9]+)?$ ]] || return 0
|
|
fi
|
|
major="${GO_XCAT_LINUX_VERSION%%.*}"
|
|
if ! repo_carries "${EL_EPEL_TEST_RPM}"
|
|
then
|
|
echo "
|
|
Installation on ${GO_XCAT_LINUX_DISTRO} ${GO_XCAT_LINUX_VERSION} requires EPEL repository to be enabled"
|
|
echo "Running '${action} install https://dl.fedoraproject.org/pub/epel/epel-release-latest-${major}.noarch.rpm' will enable EPEL repository"
|
|
exit 1
|
|
fi
|
|
if ! repo_carries "${EL_CRB_TEST_RPM}"
|
|
then
|
|
echo "
|
|
Installation on ${GO_XCAT_LINUX_DISTRO} ${GO_XCAT_LINUX_VERSION} requires CRB repository to be enabled"
|
|
echo "Running '${action} update epel-release' and then 'crb enable' will enable it on Red Hat Enterprise Linux, Rocky Linux, AlmaLinux and CentOS Stream"
|
|
echo "On Oracle Linux, running 'dnf config-manager --enable ol${major}_codeready_builder' will enable it"
|
|
exit 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
function install_packages_zypper()
|
|
{
|
|
type zypper >/dev/null 2>&1 || return 255
|
|
github_issue_5503_workaround
|
|
github_issue_6525_workaround
|
|
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[0]}" "$@"
|
|
}
|
|
|
|
function remove_package_dnf()
|
|
{
|
|
type dnf >/dev/null 2>&1 || return 255
|
|
local -a yes=()
|
|
[[ "$1" = "-y" ]] && yes=("-y") && shift
|
|
dnf --nogpgcheck "${yes[@]}" remove "$@"
|
|
}
|
|
|
|
function remove_package_yum()
|
|
{
|
|
type yum >/dev/null 2>&1 || return 255
|
|
local -a yes=()
|
|
[[ "$1" = "-y" ]] && yes=("-y") && shift
|
|
yum --nogpgcheck "${yes[@]}" remove "$@"
|
|
}
|
|
|
|
function remove_package_zypper()
|
|
{
|
|
type zypper >/dev/null 2>&1 || return 255
|
|
local -a yes=()
|
|
local ret=""
|
|
[[ "$1" = "-y" ]] && yes=("-n") && shift
|
|
zypper --no-gpg-checks "${yes[@]}" remove --force-resolution "$@"
|
|
ret="$?"
|
|
case "${ret}" in
|
|
"104")
|
|
# ZYPPER_EXIT_INF_CAP_NOT_FOUND
|
|
ret="0"
|
|
;;
|
|
esac
|
|
return "${ret}"
|
|
}
|
|
|
|
function remove_package_apt()
|
|
{
|
|
type apt-get >/dev/null 2>&1 || return 255
|
|
local -a yes=()
|
|
[[ "$1" = "-y" ]] && yes=("-y") && shift
|
|
# For each package, remove one at a time
|
|
for package in "$@"
|
|
do
|
|
apt-get --allow-unauthenticated remove "${yes[@]}" "${package}"
|
|
warn_if_bad "$?" "Unable to remove xCAT package ${package}"
|
|
done
|
|
}
|
|
|
|
function remove_package()
|
|
{
|
|
function_dispatch "${FUNCNAME[0]}" "$@"
|
|
}
|
|
|
|
# $1 -y
|
|
function purge_package_apt()
|
|
{
|
|
type apt-get >/dev/null 2>&1 || return 255
|
|
local -a yes=()
|
|
[[ "$1" = "-y" ]] && yes=("-y") && shift
|
|
# For each package, remove one at a time
|
|
for package in "$@"
|
|
do
|
|
apt-get --allow-unauthenticated purge "${yes[@]}" "${package}"
|
|
warn_if_bad "$?" "Unable to purge xCAT package ${package}"
|
|
done
|
|
}
|
|
|
|
function purge_package_others()
|
|
{
|
|
remove_package "$@"
|
|
}
|
|
|
|
# $1 -y
|
|
function purge_package()
|
|
{
|
|
function_dispatch "${FUNCNAME[0]}" "$@"
|
|
}
|
|
|
|
# $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[@]}"
|
|
}
|
|
|
|
# $1 -y
|
|
function uninstall_xcat()
|
|
{
|
|
remove_package "$@" "${GO_XCAT_UNINSTALL_LIST[@]}"
|
|
}
|
|
|
|
function kill_xcat()
|
|
{
|
|
local f=""
|
|
|
|
for f in /var/run/xcat{d,/{main,udp,install,cmdlog}service}.pid
|
|
do
|
|
[[ -f "${f}" ]] && kill -TERM "$(<"${f}")" 2>/dev/null
|
|
done
|
|
|
|
sleep 1
|
|
|
|
for f in /var/run/xcat{d,/{main,udp,install,cmdlog}service}.pid
|
|
do
|
|
[[ -f "${f}" ]] && kill -KILL "$(<"${f}")" 2>/dev/null
|
|
done
|
|
|
|
return 0
|
|
}
|
|
|
|
# Remove all xCAT related directories and files
|
|
function trash_xcat()
|
|
{
|
|
rm -f /etc/init.d/xcatpostinit1
|
|
rm -f /etc/systemd/system/xcatpostinit1.service
|
|
rm -f /etc/systemd/system/multi-user.target.wants/xcatd.service
|
|
rm -f /etc/tftpmapfile4xcat.conf
|
|
rm -f /etc/profile.d/xcat.{c,}sh
|
|
rm -rf /etc/xcat
|
|
rm -rf /etc/xcatdockerca
|
|
rm -f /etc/apt/sources.list.d/xcat-{core,dep}.list
|
|
rm -f /etc/yum.repos.d/xCAT-{core,dep,dep-common}.repo{,.nouse}
|
|
rm -f /etc/yum.repos.d/xcat-{core,dep,dep-common}.repo
|
|
rm -f /etc/zypp/repos.d/xCAT-{core,dep,dep-common}.repo{,.nouse}
|
|
rm -f /etc/zypp/repos.d/xcat-{core,dep,dep-common}.repo
|
|
rm -rf /install/postscripts
|
|
rm -rf /opt/xcat
|
|
rm -rf /root/.xcat
|
|
rm -rf /root/xcat-dbback
|
|
rm -rf /tftpboot/xcat
|
|
rm -rf /var/lock/xcat
|
|
rm -rf /var/log/xcat
|
|
rm -rf /xcatpost
|
|
# For goconserver
|
|
rm -rf /etc/goconserver
|
|
rm -rf /var/lib/goconserver
|
|
rm -rf /var/log/goconserver
|
|
|
|
return 0
|
|
}
|
|
|
|
function uninstall_xcat_completely()
|
|
{
|
|
purge_package -y "${GO_XCAT_UNINSTALL_LIST[@]}"
|
|
|
|
kill_xcat
|
|
trash_xcat
|
|
|
|
return 0
|
|
}
|
|
|
|
function list_xcat_packages()
|
|
{
|
|
GO_XCAT_CORE_PACKAGE_LIST=($(get_package_list xcat-core))
|
|
GO_XCAT_DEP_PACKAGE_LIST=($(
|
|
for repo_id in "${GO_XCAT_DEP_REPOSITORY_IDS[@]}"
|
|
do
|
|
get_package_list "${repo_id}"
|
|
done | tr ' ' '\n' | sort -u
|
|
))
|
|
|
|
[ "${#GO_XCAT_CORE_PACKAGE_LIST[@]}" -gt "0" ]
|
|
warn_if_bad "$?" "Failed to get package list from repository \`xcat-core'." || return 1
|
|
[ "${#GO_XCAT_DEP_PACKAGE_LIST[@]}" -gt "0" ]
|
|
warn_if_bad "$?" "Failed to get package list from repository \`xcat-dep'." || return 1
|
|
|
|
local -i cols
|
|
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[@]}")
|
|
}
|
|
|
|
#
|
|
# ask_to_continue Ask to continue
|
|
#
|
|
# Exits (not returns) if get negative reply from end user.
|
|
# This function is intend to read from STDIN.
|
|
#
|
|
# $1 -y
|
|
# $2 Prompt
|
|
#
|
|
function ask_to_continue()
|
|
{
|
|
[[ "$1" = "-y" ]] && return 0
|
|
shift
|
|
local prompt="$1"
|
|
|
|
echo
|
|
echo "${prompt}"
|
|
echo | debug_logger debug
|
|
echo ".-> ${prompt}" | debug_logger debug
|
|
while :
|
|
do
|
|
read -r -p "Continue? [y/n] "
|
|
echo "'-> Continue? [y/n] ... ${REPLY}" | debug_logger debug
|
|
case "${REPLY}" in
|
|
"Y"*|"y"*)
|
|
break
|
|
;;
|
|
"N"*|"n"*)
|
|
echo "Good-bye!"
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Invalid response!"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
return 0
|
|
}
|
|
|
|
# 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
|
|
|
|
# Call function list_xcat_packages to fill up global array
|
|
# GO_XCAT_CORE_PACKAGE_LIST
|
|
# And the output will be logged into the debug log.
|
|
#
|
|
# Missing command `repoquery' may cause list_xcat_packages fail,
|
|
# in that case, just skip this test.
|
|
list_xcat_packages
|
|
|
|
while read -r
|
|
do
|
|
[[ "${REPLY}" = "(not installed)" ]] && continue
|
|
[[ -z "${ver}" ]] && ver="${REPLY%%-*}"
|
|
[[ "${ver}" = "${REPLY%%-*}" ]]
|
|
(( ret += $? ))
|
|
done < <(check_package_version "${GO_XCAT_CORE_PACKAGE_LIST[@]}")
|
|
|
|
[ "${ret}" -ne "0" ] && echo
|
|
warn_if_bad "${ret}" "xCAT packages version mismatch"
|
|
|
|
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{d,/{main,udp,install,cmdlog}service}.pid
|
|
do
|
|
[ -f "${f}" ]
|
|
warn_if_bad "$?" "${f}: no such file" || continue
|
|
|
|
kill -0 "$(<"${f}")" >/dev/null 2>&1
|
|
warn_if_bad "$?" "Process with an ID $(<"${f}") is not running"
|
|
(( ret += $? ))
|
|
done
|
|
|
|
return "${ret}"
|
|
}
|
|
|
|
# Test case 002
|
|
# Check if command lsdef can be run
|
|
function test_case_002_lsdef()
|
|
{
|
|
bash -c "source /etc/profile.d/xcat.sh && lsdef" >/dev/null 2>&1
|
|
warn_if_bad "$?" "Attempt of run \`lsdef' failed"
|
|
}
|
|
|
|
# Perform basic smoke testing
|
|
function smoke_testing()
|
|
{
|
|
local test_case=""
|
|
local -i ret=0
|
|
|
|
for test_case in $(compgen -A function "test_case_")
|
|
do
|
|
debug_trace "${test_case}"
|
|
warn_if_bad "$?" "Something went wrong. :'(" || return 1
|
|
done
|
|
|
|
echo
|
|
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 "...... "
|
|
}
|
|
|
|
# $1 0 (pass) or non-zero (fail).
|
|
function boo_boo_if_bad()
|
|
{
|
|
local -i rc="$1"
|
|
|
|
# Ignore if no problems
|
|
[ "${rc}" -eq "0" ] && return 0
|
|
|
|
debug_logger <<-EOF
|
|
|
|
Boo-boo
|
|
=======
|
|
|
|
Something went wrong. :(
|
|
|
|
Please check log file \`${GO_XCAT_LOG}' for more details.
|
|
EOF
|
|
|
|
exit "${rc}"
|
|
}
|
|
|
|
#
|
|
# |\/| _.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=}"
|
|
;;
|
|
"-x"|"--xcat-version")
|
|
shift
|
|
GO_XCAT_VERSION="$1"
|
|
;;
|
|
"--xcat-version="*)
|
|
GO_XCAT_VERSION="${1##--xcat-version=}"
|
|
if [ "${GO_XCAT_VERSION}" = "stable" ];
|
|
then
|
|
GO_XCAT_VERSION="latest"
|
|
fi
|
|
;;
|
|
"-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"
|
|
case "$1 $2" in
|
|
"completely uninstall"|"smoke test")
|
|
GO_XCAT_ACTION="$1 $2"
|
|
shift
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
case "${GO_XCAT_ACTION}" in
|
|
"away")
|
|
GO_XCAT_YES=("-y")
|
|
;;
|
|
"completely uninstall")
|
|
GO_XCAT_ACTION="away"
|
|
;;
|
|
"check"|"install"|"uninstall"|"update")
|
|
;;
|
|
"smoke test")
|
|
smoke_testing
|
|
exit "$?"
|
|
;;
|
|
"")
|
|
usage
|
|
exit 1
|
|
;;
|
|
*)
|
|
warn_if_bad 1 "invalid action -- \`${GO_XCAT_ACTION}'"
|
|
exit_if_bad 1 "Try \`$0 --help' for more information"
|
|
;;
|
|
esac # case "${GO_XCAT_ACTION}" in
|
|
|
|
GO_XCAT_OS="$(check_os)"
|
|
GO_XCAT_ARCH="$(check_arch)"
|
|
|
|
debug_logger <<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)"
|
|
|
|
debug_logger <<EOF
|
|
Linux Distribution: ${GO_XCAT_LINUX_DISTRO}
|
|
Version: ${GO_XCAT_LINUX_VERSION}
|
|
EOF
|
|
|
|
case "${GO_XCAT_LINUX_DISTRO}" in
|
|
"centos"|"fedora"|"rhel"|"sles"|"ubuntu"|"ol"|"rocky"|"almalinux")
|
|
;;
|
|
*)
|
|
warn_if_bad 1 "${GO_XCAT_LINUX_DISTRO}: unsupported Linux distro"
|
|
;;
|
|
esac
|
|
|
|
debug_logger debug <<EOF
|
|
|
|
Host Name: ${HOSTNAME%%.*}
|
|
Bash Version: ${BASH_VERSION}
|
|
EOF
|
|
printf "%-19s %s\n\n" "${0##*/} Version:" "$(version)" | debug_logger
|
|
|
|
case "${GO_XCAT_ACTION}" in
|
|
"away"|"uninstall")
|
|
# Remove xCAT
|
|
ask_to_continue "${GO_XCAT_YES[0]}" "xCAT is going to be ${GO_XCAT_ACTION/away/trash}ed."
|
|
|
|
case "${GO_XCAT_ACTION}" in
|
|
"away")
|
|
debug_trace uninstall_xcat_completely
|
|
|
|
debug_logger <<-EOF
|
|
|
|
xCAT has been uninstalled.
|
|
To install again - https://xcat.org/download.html
|
|
EOF
|
|
;;
|
|
"uninstall")
|
|
debug_trace uninstall_xcat -y
|
|
|
|
debug_logger <<-EOF
|
|
|
|
xCAT has been uninstalled.
|
|
To install again - https://xcat.org/download.html
|
|
EOF
|
|
;;
|
|
esac
|
|
exit 0
|
|
;;
|
|
esac # case "${GO_XCAT_ACTION}" in
|
|
|
|
echo
|
|
echo -n "Reading repositories "
|
|
show_progress_meters
|
|
ERR_MSG="$(
|
|
{
|
|
echo
|
|
|
|
if [ "check" == "${GO_XCAT_ACTION}" ]
|
|
then
|
|
debug_trace update_repo && exit 0
|
|
exit 1
|
|
fi
|
|
|
|
if debug_trace add_xcat_core_repo -y \
|
|
"${GO_XCAT_CORE_URL}" "${GO_XCAT_VERSION}"
|
|
then
|
|
if debug_trace add_xcat_dep_repo -y \
|
|
"${GO_XCAT_DEP_URL}" "${GO_XCAT_VERSION}"
|
|
then
|
|
debug_trace update_repo && exit 0
|
|
debug_trace remove_repo "xcat-dep-common"
|
|
debug_trace remove_repo "xcat-dep"
|
|
fi
|
|
debug_trace remove_repo "xcat-core"
|
|
fi
|
|
exit 1
|
|
} 2>&1)"
|
|
RET="$?"
|
|
stop_progress_meters
|
|
if [[ "${RET}" -ne 0 ]]
|
|
then
|
|
echo "failed"
|
|
echo "${ERR_MSG}" >&2
|
|
boo_boo_if_bad "${RET}"
|
|
fi
|
|
echo "done"
|
|
refresh_xcat_dep_repository_ids
|
|
|
|
case "${GO_XCAT_ACTION}" in
|
|
"check")
|
|
list_xcat_packages
|
|
;;
|
|
"install"|"update")
|
|
GO_XCAT_INSTALLER="${GO_XCAT_ACTION}_xcat"
|
|
list_xcat_packages
|
|
ask_to_continue "${GO_XCAT_YES[0]}" "xCAT is going to be ${GO_XCAT_ACTION/%e/}ed."
|
|
# Use `-y' here. Since the STDOUT is redirected.
|
|
# `yum' does not display the prompt message properly when
|
|
# working with redirected I/O.
|
|
debug_trace "${GO_XCAT_INSTALLER}" -y
|
|
RET="$?"
|
|
if [[ "${RET}" -eq "0" ]]
|
|
then
|
|
# xCAT has been installed and so far so good
|
|
smoke_testing >/dev/null 2>&1
|
|
RET="$?"
|
|
[ "${RET}" -ne "0" ] && echo
|
|
warn_if_bad "${RET}" "xCAT smoke testing failed."
|
|
fi
|
|
|
|
boo_boo_if_bad "${RET}"
|
|
|
|
case "${GO_XCAT_ACTION}" in
|
|
"install")
|
|
# Only print out this message on install
|
|
debug_logger <<-EOF
|
|
|
|
xCAT has been installed!
|
|
========================
|
|
|
|
If this is the very first time xCAT has been installed, run one of the
|
|
following commands to set the environment variables.
|
|
|
|
For sh:
|
|
source /etc/profile.d/xcat.sh
|
|
|
|
For csh:
|
|
source /etc/profile.d/xcat.csh
|
|
EOF
|
|
;;
|
|
"update")
|
|
debug_logger <<-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
|