fix(sre): remove Host188 callback sudo dependency
This commit is contained in:
@@ -692,7 +692,7 @@ _CATALOG: tuple[dict[str, Any], ...] = (
|
||||
"approval_required": False,
|
||||
"risk_level": "medium",
|
||||
"canonical_asset_id": "service:openclaw:host188",
|
||||
"catalog_revision": "2026-07-17-openclaw-callback-overlay-v2",
|
||||
"catalog_revision": "2026-07-17-openclaw-callback-user-overlay-v3",
|
||||
"cross_domain_fallback_allowed": False,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -249,63 +249,53 @@ _POSTCONDITION_REGISTRY: dict[str, tuple[AssetPostcondition, ...]] = {
|
||||
"configuration",
|
||||
"host_188",
|
||||
"set -euo pipefail; "
|
||||
"root=/var/lib/awoooi-controlled-apply/openclaw-callback-forwarder/"
|
||||
"root=/home/ollama/.local/share/awoooi-controlled-apply/"
|
||||
"openclaw-callback-forwarder/"
|
||||
"payloads/ffc45311b6403b30cb6ae6e1aa83dae1a047e9c9 && "
|
||||
"manifest=\"$root/manifest.json\" && "
|
||||
"test -d \"$root\" && test ! -L \"$root\" && "
|
||||
"test \"$(stat -c '%u:%g:%a' \"$root\")\" = '0:0:755' && "
|
||||
"test \"$(stat -c '%U:%G:%a' \"$root\")\" = 'ollama:ollama:755' && "
|
||||
"test -f \"$manifest\" && test ! -L \"$manifest\" && "
|
||||
"test \"$(stat -c '%u:%g:%a' \"$manifest\")\" = '0:0:444' && "
|
||||
"test \"$(stat -c '%U:%G:%a' \"$manifest\")\" = 'ollama:ollama:444' && "
|
||||
"test \"$(sha256sum \"$manifest\" | cut -d' ' -f1)\" = "
|
||||
"f06df6f3163e5ae7bf999624b011a3ae0bff096c9d0c8cb4c43f8b40be43ae2b",
|
||||
"dafeb467b744ee7e80dc043d51f9e5d7e6905a58103f1710d519b553b56c6e48",
|
||||
),
|
||||
AssetPostcondition(
|
||||
"host_188_openclaw_callback_overlay_enabled",
|
||||
"configuration",
|
||||
"host_188",
|
||||
"set -euo pipefail; "
|
||||
"drop=/etc/systemd/system/clawbot.service.d/"
|
||||
"20-awoooi-callback-forwarder.conf && "
|
||||
"override=/etc/awoooi/openclaw-callback-forwarder/"
|
||||
"docker-compose.callback.yml && "
|
||||
"COMPOSE_FILE_key=COMPOSE_FILE && "
|
||||
"test \"$COMPOSE_FILE_key\" = 'COMPOSE_FILE' && "
|
||||
"wd=$(systemctl show clawbot.service --property=WorkingDirectory "
|
||||
"--value) && "
|
||||
"test -f \"$drop\" && test ! -L \"$drop\" && "
|
||||
"test \"$(stat -c '%u:%g:%a' \"$drop\")\" = '0:0:644' && "
|
||||
"drop_sha=$(sha256sum \"$drop\" | cut -d' ' -f1) && "
|
||||
"case \"$wd:$drop_sha\" in "
|
||||
"'/home/ollama/clawbot-v5:"
|
||||
"419fb4f249f7e1370fbca87086fd725e57b1f5cf54da2f84caf9a21fea7111e3'"
|
||||
"|'/opt/openclaw:"
|
||||
"4a78d414e4b591f54232fab04529861a6042718a7627c4e17ccd5cc0cbd485f9') "
|
||||
"true ;; *) false ;; esac && "
|
||||
"test \"$wd\" = '/home/ollama/clawbot-v5' && "
|
||||
"override=\"$wd/docker-compose.override.yml\" && "
|
||||
"test -f \"$override\" && test ! -L \"$override\" && "
|
||||
"test \"$(stat -c '%u:%g:%a' \"$override\")\" = '0:0:444' && "
|
||||
"test \"$(stat -c '%U:%G:%a' \"$override\")\" = "
|
||||
"'ollama:ollama:444' && "
|
||||
"test \"$(sha256sum \"$override\" | cut -d' ' -f1)\" = "
|
||||
"f6fa7f6724c35f86f1c8dafac07e2680231dfa29a5d45534ed0515c58ac2de77",
|
||||
"8f6b7e8a0d6746c1331e99910656e64deebf67c9582bab3e1d36f71bb7a253c0",
|
||||
),
|
||||
AssetPostcondition(
|
||||
"host_188_openclaw_callback_payload_runtime",
|
||||
"configuration",
|
||||
"host_188",
|
||||
"set -euo pipefail; "
|
||||
"root=/var/lib/awoooi-controlled-apply/openclaw-callback-forwarder/"
|
||||
"root=/home/ollama/.local/share/awoooi-controlled-apply/"
|
||||
"openclaw-callback-forwarder/"
|
||||
"payloads/ffc45311b6403b30cb6ae6e1aa83dae1a047e9c9 && "
|
||||
"telegram=\"$root/app/bot/telegram.py\" && "
|
||||
"config=\"$root/app/core/config.py\" && "
|
||||
"forwarder=\"$root/app/services/telegram_callback_forwarder.py\" && "
|
||||
"test -f \"$telegram\" && test ! -L \"$telegram\" && "
|
||||
"test \"$(stat -c '%u:%g:%a' \"$telegram\")\" = '0:0:444' && "
|
||||
"test \"$(stat -c '%U:%G:%a' \"$telegram\")\" = 'ollama:ollama:444' && "
|
||||
"test \"$(sha256sum \"$telegram\" | cut -d' ' -f1)\" = "
|
||||
"af9600f32305ae73184651a8d3437063d7c8d35e3c3eb0910a2e27ac874c9302 && "
|
||||
"test -f \"$config\" && test ! -L \"$config\" && "
|
||||
"test \"$(stat -c '%u:%g:%a' \"$config\")\" = '0:0:444' && "
|
||||
"test \"$(stat -c '%U:%G:%a' \"$config\")\" = 'ollama:ollama:444' && "
|
||||
"test \"$(sha256sum \"$config\" | cut -d' ' -f1)\" = "
|
||||
"e1b8b633f7b4780d3078d6c42a55e49d200255d3597a34e0cd2fd649b84eaea1 && "
|
||||
"test -f \"$forwarder\" && test ! -L \"$forwarder\" && "
|
||||
"test \"$(stat -c '%u:%g:%a' \"$forwarder\")\" = '0:0:444' && "
|
||||
"test \"$(stat -c '%U:%G:%a' \"$forwarder\")\" = 'ollama:ollama:444' && "
|
||||
"test \"$(sha256sum \"$forwarder\" | cut -d' ' -f1)\" = "
|
||||
"0d7693e34f63db4491d974f9f76a3a1c793d32cda193cb55ed3d8c86297b4fe3 && "
|
||||
"ids=$(docker ps -q "
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
@@ -31,6 +32,12 @@ MONITORING_REGISTRY = ROOT / "ops" / "monitoring" / "service-registry.yaml"
|
||||
CATALOG_ID = "ansible:188-openclaw-callback-forwarder"
|
||||
CANONICAL_ASSET_ID = "service:openclaw:host188"
|
||||
EXPECTED_SHA = "ffc45311b6403b30cb6ae6e1aa83dae1a047e9c9"
|
||||
EXPECTED_MANIFEST_SHA256 = (
|
||||
"dafeb467b744ee7e80dc043d51f9e5d7e6905a58103f1710d519b553b56c6e48"
|
||||
)
|
||||
EXPECTED_OVERRIDE_SHA256 = (
|
||||
"8f6b7e8a0d6746c1331e99910656e64deebf67c9582bab3e1d36f71bb7a253c0"
|
||||
)
|
||||
PAYLOAD_ROOT = (
|
||||
ROOT
|
||||
/ "infra"
|
||||
@@ -201,7 +208,7 @@ def test_openclaw_catalog_and_independent_verifier_are_exact() -> None:
|
||||
"host_188",
|
||||
]
|
||||
assert catalog["catalog_revision"] == (
|
||||
"2026-07-17-openclaw-callback-overlay-v2"
|
||||
"2026-07-17-openclaw-callback-user-overlay-v3"
|
||||
)
|
||||
assert catalog["cross_domain_fallback_allowed"] is False
|
||||
|
||||
@@ -217,7 +224,8 @@ def test_openclaw_catalog_and_independent_verifier_are_exact() -> None:
|
||||
assert {condition.inventory_host for condition in conditions} == {"host_188"}
|
||||
probes = "\n".join(condition.probe for condition in conditions)
|
||||
assert EXPECTED_SHA in probes
|
||||
assert "COMPOSE_FILE" in probes
|
||||
assert "docker-compose.override.yml" in probes
|
||||
assert "COMPOSE_FILE" not in probes
|
||||
assert "TELEGRAM_CALLBACK_FORWARD_ENABLED is True" in probes
|
||||
assert all(digest in probes for digest in EXPECTED_PAYLOAD_SHA256.values())
|
||||
assert "http://127.0.0.1:8088/health" in probes
|
||||
@@ -234,15 +242,15 @@ def test_openclaw_playbook_is_check_first_bounded_and_rollback_capable() -> None
|
||||
|
||||
assert play["hosts"] == "host_188"
|
||||
assert play["gather_facts"] is False
|
||||
assert play["become"] is True
|
||||
assert play["become"] is False
|
||||
assert play["vars"]["catalog_id"] == CATALOG_ID
|
||||
assert play["vars"]["canonical_asset_id"] == CANONICAL_ASSET_ID
|
||||
assert play["vars"]["expected_source_sha"] == EXPECTED_SHA
|
||||
assert play["vars"]["allowed_working_directories"] == [
|
||||
"/opt/openclaw",
|
||||
"/home/ollama/clawbot-v5",
|
||||
]
|
||||
assert len(play["vars"]["payloads"]) == 3
|
||||
assert play["vars"]["expected_manifest_sha256"] == EXPECTED_MANIFEST_SHA256
|
||||
assert {
|
||||
item["relative_path"]: item["target_sha256"]
|
||||
for item in play["vars"]["payloads"]
|
||||
@@ -298,23 +306,44 @@ def test_openclaw_playbook_is_check_first_bounded_and_rollback_capable() -> None
|
||||
assert check_receipt["ansible.builtin.debug"]["msg"][
|
||||
"runtime_source_mutation_allowed"
|
||||
] is False
|
||||
assert check_receipt["ansible.builtin.debug"]["msg"][
|
||||
"runtime_compose_override_write_allowed"
|
||||
] is True
|
||||
assert check_receipt["ansible.builtin.debug"]["msg"][
|
||||
"host_privilege_escalation_required"
|
||||
] is False
|
||||
assert check_receipt["ansible.builtin.debug"]["msg"][
|
||||
"image_build_allowed"
|
||||
] is False
|
||||
|
||||
for name in (
|
||||
"Reload systemd and restart the existing owned service once",
|
||||
"Reload systemd and restore the previous container definition",
|
||||
"Activate the existing Compose project without build or pull",
|
||||
"Restore the previous Compose definition without build or pull",
|
||||
):
|
||||
assert tasks[name]["ansible.builtin.systemd"] == {
|
||||
"name": "clawbot.service",
|
||||
"state": "restarted",
|
||||
"daemon_reload": True,
|
||||
}
|
||||
assert tasks[name]["ansible.builtin.command"]["argv"] == [
|
||||
"/usr/bin/docker",
|
||||
"compose",
|
||||
"up",
|
||||
"-d",
|
||||
"--no-build",
|
||||
"--pull",
|
||||
"never",
|
||||
]
|
||||
assert tasks[name]["args"]["chdir"] == "{{ openclaw_workdir }}"
|
||||
assert tasks[name]["no_log"] is True
|
||||
assert tasks["Install COMPOSE_FILE-only systemd drop-in"][
|
||||
"ansible.builtin.copy"
|
||||
]["content"] == "{{ callback_dropin_content }}"
|
||||
assert "Install COMPOSE_FILE-only systemd drop-in" not in tasks
|
||||
rendered_override = tasks["Define exact non-secret managed overlay documents"][
|
||||
"ansible.builtin.set_fact"
|
||||
]["compose_override_content"].replace(
|
||||
"{{ payload_root }}",
|
||||
(
|
||||
"/home/ollama/.local/share/awoooi-controlled-apply/"
|
||||
f"openclaw-callback-forwarder/payloads/{EXPECTED_SHA}"
|
||||
),
|
||||
)
|
||||
assert hashlib.sha256(rendered_override.encode()).hexdigest() == (
|
||||
EXPECTED_OVERRIDE_SHA256
|
||||
)
|
||||
correlation = tasks["Require same-run controlled execution correlation"][
|
||||
"ansible.builtin.assert"
|
||||
]["that"]
|
||||
@@ -333,7 +362,7 @@ def test_openclaw_playbook_is_check_first_bounded_and_rollback_capable() -> None
|
||||
assert "target_mounts_rollback == target_mounts_before" in tasks[
|
||||
"Require bounded rollback verification"
|
||||
]["ansible.builtin.assert"]["that"]
|
||||
assert tasks["Reload systemd and restore the previous container definition"][
|
||||
assert tasks["Restore the previous Compose definition without build or pull"][
|
||||
"when"
|
||||
] == "activation_attempted | default(false) | bool"
|
||||
runtime_setting = tasks[
|
||||
@@ -346,7 +375,7 @@ def test_openclaw_playbook_is_check_first_bounded_and_rollback_capable() -> None
|
||||
]["that"] == [
|
||||
"clawbot_image_after.stdout | trim == clawbot_image_before"
|
||||
]
|
||||
assert "openclaw_callback_overlay_rollback_v2" in source
|
||||
assert "openclaw_callback_overlay_rollback_v3" in source
|
||||
assert "runtime_checkout_preserved" in source
|
||||
for forbidden in (
|
||||
"git remote",
|
||||
@@ -364,12 +393,18 @@ def test_openclaw_playbook_is_check_first_bounded_and_rollback_capable() -> None
|
||||
|
||||
|
||||
def test_openclaw_payload_manifest_is_hash_pinned_and_overlay_only() -> None:
|
||||
import hashlib
|
||||
|
||||
manifest = json.loads((PAYLOAD_ROOT / "manifest.json").read_text(encoding="utf-8"))
|
||||
manifest_path = PAYLOAD_ROOT / "manifest.json"
|
||||
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
|
||||
assert hashlib.sha256(manifest_path.read_bytes()).hexdigest() == (
|
||||
EXPECTED_MANIFEST_SHA256
|
||||
)
|
||||
assert manifest["source_commit"] == EXPECTED_SHA
|
||||
assert manifest["deployment_mode"] == "root_owned_read_only_overlay_no_build"
|
||||
assert manifest["deployment_mode"] == (
|
||||
"host_user_owned_read_only_compose_override_no_build_no_pull"
|
||||
)
|
||||
assert manifest["runtime_source_mutation_allowed"] is False
|
||||
assert manifest["runtime_compose_override_write_allowed"] is True
|
||||
assert manifest["host_privilege_escalation_required"] is False
|
||||
assert manifest["runtime_secret_read_allowed"] is False
|
||||
assert {row["path"]: row["sha256"] for row in manifest["payloads"]} == (
|
||||
EXPECTED_PAYLOAD_SHA256
|
||||
|
||||
@@ -69,13 +69,13 @@ def test_host188_overlay_probes_are_exact_and_secret_blind() -> None:
|
||||
assert "docker inspect --format='{{.Config.WorkingDir}}'" in joined
|
||||
assert "{{.Source}}|{{.Destination}}|{{.Type}}|{{.RW}}" in joined
|
||||
assert "|bind|false" in joined
|
||||
assert "stat -c '%u:%g:%a'" in joined
|
||||
assert "0:0:444" in joined
|
||||
assert "0:0:644" in joined
|
||||
assert "f06df6f3163e5ae7bf999624b011a3ae0bff096c9d0c8cb4c43f8b40be43ae2b" in joined
|
||||
assert "f6fa7f6724c35f86f1c8dafac07e2680231dfa29a5d45534ed0515c58ac2de77" in joined
|
||||
assert "419fb4f249f7e1370fbca87086fd725e57b1f5cf54da2f84caf9a21fea7111e3" in joined
|
||||
assert "4a78d414e4b591f54232fab04529861a6042718a7627c4e17ccd5cc0cbd485f9" in joined
|
||||
assert "stat -c '%U:%G:%a'" in joined
|
||||
assert "ollama:ollama:444" in joined
|
||||
assert "ollama:ollama:755" in joined
|
||||
assert "dafeb467b744ee7e80dc043d51f9e5d7e6905a58103f1710d519b553b56c6e48" in joined
|
||||
assert "8f6b7e8a0d6746c1331e99910656e64deebf67c9582bab3e1d36f71bb7a253c0" in joined
|
||||
assert "docker-compose.override.yml" in joined
|
||||
assert "COMPOSE_FILE" not in joined
|
||||
assert all(digest in joined for digest in EXPECTED_PAYLOAD_SHA256)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user