direxio-deployer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +92 -0
- package/LICENSE +21 -0
- package/README.md +221 -0
- package/README_zh.md +218 -0
- package/SKILL.md +722 -0
- package/agents/README.md +25 -0
- package/agents/openai.yaml +12 -0
- package/bin/direxio-deployer.mjs +375 -0
- package/package.json +28 -0
- package/references/agent-targets.md +128 -0
- package/references/architecture.md +44 -0
- package/references/bug-history.md +78 -0
- package/references/deployment-lessons.md +218 -0
- package/references/deployment-optimization-audit.md +317 -0
- package/references/deployment-workflow.md +341 -0
- package/references/iam-policy.json +52 -0
- package/references/runtime-wiring.md +209 -0
- package/references/state-machine.md +46 -0
- package/references/token-refresh.md +81 -0
- package/references/tooling.md +106 -0
- package/references/troubleshooting.md +26 -0
- package/references/user-journey.md +75 -0
- package/references/verification-recovery.md +84 -0
- package/references/voip-turn-runbook.md +154 -0
- package/references/windows-deployment-notes.md +119 -0
- package/scripts/aws-credentials.sh +195 -0
- package/scripts/cloud-init/Caddyfile +48 -0
- package/scripts/cloud-init/docker-compose.yml +125 -0
- package/scripts/cloud-init/init-tokens.sh +238 -0
- package/scripts/cloud-init/user-data.yaml +40 -0
- package/scripts/destroy.ps1 +77 -0
- package/scripts/destroy.sh +589 -0
- package/scripts/lib/aws.sh +73 -0
- package/scripts/lib/domain.sh +175 -0
- package/scripts/lib/operation_report.sh +240 -0
- package/scripts/lib/ops.sh +230 -0
- package/scripts/lib/paths.sh +35 -0
- package/scripts/lib/state.sh +137 -0
- package/scripts/mcp-tools-list.mjs +95 -0
- package/scripts/orchestrate.ps1 +112 -0
- package/scripts/orchestrate.sh +1126 -0
- package/scripts/phases/s0_prereq_aws.sh +39 -0
- package/scripts/phases/s1_preflight.sh +72 -0
- package/scripts/phases/s2_domain.sh +103 -0
- package/scripts/phases/s3_provision.sh +421 -0
- package/scripts/phases/s4_bootstrap_stack.sh +38 -0
- package/scripts/phases/s5_init_tokens.sh +118 -0
- package/scripts/phases/s6_wire_local.sh +1435 -0
- package/scripts/phases/s7_verify_e2e.sh +136 -0
- package/scripts/pricing-estimate.sh +256 -0
- package/scripts/render/render-userdata.sh +86 -0
- package/scripts/reset-app-data.sh +40 -0
- package/scripts/update.sh +30 -0
- package/tests/aws_credentials_test.sh +139 -0
- package/tests/connect_daemon_runtime_check_test.sh +120 -0
- package/tests/default_paths_test.sh +58 -0
- package/tests/destroy_local_bridge_test.sh +154 -0
- package/tests/destroy_root_identity_test.sh +91 -0
- package/tests/destroy_route53_zone_test.sh +80 -0
- package/tests/domain_authoritative_dns_test.sh +49 -0
- package/tests/mcp_doctor_runtime_check_test.sh +86 -0
- package/tests/mcp_smoke_runtime_check_test.sh +121 -0
- package/tests/mcp_tools_runtime_check_test.sh +123 -0
- package/tests/npm_skill_distribution_test.sh +95 -0
- package/tests/operation_report_test.sh +258 -0
- package/tests/orchestrate_status_recovery_test.sh +91 -0
- package/tests/phase_timeout_test.sh +88 -0
- package/tests/pricing_estimate_test.sh +159 -0
- package/tests/render_userdata_remote_nodes_test.sh +40 -0
- package/tests/root_volume_tracking_test.sh +41 -0
- package/tests/route53_overwrite_guard_test.sh +86 -0
- package/tests/route53_zone_auto_create_test.sh +66 -0
- package/tests/runtime_summary_check_test.sh +203 -0
- package/tests/s6_wire_local_test.sh +405 -0
- package/tests/skill_structure_test.sh +298 -0
- package/tests/update_reset_ops_test.sh +230 -0
- package/tests/user_confirmation_gates_test.sh +152 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT=$(cd "$(dirname "$0")/.." && pwd)
|
|
5
|
+
tmp=$(mktemp -d)
|
|
6
|
+
trap 'rm -rf "$tmp"' EXIT
|
|
7
|
+
|
|
8
|
+
export HOME="$tmp/home"
|
|
9
|
+
export P2P_WORKDIR="$tmp/work"
|
|
10
|
+
mkdir -p "$HOME" "$P2P_WORKDIR"
|
|
11
|
+
|
|
12
|
+
fakebin="$tmp/bin"
|
|
13
|
+
mkdir -p "$fakebin"
|
|
14
|
+
cat > "$fakebin/aws" <<'EOF'
|
|
15
|
+
#!/usr/bin/env bash
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
case "${1:-} ${2:-}" in
|
|
18
|
+
"ec2 describe-instances")
|
|
19
|
+
printf 'vol-root-test\n'
|
|
20
|
+
;;
|
|
21
|
+
*)
|
|
22
|
+
echo "unexpected aws command: $*" >&2
|
|
23
|
+
exit 1
|
|
24
|
+
;;
|
|
25
|
+
esac
|
|
26
|
+
EOF
|
|
27
|
+
chmod 700 "$fakebin/aws"
|
|
28
|
+
export PATH="$fakebin:$PATH"
|
|
29
|
+
|
|
30
|
+
# shellcheck disable=SC1091
|
|
31
|
+
source "$ROOT/scripts/lib/state.sh"
|
|
32
|
+
state_init >/dev/null 2>&1
|
|
33
|
+
|
|
34
|
+
# shellcheck disable=SC1091
|
|
35
|
+
source "$ROOT/scripts/phases/s3_provision.sh"
|
|
36
|
+
|
|
37
|
+
_record_root_volume_id i-root-test
|
|
38
|
+
|
|
39
|
+
jq -e '.resources.root_volume_id == "vol-root-test"' "$STATE_JSON" >/dev/null
|
|
40
|
+
|
|
41
|
+
echo "root volume tracking ok"
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT=$(cd "$(dirname "$0")/.." && pwd)
|
|
5
|
+
tmp=$(mktemp -d)
|
|
6
|
+
trap 'rm -rf "$tmp"' EXIT
|
|
7
|
+
|
|
8
|
+
export HOME="$tmp/home"
|
|
9
|
+
export P2P_WORKDIR="$tmp/work"
|
|
10
|
+
mkdir -p "$HOME" "$P2P_WORKDIR"
|
|
11
|
+
|
|
12
|
+
fakebin="$tmp/bin"
|
|
13
|
+
mkdir -p "$fakebin"
|
|
14
|
+
cat > "$fakebin/aws" <<'EOF'
|
|
15
|
+
#!/usr/bin/env bash
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
printf 'aws' >> "$CALLS"
|
|
18
|
+
printf ' %q' "$@" >> "$CALLS"
|
|
19
|
+
printf '\n' >> "$CALLS"
|
|
20
|
+
|
|
21
|
+
case "${1:-} ${2:-}" in
|
|
22
|
+
"route53 list-hosted-zones")
|
|
23
|
+
printf '{"HostedZones":[{"Id":"/hostedzone/ZEXISTING","Name":"overwrite.example.test."}]}\n'
|
|
24
|
+
;;
|
|
25
|
+
"route53 list-resource-record-sets")
|
|
26
|
+
printf '{"ResourceRecordSets":[{"Name":"overwrite.example.test.","Type":"A","TTL":60,"ResourceRecords":[{"Value":"198.51.100.10"}]}]}\n'
|
|
27
|
+
;;
|
|
28
|
+
"route53 change-resource-record-sets")
|
|
29
|
+
printf '{"ChangeInfo":{"Id":"/change/C123","Status":"PENDING"}}\n'
|
|
30
|
+
;;
|
|
31
|
+
"route53 wait")
|
|
32
|
+
exit 0
|
|
33
|
+
;;
|
|
34
|
+
*)
|
|
35
|
+
echo "unexpected aws command: $*" >&2
|
|
36
|
+
exit 1
|
|
37
|
+
;;
|
|
38
|
+
esac
|
|
39
|
+
EOF
|
|
40
|
+
chmod 700 "$fakebin/aws"
|
|
41
|
+
export PATH="$fakebin:$PATH"
|
|
42
|
+
|
|
43
|
+
# shellcheck disable=SC1091
|
|
44
|
+
source "$ROOT/scripts/lib/state.sh"
|
|
45
|
+
state_init >/dev/null 2>&1
|
|
46
|
+
state_set run_id route53-overwrite-test
|
|
47
|
+
state_set domain overwrite.example.test
|
|
48
|
+
state_set domain_mode route53
|
|
49
|
+
|
|
50
|
+
# shellcheck disable=SC1091
|
|
51
|
+
source "$ROOT/scripts/phases/s3_provision.sh"
|
|
52
|
+
|
|
53
|
+
CALLS="$tmp/blocked.calls"
|
|
54
|
+
export CALLS
|
|
55
|
+
set +e
|
|
56
|
+
_upsert_route53_record overwrite.example.test 203.0.113.88 > "$tmp/blocked.out" 2>&1
|
|
57
|
+
blocked_rc=$?
|
|
58
|
+
set -e
|
|
59
|
+
[ "$blocked_rc" -eq 2 ] || {
|
|
60
|
+
echo "Route53 overwrite without confirmation should return waiting_user rc=2" >&2
|
|
61
|
+
cat "$tmp/blocked.out" >&2
|
|
62
|
+
exit 1
|
|
63
|
+
}
|
|
64
|
+
grep -q 'Route53 A record overwrite requires confirmation' "$tmp/blocked.out"
|
|
65
|
+
if grep -q 'route53 change-resource-record-sets' "$CALLS"; then
|
|
66
|
+
echo "Route53 overwrite without confirmation must not change records" >&2
|
|
67
|
+
cat "$CALLS" >&2
|
|
68
|
+
exit 1
|
|
69
|
+
fi
|
|
70
|
+
jq -e '
|
|
71
|
+
.phases.S3_PROVISION.status == "waiting_user"
|
|
72
|
+
and .resources.route53_existing_a_value == "198.51.100.10"
|
|
73
|
+
and .resources.route53_pending_a_value == "203.0.113.88"
|
|
74
|
+
' "$STATE_JSON" >/dev/null
|
|
75
|
+
|
|
76
|
+
CALLS="$tmp/confirmed.calls"
|
|
77
|
+
export CALLS
|
|
78
|
+
DIREXIO_CONFIRM_DNS_OVERWRITE=1 _upsert_route53_record overwrite.example.test 203.0.113.88
|
|
79
|
+
grep -q 'route53 change-resource-record-sets' "$CALLS"
|
|
80
|
+
jq -e '
|
|
81
|
+
.resources.route53_existing_a_value == "198.51.100.10"
|
|
82
|
+
and .resources.route53_pending_a_value == "203.0.113.88"
|
|
83
|
+
and .resources.route53_overwrite_confirmed == "true"
|
|
84
|
+
' "$STATE_JSON" >/dev/null
|
|
85
|
+
|
|
86
|
+
echo "route53 overwrite guard ok"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT=$(cd "$(dirname "$0")/.." && pwd)
|
|
5
|
+
tmp=$(mktemp -d)
|
|
6
|
+
trap 'rm -rf "$tmp"' EXIT
|
|
7
|
+
|
|
8
|
+
export HOME="$tmp/home"
|
|
9
|
+
export P2P_WORKDIR="$tmp/work"
|
|
10
|
+
mkdir -p "$HOME" "$P2P_WORKDIR"
|
|
11
|
+
|
|
12
|
+
fakebin="$tmp/bin"
|
|
13
|
+
mkdir -p "$fakebin"
|
|
14
|
+
cat > "$fakebin/aws" <<'EOF'
|
|
15
|
+
#!/usr/bin/env bash
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
printf 'aws' >> "$CALLS"
|
|
18
|
+
printf ' %q' "$@" >> "$CALLS"
|
|
19
|
+
printf '\n' >> "$CALLS"
|
|
20
|
+
|
|
21
|
+
case "${1:-} ${2:-}" in
|
|
22
|
+
"route53 list-hosted-zones")
|
|
23
|
+
printf '{"HostedZones":[]}\n'
|
|
24
|
+
;;
|
|
25
|
+
"route53 create-hosted-zone")
|
|
26
|
+
printf '{"HostedZone":{"Id":"/hostedzone/ZCREATE","Name":"auto-zone.example.test."},"DelegationSet":{"NameServers":["ns-1.awsdns.test","ns-2.awsdns.test"]}}\n'
|
|
27
|
+
;;
|
|
28
|
+
"route53 change-resource-record-sets")
|
|
29
|
+
printf '{"ChangeInfo":{"Id":"/change/C123","Status":"PENDING"}}\n'
|
|
30
|
+
;;
|
|
31
|
+
"route53 wait")
|
|
32
|
+
exit 0
|
|
33
|
+
;;
|
|
34
|
+
*)
|
|
35
|
+
echo "unexpected aws command: $*" >&2
|
|
36
|
+
exit 1
|
|
37
|
+
;;
|
|
38
|
+
esac
|
|
39
|
+
EOF
|
|
40
|
+
chmod 700 "$fakebin/aws"
|
|
41
|
+
export CALLS="$tmp/aws.calls"
|
|
42
|
+
export PATH="$fakebin:$PATH"
|
|
43
|
+
|
|
44
|
+
# shellcheck disable=SC1091
|
|
45
|
+
source "$ROOT/scripts/lib/state.sh"
|
|
46
|
+
state_init >/dev/null 2>&1
|
|
47
|
+
state_set run_id route53-test
|
|
48
|
+
state_set domain auto-zone.example.test
|
|
49
|
+
state_set domain_mode route53
|
|
50
|
+
|
|
51
|
+
# shellcheck disable=SC1091
|
|
52
|
+
source "$ROOT/scripts/phases/s3_provision.sh"
|
|
53
|
+
|
|
54
|
+
_upsert_route53_record auto-zone.example.test 203.0.113.88
|
|
55
|
+
|
|
56
|
+
jq -e '
|
|
57
|
+
.resources.route53_zone_id == "ZCREATE"
|
|
58
|
+
and .resources.route53_zone_name == "auto-zone.example.test"
|
|
59
|
+
and .resources.route53_zone_created_by_deployer == "true"
|
|
60
|
+
and (.resources.route53_name_servers | contains("ns-1.awsdns.test"))
|
|
61
|
+
' "$STATE_JSON" >/dev/null
|
|
62
|
+
|
|
63
|
+
grep -q 'route53 create-hosted-zone' "$CALLS"
|
|
64
|
+
grep -q 'route53 change-resource-record-sets' "$CALLS"
|
|
65
|
+
|
|
66
|
+
echo "route53 zone auto create ok"
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT=$(cd "$(dirname "$0")/.." && pwd)
|
|
5
|
+
tmp=$(mktemp -d "$ROOT/.tmp-runtime-summary.XXXXXX")
|
|
6
|
+
trap 'rm -rf "$tmp"' EXIT
|
|
7
|
+
|
|
8
|
+
export HOME="$tmp/home"
|
|
9
|
+
mkdir -p "$HOME"
|
|
10
|
+
|
|
11
|
+
fakebin="$tmp/bin"
|
|
12
|
+
mkdir -p "$fakebin"
|
|
13
|
+
|
|
14
|
+
windows_path() {
|
|
15
|
+
local path=$1 drive rest
|
|
16
|
+
case "$path" in
|
|
17
|
+
/mnt/[A-Za-z]/*)
|
|
18
|
+
drive=${path#/mnt/}
|
|
19
|
+
drive=${drive%%/*}
|
|
20
|
+
rest=${path#/mnt/$drive/}
|
|
21
|
+
printf '%s:\\%s\n' "$(printf '%s' "$drive" | tr '[:lower:]' '[:upper:]')" "$(printf '%s' "$rest" | sed 's#/#\\#g')"
|
|
22
|
+
;;
|
|
23
|
+
/[A-Za-z]/*)
|
|
24
|
+
drive=${path#/}
|
|
25
|
+
drive=${drive%%/*}
|
|
26
|
+
rest=${path#/$drive/}
|
|
27
|
+
printf '%s:\\%s\n' "$(printf '%s' "$drive" | tr '[:lower:]' '[:upper:]')" "$(printf '%s' "$rest" | sed 's#/#\\#g')"
|
|
28
|
+
;;
|
|
29
|
+
*) printf '%s\n' "$path" ;;
|
|
30
|
+
esac
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
cat > "$fakebin/direxio-connect" <<'EOF'
|
|
34
|
+
#!/usr/bin/env bash
|
|
35
|
+
set -euo pipefail
|
|
36
|
+
[ "${1:-}" = "daemon" ]
|
|
37
|
+
[ "${2:-}" = "status" ]
|
|
38
|
+
[ "${3:-}" = "--service-name" ]
|
|
39
|
+
[ "${4:-}" = "runtime-summary.example.test" ]
|
|
40
|
+
cat <<STATUS
|
|
41
|
+
cc-connect daemon status
|
|
42
|
+
|
|
43
|
+
Status: Running
|
|
44
|
+
Platform: test
|
|
45
|
+
WorkDir: ${CONNECT_WORK_DIR:-}
|
|
46
|
+
STATUS
|
|
47
|
+
EOF
|
|
48
|
+
chmod 700 "$fakebin/direxio-connect"
|
|
49
|
+
|
|
50
|
+
cat > "$fakebin/direxio-mcp" <<'EOF'
|
|
51
|
+
#!/usr/bin/env bash
|
|
52
|
+
set -euo pipefail
|
|
53
|
+
if [ "${DIREXIO_CREDENTIALS_FILE:-}" != "${EXPECTED_CREDENTIALS_FILE:-}" ]; then
|
|
54
|
+
echo "wrong DIREXIO_CREDENTIALS_FILE" >&2
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
if [ "${1:-}" = "doctor" ] && [ "${2:-}" = "--json" ]; then
|
|
59
|
+
printf '{"ok":true,"domain":"runtime-summary.example.test","agent_room_id":"!agent:runtime-summary.example.test","token":"redacted"}\n'
|
|
60
|
+
exit 0
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
frame() {
|
|
64
|
+
local body=$1
|
|
65
|
+
printf 'Content-Length: %s\r\n\r\n%s' "${#body}" "$body"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
frame '{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"fake-direxio-mcp","version":"0.0.0"}}}'
|
|
69
|
+
frame '{"jsonrpc":"2.0","id":2,"result":{"tools":[{"name":"search_rooms"},{"name":"send_message"},{"name":"list_messages"}]}}'
|
|
70
|
+
EOF
|
|
71
|
+
chmod 700 "$fakebin/direxio-mcp"
|
|
72
|
+
|
|
73
|
+
cat > "$tmp/fake-mcp.ps1" <<'EOF'
|
|
74
|
+
if ($env:DIREXIO_CREDENTIALS_FILE -ne $env:EXPECTED_CREDENTIALS_FILE) {
|
|
75
|
+
[Console]::Error.WriteLine("wrong DIREXIO_CREDENTIALS_FILE")
|
|
76
|
+
exit 1
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (($args.Count -ge 2) -and ($args[0] -eq "doctor") -and ($args[1] -eq "--json")) {
|
|
80
|
+
[Console]::Out.WriteLine('{"ok":true,"domain":"runtime-summary.example.test","agent_room_id":"!agent:runtime-summary.example.test","token":"redacted"}')
|
|
81
|
+
exit 0
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function Frame($body) {
|
|
85
|
+
[Console]::Out.Write("Content-Length: $($body.Length)`r`n`r`n$body")
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
Frame '{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"fake-direxio-mcp","version":"0.0.0"}}}'
|
|
89
|
+
Frame '{"jsonrpc":"2.0","id":2,"result":{"tools":[{"name":"search_rooms"},{"name":"send_message"},{"name":"list_messages"}]}}'
|
|
90
|
+
EOF
|
|
91
|
+
|
|
92
|
+
mcp_command=direxio-mcp
|
|
93
|
+
case "$(uname -s)" in
|
|
94
|
+
MINGW*|MSYS*|CYGWIN*) use_windows_mcp=1 ;;
|
|
95
|
+
*) use_windows_mcp=0 ;;
|
|
96
|
+
esac
|
|
97
|
+
if { [ "$use_windows_mcp" = "1" ] || ! command -v node >/dev/null 2>&1; } && command -v node.exe >/dev/null 2>&1; then
|
|
98
|
+
fake_mcp_ps1=$(windows_path "$tmp/fake-mcp.ps1")
|
|
99
|
+
mcp_command="powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"$fake_mcp_ps1\""
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
cat > "$fakebin/curl" <<'EOF'
|
|
103
|
+
#!/usr/bin/env bash
|
|
104
|
+
set -euo pipefail
|
|
105
|
+
body_path=""
|
|
106
|
+
write_code=0
|
|
107
|
+
while [ "$#" -gt 0 ]; do
|
|
108
|
+
case "$1" in
|
|
109
|
+
-o) body_path=$2; shift 2 ;;
|
|
110
|
+
-w) write_code=1; shift 2 ;;
|
|
111
|
+
*) shift ;;
|
|
112
|
+
esac
|
|
113
|
+
done
|
|
114
|
+
payload='{"room_id":"!agent:runtime-summary.example.test","messages":[]}'
|
|
115
|
+
if [ -n "$body_path" ]; then
|
|
116
|
+
printf '%s\n' "$payload" > "$body_path"
|
|
117
|
+
else
|
|
118
|
+
printf '%s\n' "$payload"
|
|
119
|
+
fi
|
|
120
|
+
[ "$write_code" -eq 1 ] && printf '200'
|
|
121
|
+
EOF
|
|
122
|
+
chmod 700 "$fakebin/curl"
|
|
123
|
+
|
|
124
|
+
service_dir="$HOME/.direxio/nodes/runtime-summary.example.test"
|
|
125
|
+
mkdir -p "$service_dir/cc-connect"
|
|
126
|
+
credentials="$service_dir/credentials.json"
|
|
127
|
+
config="$service_dir/cc-connect/config.toml"
|
|
128
|
+
: > "$credentials"
|
|
129
|
+
: > "$config"
|
|
130
|
+
expected_credentials="$credentials"
|
|
131
|
+
if command -v cygpath >/dev/null 2>&1; then
|
|
132
|
+
expected_credentials=$(cygpath -m "$expected_credentials")
|
|
133
|
+
fi
|
|
134
|
+
state="$service_dir/state.json"
|
|
135
|
+
jq -n \
|
|
136
|
+
--arg service_dir "$service_dir" \
|
|
137
|
+
--arg credentials "$credentials" \
|
|
138
|
+
--arg config "$config" \
|
|
139
|
+
--arg mcp_command "$mcp_command" \
|
|
140
|
+
'{
|
|
141
|
+
run_id: "runtime-summary-test",
|
|
142
|
+
region: "ap-northeast-1",
|
|
143
|
+
domain_mode: "user",
|
|
144
|
+
domain: "runtime-summary.example.test",
|
|
145
|
+
as_url: "https://runtime-summary.example.test",
|
|
146
|
+
agent_service_id: "runtime-summary.example.test",
|
|
147
|
+
agent_service_dir: $service_dir,
|
|
148
|
+
agent_credentials_file: $credentials,
|
|
149
|
+
mcp_credentials_file: $credentials,
|
|
150
|
+
mcp_command: $mcp_command,
|
|
151
|
+
agent_token: "AGENT_TOKEN_RUNTIME",
|
|
152
|
+
agent_room_id: "!agent:runtime-summary.example.test",
|
|
153
|
+
cc_connect_config: $config,
|
|
154
|
+
cc_connect_binary: "direxio-connect",
|
|
155
|
+
phase: "S7_VERIFY_E2E",
|
|
156
|
+
phases: {
|
|
157
|
+
S0_PREREQ_AWS: {status: "done"},
|
|
158
|
+
S1_PREFLIGHT: {status: "done"},
|
|
159
|
+
S2_DOMAIN: {status: "done"},
|
|
160
|
+
S3_PROVISION: {status: "done"},
|
|
161
|
+
S4_BOOTSTRAP_STACK: {status: "done"},
|
|
162
|
+
S5_INIT_TOKENS: {status: "done"},
|
|
163
|
+
S6_WIRE_LOCAL: {status: "done"},
|
|
164
|
+
S7_VERIFY_E2E: {status: "done"}
|
|
165
|
+
},
|
|
166
|
+
resources: {}
|
|
167
|
+
}' > "$state"
|
|
168
|
+
|
|
169
|
+
verify_output=$(P2P_WORKDIR="$service_dir" PATH="$fakebin:$PATH" EXPECTED_CREDENTIALS_FILE="$expected_credentials" CONNECT_WORK_DIR="$service_dir/cc-connect" bash "$ROOT/scripts/orchestrate.sh" verify runtime)
|
|
170
|
+
printf '%s\n' "$verify_output" | grep -q 'verified runtime checks: passed'
|
|
171
|
+
|
|
172
|
+
jq -e '
|
|
173
|
+
.runtime_checks.summary.status == "passed"
|
|
174
|
+
and .runtime_checks.summary.failed_count == 0
|
|
175
|
+
and .runtime_checks.summary.checks.connect_daemon == "passed"
|
|
176
|
+
and .runtime_checks.summary.checks.mcp_doctor == "passed"
|
|
177
|
+
and .runtime_checks.summary.checks.mcp_tools == "passed"
|
|
178
|
+
and .runtime_checks.summary.checks.mcp_smoke == "passed"
|
|
179
|
+
and (.user_confirmations.agent_mcp_runtime | not)
|
|
180
|
+
' "$state" >/dev/null
|
|
181
|
+
|
|
182
|
+
report_output=$(P2P_WORKDIR="$service_dir" bash "$ROOT/scripts/orchestrate.sh" report new_deploy)
|
|
183
|
+
report_path=$(printf '%s\n' "$report_output" | sed -nE 's/^operation report: //p' | tail -n 1)
|
|
184
|
+
jq -e '.runtime_checks.summary.status == "passed"' "$report_path" >/dev/null
|
|
185
|
+
|
|
186
|
+
set +e
|
|
187
|
+
P2P_WORKDIR="$service_dir" PATH="$fakebin:$PATH" EXPECTED_CREDENTIALS_FILE="$expected_credentials" CONNECT_WORK_DIR="$HOME/.direxio/nodes/other.example.test/cc-connect" bash "$ROOT/scripts/orchestrate.sh" verify runtime > "$tmp/runtime-fail.out" 2>&1
|
|
188
|
+
fail_rc=$?
|
|
189
|
+
set -e
|
|
190
|
+
[ "$fail_rc" -ne 0 ] || {
|
|
191
|
+
echo "runtime summary must fail when any runtime check fails" >&2
|
|
192
|
+
exit 1
|
|
193
|
+
}
|
|
194
|
+
jq -e '
|
|
195
|
+
.runtime_checks.summary.status == "failed"
|
|
196
|
+
and .runtime_checks.summary.failed_count == 1
|
|
197
|
+
and .runtime_checks.summary.checks.connect_daemon == "failed"
|
|
198
|
+
and .runtime_checks.summary.checks.mcp_doctor == "passed"
|
|
199
|
+
and .runtime_checks.summary.checks.mcp_tools == "passed"
|
|
200
|
+
and .runtime_checks.summary.checks.mcp_smoke == "passed"
|
|
201
|
+
' "$state" >/dev/null
|
|
202
|
+
|
|
203
|
+
echo "runtime summary check ok"
|