mirror of
https://github.com/PR0M3TH3AN/VoxVera.git
synced 2026-11-06 22:50:41 +00:00
docs: add linux hosting validation runbook
This commit is contained in:
1 parent
2de7ea073c
commit
4e49762a85
6 files changed
+322
No files matched your search
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
if [[ "$(uname -s)" != "Linux" ]]; then
|
||||
echo "linux-recovery-check.sh is only for Linux hosts." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
command -v voxvera >/dev/null 2>&1 || {
|
||||
echo "voxvera is not on PATH" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
TMP_DIR="${VOXVERA_RECOVERY_TMPDIR:-$(mktemp -d /tmp/voxvera-linux-recovery-XXXXXX)}"
|
||||
cleanup() {
|
||||
if [[ -z "${VOXVERA_RECOVERY_TMPDIR:-}" ]]; then
|
||||
rm -rf "$TMP_DIR"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
PLATFORM_JSON="$TMP_DIR/platform-status.json"
|
||||
DOCTOR_JSON="$TMP_DIR/doctor.json"
|
||||
AUTOSTART_JSON="$TMP_DIR/autostart-status.json"
|
||||
|
||||
voxvera platform-status --json >"$PLATFORM_JSON"
|
||||
voxvera doctor --json >"$DOCTOR_JSON"
|
||||
voxvera autostart status --json >"$AUTOSTART_JSON"
|
||||
|
||||
PLATFORM_JSON="$PLATFORM_JSON" \
|
||||
DOCTOR_JSON="$DOCTOR_JSON" \
|
||||
AUTOSTART_JSON="$AUTOSTART_JSON" \
|
||||
python3 - <<'PY'
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
platform_status = json.loads(Path(os.environ["PLATFORM_JSON"]).read_text(encoding="utf-8"))
|
||||
doctor = json.loads(Path(os.environ["DOCTOR_JSON"]).read_text(encoding="utf-8"))
|
||||
autostart = json.loads(Path(os.environ["AUTOSTART_JSON"]).read_text(encoding="utf-8"))
|
||||
|
||||
errors = []
|
||||
warnings = []
|
||||
|
||||
if platform_status.get("platform_id") != "linux_cli_systemd":
|
||||
errors.append(f"expected linux_cli_systemd, got {platform_status.get('platform_id')}")
|
||||
if platform_status.get("tier") != "supported":
|
||||
errors.append(f"expected supported tier, got {platform_status.get('tier')}")
|
||||
|
||||
checks = {check["name"]: check for check in doctor.get("checks", [])}
|
||||
|
||||
required_ok = ["platform", "voxvera_cli", "onionshare_cli", "tor_binary", "host_root"]
|
||||
for name in required_ok:
|
||||
check = checks.get(name)
|
||||
if not check:
|
||||
errors.append(f"missing doctor check: {name}")
|
||||
elif not check.get("ok"):
|
||||
errors.append(f"{name} failed: {check.get('detail')}")
|
||||
|
||||
tor_check = checks.get("tor_socks_reachable")
|
||||
if not tor_check:
|
||||
errors.append("missing doctor check: tor_socks_reachable")
|
||||
elif not tor_check.get("ok"):
|
||||
warnings.append(f"tor_socks_reachable: {tor_check.get('detail')}")
|
||||
|
||||
timer_check = next((check for check in autostart.get("checks", []) if check["name"] == "systemd_timer_enabled"), None)
|
||||
if not timer_check:
|
||||
errors.append("missing autostart check: systemd_timer_enabled")
|
||||
elif not timer_check.get("ok"):
|
||||
warnings.append(f"systemd_timer_enabled: {timer_check.get('detail')}")
|
||||
|
||||
artifacts = [Path(path) for path in autostart.get("artifacts", [])]
|
||||
missing = [str(path) for path in artifacts if not path.exists()]
|
||||
if missing:
|
||||
warnings.append("missing autostart artifacts: " + ", ".join(missing))
|
||||
|
||||
host_root = Path.home() / "host"
|
||||
sites = []
|
||||
if host_root.exists():
|
||||
for site_dir in sorted(path for path in host_root.iterdir() if path.is_dir()):
|
||||
config = site_dir / "config.json"
|
||||
if not config.exists():
|
||||
continue
|
||||
session = site_dir / ".onionshare-session"
|
||||
log = site_dir / "onionshare.log"
|
||||
pid = site_dir / "server.pid"
|
||||
sites.append(
|
||||
{
|
||||
"name": site_dir.name,
|
||||
"session": session.exists(),
|
||||
"log": log.exists(),
|
||||
"pid": pid.exists(),
|
||||
}
|
||||
)
|
||||
|
||||
if errors:
|
||||
print("Linux recovery check failed:", file=sys.stderr)
|
||||
for error in errors:
|
||||
print(f"- {error}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
print(f"Platform: {platform_status['label']} [{platform_status['tier']}]")
|
||||
print(f"Hosting model: {platform_status.get('hosting_model', '')}")
|
||||
print(f"Autostart: {autostart.get('message', '')}")
|
||||
if warnings:
|
||||
print("Warnings:")
|
||||
for warning in warnings:
|
||||
print(f"- {warning}")
|
||||
else:
|
||||
print("Warnings: none")
|
||||
|
||||
if sites:
|
||||
print("Site state:")
|
||||
for site in sites:
|
||||
print(
|
||||
f"- {site['name']}: session={'yes' if site['session'] else 'no'}, "
|
||||
f"log={'yes' if site['log'] else 'no'}, pid={'yes' if site['pid'] else 'no'}"
|
||||
)
|
||||
else:
|
||||
print("Site state: no configured sites under ~/host")
|
||||
PY
|
||||
|
||||
echo "Detailed JSON artifacts written to $TMP_DIR"
|
||||
Reference in new issue
Block a user