cluster-deployment/execute

173 lines
4.5 KiB
Bash
Executable file

#!/usr/bin/env bash
set -e;
# Interesting chars:
# 🛰 - Satellite - looks very cool indeed in Firefox
lantern_path="../lantern-build-engine";
if [[ -z "${do_parallel}" ]]; then
do_parallel="true";
fi
###############################################################################
# Make sure the current directory is the location of this script to simplify matters
cd "$(dirname "$(readlink -f "$0")")";
# Check out the lantern git submodule if needed
if [ ! -f "${lantern_path}/lantern.sh" ]; then git submodule update --init "${lantern_path}"; fi
#shellcheck disable=SC1090
source "${lantern_path}/lantern.sh";
###############################################################################
if [[ -z "${2}" ]]; then
echo "Usage:";
echo " ./execute {{path/to/jobfile}} {{path/to/hostsfile_a}} {{path/to/hostsfile_n}}";
exit 1;
fi
job_filepath="$1";
if [[ ! -f "${job_filepath}" ]]; then
job_filepath="jobs/${job_filepath}/${job_filepath}.job";
fi
shift;
hosts="";
while [[ ! -z "${1}" ]]; do
hosts_filename="${1}";
if [[ ! -f "${hosts_filename}" ]]; then
hosts_filename="hosts/${hosts_filename}.txt";
fi
hosts="$(echo "${hosts}" && cat "${hosts_filename}")";
shift;
done
ssh_configfile="./ssh-config";
if [[ ! -x "${job_filepath}" ]]; then
echo -e "${FRED}Error: ${job_filepath} doesn't exist, or is not executable.${RS}" >&2;
exit 1;
fi
log_msg() {
echo -e "[ $(date -u +"%Y-%m-%dT%H:%M:%SZ") ] $*" >&2;
}
# $1 Command to execute
RUN_ONCE() {
command="${1}";
hash="$(echo "${command}" | sha256sum | cut -d- -f1)";
if [[ -z "${EXECUTE_HOSTNAME}" ]]; then
task_end 1 "Oops! The hostname to execute on wasn't found. This is probably a bug.";
fi
log_msg "️🛡️ ${HC}[ ${EXECUTE_HOSTNAME} ]${RS} ${FBLE}RUN_ONCE${RS} ${command}";
if [[ "${INTERACTIVE}" == "true" ]]; then
echo "Enabling interactive mode";
SSH_FLAGS="-t ";
fi
echo "
if [[ ! -d /etc/remote-exec ]]; then sudo mkdir /etc/remote-exec; fi
if [[ ! -f /etc/remote-exec/${hash} ]]; then
echo \"[ \${HOSTNAME} ] [ \$(date -u +\"%Y-%m-%dT%H:%M:%SZ\") ] Executing once\"
${command}
sudo touch /etc/remote-exec/${hash};
fi
" | ssh ${SSH_FLAGS} -F "${ssh_configfile}" "${EXECUTE_HOSTNAME}" bash;
}
# $1 Command to execute
RUN() {
command="${1}";
if [[ -z "${EXECUTE_HOSTNAME}" ]]; then
task_end 1 "Oops! The hostname to execute on wasn't found. This is probably a bug.";
fi
log_msg "🚏 ${HC}[ ${EXECUTE_HOSTNAME} ]${RS} ${FBLE}RUN${RS} ${command}";
if [[ "${INTERACTIVE}" == "true" ]]; then
echo "Enabling interactive mode";
SSH_FLAGS="-t ";
fi
echo "${command}" | ssh ${SSH_FLAGS} -F "${ssh_configfile}" "${EXECUTE_HOSTNAME}" bash;
}
# $1 Filepath to script to copy & execute
SCRIPT() {
script_filepath="${1}";
remote_filepath="/tmp/$(basename ${script_filepath})";
if [[ -z "${EXECUTE_HOSTNAME}" ]]; then
task_end 1 "Oops! The hostname to execute on wasn't found. This is probably a bug.";
fi
log_msg "🚂 ${HC}[ ${EXECUTE_HOSTNAME} ]${RS} ${FMAG}SCRIPT${RS} ${command}";
scp -F "${ssh_configfile}" "${script_filepath}" "${EXECUTE_HOSTNAME}:${remote_filepath}";
echo -e "${remote_filepath}\nrm ${remote_filepath}" | ssh -F "${ssh_configfile}" "${EXECUTE_HOSTNAME}" bash;
echo ""
}
# $1 The filepath to copy
# $2 The location to copy it to on the remote host
COPY() {
filepath_local="${1}";
filepath_remote="${2}";
log_msg "🚚 ${HC}[ ${EXECUTE_HOSTNAME} ]${RS} ${FMAG}COPY${RS} ${filepath_local}${filepath_remote}";
if [[ ! -f "${filepath_local}" ]]; then
task_end 1 "[ ${HC}COPY${RS} ] Error: Couldn't find ${filepath_local} on disk (CWD is ${PWD}).";
fi
if [[ -z "${EXECUTE_HOSTNAME}" ]]; then
task_end 1 "[ ${HC}COPY${RS} ] Oops! The hostname to copy to wasn't found. This is probably a bug.";
fi
scp -F "${ssh_configfile}" "${filepath_local}" "${EXECUTE_HOSTNAME}:${filepath_remote}";
}
# $1 job filepath
# $2 hostname
__do_execute() {
job_filepath="${1}";
hostname="${2}";
log_msg "${FBLE}${HC}${RS} Starting on ${HC}${hostname}${RS}";
export EXECUTE_HOSTNAME="${hostname}";
export JOBFILE_DIR; JOBFILE_DIR="$(dirname "${job_filepath}")";
#shellcheck disable=SC1090
source "${job_filepath}";
log_msg "${FGRN}${HC}${RS} Finished on ${HC}${hostname}${RS}";
}
task_begin "Executing ${job_filepath}";
while read -r hostname; do
if [[ -z "${hostname}" ]]; then
continue;
fi
if [[ "${do_parallel}" == "true" ]]; then
__do_execute "${job_filepath}" "${hostname}" &
else
__do_execute "${job_filepath}" "${hostname}";
fi
done < <(echo "${hosts}");
wait