Skip to content

fix: read pkgs.frigate in module default so overlays compose#5

Merged
josibake merged 1 commit into
mainfrom
fix/frigate-package-overlay-composition
May 20, 2026
Merged

fix: read pkgs.frigate in module default so overlays compose#5
josibake merged 1 commit into
mainfrom
fix/frigate-package-overlay-composition

Conversation

@josibake
Copy link
Copy Markdown
Member

Summary

  • Change services.frigate.package default from pkgs.callPackage ../pkgs/frigate/package.nix { } to pkgs.frigate or (pkgs.callPackage …).
  • The three standard Nix override paths now all compose: nixpkgs.overlays = [ roost.overlays.default ] (or a consumer overlay), services.frigate.package = <drv>, or a downstream package fork.
  • Strictly additive — callers not applying any overlay get the same package as before.

Why

The module previously bypassed the package set entirely, so overlays.default (which this flake ships) had no effect on actual deployments, and a consumer's nixpkgs.overlays injection of pkgs.frigate was also silently ineffective. The only override path that reached the module was the option itself, which forced consumers running a custom build (version pin, local fork, batching experiment) into per-host module edits.

Surfaced while running a batched-frigate experiment on a flotilla host: had to thread roost through specialArgs and set services.frigate.package = … in hosts/<box>/frigate.nix because the overlay shipped right here in this flake didn't reach the module.

Test plan

  • nix flake check — existing regtest E2E suites still pass (they apply no overlay → fall back to the same callPackage as before).
  • nix eval .#nixosConfigurations.<host>.config.services.frigate.package resolves to the overlay's frigate when a consumer applies nixpkgs.overlays = [ roost.overlays.default ] (or any overlay defining pkgs.frigate), and to the local-callPackage fallback otherwise.
  • nix fmt — clean (already verified locally).

The services.frigate.package default was a direct callPackage of
pkgs/frigate/package.nix, bypassing the package set. That meant
overlays.default (which adds frigate to nixpkgs) had no effect on
actual deployments, and consumer-side overlays on pkgs.frigate were
also silently ineffective. The only override path that actually
reached the module was services.frigate.package = ..., which forced
consumers wanting a custom build (overlay, version pin, batching
experiments) into per-host module edits.

Read pkgs.frigate instead, falling back to the original callPackage
if no overlay defines it. The three standard Nix override paths now
all compose:

- nixpkgs.overlays = [ roost.overlays.default ] (or any equivalent)
- services.frigate.package = <derivation>
- a downstream fork of pkgs/frigate/package.nix

Strictly additive: callers not applying any overlay get the same
package as before.
@josibake josibake merged commit f685d2c into main May 20, 2026
2 checks passed
josibake added a commit that referenced this pull request May 20, 2026
…sion

PR #5 made `services.frigate.package`'s default read
`pkgs.frigate or (callPackage …)` to enable overlay-based override
composition. But nixpkgs already defines `pkgs.frigate` as
blakeblackshear/frigate (an unrelated NVR camera, v0.17.1) — so the
fallback never fires for consumers not applying roost's overlay
themselves, and they silently get the NVR camera. A regression from
PR #5.

A first attempt at this PR registered `nixpkgs.overlays` from inside
the module to shadow nixpkgs's `pkgs.frigate`. That works for normal
deployments but fails NixOS VM tests: the test framework injects
pkgs via `nixpkgs.pkgs` and pins `nixpkgs.overlays` to read-only
(unique-typed), which collides with module-level contributions
regardless of `mkBefore`/`mkForce`/`mkDefault` priority.

Use a distinct overlay attribute name instead: `frigate-sparrowwallet`.
No collision with nixpkgs's `pkgs.frigate`, no need to register
`nixpkgs.overlays` from inside the module, and the
`pkgs.frigate-sparrowwallet or (callPackage …)` default resolves
correctly in all three cases:

- consumer applies `roost.overlays.default` → module picks up the
  silent-payments frigate from the overlay
- consumer applies own overlay defining `frigate-sparrowwallet` →
  module picks up the override
- consumer applies no overlay → fallback callPackage builds the
  silent-payments frigate from this flake

All three standard override paths still compose:

- nixpkgs.overlays = [ (f: p: { frigate-sparrowwallet = X; }) ]
- services.frigate.package = X
- a downstream fork of pkgs/frigate/package.nix

Cost is the non-standard attribute name. Bitcoin-related variants of
common names are precedented in nixpkgs (`bitcoind-knots`,
`bitcoind-clightning`, etc.); `frigate-sparrowwallet` follows the
same `<base>-<variant>` convention.

Verified `nix flake check --no-build` passes locally with this
shape — the previous read-only-nixpkgs failure mode is no longer
reachable since we never touch `nixpkgs.overlays`.
josibake added a commit that referenced this pull request May 20, 2026
…sion (#7)

PR #5 made `services.frigate.package`'s default read
`pkgs.frigate or (callPackage …)` to enable overlay-based override
composition. But nixpkgs already defines `pkgs.frigate` as
blakeblackshear/frigate (an unrelated NVR camera, v0.17.1) — so the
fallback never fires for consumers not applying roost's overlay
themselves, and they silently get the NVR camera. A regression from
PR #5.

A first attempt at this PR registered `nixpkgs.overlays` from inside
the module to shadow nixpkgs's `pkgs.frigate`. That works for normal
deployments but fails NixOS VM tests: the test framework injects
pkgs via `nixpkgs.pkgs` and pins `nixpkgs.overlays` to read-only
(unique-typed), which collides with module-level contributions
regardless of `mkBefore`/`mkForce`/`mkDefault` priority.

Use a distinct overlay attribute name instead: `frigate-sparrowwallet`.
No collision with nixpkgs's `pkgs.frigate`, no need to register
`nixpkgs.overlays` from inside the module, and the
`pkgs.frigate-sparrowwallet or (callPackage …)` default resolves
correctly in all three cases:

- consumer applies `roost.overlays.default` → module picks up the
  silent-payments frigate from the overlay
- consumer applies own overlay defining `frigate-sparrowwallet` →
  module picks up the override
- consumer applies no overlay → fallback callPackage builds the
  silent-payments frigate from this flake

All three standard override paths still compose:

- nixpkgs.overlays = [ (f: p: { frigate-sparrowwallet = X; }) ]
- services.frigate.package = X
- a downstream fork of pkgs/frigate/package.nix

Cost is the non-standard attribute name. Bitcoin-related variants of
common names are precedented in nixpkgs (`bitcoind-knots`,
`bitcoind-clightning`, etc.); `frigate-sparrowwallet` follows the
same `<base>-<variant>` convention.

Verified `nix flake check --no-build` passes locally with this
shape — the previous read-only-nixpkgs failure mode is no longer
reachable since we never touch `nixpkgs.overlays`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant