diff --git a/doc/languages-frameworks/ocaml.section.md b/doc/languages-frameworks/ocaml.section.md
index acefddc7c2f2..7f2c2a63a00b 100644
--- a/doc/languages-frameworks/ocaml.section.md
+++ b/doc/languages-frameworks/ocaml.section.md
@@ -38,12 +38,12 @@ Here is a simple package example.
- It uses the `fetchFromGitHub` fetcher to get its source.
-- It also accept `duneVersion` parameter (valid value are `"1"`, `"2"`, and
- `"3"`). The recommended practice it to set only if you don't want the default
+- It also accepts a `duneVersion` parameter (valid values are `"1"`, `"2"`, and
+ `"3"`). The recommended practice is to set it only if you don't want the default
value and/or it depends on something else like package version. You might see
a not-supported argument `useDune2`. The behavior was `useDune2 = true;` =>
`duneVersion = "2";` and `useDune2 = false;` => `duneVersion = "1";`. It was
- used at the time when dune3 didn't existed.
+ used at the time when dune3 didn't exist.
- It sets the optional `doCheck` attribute such that tests will be run with
`dune runtest -p angstrom` after the build (`dune build -p angstrom`) is
diff --git a/lib/strings.nix b/lib/strings.nix
index bcaaab9af4fb..7ee459f5b443 100644
--- a/lib/strings.nix
+++ b/lib/strings.nix
@@ -2434,7 +2434,13 @@ rec {
if isStringLike x then
let str = toString x; in
substring 0 1 str == "/"
- && dirOf str == storeDir
+ && (dirOf str == storeDir
+ # Match contentâaddressed derivations, which _currently_ do not have a
+ # store directory prefix.
+ # This is a workaround for https://github.com/NixOS/nix/issues/12361
+ # which was needed during the experimental phase of ca-derivations and
+ # should be removed once the issue has been resolved.
+ || builtins.match "/[0-9a-z]{52}" str != null)
else
false;
diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix
index e86c366d4ce4..fde2d44e3efe 100644
--- a/lib/tests/misc.nix
+++ b/lib/tests/misc.nix
@@ -537,6 +537,7 @@ runTests {
expr =
let goodPath =
"${builtins.storeDir}/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11";
+ goodCAPath = "/1121rp0gvr1qya7hvy925g5kjwg66acz6sn1ra1hca09f1z5dsab";
in {
storePath = isStorePath goodPath;
storePathDerivation = isStorePath (import ../.. { system = "x86_64-linux"; }).hello;
@@ -545,6 +546,12 @@ runTests {
nonAbsolute = isStorePath (concatStrings (tail (stringToCharacters goodPath)));
asPath = isStorePath (/. + goodPath);
otherPath = isStorePath "/something/else";
+
+ caPath = isStorePath goodCAPath;
+ caPathAppendix = isStorePath
+ "${goodCAPath}/bin/python";
+ caAsPath = isStorePath (/. + goodCAPath);
+
otherVals = {
attrset = isStorePath {};
list = isStorePath [];
@@ -557,6 +564,9 @@ runTests {
storePathAppendix = false;
nonAbsolute = false;
asPath = true;
+ caPath = true;
+ caPathAppendix = false;
+ caAsPath = true;
otherPath = false;
otherVals = {
attrset = false;
diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix
index 278b084f9d59..da1751fb2ec5 100644
--- a/maintainers/maintainer-list.nix
+++ b/maintainers/maintainer-list.nix
@@ -4529,6 +4529,12 @@
github = "CnTeng";
githubId = 56501688;
};
+ coat = {
+ email = "kentsmith@gmail.com";
+ name = "Kent Smith";
+ github = "coat";
+ githubId = 1661;
+ };
cobalt = {
email = "cobalt@cobalt.rocks";
github = "Chaostheorie";
@@ -4587,6 +4593,11 @@
email = "jupiter@m.rdis.dev";
name = "Scott Little";
};
+ coderofsalvation = {
+ github = "coderofsalvation";
+ githubId = 180068;
+ name = "Leon van Kammen";
+ };
codgician = {
email = "codgician@outlook.com";
github = "codgician";
diff --git a/nixos/doc/manual/release-notes/rl-2505.section.md b/nixos/doc/manual/release-notes/rl-2505.section.md
index 7cf681b8b8cd..e3c61c882cb4 100644
--- a/nixos/doc/manual/release-notes/rl-2505.section.md
+++ b/nixos/doc/manual/release-notes/rl-2505.section.md
@@ -225,6 +225,8 @@
- `strawberry` has been updated to 1.2, which drops support for the VLC backend and Qt 5. The `strawberry-qt5` package
and `withGstreamer`/`withVlc` override options have been removed due to this.
+- `nezha` and its agent `nezha-agent` have been updated to v1, which contains breaking changes. See the [official wiki](https://nezha.wiki/en_US/) for more details.
+
- `ps3-disc-dumper` was updated to 4.2.5, which removed the CLI project and now exclusively offers the GUI
- [](#opt-services.nextcloud.config.dbtype) is unset by default, the previous default was `sqlite`.
@@ -542,6 +544,8 @@
- `services.gitea` now supports CAPTCHA usage through the `services.gitea.captcha` variable.
+- `services.soft-serve` now restarts upon config change.
+
- `bind.cacheNetworks` now only controls access for recursive queries, where it previously controlled access for all queries.
- [`services.mongodb.enableAuth`](#opt-services.mongodb.enableAuth) now uses the newer [mongosh](https://github.com/mongodb-js/mongosh) shell instead of the legacy shell to configure the initial superuser. You can configure the mongosh package to use through the [`services.mongodb.mongoshPackage`](#opt-services.mongodb.mongoshPackage) option.
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 6a404afa8123..efa81f833fb5 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -1507,6 +1507,7 @@
./services/web-apps/gotosocial.nix
./services/web-apps/grav.nix
./services/web-apps/grocy.nix
+ ./services/web-apps/part-db.nix
./services/web-apps/pixelfed.nix
./services/web-apps/goatcounter.nix
./services/web-apps/guacamole-client.nix
diff --git a/nixos/modules/services/backup/restic.nix b/nixos/modules/services/backup/restic.nix
index aaddc5d16589..ce8bcc3994b8 100644
--- a/nixos/modules/services/backup/restic.nix
+++ b/nixos/modules/services/backup/restic.nix
@@ -195,6 +195,7 @@ in
Extra arguments passed to restic backup.
'';
example = [
+ "--cleanup-cache"
"--exclude-file=/etc/nixos/restic-ignore"
];
};
@@ -352,6 +353,7 @@ in
filesFromTmpFile = "/run/restic-backups-${name}/includes";
doBackup = (backup.dynamicFilesFrom != null) || (backup.paths != null && backup.paths != [ ]);
pruneCmd = lib.optionals (builtins.length backup.pruneOpts > 0) [
+ (resticCmd + " unlock")
(resticCmd + " forget --prune " + (lib.concatStringsSep " " backup.pruneOpts))
];
checkCmd = lib.optionals backup.runCheck [
diff --git a/nixos/modules/services/misc/soft-serve.nix b/nixos/modules/services/misc/soft-serve.nix
index e9719c02e41e..0c34d27d7542 100644
--- a/nixos/modules/services/misc/soft-serve.nix
+++ b/nixos/modules/services/misc/soft-serve.nix
@@ -59,6 +59,8 @@ in
environment.SOFT_SERVE_DATA_PATH = stateDir;
+ restartTriggers = [ configFile ];
+
serviceConfig = {
Type = "simple";
DynamicUser = true;
diff --git a/nixos/modules/services/monitoring/nezha-agent.nix b/nixos/modules/services/monitoring/nezha-agent.nix
index 035485a939b8..87ecbfdde710 100644
--- a/nixos/modules/services/monitoring/nezha-agent.nix
+++ b/nixos/modules/services/monitoring/nezha-agent.nix
@@ -6,6 +6,11 @@
}:
let
cfg = config.services.nezha-agent;
+
+ # nezha-agent uses yaml as the configuration file format.
+ # Since we need to use jq to update the content, so here we generate json
+ settingsFormat = pkgs.formats.json { };
+ configFile = settingsFormat.generate "config.json" cfg.settings;
in
{
meta = {
@@ -16,141 +21,280 @@ in
enable = lib.mkEnableOption "Agent of Nezha Monitoring";
package = lib.mkPackageOption pkgs "nezha-agent" { };
+
debug = lib.mkEnableOption "verbose log";
- tls = lib.mkOption {
+
+ settings = lib.mkOption {
+ description = ''
+ Generate to {file}`config.json` as a Nix attribute set.
+ Check the [guide](https://nezha.wiki/en_US/guide/agent.html)
+ for possible options.
+ '';
+ type = lib.types.submodule {
+ freeformType = settingsFormat.type;
+
+ options = {
+ disable_command_execute = lib.mkOption {
+ type = lib.types.bool;
+ default = true;
+ description = ''
+ Disable executing the command from dashboard.
+ '';
+ };
+ disable_nat = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = ''
+ Disable NAT penetration.
+ '';
+ };
+ disable_send_query = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = ''
+ Disable sending TCP/ICMP/HTTP requests.
+ '';
+ };
+ gpu = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = ''
+ Enable GPU monitoring.
+ '';
+ };
+ tls = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = ''
+ Enable SSL/TLS encryption.
+ '';
+ };
+ temperature = lib.mkOption {
+ type = lib.types.bool;
+ default = true;
+ description = ''
+ Enable temperature monitoring.
+ '';
+ };
+ use_ipv6_country_code = lib.mkOption {
+ type = lib.types.bool;
+ default = true;
+ description = ''
+ Use ipv6 countrycode to report location.
+ '';
+ };
+ skip_connection_count = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = ''
+ Do not monitor the number of connections.
+ '';
+ };
+ skip_procs_count = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = ''
+ Do not monitor the number of processes.
+ '';
+ };
+ report_delay = lib.mkOption {
+ type = lib.types.enum [
+ 1
+ 2
+ 3
+ 4
+ ];
+ default = 3;
+ description = ''
+ The interval between system status reportings.
+ The value must be an integer from 1 to 4.
+ '';
+ };
+ server = lib.mkOption {
+ type = lib.types.str;
+ example = "127.0.0.1:8008";
+ description = ''
+ Address to the dashboard.
+ '';
+ };
+ uuid = lib.mkOption {
+ type = with lib.types; nullOr str;
+ # pre-defined uuid of Dns in RFC 4122
+ example = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
+ default = null;
+ description = ''
+ Must be set to a unique identifier, preferably a UUID according to
+ RFC 4122. UUIDs can be generated with `uuidgen` command, found in
+ the `util-linux` package.
+
+ Set {option}`services.nezha-agent.genUuid` to true to generate uuid
+ from {option}`networking.fqdn` automatically.
+ '';
+ };
+ };
+ };
+ };
+
+ genUuid = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
- Enable SSL/TLS encryption.
+ Whether to generate uuid from fqdn automatically.
+ Please note that changes in hostname/domain will result in different uuid.
'';
};
- gpu = lib.mkOption {
- type = lib.types.bool;
- default = true;
- description = ''
- Enable GPU monitoring.
- '';
- };
- temperature = lib.mkOption {
- type = lib.types.bool;
- default = true;
- description = ''
- Enable temperature monitoring.
- '';
- };
- useIPv6CountryCode = lib.mkOption {
- type = lib.types.bool;
- default = true;
- description = ''
- Use ipv6 countrycode to report location.
- '';
- };
- disableCommandExecute = lib.mkOption {
- type = lib.types.bool;
- default = true;
- description = ''
- Disable executing the command from dashboard.
- '';
- };
- disableNat = lib.mkOption {
- type = lib.types.bool;
- default = false;
- description = ''
- Disable NAT penetration.
- '';
- };
- disableSendQuery = lib.mkOption {
- type = lib.types.bool;
- default = false;
- description = ''
- Disable sending TCP/ICMP/HTTP requests.
- '';
- };
- skipConnection = lib.mkOption {
- type = lib.types.bool;
- default = false;
- description = ''
- Do not monitor the number of connections.
- '';
- };
- skipProcess = lib.mkOption {
- type = lib.types.bool;
- default = false;
- description = ''
- Do not monitor the number of processes.
- '';
- };
- reportDelay = lib.mkOption {
- type = lib.types.enum [
- 1
- 2
- 3
- 4
- ];
- default = 1;
- description = ''
- The interval between system status reportings.
- The value must be an integer from 1 to 4
- '';
- };
- passwordFile = lib.mkOption {
- type = with lib.types; nullOr str;
+
+ clientSecretFile = lib.mkOption {
+ type = with lib.types; nullOr path;
default = null;
description = ''
- Path to the file contained the password from dashboard.
- '';
- };
- server = lib.mkOption {
- type = lib.types.str;
- description = ''
- Address to the dashboard
- '';
- };
- extraFlags = lib.mkOption {
- type = lib.types.listOf lib.types.str;
- default = [ ];
- example = [ "--gpu" ];
- description = ''
- Extra command-line flags passed to nezha-agent.
+ Path to the file contained the client_secret of the dashboard.
'';
};
};
};
+ imports = with lib; [
+ (mkRenamedOptionModule
+ [ "services" "nezha-agent" "disableCommandExecute" ]
+ [ "services" "nezha-agent" "settings" "disable_command_execute" ]
+ )
+ (mkRenamedOptionModule
+ [ "services" "nezha-agent" "disableNat" ]
+ [ "services" "nezha-agent" "settings" "disable_nat" ]
+ )
+ (mkRenamedOptionModule
+ [ "services" "nezha-agent" "disableSendQuery" ]
+ [ "services" "nezha-agent" "settings" "disable_send_query" ]
+ )
+ (mkRenamedOptionModule
+ [ "services" "nezha-agent" "gpu" ]
+ [ "services" "nezha-agent" "settings" "gpu" ]
+ )
+ (mkRenamedOptionModule
+ [ "services" "nezha-agent" "tls" ]
+ [ "services" "nezha-agent" "settings" "tls" ]
+ )
+ (mkRenamedOptionModule
+ [ "services" "nezha-agent" "temperature" ]
+ [ "services" "nezha-agent" "settings" "temperature" ]
+ )
+ (mkRenamedOptionModule
+ [ "services" "nezha-agent" "useIPv6CountryCode" ]
+ [ "services" "nezha-agent" "settings" "use_ipv6_country_code" ]
+ )
+ (mkRenamedOptionModule
+ [ "services" "nezha-agent" "skipConnection" ]
+ [ "services" "nezha-agent" "settings" "skip_connection_count" ]
+ )
+ (mkRenamedOptionModule
+ [ "services" "nezha-agent" "skipProcess" ]
+ [ "services" "nezha-agent" "settings" "skip_procs_count" ]
+ )
+ (mkRenamedOptionModule
+ [ "services" "nezha-agent" "reportDelay" ]
+ [ "services" "nezha-agent" "settings" "report_delay" ]
+ )
+ (mkRenamedOptionModule
+ [ "services" "nezha-agent" "server" ]
+ [ "services" "nezha-agent" "settings" "server" ]
+ )
+ (lib.mkRemovedOptionModule [ "services" "nezha-agent" "extraFlags" ] ''
+ Use `services.nezha-agent.settings` instead.
+
+ Nezha-agent v1 is no longer configured via command line flags.
+ '')
+ (lib.mkRemovedOptionModule [ "services" "nezha-agent" "passwordFile" ] ''
+ Use `services.nezha-agent.clientSecretFile` instead.
+
+ Nezha-agent v1 uses the client secret from the dashboard to connect.
+ '')
+ ];
+
config = lib.mkIf cfg.enable {
- systemd.packages = [ cfg.package ];
+ assertions = [
+ {
+ assertion = cfg.settings.uuid == null -> cfg.genUuid;
+ message = "Please set `service.nezha-agent.settings.uuid` while `genUuid` is false.";
+ }
+ {
+ assertion = cfg.settings.uuid != null -> !cfg.genUuid;
+ message = "When `service.nezha-agent.genUuid = true`, `settings.uuid` cannot be set.";
+ }
+ ];
+
+ services.nezha-agent.settings = {
+ debug = cfg.debug;
+ # Automatic updates should never be enabled in NixOS.
+ disable_auto_update = true;
+ disable_force_update = true;
+ };
systemd.services.nezha-agent = {
serviceConfig = {
- ProtectSystem = "full";
- PrivateDevices = "yes";
- PrivateTmp = "yes";
+ Restart = "on-failure";
+ StateDirectory = "nezha-agent";
+ RuntimeDirectory = "nezha-agent";
+ WorkingDirectory = "/var/lib/nezha-agent";
+ ReadWritePaths = "/var/lib/nezha-agent";
+
+ LoadCredential = lib.optionalString (
+ cfg.clientSecretFile != null
+ ) "client-secret:${cfg.clientSecretFile}";
+
+ # Hardening
+ ProcSubset = "all"; # Needed to get host information
+ DynamicUser = true;
+ RemoveIPC = true;
+ LockPersonality = true;
+ ProtectClock = true;
+ MemoryDenyWriteExecute = true;
+ PrivateUsers = true;
+ ProtectHostname = true;
+ RestrictSUIDSGID = true;
+ AmbientCapabilities = [ ];
+ CapabilityBoundingSet = "";
NoNewPrivileges = true;
+ PrivateTmp = true;
+ ProtectControlGroups = true;
+ ProtectHome = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ ProtectProc = "invisible";
+ ProtectSystem = "strict";
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ SystemCallArchitectures = "native";
+ UMask = "0066";
+ SystemCallFilter = [
+ "@system-service"
+ "~@privileged"
+ ];
+ RestrictAddressFamilies = [
+ "AF_INET"
+ "AF_INET6"
+ ];
+ PrivateDevices = "yes";
};
- path = [ cfg.package ];
+ environment.HOME = "/var/lib/nezha-agent";
+ enableStrictShellChecks = true;
startLimitIntervalSec = 10;
startLimitBurst = 3;
- script = lib.concatStringsSep " " (
- [
- "${lib.getExe cfg.package}"
- "--disable-auto-update"
- "--disable-force-update"
- "--password $(cat ${cfg.passwordFile})"
- ]
- ++ lib.optional cfg.debug "--debug"
- ++ lib.optional cfg.disableCommandExecute "--disable-command-execute"
- ++ lib.optional cfg.disableNat "--disable-nat"
- ++ lib.optional cfg.disableSendQuery "--disable-send-query"
- ++ lib.optional (cfg.reportDelay != null) "--report-delay ${toString cfg.reportDelay}"
- ++ lib.optional (cfg.server != null) "--server ${cfg.server}"
- ++ lib.optional cfg.skipConnection "--skip-conn"
- ++ lib.optional cfg.skipProcess "--skip-procs"
- ++ lib.optional cfg.tls "--tls"
- ++ lib.optional cfg.gpu "--gpu"
- ++ lib.optional cfg.temperature "--temperature"
- ++ lib.optional cfg.useIPv6CountryCode "--use-ipv6-countrycode"
- ++ cfg.extraFlags
- );
+ script = ''
+ cp "${configFile}" "''${RUNTIME_DIRECTORY}"/config.json
+ ${lib.optionalString (cfg.clientSecretFile != null) ''
+ ${lib.getExe pkgs.jq} --arg client_secret "$(<"''${CREDENTIALS_DIRECTORY}"/client-secret)" \
+ '. + { client_secret: $client_secret }' < "''${RUNTIME_DIRECTORY}"/config.json > "''${RUNTIME_DIRECTORY}"/config.json.tmp
+ mv "''${RUNTIME_DIRECTORY}"/config.json.tmp "''${RUNTIME_DIRECTORY}"/config.json
+ ''}
+ ${lib.optionalString cfg.genUuid ''
+ ${lib.getExe pkgs.jq} --arg uuid "$(${lib.getExe' pkgs.util-linux "uuidgen"} --md5 -n @dns -N "${config.networking.fqdn}")" \
+ '. + { uuid: $uuid }' < "''${RUNTIME_DIRECTORY}"/config.json > "''${RUNTIME_DIRECTORY}"/config.json.tmp
+ mv "''${RUNTIME_DIRECTORY}"/config.json.tmp "''${RUNTIME_DIRECTORY}"/config.json
+ ''}
+ ${lib.getExe cfg.package} --config "''${RUNTIME_DIRECTORY}"/config.json
+ '';
wantedBy = [ "multi-user.target" ];
};
};
diff --git a/nixos/modules/services/web-apps/part-db.nix b/nixos/modules/services/web-apps/part-db.nix
new file mode 100644
index 000000000000..c165969aa620
--- /dev/null
+++ b/nixos/modules/services/web-apps/part-db.nix
@@ -0,0 +1,247 @@
+{
+ pkgs,
+ config,
+ lib,
+ ...
+}:
+let
+ cfg = config.services.part-db;
+ pkg = cfg.package;
+
+ inherit (lib)
+ mkEnableOption
+ mkPackageOption
+ mkOption
+ types
+ mkIf
+ ;
+in
+{
+ meta.maintainers = with lib.maintainers; [ felbinger ];
+
+ options.services.part-db = {
+ enable = mkEnableOption "PartDB";
+
+ package = mkPackageOption pkgs "part-db" { };
+
+ phpPackage = mkPackageOption pkgs "php" { } // {
+ apply =
+ pkg:
+ pkg.override {
+ extraConfig = ''
+ memory_limit = 256M;
+ '';
+ };
+ };
+
+ enableNginx = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether to enable nginx or not. If enabled, an nginx virtual host will
+ be created for access to part-db. If not enabled, then you may use
+ `''${config.services.part-db.package}/public` as your document root in
+ whichever webserver you wish to setup.
+ '';
+ };
+
+ enablePostgresql = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether to configure the postgresql database for part-db. If enabled,
+ a database and user will be created for part-db.
+ '';
+ };
+
+ virtualHost = mkOption {
+ type = types.str;
+ default = "localhost";
+ description = ''
+ The virtualHost at which you wish part-db to be served.
+ '';
+ };
+
+ poolConfig = lib.mkOption {
+ type = lib.types.attrsOf (
+ lib.types.oneOf [
+ lib.types.str
+ lib.types.int
+ lib.types.bool
+ ]
+ );
+ default = { };
+ defaultText = ''
+ {
+ "pm" = "dynamic";
+ "pm.max_children" = 32;
+ "pm.start_servers" = 2;
+ "pm.min_spare_servers" = 2;
+ "pm.max_spare_servers" = 4;
+ "pm.max_requests" = 500;
+ }
+ '';
+ description = ''
+ Options for the PartDB PHP pool. See the documentation on php-fpm.conf
+ for details on configuration directives.
+ '';
+ };
+
+ settings = lib.mkOption {
+ default = { };
+ description = ''
+ Options for part-db configuration. Refer to
+ for
+ details on supported values. All