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() {