Files
apex.ermnvldmr.com/engine/cli.py
T
deytenit 6463bad5ee feat(engine): de-slop commons, harden security, add targeted compose and env bridge
- Purge misplaced RFCs, scratch tokens, and node-proprietary assets
- Decouple remote provisioning to ci/scripts/init-node.py
- Add targeted composition orchestration in actions/compose.py
- Add host-side Xray stale socket cleanup in /dev/shm
- Add actions/env.py for shell exports and .env synchronization
- Harden UFW, backup retention, host tempfiles, and notify dispatcher
- Add pyproject.toml and Makefile with 78 passing unit tests
2026-10-26 00:03:33 +03:00

77 lines
2.8 KiB
Python

# engine/cli.py
"""apex CLI: list / dispatch / help. Acts on the local checkout (no <node> arg)."""
from __future__ import annotations
import os
import socket
import sys
from engine import overlay
from engine.identity import resolve
from engine.context import Context, Paths
from engine.descriptor import build_parser, Meta
def _resolve_layout():
commons_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
parent = os.path.dirname(commons_dir)
cwd = os.getcwd()
if os.path.isfile(os.path.join(parent, "node.env")):
repo_root = parent
prop_actions = os.path.join(repo_root, "proprietaries", "actions")
return commons_dir, repo_root, prop_actions, True
if os.path.isfile(os.path.join(cwd, "node.env")):
repo_root = cwd
prop_actions = os.path.join(repo_root, "proprietaries", "actions")
return commons_dir, repo_root, prop_actions, True
return commons_dir, commons_dir, None, False
def _print_list(commons_actions, prop_actions):
print("Usage: apex <group>/<action> [args...]\n\nAvailable actions:")
tag = {"commons": "", "local": " (local)", "override": " (local override)"}
for i in overlay.discover(commons_actions, prop_actions):
mark = f" [DISABLED: {i.disabled}]" if i.disabled else ""
print(f" {i.name:<34} {i.summary}{tag[i.source]}{mark}")
def main(argv) -> int:
commons_dir, repo_root, prop_actions, is_node = _resolve_layout()
commons_actions = os.path.join(commons_dir, "actions")
if not argv or argv[0] in ("--help", "-h"):
_print_list(commons_actions, prop_actions)
return 0
name, rest = argv[0], argv[1:]
r = overlay.resolve(name, commons_actions, prop_actions)
if r is None:
sys.stderr.write(f"[global] [core] [ERROR] Unknown action: {name}\n")
return 1
node, warns = (resolve(socket.getfqdn(), repo_root) if is_node else (None, []))
ctx = Context(node, Paths(repo_root, commons_dir), name, shadowed=r.shadowed)
for w in warns:
ctx.log.warn(w)
modname = "apex_action_" + name.replace("/", "_").replace("-", "_")
mod = overlay.load_module(r.path, modname)
disabled = getattr(mod, "DISABLED", None)
if disabled:
reason = disabled if isinstance(disabled, str) else "disabled"
ctx.log.error(f"Action {name} is disabled: {reason}")
return 1
meta = getattr(mod, "METADATA", Meta(summary=""))
args = build_parser(meta, f"apex {name}").parse_args(rest) # --help & EX_USAGE handled here
try:
rc = mod.run(ctx, args)
return int(rc) if isinstance(rc, int) else 0
except SystemExit as e:
return e.code if isinstance(e.code, int) else 1
except Exception as e: # map to general error, log with context prefix
ctx.log.error(f"{type(e).__name__}: {e}")
return 1