98 lines
3.1 KiB
Python
98 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
||
"""从 /opt/live/config(或 LIVE_CONFIG_ROOT)JSON 配置生成 system-stack.env,供现有 service_ctl / install 脚本读取。"""
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
import os
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
|
||
def config_root() -> Path:
|
||
env = os.environ.get("LIVE_CONFIG_ROOT", "").strip()
|
||
if env:
|
||
return Path(env)
|
||
if Path("/opt/live/config/system.json").is_file():
|
||
return Path("/opt/live/config")
|
||
here = Path(__file__).resolve()
|
||
return here.parent.parent / "config" / "defaults"
|
||
|
||
|
||
def load_json(path: Path) -> dict:
|
||
if not path.is_file():
|
||
return {}
|
||
return json.loads(path.read_text(encoding="utf-8"))
|
||
|
||
|
||
def collect_env(root: Path) -> dict[str, str]:
|
||
lines: dict[str, str] = {}
|
||
|
||
sys_j = load_json(root / "system.json")
|
||
web = sys_j.get("web_console") or {}
|
||
ident = sys_j.get("identity") or {}
|
||
if ident.get("hostname_alias"):
|
||
lines["HOSTNAME_ALIAS"] = str(ident["hostname_alias"])
|
||
if web.get("api_port") is not None:
|
||
lines["PORT"] = str(web["api_port"])
|
||
|
||
net = load_json(root / "network.json")
|
||
wifi = net.get("wifi") or {}
|
||
if wifi.get("connection_name"):
|
||
lines["WIFI_CONNECTION_NAME"] = str(wifi["connection_name"])
|
||
if wifi.get("ssid"):
|
||
lines["WIFI_SSID"] = str(wifi["ssid"])
|
||
if wifi.get("psk"):
|
||
lines["WIFI_PSK"] = str(wifi["psk"])
|
||
if net.get("ipv6", {}).get("disable"):
|
||
lines["DISABLE_IPV6"] = "1"
|
||
|
||
svc_dir = root / "services"
|
||
if svc_dir.is_dir():
|
||
for f in sorted(svc_dir.glob("*.json")):
|
||
data = load_json(f)
|
||
env = data.get("env") or {}
|
||
if not isinstance(env, dict):
|
||
continue
|
||
for k, v in env.items():
|
||
if v is not None and str(v) != "":
|
||
lines[str(k)] = str(v)
|
||
|
||
ports = {}
|
||
if svc_dir.is_dir():
|
||
for f in sorted(svc_dir.glob("*.json")):
|
||
data = load_json(f)
|
||
pid = data.get("id") or f.stem
|
||
pr = data.get("ports") or {}
|
||
if isinstance(pr, dict) and "http" in pr:
|
||
ports[pid] = pr["http"]
|
||
# 固定映射:homepage 使用 HOMEPAGE_PORT
|
||
if "homepage" in ports:
|
||
lines.setdefault("HOMEPAGE_PORT", str(ports["homepage"]))
|
||
|
||
lines.setdefault("ENABLE_MDNS", "1")
|
||
lines.setdefault("ENABLE_WIFI_PROFILE", "1")
|
||
lines.setdefault("ENABLE_BROWSER", "1")
|
||
lines.setdefault("ENABLE_COCKPIT", "1")
|
||
return lines
|
||
|
||
|
||
def main() -> int:
|
||
root = config_root()
|
||
out = Path(os.environ.get("LIVE_ENV_OUT", "/opt/live/generated/system-stack.env"))
|
||
if len(sys.argv) > 1:
|
||
out = Path(sys.argv[1])
|
||
lines = collect_env(root)
|
||
out.parent.mkdir(parents=True, exist_ok=True)
|
||
body = "\n".join(f"{k}={v}" for k, v in sorted(lines.items())) + "\n"
|
||
out.write_text(
|
||
"# Generated by live-platform/tools/render_stack_env.py — do not hand-edit\n" + body,
|
||
encoding="utf-8",
|
||
)
|
||
# 开发树:可选同步到仓库 config(由 install 脚本 ln -sf)
|
||
print(str(out))
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
raise SystemExit(main())
|