diff --git a/README.md b/README.md index 61fe7c6..b6c5263 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ sudo systemctl status vw-eu-data-act-exporter | `vins` | List of vehicle VINs to scrape | | `scrape_interval_minutes` | Poll interval per vehicle. The portal only delivers new datasets for "continuous" data requests roughly every ~15 min anyway - a shorter interval will not yield fresher data, but will increase the login frequency against the account | | `persist_raw_json` | `False` by default. When set to `True`, the JSON extracted from every downloaded dataset is written to disk (one file per VIN per scrape), including the JSON extracted from `_no_content_found.zip` placeholders when they carry one. ZIP files are never written to disk, only the extracted JSON - useful while tuning the field mapping in `vw-eu-data-act-exporter.py`. Not needed for normal operation | -| `persist_raw_json_dir` | Directory the raw JSON files are written to when `persist_raw_json` is enabled (default: `./raw_json`, relative to the working directory) | +| `persist_raw_json_dir` | Directory the raw JSON files are written to when `persist_raw_json` is enabled. Defaults to `$STATE_DIRECTORY` (set automatically by the systemd unit's `StateDirectory=vw-eu-data-act-exporter`, i.e. `/var/lib/vw-eu-data-act-exporter`), falling back to `./raw_json` for ad-hoc/local runs outside systemd | Prerequisite in the portal (one-time, in a browser): connect vehicle -> "Get customised data" -> enable continuous, 15-minute frequency (see the @@ -136,3 +136,11 @@ be independent of, and significantly shorter than, `scrape_interval_minutes` - `WARNING ... Unknown enum value`: a new, not-yet-listed value for an enum metric - the state is exported as `UNKNOWN`, extend the list in the source code if needed. +- Service fails immediately with `status=226/NAMESPACE` / + `Failed to set up mount namespacing`: usually a stale unit file from + before `StateDirectory=` was introduced (e.g. still using + `ReadWritePaths=.../raw_json` pointing at a directory that was never + created). Re-copy the current `vw-eu-data-act-exporter.service`, run + `sudo systemctl daemon-reload`, and restart - `StateDirectory=` makes + systemd create that directory (with correct ownership) itself, no manual + `mkdir`/`chown` needed. diff --git a/config.py b/config.py index ef11a60..9c3c2a5 100644 --- a/config.py +++ b/config.py @@ -48,7 +48,10 @@ scrape_interval_minutes = 15 # carry one. ZIP files themselves are never written to disk. Disabled by # default, since the exporter is designed to be stateless (see README.md). persist_raw_json = False -persist_raw_json_dir = "./raw_json" +# Under the systemd unit, StateDirectory=vw-eu-data-act-exporter makes +# systemd export $STATE_DIRECTORY (an already-created, correctly-owned +# directory) - fall back to a relative path for ad-hoc/local runs. +persist_raw_json_dir = os.environ.get("STATE_DIRECTORY", "./raw_json") # --- Logging --------------------------------------------------------------- log_level = "INFO" diff --git a/vw-eu-data-act-exporter.service b/vw-eu-data-act-exporter.service index 8cdf2e1..7362885 100644 --- a/vw-eu-data-act-exporter.service +++ b/vw-eu-data-act-exporter.service @@ -13,7 +13,13 @@ Restart=on-failure RestartSec=30 # Hardening -ReadWritePaths=/opt/vw-eu-data-act-exporter/raw_json +# StateDirectory is created automatically (with correct ownership) before +# the service starts and is writable under ProtectSystem=strict without a +# ReadWritePaths= entry - systemd exposes its absolute path via +# $STATE_DIRECTORY, which config.py picks up for persist_raw_json_dir. +# Unlike ReadWritePaths=, this does not require the directory to already +# exist on disk. +StateDirectory=vw-eu-data-act-exporter NoNewPrivileges=true ProtectSystem=strict ProtectHome=true