Spaces:
Running
Running
Update Dockerfile
Browse files- Dockerfile +49 -20
Dockerfile
CHANGED
|
@@ -127,12 +127,39 @@ def restore():
|
|
| 127 |
print("Restore skip: RESTORE_SKIP=all, skipping all restore.")
|
| 128 |
return
|
| 129 |
|
| 130 |
-
#
|
| 131 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
|
| 133 |
try:
|
| 134 |
all_files = list(api.list_repo_files(repo_id=repo_id, repo_type="dataset", token=token))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
# ── 從 tar.gz 備份恢復 ───────────────────────────────────────────────
|
| 137 |
# 備份範圍:/root/.openclaw 下所有文件及文件夾(保持完整目錄結構)
|
| 138 |
# tar 包內 arcname 直接對應 .openclaw/ 下的相對路徑,解壓目標為 /root/.openclaw/
|
|
@@ -157,11 +184,24 @@ def restore():
|
|
| 157 |
print(f"Success: Restored from {name}")
|
| 158 |
break
|
| 159 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
except Exception as e:
|
| 161 |
print(f"Restore Error: {e}")
|
| 162 |
|
| 163 |
|
| 164 |
-
|
| 165 |
# ── backup() ──────────────────────────────────────────────────────────────────
|
| 166 |
|
| 167 |
def backup():
|
|
@@ -259,23 +299,12 @@ RUN cat <<'EOF' > /usr/local/bin/start-openclaw
|
|
| 259 |
set -e
|
| 260 |
|
| 261 |
# ── restore() 觸發條件判斷 ──────────────────────────────────────────────────
|
| 262 |
-
#
|
| 263 |
-
#
|
| 264 |
-
#
|
| 265 |
-
#
|
| 266 |
-
#
|
| 267 |
-
|
| 268 |
-
# 改用 workspace/USER.md 作為判定標誌:
|
| 269 |
-
# - 該文件由本腳本在 restore() 之後的配置寫入步驟生成
|
| 270 |
-
# - mkdir -p /root/.openclaw/logs 不會創建它
|
| 271 |
-
# - 首次部署 / 任何形式的容器重建:文件不存在 → 執行 restore()
|
| 272 |
-
# - 運行中再次調用本腳本(文件已存在) → 跳過 restore()
|
| 273 |
-
if [ ! -f /root/.openclaw/workspace/USER.md ]; then
|
| 274 |
-
echo "=== First deploy / rebuild detected: running restore() ==="
|
| 275 |
-
python3 /usr/local/bin/sync.py restore
|
| 276 |
-
else
|
| 277 |
-
echo "=== USER.md exists, skipping restore() ==="
|
| 278 |
-
fi
|
| 279 |
|
| 280 |
mkdir -p /root/.openclaw/sessions
|
| 281 |
|
|
|
|
| 127 |
print("Restore skip: RESTORE_SKIP=all, skipping all restore.")
|
| 128 |
return
|
| 129 |
|
| 130 |
+
# ── 方案 B:以 Dataset 中的 initialized.flag 作為觸發條件 ─────────────────
|
| 131 |
+
# 邏輯:
|
| 132 |
+
# - Dataset 中無 initialized.flag → 首次部署 → 執行 restore,完成後寫入標記
|
| 133 |
+
# - Dataset 中有 initialized.flag → 普通 restart → 跳過 restore
|
| 134 |
+
# - FORCE_RESTORE=true → 無視標記,強制執行 restore(用於 factory rebuild)
|
| 135 |
+
#
|
| 136 |
+
# Factory rebuild 場景的兩種觸發方式(任選其一):
|
| 137 |
+
# 1. 在 HF Space Settings 中設置環境變量 FORCE_RESTORE=true,重建後再刪除此變量
|
| 138 |
+
# 2. 直接在 HF Dataset 網頁上刪除 initialized.flag 文件,再點 Restart
|
| 139 |
+
INIT_FLAG = "initialized.flag"
|
| 140 |
+
force_restore = os.getenv("FORCE_RESTORE", "").strip().lower() in ("true", "1", "yes")
|
| 141 |
|
| 142 |
try:
|
| 143 |
all_files = list(api.list_repo_files(repo_id=repo_id, repo_type="dataset", token=token))
|
| 144 |
+
except Exception as e:
|
| 145 |
+
print(f"Restore Error (list_repo_files): {e}")
|
| 146 |
+
return
|
| 147 |
+
|
| 148 |
+
flag_exists = INIT_FLAG in all_files
|
| 149 |
+
|
| 150 |
+
if flag_exists and not force_restore:
|
| 151 |
+
print("Restore skip: initialized.flag found in Dataset, this is a normal restart.")
|
| 152 |
+
return
|
| 153 |
+
|
| 154 |
+
if force_restore:
|
| 155 |
+
print("Restore: FORCE_RESTORE=true, ignoring initialized.flag.")
|
| 156 |
+
else:
|
| 157 |
+
print("Restore: initialized.flag not found, this is first deploy or rebuild.")
|
| 158 |
|
| 159 |
+
# 解析跳過列表(用於在解壓時逐條目跳過,不是解壓後刪除)
|
| 160 |
+
skip_set = _parse_skip_list("RESTORE_SKIP")
|
| 161 |
+
|
| 162 |
+
try:
|
| 163 |
# ── 從 tar.gz 備份恢復 ───────────────────────────────────────────────
|
| 164 |
# 備份範圍:/root/.openclaw 下所有文件及文件夾(保持完整目錄結構)
|
| 165 |
# tar 包內 arcname 直接對應 .openclaw/ 下的相對路徑,解壓目標為 /root/.openclaw/
|
|
|
|
| 184 |
print(f"Success: Restored from {name}")
|
| 185 |
break
|
| 186 |
|
| 187 |
+
# ── 寫入 initialized.flag 到 Dataset ────────────────────────────────
|
| 188 |
+
# 無論是否找到備份,只要走到這裡就說明應當完成初始化流程,寫入標記
|
| 189 |
+
import io
|
| 190 |
+
flag_content = f"initialized at container startup\n".encode()
|
| 191 |
+
api.upload_file(
|
| 192 |
+
path_or_fileobj=io.BytesIO(flag_content),
|
| 193 |
+
path_in_repo=INIT_FLAG,
|
| 194 |
+
repo_id=repo_id,
|
| 195 |
+
repo_type="dataset",
|
| 196 |
+
token=token,
|
| 197 |
+
commit_message="Set initialized.flag",
|
| 198 |
+
)
|
| 199 |
+
print(f"initialized.flag written to Dataset.")
|
| 200 |
+
|
| 201 |
except Exception as e:
|
| 202 |
print(f"Restore Error: {e}")
|
| 203 |
|
| 204 |
|
|
|
|
| 205 |
# ── backup() ──────────────────────────────────────────────────────────────────
|
| 206 |
|
| 207 |
def backup():
|
|
|
|
| 299 |
set -e
|
| 300 |
|
| 301 |
# ── restore() 觸發條件判斷 ──────────────────────────────────────────────────
|
| 302 |
+
# 判定邏輯已移入 sync.py restore() 函數內部(方案 B):
|
| 303 |
+
# - Dataset 中無 initialized.flag → 首次部署 → 執行 restore,完成後寫入標記
|
| 304 |
+
# - Dataset 中有 initialized.flag → 普通 restart → 跳過 restore
|
| 305 |
+
# - FORCE_RESTORE=true → 強制執行 restore(用於 factory rebuild)
|
| 306 |
+
# 此處直接調用,觸發與否由 restore() 自行決定。
|
| 307 |
+
python3 /usr/local/bin/sync.py restore
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
|
| 309 |
mkdir -p /root/.openclaw/sessions
|
| 310 |
|