mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-04 10:42:23 +00:00
69 lines
4.8 KiB
Bash
Executable File
69 lines
4.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Transfer both VM servers A -> B through the API and check source, target, server, and a redeploy from B.
|
|
# Run reset.sh before and after.
|
|
source "$(dirname "$0")/lib.sh"
|
|
TA="$(source_token)"
|
|
TB="$(target_token)"
|
|
|
|
for profile in "${TRANSFER_PROFILES[@]}"; do
|
|
S="$(vm_field "$profile" uuid)"
|
|
ip="$(vm_field "$profile" ip)"
|
|
echo "=== $S"
|
|
before="$(stable_workloads "$profile")"
|
|
apps="$(tinker "$A" "echo App\\Models\\Server::where('uuid','$S')->first()->applications()->pluck('uuid')->implode(' ');" | tail -1)"
|
|
|
|
echo '-- start the transfer on A'
|
|
r="$(api POST "$A_PORT" "/servers/$S/migrate" "$TA" "$(jq -nc --arg u "http://localhost:$B_PORT" --arg t "$TB" '{target_url:$u,target_token:$t}')")"
|
|
if [[ "$(jq -r .migration.status <<<"$r" 2>/dev/null)" != running ]]; then
|
|
bad "transfer request accepted: $r"
|
|
continue
|
|
fi
|
|
ok 'transfer request accepted'
|
|
for _ in $(seq 1 40); do sleep 3; st="$(api GET "$A_PORT" "/servers/$S/transfer" "$TA" | jq -r .migration.status)"; [[ "$st" != running ]] && break; done
|
|
check "transfer finished ($st)" test "$st" = succeeded
|
|
|
|
echo '-- source A'
|
|
a="$(api GET "$A_PORT" "/servers/$S/transfer" "$TA")"
|
|
export_id="$(jq -r .transfer.export_id <<<"$a")"
|
|
check 'A transfer.status = transferred' test "$(jq -r .transfer.status <<<"$a")" = transferred
|
|
check 'A force_disabled + Sentinel off' test "$(tinker "$A" "\$s=App\\Models\\Server::where('uuid','$S')->first()->settings; echo (int)\$s->force_disabled.(int)\$s->is_sentinel_enabled;" | tail -1)" = 10
|
|
check 'A shows the take-back modal' test "$(tinker "$A" "$login_php echo (int) str_contains(Livewire\\Livewire::test(App\\Livewire\\Server\\Show::class, ['server_uuid'=>'$S'])->html(), 'Take back a transferred server?');" | tail -1)" = 1
|
|
r="$(api POST "$A_PORT" "/servers/$S/migrate" "$TA" "$(jq -nc --arg u "http://localhost:$B_PORT" --arg t "$TB" '{target_url:$u,target_token:$t}')")"
|
|
check 'second transfer refused by the prechecks' grep -q 'already transferred' <<<"$r"
|
|
|
|
echo '-- target B'
|
|
b="$(api GET "$B_PORT" "/servers/$S/transfer" "$TB")"
|
|
check 'B transfer.status = claimed' test "$(jq -r .transfer.status <<<"$b")" = claimed
|
|
check 'same export id on A and B' test "$(jq -r .transfer.export_id <<<"$b")" = "$export_id"
|
|
for _ in $(seq 1 20); do
|
|
sleep 3
|
|
meta="$(tinker "$B" "\$s=App\\Models\\Server::where('uuid','$S')->first(); echo json_encode(['os'=>data_get(\$s->server_metadata,'os'),'reach'=>\$s->settings->is_reachable,'usable'=>\$s->settings->is_usable,'logs'=>\$s->validation_logs,'transfer'=>data_get(\$s->server_metadata,'transfer.status')]);" | tail -1)"
|
|
[[ "$(jq -r .os <<<"$meta")" != null ]] && break
|
|
done
|
|
check "automatic validation filled the metadata ($(jq -r .os <<<"$meta"))" test "$(jq -r .os <<<"$meta")" != null
|
|
check 'B reachable + usable, no validation error' test "$(jq -c '[.reach,.usable,.logs]' <<<"$meta")" = '[true,true,null]'
|
|
check 'transfer state kept after validation' test "$(jq -r .transfer <<<"$meta")" = claimed
|
|
check 'B started the finish list' test "$(tinker "$B" "echo count((array) data_get(App\\Models\\Server::where('uuid','$S')->first()->server_metadata,'transfer.finish.items')) > 0 ? 1 : 0;" | tail -1)" = 1
|
|
check 'A links to the server on B' test "$(jq -r .migration.target_server_url <<<"$a")" = "$B_URL/server/$S"
|
|
check 'B has all applications' test "$(tinker "$B" "echo App\\Models\\Server::where('uuid','$S')->first()->applications()->pluck('uuid')->implode(' ');" | tail -1)" = "$apps"
|
|
check 'B validates the server over SSH' test "$(tinker "$B" "\$r=App\\Models\\Server::where('uuid','$S')->first()->validateConnection(); echo (int)(bool)\$r['uptime'];" | tail -1)" = 1
|
|
|
|
echo '-- server'
|
|
sleep 5
|
|
after="$(workloads "$profile")"
|
|
check 'proxy + workloads not recreated' test "$before" = "$after"
|
|
sentinel_env="$(ssh_vm "$profile" "docker inspect coolify-sentinel --format '{{range .Config.Env}}{{println .}}{{end}}'")"
|
|
check 'Sentinel sends to B' grep -qx "PUSH_ENDPOINT=$B_URL" <<<"$sentinel_env"
|
|
for app in $apps; do check "app $app answers over HTTP" bash -c "curl -sf -m5 -H 'Host: $app.$ip.sslip.io' http://$ip/ >/dev/null"; done
|
|
|
|
echo '-- redeploy one app from B'
|
|
app="${apps%% *}"
|
|
api POST "$B_PORT" "/deploy?uuid=$app&force=false" "$TB" >/dev/null
|
|
for _ in $(seq 1 40); do sleep 5; ds="$(tinker "$B" "echo App\\Models\\ApplicationDeploymentQueue::where('application_id', App\\Models\\Application::where('uuid','$app')->value('id'))->latest('id')->value('status');" | tail -1)"; [[ "$ds" == finished || "$ds" == failed ]] && break; done
|
|
check "redeploy from B ($ds)" test "$ds" = finished
|
|
check 'app answers after the redeploy' bash -c "for i in {1..10}; do curl -sf -m5 -H 'Host: $app.$ip.sslip.io' http://$ip/ >/dev/null && exit 0; sleep 3; done; exit 1"
|
|
done
|
|
|
|
echo "=== $FAILS failure(s)"
|
|
exit "$FAILS"
|