feat(core): node veth idempotency, multi-node cdp ports, brain last ids persistence, and pulse interval variable
This commit is contained in:
@@ -45,42 +45,59 @@ def get_tailscale_dns():
|
||||
pass
|
||||
return "bl.tailfb5960.ts.net"
|
||||
|
||||
def get_node_cdp_port(node):
|
||||
nodes_file = os.path.join(NETVM_DIR, "NODES.md")
|
||||
pinned = {"muse": 9410, "pip": 9420, "646": 9430, "opm": 9440, "def": 9450, "dev": 9460}
|
||||
if node in pinned:
|
||||
return pinned[node]
|
||||
try:
|
||||
with open(nodes_file) as f:
|
||||
for line in f:
|
||||
if not line.strip().startswith("|"): continue
|
||||
cells = [c.strip() for c in line.strip("|").split("|")]
|
||||
if len(cells) >= 4 and cells[0] == node and cells[3].isdigit():
|
||||
return int(cells[3])
|
||||
except Exception:
|
||||
pass
|
||||
return 9450
|
||||
|
||||
def fetch_node_ig_link(node):
|
||||
"""Query CDP within node netns to get fresh Meta Accounts Center OAuth URL."""
|
||||
script = """
|
||||
port = get_node_cdp_port(node)
|
||||
script = f"""
|
||||
import json, websocket, sys, urllib.request
|
||||
|
||||
try:
|
||||
tabs = json.loads(urllib.request.urlopen("http://127.0.0.1:9450/json").read())
|
||||
tabs = json.loads(urllib.request.urlopen("http://127.0.0.1:{port}/json").read())
|
||||
except Exception as e:
|
||||
print(json.dumps({"error": f"CDP unreachable: {e}"}))
|
||||
print(json.dumps({{"error": f"CDP unreachable: {{e}}"}}))
|
||||
sys.exit(0)
|
||||
|
||||
muse_tab = next((t for t in tabs if "muse.ai" in t.get("url", "") and t.get("type") == "page"), None)
|
||||
if not muse_tab:
|
||||
print(json.dumps({"error": "No muse.ai tab open"}))
|
||||
print(json.dumps({{"error": "No muse.ai tab open"}}))
|
||||
sys.exit(0)
|
||||
|
||||
try:
|
||||
ws = websocket.create_connection(muse_tab["webSocketDebuggerUrl"], timeout=5)
|
||||
expr = '''(async()=>{
|
||||
try {
|
||||
const r = await fetch('/api/hatch/age-confirmation/linking-web-auth?account_type=instagram', {
|
||||
headers: {'Accept': 'application/json'}
|
||||
});
|
||||
expr = \'\'\'(async()=>{{
|
||||
try {{
|
||||
const r = await fetch('/api/hatch/age-confirmation/linking-web-auth?account_type=instagram', {{
|
||||
headers: {{'Accept': 'application/json'}}
|
||||
}});
|
||||
return await r.json();
|
||||
} catch(e) { return {error: String(e)}; }
|
||||
})()'''
|
||||
ws.send(json.dumps({"id": 1, "method": "Runtime.evaluate", "params": {"expression": expr, "awaitPromise": True, "returnByValue": True}}))
|
||||
}} catch(e) {{ return {{error: String(e)}}; }}
|
||||
}})()\'\'\'
|
||||
ws.send(json.dumps({{"id": 1, "method": "Runtime.evaluate", "params": {{"expression": expr, "awaitPromise": True, "returnByValue": True}}}}))
|
||||
while True:
|
||||
msg = json.loads(ws.recv())
|
||||
if msg.get("id") == 1:
|
||||
val = msg.get("result", {}).get("result", {}).get("value", {})
|
||||
val = msg.get("result", {{}}).get("result", {{}}).get("value", {{}})
|
||||
print(json.dumps(val))
|
||||
break
|
||||
ws.close()
|
||||
except Exception as e:
|
||||
print(json.dumps({"error": f"CDP evaluate failed: {e}"}))
|
||||
print(json.dumps({{"error": f"CDP evaluate failed: {{e}}"}}))
|
||||
"""
|
||||
cmd = ["sudo", "-n", "ip", "netns", "exec", f"warp-{node}", sys.executable, "-c", script]
|
||||
try:
|
||||
@@ -96,8 +113,7 @@ except Exception as e:
|
||||
def check_node_cleared(node):
|
||||
"""Check if node has transitioned past access/verification into active chat."""
|
||||
checker = os.path.join(NETVM_DIR, "bin", "accounts-health.py")
|
||||
# Lookup port from registry or default to 9450 for def
|
||||
port = 9450
|
||||
port = get_node_cdp_port(node)
|
||||
cmd = ["sudo", "-n", "ip", "netns", "exec", f"warp-{node}", sys.executable, checker, str(port)]
|
||||
try:
|
||||
res = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
|
||||
|
||||
Reference in New Issue
Block a user