#!/bin/bash function do_step(){ echo "Executing: $@" echo if "$@" then echo echo "==================== Step $@ ran OK ====================" else echo >&2 echo "!!!!!!!!!!!!!!!!!!!!! Step $@ Failed !!!!!!!!!!!!!!!!!!!!!" return 1 fi } function step_type(){ echo "$1"|cut -d _ -f 1|cut -d : -f 1 } function step_3digit_number(){ printf "%03d" "$(step_number "$1")" } function step_number(){ for number in "${!steps[@]}" do if [ "${steps[$number]}" = "$1" ] then echo "$number" fi done } function step_script(){ echo "$1"|cut -d : -f 2- } function has_step(){ found=false for step in "${steps[@]}" do if [ "$(step_3digit_number "$step")" == "$1" ] then found=true break; fi done $found } function step_check(){ script_type="$(step_type "$1")" script="$(step_script "$1")" if [ "$script_type" == "function" ] then type "$script" > /dev/null 2>&1 else [ -x "$script" ] fi } function next_step(){ printf "%03d" "$(($(step_number "$1")+1))" } function prepend_timestamp(){ while IFS= read -r line; do printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$line"; done } function do_menu(){ next_step="$(step_3digit_number "${steps[0]}")" while true do echo "Environment:" echo "Azure master: $AZURE_MASTER" echo "Azure slaves: ${AZURE_SLAVES[*]}" echo "Azure pgbouncers: ${AZURE_PGBOUNCERS[*]}" echo "GCP master candidate: $GCP_MASTER_CANDIDATE" echo "GCP slaves: ${GCP_SLAVES[*]}" echo "GCP pgbouncers: ${GCP_PGBOUNCERS[*]}" echo echo "Available steps:" echo for step in "${steps[@]}" do echo "$(step_3digit_number "$step")) $(step_script "$step")" done echo if has_step "$next_step" then read_prompt="Enter the step number to execute, next to execute step $next_step or quit to exit? " else read_prompt="Enter the step number to execute or quit to exit? " fi if which rlwrap > /dev/null 2>&1 then command="$(rlwrap -f migration.dict -C migration bash -c 'read -r -p "'"$read_prompt"'" command; echo "$command"')" else read -r -p "$read_prompt" command fi step= case "$command" in quit) exit 0 ;; next) found=false for step in "${steps[@]}" do if [ "$(step_3digit_number "$step")" == "$next_step" ] then found=true break; fi done if ! $found then step= fi ;; [0-9][0-9][0-9]) found=false for step in "${steps[@]}" do if [ "$(step_3digit_number "$step")" == "$command" ] then found=true break; fi done if ! $found then echo "Sorry, no step $command found! Please enter all step digits." step= fi ;; esac if [ ! -z "$step" ] then script_type="$(step_type "$step")" script="$(step_script "$step")" echo "Step $step will be executed ($script_type $script):" echo if [ "$script_type" == "function" ] then type "$script" | head -n -1 | tail -n +4 else script="${BASE}/$(step_script "$step")" cat "$script" fi echo read -r -s -N 1 -p "Press [y] to continue, any other key to abort." key echo if [ "$key" == "y" ] then if do_step "$script" > >(prepend_timestamp | tee -a migration.log) 2> >(prepend_timestamp | tee -a migration.log >&2) then next_step="$(next_step "$step")" else next_step="$(step_3digit_number "$step")" fi # wait for the redirect subshells to complete sleep 1 fi echo step= fi done }