mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-26 08:55:24 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1836 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1836 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash
 | |
| #
 | |
| # go-xcat - Install xCAT automatically.
 | |
| #
 | |
| # Version 1.0.29
 | |
| #
 | |
| # 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
 | |
| 				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}" "$@"
 | |
| }
 | |
| 
 | |
| #       $@      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 "$@"
 | |
| }
 | |
| 
 | |
| # 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
 | |
| }
 | |
| 
 | |
| function install_packages_zypper()
 | |
| {
 | |
| 	type zypper >/dev/null 2>&1 || return 255
 | |
| 	github_issue_5503_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}" "$@"
 | |
| }
 | |
| 
 | |
| #       $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
 |