Vendor OpenClaw source as Adolf fork baseline
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
This commit is contained in:
265
scripts/e2e/lib/upgrade-survivor/update-restart-auth.sh
Normal file
265
scripts/e2e/lib/upgrade-survivor/update-restart-auth.sh
Normal file
@@ -0,0 +1,265 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
install_update_restart_systemctl_shim() {
|
||||
local shim_dir="$npm_config_prefix/bin"
|
||||
mkdir -p "$shim_dir"
|
||||
cat >"$shim_dir/systemctl" <<'SHIM'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
log_file="${OPENCLAW_UPGRADE_SURVIVOR_SYSTEMCTL_SHIM_LOG:-/tmp/openclaw-systemctl-shim.log}"
|
||||
pid_file="${OPENCLAW_UPGRADE_SURVIVOR_SYSTEMCTL_SHIM_PID_FILE:-/tmp/openclaw-systemctl-shim.pid}"
|
||||
daemon_log="${OPENCLAW_UPGRADE_SURVIVOR_SYSTEMCTL_SHIM_DAEMON_LOG:-/tmp/openclaw-systemctl-shim-gateway.log}"
|
||||
printf '%s\n' "$*" >>"$log_file"
|
||||
|
||||
filtered=()
|
||||
for ((i = 1; i <= $#; i++)); do
|
||||
arg="${!i}"
|
||||
case "$arg" in
|
||||
--user | --quiet | --no-page | --now)
|
||||
;;
|
||||
--property)
|
||||
i=$((i + 1))
|
||||
;;
|
||||
*)
|
||||
filtered+=("$arg")
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
command="${filtered[0]:-status}"
|
||||
|
||||
is_running() {
|
||||
[ -s "$pid_file" ] || return 1
|
||||
local pid
|
||||
pid="$(cat "$pid_file" 2>/dev/null || true)"
|
||||
[ -n "$pid" ] || return 1
|
||||
kill -0 "$pid" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
stop_gateway() {
|
||||
[ -s "$pid_file" ] || return 0
|
||||
local pid
|
||||
pid="$(cat "$pid_file" 2>/dev/null || true)"
|
||||
if [[ "$pid" =~ ^[0-9]+$ ]] && [ "$pid" -gt 1 ] && kill -0 "$pid" >/dev/null 2>&1; then
|
||||
kill "$pid" >/dev/null 2>&1 || true
|
||||
for _ in $(seq 1 100); do
|
||||
kill -0 "$pid" >/dev/null 2>&1 || break
|
||||
sleep 0.1
|
||||
done
|
||||
kill -9 "$pid" >/dev/null 2>&1 || true
|
||||
fi
|
||||
rm -f "$pid_file"
|
||||
}
|
||||
|
||||
unit_path() {
|
||||
printf '%s/.config/systemd/user/openclaw-gateway.service\n' "${HOME:?missing HOME}"
|
||||
}
|
||||
|
||||
load_unit_environment() {
|
||||
local unit="$1"
|
||||
while IFS= read -r line; do
|
||||
case "$line" in
|
||||
EnvironmentFile=*)
|
||||
local spec="${line#EnvironmentFile=}"
|
||||
for token in $spec; do
|
||||
local file="${token#-}"
|
||||
[ -f "$file" ] || continue
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
. "$file"
|
||||
set +a
|
||||
done
|
||||
;;
|
||||
Environment=*)
|
||||
local assignment="${line#Environment=}"
|
||||
assignment="${assignment#\"}"
|
||||
assignment="${assignment%\"}"
|
||||
export "$assignment"
|
||||
;;
|
||||
esac
|
||||
done <"$unit"
|
||||
}
|
||||
|
||||
start_gateway() {
|
||||
local unit
|
||||
local exec_start
|
||||
unit="$(unit_path)"
|
||||
exec_start="$(sed -n 's/^ExecStart=//p' "$unit" | tail -n 1)"
|
||||
[ -n "$exec_start" ] || {
|
||||
echo "systemctl shim could not find ExecStart in $unit" >&2
|
||||
return 1
|
||||
}
|
||||
(
|
||||
load_unit_environment "$unit"
|
||||
nohup bash -lc "exec $exec_start" >>"$daemon_log" 2>&1 &
|
||||
printf '%s\n' "$!" >"$pid_file"
|
||||
)
|
||||
}
|
||||
|
||||
case "$command" in
|
||||
daemon-reload | enable | disable)
|
||||
exit 0
|
||||
;;
|
||||
status)
|
||||
is_running && exit 0
|
||||
exit 0
|
||||
;;
|
||||
stop)
|
||||
stop_gateway
|
||||
exit 0
|
||||
;;
|
||||
restart | start)
|
||||
stop_gateway
|
||||
start_gateway
|
||||
exit 0
|
||||
;;
|
||||
is-enabled)
|
||||
exit 0
|
||||
;;
|
||||
is-active)
|
||||
is_running && exit 0
|
||||
exit 3
|
||||
;;
|
||||
show)
|
||||
if is_running; then
|
||||
printf 'ActiveState=active\nSubState=running\nMainPID=%s\nExecMainStatus=0\nExecMainCode=0\n' "$(cat "$pid_file")"
|
||||
else
|
||||
printf 'ActiveState=inactive\nSubState=dead\nMainPID=0\nExecMainStatus=0\nExecMainCode=0\n'
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "systemctl shim unsupported command: $*" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
SHIM
|
||||
chmod +x "$shim_dir/systemctl"
|
||||
export PATH="$shim_dir:$PATH"
|
||||
}
|
||||
|
||||
seed_update_restart_probe_device_auth() {
|
||||
node --input-type=module <<'NODE'
|
||||
import crypto from "node:crypto";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const stateDir = process.env.OPENCLAW_STATE_DIR;
|
||||
if (!stateDir) {
|
||||
throw new Error("missing OPENCLAW_STATE_DIR");
|
||||
}
|
||||
|
||||
const base64UrlEncode = (buf) =>
|
||||
buf.toString("base64").replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/g, "");
|
||||
const ed25519SpkiPrefix = Buffer.from("302a300506032b6570032100", "hex");
|
||||
const { publicKey, privateKey } = crypto.generateKeyPairSync("ed25519");
|
||||
const publicKeyPem = publicKey.export({ type: "spki", format: "pem" });
|
||||
const privateKeyPem = privateKey.export({ type: "pkcs8", format: "pem" });
|
||||
const spki = crypto.createPublicKey(publicKeyPem).export({ type: "spki", format: "der" });
|
||||
const rawPublicKey =
|
||||
spki.length === ed25519SpkiPrefix.length + 32 &&
|
||||
spki.subarray(0, ed25519SpkiPrefix.length).equals(ed25519SpkiPrefix)
|
||||
? spki.subarray(ed25519SpkiPrefix.length)
|
||||
: spki;
|
||||
const publicKeyRaw = base64UrlEncode(rawPublicKey);
|
||||
const deviceId = crypto.createHash("sha256").update(rawPublicKey).digest("hex");
|
||||
const token = base64UrlEncode(crypto.randomBytes(32));
|
||||
const now = Date.now();
|
||||
const scopes = ["operator.read"];
|
||||
|
||||
function writeJson(filePath, value) {
|
||||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||
fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, { mode: 0o600 });
|
||||
try {
|
||||
fs.chmodSync(filePath, 0o600);
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
|
||||
writeJson(path.join(stateDir, "identity", "device.json"), {
|
||||
version: 1,
|
||||
deviceId,
|
||||
publicKeyPem,
|
||||
privateKeyPem,
|
||||
createdAtMs: now,
|
||||
});
|
||||
writeJson(path.join(stateDir, "identity", "device-auth.json"), {
|
||||
version: 1,
|
||||
deviceId,
|
||||
tokens: {
|
||||
operator: {
|
||||
token,
|
||||
role: "operator",
|
||||
scopes,
|
||||
updatedAtMs: now,
|
||||
},
|
||||
},
|
||||
});
|
||||
writeJson(path.join(stateDir, "devices", "paired.json"), {
|
||||
[deviceId]: {
|
||||
deviceId,
|
||||
publicKey: publicKeyRaw,
|
||||
displayName: "upgrade survivor restart probe",
|
||||
platform: process.platform,
|
||||
clientId: "openclaw-cli",
|
||||
clientMode: "probe",
|
||||
role: "operator",
|
||||
roles: ["operator"],
|
||||
scopes,
|
||||
approvedScopes: scopes,
|
||||
tokens: {
|
||||
operator: {
|
||||
token,
|
||||
role: "operator",
|
||||
scopes,
|
||||
createdAtMs: now,
|
||||
},
|
||||
},
|
||||
createdAtMs: now,
|
||||
approvedAtMs: now,
|
||||
},
|
||||
});
|
||||
writeJson(path.join(stateDir, "devices", "pending.json"), {});
|
||||
NODE
|
||||
}
|
||||
|
||||
write_update_restart_service_auth_env() {
|
||||
mkdir -p "$OPENCLAW_STATE_DIR"
|
||||
local dotenv_path="$OPENCLAW_STATE_DIR/.env"
|
||||
local tmp_path="$dotenv_path.tmp.$$"
|
||||
if [ -f "$dotenv_path" ]; then
|
||||
grep -v '^GATEWAY_AUTH_TOKEN_REF=' "$dotenv_path" >"$tmp_path" || true
|
||||
else
|
||||
: >"$tmp_path"
|
||||
fi
|
||||
printf 'GATEWAY_AUTH_TOKEN_REF=%s\n' "$GATEWAY_AUTH_TOKEN_REF" >>"$tmp_path"
|
||||
mv "$tmp_path" "$dotenv_path"
|
||||
printf 'GATEWAY_AUTH_TOKEN_REF=%s\n' "$GATEWAY_AUTH_TOKEN_REF" >"$OPENCLAW_STATE_DIR/gateway.systemd.env"
|
||||
}
|
||||
|
||||
prepare_update_restart_probe_current_install() {
|
||||
local port="$1"
|
||||
local log_file="$2"
|
||||
local command_timeout="${OPENCLAW_UPGRADE_SURVIVOR_COMMAND_TIMEOUT:-900s}"
|
||||
local start_epoch
|
||||
local ready_epoch
|
||||
|
||||
echo "Preparing candidate-auth gateway for automatic update restart."
|
||||
install_update_restart_systemctl_shim
|
||||
seed_update_restart_probe_device_auth
|
||||
start_epoch="$(node -e "process.stdout.write(String(Date.now()))")"
|
||||
env -u OPENCLAW_GATEWAY_TOKEN -u OPENCLAW_GATEWAY_PASSWORD openclaw gateway --port "$port" --bind loopback --allow-unconfigured >"$log_file" 2>&1 &
|
||||
gateway_pid="$!"
|
||||
printf '%s\n' "$gateway_pid" >"$OPENCLAW_UPGRADE_SURVIVOR_SYSTEMCTL_SHIM_PID_FILE"
|
||||
openclaw_e2e_wait_gateway_ready "$gateway_pid" "$log_file" 360 "$port"
|
||||
ready_epoch="$(node -e "process.stdout.write(String(Date.now()))")"
|
||||
start_seconds=$(((ready_epoch - start_epoch + 999) / 1000))
|
||||
write_update_restart_service_auth_env
|
||||
if ! openclaw_e2e_maybe_timeout "$command_timeout" env -u OPENCLAW_GATEWAY_TOKEN -u OPENCLAW_GATEWAY_PASSWORD openclaw gateway install --force --json >"$OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SERVICE_INSTALL_JSON" 2>"$OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SERVICE_INSTALL_ERR"; then
|
||||
echo "gateway service install failed" >&2
|
||||
cat "$OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SERVICE_INSTALL_ERR" >&2 || true
|
||||
cat "$OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SERVICE_INSTALL_JSON" >&2 || true
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user