Commit c8327c22 authored by K900's avatar K900
Browse files

Merge remote-tracking branch 'origin/master' into staging-next

parents d2134d41 40a510d9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -123,6 +123,9 @@

- `fetchgit`: Add `rootDir` argument to limit the resulting source to one subdirectory of the whole Git repository. Corresponding `--root-dir` option added to `nix-prefetch-git`.

- `sftpman` has been updated to version 2, a rewrite in Rust which is mostly backward compatible but does include some changes to the CLI.
  For more information, [check the project's README](https://github.com/spantaleev/sftpman-rs#is-sftpman-v2-compatible-with-sftpman-v1).

- The `clickhouse` package now track the stable upstream version per [upstream's
  recommendation](https://clickhouse.com/docs/faq/operations/production). Users
  can continue to use the `clickhouse-lts` package if desired.
+5 −0
Original line number Diff line number Diff line
@@ -13088,6 +13088,11 @@
    githubId = 56224949;
    name = "Mia Kanashi";
  };
  kaptcha0 = {
    name = "J'C Kabunga";
    github = "kaptcha0";
    githubId = 50426223;
  };
  karantan = {
    name = "Gasper Vozel";
    email = "karantan@gmail.com";
+27 −0
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@ See the [Modular Services chapter] in the manual [[source]](../../doc/manual/dev

# Design decision log

## Initial design

- `system.services.<name>`. Alternatives considered
  - `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.
@@ -26,3 +28,28 @@ See the [Modular Services chapter] in the manual [[source]](../../doc/manual/dev
    2. `systemd/system` configures SystemD _system units_.
  - This reserves `modules/service` for actual service modules, at least until those are lifted out of NixOS, potentially

## Configuration Data (`configData`) Design

Without a mechanism for adding files, all configuration had to go through `process.*`, requiring process restarts even when those would have been avoidable.
Many services implement automatic reloading or reloading on e.g. `SIGUSR1`, but those mechanisms need files to read. `configData` provides such files.

### Naming and Terminology

- **`configData` instead of `environment.etc`**: The name `configData` is service manager agnostic. While systemd system services can use `/etc`, other service managers may expose configuration data differently (e.g., different directory, relative paths).

- **`path` attribute**: Each `configData` entry automatically gets a `path` attribute set by the service manager implementation, allowing services to reference the location of their configuration files. These paths themselves are not subject to change from generation to generation; only their contents are.

- **`name` attribute**: In `environment.etc` this would be `target` but that's confusing, especially for symlinks, as it's not the symlink's target.

### Service Manager Integration

- **Portable base**: The `configData` interface is declared in `portable/config-data.nix`, making it available to all service manager implementations.

- **Systemd integration**: The systemd implementation (`systemd/system.nix`) maps `configData` entries to `environment.etc` entries under `/etc/system-services/`.

- **Path computation**: `systemd/config-data-path.nix` recursively computes unique paths for services and sub-services (e.g., `/etc/system-services/webserver/` vs `/etc/system-services/webserver-api/`).
  Fun fact: for the module system it is a completely normal module, despite its recursive definition.
  If we parameterize `/etc/system-services`, it will have to become an `importApply` style module nonetheless (function returning module).

- **Simple attribute structure**: Unlike `environment.etc`, `configData` uses a simpler structure with just `enable`, `name`, `text`, `source`, and `path` attributes. Complex ownership options were omitted for simplicity and portability.
  Per-service user creation is still TBD.
+65 −0
Original line number Diff line number Diff line
# Tests in: ../../../../tests/modular-service-etc/test.nix
# This file is a function that returns a module.
pkgs:
{
  lib,
  name,
  config,
  options,
  ...
}:
let
  inherit (lib) mkOption types;
in
{
  options = {
    enable = mkOption {
      type = types.bool;
      default = true;
      description = ''
        Whether this configuration file should be generated.
        This option allows specific configuration files to be disabled.
      '';
    };

    name = mkOption {
      type = types.str;
      description = ''
        Name of the configuration file (relative to the service's configuration directory). Defaults to the attribute name.
      '';
    };

    path = mkOption {
      type = types.str;
      readOnly = true;
      description = ''
        The actual path where this configuration file will be available.
        This is determined by the service manager implementation.

        On NixOS it is an absolute path.
        Other service managers may provide a relative path, in order to be unprivileged and/or relocatable.
      '';
    };

    text = mkOption {
      default = null;
      type = types.nullOr types.lines;
      description = "Text content of the configuration file.";
    };

    source = mkOption {
      type = types.path;
      description = "Path of the source file.";
    };
  };

  config = {
    name = lib.mkDefault name;
    source = lib.mkIf (config.text != null) (
      let
        name' = "service-configdata-" + lib.replaceStrings [ "/" ] [ "-" ] name;
      in
      lib.mkDerivedConfig options.text (pkgs.writeText name')
    );
  };
}
+44 −0
Original line number Diff line number Diff line
# Tests in: ../../../../tests/modular-service-etc/test.nix
# Configuration data support for portable services
# This module provides configData for services, enabling configuration reloading
# without terminating and restarting the service process.
{
  lib,
  pkgs,
  ...
}:
let
  inherit (lib) mkOption types;
  inherit (lib.modules) importApply;
in
{
  options = {
    configData = mkOption {
      default = { };
      example = lib.literalExpression ''
        {
          "server.conf" = {
            text = '''
              port = 8080
              workers = 4
            ''';
          };
          "ssl/cert.pem" = {
            source = ./cert.pem;
          };
        }
      '';
      description = ''
        Configuration data files for the service

        These files are made available to the service and can be updated without restarting the service process, enabling configuration reloading.
        The service manager implementation determines how these files are exposed to the service (e.g., via a specific directory path).
        This path is available in the `path` sub-option for each `configData.<name>` entry.

        This is particularly useful for services that support configuration reloading via signals (e.g., SIGHUP) or which pick up changes automatically, so that no downtime is required in order to reload the service.
      '';

      type = types.lazyAttrsOf (types.submodule (importApply ./config-data-item.nix pkgs));
    };
  };
}
Loading