From 25d7a522cc336e0d851397245f92518328e77431 Mon Sep 17 00:00:00 2001 From: Paul Payne Date: Thu, 16 Jul 2026 21:25:47 -0700 Subject: [PATCH] core: write job secret env files with the -job unit suffix A job's systemd unit is castle--job.service and its EnvironmentFile points at castle--job.service.env, but _write_secret_env_file wrote castle-.service.env (kind defaulted to 'service'). Every secret-using job failed to start (Failed to load environment files). Thread the deployment kind through to secret_env_path so the filename matches the unit. --- core/src/castle_core/deploy.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/core/src/castle_core/deploy.py b/core/src/castle_core/deploy.py index fdf81e0..2093ff7 100644 --- a/core/src/castle_core/deploy.py +++ b/core/src/castle_core/deploy.py @@ -745,15 +745,21 @@ def _env_context( return ctx -def _write_secret_env_file(name: str, secret_env: dict[str, str]) -> Path | None: +def _write_secret_env_file( + name: str, secret_env: dict[str, str], kind: str = "service" +) -> Path | None: """Write a deployment's resolved secrets to a mode-0600 env file. Keeps secrets out of the generated unit file and the process argv: systemd loads it via ``EnvironmentFile=`` and docker via ``--env-file``. Returns the path, or ``None`` (after removing any stale file) when there are no secrets, so a service that drops its last secret doesn't leave a dangling file. + + ``kind`` must match the unit's kind so the filename lines up with the unit's + ``EnvironmentFile=`` (jobs carry a ``-job`` marker); otherwise systemd looks + for a file that was never written and the unit fails to start. """ - path = secret_env_path(name) + path = secret_env_path(name, kind) if not secret_env: path.unlink(missing_ok=True) return None @@ -899,7 +905,7 @@ def _build_deployed( } ) env, secret_env = resolve_env_split(raw_env, ctx) - secret_env_file = _write_secret_env_file(name, secret_env) + secret_env_file = _write_secret_env_file(name, secret_env, kind) # `command` launchers resolve a tool on PATH → ensure it's installed. # `python` launchers run in place via `uv run` (below) — no tool venv.