Skip to content

Commit 480db35

Browse files
xgboostedCyclenerd
andauthored
Add retry logic for server creation with configurable attempts and delay (fixes #8) (#10)
* Add retry logic for server creation with configurable attempts --------- Co-authored-by: Nils <Cyclenerd@users.noreply.github.com>
1 parent 273c9a2 commit 480db35

3 files changed

Lines changed: 41 additions & 9 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ jobs:
141141

142142
| Name | Required | Description | Default |
143143
|---------------------|----------|-------------|---------|
144+
| `create_wait` | | Wait up to 'create_wait' retries (10 sec each) to create the Hetzner Cloud Server resource. | `360` (1 hour) |
144145
| `enable_ipv4` | | Attach an IPv4 on the public NIC (true/false). If false, no IPv4 address will be attached. Warning: The GitHub API requires IPv4. Disabling it will result in connection failures. | `true` |
145146
| `enable_ipv6` | | Attach an IPv6 on the public NIC (true/false). If false, no IPv6 address will be attached. | `true` |
146147
| `github_token` | ✓ (always) | Fine-grained GitHub Personal Access Token (PAT) with 'Read and write' access to 'Administration' assigned. | |

action.sh

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,12 +197,19 @@ if [[ "$MY_RUNNER_VERSION" != "latest" && "$MY_RUNNER_VERSION" != "skip" && ! "$
197197
exit_with_failure "'$MY_RUNNER_VERSION' is not a valid GitHub Actions Runner version! Enter 'latest', 'skip' or the version without 'v'."
198198
fi
199199

200-
# Set maximal wait time (retries * 10 sec) for GitHub Actions Runner registration (default: 30 [5 min])
201-
# If MY_RUNNER_WAIT is set, use its value; otherwise, use "30".
200+
# Set maximal wait time (retries * 10 sec) for GitHub Actions Runner registration (default: 60 [10 min])
201+
# If INPUT_RUNNER_WAIT is set, use its value; otherwise, use "60".
202202
MY_RUNNER_WAIT=${INPUT_RUNNER_WAIT:-"60"}
203203
# Check if MY_RUNNER_WAIT is an integer
204204
if [[ ! "$MY_RUNNER_WAIT" =~ ^[0-9]+$ ]]; then
205-
exit_with_failure "The maximum wait time (reties) for GitHub Action Runner registration must be an integer!"
205+
exit_with_failure "The maximum wait time (retries) for GitHub Action Runner registration must be an integer!"
206+
fi
207+
208+
# Set maximal wait time (retries * 10 sec) for Hetzner Server creation (default: 360 [1 hour])
209+
# If INPUT_CREATE_WAIT is set, use its value; otherwise, use "360".
210+
MY_CREATE_WAIT=${INPUT_CREATE_WAIT:-360}
211+
if [[ ! "$MY_CREATE_RETRIES" =~ ^[0-9]+$ ]]; then
212+
exit_with_failure "The maximum wait time (retries) for Hetzner Server creation must be an integer!"
206213
fi
207214

208215
# Set Hetzner Cloud Server ID
@@ -363,18 +370,37 @@ fi
363370

364371
# Send a POST request to the Hetzner Cloud API to create a server.
365372
# https://docs.hetzner.cloud/#servers-create-a-server
366-
echo "Create server..."
367-
if ! curl \
373+
MAX_RETRIES=$MY_CREATE_WAIT
374+
RETRY_COUNT=0
375+
WAIT_SEC=10
376+
while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do
377+
echo "Create Server..."
378+
if curl \
368379
-X POST \
369380
--fail-with-body \
370381
-o "servers.json" \
371382
-H "Content-Type: application/json" \
372383
-H "Authorization: Bearer ${MY_HETZNER_TOKEN}" \
373384
-d @create-server.json \
374385
"https://api.hetzner.cloud/v1/servers"; then
375-
cat "servers.json"
376-
exit_with_failure "Failed to create Server in Hetzner Cloud!"
377-
fi
386+
echo "Server created successfully."
387+
break
388+
else
389+
# Check if the error is related to resource unavailability
390+
if grep -q -E "resource_unavailable|resource_limit_exceeded" "servers.json"; then
391+
echo "Resource limitation detected."
392+
# If error is not resource-related, don't retry
393+
else
394+
cat "servers.json"
395+
exit_with_failure "Failed to create Server in Hetzner Cloud!"
396+
fi
397+
fi
398+
399+
RETRY_COUNT=$((RETRY_COUNT + 1)) # Increment retry counter
400+
401+
echo "Failed to create Server. Wait $WAIT_SEC seconds... (Attempt $RETRY_COUNT/$MAX_RETRIES)"
402+
sleep "$WAIT_SEC"
403+
done
378404

379405
# Get the Hetzner Server ID from the JSON response (assuming valid JSON)
380406
MY_HETZNER_SERVER_ID=$(jq -er '.server.id' < "servers.json")
@@ -393,7 +419,6 @@ echo "server_id=$MY_HETZNER_SERVER_ID" >> "$GITHUB_OUTPUT"
393419

394420
# Wait for server
395421
MAX_RETRIES=$MY_SERVER_WAIT
396-
WAIT_SEC=10
397422
RETRY_COUNT=0
398423
echo "Wait for server..."
399424
while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do

action.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ inputs:
7373
'skip' will skip the installation. A working installation is expected in the 'runner_dir'.
7474
required: false
7575
default: 'latest'
76+
create_wait:
77+
description: >-
78+
Wait up to 'create_wait' retries (10 sec each) to create the Hetzner Cloud Server resource (default: 360 = 1 hour).
79+
required: false
80+
default: '360'
7681
runner_wait:
7782
description: >-
7883
Wait up to 'runner_wait' retries (10 sec each) for runner registration (default: 10 minutes).
@@ -142,3 +147,4 @@ runs:
142147
INPUT_SERVER_TYPE: ${{ inputs.server_type }}
143148
INPUT_SERVER_WAIT: ${{ inputs.server_wait }}
144149
INPUT_SSH_KEY: ${{ inputs.ssh_key }}
150+
INPUT_CREATE_WAIT: ${{ inputs.create_wait }}

0 commit comments

Comments
 (0)