Some checks are pending
review / inventory (push) Waiting to run
UserReview leftovers implemented without rewriting 70 website repos and without fail-closing pfc-py-admin.
201 lines
9.6 KiB
Bash
Executable file
201 lines
9.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Test locally, then rsync validated trees to ns1. Does not enable PFC_REQUIRE_NPE.
|
|
# Never skip tests. Does not replace pfc-py-admin with Go pfc-admin.
|
|
set -euo pipefail
|
|
ROOT="${RESEARCH:-$HOME/research}"
|
|
HOST="${DEPLOY_HOST:-marchon@70.88.205.138}"
|
|
export PATH="/opt/homebrew/bin:$PATH"
|
|
|
|
echo "=== review ==="
|
|
bash "$ROOT/system-git-sync/cicd/run-review.sh"
|
|
|
|
echo "=== linux sm-leaf ==="
|
|
mkdir -p "$ROOT/secure-messaging/go/bin"
|
|
( cd "$ROOT/secure-messaging/go" && GOOS=linux GOARCH=amd64 go build -o bin/sm-leaf-linux ./cmd/sm-leaf )
|
|
|
|
echo "=== rsync ==="
|
|
ssh "$HOST" 'sudo mkdir -p /opt/pfc/bin /opt/pfc/python/secure_messaging /opt/pfc/python/admin /opt/pfc/python/lib /opt/pfc/etc /opt/pfc/data/admin/admin-history /opt/pfc/docs/html/sync /opt/pfc/docs/html/nats-service-endpoints'
|
|
rsync -az "$ROOT/secure-messaging/go/bin/sm-leaf-linux" "$HOST:/tmp/sm-leaf-linux"
|
|
rsync -az --exclude '__pycache__' "$ROOT/secure-messaging/python/secure_messaging/" "$HOST:/tmp/secure_messaging/"
|
|
rsync -az "$ROOT/secure-messaging/deploy/pfc-sm-leaf.service" "$HOST:/tmp/pfc-sm-leaf.service"
|
|
rsync -az "$ROOT/system-git-sync/" --exclude '.git' --exclude '.forgejo' "$HOST:/tmp/system-git-sync/"
|
|
rsync -az --exclude '__pycache__' "$ROOT/peergos-for-compliance-admin/pfc_admin/" "$HOST:/tmp/pfc_admin/"
|
|
rsync -az --exclude '__pycache__' "$ROOT/peergos-for-compliance/lib/" "$HOST:/tmp/pfc_lib/"
|
|
if [[ -d "$ROOT/nats-service-endpoints/build/html" ]]; then
|
|
rsync -az "$ROOT/nats-service-endpoints/build/html/" "$HOST:/tmp/nse-html/"
|
|
fi
|
|
if [[ -f "$ROOT/nats-service-endpoints/build/latex/nats-service-endpoints.pdf" ]]; then
|
|
rsync -az "$ROOT/nats-service-endpoints/build/latex/nats-service-endpoints.pdf" "$HOST:/tmp/nse.pdf"
|
|
fi
|
|
if [[ -d "$ROOT/peergos-compliance-docs/build/html" ]]; then
|
|
rsync -az "$ROOT/peergos-compliance-docs/build/html/" "$HOST:/tmp/pfc-docs-html/"
|
|
fi
|
|
if [[ -f "$ROOT/peergos-compliance-docs/build/latex/peergos-for-compliance.pdf" ]]; then
|
|
rsync -az "$ROOT/peergos-compliance-docs/build/latex/peergos-for-compliance.pdf" "$HOST:/tmp/pfc-docs.pdf"
|
|
fi
|
|
if [[ -d "$ROOT/secure-messaging/build/html" ]]; then
|
|
rsync -az "$ROOT/secure-messaging/build/html/" "$HOST:/tmp/sm-html/"
|
|
fi
|
|
if [[ -d "$ROOT/peergos-compliance-config/web" ]]; then
|
|
rsync -az "$ROOT/peergos-compliance-config/web/" "$HOST:/tmp/config-web/"
|
|
fi
|
|
rsync -az "$ROOT/peergos-compliance-go/deploy/pfc.georgelambert.org.caddy" "$HOST:/tmp/pfc.georgelambert.org.caddy"
|
|
rsync -az "$ROOT/system-git-sync/docs/pfc-site/" "$HOST:/tmp/pfc-site/"
|
|
rsync -az "$ROOT/system-git-sync/docs/" --exclude pfc-site "$HOST:/tmp/sync-docs-extra/"
|
|
|
|
echo "=== install on host ==="
|
|
ssh "$HOST" 'bash -s' << "EOF"
|
|
set -e
|
|
sudo systemctl stop pfc-sm-leaf || true
|
|
sudo cp /tmp/sm-leaf-linux /opt/pfc/bin/sm-leaf
|
|
sudo chmod +x /opt/pfc/bin/sm-leaf
|
|
sudo mkdir -p /opt/pfc/python/secure_messaging /opt/pfc/python/admin/pfc_admin /opt/pfc/python/lib
|
|
sudo rsync -a /tmp/secure_messaging/ /opt/pfc/python/secure_messaging/
|
|
sudo rsync -a /tmp/pfc_admin/ /opt/pfc/python/admin/pfc_admin/
|
|
sudo rsync -a /tmp/pfc_lib/ /opt/pfc/python/lib/
|
|
sudo cp /tmp/pfc-sm-leaf.service /etc/systemd/system/pfc-sm-leaf.service
|
|
sudo mkdir -p /etc/systemd/system/pfc-py-admin.service.d
|
|
sudo tee /etc/systemd/system/pfc-py-admin.service.d/sm.conf >/dev/null << 'UNIT'
|
|
[Service]
|
|
Environment=PYTHONPATH=/opt/pfc/python/lib:/opt/pfc/python/admin:/opt/pfc/python
|
|
Environment=PFC_SIGNED_CONFIG=/opt/pfc/etc/secure-messaging.signed.json
|
|
Environment=PFC_CONFIG_KEY_PEM=/opt/pfc/etc/sm-keys/config.ed25519.pem
|
|
Environment=PFC_REPL_URL=http://127.0.0.1:18784
|
|
Environment=NPE_BIN=/opt/pfc/bin/npe
|
|
UNIT
|
|
# lab keys on host only — never overwrite an existing private key
|
|
sudo mkdir -p /opt/pfc/etc/sm-keys
|
|
if [ ! -f /opt/pfc/etc/sm-keys/config.ed25519.pem ]; then
|
|
sudo python3 - << 'PY'
|
|
from pathlib import Path
|
|
import sys
|
|
sys.path.insert(0, "/opt/pfc/python")
|
|
from secure_messaging.signed_config import generate_signing_key, pem_private, pem_public, save_signed, sign
|
|
priv = generate_signing_key()
|
|
d = Path("/opt/pfc/etc/sm-keys")
|
|
d.mkdir(parents=True, exist_ok=True)
|
|
(d / "config.ed25519.pem").write_bytes(pem_private(priv))
|
|
(d / "config.ed25519.pem").chmod(0o600)
|
|
(d / "config.ed25519.pub.pem").write_bytes(pem_public(priv.public_key()))
|
|
(d / "config.ed25519.pub.pem").chmod(0o644)
|
|
payload = {
|
|
"crypto": {"mode": "lab-xor", "system_key_id": "lab-system"},
|
|
"routing": {"mode": "passthrough"},
|
|
"admin": {"history_cube": "admin-history"},
|
|
"logging": {"mode": "summary"},
|
|
}
|
|
save_signed(Path("/opt/pfc/etc/secure-messaging.signed.json"), sign(payload, priv))
|
|
print("signed config written")
|
|
PY
|
|
fi
|
|
sudo chmod 600 /opt/pfc/etc/sm-keys/config.ed25519.pem
|
|
sudo chmod 644 /opt/pfc/etc/sm-keys/config.ed25519.pub.pem /opt/pfc/etc/secure-messaging.signed.json || true
|
|
# seed admin-history if empty (prev empty, new = current signed file)
|
|
sudo python3 - << 'PY'
|
|
from pathlib import Path
|
|
import sys
|
|
sys.path.insert(0, "/opt/pfc/python")
|
|
from secure_messaging.admin_history import AdminHistory
|
|
hist = Path("/opt/pfc/data/admin/admin-history")
|
|
chain = hist / "blockchain" / "chain.jsonl"
|
|
new = Path("/opt/pfc/etc/secure-messaging.signed.json").read_text()
|
|
if not chain.exists() or not chain.read_text().strip():
|
|
row = AdminHistory(hist).append_change(actor="deploy-ns1", prev_text="", new_text=new)
|
|
print("admin-history seeded seq", row.get("seq"))
|
|
else:
|
|
print("admin-history exists lines", sum(1 for _ in chain.open()))
|
|
PY
|
|
if [ -d /tmp/system-git-sync ]; then
|
|
sudo mkdir -p /opt/pfc/docs/html/sync
|
|
sudo rsync -a /tmp/system-git-sync/*.MD /tmp/system-git-sync/*.md /opt/pfc/docs/html/sync/ 2>/dev/null || true
|
|
if [ -f /tmp/system-git-sync/docs/index.html ]; then
|
|
sudo cp /tmp/system-git-sync/docs/index.html /opt/pfc/docs/html/sync/index.html
|
|
fi
|
|
if [ -f /tmp/system-git-sync/docs/thesaurus.md ]; then
|
|
sudo cp /tmp/system-git-sync/docs/thesaurus.md /opt/pfc/docs/html/sync/thesaurus.md
|
|
fi
|
|
if [ -d /tmp/sync-docs-extra ]; then
|
|
sudo cp /tmp/sync-docs-extra/*.md /tmp/sync-docs-extra/*.html /opt/pfc/docs/html/sync/ 2>/dev/null || true
|
|
fi
|
|
fi
|
|
if [ -f /tmp/pfc.georgelambert.org.caddy ]; then
|
|
sudo cp /tmp/pfc.georgelambert.org.caddy /etc/caddy/sites/pfc.georgelambert.org.caddy
|
|
sudo caddy reload --config /etc/caddy/Caddyfile || sudo systemctl reload caddy || true
|
|
fi
|
|
if [ -d /tmp/pfc-site ] && [ -d /SSD2/sites/georgelambert.org ]; then
|
|
sudo mkdir -p /SSD2/sites/georgelambert.org/pfc
|
|
sudo cp /tmp/pfc-site/index.html /SSD2/sites/georgelambert.org/pfc/index.html
|
|
fi
|
|
if [ -x /opt/pfc/bin/npe ] && [ ! -f /opt/pfc/etc/npe/lab.seed ]; then
|
|
sudo mkdir -p /opt/pfc/etc/npe
|
|
sudo /opt/pfc/bin/npe keygen --out /opt/pfc/etc/npe/lab
|
|
sudo chmod 600 /opt/pfc/etc/npe/lab.seed
|
|
sudo chmod 644 /opt/pfc/etc/npe/lab.npeid || true
|
|
fi
|
|
if [ -d /tmp/nse-html ]; then
|
|
sudo rsync -a /tmp/nse-html/ /opt/pfc/docs/html/nats-service-endpoints/
|
|
fi
|
|
if [ -f /tmp/nse.pdf ]; then
|
|
sudo cp /tmp/nse.pdf /opt/pfc/docs/html/nats-service-endpoints/nats-service-endpoints.pdf
|
|
fi
|
|
if [ -d /tmp/pfc-docs-html ]; then
|
|
sudo rsync -a /tmp/pfc-docs-html/ /opt/pfc/docs/html/
|
|
fi
|
|
if [ -f /tmp/pfc-docs.pdf ]; then
|
|
sudo cp /tmp/pfc-docs.pdf /opt/pfc/docs/html/peergos-for-compliance.pdf
|
|
fi
|
|
if [ -d /tmp/sm-html ]; then
|
|
sudo mkdir -p /opt/pfc/docs/html/secure-messaging
|
|
sudo rsync -a /tmp/sm-html/ /opt/pfc/docs/html/secure-messaging/
|
|
fi
|
|
if [ -d /tmp/config-web ]; then
|
|
sudo mkdir -p /opt/pfc/config-ui
|
|
sudo rsync -a /tmp/config-web/ /opt/pfc/config-ui/
|
|
fi
|
|
# lab NPE identity on host only (never git)
|
|
if [ -x /opt/pfc/bin/npe ] && [ ! -f /opt/pfc/etc/npe/lab.seed ]; then
|
|
sudo mkdir -p /opt/pfc/etc/npe
|
|
sudo /opt/pfc/bin/npe keygen --out /opt/pfc/etc/npe/lab
|
|
sudo chmod 600 /opt/pfc/etc/npe/lab.seed
|
|
sudo chmod 644 /opt/pfc/etc/npe/lab.npeid
|
|
fi
|
|
# Caddy: sync.pfc (DNS already 70.88.205.138)
|
|
if [ -f /tmp/system-git-sync/../peergos-compliance-go/deploy/pfc.georgelambert.org.caddy ]; then
|
|
true
|
|
fi
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now pfc-sm-leaf
|
|
sudo systemctl restart pfc-py-admin
|
|
sleep 2
|
|
systemctl is-active pfc-sm-leaf pfc-py-admin pfc-connector pfc-peergos-bridge
|
|
echo "--- health ---"
|
|
curl -sS -m 5 http://127.0.0.1:18783/health; echo
|
|
curl -sS -m 5 http://127.0.0.1:18780/health; echo
|
|
echo "--- config unauth ---"
|
|
curl -sS -m 5 -o /tmp/cfg.out -w "http=%{http_code}\n" http://127.0.0.1:18780/v1/admin/config
|
|
cat /tmp/cfg.out; echo
|
|
echo "--- signed load ---"
|
|
sudo python3 - << 'PY'
|
|
from pathlib import Path
|
|
import sys
|
|
sys.path.insert(0, "/opt/pfc/python")
|
|
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
|
from secure_messaging.signed_config import load_signed
|
|
priv = load_pem_private_key(Path("/opt/pfc/etc/sm-keys/config.ed25519.pem").read_bytes(), password=None)
|
|
payload = load_signed(Path("/opt/pfc/etc/secure-messaging.signed.json"), priv.public_key())
|
|
assert payload["crypto"]["mode"] in ("lab-xor", "npe", "plain-lab")
|
|
assert payload["routing"]["mode"] == "passthrough"
|
|
print("signed_ok", payload["crypto"], payload["routing"])
|
|
PY
|
|
# never enable NPE on the live console from this script
|
|
if systemctl show pfc-py-admin -p Environment | grep -q PFC_REQUIRE_NPE=1; then
|
|
echo "WARNING: PFC_REQUIRE_NPE=1 is set; fail-closed if sidecar unused"
|
|
fi
|
|
echo DEPLOY_HOST_OK
|
|
EOF
|
|
echo "=== public smoke ==="
|
|
curl -sS -m 10 -o /tmp/pfc.health -w "pfc_https=%{http_code}\n" https://pfc.georgelambert.org/health
|
|
curl -sS -m 10 -o /tmp/nse.html -w "docs_nse=%{http_code}\n" https://docs.pfc.georgelambert.org/nats-service-endpoints/index.html
|
|
curl -sS -m 10 -o /tmp/sync.html -w "docs_sync=%{http_code}\n" https://docs.pfc.georgelambert.org/sync/index.html
|
|
curl -sS -m 10 -o /tmp/hist.md -w "docs_hist=%{http_code}\n" https://docs.pfc.georgelambert.org/sync/Historical-Information.MD
|
|
echo "DEPLOY OK"
|