allow sudo calls
This commit is contained in:
parent
87bc78e063
commit
20fe86d399
|
|
@ -32,10 +32,11 @@ _LABEL_HARDWARE = "ria.hardware"
|
||||||
_LABEL_APP = "ria.app"
|
_LABEL_APP = "ria.app"
|
||||||
|
|
||||||
|
|
||||||
def _engine() -> str:
|
def _engine(cfg: _config.AppConfig, sudo_override: bool = False) -> list[str]:
|
||||||
for exe in ("docker", "podman"):
|
for exe in ("docker", "podman"):
|
||||||
if shutil.which(exe):
|
if shutil.which(exe):
|
||||||
return exe
|
use_sudo = sudo_override or cfg.sudo
|
||||||
|
return (["sudo", exe] if use_sudo else [exe])
|
||||||
print("error: neither 'docker' nor 'podman' found on PATH", file=sys.stderr)
|
print("error: neither 'docker' nor 'podman' found on PATH", file=sys.stderr)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
|
|
@ -62,10 +63,10 @@ def _container_name(ref: str) -> str:
|
||||||
return f"ria-app-{name}"
|
return f"ria-app-{name}"
|
||||||
|
|
||||||
|
|
||||||
def _inspect_labels(engine: str, ref: str) -> dict:
|
def _inspect_labels(engine: list[str], ref: str) -> dict:
|
||||||
try:
|
try:
|
||||||
out = subprocess.check_output(
|
out = subprocess.check_output(
|
||||||
[engine, "image", "inspect", "--format", "{{json .Config.Labels}}", ref],
|
[*engine, "image", "inspect", "--format", "{{json .Config.Labels}}", ref],
|
||||||
stderr=subprocess.DEVNULL,
|
stderr=subprocess.DEVNULL,
|
||||||
)
|
)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
|
|
@ -102,35 +103,38 @@ def _cmd_configure(args: argparse.Namespace) -> int:
|
||||||
cfg.registry = args.registry
|
cfg.registry = args.registry
|
||||||
if args.namespace:
|
if args.namespace:
|
||||||
cfg.namespace = args.namespace
|
cfg.namespace = args.namespace
|
||||||
|
if args.sudo is not None:
|
||||||
|
cfg.sudo = args.sudo
|
||||||
path = _config.save(cfg)
|
path = _config.save(cfg)
|
||||||
print(f"Saved app config to {path}")
|
print(f"Saved app config to {path}")
|
||||||
print(f" registry: {cfg.registry or '(unset)'}")
|
print(f" registry: {cfg.registry or '(unset)'}")
|
||||||
print(f" namespace: {cfg.namespace or '(unset)'}")
|
print(f" namespace: {cfg.namespace or '(unset)'}")
|
||||||
|
print(f" sudo: {cfg.sudo}")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def _cmd_pull(args: argparse.Namespace) -> int:
|
def _cmd_pull(args: argparse.Namespace) -> int:
|
||||||
engine = _engine()
|
|
||||||
cfg = _config.load()
|
cfg = _config.load()
|
||||||
|
engine = _engine(cfg, args.sudo)
|
||||||
ref = _resolve_ref(args.app, cfg)
|
ref = _resolve_ref(args.app, cfg)
|
||||||
print(f"Pulling {ref}")
|
print(f"Pulling {ref}")
|
||||||
return subprocess.call([engine, "pull", ref])
|
return subprocess.call([*engine, "pull", ref])
|
||||||
|
|
||||||
|
|
||||||
def _cmd_run(args: argparse.Namespace) -> int:
|
def _cmd_run(args: argparse.Namespace) -> int:
|
||||||
engine = _engine()
|
|
||||||
cfg = _config.load()
|
cfg = _config.load()
|
||||||
|
engine = _engine(cfg, args.sudo)
|
||||||
ref = _resolve_ref(args.app, cfg)
|
ref = _resolve_ref(args.app, cfg)
|
||||||
|
|
||||||
if not _inspect_labels(engine, ref):
|
if not _inspect_labels(engine, ref):
|
||||||
rc = subprocess.call([engine, "pull", ref])
|
rc = subprocess.call([*engine, "pull", ref])
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
labels = _inspect_labels(engine, ref)
|
labels = _inspect_labels(engine, ref)
|
||||||
hw_flags = _hardware_flags(labels)
|
hw_flags = _hardware_flags(labels)
|
||||||
|
|
||||||
cmd = [engine, "run", "--rm"]
|
cmd = [*engine, "run", "--rm"]
|
||||||
if not args.foreground:
|
if not args.foreground:
|
||||||
cmd += ["-d"]
|
cmd += ["-d"]
|
||||||
cmd += ["--name", args.name or _container_name(ref)]
|
cmd += ["--name", args.name or _container_name(ref)]
|
||||||
|
|
@ -161,11 +165,12 @@ def _cmd_run(args: argparse.Namespace) -> int:
|
||||||
return subprocess.call(cmd)
|
return subprocess.call(cmd)
|
||||||
|
|
||||||
|
|
||||||
def _cmd_list(_args: argparse.Namespace) -> int:
|
def _cmd_list(args: argparse.Namespace) -> int:
|
||||||
engine = _engine()
|
cfg = _config.load()
|
||||||
|
engine = _engine(cfg, args.sudo)
|
||||||
return subprocess.call(
|
return subprocess.call(
|
||||||
[
|
[
|
||||||
engine,
|
*engine,
|
||||||
"images",
|
"images",
|
||||||
"--filter",
|
"--filter",
|
||||||
f"label={_LABEL_APP}",
|
f"label={_LABEL_APP}",
|
||||||
|
|
@ -176,15 +181,17 @@ def _cmd_list(_args: argparse.Namespace) -> int:
|
||||||
|
|
||||||
|
|
||||||
def _cmd_stop(args: argparse.Namespace) -> int:
|
def _cmd_stop(args: argparse.Namespace) -> int:
|
||||||
engine = _engine()
|
cfg = _config.load()
|
||||||
name = args.name or _container_name(_resolve_ref(args.app, _config.load()))
|
engine = _engine(cfg, args.sudo)
|
||||||
return subprocess.call([engine, "stop", name])
|
name = args.name or _container_name(_resolve_ref(args.app, cfg))
|
||||||
|
return subprocess.call([*engine, "stop", name])
|
||||||
|
|
||||||
|
|
||||||
def _cmd_logs(args: argparse.Namespace) -> int:
|
def _cmd_logs(args: argparse.Namespace) -> int:
|
||||||
engine = _engine()
|
cfg = _config.load()
|
||||||
name = args.name or _container_name(_resolve_ref(args.app, _config.load()))
|
engine = _engine(cfg, args.sudo)
|
||||||
cmd = [engine, "logs"]
|
name = args.name or _container_name(_resolve_ref(args.app, cfg))
|
||||||
|
cmd = [*engine, "logs"]
|
||||||
if args.follow:
|
if args.follow:
|
||||||
cmd += ["-f"]
|
cmd += ["-f"]
|
||||||
cmd += [name]
|
cmd += [name]
|
||||||
|
|
@ -193,11 +200,19 @@ def _cmd_logs(args: argparse.Namespace) -> int:
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
parser = argparse.ArgumentParser(prog="ria-app")
|
parser = argparse.ArgumentParser(prog="ria-app")
|
||||||
|
parser.add_argument("--sudo", action="store_true", default=False, help="Run docker/podman via sudo")
|
||||||
sub = parser.add_subparsers(dest="command", required=True)
|
sub = parser.add_subparsers(dest="command", required=True)
|
||||||
|
|
||||||
p_cfg = sub.add_parser("configure", help="Set default registry/namespace")
|
p_cfg = sub.add_parser("configure", help="Set default registry/namespace")
|
||||||
p_cfg.add_argument("--registry", default=None, help="Default container registry (e.g. registry.riahub.ai)")
|
p_cfg.add_argument("--registry", default=None, help="Default container registry (e.g. registry.riahub.ai)")
|
||||||
p_cfg.add_argument("--namespace", default=None, help="Default namespace (e.g. qoherent)")
|
p_cfg.add_argument("--namespace", default=None, help="Default namespace (e.g. qoherent)")
|
||||||
|
p_cfg.add_argument(
|
||||||
|
"--sudo",
|
||||||
|
dest="sudo",
|
||||||
|
action=argparse.BooleanOptionalAction,
|
||||||
|
default=None,
|
||||||
|
help="Persist sudo default (--sudo / --no-sudo)",
|
||||||
|
)
|
||||||
|
|
||||||
p_pull = sub.add_parser("pull", help="Pull an app image")
|
p_pull = sub.add_parser("pull", help="Pull an app image")
|
||||||
p_pull.add_argument("app", help="App name or image reference")
|
p_pull.add_argument("app", help="App name or image reference")
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ _DEFAULT_PATH = Path(os.environ.get("RIA_TOOLKIT_CONFIG", str(Path.home() / ".ri
|
||||||
class AppConfig:
|
class AppConfig:
|
||||||
registry: str = ""
|
registry: str = ""
|
||||||
namespace: str = ""
|
namespace: str = ""
|
||||||
|
sudo: bool = False
|
||||||
|
|
||||||
|
|
||||||
def default_path() -> Path:
|
def default_path() -> Path:
|
||||||
|
|
@ -39,6 +40,7 @@ def load(path: Path | None = None) -> AppConfig:
|
||||||
return AppConfig(
|
return AppConfig(
|
||||||
registry=data.get("registry", "") or os.environ.get("RIA_REGISTRY", ""),
|
registry=data.get("registry", "") or os.environ.get("RIA_REGISTRY", ""),
|
||||||
namespace=data.get("namespace", "") or os.environ.get("RIA_NAMESPACE", ""),
|
namespace=data.get("namespace", "") or os.environ.get("RIA_NAMESPACE", ""),
|
||||||
|
sudo=bool(data.get("sudo", False)) or os.environ.get("RIA_DOCKER_SUDO", "") not in ("", "0", "false"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user