nixos/service/portable: Provide an entrypoint function

... and tidy up in various small ways.

This should help a bit to make more clear the separation between
the portable parts and the systemd system service parts.
This commit is contained in:
Robert Hensing
2025-08-20 11:34:52 +02:00
parent d88b9464b0
commit 90162e8113
5 changed files with 81 additions and 31 deletions

View File

@@ -25,6 +25,7 @@ let
escapeShellArg
concatMapStringsSep
sourceFilesBySuffices
modules
;
common = import ./common.nix;
@@ -129,7 +130,16 @@ let
'';
portableServiceOptions = buildPackages.nixosOptionsDoc {
inherit (evalModules { modules = [ ../../modules/system/service/portable/service.nix ]; }) options;
inherit
(evalModules {
modules = [
(modules.importApply ../../modules/system/service/portable/service.nix {
pkgs = throw "nixos docs / portableServiceOptions: Do not reference pkgs in docs";
})
];
})
options
;
inherit revision warningsAreErrors;
transformOptions =
opt:

View File

@@ -1,6 +1,11 @@
{ lib, ... }:
let
inherit (lib) concatLists mapAttrsToList showOption;
inherit (lib)
concatLists
mapAttrsToList
showOption
types
;
in
rec {
flattenMapServicesConfigToList =
@@ -30,4 +35,43 @@ rec {
assertion = ass.assertion;
}) config.assertions
);
/**
This is the entrypoint for the portable part of modular services.
It provides the various options that are consumed by service manager implementations.
# Inputs
`serviceManagerPkgs`: A Nixpkgs instance which will be used for built-in logic such as converting `configData.<path>.text` to a store path.
`extraRootModules`: Modules to be loaded into the "root" service submodule, but not into its sub-`services`. That's the modules' own responsibility.
`extraRootSpecialArgs`: Fixed module arguments that are provided in a similar manner to `extraRootModules`.
# Output
An attribute set.
`serviceSubmodule`: a Module System option type which is a `submodule` with the portable modules and this function's inputs loaded into it.
*/
configure =
{
serviceManagerPkgs,
extraRootModules ? [ ],
extraRootSpecialArgs ? { },
}:
let
modules = [
(lib.modules.importApply ./service.nix { pkgs = serviceManagerPkgs; })
];
serviceSubmodule = types.submoduleWith {
class = "service";
modules = modules ++ extraRootModules;
specialArgs = extraRootSpecialArgs;
};
in
{
inherit serviceSubmodule;
};
}

View File

@@ -1,3 +1,9 @@
# Non-module arguments
# These are separate from the module arguments to avoid implicit dependencies.
# This makes service modules self-contains, allowing mixing of Nixpkgs versions.
{ pkgs }:
# The module
{
lib,
...
@@ -11,13 +17,14 @@ in
_class = "service";
imports = [
../../../misc/assertions.nix
(lib.modules.importApply ./config-data.nix { inherit pkgs; })
];
options = {
services = mkOption {
type = types.attrsOf (
types.submoduleWith {
modules = [
./service.nix
(lib.modules.importApply ./service.nix { inherit pkgs; })
];
}
);

View File

@@ -52,8 +52,8 @@ let
in
{
_class = "service";
imports = [
../portable/service.nix
(lib.mkAliasOptionModule [ "systemd" "service" ] [ "systemd" "services" "" ])
(lib.mkAliasOptionModule [ "systemd" "socket" ] [ "systemd" "sockets" "" ])
];
@@ -101,6 +101,8 @@ in
};
}
);
# Rendered by the portable docs instead.
visible = false;
};
};
config = {

View File

@@ -59,41 +59,28 @@ let
// concatMapAttrs (
subServiceName: subService: makeUnits unitType (dash prefix subServiceName) subService
) service.services;
modularServiceConfiguration = portable-lib.configure {
serviceManagerPkgs = pkgs;
extraRootModules = [
./service.nix
./config-data-path.nix
];
extraRootSpecialArgs = {
systemdPackage = config.systemd.package;
};
};
in
{
_class = "nixos";
# First half of the magic: mix systemd logic into the otherwise abstract services
options = {
system.services = mkOption {
description = ''
A collection of NixOS [modular services](https://nixos.org/manual/nixos/unstable/#modular-services) that are configured as systemd services.
'';
type = types.attrsOf (
types.submoduleWith {
class = "service";
modules = [
./service.nix
./config-data-path.nix
(lib.modules.importApply ../portable/config-data.nix { inherit pkgs; })
{
# Extend portable services option
options.services = lib.mkOption {
type = types.attrsOf (
types.submoduleWith {
modules = [
(lib.modules.importApply ../portable/config-data.nix { inherit pkgs; })
];
}
);
};
}
];
specialArgs = {
# perhaps: features."systemd" = { };
systemdPackage = config.systemd.package;
};
}
);
type = types.attrsOf modularServiceConfiguration.serviceSubmodule;
default = { };
visible = "shallow";
};