Spaces:
Building
Building
Merge pull request #2 from anurag162008/hf-sync
Browse files- iframe-fix.cjs +4 -0
- openclaw-sync.py +43 -8
- start.sh +36 -0
iframe-fix.cjs
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
/**
|
| 2 |
* iframe-fix.cjs β Node.js preload script
|
| 3 |
*
|
|
|
|
| 1 |
+
process.on('uncaughtException', function(err) {
|
| 2 |
+
if (err.code === 'EPIPE') return;
|
| 3 |
+
throw err;
|
| 4 |
+
});
|
| 5 |
/**
|
| 6 |
* iframe-fix.cjs β Node.js preload script
|
| 7 |
*
|
openclaw-sync.py
CHANGED
|
@@ -87,20 +87,33 @@ def count_files(path: Path) -> int:
|
|
| 87 |
def snapshot_state_into_workspace() -> None:
|
| 88 |
try:
|
| 89 |
STATE_DIR.mkdir(parents=True, exist_ok=True)
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
|
| 94 |
for source_path in OPENCLAW_HOME.iterdir():
|
| 95 |
if source_path.name in EXCLUDED_STATE_NAMES:
|
| 96 |
continue
|
| 97 |
|
| 98 |
-
backup_path =
|
| 99 |
if source_path.is_dir():
|
| 100 |
shutil.copytree(source_path, backup_path)
|
| 101 |
elif source_path.is_file():
|
| 102 |
shutil.copy2(source_path, backup_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
except Exception as exc:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
print(f"Warning: could not snapshot OpenClaw state: {exc}")
|
| 105 |
|
| 106 |
try:
|
|
@@ -135,6 +148,23 @@ def snapshot_state_into_workspace() -> None:
|
|
| 135 |
|
| 136 |
def restore_embedded_state() -> None:
|
| 137 |
state_backup_root = STATE_DIR / "openclaw"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
if state_backup_root.is_dir():
|
| 139 |
for source_path in state_backup_root.iterdir():
|
| 140 |
name = source_path.name
|
|
@@ -398,12 +428,18 @@ def loop() -> int:
|
|
| 398 |
print(f"Workspace sync error: {exc}")
|
| 399 |
return 1
|
| 400 |
|
| 401 |
-
last_fingerprint = fingerprint_dir(WORKSPACE)
|
| 402 |
-
last_marker = metadata_marker(WORKSPACE)
|
| 403 |
-
|
| 404 |
time.sleep(INITIAL_DELAY)
|
| 405 |
print(f"Workspace sync started: every {INTERVAL}s -> {repo_id}")
|
| 406 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 407 |
while not STOP_EVENT.is_set():
|
| 408 |
try:
|
| 409 |
last_fingerprint, last_marker = sync_once(last_fingerprint, last_marker)
|
|
@@ -416,7 +452,6 @@ def loop() -> int:
|
|
| 416 |
|
| 417 |
return 0
|
| 418 |
|
| 419 |
-
|
| 420 |
def main() -> int:
|
| 421 |
WORKSPACE.mkdir(parents=True, exist_ok=True)
|
| 422 |
|
|
|
|
| 87 |
def snapshot_state_into_workspace() -> None:
|
| 88 |
try:
|
| 89 |
STATE_DIR.mkdir(parents=True, exist_ok=True)
|
| 90 |
+
# Atomic snapshot: copy to a staging dir first, then rename.
|
| 91 |
+
# This prevents a half-written (or empty) backup if we crash mid-copy,
|
| 92 |
+
# which would otherwise be uploaded and overwrite the real HF backup.
|
| 93 |
+
staging_dir = STATE_DIR / ".openclaw-staging"
|
| 94 |
+
if staging_dir.exists():
|
| 95 |
+
shutil.rmtree(staging_dir, ignore_errors=True)
|
| 96 |
+
staging_dir.mkdir(parents=True, exist_ok=True)
|
| 97 |
|
| 98 |
for source_path in OPENCLAW_HOME.iterdir():
|
| 99 |
if source_path.name in EXCLUDED_STATE_NAMES:
|
| 100 |
continue
|
| 101 |
|
| 102 |
+
backup_path = staging_dir / source_path.name
|
| 103 |
if source_path.is_dir():
|
| 104 |
shutil.copytree(source_path, backup_path)
|
| 105 |
elif source_path.is_file():
|
| 106 |
shutil.copy2(source_path, backup_path)
|
| 107 |
+
|
| 108 |
+
# Atomically swap staging β real backup dir
|
| 109 |
+
if OPENCLAW_STATE_BACKUP_DIR.exists():
|
| 110 |
+
shutil.rmtree(OPENCLAW_STATE_BACKUP_DIR, ignore_errors=True)
|
| 111 |
+
staging_dir.rename(OPENCLAW_STATE_BACKUP_DIR)
|
| 112 |
except Exception as exc:
|
| 113 |
+
# Clean up staging on failure so it doesn't interfere next time
|
| 114 |
+
staging_dir = STATE_DIR / ".openclaw-staging"
|
| 115 |
+
if staging_dir.exists():
|
| 116 |
+
shutil.rmtree(staging_dir, ignore_errors=True)
|
| 117 |
print(f"Warning: could not snapshot OpenClaw state: {exc}")
|
| 118 |
|
| 119 |
try:
|
|
|
|
| 148 |
|
| 149 |
def restore_embedded_state() -> None:
|
| 150 |
state_backup_root = STATE_DIR / "openclaw"
|
| 151 |
+
|
| 152 |
+
# Migration fix: old backups stored state in ".huggingclaw-state/openclaw"
|
| 153 |
+
# (hidden dir). If new path doesn't exist but old hidden path does, use it
|
| 154 |
+
# and migrate it to the new path so future syncs write to the right place.
|
| 155 |
+
if not state_backup_root.is_dir():
|
| 156 |
+
legacy_state = WORKSPACE / ".huggingclaw-state" / "openclaw"
|
| 157 |
+
if legacy_state.is_dir():
|
| 158 |
+
print("Found legacy state backup at .huggingclaw-state/; migrating to huggingclaw-state/...")
|
| 159 |
+
try:
|
| 160 |
+
STATE_DIR.mkdir(parents=True, exist_ok=True)
|
| 161 |
+
shutil.copytree(legacy_state, state_backup_root)
|
| 162 |
+
legacy_root = WORKSPACE / ".huggingclaw-state"
|
| 163 |
+
shutil.rmtree(legacy_root, ignore_errors=True)
|
| 164 |
+
print("Legacy state migrated and .huggingclaw-state/ removed.")
|
| 165 |
+
except Exception as exc:
|
| 166 |
+
print(f"Warning: could not migrate legacy state: {exc}")
|
| 167 |
+
|
| 168 |
if state_backup_root.is_dir():
|
| 169 |
for source_path in state_backup_root.iterdir():
|
| 170 |
name = source_path.name
|
|
|
|
| 428 |
print(f"Workspace sync error: {exc}")
|
| 429 |
return 1
|
| 430 |
|
|
|
|
|
|
|
|
|
|
| 431 |
time.sleep(INITIAL_DELAY)
|
| 432 |
print(f"Workspace sync started: every {INTERVAL}s -> {repo_id}")
|
| 433 |
|
| 434 |
+
# Take a fingerprint of the workspace AS RESTORED (after snapshotting state)
|
| 435 |
+
# so the first loop iteration only uploads if something genuinely changed.
|
| 436 |
+
# Previously this was None, which forced an unconditional upload every restart
|
| 437 |
+
# β even when restore had failed silently and the workspace was empty.
|
| 438 |
+
snapshot_state_into_workspace()
|
| 439 |
+
last_fingerprint = fingerprint_dir(WORKSPACE)
|
| 440 |
+
last_marker = metadata_marker(WORKSPACE)
|
| 441 |
+
print("Initial workspace fingerprint captured.")
|
| 442 |
+
|
| 443 |
while not STOP_EVENT.is_set():
|
| 444 |
try:
|
| 445 |
last_fingerprint, last_marker = sync_once(last_fingerprint, last_marker)
|
|
|
|
| 452 |
|
| 453 |
return 0
|
| 454 |
|
|
|
|
| 455 |
def main() -> int:
|
| 456 |
WORKSPACE.mkdir(parents=True, exist_ok=True)
|
| 457 |
|
start.sh
CHANGED
|
@@ -536,6 +536,29 @@ if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ]; then
|
|
| 536 |
python3 /home/node/app/cloudflare-keepalive-setup.py || true
|
| 537 |
fi
|
| 538 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 539 |
# ββ Re-install previously installed plugins ββ
|
| 540 |
EXISTING_CONFIG="/home/node/.openclaw/openclaw.json"
|
| 541 |
if [ -f "$EXISTING_CONFIG" ]; then
|
|
@@ -557,6 +580,19 @@ if [ -f "$EXISTING_CONFIG" ]; then
|
|
| 557 |
fi
|
| 558 |
fi
|
| 559 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 560 |
# ββ Launch gateway ββ
|
| 561 |
echo "Launching OpenClaw gateway on port 7860..."
|
| 562 |
|
|
|
|
| 536 |
python3 /home/node/app/cloudflare-keepalive-setup.py || true
|
| 537 |
fi
|
| 538 |
|
| 539 |
+
# ββ Write shell capture wrappers to .bashrc ββ
|
| 540 |
+
STARTUP_FILE="/home/node/.openclaw/workspace/startup.sh"
|
| 541 |
+
cat > /home/node/.bashrc << 'BASHRC'
|
| 542 |
+
STARTUP_FILE="/home/node/.openclaw/workspace/startup.sh"
|
| 543 |
+
_hc_append() {
|
| 544 |
+
local line="$*"
|
| 545 |
+
grep -qxF "$line" "$STARTUP_FILE" 2>/dev/null || echo "$line" >> "$STARTUP_FILE"
|
| 546 |
+
}
|
| 547 |
+
apt-get() {
|
| 548 |
+
command apt-get "$@"
|
| 549 |
+
[[ "$1" == "install" ]] && _hc_append "apt-get install -y ${@:2}"
|
| 550 |
+
}
|
| 551 |
+
apt() {
|
| 552 |
+
command apt "$@"
|
| 553 |
+
[[ "$1" == "install" ]] && _hc_append "apt-get install -y ${@:2}"
|
| 554 |
+
}
|
| 555 |
+
pip() { command pip "$@"; [[ "$1" == "install" ]] && _hc_append "pip install ${@:2}"; }
|
| 556 |
+
pip3() { command pip3 "$@"; [[ "$1" == "install" ]] && _hc_append "pip3 install ${@:2}"; }
|
| 557 |
+
npm() { command npm "$@"; [[ "$1" == "install" && "$2" == "-g" ]] && _hc_append "npm install -g ${@:3}"; }
|
| 558 |
+
openclaw() { command openclaw "$@"; [[ "$1" == "plugins" && "$2" == "install" ]] && _hc_append "openclaw plugins install ${@:3}"; }
|
| 559 |
+
BASHRC
|
| 560 |
+
echo "Shell capture wrappers ready."
|
| 561 |
+
|
| 562 |
# ββ Re-install previously installed plugins ββ
|
| 563 |
EXISTING_CONFIG="/home/node/.openclaw/openclaw.json"
|
| 564 |
if [ -f "$EXISTING_CONFIG" ]; then
|
|
|
|
| 580 |
fi
|
| 581 |
fi
|
| 582 |
|
| 583 |
+
# ββ Run workspace startup script ββ
|
| 584 |
+
STARTUP_FILE="/home/node/.openclaw/workspace/startup.sh"
|
| 585 |
+
if [ ! -f "$STARTUP_FILE" ]; then
|
| 586 |
+
touch "$STARTUP_FILE"
|
| 587 |
+
chmod +x "$STARTUP_FILE"
|
| 588 |
+
echo "Created workspace/startup.sh"
|
| 589 |
+
fi
|
| 590 |
+
if [ -s "$STARTUP_FILE" ]; then
|
| 591 |
+
echo "Running workspace/startup.sh..."
|
| 592 |
+
bash "$STARTUP_FILE" || echo "Warning: startup.sh had errors, continuing..."
|
| 593 |
+
echo "Startup script complete."
|
| 594 |
+
fi
|
| 595 |
+
|
| 596 |
# ββ Launch gateway ββ
|
| 597 |
echo "Launching OpenClaw gateway on port 7860..."
|
| 598 |
|