PAD-12: per-terminal transport (direct Tailscale SSH or Warpgate, pre-session fallback, pinned host keys, agent key from Vault), one-call win10 launch and one-call collect, remote call timings, agentd ping
This commit is contained in:
@@ -9,6 +9,7 @@ from . import config as config_mod
|
||||
from .core import Agentd
|
||||
from .plane import Plane, brief_to_html, html_to_text, text_to_html
|
||||
from .store import Busy
|
||||
from .transports import CallLog, TransportError, direct_ssh, make_transport
|
||||
|
||||
|
||||
def identity(cfg, wanted=None):
|
||||
@@ -159,6 +160,31 @@ def cmd_smoke(cfg, a):
|
||||
sys.exit(0 if ok else 1)
|
||||
|
||||
|
||||
def cmd_ping(cfg, a):
|
||||
"""Trivial command on a terminal, timed per call (verifies direct-ssh / warpgate-ssh after a deployment). The
|
||||
direct-ssh key comes from the environment like the Plane tokens (agent-access.py exec --secret-env)."""
|
||||
if a.terminal not in cfg.terminals:
|
||||
sys.exit("unknown terminal %s" % a.terminal)
|
||||
t = cfg.terminals[a.terminal]
|
||||
if (a.transport or t["transport"]) == "local":
|
||||
sys.exit("%s is a local terminal: nothing to ping" % a.terminal)
|
||||
if a.transport == "direct-ssh" and "ssh" not in t:
|
||||
sys.exit("terminals.%s has no ssh section" % a.terminal)
|
||||
log = CallLog(event=lambda m: print("event: " + m, flush=True), echo=True)
|
||||
tr = make_transport(cfg, a.terminal, log=log, force=a.transport)
|
||||
ok = True
|
||||
for i in range(a.count):
|
||||
t0 = time.monotonic()
|
||||
try:
|
||||
pong = tr.ping()
|
||||
except TransportError as exc:
|
||||
ok = False
|
||||
print("ping %d: FAILED after %d ms: %s" % (i + 1, (time.monotonic() - t0) * 1000, exc), flush=True)
|
||||
continue
|
||||
print("ping %d: %d ms %s" % (i + 1, (time.monotonic() - t0) * 1000, pong), flush=True)
|
||||
sys.exit(0 if ok else 1)
|
||||
|
||||
|
||||
def cmd_check_config(cfg, a):
|
||||
print("config %s is valid" % cfg.path)
|
||||
print("projects: %s" % ", ".join(cfg.projects))
|
||||
@@ -166,6 +192,13 @@ def cmd_check_config(cfg, a):
|
||||
env = cfg.token_env(name)
|
||||
print("terminal %-10s %-13s %-8s executors=%s token %s: %s" % (
|
||||
name, t["transport"], t["os"], ",".join(t["executors"]), env, "set" if os.environ.get(env) else "MISSING"))
|
||||
if t["transport"] == "direct-ssh":
|
||||
s = t["ssh"]
|
||||
print(" direct-ssh %s@%s:%s, fallback %s" % (s["user"], s["host"], s.get("port", 22), t.get("fallback", "none")))
|
||||
if cfg.uses_direct_ssh():
|
||||
print("direct-ssh key %s: %s; ssh_dir %s" % (
|
||||
cfg.ssh_key_env, "set" if direct_ssh.key_present(cfg.ssh_key_env) else "MISSING (direct terminals use their fallback)",
|
||||
cfg.ssh_dir))
|
||||
print("cron/exec secret args: %s" % " ".join(cfg.secret_env_args()))
|
||||
if cfg.webhook:
|
||||
k = cfg.webhook["secret_key"]
|
||||
@@ -221,6 +254,12 @@ def parser():
|
||||
s.add_argument("--port", type=int, help="port (default: webhook.port)")
|
||||
s.set_defaults(fn=cmd_webhook_serve)
|
||||
sub.add_parser("check-config", help="validate the config and list token env vars").set_defaults(fn=cmd_check_config)
|
||||
s = sub.add_parser("ping", help="time a trivial command on a terminal (direct-ssh needs the key env var, see check-config)")
|
||||
s.add_argument("terminal")
|
||||
s.add_argument("--transport", choices=["direct-ssh", "warpgate-ssh"],
|
||||
help="force one channel, no fallback (default: the terminal's transport with its fallback)")
|
||||
s.add_argument("-n", "--count", type=int, default=3, help="calls (default 3: the 2nd+ reuse the SSH connection)")
|
||||
s.set_defaults(fn=cmd_ping)
|
||||
return ap
|
||||
|
||||
|
||||
@@ -230,4 +269,5 @@ def main(argv=None):
|
||||
cfg = config_mod.load(a.config)
|
||||
except config_mod.ConfigError as exc:
|
||||
sys.exit(str(exc))
|
||||
direct_ssh.take_key(cfg.ssh_key_env) # out of os.environ before any child process starts
|
||||
a.fn(cfg, a)
|
||||
|
||||
Reference in New Issue
Block a user