mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
fix(ci): isolate bounded metadata retries (#108804)
* fix(ci): bound Mantis runner IP retries * fix(e2e): isolate Windows metadata retries * fix(ci): validate complete runner IPv4 Co-authored-by: Alix-007 <li.long15@xydigit.com> --------- Co-authored-by: Alix-007 <li.long15@xydigit.com>
This commit is contained in:
co-authored by
Alix-007
parent
d572c5cb2d
commit
e0ffbd90d9
@@ -266,8 +266,29 @@ jobs:
|
||||
require_var OPENCLAW_QA_CONVEX_SECRET_CI
|
||||
require_var CRABBOX_COORDINATOR_TOKEN
|
||||
if [[ -z "${CRABBOX_LEASE_ID:-}" && "$CRABBOX_PROVIDER" == "aws" ]]; then
|
||||
runner_ip="$(curl -fsS --connect-timeout 5 --max-time 15 --retry 2 https://checkip.amazonaws.com | tr -d '[:space:]')"
|
||||
if [[ -z "$runner_ip" ]]; then
|
||||
runner_ip=""
|
||||
for attempt in 1 2 3; do
|
||||
if runner_ip="$(curl -fsS --connect-timeout 5 --max-time 15 https://checkip.amazonaws.com | tr -d '[:space:]')"; then
|
||||
break
|
||||
fi
|
||||
runner_ip=""
|
||||
if [[ "$attempt" != "3" ]]; then
|
||||
sleep "$attempt"
|
||||
fi
|
||||
done
|
||||
valid_runner_ip=true
|
||||
if [[ ! "$runner_ip" =~ ^(0|[1-9][0-9]{0,2})\.(0|[1-9][0-9]{0,2})\.(0|[1-9][0-9]{0,2})\.(0|[1-9][0-9]{0,2})$ ]]; then
|
||||
valid_runner_ip=false
|
||||
else
|
||||
IFS=. read -r -a runner_ip_octets <<<"$runner_ip"
|
||||
for octet in "${runner_ip_octets[@]}"; do
|
||||
if ((10#$octet > 255)); then
|
||||
valid_runner_ip=false
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ "$valid_runner_ip" != "true" ]]; then
|
||||
echo "Could not resolve GitHub runner public IPv4 for AWS SSH ingress." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -95,7 +95,18 @@ require_host_tools() {
|
||||
|
||||
fetch_host_metadata() {
|
||||
# Keep host metadata lookups bounded like the guest download paths below.
|
||||
curl -fsSL --connect-timeout 10 --max-time 120 --retry 2 "$@"
|
||||
local attempt output
|
||||
for attempt in 1 2 3; do
|
||||
if output="$(curl -fsSL --connect-timeout 10 --max-time 120 "$@")"; then
|
||||
printf '%s' "$output"
|
||||
return 0
|
||||
fi
|
||||
output=""
|
||||
if [[ "$attempt" != "3" ]]; then
|
||||
sleep "$attempt"
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
vm_exists() {
|
||||
|
||||
@@ -2161,9 +2161,79 @@ describe("ci workflow guards", () => {
|
||||
(step) => step.name === "Run Slack desktop scenario",
|
||||
);
|
||||
|
||||
expect(runStep?.run).toContain("for attempt in 1 2 3");
|
||||
expect(runStep?.run).toContain(
|
||||
"curl -fsS --connect-timeout 5 --max-time 15 --retry 2 https://checkip.amazonaws.com",
|
||||
"curl -fsS --connect-timeout 5 --max-time 15 https://checkip.amazonaws.com",
|
||||
);
|
||||
expect(runStep?.run).not.toContain("--retry");
|
||||
expect(runStep?.run).toContain('runner_ip=""');
|
||||
expect(runStep?.run).toContain('[[ ! "$runner_ip" =~ ^(0|[1-9][0-9]{0,2})\\.');
|
||||
expect(runStep?.run).toContain("((10#$octet > 255))");
|
||||
|
||||
const discoveryBlock = runStep?.run?.match(
|
||||
/runner_ip=""[\s\S]*?echo "Using AWS SSH CIDR \$\{CRABBOX_AWS_SSH_CIDRS\}"/u,
|
||||
)?.[0];
|
||||
expect(discoveryBlock).toBeTruthy();
|
||||
|
||||
const root = mkdtempSync(path.join(tmpdir(), "openclaw-mantis-runner-ip-"));
|
||||
try {
|
||||
const fakeBin = path.join(root, "bin");
|
||||
const callCount = path.join(root, "curl-calls");
|
||||
mkdirSync(fakeBin);
|
||||
writeFileSync(callCount, "0\n");
|
||||
writeFileSync(
|
||||
path.join(fakeBin, "curl"),
|
||||
`#!/bin/bash
|
||||
count="$(<"$CURL_CALL_COUNT")"
|
||||
count=$((count + 1))
|
||||
printf '%s\n' "$count" >"$CURL_CALL_COUNT"
|
||||
if [[ "$count" == "1" ]]; then
|
||||
printf '198.51.'
|
||||
exit 28
|
||||
fi
|
||||
printf '%s\n' "\${CURL_SUCCESS_IP:-203.0.113.7}"
|
||||
`,
|
||||
{ mode: 0o755 },
|
||||
);
|
||||
writeFileSync(path.join(fakeBin, "sleep"), "#!/bin/sh\nexit 0\n", { mode: 0o755 });
|
||||
|
||||
const result = spawnSync(
|
||||
"bash",
|
||||
[
|
||||
"-c",
|
||||
`set -euo pipefail\n${discoveryBlock}\nprintf 'result=%s\\n' "$CRABBOX_AWS_SSH_CIDRS"`,
|
||||
],
|
||||
{
|
||||
encoding: "utf8",
|
||||
env: {
|
||||
CURL_CALL_COUNT: callCount,
|
||||
PATH: `${fakeBin}:${process.env.PATH}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
expect(result.status, result.stderr).toBe(0);
|
||||
expect(result.stdout).toContain("result=203.0.113.7/32");
|
||||
expect(result.stdout).not.toContain("198.51.");
|
||||
expect(readFileSync(callCount, "utf8")).toBe("2\n");
|
||||
|
||||
for (const invalidIp of ["999.0.0.1", "203.0.113.7."]) {
|
||||
writeFileSync(callCount, "0\n");
|
||||
const invalidResult = spawnSync("bash", ["-c", `set -euo pipefail\n${discoveryBlock}`], {
|
||||
encoding: "utf8",
|
||||
env: {
|
||||
CURL_CALL_COUNT: callCount,
|
||||
CURL_SUCCESS_IP: invalidIp,
|
||||
PATH: `${fakeBin}:${process.env.PATH}`,
|
||||
},
|
||||
});
|
||||
expect(invalidResult.status).toBe(1);
|
||||
expect(invalidResult.stderr).toContain(
|
||||
"Could not resolve GitHub runner public IPv4 for AWS SSH ingress.",
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
rmSync(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("fails Windows Testbox setup when Blacksmith phone-home is not accepted", () => {
|
||||
|
||||
@@ -318,14 +318,43 @@ describe("Parallels smoke model selection", () => {
|
||||
"10",
|
||||
"--max-time",
|
||||
"120",
|
||||
"--retry",
|
||||
"2",
|
||||
"https://example.test/metadata",
|
||||
]);
|
||||
|
||||
const controller = readFileSync(WINDOWS_PREPARE_WRAPPER, "utf8");
|
||||
expect(controller.match(/\bcurl -fsSL\b/g)).toHaveLength(1);
|
||||
expect(controller.match(/\bfetch_host_metadata\b/g)).toHaveLength(5);
|
||||
expect(controller).toContain("for attempt in 1 2 3");
|
||||
expect(controller).not.toContain("--retry 2");
|
||||
|
||||
const tempDir = makeTempDir(tempDirs, "openclaw-windows-metadata-retry-");
|
||||
const callCount = join(tempDir, "curl-calls");
|
||||
writeFileSync(callCount, "0\n");
|
||||
const retryResult = spawnSync(
|
||||
"bash",
|
||||
[
|
||||
"-c",
|
||||
`OPENCLAW_PARALLELS_WINDOWS_LIBRARY_ONLY=1 source "$1"
|
||||
curl() {
|
||||
count="$(<"$CURL_CALL_COUNT")"
|
||||
count=$((count + 1))
|
||||
printf '%s\\n' "$count" >"$CURL_CALL_COUNT"
|
||||
if [[ "$count" == "1" ]]; then
|
||||
printf 'partial-'
|
||||
return 28
|
||||
fi
|
||||
printf 'complete'
|
||||
}
|
||||
sleep() { :; }
|
||||
fetch_host_metadata "https://example.test/metadata"`,
|
||||
"bash",
|
||||
WINDOWS_PREPARE_WRAPPER,
|
||||
],
|
||||
{ encoding: "utf8", env: { ...process.env, CURL_CALL_COUNT: callCount } },
|
||||
);
|
||||
expect(retryResult.status, retryResult.stderr).toBe(0);
|
||||
expect(retryResult.stdout).toBe("complete");
|
||||
expect(readFileSync(callCount, "utf8")).toBe("2\n");
|
||||
});
|
||||
|
||||
it("accepts leading package-manager separators and still honors later terminators", () => {
|
||||
|
||||
Reference in New Issue
Block a user