feat: 完整游戏运维功能
This commit is contained in:
@@ -38,7 +38,7 @@ wait_for_url() {
|
||||
}
|
||||
|
||||
start_self_hosted_stack() {
|
||||
mkdir -p "$LOCAL_DEBUG_LOG_DIR" "$LOCAL_DEBUG_PID_DIR" "$PLATFORM_DATA_DIR" "$PLATFORM_LOG_DIR" "$RUN_WORKSPACE_ROOT" "$RUN_SPOOL_ROOT" "$GOCACHE"
|
||||
mkdir -p "$LOCAL_DEBUG_LOG_DIR" "$LOCAL_DEBUG_PID_DIR" "$PLATFORM_DATA_DIR" "$PLATFORM_LOG_DIR" "$PLATFORM_ARTIFACT_DIR" "$RUN_WORKSPACE_ROOT" "$RUN_SPOOL_ROOT" "$GOCACHE"
|
||||
trap cleanup_self_started EXIT
|
||||
|
||||
printf 'self-starting platform for local debug smoke\n'
|
||||
@@ -52,6 +52,10 @@ start_self_hosted_stack() {
|
||||
PLATFORM_METADATA_PATH="$PLATFORM_METADATA_PATH" \
|
||||
PLATFORM_LOG_BODY_BACKEND="$PLATFORM_LOG_BODY_BACKEND" \
|
||||
PLATFORM_LOG_DIR="$PLATFORM_LOG_DIR" \
|
||||
PLATFORM_ARTIFACT_DIR="$PLATFORM_ARTIFACT_DIR" \
|
||||
PLATFORM_BOOTSTRAP_ADMIN_EMAIL="$PLATFORM_BOOTSTRAP_ADMIN_EMAIL" \
|
||||
PLATFORM_BOOTSTRAP_ADMIN_PASSWORD="$PLATFORM_BOOTSTRAP_ADMIN_PASSWORD" \
|
||||
PLATFORM_SECRET_ENVELOPE_KEY="$PLATFORM_SECRET_ENVELOPE_KEY" \
|
||||
go run ./cmd/platform
|
||||
) >"$LOCAL_DEBUG_LOG_DIR/platform.log" 2>&1 &
|
||||
SELF_STARTED_PIDS+=("$!")
|
||||
@@ -103,8 +107,9 @@ json_post() {
|
||||
local url="$1"
|
||||
local body_file="$2"
|
||||
local output_file="$3"
|
||||
shift 3
|
||||
local status
|
||||
status="$(curl -sS -H 'Content-Type: application/json' --data-binary "@$body_file" "$url" -o "$output_file" -w '%{http_code}')"
|
||||
status="$(curl -sS -H 'Content-Type: application/json' "$@" --data-binary "@$body_file" "$url" -o "$output_file" -w '%{http_code}')"
|
||||
case "$status" in
|
||||
2*)
|
||||
return 0
|
||||
@@ -152,6 +157,61 @@ json_id() {
|
||||
node -e 'const fs=require("fs"); const data=JSON.parse(fs.readFileSync(process.argv[1],"utf8")); const id=data.instance?.id || data.serverInstance?.id || data.id || ((data.items||[])[0]||{}).id; if (!id) process.exit(2); process.stdout.write(id);' "$1"
|
||||
}
|
||||
|
||||
wait_for_distribution_build() {
|
||||
local distribution_file="$1"
|
||||
local job_file="$2"
|
||||
local artifact_file="$3"
|
||||
local job_id
|
||||
local artifact_id
|
||||
job_id="$(node -e 'const fs=require("fs"); const data=JSON.parse(fs.readFileSync(process.argv[1],"utf8")); if (!data.buildJobId) process.exit(2); process.stdout.write(data.buildJobId);' "$distribution_file")"
|
||||
artifact_id="$(node -e 'const fs=require("fs"); const data=JSON.parse(fs.readFileSync(process.argv[1],"utf8")); if (!data.artifactId) process.exit(2); process.stdout.write(data.artifactId);' "$distribution_file")"
|
||||
rm -f "$job_file" "$artifact_file"
|
||||
|
||||
for _ in $(seq 1 60); do
|
||||
json_get "$API_URL/jobs/$job_id" "$job_file" "${AUTH_HEADER[@]}" || true
|
||||
if [[ ! -s "$job_file" ]]; then
|
||||
sleep 1
|
||||
continue
|
||||
fi
|
||||
if node - "$job_file" <<'NODE'; then
|
||||
const fs = require("fs");
|
||||
const job = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
|
||||
process.exit(job.state === "succeeded" && job.resultRef ? 0 : 1);
|
||||
NODE
|
||||
break
|
||||
fi
|
||||
if node - "$job_file" <<'NODE'; then
|
||||
const fs = require("fs");
|
||||
const job = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
|
||||
process.exit(job.state === "failed" || job.state === "cancelled" ? 0 : 1);
|
||||
NODE
|
||||
printf 'distribution build job reached terminal failure\n' >&2
|
||||
sed -n '1,120p' "$job_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
json_get "$API_URL/jobs/$job_id" "$job_file" "${AUTH_HEADER[@]}"
|
||||
json_get "$API_URL/artifacts/$artifact_id" "$artifact_file" "${AUTH_HEADER[@]}"
|
||||
node - "$job_file" "$artifact_file" "$artifact_id" <<'NODE'
|
||||
const fs = require("fs");
|
||||
const job = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
|
||||
const artifact = JSON.parse(fs.readFileSync(process.argv[3], "utf8"));
|
||||
const artifactId = process.argv[4];
|
||||
if (job.state !== "succeeded" || job.resultRef !== `artifact://${artifactId}`) {
|
||||
console.error("expected distribution build job to succeed with artifact result");
|
||||
console.error(JSON.stringify(job, null, 2));
|
||||
process.exit(1);
|
||||
}
|
||||
if (artifact.id !== artifactId || artifact.state !== "available" || !/^sha256:/.test(artifact.checksum || "")) {
|
||||
console.error("expected available distribution artifact with sha256 checksum");
|
||||
console.error(JSON.stringify(artifact, null, 2));
|
||||
process.exit(1);
|
||||
}
|
||||
NODE
|
||||
}
|
||||
|
||||
printf 'checking platform health at %s\n' "$PLATFORM_URL"
|
||||
json_get "$PLATFORM_URL/healthz" "$WORK_DIR/health.json"
|
||||
require_file_contains "$WORK_DIR/health.json" '"status"[[:space:]]*:[[:space:]]*"ok"'
|
||||
@@ -159,7 +219,7 @@ require_file_contains "$WORK_DIR/health.json" '"status"[[:space:]]*:[[:space:]]*
|
||||
cat >"$WORK_DIR/login.request.json" <<'JSON'
|
||||
{"account":"operator.local@example.test","password":"operator-local"}
|
||||
JSON
|
||||
json_post "$API_URL/auth/login" "$WORK_DIR/login.request.json" "$WORK_DIR/login.response.json"
|
||||
json_post "$API_URL/auth/login" "$WORK_DIR/login.request.json" "$WORK_DIR/login.response.json" -H 'X-Auth-Token-Response: bearer'
|
||||
SESSION_ID="$(session_token_from_login "$WORK_DIR/login.response.json")"
|
||||
AUTH_HEADER=(-H "Authorization: Bearer $SESSION_ID")
|
||||
require_file_contains "$WORK_DIR/login.response.json" '"status"[[:space:]]*:[[:space:]]*"active"'
|
||||
@@ -356,7 +416,19 @@ curl -fsS -H 'Content-Type: application/json' "${AUTH_HEADER[@]}" --data-binary
|
||||
reject_forbidden_fragments "$WORK_DIR/scum-alpha-run-generate.response.json"
|
||||
require_file_contains "$WORK_DIR/scum-alpha-run-generate.response.json" '"serverInstanceId"[[:space:]]*:[[:space:]]*"scum-alpha"'
|
||||
require_file_contains "$WORK_DIR/scum-alpha-run-generate.response.json" '"artifactId"[[:space:]]*:[[:space:]]*"artifact-run-dist-scum-alpha'
|
||||
require_file_contains "$WORK_DIR/scum-alpha-run-generate.response.json" '"checksum"[[:space:]]*:[[:space:]]*"sha256:'
|
||||
require_file_contains "$WORK_DIR/scum-alpha-run-generate.response.json" '"buildJobId"[[:space:]]*:[[:space:]]*"job-distribution-build'
|
||||
node - "$WORK_DIR/scum-alpha-run-generate.response.json" <<'NODE'
|
||||
const fs = require("fs");
|
||||
const distribution = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
|
||||
if (distribution.status !== "building" && distribution.status !== "available") {
|
||||
console.error("expected run distribution to be building or available");
|
||||
console.error(JSON.stringify(distribution, null, 2));
|
||||
process.exit(1);
|
||||
}
|
||||
NODE
|
||||
wait_for_distribution_build "$WORK_DIR/scum-alpha-run-generate.response.json" "$WORK_DIR/scum-alpha-run-build-job.response.json" "$WORK_DIR/scum-alpha-run-build-artifact.response.json"
|
||||
reject_forbidden_fragments "$WORK_DIR/scum-alpha-run-build-job.response.json"
|
||||
reject_forbidden_fragments "$WORK_DIR/scum-alpha-run-build-artifact.response.json"
|
||||
|
||||
printf 'checking jobs, logs, artifacts, and marketplace refs\n'
|
||||
json_get "$API_URL/server-instances" "$WORK_DIR/server-instances.response.json" "${AUTH_HEADER[@]}"
|
||||
|
||||
Reference in New Issue
Block a user