From 2251c7ca6dbb811bdef3603e6a12f2e050402f8a Mon Sep 17 00:00:00 2001 From: Lukas Remis Date: Thu, 17 Sep 2026 20:52:21 +0200 Subject: [PATCH] Deploy: set_env_value could not add a key, and said it had MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `sed "s|^KEY=.*|KEY=value|"` only rewrites a line that already exists. A setting introduced by a later release is absent from an older .env, so the substitution matched nothing, reported success, and the value vanished — while `ensure_secrets` printed "RSPAMD_CONTROLLER_PASSWORD was empty — generated one". The v1.1.0 upgrade then ran with a blank controller password: every compose call warned, the engine came up unauthenticated, and learning would have failed against it. Classification was unaffected, which is exactly what made it quiet. Now appends when the key is absent — ensuring the file ends in a newline first, so the key cannot be glued onto the last line of a hand-edited .env — and verifies the value is present afterwards rather than trusting sed's exit status. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018SqJYt7jD7oUEkoY68sBZo --- deploy/webmail.sh | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/deploy/webmail.sh b/deploy/webmail.sh index 6267cdb..e6a09f8 100755 --- a/deploy/webmail.sh +++ b/deploy/webmail.sh @@ -129,8 +129,24 @@ state_dir() { echo "${DATA_ROOT}/state"; } # in-place edit goes through a temp file. set_env_value() { local key="$1" value="$2" - sed "s|^${key}=.*|${key}=${value}|" "$ENV_FILE" > "${ENV_FILE}.tmp" \ - && mv "${ENV_FILE}.tmp" "$ENV_FILE" && chmod 600 "$ENV_FILE" + if grep -q "^${key}=" "$ENV_FILE" 2>/dev/null; then + sed "s|^${key}=.*|${key}=${value}|" "$ENV_FILE" > "${ENV_FILE}.tmp" \ + && mv "${ENV_FILE}.tmp" "$ENV_FILE" + else + # A key introduced by a later release is simply absent from an older + # .env, and `sed s|^KEY=.*|` substitutes nothing while reporting success + # — so a generated secret was announced and then silently dropped. Append + # instead, after making sure the file ends in a newline so the new key + # cannot be glued onto the last line. + if [ -s "$ENV_FILE" ] && [ -n "$(tail -c1 "$ENV_FILE")" ]; then + printf '\n' >> "$ENV_FILE" + fi + printf '%s=%s\n' "$key" "$value" >> "$ENV_FILE" + fi + chmod 600 "$ENV_FILE" + # Never report success for a value that did not land: this function silently + # dropped a generated secret once, and the install only failed much later. + grep -q "^${key}=" "$ENV_FILE" || die "failed to write ${key} to ${ENV_FILE}" } record_version() {