#!/bin/bash
set -e
#
# HTCondor for Linux Quick Install script
#
# For the installation steps, including how to verify the contents of
# this file, see:
#
#   https://htcondor.readthedocs.io/en/latest/getting-htcondor/
#
# This script is meant for quick & easy install via:
#
#   $ sudo curl -fsSL https://get.htcondor.org | /bin/bash -s -- --no-dry-run
#

usage() {
	cat <<-EOF
	Specify only one of the following:
	--dist		: Display detected operating system and exit
	-h, --help	: Display this message and exit
	--download	: Download the tarball for a user-level installation and exit.
	--dry-run	: Do not install, just print commands [default]
	--no-dry-run	: Issue all the commands neeed to install HTCondor

	Installation options:
	--channel NAME	: Specify version channel to install; NAME can be
	    current: Most recent release with new features [default]
	    stable : Most recent release with only bug-fixes
	--password	: Set the password used to secure the pool.  Use only if
	          	  nobody else can log into the machine.  Otherwise specify
	          	  in the environment (GET_HTCONDOR_PASSWORD) or interactively.
	--shared-filesystem-domain NAME : Specifies that machines installed with
	    the same NAME share a filesystem.

	Installation options, specify only one:
	--minicondor            : Install a complete stand-alone HTCondor.  [default]
	--central-manager NAME	: Install as the central manager role.
	--submit NAME		: Install as the submit role.
	--execute NAME		: Install as the execute role.
	     The NAME of central manager's machine must be a DNS name resolvable
	     on all the machines in the pool, or an IP address.
	EOF
	exit 0
}

command_exists() {
	command -v "$@" > /dev/null 2>&1
}

install_config_file() {
	# Install a config file by either copying it from examples dir, or if
	# that does not exist, curl it.  Hopefully we do not need to curl it.
	if [ -r "/usr/share/condor/get_configs/$@" ]; then
		cp "/usr/share/condor/get_configs/$@" /etc/condor/config.d/.
		chmod 644 "/etc/condor/config.d/$@"
	fi
}

is_download() {
	[[ $DOWNLOAD ]]
}

is_dry_run() {
	[[ $DRY_RUN ]]
}

is_display_dist() {
	[[ $DIST ]]
}

is_darwin() {
	case "$(uname -s)" in
	*darwin* ) true ;;
	*Darwin* ) true ;;
	* ) false;;
	esac
}


# Check if this is a forked Linux distro
check_forked() {

	# Check for lsb_release command existence, it usually exists in forked distros
	if command_exists lsb_release; then
		# Check if the `-u` option is supported
		# If the command has exited successfully, it means we're in a forked distro
		if lsb_release -a -u > /dev/null 2>&1; then
			# Print info about current distro
			cat <<-EOF
			You're using '$lsb_dist' version '$dist_version'.
			EOF

			# Get the upstream release info
			lsb_dist=$(lsb_release           --id -u | cut -f2 | tr '[:upper:]' '[:lower:]')
			dist_version=$(lsb_release --codename -u | cut -f2 | tr '[:upper:]' '[:lower:]')

			# Print info about upstream distro
			cat <<-EOF
			Upstream release is '$lsb_dist' version '$dist_version'.
			EOF
			if is_display_dist; then
				exit 0
			fi
		fi
	else
		if [ -r /etc/debian_version ] && [ "$lsb_dist" != "ubuntu" ] && [ "$lsb_dist" != "raspbian" ]; then
			if [ "$lsb_dist" = "osmc" ]; then
				# OSMC runs Raspbian
				lsb_dist="raspbian"
			else
				# We're Debian and don't even know it!
				lsb_dist="debian"
			fi
			dist_version=$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')
			case $dist_version in
				12)
					dist_version_number=12
					dist_version="bookworm"
				;;
				11)
					dist_version_number=11
					dist_version="bullseye"
				;;
				10)
					dist_version_number=10
					dist_version="buster"
				;;
				9)
					dist_version_number=9
					dist_version="stretch"
				;;
				8|'Kali Linux 2')
					dist_version_number=8
					dist_version="jessie"
				;;
			esac
		fi
	fi

	if is_display_dist; then
		cat <<-EOF
		You're using '$lsb_dist' version '$dist_version'.
		EOF
		exit 0
	fi
}


get_distribution() {
	if [[ $DISTRIBUTION ]]; then
		#
		# For testing purposes.  DISTRIBUTION is a space-separated tuple:
		#      ${lsb_dist} ${dist_version} ${dist_version_number}
		# where $dist_version number is only set on Debian.  Because the list
		# is space-separated, it must be quoted (or escaped) on the command-
		# line.  The values generated by this script for the supported
		# platforms follow.
		#
		#     debian bullseye 11
		#     debian bookworm 12
		#     ubuntu focal
		#     ubuntu jammy
		#     centos 7
		#     rocky 8
		#     rocky 9
		#     almalinux 8
		#     almalinux 9
		#

		read lsb_dist dist_version dist_version_number <<< $DISTRIBUTION
		return
	fi

	lsb_dist=""
	# Every system that we officially support has /etc/os-release
	if [ -r /etc/os-release ]; then
		lsb_dist=$(. /etc/os-release && echo "$ID")
	fi
	lsb_dist=$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')

	# An empty string for lsb_dist should be alright since the
	# case statements don't act unless you provide an actual value

	case $lsb_dist in

		ubuntu)
			if command_exists lsb_release; then
				dist_version=$(lsb_release --codename | cut -f2)
			fi
			if [[ ! $dist_version ]] && [ -r /etc/lsb-release ]; then
				dist_version=$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")
			fi
		;;

		debian|raspbian)
			# Echoing VERSION_CODENAME out of /etc/os-release works
			# better on Devuan and is simpler... is that file missing on
			# raspbian?
			dist_version=$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')
			case $dist_version in
				12)
					dist_version="bookworm"
				;;
				11)
					dist_version="bullseye"
				;;
				10)
					dist_version="buster"
				;;
				9)
					dist_version="stretch"
				;;
				8)
					dist_version="jessie"
				;;
			esac
		;;

		scientific|centos|rhel|almalinux|rocky|amzn|suse|opensuse-leap)
			if [[ ! $dist_version ]] && [ -r /etc/os-release ]; then
				dist_version=$(. /etc/os-release && echo "$VERSION_ID")
			fi
			dist_version=$(echo "$dist_version" | cut -d. -f1)
		;;

		*)
			if command_exists lsb_release; then
				dist_version=$(lsb_release --release | cut -f2)
			fi
			if [[ ! $dist_version ]] && [ -r /etc/os-release ]; then
				dist_version=$(. /etc/os-release && echo "$VERSION_ID")
			fi
		;;

	esac

	# Check if this is a forked Linux distro
	check_forked

	if [[ $SHOW_DISTRIBUTION ]]; then
		echo "${lsb_dist} ${dist_version} ${dist_version_number}"
		exit 0
	fi
}

do_configure_firewall() {
	if command_exists firewall-cmd; then
		echo -e "\n# Open port 9618 for use by HTCondor"
		(
			if ! is_dry_run; then
				set -x
			fi
			$sh_c "firewall-cmd --zone=public --add-port=9618/tcp --permanent"
			$sh_c "firewall-cmd --reload"
		)
	fi
}

do_start_service() {
	# Start HTCondor via systemd if detected, else via just condor_master
	if [ "$(ps --pid 1 -o comm -h)" != 'systemd' ] || ! command_exists systemctl; then
		echo -e "\n# Start the HTCondor service in the background (without systemd)"
		(
			if ! is_dry_run; then
				set -x
			fi
			$sh_c "condor_master"
		)
	else
		echo -e "\n# Start the HTCondor service via systemd"
		(
			if ! is_dry_run; then
				set -x
			fi
			$sh_c "systemctl enable condor"
			$sh_c "systemctl start condor"
		)
	fi
}

do_token_security() {
	# Remove the default 9.0 security configuration.  Arguably, the
	# get_htcondor metaknobs should instead check for SECURITY_MODEL == 9.0
	# and adjust accordingly, which might make microversion upgrades easier.
	$sh_c "rm -f /etc/condor/config.d/00-htcondor-9.0.config"

	# Ensure that the password directory exists, since the condor_master has
	# not yet been run.
	$sh_c "umask 0077; mkdir -p \$(condor_config_val SEC_PASSWORD_DIRECTORY)"

	# So 'echo' is a shell built-in, which means no command-line to show
	# up in 'ps' and leak the password.  You MUST do the 'echo' before the
	# '$sh_c', because the '$sh_c' itself will show up in 'ps'.
	# But if we're a dry run, then we need the $sh_c first.
	if is_dry_run; then
		$sh_c "echo -n \"${PASSWORD}\" | condor_store_cred add -c -i -"
	else
		echo -n "${PASSWORD}" | $sh_c "condor_store_cred add -c -i -"
	fi

	# Ensure that the tokens directory exists, since the condor_master has
	# not yet been run.
	$sh_c "umask 0077; mkdir -p \$(condor_config_val SEC_TOKEN_SYSTEM_DIRECTORY)"

	# Now issue myself a token.
	$sh_c "umask 0077; condor_token_create -identity condor@${CONDOR_HOST} > /etc/condor/tokens.d/condor@${CONDOR_HOST}"
}

do_install() {
	# Figure out the distribution and version we are running on.
	# This will set $lsb_dist and $dist_version.
	get_distribution

	user=$(id -un 2>/dev/null || true)

	if is_dry_run; then
		sh_c="echo"
	elif [ "$user" != 'root' ]; then
		if command_exists sudo; then
			sh_c='sudo -E sh -c'
		elif command_exists su; then
			sh_c='su -c'
		else
			cat >&2 <<-'EOF'
			Error: this installer needs the ability to run commands as root.
			We are unable to find either "sudo" or "su" available to make this happen.
			EOF
			exit 1
		fi
	fi

    case $lsb_dist in
    scientific|centos|rhel|almalinux|rocky|amzn|suse|opensuse-leap)
        repo_cmd="dnf --assumeyes"
        case $lsb_dist in
        centos|scientific)
            repo_cmd="yum --assumeyes"
            ;;
        suse|opensuse-leap)
            repo_cmd="zypper --non-interactive"
            ;;
        esac
    esac
	#
	# Check for a previous installation.  The instructions below remove
	# the HTCondor package(s) and whatever packages they depended on but
	# which no other package(s) did.  However, neither set of instructions
	# removes HTCondor's repositories, which will prevent downgrades.  I
	# thinks that's OK for now.
	#
	if [ -f "/etc/condor/condor_config" ]; then
		cat >&2 <<-'EOF'
			Error: HTCondor appears to have been installed previously on this system.

			You may update the existing install, or remove and then re-install.
		EOF
		case $lsb_dist in
		ubuntu|debian)
			PACKAGE="condor"
			if [[ ! $ROLE ]]; then
				PACKAGE="minicondor"
			fi

			cat >&2 <<-EOF
				To update: $sh_c "apt-get update && apt-get upgrade ${PACKAGE}"
				To remove: $sh_c "apt-get -y remove --purge ${PACKAGE} && apt-get -y autoremove --purge && rm -fr /etc/condor"
			EOF
			;;
		scientific|centos|rhel|almalinux|rocky|amzn|suse|opensuse-leap)
			PACKAGE="condor"
			if [[ ! $ROLE ]]; then
				PACKAGE="minicondor"
			fi

			cat >&2 <<-EOF
				To update: $sh_c "${repo_cmd} update ${PACKAGE}"
				To remove: $sh_c "${repo_cmd} remove ${PACKAGE} && rm -fr /etc/condor"
			EOF
			;;
		esac
		exit 1
	fi


	#
	# Check for the pool password / default signing key before installing.
	#
	if [[ $ROLE ]]; then
		if [[ ! $PASSWORD ]]; then
			if ! is_dry_run; then
				echo -n "Enter a pool password: "
				read PASSWORD
			else
				PASSWORD="NONE"
				echo "SKIPPING PASSWORD PROMPT DURING DRY RUN"
			fi
		fi

		if [[ ! $PASSWORD ]]; then
			echo
			echo "You must set a password!  Did you replace \$htcondor_password with a password?"
			echo
			exit 1
		fi
	fi

	if [[ ! $ROLE ]]; then
		echo -e "\n# Installing mini HTCondor for ${lsb_dist^} $dist_version"
	else
		echo -e "\n# Installing HTCondor as ${ROLE} for ${lsb_dist^} $dist_version"
	fi

	# Run install binaries for each distro accordingly
	case $lsb_dist in
		ubuntu|debian)
			(
				if ! is_dry_run; then
					set -x
				fi

				echo -e "\n# Adding our repository"

				# Install our repository key.
				$sh_c "apt-get update"
				$sh_c "apt-get install -y gnupg"
				$sh_c "curl -fsSL ${DOWNLOAD_URL}/repo/keys/HTCondor-${CHANNEL_DIR}-Key | apt-key add -"

				# Our repository redirects to https even if you try to
				# avoid it, and Debian 9 doesn't come with this by default.
				$sh_c "apt-get install apt-transport-https"

				# Add our repository.
				HTCONDOR_LIST=/etc/apt/sources.list.d/htcondor.list
				$sh_c "echo \"deb ${DOWNLOAD_URL}/repo/${lsb_dist}/${CHANNEL_DIR} ${dist_version} main\" > ${HTCONDOR_LIST}"
				$sh_c "echo \"deb-src ${DOWNLOAD_URL}/repo/${lsb_dist}/${CHANNEL_DIR} ${dist_version} main\" >> ${HTCONDOR_LIST}"

				echo -e "\n# Updating package lists"
				$sh_c "apt-get update"

				echo -e "\n# Installing ps"
				$sh_c "apt-get install -y procps"

				# In the Ubuntu 20.04 Docker container, the following packages
				# need to be installed non-interactively, because the pipe
				# out of curl eats the tty they'd like to use:
				#	keyboard-configuration
				#	console-setup
				#	tzdata
				# apt-get will succeed if these packages are already installed,
				# but for now let's not risk screwing things up by adding them
				# on the platforms that don't need them.
				case $lsb_dist.$dist_version in
				    ubuntu.bionic|ubuntu.focal|ubuntu.jammy)
    					echo -e "\n# Preconfiguring packages for Ubuntu."
	    				$sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y keyboard-configuration console-setup tzdata"
                    ;;
                esac

				echo -e "\n# Installing HTCondor binaries and dependencies"
				if [[ ! $ROLE ]]; then
					$sh_c "apt-get install -y minicondor"
				else
					$sh_c "apt-get install -y condor"
				fi
			)
			;;
		scientific|centos|rhel|almalinux|rocky|amzn|suse|opensuse-leap)
			(
			if ! is_dry_run; then
				set -x
			fi

			# Some distros don't include ps by default.
			case $lsb_dist in
			amzn|almalinux|rocky)
				echo -e "\n# Installing ps"
				$sh_c "${repo_cmd} install procps-ng"
				;;
			suse|opensuse-leap)
				echo -e "\n# Installing ps"
				$sh_c "${repo_cmd} install procps"
				;;
			esac

			repo_dist=$lsb_dist
			case $lsb_dist in
				scientific|centos|rhel|almalinux|rocky)
					repo_dist="el"
                    echo -e "\n# Installing EPEL"
                    epel_version=$dist_version
                    $sh_c "${repo_cmd} install https://dl.fedoraproject.org/pub/epel/epel-release-latest-${epel_version}.noarch.rpm || ${repo_cmd} reinstall https://dl.fedoraproject.org/pub/epel/epel-release-latest-${epel_version}.noarch.rpm"
                    ;;
				suse|opensuse-leap)
					repo_dist="leap"
                    ;;
			esac
			repo_suffix="${repo_dist}${dist_version}"
			yum_repo_rpm="${DOWNLOAD_URL}/repo/${CHANNEL_DIR}/htcondor-release-current.${repo_suffix}.noarch.rpm"

			# Just to make our lives harder, the packages we need from
			# EPEL depend on repositories which are disabled by default,
			# and those repositories and how to enable them between
			# RHEL and Rocky and between version 7 and 8.
			#
			case ${lsb_dist}.${dist_version} in
				almalinux.8|rocky.8 ) $sh_c "dnf -y install dnf-plugins-core"
				                 $sh_c "dnf config-manager --set-enabled PowerTools || dnf config-manager --set-enabled powertools"
				                 ;;
				almalinux.9|rocky.9 ) $sh_c "dnf -y install dnf-plugins-core"
				                 $sh_c "dnf config-manager --set-enabled crb"
				                 ;;
				# subscription-manager only works if you've already
				# "register"ed and "attach"ed the system.
				rhel.7 ) $sh_c "subscription-manager repos --enable \"rhel-*-optional-rpms\" --enable \"rhel-*-extras-rpms\" --enable \"rhel-ha-for-rhel-*-server-rpms\""
				         ;;
				rhel.8 ) ARCH=$(/bin/arch)
				         $sh_c "subscription-manager repos --enable \"codeready-builder-for-rhel-8-${ARCH}-rpms\""
				         ;;
				rhel.9 ) ARCH=$(/bin/arch)
				         $sh_c "subscription-manager repos --enable \"codeready-builder-for-rhel-9-${ARCH}-rpms\""
				         ;;
			esac

			echo -e "\n# Installing the HTCondor repo"
            case $lsb_dist in
                suse|opensuse-leap)
                    # There is a way to setup SUSE repos where you can install the repo
                    # with a single zypper command. But, I don't know how to do that (yet)
                    $sh_c "${repo_cmd} --no-gpg-checks install ${yum_repo_rpm} || ${repo_cmd} reinstall ${yum_repo_rpm}"
                    ;;
                *)
                    $sh_c "${repo_cmd} install ${yum_repo_rpm} || ${repo_cmd} reinstall ${yum_repo_rpm}"
                    ;;
            esac

            # Needed for SUSE, limits chattyness for other RPM distros
			echo -e "\n# Importing RPM keys"
            for key in /etc/pki/rpm-gpg/RPM-GPG-KEY-HTCondor-*; do
                $sh_c "rpmkeys --import $key"
            done

			echo -e "\n# Installing HTCondor"
			if [[ ! $ROLE ]]; then
				$sh_c "${repo_cmd} install ${YUM_REPO} minicondor"
			else
				$sh_c "${repo_cmd} install ${YUM_REPO} condor"
			fi
			)
			;;
		*)
			if [[ ! $lsb_dist ]]; then
				if is_darwin; then
					echo
					echo "Error: Unsupported operating system 'macOS'"
					echo
					exit 1
				fi
			fi
			echo
			echo "Error: Unsupported distribution '$lsb_dist'"
			echo
			exit 1
			;;
	esac

	if [[ $SHARED_FS_DOMAIN ]]; then
		DOMAIN_CONFIG=$(cat <<-EOF

			# HTCondor assumes that any two machines with the same value
			# for this variable have the same shared filesystems.  Shared
			# filesystems tend not to scale as well as you would like, but
			# they do make it simpler to explain how a job accesses its file.
			FILESYSTEM_DOMAIN = ${SHARED_FS_DOMAIN}

			# If your jobs are accessing a shared filesystem, they probably
			# need to be run as the user who submitted them (as opposed to
			# user nobody or a local user which only runs batch jobs).  This
			# variable must be set to the same thing on the submit machine
			# and on the execute machine to do this.
			UID_DOMAIN = ${SHARED_FS_DOMAIN}

			# The UID_DOMAIN must normally be a suffix of the fully-qualified
			# DNS name of the submit machine (as determined by a reverse
			# lookup of the IP address used to contact the execute machine).
			# Setting this variable relaxes that requirement, which is safe
			# to do for this configuration because only submit machines you
			# trust can contact your execute machines.
			TRUST_UID_DOMAIN = TRUE

			# Normally, before running a job as a particular user (that is,
			# not as user nobody), HTCondor checks to make sure that user
			# is in the password file.  Not all methods for sharing UIDs
			# across machines store every user in every password file (for
			# example, LDAP does not).  Setting this this variable relaxes
			# this requirement.
			SOFT_UID_DOMAIN = TRUE

		EOF
		)
	fi

	# Configure the role, if any.
	echo -e "\n# Configuring role, if any ..."
	case $ROLE in
		"central manager")
			CONFIG_FILE="/etc/condor/config.d/01-central-manager.config"
			$sh_c "echo CONDOR_HOST = ${CONDOR_HOST} > ${CONFIG_FILE}"
			$sh_c "echo '# For details, run condor_config_val use role:get_htcondor_central_manager' >> ${CONFIG_FILE}"
			$sh_c "echo 'use role:get_htcondor_central_manager' >> ${CONFIG_FILE}"

			do_token_security
			;;

		"submit")
			CONFIG_FILE="/etc/condor/config.d/01-submit.config"
			$sh_c "echo CONDOR_HOST = ${CONDOR_HOST} > ${CONFIG_FILE}"
			$sh_c "echo '# For details, run condor_config_val use role:get_htcondor_submit' >> ${CONFIG_FILE}"
			$sh_c "echo 'use role:get_htcondor_submit' >> ${CONFIG_FILE}"

			if [[ ${SHARED_FS_DOMAIN} ]]; then
				$sh_c "echo '${DOMAIN_CONFIG}' >> ${CONFIG_FILE}"
			fi

			do_token_security
			;;

		"execute")
			CONFIG_FILE="/etc/condor/config.d/01-execute.config"
			$sh_c "echo CONDOR_HOST = ${CONDOR_HOST} > ${CONFIG_FILE}"
			$sh_c "echo '# For details, run condor_config_val use role:get_htcondor_execute' >> ${CONFIG_FILE}"
			$sh_c "echo 'use role:get_htcondor_execute' >> ${CONFIG_FILE}"

			if [[ "${SHARED_FS_DOMAIN}" ]]; then
				$sh_c "echo '${DOMAIN_CONFIG}' >> ${CONFIG_FILE}"
			fi

			do_token_security
			;;

		*)
			# The mini[ht]condor package has done everything for us.
			;;

	esac

	# Open port 9618 on system firewall
	do_configure_firewall

	# Finally, start the HTCondor service
	do_start_service

	echo
}

do_download() {
	get_distribution

	TARBALL_BASE_URL="${DOWNLOAD_URL}/tarball"
	TARBALL_DIR_URL="${TARBALL_BASE_URL}/${CHANNEL_DIR}/current"

	OS_VERSION=$dist_version
	case $lsb_dist in
		# We don't release HTCondor for Fedora.
		# fedora)
		#	;;
		ubuntu)
			OS_NAME="Ubuntu"
			dist_version_number=$(. /etc/os-release && echo "$VERSION_ID")
			dist_version_number=$(echo $dist_version_number | sed -e s'/\.[0-9]*//')
			OS_VERSION=$dist_version_number
			;;
		debian)
			OS_NAME="Debian"
			OS_VERSION=$dist_version_number
			;;
		scientific|centos|rhel)
			if [ "$dist_version" = "7" ]; then
				OS_NAME="CentOS"
			else
				OS_NAME="AlmaLinux"
			fi
			;;
		almalinux)
			OS_NAME="AlmaLinux"
			;;
		rocky)
			OS_NAME="AlmaLinux"
			;;
		amzn)
			OS_NAME="AmazonLinux"
			;;
		suse|opensuse-leap)
			OS_NAME="openSUSE"
			;;
		*)
			if is_darwin; then
				OS_NAME=macOS
				OS_VERSION=13
			else
				echo
				echo "Error: Unsupported distribution '$lsb_dist'"
				echo
				exit 1
			fi
			;;
	esac

	TARBALL_NAME="condor-x86_64_${OS_NAME}${OS_VERSION}-stripped.tar.gz"
	TARBALL_URL="${TARBALL_DIR_URL}/${TARBALL_NAME}"

	echo "Downloading to condor.tar.gz..."
	curl -fSL ${TARBALL_URL} -o condor.tar.gz
}

# Set global defaults
CHANNEL="current"
DOWNLOAD_URL="https://research.cs.wisc.edu/htcondor"
DRY_RUN=1
sh_c='sh -c'
unset DIST
PASSWORD=$GET_HTCONDOR_PASSWORD

# Process command-line options
while [ $# -gt 0 ]; do
	case $1 in
		--show-distribution)
			SHOW_DISTRIBUTION=TRUE
			;;
		--distribution)
			DISTRIBUTION=$2
			if [[ ! $DISTRIBUTION ]]; then
				echo "--distribution requires an argument"
				exit 1
			fi
			shift
			;;
		--password)
			PASSWORD=$2
			if [[ ! $PASSWORD ]]; then
				echo "--password requires an argument"
				exit 1
			fi
			shift
			;;
		--shared-filesystem-domain)
			SHARED_FS_DOMAIN=$2
			if [[ ! $SHARED_FS_DOMAIN ]]; then
				echo "--shared-filesystem-domain requires an argument"
				exit 1
			fi
			shift
			;;
		--minicondor)
			unset ROLE
			;;
		--central-manager)
			ROLE="central manager"
			CONDOR_HOST=$2
			if [[ ! $CONDOR_HOST ]]; then
				echo "--central-manager requires its external name as an argument"
				exit 1
			fi
			shift
			;;
		--submit)
			ROLE="submit"
			CONDOR_HOST=$2
			if [[ ! $CONDOR_HOST ]]; then
				echo "--submit requires the central manager as an argument"
				exit 1
			fi
			shift
			;;
		--execute)
			ROLE="execute"
			CONDOR_HOST=$2
			if [[ ! $CONDOR_HOST ]]; then
				echo "--execute requires the central manager as an argument"
				exit 1
			fi
			shift
			;;
		--yum-repo)
			REPO_SUFFIX=$2
			if [[ ! $REPO_SUFFIX ]]; then
				echo "--yum-repo requires a repo-suffix as an argument"
				exit 1
			fi
			YUM_REPO=--enablerepo=htcondor-${REPO_SUFFIX}
			shift
			;;
		--channel)
			case $2 in
				stable)
					CHANNEL="stable"
					;;
				current|latest|developer)
					CHANNEL="current"
					;;
				*-rc)
					CHANNEL=$2
					;;
				*)
					echo "Illegal option $2 for --channel"
					echo "Run $0 --help for usage"
					exit 1
					;;
			esac
			shift
			;;
		--no-dry-run)
			unset DRY_RUN
			;;
		--dry-run)
			DRY_RUN=1
			;;
		--dist)
			DIST=1
			;;
		--download)
			DOWNLOAD=1
			;;
		--help|-h)
			usage
			;;
		*)
			echo "Illegal option $1"
			echo "Run $0 --help for usage"
			exit 1
			;;
	esac
	shift
done

# We have to update this once every stable release; we don't want
# to update a symlink, like we do for 'current', because we don't
# want to surprise other stable-channel users with new features.
if [ "${CHANNEL}" = "stable" ]; then
	CHANNEL_DIR=23.0
else
	CHANNEL_DIR=$CHANNEL
fi

# wrapped up in functions so that we have some protection against only getting
# half the file during "curl | sh"

if is_download; then
	do_download
else
	do_install
fi

exit 0
