mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-05-07 17:31:04 +00:00
refactor: replace hand-rolled API wrapper and polling loop with shared helpers (#927)
- hostkey: replace 22-line raw curl wrapper with generic_cloud_api delegation (adds retry logic, standardizes METHOD ENDPOINT [BODY] signature) - exoscale: replace 30-line hand-rolled polling loop with generic_wait_for_instance via thin CLI wrapper Agent: complexity-hunter Co-authored-by: A <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ebc5a6cc2f
commit
84681fe092
2 changed files with 26 additions and 54 deletions
|
|
@ -165,38 +165,25 @@ get_server_name() {
|
|||
get_validated_server_name "EXOSCALE_SERVER_NAME" "Enter server name: "
|
||||
}
|
||||
|
||||
# Thin wrapper around exo CLI that matches the generic_wait_for_instance API
|
||||
# signature (func METHOD ENDPOINT) so the shared polling loop can be reused.
|
||||
# The endpoint is the instance ID.
|
||||
_exoscale_instance_api() {
|
||||
local _method="$1" # unused; exo CLI doesn't distinguish methods
|
||||
local instance_id="$2"
|
||||
exo compute instance show "$instance_id" -O json 2>/dev/null || echo '{}'
|
||||
}
|
||||
|
||||
# Wait for Exoscale instance to become running and get its IP
|
||||
# Sets: EXOSCALE_SERVER_IP
|
||||
# Usage: _wait_for_exoscale_instance INSTANCE_ID [MAX_ATTEMPTS]
|
||||
_wait_for_exoscale_instance() {
|
||||
local instance_id="$1"
|
||||
local max_attempts=${2:-60}
|
||||
local attempt=1
|
||||
|
||||
log_step "Waiting for instance to become running..."
|
||||
while [[ "$attempt" -le "$max_attempts" ]]; do
|
||||
local status_json
|
||||
status_json=$(exo compute instance show "$instance_id" -O json 2>/dev/null || echo '{}')
|
||||
|
||||
local status
|
||||
status=$(echo "$status_json" | python3 -c "import json,sys; d=json.loads(sys.stdin.read()); print(d.get('state','unknown'))" 2>/dev/null || echo "unknown")
|
||||
|
||||
if [[ "$status" == "running" ]]; then
|
||||
EXOSCALE_SERVER_IP=$(echo "$status_json" | python3 -c "import json,sys; d=json.loads(sys.stdin.read()); print(d.get('public-ip',''))" 2>/dev/null)
|
||||
export EXOSCALE_SERVER_IP
|
||||
if [[ -n "$EXOSCALE_SERVER_IP" ]]; then
|
||||
log_info "Instance running: IP=$EXOSCALE_SERVER_IP"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
log_step "Instance status: $status ($attempt/$max_attempts)"
|
||||
sleep "${INSTANCE_STATUS_POLL_DELAY}"
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
|
||||
log_error "Instance did not become running in time"
|
||||
return 1
|
||||
local max_attempts="${2:-60}"
|
||||
generic_wait_for_instance _exoscale_instance_api "$instance_id" \
|
||||
"running" "d.get('state','unknown')" \
|
||||
"d.get('public-ip','')" \
|
||||
EXOSCALE_SERVER_IP "Instance" "$max_attempts"
|
||||
}
|
||||
|
||||
# Write cloud-init userdata to a temporary file for exo CLI
|
||||
|
|
|
|||
|
|
@ -23,35 +23,20 @@ fi
|
|||
readonly HOSTKEY_API_BASE="https://invapi.hostkey.com"
|
||||
|
||||
# Centralized curl wrapper for HOSTKEY API
|
||||
# Delegates to generic_cloud_api for retry logic and error handling
|
||||
# Usage: hostkey_api METHOD ENDPOINT [BODY]
|
||||
hostkey_api() {
|
||||
local endpoint="$1"
|
||||
local body="${2:-}"
|
||||
local method="$1"
|
||||
local endpoint="$2"
|
||||
local body="${3:-}"
|
||||
|
||||
if [[ -z "${HOSTKEY_API_KEY:-}" ]]; then
|
||||
log_error "HOSTKEY_API_KEY is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local response
|
||||
if [[ -n "$body" ]]; then
|
||||
response=$(curl -s "${HOSTKEY_API_BASE}${endpoint}" \
|
||||
-H "Authorization: Bearer ${HOSTKEY_API_KEY}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$body")
|
||||
else
|
||||
response=$(curl -s "${HOSTKEY_API_BASE}${endpoint}" \
|
||||
-H "Authorization: Bearer ${HOSTKEY_API_KEY}")
|
||||
fi
|
||||
|
||||
printf '%s' "$response"
|
||||
generic_cloud_api "$HOSTKEY_API_BASE" "$HOSTKEY_API_KEY" "$method" "$endpoint" "$body"
|
||||
}
|
||||
|
||||
# Test HOSTKEY API key validity
|
||||
test_hostkey_token() {
|
||||
local response
|
||||
# Try to get server list as a simple auth test
|
||||
response=$(curl -s "${HOSTKEY_API_BASE}/v1/services" \
|
||||
-H "Authorization: Bearer ${HOSTKEY_API_KEY:-}" 2>&1)
|
||||
response=$(hostkey_api GET "/v1/services" 2>&1) || true
|
||||
|
||||
if echo "$response" | grep -qi "unauthorized\|invalid\|error"; then
|
||||
log_error "API Error: Invalid or expired HOSTKEY API key"
|
||||
|
|
@ -80,7 +65,7 @@ ensure_hostkey_token() {
|
|||
hostkey_check_ssh_key() {
|
||||
local fingerprint="$1"
|
||||
local response
|
||||
response=$(hostkey_api "/ssh_keys")
|
||||
response=$(hostkey_api GET "/ssh_keys")
|
||||
|
||||
if echo "$response" | grep -q "$fingerprint"; then
|
||||
return 0
|
||||
|
|
@ -99,7 +84,7 @@ hostkey_register_ssh_key() {
|
|||
|
||||
local register_body="{\"name\":\"$key_name\",\"public_key\":$json_pub_key}"
|
||||
local register_response
|
||||
register_response=$(hostkey_api "/ssh_keys" "$register_body")
|
||||
register_response=$(hostkey_api POST "/ssh_keys" "$register_body")
|
||||
|
||||
if echo "$register_response" | grep -qi "error"; then
|
||||
log_error "API Error: $(echo "$register_response" | grep -o '"message":"[^"]*"' || echo "$register_response")"
|
||||
|
|
@ -227,7 +212,7 @@ create_server() {
|
|||
'{name: $name, location: $location, preset: $preset, os: "ubuntu-24.04"}')
|
||||
|
||||
local response
|
||||
response=$(hostkey_api "/eq/order_instance" "$order_body")
|
||||
response=$(hostkey_api POST "/eq/order_instance" "$order_body")
|
||||
|
||||
if echo "$response" | grep -qi "error"; then
|
||||
log_error "Failed to create HOSTKEY instance"
|
||||
|
|
@ -268,7 +253,7 @@ destroy_server() {
|
|||
|
||||
log_step "Destroying instance $instance_id..."
|
||||
local response
|
||||
response=$(hostkey_api "/eq/terminate" "{\"id\":\"$instance_id\"}")
|
||||
response=$(hostkey_api POST "/eq/terminate" "{\"id\":\"$instance_id\"}")
|
||||
|
||||
if echo "$response" | grep -qi "error"; then
|
||||
log_error "Failed to destroy instance: $response"
|
||||
|
|
@ -281,7 +266,7 @@ destroy_server() {
|
|||
# List all HOSTKEY instances
|
||||
list_servers() {
|
||||
local response
|
||||
response=$(hostkey_api "/v1/services")
|
||||
response=$(hostkey_api GET "/v1/services")
|
||||
|
||||
local count
|
||||
count=$(printf '%s' "$response" | jq 'length' 2>/dev/null || echo "0")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue