FiWiManager/fiwi/config.py

81 lines
2.8 KiB
Python

"""Load ``config/*.ini`` profiles into the environment (``setdefault``; shell and dotenv win)."""
from __future__ import annotations
import configparser
import os
from typing import Optional
def _resolve_config_path(app_dir: str) -> Optional[str]:
"""
Pick the INI file under ``<app_dir>/config/``.
* ``FIWI_CONFIG`` — profile name (``uax24`` → ``config/uax24.ini``) or absolute ``*.ini`` path.
* If unset — ``config/default.ini`` when that file exists.
"""
raw = (os.environ.get("FIWI_CONFIG") or "").strip()
cfg_root = os.path.join(app_dir, "config")
if raw:
if os.path.isabs(raw) and os.path.isfile(raw):
return raw
base = raw[:-4] if raw.lower().endswith(".ini") else raw
candidate = os.path.join(cfg_root, f"{base}.ini")
if os.path.isfile(candidate):
return candidate
return None
default = os.path.join(cfg_root, "default.ini")
if os.path.isfile(default):
return default
return None
def resolved_config_path(app_dir: str) -> Optional[str]:
"""Absolute path to the active profile INI, or ``None`` if none applies."""
return _resolve_config_path(app_dir)
def apply_config_ini(app_dir: str) -> None:
"""
Merge one profile INI into ``os.environ`` (only keys not already set).
Precedence: process environment, then ``remote_ssh.env`` (already applied in
:func:`fiwi.paths.configure`), then this file, then code defaults.
"""
path = _resolve_config_path(app_dir)
if not path:
return
parser = configparser.ConfigParser(interpolation=None)
try:
parser.read(path, encoding="utf-8")
except configparser.Error:
return
def setdefault(section: str, option: str, env_key: str) -> None:
if not parser.has_section(section):
return
if not parser.has_option(section, option):
return
val = parser.get(section, option, fallback="").strip()
if val:
os.environ.setdefault(env_key, val)
setdefault("paths", "fiber_map", "FIWI_FIBER_MAP")
setdefault("patch_panel", "default_ports", "FIWI_DEFAULT_PANEL_PORTS")
setdefault("remote_ssh", "remote_python", "FIWI_REMOTE_PYTHON")
setdefault("remote_ssh", "remote_script", "FIWI_REMOTE_SCRIPT")
setdefault("remote_ssh", "ssh_bin", "FIWI_SSH_BIN")
setdefault("remote_ssh", "ssh_opts", "FIWI_SSH_OPTS")
setdefault("remote_ssh", "calibrate_remotes", "FIWI_CALIBRATE_REMOTES")
setdefault("remote_hubs", "hosts", "FIWI_REMOTE_HUBS")
setdefault("remote_hubs", "label", "FIWI_REMOTE_HUB_LABEL")
if parser.has_section("remote_ssh") and parser.has_option("remote_ssh", "remote_defer"):
v = parser.get("remote_ssh", "remote_defer", fallback="").strip().lower()
if v in ("1", "true", "yes", "on"):
os.environ.setdefault("FIWI_REMOTE_DEFER", "1")