#!/bin/sh # # Control script for the remote execution jobs. # # The initial script calls `$CONTROL_SCRIPT init-script-finish` once the original script exits. # In automatic mode, the exit code is sent back to the proxy on `init-script-finish`. # # What the script provides is also a manual mode, where the author of the rex script can take # full control of the job lifecycle. This allows keeping the marked as running even when # the initial script finishes. # # The manual mode is turned on by calling `$CONTROL_SCRIPT manual-control`. After calling this, # one can call `echo message | $CONTROL_SCRIPT update` to send output to the remote execution jobs # and `$CONTROL_SCRIPT finish 0` once finished (with 0 as exit code) to send output to the remote execution jobs # and `$CONTROL_SCRIPT finish 0` once finished (with 0 as exit code) BASE_DIR=“$(dirname ”$(readlink -f “$0”)“)”

if ! command -v curl >/dev/null; then

echo 'curl is required' >&2
exit 1

fi

# send the callback data to proxy update() {

"$BASE_DIR/retrieve.sh" push_update

}

# wait for named pipe $1 to retrieve data. If $2 is provided, it serves as timeout # in seconds on how long to wait when reading. wait_for_pipe() {

pipe_path=$1
if [ -n "$2" ]; then
    timeout="-t $2"
fi
if read $timeout <>"$pipe_path"; then
    rm "$pipe_path"
    return 0
else
    return 1
fi

}

# function run in background, when receiving update data via STDIN. periodic_update() {

interval=1
# reading some data from periodic_update_control signals we're done
while ! wait_for_pipe "$BASE_DIR/periodic_update_control" "$interval"; do
    update
done
# one more update before we finish
update
# signal the main process that we are finished
echo > "$BASE_DIR/periodic_update_finished"

}

# signal the periodic_update process that the main process is finishing periodic_update_finish() {

if [ -e "$BASE_DIR/periodic_update_control" ]; then
   echo > "$BASE_DIR/periodic_update_control"
fi

}

ACTION=${1:-finish}

case “$ACTION” in

init-script-finish)
    if ! [ -e "$BASE_DIR/manual_mode" ]; then
        # make the exit code of initialization script the exit code of the whole job
        cp init_exit_code exit_code
        update
    fi
    ;;
finish)
    # take exit code passed via the command line, with fallback
    # to the exit code of the initialization script
    exit_code=${2:-$(cat "$BASE_DIR/init_exit_code")}
    echo $exit_code > "$BASE_DIR/exit_code"
    update
    if [ -e "$BASE_DIR/manual_mode" ]; then
        rm "$BASE_DIR/manual_mode"
    fi
    ;;
update)
    # read data from input when redirected though a pipe
    if ! [ -t 0 ]; then
        # couple of named pipes to coordinate the main process with the periodic_update
        mkfifo "$BASE_DIR/periodic_update_control"
        mkfifo "$BASE_DIR/periodic_update_finished"
        trap "periodic_update_finish" EXIT
        # run periodic update as separate process to keep sending updates in output to server
        periodic_update &
        # redirect the input into output
        tee -a "$BASE_DIR/output"
        periodic_update_finish
        # ensure the periodic update finished before we return
        wait_for_pipe "$BASE_DIR/periodic_update_finished"
    else
        update
    fi
    ;;
# mark the script to be in manual mode: this means the script author needs to use `update` and `finish`
# commands to send output to the remote execution job or mark it as finished.
manual-mode)
    touch "$BASE_DIR/manual_mode"
    ;;
*)
    echo "Unknown action $ACTION"
    exit 1
    ;;

esac