fix(rust): read .env like python-dotenv; dry run in the service environment
CI / Format & lint (push) Successful in 18s
CI / Test suite (push) Successful in 45s
Rust / fmt, clippy, test, build (push) Successful in 7m4s

dotenvy aborted on the production .env (a quote in an unquoted value makes it
read to the end of the file) and echoed the offending line, password
included. envfile.rs ports python-dotenv 1.1.1 (parser + ${VAR} interpolation,
no override): unparsable statements are skipped with a warning that names only
the line number. Verified against python-dotenv on 614 generated inputs
(testdata/). The .env is loaded before the tokio runtime starts.

install_collector.sh now runs the dry run through systemd-run with the unit's
User, WorkingDirectory and EnvironmentFile, i.e. exactly what the service sees.
This commit is contained in:
grabowski committed 2026-10-17 22:58:12 +07:00
1 parent 63353f1e80
commit c8e89840b5
9 files changed
+7456 -12

No files matched your search

+12 -2
View File
@@ -17,6 +17,7 @@
set -euo pipefail
APP_DIR="${APP_DIR:-/opt/thailand-water-monitor}"
SERVICE_USER="${SERVICE_USER:-water-monitor}" # as in scripts/ping-collector.service
ENV_FILE="${APP_DIR}/.env"
STATUS_FILE="${APP_DIR}/collector-status.json"
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
@@ -59,10 +60,19 @@ systemctl daemon-reload
# the app dir: the units use PrivateTmp).
set_env SCRAPING_STATUS_FILE "$STATUS_FILE"
touch "$STATUS_FILE"
chown "$(stat -c %U:%G "$APP_DIR")" "$STATUS_FILE"
chown "${SERVICE_USER}:$(id -gn "$SERVICE_USER")" "$STATUS_FILE"
log "Dry run against the configured database (writes nothing)"
(cd "$APP_DIR" && "${APP_DIR}/bin/ping-collector" --env-file "$ENV_FILE" once --dry-run)
# Run it the way the service will: same user, working directory and
# EnvironmentFile parsing (systemd's, not a .env library's).
if systemd-run --version >/dev/null 2>&1; then
systemd-run --quiet --pipe --wait --collect \
-p User="$SERVICE_USER" -p Group="$(id -gn "$SERVICE_USER")" \
-p WorkingDirectory="$APP_DIR" -p EnvironmentFile="$ENV_FILE" \
"${APP_DIR}/bin/ping-collector" once --dry-run
else
(cd "$APP_DIR" && "${APP_DIR}/bin/ping-collector" --env-file "$ENV_FILE" once --dry-run)
fi
if [ "$MODE" = "--cutover" ]; then
log "Cutover: ping-collector collects, the Python app forecasts and notifies"