- 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
55 lines
1.8 KiB
Python
55 lines
1.8 KiB
Python
# actions/env.py
|
|
"""Export or synchronize synthesized APEX_* environment variables.
|
|
|
|
Outputs shell export statements (for `eval $(apex env)`) or writes a .env file
|
|
for direct compatibility with bare `docker compose` commands.
|
|
"""
|
|
import os
|
|
import shlex
|
|
from engine.descriptor import Flag, Meta, Opt
|
|
|
|
METADATA = Meta(
|
|
summary="Export or sync synthesized APEX_* variables for shell or docker compose.",
|
|
args=[
|
|
Flag("--export", "Format as shell export statements (default)."),
|
|
Flag("--dotenv", "Format as raw KEY=VAL lines without 'export'."),
|
|
Opt("--write", "Write variables to the specified file path.", default=None),
|
|
Flag("--sync", "Sync variables into compositions/apex/.env for bare docker compose."),
|
|
],
|
|
)
|
|
|
|
|
|
def run(ctx, args):
|
|
log = ctx.log
|
|
vars_dict = {k: v for k, v in ctx.vars().items() if k.startswith("APEX_")}
|
|
|
|
target_file = None
|
|
if args.sync:
|
|
target_file = os.path.join(ctx.paths.compositions, "apex", ".env")
|
|
elif args.write:
|
|
target_file = args.write
|
|
|
|
if target_file:
|
|
content = [
|
|
"# Generated by apex env. Do not edit directly.",
|
|
"# Contains synthesized node and path scalars for docker compose interpolation.",
|
|
]
|
|
for k in sorted(vars_dict.keys()):
|
|
content.append(f"{k}={vars_dict[k]}")
|
|
content.append("")
|
|
body = "\n".join(content)
|
|
|
|
os.makedirs(os.path.dirname(os.path.abspath(target_file)), exist_ok=True)
|
|
ctx.host.write_file(target_file, body, mode="0600")
|
|
log.success(f"Synced {len(vars_dict)} variables to {target_file}.")
|
|
return 0
|
|
|
|
if args.dotenv:
|
|
for k in sorted(vars_dict.keys()):
|
|
print(f"{k}={vars_dict[k]}")
|
|
else:
|
|
for k in sorted(vars_dict.keys()):
|
|
print(f"export {k}={shlex.quote(str(vars_dict[k]))}")
|
|
|
|
return 0
|