#!/usr/bin/python3 import argparse import shlex import subprocess def debug(msg): if False: print(msg) class RadicleHost: def __init__(self, host=None, ssh_user=None, rad_user=None): assert host is not None self.host = host assert ssh_user is not None self.ssh_user = ssh_user assert rad_user is not None self.rad_user = rad_user self._path = None def _ssh(self, caller_args, as_rad_user=True): base_argv = ["ssh", f"{self.ssh_user}@{self.host}"] sudo_argv = ["sudo", "-u", self.rad_user] if self._path is None: path_argv = base_argv + sudo_argv + ["env"] debug(f"PATH_ARGV: {path_argv!r}") p = subprocess.run( path_argv, check=True, capture_output=True, ) path = [ line.strip() for line in p.stdout.decode().splitlines() if line.startswith("PATH=") ][0][len("PATH=") :] self._path = f"/home/{self.rad_user}/.radicle/bin:{path}" argv = base_argv if as_rad_user: argv += sudo_argv + ["env", f"PATH={self._path}"] argv += [shlex.quote(a) for a in caller_args] debug(f"ARGV: {argv!r}") p = subprocess.run( argv, capture_output=True, ) if p.returncode != 0: raise Exception( f"ssh failed, exit code {p.returncode}:\n{p.stderr.decode()}" ) return p.stdout.decode() def can_become_rad_user(self): out = self._ssh(["id", "-nu"]) assert out.strip() == self.rad_user print("OK: can become rad user") def node_is_running(self): out = self._ssh(["env", "TERM=dumb", "rad", "node", "status"]) assert "is running" in out.splitlines()[0] print("OK: node is running") def main(): p = argparse.ArgumentParser() p.add_argument("--host", required=True) p.add_argument("--ssh-user", required=True) p.add_argument("--rad-user", default="_rad") args = p.parse_args() rad = RadicleHost(host=args.host, ssh_user=args.ssh_user, rad_user=args.rad_user) rad.can_become_rad_user() rad.node_is_running() main()