From 850f12f86a8cfc7745f9fc68a37910180fbf98b5 Mon Sep 17 00:00:00 2001 From: hiroTochigi Date: Fri, 2 Aug 2024 22:55:10 -0500 Subject: [PATCH] feat: wait the status until it is not "stopping" - attempt three times to get state - the state is "stopping" after three times attempt, terminate the script and ask the user to run the script later - if the state is not "stopping", proceeds the process --- src/aws/dependencies/utilitiyFunction.sh | 102 ++++++++++++++++------- src/aws/start.sh | 65 +++++++-------- 2 files changed, 106 insertions(+), 61 deletions(-) diff --git a/src/aws/dependencies/utilitiyFunction.sh b/src/aws/dependencies/utilitiyFunction.sh index 2a003533..72847407 100644 --- a/src/aws/dependencies/utilitiyFunction.sh +++ b/src/aws/dependencies/utilitiyFunction.sh @@ -1,4 +1,3 @@ - # Filters instances from JSON data based on the tag "Class" with a value of "treehouses". # Expects JSON data in the format returned by the AWS CLI command 'describe-instances'. # Uses 'jq' to parse and filter the data. @@ -9,43 +8,90 @@ function filterInstancesByTag { echo "$jsonData" | jq '[.Reservations[].Instances[] | select(.Tags[]? | .Key=="Class" and .Value=="treehouses")]' } -function waitForOutput(){ - local cmd=$1 - local result=$(eval $cmd) - while [ -z "$result" ] || [ "$result" == "null" ] - do - sleep 5 - result=$(eval $cmd) - done - echo $result +function waitForOutput() { + local cmd=$1 + local result=$(eval $cmd) + while [ -z "$result" ] || [ "$result" == "null" ]; do + sleep 5 + result=$(eval $cmd) + done + echo $result } setBalloonName() { - if [ -z "$1" ]; then - echo "luftballon" - else - echo "$1" - fi + if [ -z "$1" ]; then + echo "luftballon" + else + echo "$1" + fi } function makePortArray { - local portString="$1" - local -a portArray + local portString="$1" + local -a portArray - IFS=',' read -ra pairs <<< "$portString" + IFS=',' read -ra pairs <<<"$portString" - for pair in "${pairs[@]}"; do - IFS=':' read -ra ports <<< "$pair" - for port in "${ports[@]}"; do - portArray+=("$port") - done + for pair in "${pairs[@]}"; do + IFS=':' read -ra ports <<<"$pair" + for port in "${ports[@]}"; do + portArray+=("$port") done + done + + echo "${portArray[@]}" +} - echo "${portArray[@]}" +function getState() { + local instanceId=$1 + local state=$(aws ec2 describe-instances --instance-ids $instanceId | jq '.Reservations[].Instances[].State.Name') + echo $state } -function getState(){ - local instanceId=$1 - local state=$(aws ec2 describe-instances --instance-ids $instanceId | jq '.Reservations[].Instances[].State.Name') - echo $state +# Function: waitForConditionalOutput +# Description: Waits for a command to produce a specific result based on the specified mode. +# Parameters: +# $1 - The command to execute +# $2 - The target value to compare against +# $3 - The mode of operation: 'match' or 'different' +# 'match': Waits for the result to match the target value +# 'different': Waits for the result to be different from the target value +# Returns: +# 0 - If the desired condition is met within the max attempts +# 1 - If the desired condition is not met within the max attempts + +function waitForConditionalOutput() { + local cmd=$1 + local targetValue=$2 + local mode=$3 + local maxAttempts=3 + local attempt=0 + + # Validate mode + if [[ "$mode" != "match" && "$mode" != "different" ]]; then + echo "Error: Invalid mode. Use 'match' or 'different'." + return 1 + fi + + while [ $attempt -lt $maxAttempts ]; do + local result=$(eval $cmd) + if [ "$mode" == "match" ]; then + # Wait for the result to match the target value + if [ "$result" == "$targetValue" ]; then + echo $result + return 0 + fi + elif [ "$mode" == "different" ]; then + # Wait for the result to be different from the target value + if [ "$result" != "$targetValue" ]; then + echo $result + return 0 + fi + fi + attempt=$((attempt + 1)) + sleep 5 + done + + echo "Error: Failed to meet the condition after $maxAttempts attempts." + return 1 } diff --git a/src/aws/start.sh b/src/aws/start.sh index 76cec03f..0933a399 100644 --- a/src/aws/start.sh +++ b/src/aws/start.sh @@ -3,49 +3,48 @@ #BASE=$HOME BASE=/home/pi -function start(){ - balloonName=$(setBalloonName "$1") +function start() { + balloonName=$(setBalloonName "$1") - if ! isBalloonNameValid "$balloonName"; then - echo "Please provide a valid balloon name" - exit 1 - fi + if ! isBalloonNameValid "$balloonName"; then + echo "Please provide a valid balloon name" + exit 1 + fi - instanceId=$(getValueByAttribute $balloonName instanceId) + instanceId=$(getValueByAttribute "$balloonName" instanceId) - if [ "$instanceId" = "null" ]; then - echo "$balloonName does not exist" - exit 1 - fi + if [ "$instanceId" = "null" ]; then + echo "$balloonName does not exist" + exit 1 + fi - oldPublicIp=$(getValueByAttribute $balloonName publicIp) + # oldPublicIp=$(getValueByAttribute "$balloonName" publicIp) - state=$(getState $instanceId) + state=$(waitForConditionalOutput "getState $instanceId" "\"stopping\"" "different") + if [ $? -ne 0 ]; then + echo "Wait for starting on start command until instance is stopped." + exit 1 + fi - if [ "$state" == "\"running\"" ]; then - echo "The instance is already running" - exit 0 - fi + if [ "$state" == "\"running\"" ]; then + echo "The instance is already running" + exit 0 + fi - if [ "$state" == "\"stopping\"" ]; then - echo "The instance is stopping" - exit 1 - fi + aws ec2 start-instances --instance-ids "$instanceId" - aws ec2 start-instances --instance-ids $instanceId + echo "get the new ip address. The procedure might take time for a while" + publicIp=$(waitForOutput "getLatestIpAddress $instanceId") - echo "get the new ip address. The procedure might take time for a while" - publicIp=$(waitForOutput "getLatestIpAddress $instanceId") + # portConfigArray=$(getArrayValueAsStringByKey "$instanceName" tcpPortArray) - portConfigArray=$(getArrayValueAsStringByKey $instanceName tcpPortArray) + echo "the new ip address is $publicIp" + updateIPAddress "$balloonName" "$publicIp" - echo "the new ip address is $publicIp" - updateIPAddress $balloonName $publicIp + closeSSHTunnel + echo "remove old ssh tunnel settings" + sleep 5 - closeSSHTunnel - echo "remove old ssh tunnel settings" - sleep 5 - - restartSSHTunnel $balloonName $publicIp - echo "open new ssh tunnel" + restartSSHTunnel "$balloonName" "$publicIp" + echo "open new ssh tunnel" }