Spaces:
Running
Running
File size: 4,573 Bytes
3d325be 04a3a48 24f9049 04a3a48 24f9049 04a3a48 24f9049 3d325be 24f9049 3d325be 24f9049 04a3a48 24f9049 04a3a48 3d325be 04a3a48 24f9049 04a3a48 24f9049 04a3a48 24f9049 04a3a48 3d325be 24f9049 3d325be 04a3a48 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | import os
import sys
import tarfile
from huggingface_hub import HfApi, hf_hub_download
api = HfApi()
repo_id = os.getenv("HF_DATASET")
token = os.getenv("HF_TOKEN")
FILENAME = "latest_backup.tar.gz"
STATE_DIR = "/root/.openclaw"
# 只备份/恢复这些数据目录(不含 openclaw.json,让 config-generator 重新生成)
DATA_DIRS = [
"agents",
"workspace",
"sessions",
"credentials",
"backups",
"skills",
"logs",
"openclaw-weixin",
"identity",
"media",
"plugins",
"plugin-skills",
"tasks",
"npm",
".cc-switch",
]
# 单独文件也需要保留
DATA_FILES = [
"agent_bindings.json",
"update-check.json",
]
def restore():
try:
if not repo_id or not token:
print("[Sync] Skip Restore: HF_DATASET or HF_TOKEN not set")
return
print(f"[Sync] Downloading {FILENAME} from {repo_id}...")
path = hf_hub_download(
repo_id=repo_id, filename=FILENAME,
repo_type="dataset", token=token,
force_download=True
)
print(f"[Sync] Selective restore: only data dirs, skip openclaw.json")
extracted = 0
skipped = 0
with tarfile.open(path, "r:gz") as tar:
for member in tar.getmembers():
name = member.name
# 跳过根级别的 openclaw.json(让 config-generator 重新生成)
if name == "openclaw.json":
skipped += 1
continue
# 检查是否属于数据目录或数据文件
allowed = False
for d in DATA_DIRS:
if name == d or name.startswith(d + "/"):
allowed = True
break
if not allowed:
for f in DATA_FILES:
if name == f:
allowed = True
break
if allowed:
tar.extract(member, path=STATE_DIR)
extracted += 1
else:
skipped += 1
print(f"[Sync] Restore done: extracted {extracted}, skipped {skipped}")
# 验证关键文件
for check_dir, label in [
("agents/agent_1/sessions", "agent_1 sessions"),
("sessions", "root sessions"),
("workspace", "workspace"),
("openclaw-weixin", "weixin data"),
]:
full = os.path.join(STATE_DIR, check_dir)
if os.path.exists(full):
count = len([f for f in os.listdir(full) if os.path.isfile(os.path.join(full, f))])
print(f"[Sync] {label}: {count} files")
else:
print(f"[Sync] {label}: NOT FOUND")
memory_file = os.path.join(STATE_DIR, "workspace", "MEMORY.md")
if os.path.exists(memory_file):
size = os.path.getsize(memory_file)
print(f"[Sync] MEMORY.md: {size} bytes")
else:
print(f"[Sync] MEMORY.md: NOT FOUND")
return True
except Exception as e:
print(f"[Sync] Restore note: No existing backup or error: {e}")
return False
def backup():
try:
if not repo_id or not token:
print("[Sync] Skip Backup: HF_DATASET or HF_TOKEN not set")
return
print(f"[Sync] Backing up data from {STATE_DIR}...")
file_count = 0
with tarfile.open(FILENAME, "w:gz") as tar:
# 备份数据目录
for d in DATA_DIRS:
full = os.path.join(STATE_DIR, d)
if os.path.exists(full):
tar.add(full, arcname=d)
file_count += 1
# 备份数据文件
for f in DATA_FILES:
full = os.path.join(STATE_DIR, f)
if os.path.exists(full):
tar.add(full, arcname=f)
file_count += 1
size = os.path.getsize(FILENAME)
print(f"[Sync] Archive: {file_count} items, {size // 1024} KB")
api.upload_file(
path_or_fileobj=FILENAME,
path_in_repo=FILENAME,
repo_id=repo_id,
repo_type="dataset",
token=token
)
print(f"[Sync] Backup uploaded to {repo_id}/{FILENAME}")
except Exception as e:
print(f"[Sync] Backup error: {e}")
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "backup":
backup()
else:
restore()
|