Skip to content

nixos/modular-services: add portable process.environment - #518860

Merged
roberth merged 1 commit into
NixOS:masterfrom
KiaraGrouwstra:modular-services-env-vars
Jul 24, 2026
Merged

nixos/modular-services: add portable process.environment#518860
roberth merged 1 commit into
NixOS:masterfrom
KiaraGrouwstra:modular-services-env-vars

Conversation

@KiaraGrouwstra

@KiaraGrouwstra KiaraGrouwstra commented May 10, 2026

Copy link
Copy Markdown
Contributor

Adds new modular service option process.environment for declaring env vars.

Disclaimer: I used a coding agent in the creation of this patch.

Things done

  • Built on platform:
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • Tested, as applicable:
  • Ran nixpkgs-review on this PR. See nixpkgs-review usage.
  • Tested basic functionality of all binary files, usually in ./result/bin/.
  • Nixpkgs Release Notes
    • Package update: when the change is major or breaking.
  • NixOS Release Notes
    • Module addition: when adding a new NixOS module.
    • Module update: when the change is significant.
  • Fits CONTRIBUTING.md, pkgs/README.md, maintainers/README.md and other READMEs.

@nixpkgs-ci
nixpkgs-ci Bot requested review from hsjobeki and infinisil May 10, 2026 21:43
@nixpkgs-ci nixpkgs-ci Bot added 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` 6.topic: lib The Nixpkgs function library labels May 10, 2026
Comment thread lib/services/service.nix Outdated
@KiaraGrouwstra
KiaraGrouwstra marked this pull request as draft May 11, 2026 12:04
Comment thread lib/services/service.nix Outdated
@KiaraGrouwstra
KiaraGrouwstra force-pushed the modular-services-env-vars branch from ed9202c to b168777 Compare May 20, 2026 09:30
@KiaraGrouwstra KiaraGrouwstra changed the title nixos/modular-services: add portable process.environment and process.environmentFile nixos/modular-services: add portable process.environment May 20, 2026
@KiaraGrouwstra
KiaraGrouwstra marked this pull request as ready for review May 20, 2026 12:38
Comment thread lib/services/service.nix Outdated
@KiaraGrouwstra
KiaraGrouwstra force-pushed the modular-services-env-vars branch from b168777 to 540a74f Compare May 23, 2026 10:50
@roberth roberth mentioned this pull request May 26, 2026
16 tasks
@KiaraGrouwstra
KiaraGrouwstra force-pushed the modular-services-env-vars branch from 540a74f to 201526e Compare May 26, 2026 17:31

@roberth roberth left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In pretty good shape

Comment thread lib/services/service.nix Outdated
Comment thread nixos/modules/system/service/systemd/system.nix Outdated
Comment thread nixos/modules/system/service/systemd/test.nix
Comment thread lib/services/service.nix Outdated
Comment thread nixos/modules/system/service/systemd/test.nix
@KiaraGrouwstra
KiaraGrouwstra force-pushed the modular-services-env-vars branch from 201526e to e50372c Compare June 26, 2026 18:13
@nixpkgs-ci
nixpkgs-ci Bot requested review from llakala and philiptaron June 26, 2026 18:18
@nixpkgs-ci nixpkgs-ci Bot added 6.topic: testing Tooling for automated testing of packages and modules 8.has: documentation This PR adds or changes documentation labels Jun 26, 2026
@eveeifyeve

Copy link
Copy Markdown
Member

Something to consider for this pr is handling secrets securely.

@nixpkgs-ci nixpkgs-ci Bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Jul 11, 2026
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
@KiaraGrouwstra

Copy link
Copy Markdown
Contributor Author

secrets i would like to consider non-blocking for this PR, given what's involved there.

that said, i believe PRs that'd get us closer on that would include #449574 and #522054.

@roberth roberth left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!
Tests pass after rebase ✔️

@roberth
roberth added this pull request to the merge queue Jul 24, 2026
@nixpkgs-ci nixpkgs-ci Bot added the 12.approvals: 1 This PR was reviewed and approved by one person. label Jul 24, 2026
Merged via the queue into NixOS:master with commit 541a6f3 Jul 24, 2026
30 checks passed
@KiaraGrouwstra
KiaraGrouwstra deleted the modular-services-env-vars branch July 24, 2026 22:36
@c2fc2f

c2fc2f commented Jul 25, 2026

Copy link
Copy Markdown
Member

Since this merge, I have this:

       error: function 'anonymous lambda' called with unexpected argument 'lib'
       at «github:nixos/nixpkgs/ec830498ebdf7052e3ce91646d09ae7b43313384?narHash=sha256-A2KfwKftvyG1%2BE%2Bmr1Fh/Q0rM6tQbCq4pB7sRbd/Q5c%3D»/nixos/modules/system/service/systemd/service.nix:4:1:
            3| # This makes service modules self-contained, allowing mixing of Nixpkgs versions.
            4| { pkgs }:
             | ^
            5|

# Non-module arguments
# These are separate from the module arguments to avoid implicit dependencies.
# This makes service modules self-contained, allowing mixing of Nixpkgs versions.
{ pkgs }:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that this breaks home-manager at this location. https://github.com/nix-community/home-manager/blob/master/modules/services-modular/service.nix

Changing the import in the home-manager service.nix file to the following appears to fix it. I'm not sure if there are many other consumers of this file?

(import (nixpkgsPath + "/nixos/modules/system/service/systemd/service.nix") { inherit pkgs; })

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe lib.modules.importApply instead of import, since that's what they use in this merge? But yes, the problem remains, because this might not be the only place where this import appears

@mvnetbiz mvnetbiz Jul 25, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the only use of pkgs unsetting environment variables with pkgs.execline in generated systemd units? Can UnsetEnvironment= be used?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks - i filed a fix based on UnsetEnvironment now at #545521.

eveeifyeve added a commit to DigitalBrewStudios/finix-modular-services that referenced this pull request Jul 25, 2026
eveeifyeve added a commit to DigitalBrewStudios/finix-modular-services that referenced this pull request Jul 25, 2026
eveeifyeve added a commit to DigitalBrewStudios/finix-modular-services that referenced this pull request Jul 25, 2026
eveeifyeve added a commit to DigitalBrewStudios/finix-modular-services that referenced this pull request Jul 25, 2026
@ser

ser commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

after this commit it stopped building

ERROR Failed to complete requested operation - Last 1 lines of logs:                                                                                                                  
ERROR  failure) Child process exited with error code: 1                                                                                                                               
ERROR Failed to evaluate nixx1 - Last 20 lines of logs:                                                                                                                               
ERROR   stderr)          at /nix/store/yv79v7sqfzsxskqhqrdagnr71ivgq69m-nixpkgs-with-prs/lib/modules.nix:711:5:                                                                       
ERROR   stderr)           710|     key: f:                                                                                                                                            
ERROR   stderr)           711|     args@{ config, ... }:                                                                                                                              
ERROR   stderr)              |     ^                                                                                                                                                  
ERROR   stderr)           712|     let                                                                                                                                                
ERROR   stderr)                                                                                                                                                                       
ERROR   stderr)        … from call site                                                                                                                                               
ERROR   stderr)          at /nix/store/yv79v7sqfzsxskqhqrdagnr71ivgq69m-nixpkgs-with-prs/lib/modules.nix:741:5:                                                                       
ERROR   stderr)           740|     in                                                                                                                                                 
ERROR   stderr)           741|     f (args // extraArgs);                                                                                                                             
ERROR   stderr)              |     ^                                                                                                                                                  
ERROR   stderr)           742|                                                                                                                                                        
ERROR   stderr)                                                                                                                                                                       
ERROR   stderr)        error: function 'anonymous lambda' called with unexpected argument 'config'                                                                                    
ERROR   stderr)        at /nix/store/yv79v7sqfzsxskqhqrdagnr71ivgq69m-nixpkgs-with-prs/nixos/modules/system/service/systemd/service.nix:4:1:                                          
ERROR   stderr)             3| # This makes service modules self-contained, allowing mixing of Nixpkgs versions.                                                                      
ERROR   stderr)             4| { pkgs }:                                                                                                                                              
ERROR   stderr)              | ^                                                                                                                                                      
ERROR   stderr)             5|                                   

@K900

K900 commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

OK so we clearly need more integration tests for modular service consumers, at the very least. Reverting for now.

KiaraGrouwstra added a commit to KiaraGrouwstra/nixpkgs that referenced this pull request Jul 25, 2026
Switch the approach to unsetting environment variables in NixOS's modular
services from `pkgs.execline` to `UnsetEnvironment`, removing the closure
that broke usage for downstream consumers depending on the prior interface.

Post-merge comments at NixOS#518860 revealed that the newly-introduced closure
at `nixos/modules/system/service/systemd/service.nix`, introducing a `pkgs`
argument to unset environment variables using `pkgs.execline`, broke
downstream consumption such as by Home Manager, which so far imports this
file by path.

Note that, while a proper fix to making downstream consumption more robust
is introduced at NixOS#507052, the current change renders unsetting of environment
variables more idiomatic to systemd, while simplifying the interface again.

Assisted-by: Claude:claude-opus-4-8

Signed-off-by: cinereal <cinereal@riseup.net>
KiaraGrouwstra added a commit to KiaraGrouwstra/nixpkgs that referenced this pull request Jul 25, 2026
…etEnvironment`

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.

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

Differs from the ealier approach from NixOS#518860, which instead
unset environment variables using `pkgs.execline`, removing its `pkgs` closure
that broke usage for downstream consumers depending on the prior interface.

Assisted-by: Claude:claude-opus-4-8

Signed-off-by: cinereal <cinereal@riseup.net>
KiaraGrouwstra added a commit to KiaraGrouwstra/nixpkgs that referenced this pull request Jul 25, 2026
…etEnvironment`

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.

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

Differs from the ealier approach from NixOS#518860, which instead
unset environment variables using `pkgs.execline`, removing its `pkgs` closure
that broke usage for downstream consumers depending on the prior interface.

Assisted-by: Claude:claude-opus-4-8

Signed-off-by: cinereal <cinereal@riseup.net>
@roberth

roberth commented Jul 25, 2026

Copy link
Copy Markdown
Member

Thank you @K900 for the revert.


The root cause here is a missing public interface for the systemd integration, which was built against NixOS, not against systemd in isolation.
That made home manager depend on internal implementation files.
File paths are generally not considered to be part of this repo's public interface.

This also means that we should soon merge

And of course we need to refactor out a systemd integration that isn't as coupled to NixOS, and give that a documented and tested interface that HM can use.

KiaraGrouwstra added a commit to KiaraGrouwstra/nixpkgs that referenced this pull request Aug 2, 2026
…etEnvironment`

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.

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

Differs from the ealier approach from NixOS#518860, which instead
unset environment variables using `pkgs.execline`, removing its `pkgs` closure
that broke usage for downstream consumers depending on the prior interface.

Assisted-by: Claude:claude-opus-4-8

Signed-off-by: cinereal <cinereal@riseup.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: lib The Nixpkgs function library 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 6.topic: package configuration modules Modular services / package configuration modules https://matrix.to/#/#modular-services:nixos.org 6.topic: testing Tooling for automated testing of packages and modules 8.has: documentation This PR adds or changes documentation 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 12.approvals: 1 This PR was reviewed and approved by one person. llm-assisted Contributions that include code generation with LLMs

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

9 participants