Commit Graph

9 Commits

Author SHA1 Message Date
cinereal
639d4f74e5 lib/services/service: pin flag ordering relative to argv
`attrListWith` re-emits every flag as an `lib.mkOrder` definition, so `argv` and
`flags` share one ordering space. Unadorned flags arrived at
`lib.modules.defaultOrderPriority`, the same priority as unadorned `argv`, and
only landed after `argv` because the declaring module's `config` happened to be
collected last.

Give flags that carry no ordering property of their own a priority of 1250,
between `lib.modules.defaultOrderPriority` and `lib.mkAfter`. Plain flags now
provably follow plain `argv`, `lib.mkAfter` on `argv` still places trailing
positional arguments after the flags, and an explicit `lib.mkOrder` on a flag is
honoured verbatim, which is what interleaving a sub-command among flags needs.

Also render path flag values through `pathOrStr`. `lib.cli.toCommandLine`
formats values with `lib.generators.mkValueStringDefault`, which has no case for
paths and aborts; coercing first yields the store path, matching `argv`.

Assisted-by: Claude:claude-opus-5
2026-07-26 17:02:34 +02:00
lassulus
85f295f566 lib/services/service: add flags and flagFormat options
Add `process.flags` for declarative command-line flag generation
using `lib.cli.toCommandLine`, with per-flag ordering via valueMeta.
Add `process.flagFormat` to control flag rendering.
2026-07-26 16:48:41 +02:00
K900
ec69cf3f7b Revert "nixos/modular-services: add portable process.environment" 2026-07-25 10:19:30 +03:00
Robert Hensing
541a6f371f nixos/modular-services: add portable process.environment (#518860) 2026-07-24 17:40:13 +00:00
cinereal
ae9994806c lib/services: fix reload/readiness bugs and add compliance coverage
Fixes several correctness bugs primarily around modular services' recent
reload/notification options (#535695) and adds compliance coverage to guard them.

Fixes:

- `lib/services/service.nix`:
  - the reload-conflict assertion had inverted polarity, so it fired on the
    default configuration
  - the `mkIf` guard on `process.reloadCommand` had a misplaced paren, applying
    `!= null` to the `mkIf` result rather than to the condition
  - `process.reloadSignal` derives `process.reloadCommand`, so the assertion
    could not check `reloadCommand != null` -- that fired on every signal-only
    service. The command is now derived at `mkDefault` priority and the
    assertion is gated on `options.process.reloadCommand.highestPrio`, firing
    only when the user also set `reloadCommand` explicitly.
  - change `notificationProtocol` to a sub-module type
- `nixos/modules/system/service/systemd/service.nix`:
  - `systemd.mainExecReload`'s default ran `escapeSystemdExecArgs` (a list
    escaper) on the `nullOr str` `process.reloadCommand`; this threw
    `expected a list but found a string` and would have mangled `$MAINPID`. It
    now uses `process.reloadCommand` verbatim.
  - the `Type` default read a non-existent
    `config.serviceManager.notificationProtocol` instead of
    `config.notificationProtocol`.

Tests:

Extend the modular-service compliance suite to guard the above:

- Portable (manager-agnostic) eval assertions: `reloadSignal` derives
  `reloadCommand`, the conflict assertion does not fire on signal-only services
  but does when both are set explicitly, and `notificationProtocol.systemd`/`.s6`
  default to `false`.
- systemd-specific eval assertions: `serviceConfig.Type` (simple/notify) and
  `serviceConfig.ExecReload` are asserted on the resolved host units. This
  directly guards the `mainExecReload` fix, which threw before it.
- Runtime reload compliance test: a nested reloadable sub-service is started and
  reloaded, asserting the service observed the reload (recorded a SIGHUP marker).
  `callReload` receives the service's name path (the list of names from the
  top-level service down to the target sub-service); each integration joins it
  per its own unit-naming convention (NixOS dash-joins to the systemd unit name,
  e.g. `reload-inner.service`). Keeping it a path list rather than a read-only
  submodule option keeps the suite manager-agnostic.
- `doc/build-helpers/testers.chapter.md`: document `callReload`.

Follow-up to #535695.

Signed-off-by: cinereal <cinereal@riseup.net>
Assisted-by: Claude:claude-opus-4-8
2026-07-20 11:01:04 +02:00
cinereal
608690995f nixos/modular-services: add portable process.environment
Adds modular service option `process.environment` to pass an attrset of
env vars to the service manager.
`null` values actively unset the variable before the process starts.

Values are `coercedTo (either path package) str` via interpolation,
mirroring `pathOrStr`, so paths and packages render to store-path strings
with string context preserved. The type is `lazyAttrsOf`, allowing one
entry to reference another (recursive env definitions).

The systemd backend unsets entries using `unexport` in `ExecStart`,
so the variable is absent even when `Environment=` or
the inherited environment would otherwise supply it.

The systemd backend lifts non-null entries onto the primary unit wrapped
per-key with `lib.mkDefault` so they merge with the existing priority-100
`environment.PATH` binding in `nixos/lib/systemd-lib.nix` while still letting
explicit `systemd.service.environment.<k>` overrides win.

The systemd extra-root modules are loaded via `importApply`, closing `pkgs`
over `systemd/service.nix` as a non-module argument (matching the portable
`lib/services/service.nix` convention) instead of passing a redundant `pkgs`
specialArg. The docs eval threads `pkgs = throw` accordingly.

Portable coverage lives in `testers.modularServiceCompliance`: an eval-level
check that a set value round-trips and a `null` value is preserved, plus an
integration test that records the service's own `/proc/$$/environ` and asserts
the set variable is present and the null variable is absent. The
systemd-specific grep assertions in `systemd/test.nix` cover how systemd
achieves this (`Environment=` rendering, null filtering, the `unexport`
wrapper, and override precedence).

Assisted-by: Claude:claude-opus-4-8
2026-07-11 22:54:46 +02:00
eveeifyeve
aae4936e07 lib/services: add reload support for service management 2026-07-11 04:21:03 +10:00
eveeifyeve
03deb31b6b lib/services: add service readiness protocol support 2026-07-11 04:21:03 +10:00
cinereal
a338deb8a1 lib/services: move portable service infrastructure out of nixos/
Move the portable modular service base from
nixos/modules/system/service/portable/ to lib/services/, making it
importable by any module system (home-manager, nix-darwin) without
reaching into the nixos/ tree.

Moved files: service.nix, lib.nix, config-data.nix, config-data-item.nix,
test.nix. All external references updated (systemd/system.nix,
doc/manual/default.nix, assertions.nix, README.md).

No functional changes - only import paths differ.
2026-04-04 08:23:23 +02:00