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.

Changed files
+81 -31
nixos
doc
manual
modules
system
service
+11 -1
nixos/doc/manual/default.nix
···
escapeShellArg
concatMapStringsSep
sourceFilesBySuffices
;
common = import ./common.nix;
···
'';
portableServiceOptions = buildPackages.nixosOptionsDoc {
-
inherit (evalModules { modules = [ ../../modules/system/service/portable/service.nix ]; }) options;
inherit revision warningsAreErrors;
transformOptions =
opt:
···
escapeShellArg
concatMapStringsSep
sourceFilesBySuffices
+
modules
;
common = import ./common.nix;
···
'';
portableServiceOptions = buildPackages.nixosOptionsDoc {
+
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:
+45 -1
nixos/modules/system/service/portable/lib.nix
···
{ lib, ... }:
let
-
inherit (lib) concatLists mapAttrsToList showOption;
in
rec {
flattenMapServicesConfigToList =
···
assertion = ass.assertion;
}) config.assertions
);
}
···
{ lib, ... }:
let
+
inherit (lib)
+
concatLists
+
mapAttrsToList
+
showOption
+
types
+
;
in
rec {
flattenMapServicesConfigToList =
···
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;
+
};
}
+8 -1
nixos/modules/system/service/portable/service.nix
···
{
lib,
...
···
_class = "service";
imports = [
../../../misc/assertions.nix
];
options = {
services = mkOption {
type = types.attrsOf (
types.submoduleWith {
modules = [
-
./service.nix
];
}
);
···
+
# 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,
...
···
_class = "service";
imports = [
../../../misc/assertions.nix
+
(lib.modules.importApply ./config-data.nix { inherit pkgs; })
];
options = {
services = mkOption {
type = types.attrsOf (
types.submoduleWith {
modules = [
+
(lib.modules.importApply ./service.nix { inherit pkgs; })
];
}
);
+3 -1
nixos/modules/system/service/systemd/service.nix
···
in
{
imports = [
-
../portable/service.nix
(lib.mkAliasOptionModule [ "systemd" "service" ] [ "systemd" "services" "" ])
(lib.mkAliasOptionModule [ "systemd" "socket" ] [ "systemd" "sockets" "" ])
];
···
};
}
);
};
};
config = {
···
in
{
+
_class = "service";
imports = [
(lib.mkAliasOptionModule [ "systemd" "service" ] [ "systemd" "services" "" ])
(lib.mkAliasOptionModule [ "systemd" "socket" ] [ "systemd" "sockets" "" ])
];
···
};
}
);
+
# Rendered by the portable docs instead.
+
visible = false;
};
};
config = {
+14 -27
nixos/modules/system/service/systemd/system.nix
···
// concatMapAttrs (
subServiceName: subService: makeUnits unitType (dash prefix subServiceName) subService
) service.services;
in
{
# 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;
-
};
-
}
-
);
default = { };
visible = "shallow";
};
···
// 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 modularServiceConfiguration.serviceSubmodule;
default = { };
visible = "shallow";
};