Skip to content

fix(nix): maintenance and backup scripts fail with non-default postgres.user due to peer auth #5533

Description

@JakobLichterfeld

What happened?

The NixOS maintenance scripts teslamate-delete-drive and teslamate-delete-charge (nix/maintenance.nix) connect with:

sudo -u teslamate psql -U ${databaseUser} -d ${databaseName}

With a local PostgreSQL, this relies on peer authentication: the OS user (teslamate, hardcoded) must match the database role. If services.teslamate.postgres.user is set to anything other than "teslamate", peer auth rejects the connection and the scripts fail. It also means the scripts cannot work against an external database server at all.

This is pre-existing behavior, but since #5337 the module explicitly distinguishes between the default role name (socket + peer auth) and other role names (TCP + password fallback), which makes the asymmetry more visible: TeslaMate itself handles a non-default role name fine, the delete scripts do not. Noted during review in #5337 and deliberately kept out of that PR to avoid scope creep.

The closeDrive/closeCharge scripts are not affected: they go through the running Elixir release (teslamate rpc, authenticated via RELEASE_COOKIE), not psql.

The same limitation applies to teslamate-backup and teslamate-restore (nix/backup_and_restore.nix), which use sudo -u teslamate pg_dump/psql -U ${databaseUser}.
The restore script's psql invocations additionally run without -v ON_ERROR_STOP=1, so individual failing statements (e.g. CREATE EXTENSION) do not abort the script.

Preferred solution: route deletes through the release, like the close scripts

The delete scripts only do an existence check plus DELETE FROM drives/charging_processes WHERE id = X. That maps directly onto teslamate rpc with TeslaMate.Repo, e.g.:

teslamate rpc "TeslaMate.Repo.get!(TeslaMate.Log.Drive, ID) |> TeslaMate.Repo.delete!()"

This reuses the app's own database configuration (socket or TCP, any role name, external servers, no superuser), removes the psql/peer-auth dependency entirely, and makes all four maintenance scripts consistent. Repo.get! also gives the existence check for free. Ideally the delete goes through proper functions in TeslaMate.Log rather than raw Repo calls in the rpc string.

Trade-off: requires the TeslaMate service to be running (like the close scripts already do), whereas psql only needed the database.

Alternatives considered

  1. sudo -u postgres psql: works for any role name, but keeps the scripts local-only and switches to superuser semantics.
  2. TCP + PGPASSWORD via the loadFromEnvFile helper from refactor(nix,postgres): provision database declaratively, connect via socket #5337: covers external servers, but puts the password into the psql process environment.
  3. Document the limitation only.

Expected Behavior

Maintenance scripts work regardless of the configured services.teslamate.postgres.user, including against external database servers.

🤖 Issue drafted with Claude Code (Fable 5 high) — sponsored by Claude for Open Source

Metadata

Metadata

Labels

enhancementNew feature or requestnixreleated to nix flake

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions