From c4561cd69a0b470d7fcffbd3e4e4216ad5f9a457 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 18 Jul 2026 17:15:25 +0800 Subject: [PATCH] chore(host188): normalize immutable overlay payload --- .../services/awooop_ansible_post_verifier.py | 6 +-- ...claw_callback_forwarder_ansible_catalog.py | 4 +- ...callback_overlay_post_verifier_contract.py | 4 +- .../app/bot/telegram.py | 46 +++++++++---------- .../manifest.json | 4 +- .../188-openclaw-callback-forwarder.yml | 4 +- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/apps/api/src/services/awooop_ansible_post_verifier.py b/apps/api/src/services/awooop_ansible_post_verifier.py index cd2d3b9fd..5dcbdc597 100644 --- a/apps/api/src/services/awooop_ansible_post_verifier.py +++ b/apps/api/src/services/awooop_ansible_post_verifier.py @@ -263,7 +263,7 @@ _POSTCONDITION_REGISTRY: dict[str, tuple[AssetPostcondition, ...]] = { "test -f \"$manifest\" && test ! -L \"$manifest\" && " "test \"$(stat -c '%U:%G:%a' \"$manifest\")\" = 'ollama:ollama:444' && " "test \"$(sha256sum \"$manifest\" | cut -d' ' -f1)\" = " - "0e5edaf700d264b44cc0eae3b9429af642be0b1563a0bffa633942d30d2c2e1c", + "0265a2c4c9b62aa571eefd56454896adf660edf5a03931bc19fac5e5d60e846e", ), AssetPostcondition( "host_188_openclaw_callback_overlay_enabled", @@ -294,7 +294,7 @@ _POSTCONDITION_REGISTRY: dict[str, tuple[AssetPostcondition, ...]] = { "test -f \"$telegram\" && test ! -L \"$telegram\" && " "test \"$(stat -c '%U:%G:%a' \"$telegram\")\" = 'ollama:ollama:444' && " "test \"$(sha256sum \"$telegram\" | cut -d' ' -f1)\" = " - "af9600f32305ae73184651a8d3437063d7c8d35e3c3eb0910a2e27ac874c9302 && " + "c53bdce72634a581538d2af087eb920fa16fd7ee464a0dc5f3cb24ec3605a287 && " "test -f \"$config\" && test ! -L \"$config\" && " "test \"$(stat -c '%U:%G:%a' \"$config\")\" = 'ollama:ollama:444' && " "test \"$(sha256sum \"$config\" | cut -d' ' -f1)\" = " @@ -317,7 +317,7 @@ _POSTCONDITION_REGISTRY: dict[str, tuple[AssetPostcondition, ...]] = { "= '/app' && " "test \"$(docker exec \"$ids\" sha256sum " "/app/app/bot/telegram.py | cut -d' ' -f1)\" = " - "af9600f32305ae73184651a8d3437063d7c8d35e3c3eb0910a2e27ac874c9302 && " + "c53bdce72634a581538d2af087eb920fa16fd7ee464a0dc5f3cb24ec3605a287 && " "test \"$(docker exec \"$ids\" sha256sum " "/app/app/core/config.py | cut -d' ' -f1)\" = " "e1b8b633f7b4780d3078d6c42a55e49d200255d3597a34e0cd2fd649b84eaea1 && " diff --git a/apps/api/tests/test_host188_openclaw_callback_forwarder_ansible_catalog.py b/apps/api/tests/test_host188_openclaw_callback_forwarder_ansible_catalog.py index 53a02561a..27a3682cf 100644 --- a/apps/api/tests/test_host188_openclaw_callback_forwarder_ansible_catalog.py +++ b/apps/api/tests/test_host188_openclaw_callback_forwarder_ansible_catalog.py @@ -34,7 +34,7 @@ CANONICAL_ASSET_ID = "service:openclaw:host188" EXPECTED_SHA = "8f367f8e7d6104c44b29bd5fa2d894db09ddf365" UPSTREAM_SOURCE_COMMIT = "ffc45311b6403b30cb6ae6e1aa83dae1a047e9c9" EXPECTED_MANIFEST_SHA256 = ( - "0e5edaf700d264b44cc0eae3b9429af642be0b1563a0bffa633942d30d2c2e1c" + "0265a2c4c9b62aa571eefd56454896adf660edf5a03931bc19fac5e5d60e846e" ) EXPECTED_OVERRIDE_SHA256 = ( "33c4594d4e4092b2a2367583a67f4c9a82ead0d28ca5078eca4896276084da0d" @@ -49,7 +49,7 @@ PAYLOAD_ROOT = ( ) EXPECTED_PAYLOAD_SHA256 = { "app/bot/telegram.py": ( - "af9600f32305ae73184651a8d3437063d7c8d35e3c3eb0910a2e27ac874c9302" + "c53bdce72634a581538d2af087eb920fa16fd7ee464a0dc5f3cb24ec3605a287" ), "app/core/config.py": ( "e1b8b633f7b4780d3078d6c42a55e49d200255d3597a34e0cd2fd649b84eaea1" diff --git a/apps/api/tests/test_host188_openclaw_callback_overlay_post_verifier_contract.py b/apps/api/tests/test_host188_openclaw_callback_overlay_post_verifier_contract.py index 9d9064ba7..6a4b02db0 100644 --- a/apps/api/tests/test_host188_openclaw_callback_overlay_post_verifier_contract.py +++ b/apps/api/tests/test_host188_openclaw_callback_overlay_post_verifier_contract.py @@ -13,7 +13,7 @@ from src.services.awooop_ansible_post_verifier import ( CATALOG_ID = "ansible:188-openclaw-callback-forwarder" EXPECTED_PAYLOAD_SHA256 = { - "af9600f32305ae73184651a8d3437063d7c8d35e3c3eb0910a2e27ac874c9302", + "c53bdce72634a581538d2af087eb920fa16fd7ee464a0dc5f3cb24ec3605a287", "e1b8b633f7b4780d3078d6c42a55e49d200255d3597a34e0cd2fd649b84eaea1", "8e8e0faf6322abb21d670ad9094f1805d7a4b3643da8fe88d74a8c9591066bf3", } @@ -74,7 +74,7 @@ def test_host188_overlay_probes_are_exact_and_secret_blind() -> None: assert "ollama:ollama:755" in joined assert "receipts/current-deployment.json" in joined assert "/run/awoooi/openclaw-callback-forwarder/current-deployment.json" in joined - assert "0e5edaf700d264b44cc0eae3b9429af642be0b1563a0bffa633942d30d2c2e1c" in joined + assert "0265a2c4c9b62aa571eefd56454896adf660edf5a03931bc19fac5e5d60e846e" in joined assert "33c4594d4e4092b2a2367583a67f4c9a82ead0d28ca5078eca4896276084da0d" in joined assert "docker-compose.override.yml" in joined assert "COMPOSE_FILE" not in joined diff --git a/infra/ansible/files/openclaw-callback-forwarder/8f367f8e7d6104c44b29bd5fa2d894db09ddf365/app/bot/telegram.py b/infra/ansible/files/openclaw-callback-forwarder/8f367f8e7d6104c44b29bd5fa2d894db09ddf365/app/bot/telegram.py index f9426b4b0..2e79b6faf 100644 --- a/infra/ansible/files/openclaw-callback-forwarder/8f367f8e7d6104c44b29bd5fa2d894db09ddf365/app/bot/telegram.py +++ b/infra/ansible/files/openclaw-callback-forwarder/8f367f8e7d6104c44b29bd5fa2d894db09ddf365/app/bot/telegram.py @@ -379,46 +379,46 @@ class TelegramBot: """處理 /users 命令 - 查看所有用戶 (僅 SUPERADMIN)""" user = update.effective_user role = get_user_role(user.id) - + if role != UserRole.SUPERADMIN: await update.message.reply_text("⛔ 此命令僅限超級管理員使用") return - + users = get_all_users() if not users: await update.message.reply_text("📭 尚無用戶記錄") return - + users.sort(key=lambda x: x.get("last_seen", ""), reverse=True) - + msg = f"👥 *已知用戶列表* ({len(users)} 人)\n\n" - + for u in users[:20]: uid = u.get("user_id") uname = u.get("username", "-") fname = u.get("first_name", "-") count = u.get("interaction_count", 0) last_seen = u.get("last_seen", "-")[:10] - + urole = get_user_role(uid) status = "✅" if urole != UserRole.UNKNOWN else "❌" - + msg += f"{status} `{uid}` @{uname}\n" msg += f" 名稱: {fname} | 互動: {count}次\n" msg += f" 最後活動: {last_seen}\n\n" - + if len(users) > 20: msg += f"... 還有 {len(users) - 20} 個用戶" - + await update.message.reply_text(msg, parse_mode="Markdown") async def _cmd_adduser(self, update: Update, context: ContextTypes.DEFAULT_TYPE): """添加授權用戶: /adduser """ user = update.effective_user - + # 追蹤用戶 track_user(user.id, user.username, user.first_name, update.effective_chat.id) - + if len(context.args) < 2: await update.message.reply_text( "⚠️ *用法:* /adduser \n\n" @@ -431,25 +431,25 @@ class TelegramBot: parse_mode="Markdown" ) return - + try: target_id = int(context.args[0]) except ValueError: await update.message.reply_text("❌ 無效的用戶 ID") return - + role = context.args[1].lower() success, message = add_auth_user(target_id, role, user.id) - + await update.message.reply_text(message) async def _cmd_removeuser(self, update: Update, context: ContextTypes.DEFAULT_TYPE): """移除授權用戶: /removeuser """ user = update.effective_user - + # 追蹤用戶 track_user(user.id, user.username, user.first_name, update.effective_chat.id) - + if len(context.args) < 1: await update.message.reply_text( "⚠️ *用法:* /removeuser \n\n" @@ -458,29 +458,29 @@ class TelegramBot: parse_mode="Markdown" ) return - + try: target_id = int(context.args[0]) except ValueError: await update.message.reply_text("❌ 無效的用戶 ID") return - + success, message = remove_auth_user(target_id, user.id) - + await update.message.reply_text(message) async def _cmd_authlist(self, update: Update, context: ContextTypes.DEFAULT_TYPE): """列出所有授權用戶""" user = update.effective_user role = get_user_role(user.id) - + # 追蹤用戶 track_user(user.id, user.username, user.first_name, update.effective_chat.id) - + if role != UserRole.SUPERADMIN: await update.message.reply_text("⛔ 此命令僅限超級管理員使用") return - + msg = list_users() await update.message.reply_text(msg, parse_mode="Markdown") @@ -1120,7 +1120,7 @@ class TelegramBot: data = query.data logger.info(f"[DEBUG] Callback data received: {data}") - + # === 處理修復按鈕回調 === if data.startswith("repair:"): logger.info(f"[DEBUG] Routing to _handle_repair_callback") diff --git a/infra/ansible/files/openclaw-callback-forwarder/8f367f8e7d6104c44b29bd5fa2d894db09ddf365/manifest.json b/infra/ansible/files/openclaw-callback-forwarder/8f367f8e7d6104c44b29bd5fa2d894db09ddf365/manifest.json index ce6c36430..75017f693 100644 --- a/infra/ansible/files/openclaw-callback-forwarder/8f367f8e7d6104c44b29bd5fa2d894db09ddf365/manifest.json +++ b/infra/ansible/files/openclaw-callback-forwarder/8f367f8e7d6104c44b29bd5fa2d894db09ddf365/manifest.json @@ -12,8 +12,8 @@ "payloads": [ { "path": "app/bot/telegram.py", - "git_blob": "f9426b4b0ee3b685bbb155d7045c75b94a6bf0eb", - "sha256": "af9600f32305ae73184651a8d3437063d7c8d35e3c3eb0910a2e27ac874c9302" + "git_blob": "2e79b6faff04262b04508fa0a181dd27ea3e6494", + "sha256": "c53bdce72634a581538d2af087eb920fa16fd7ee464a0dc5f3cb24ec3605a287" }, { "path": "app/core/config.py", diff --git a/infra/ansible/playbooks/188-openclaw-callback-forwarder.yml b/infra/ansible/playbooks/188-openclaw-callback-forwarder.yml index 07c32fb50..bc49932c7 100644 --- a/infra/ansible/playbooks/188-openclaw-callback-forwarder.yml +++ b/infra/ansible/playbooks/188-openclaw-callback-forwarder.yml @@ -17,7 +17,7 @@ catalog_id: ansible:188-openclaw-callback-forwarder canonical_asset_id: service:openclaw:host188 expected_source_sha: 8f367f8e7d6104c44b29bd5fa2d894db09ddf365 - expected_manifest_sha256: 0e5edaf700d264b44cc0eae3b9429af642be0b1563a0bffa633942d30d2c2e1c + expected_manifest_sha256: 0265a2c4c9b62aa571eefd56454896adf660edf5a03931bc19fac5e5d60e846e allowed_working_directories: - /home/ollama/clawbot-v5 compose_project: clawbot @@ -48,7 +48,7 @@ overlay_path: "{{ payload_root }}/app/bot/telegram.py" container_path: /app/app/bot/telegram.py baseline_sha256: 238c1c4499f45f7aee9f455b90afcf3842effda80c186d9e2d4a563a72a366f3 - target_sha256: af9600f32305ae73184651a8d3437063d7c8d35e3c3eb0910a2e27ac874c9302 + target_sha256: c53bdce72634a581538d2af087eb920fa16fd7ee464a0dc5f3cb24ec3605a287 - relative_path: app/core/config.py source_path: "{{ payload_source_root }}/app/core/config.py" runtime_path: "{{ openclaw_workdir }}/app/core/config.py"