Add update-vendor.sh symlink support, unify install.sh vendor flow
- update-vendor.sh now creates webui/vendor symlinks (htm.js) - install.sh calls update-vendor.sh after package install - Add vendor/.empty and webui/vendor/.empty as directory placeholders in git
This commit is contained in:
+45
-19
@@ -5,8 +5,6 @@ state instead of invoking subprocesses on every request.
|
||||
"""
|
||||
|
||||
import contextlib
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from copy import deepcopy
|
||||
@@ -14,7 +12,7 @@ from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from typing import Any, ClassVar
|
||||
|
||||
from lib.common import load_json, run, run_proc
|
||||
from lib.common import _APPLY_HASH_KEY, config_hash, load_json, run, run_proc
|
||||
from lib.firewall import (
|
||||
_parse_active_zones,
|
||||
_parse_all_zones_output,
|
||||
@@ -590,18 +588,13 @@ def _collect_dnsmasq() -> dict[str, Any]:
|
||||
# Check config file on disk
|
||||
conf_exists = Path(DNSMASQ_CONF).is_file()
|
||||
|
||||
# Check if JSON config has changed since last apply
|
||||
_APPLY_HASH_KEY = "_last_applied_hash"
|
||||
pending_changes = True
|
||||
if _APPLY_HASH_KEY in cfg:
|
||||
clean = {k: v for k, v in cfg.items() if k != _APPLY_HASH_KEY}
|
||||
current_hash = hashlib.sha256(
|
||||
json.dumps(clean, sort_keys=True).encode()
|
||||
).hexdigest()
|
||||
pending_changes = cfg[_APPLY_HASH_KEY] != current_hash
|
||||
pending_changes = _APPLY_HASH_KEY not in cfg or cfg[_APPLY_HASH_KEY] != config_hash(
|
||||
cfg
|
||||
)
|
||||
|
||||
safe_cfg = {k: v for k, v in cfg.items() if k != _APPLY_HASH_KEY}
|
||||
return {
|
||||
"config": cfg,
|
||||
"config": safe_cfg,
|
||||
"status": {
|
||||
"service_active": service_active,
|
||||
"config_file_exists": conf_exists,
|
||||
@@ -684,9 +677,15 @@ def _collect_nginx() -> dict[str, Any]:
|
||||
entry["is_websocket"] = True
|
||||
domains.append(entry)
|
||||
|
||||
pending_changes = _APPLY_HASH_KEY not in cfg or cfg[_APPLY_HASH_KEY] != config_hash(
|
||||
cfg
|
||||
)
|
||||
|
||||
safe_cfg = {k: v for k, v in cfg.items() if k != _APPLY_HASH_KEY}
|
||||
return {
|
||||
"config": cfg,
|
||||
"config": safe_cfg,
|
||||
"domains": domains,
|
||||
"status": {"pending_changes": pending_changes},
|
||||
"timestamp": _now_iso(),
|
||||
}
|
||||
|
||||
@@ -918,8 +917,12 @@ def _collect_wireguard() -> dict[str, Any]:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Safe config (strip private key)
|
||||
safe = dict(cfg)
|
||||
pending_changes = _APPLY_HASH_KEY not in cfg or cfg[_APPLY_HASH_KEY] != config_hash(
|
||||
cfg
|
||||
)
|
||||
|
||||
# Safe config (strip private key and internal hash)
|
||||
safe = {k: v for k, v in cfg.items() if k != _APPLY_HASH_KEY}
|
||||
if "interface" in safe:
|
||||
safe["interface"] = dict(safe["interface"])
|
||||
safe["interface"].pop("private_key", None)
|
||||
@@ -1000,6 +1003,7 @@ def _collect_wireguard() -> dict[str, Any]:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
status["pending_changes"] = pending_changes
|
||||
return {
|
||||
"config": safe,
|
||||
"status": status,
|
||||
@@ -1029,24 +1033,46 @@ def _collect_networkd() -> dict[str, Any]:
|
||||
"""Collect networkd interface state from networkctl.
|
||||
|
||||
Returns:
|
||||
Dict with interface runtime state parsed from networkctl output.
|
||||
Returns empty data if networkctl is not available.
|
||||
Dict with interface runtime state parsed from networkctl output,
|
||||
config, and pending changes status.
|
||||
"""
|
||||
CONFIG_PATH = PROJECT_DIR / "config" / "network" / "config.json"
|
||||
|
||||
# Load config
|
||||
net_cfg: dict[str, Any] = {}
|
||||
if CONFIG_PATH.exists():
|
||||
with contextlib.suppress(Exception):
|
||||
net_cfg = load_json(CONFIG_PATH)
|
||||
|
||||
pending_changes = _APPLY_HASH_KEY not in net_cfg or net_cfg[
|
||||
_APPLY_HASH_KEY
|
||||
] != config_hash(net_cfg)
|
||||
|
||||
result: dict[str, dict[str, Any]] = {}
|
||||
safe_net_cfg = {k: v for k, v in net_cfg.items() if k != _APPLY_HASH_KEY}
|
||||
|
||||
try:
|
||||
raw = run(["networkctl", "status", "--json=short", "--all"], sudo=True)
|
||||
result = parse_networkctl_status(raw)
|
||||
if not result:
|
||||
return {"interfaces": {}, "timestamp": _now_iso()}
|
||||
return {
|
||||
"interfaces": {},
|
||||
"config": safe_net_cfg,
|
||||
"status": {"pending_changes": pending_changes},
|
||||
"timestamp": _now_iso(),
|
||||
}
|
||||
except Exception:
|
||||
return {
|
||||
"interfaces": {},
|
||||
"config": safe_net_cfg,
|
||||
"status": {"pending_changes": pending_changes},
|
||||
"timestamp": _now_iso(),
|
||||
}
|
||||
|
||||
return {
|
||||
"interfaces": result,
|
||||
"config": safe_net_cfg,
|
||||
"status": {"pending_changes": pending_changes},
|
||||
"timestamp": _now_iso(),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user