#!/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