V6.1 continue beating on the backup
Quality Gate / gate (push) Failing after 2m34s

This commit is contained in:
Jim Lancaster
2026-09-02 10:04:38 -05:00
parent 75dc946123
commit 494f378e48
6 changed files with 124 additions and 29 deletions
+1 -1
View File
@@ -711,7 +711,7 @@ def register_page(*, settings: Settings) -> None: # noqa: PLR0915
with ui.column().classes("w-full max-w-3xl mx-auto gap-2 mt-3"):
ui.label("Other settings not shown here").classes("text-sm font-semibold")
ui.label("Edit these directly in .env:").classes("text-xs ui-text-muted")
ui.label(f"Edit these directly in {snapshot.env_file_path}:").classes("text-xs ui-text-muted")
table_rows = [
f"| {category.title} | {', '.join(f'`{key}`' for key in category.env_keys)} |"
for category in HIDDEN_SETTINGS_CATEGORIES
+64 -17
View File
@@ -84,6 +84,29 @@ HIDDEN_SETTINGS_CATEGORIES: tuple[HiddenSettingsCategory, ...] = (
"DATABASE__USER",
),
),
HiddenSettingsCategory(
title="Deployment and backup/tunnel helpers (not Runtime Settings model fields)",
reason=(
"These keys are consumed by docker-compose, backup scripts, or deployment adapters and are "
"intentionally edited outside the Runtime Settings UI."
),
env_keys=(
"POSTGRES_DB",
"POSTGRES_USER",
"POSTGRES_PASSWORD",
"POSTGRES_HOST",
"POSTGRES_PORT",
"CLOUDFLARE_TUNNEL_TOKEN",
"RUNTIME_SETTINGS_ENV_FILE",
"BACKUP_DIR",
"APP_DATA_BACKUP_DIR",
"UPLOADS_BACKUP_DIR",
"BACKUP_RETENTION_DAYS",
"SYNOLOGY_BACKUP_DIR",
"ENV_FILE",
"COMPOSE_FILE",
),
),
)
RUNTIME_SETTINGS_CATALOG: tuple[RuntimeSettingDescriptor, ...] = (
@@ -358,7 +381,15 @@ def save_runtime_settings(
env_map[descriptor.env_key] = encoded
_validate_candidate_env(env_map=env_map, env_file_path=resolved_env_path)
_write_env_lines_atomic(path=resolved_env_path, lines=mutable_lines)
try:
_write_env_lines_atomic(path=resolved_env_path, lines=mutable_lines)
except OSError as exc:
raise AppError(
"Runtime settings file is not writable.",
category=ErrorCategory.INFRA_PERSISTENT,
suggestion="Verify file path and write permissions, then retry.",
detail=f"Failed writing runtime env file {resolved_env_path}: {type(exc).__name__}: {exc}",
) from exc
refreshed = Settings(_env_file=resolved_env_path, _cli_parse_args=False)
return read_runtime_settings_snapshot(settings=refreshed, env_file_path=resolved_env_path)
@@ -438,7 +469,15 @@ def _validate_candidate_env(*, env_map: dict[str, str], env_file_path: Path) ->
def _read_env_lines(path: Path) -> list[str]:
if not path.exists():
return []
return path.read_text(encoding="utf-8").splitlines()
try:
return path.read_text(encoding="utf-8").splitlines()
except OSError as exc:
raise AppError(
"Runtime settings file is unreadable.",
category=ErrorCategory.INFRA_PERSISTENT,
suggestion="Verify file path and read permissions, then retry.",
detail=f"Failed reading runtime env file {path}: {type(exc).__name__}: {exc}",
) from exc
def _parse_env_map(lines: list[str]) -> dict[str, str]:
@@ -485,21 +524,29 @@ def _upsert_env_key(lines: list[str], key: str, value: str) -> None:
def _write_env_lines_atomic(*, path: Path, lines: list[str]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
content = "\n".join(lines).rstrip("\n")
if content:
content += "\n"
with tempfile.NamedTemporaryFile(
mode="w",
delete=False,
dir=path.parent,
encoding="utf-8",
newline="\n",
suffix=".env.tmp",
) as handle:
temp_path = Path(handle.name)
handle.write(content)
temp_path.replace(path)
try:
path.parent.mkdir(parents=True, exist_ok=True)
content = "\n".join(lines).rstrip("\n")
if content:
content += "\n"
with tempfile.NamedTemporaryFile(
mode="w",
delete=False,
dir=path.parent,
encoding="utf-8",
newline="\n",
suffix=".env.tmp",
) as handle:
temp_path = Path(handle.name)
handle.write(content)
temp_path.replace(path)
except OSError as exc:
raise AppError(
"Runtime settings file is not writable.",
category=ErrorCategory.INFRA_PERSISTENT,
suggestion="Verify file path and write permissions, then retry.",
detail=f"Failed writing runtime env file {path}: {type(exc).__name__}: {exc}",
) from exc
def _escape_json_string(value: str) -> str: