+34
nixos/doc/manual/default.nix
+34
nixos/doc/manual/default.nix
······sed -e '/@PYTHON_MACHINE_METHODS@/ {' -e 'r ${testDriverMachineDocstrings}/machine-methods.md' -e 'd' -e '}' \
······sed -e '/@PYTHON_MACHINE_METHODS@/ {' -e 'r ${testDriverMachineDocstrings}/machine-methods.md' -e 'd' -e '}' \+inherit (evalModules { modules = [ ../../modules/system/service/portable/service.nix ]; }) options;+inherit (evalModules { modules = [ ../../modules/system/service/systemd/service.nix ]; }) options;+# TODO: filter out options that are not systemd-specific, maybe also change option prefix to just `service-opt-`?
+1
nixos/doc/manual/development/development.md
+1
nixos/doc/manual/development/development.md
+98
nixos/doc/manual/development/modular-services.md
+98
nixos/doc/manual/development/modular-services.md
···
···+Status: in development. This functionality is new in NixOS 25.11, and significant changes should be expected. We'd love to hear your feedback in <https://github.com/NixOS/nixpkgs/pull/372170>+Traditionally, NixOS services were defined using sets of options *in* modules, not *as* modules. This made them non-modular, resulting in problems with composability, reuse, and portability.+A configuration management framework is an application of `evalModules` with the `class` and `specialArgs` input attribute set to particular values.+NixOS is such a configuration management framework, and so are [Home Manager](https://github.com/nix-community/home-manager) and [`nix-darwin`](https://github.com/lnl7/nix-darwin).+The service management component of a configuration management framework is the set of module options that connects Nix expressions with the underlying service (or process) manager.+For NixOS this is the module wrapping [`systemd`](https://systemd.io/), on `nix-darwin` this is the module wrapping [`launchd`](https://en.wikipedia.org/wiki/Launchd).+A *modular service* is a [module] that defines values for a core set of options declared in the service management component of a configuration management framework, including which program to run.+Since it's a module, it can be composed with other modules via `imports` to extend its functionality.+<!-- ^ This is how composition is *always* provided, instead of a difficult thing (but this is reference docs, not a changelog) -->+- a module with systemd-specific options, whose values or defaults derive from the generic module's option values.+So note that the default value of `system.services.<name>` is not a complete service. It requires that the user provide a value, and this is typically done by importing a module. For example:+<!-- Not using typical example syntax, because reading this is *not* optional, and should it should not be folded closed. -->+It is possible to write service modules that are portable. This is done by either avoiding the `systemd` option tree, or by defining process-manager-specific definitions in an optional way:+This way, the module can be loaded into a configuration manager that does not use systemd, and the `systemd` definitions will be ignored.+Similarly, other configuration managers can declare their own options for services to customize.+Compared to traditional services, modular services are inherently more composable, by virtue of being modules and receiving a user-provided name when imported.+However, composition can not end there, because services need to be able to interact with each other.+These aren't mutually exclusive. In fact, it is a good practice when developing services to first write them as individual services, and then compose them into a higher-level composition. Each of these services is a valid modular service, including their composition.+Many services could be migrated to the modular service system, but even when the modular service system is mature, it is not necessary to migrate all services.+For instance, many system-wide services are a mandatory part of a desktop system, and it doesn't make sense to have multiple instances of them.+Moving their logic into separate Nix files may still be beneficial for the efficient evaluation of configurations that don't use those services, but that is a rather minor benefit, unless modular services potentially become the standard way to define services.
+18
nixos/doc/manual/redirects.json
+18
nixos/doc/manual/redirects.json
···
+3
-1
nixos/modules/misc/assertions.nix
+3
-1
nixos/modules/misc/assertions.nix
+2
nixos/modules/module-list.nix
+2
nixos/modules/module-list.nix
+28
nixos/modules/system/service/README.md
+28
nixos/modules/system/service/README.md
···
···+See the [Modular Services chapter] in the manual [[source]](../../doc/manual/development/modular-services.md).+- `systemServices`: similar to does not allow importing a composition of services into `system`. Not sure if that's a good idea in the first place, but I've kept the possibility open.+- `services.abstract`: used in https://github.com/NixOS/nixpkgs/pull/267111, but too weird. Service modules should fit naturally into the configuration system.+Also "abstract" is wrong, because it has submodules - in other words, evalModules results, concrete services - not abstract at all.+- For now, do not add an `enable` option, because it's ambiguous. Does it disable at the Nix level (not generate anything) or at the systemd level (generate a service that is disabled)?+- Move all process options into a `process` option tree. Putting this at the root is messy, because we also have sub-services at that level. Those are rather distinct. Grouping them "by kind" should raise fewer questions.+- This reserves `modules/service` for actual service modules, at least until those are lifted out of NixOS, potentially
+33
nixos/modules/system/service/portable/lib.nix
+33
nixos/modules/system/service/portable/lib.nix
···
···
+48
nixos/modules/system/service/portable/service.nix
+48
nixos/modules/system/service/portable/service.nix
···
···+A collection of [modular services](https://nixos.org/manual/nixos/unstable/#modular-services) that are configured in one go.+It **does not** automatically create any other relationship between services (e.g. systemd slices), unless perhaps such a behavior is explicitly defined and enabled in another option.
+183
nixos/modules/system/service/portable/test.nix
+183
nixos/modules/system/service/portable/test.nix
···
···
+121
nixos/modules/system/service/systemd/service.nix
+121
nixos/modules/system/service/systemd/service.nix
···
···+This module configures systemd services, with the notable difference that their unit names will be prefixed with the abstract service name.+This option's value is not suitable for reading, but you can define a module here that interacts with just the unit configuration in the host system configuration.+This means that the module has not been combined with the system configuration yet, no values can be read from this option.+What you can do instead is define a module that reads from the module arguments (such as `config`) that are available when the module is merged into the system configuration.
+90
nixos/modules/system/service/systemd/system.nix
+90
nixos/modules/system/service/systemd/system.nix
···
···+A collection of NixOS [modular services](https://nixos.org/manual/nixos/unstable/#modular-services) that are configured as systemd services.
+92
nixos/modules/system/service/systemd/test.nix
+92
nixos/modules/system/service/systemd/test.nix
···
···+grep -F 'ExecStart="${hello}/bin/hello" "--greeting" "hoi"' ${toplevel}/etc/systemd/system/foo.service >/dev/null+grep -F 'ExecStart="${hello}/bin/hello" "--greeting" "hoi"' ${toplevel}/etc/systemd/system/bar.service >/dev/null+grep 'ExecStart="${hello}/bin/hello" "--greeting" ".*database.*"' ${toplevel}/etc/systemd/system/bar-db.service >/dev/null
+3
nixos/modules/system/service/systemd/user.nix
+3
nixos/modules/system/service/systemd/user.nix
+14
nixos/tests/all-tests.nix
+14
nixos/tests/all-tests.nix
·········
·········
+120
nixos/tests/ghostunnel-modular.nix
+120
nixos/tests/ghostunnel-modular.nix
···
···+cmd("${hostPkgs.openssl}/bin/openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -subj '/C=NL/ST=Zuid-Holland/L=The Hague/O=Stevige Balken en Planken B.V./OU=OpSec/CN=Certificate Authority' -out ca.pem")+cmd("${hostPkgs.openssl}/bin/openssl req -subj '/CN=service' -sha256 -new -key service-key.pem -out service.csr")+cmd("${hostPkgs.openssl}/bin/openssl x509 -req -days 365 -sha256 -in service.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out service-cert.pem -extfile extfile.cnf")+cmd("${hostPkgs.openssl}/bin/openssl req -subj '/CN=client' -new -key client-key.pem -out client.csr")+cmd("${hostPkgs.openssl}/bin/openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile extfile-client.cnf")+client.succeed("bash -c 'diff <(curl -v --no-progress-meter http://backend/hi.txt) <(echo hi)'")+client.succeed("bash -c 'diff <(curl -v --no-progress-meter --insecure https://service/hi.txt) <(echo hi)'")+client.succeed("bash -c 'diff <(curl -v --no-progress-meter --cacert /root/ca.pem https://service/hi.txt) <(echo hi)'")+client.succeed("bash -c 'diff <(curl -v --no-progress-meter --cert /root/client-cert.pem --key /root/client-key.pem --cacert /root/ca.pem https://service:1443/hi.txt) <(echo hi)'")+client.fail("bash -c 'diff <(curl -v --no-progress-meter --cacert /root/ca.pem https://service:1443/hi.txt) <(echo hi)'")
+6
pkgs/by-name/gh/ghostunnel/package.nix
+6
pkgs/by-name/gh/ghostunnel/package.nix
······
+241
pkgs/by-name/gh/ghostunnel/service.nix
+241
pkgs/by-name/gh/ghostunnel/service.nix
···
···
+1
-1
pkgs/by-name/ni/nixos-render-docs/src/nixos_render_docs/redirects.py
+1
-1
pkgs/by-name/ni/nixos-render-docs/src/nixos_render_docs/redirects.py
···
···+ignored_identifier_patterns = ("opt-", "auto-generated-", "function-library-", "service-opt-", "systemd-service-opt")