From 7272ccfeea615e103f90cd3da1a8ff235d4557b8 Mon Sep 17 00:00:00 2001 From: operator Date: Sat, 3 Oct 2026 20:28:18 +0000 Subject: [PATCH] opp-dm.py: fix to work from bl or container, verify writes --- bin/opp-dm.py | 94 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 31 deletions(-) diff --git a/bin/opp-dm.py b/bin/opp-dm.py index 9dc7859..9896ddb 100755 --- a/bin/opp-dm.py +++ b/bin/opp-dm.py @@ -1,55 +1,87 @@ #!/usr/bin/env python3 """ -opp-dm.py: Operator Direct Messages +opp-dm.py: Operator Direct Messages (fixed) -For operator-to-operator communication (646, operator-main). -Operators have SSH access and infrastructure tools. -This is bidirectional and reliable. +Works from container OR from bl directly. +Detects environment and acts accordingly. +Verifies writes. -Distinct from dev-dm.py (for task agents: muse, pip). - -Usage: - opp-dm.py send --to 646 "message" # operator-main -> 646 - opp-dm.py send --to operator-main "msg" # 646 -> operator-main (via SSH) - opp-dm.py read [--from 646] # Read operator messages +For operator-to-operator: 646, operator-main. """ import argparse import subprocess import sys -import time +import os +import datetime +from pathlib import Path -# Operators have SSH access to bl -# Messages stored in a shared location on bl -BL_MSG_DIR = "/home/super/Projects/NetVM/opp-dms" +# Detect if we're on bl (has /home/super/Projects/NetVM) +ON_BL = Path("/home/super/Projects/NetVM").exists() +BL_MSG_DIR = Path("/home/super/Projects/NetVM/opp-dms") -def bl_run(cmd): - """Run command on bl via SSH.""" +def bl_run_container(cmd): + """Run on bl via SSH chain (from container).""" full = f"ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes super@100.123.153.75 '{cmd}'" - # Via VM vm_cmd = f"ssh -i ~/.ssh/vm_to_gcp -o ProxyCommand=\"$HOME/workspace/bin/ssh-via-proxy %h %p\" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes super@34.139.37.135 \"{full}\"" result = subprocess.run(vm_cmd, shell=True, capture_output=True, text=True, timeout=30) - return result.stdout.strip() + return result.stdout.strip(), result.returncode def opp_send(to, message, from_who="operator-main"): - """Send an operator DM (stored on bl, both can access via SSH).""" - import datetime + """Send operator DM. Works from container or bl.""" + if to not in ["646", "operator-main"]: + print(f"ERROR: Unknown operator {to}", file=sys.stderr) + sys.exit(1) + ts = datetime.datetime.now().isoformat() - # Escape for shell safe = message.replace("'", "'\"'\"'")[:1000] - cmd = f"mkdir -p {BL_MSG_DIR} && echo '{ts} [{from_who}]: {safe}' >> {BL_MSG_DIR}/{to}.log && echo 'sent'" - result = bl_run(cmd) - print(f"OPP-DM sent to {to}") - return result + line = f"{ts} [{from_who}]: {safe}" + + if ON_BL: + # Direct write (we're on bl) + BL_MSG_DIR.mkdir(parents=True, exist_ok=True) + logfile = BL_MSG_DIR / f"{to}.log" + with open(logfile, "a") as f: + f.write(line + "\n") + # Verify + if logfile.exists(): + print(f"OPP-DM sent to {to} (verified)") + return True + else: + print(f"ERROR: Write failed", file=sys.stderr) + sys.exit(1) + else: + # Via SSH (from container) + cmd = f"mkdir -p {BL_MSG_DIR} && echo '{line}' >> {BL_MSG_DIR}/{to}.log && test -f {BL_MSG_DIR}/{to}.log && echo OK" + out, rc = bl_run_container(cmd) + if rc == 0 and "OK" in out: + print(f"OPP-DM sent to {to} (verified)") + return True + else: + print(f"ERROR: Send failed: {out}", file=sys.stderr) + sys.exit(1) def opp_read(who="operator-main", n=5): - """Read operator DMs.""" - cmd = f"tail -n {n*2} {BL_MSG_DIR}/{who}.log 2>/dev/null || echo 'no messages'" - result = bl_run(cmd) - print(result) - return result + """Read operator DMs. Works from container or bl.""" + if who not in ["646", "operator-main"]: + print(f"ERROR: Unknown operator {who}", file=sys.stderr) + sys.exit(1) + + if ON_BL: + logfile = BL_MSG_DIR / f"{who}.log" + if not logfile.exists(): + print("no messages") + return + with open(logfile) as f: + lines = f.readlines() + for l in lines[-n:]: + print(l.strip()) + else: + cmd = f"tail -n {n} {BL_MSG_DIR}/{who}.log 2>/dev/null || echo 'no messages'" + out, rc = bl_run_container(cmd) + print(out) def main(): - p = argparse.ArgumentParser(description="OPP-DM: Operator Direct Messages") + p = argparse.ArgumentParser(description="OPP-DM: Operator DMs (fixed)") sub = p.add_subparsers(dest='cmd', required=True) ps = sub.add_parser('send', help='Send operator DM')