···254 inherit
255 lib
256 options
257- config
258 specialArgs
259 ;
260 _class = class;
261 _prefix = prefix;
0262 }
263 // specialArgs
264 );
···651 # evaluation of the option.
652 context = name: ''while evaluating the module argument `${name}' in "${key}":'';
653 extraArgs = mapAttrs (
654- name: _: addErrorContext (context name) (args.${name} or config._module.args.${name})
000000655 ) (functionArgs f);
656657 # Note: we append in the opposite order such that we can add an error
···254 inherit
255 lib
256 options
0257 specialArgs
258 ;
259 _class = class;
260 _prefix = prefix;
261+ config = addErrorContext "if you get an infinite recursion here, you probably reference `config` in `imports`. If you are trying to achieve a conditional import behavior dependent on `config`, consider importing unconditionally, and using `mkEnableOption` and `mkIf` to control its effect." config;
262 }
263 // specialArgs
264 );
···651 # evaluation of the option.
652 context = name: ''while evaluating the module argument `${name}' in "${key}":'';
653 extraArgs = mapAttrs (
654+ name: _:
655+ addErrorContext (context name) (
656+ args.${name} or (addErrorContext
657+ "noting that argument `${name}` is not externally provided, so querying `_module.args` instead, requiring `config`"
658+ config._module.args.${name}
659+ )
660+ )
661 ) (functionArgs f);
662663 # Note: we append in the opposite order such that we can add an error
+35-3
lib/tests/modules.sh
···82 fi
83}
8400000000000000000000000085checkConfigError() {
86 local errorContains=$1
87 local err=""
···94 logFailure
95 logEndFailure
96 else
0000000097 if echo "$err" | grep -zP --silent "$errorContains" ; then
98 ((++pass))
99 else
···283# Check that using _module.args on imports cause infinite recursions, with
284# the proper error context.
285set -- "$@" ./define-_module-args-custom.nix ./import-custom-arg.nix
286-checkConfigError 'while evaluating the module argument .*custom.* in .*import-custom-arg.nix.*:' "$@"
287-checkConfigError 'infinite recursion encountered' "$@"
288289# Check _module.check.
290set -- config.enable ./declare-enable.nix ./define-enable.nix ./define-attrsOfSub-foo.nix
···488checkConfigOutput '^null$' config.foo ./freeform-attrsOf.nix ./freeform-str-dep-unstr.nix
489checkConfigOutput '^"24"$' config.foo ./freeform-attrsOf.nix ./freeform-str-dep-unstr.nix ./define-value-string.nix
490# Check whether an freeform-typed value can depend on a declared option, this can only work with lazyAttrsOf
491-checkConfigError 'infinite recursion encountered' config.foo ./freeform-attrsOf.nix ./freeform-unstr-dep-str.nix
492checkConfigError 'The option .* was accessed but has no value defined. Try setting the option.' config.foo ./freeform-lazyAttrsOf.nix ./freeform-unstr-dep-str.nix
493checkConfigOutput '^"24"$' config.foo ./freeform-lazyAttrsOf.nix ./freeform-unstr-dep-str.nix ./define-value-string.nix
494# submodules in freeformTypes should have their locations annotated
···82 fi
83}
8485+invertIfUnset() {
86+ gate="$1"
87+ shift
88+ if [[ -n "${!gate:-}" ]]; then
89+ "$@"
90+ else
91+ ! "$@"
92+ fi
93+}
94+95+globalErrorLogCheck() {
96+ invertIfUnset "REQUIRE_INFINITE_RECURSION_HINT" \
97+ grep -i 'if you get an infinite recursion here' \
98+ <<<"$err" >/dev/null \
99+ || {
100+ if [[ -n "${REQUIRE_INFINITE_RECURSION_HINT:-}" ]]; then
101+ echo "Unexpected infinite recursion hint"
102+ else
103+ echo "Expected infinite recursion hint, but none found"
104+ fi
105+ return 1
106+ }
107+}
108+109checkConfigError() {
110 local errorContains=$1
111 local err=""
···118 logFailure
119 logEndFailure
120 else
121+ if ! globalErrorLogCheck "$err"; then
122+ logStartFailure
123+ echo "LOG:"
124+ reportFailure "$@"
125+ echo "GLOBAL ERROR LOG CHECK FAILED"
126+ logFailure
127+ logEndFailure
128+ fi
129 if echo "$err" | grep -zP --silent "$errorContains" ; then
130 ((++pass))
131 else
···315# Check that using _module.args on imports cause infinite recursions, with
316# the proper error context.
317set -- "$@" ./define-_module-args-custom.nix ./import-custom-arg.nix
318+REQUIRE_INFINITE_RECURSION_HINT=1 checkConfigError 'while evaluating the module argument .*custom.* in .*import-custom-arg.nix.*:' "$@"
319+REQUIRE_INFINITE_RECURSION_HINT=1 checkConfigError 'infinite recursion encountered' "$@"
320321# Check _module.check.
322set -- config.enable ./declare-enable.nix ./define-enable.nix ./define-attrsOfSub-foo.nix
···520checkConfigOutput '^null$' config.foo ./freeform-attrsOf.nix ./freeform-str-dep-unstr.nix
521checkConfigOutput '^"24"$' config.foo ./freeform-attrsOf.nix ./freeform-str-dep-unstr.nix ./define-value-string.nix
522# Check whether an freeform-typed value can depend on a declared option, this can only work with lazyAttrsOf
523+REQUIRE_INFINITE_RECURSION_HINT=1 checkConfigError 'infinite recursion encountered' config.foo ./freeform-attrsOf.nix ./freeform-unstr-dep-str.nix
524checkConfigError 'The option .* was accessed but has no value defined. Try setting the option.' config.foo ./freeform-lazyAttrsOf.nix ./freeform-unstr-dep-str.nix
525checkConfigOutput '^"24"$' config.foo ./freeform-lazyAttrsOf.nix ./freeform-unstr-dep-str.nix ./define-value-string.nix
526# submodules in freeformTypes should have their locations annotated
+2
nixos/doc/manual/release-notes/rl-2511.section.md
···133134- [`services.victorialogs.package`](#opt-services.victorialogs.package) now defaults to `victorialogs`, as `victoriametrics` no longer contains the VictoriaLogs binaries.
13500136- The `wstunnel` module was converted to RFC42-style settings, you will need to update your NixOS config if you make use of this module.
137138- [private-gpt](https://github.com/zylon-ai/private-gpt) service has been removed by lack of maintenance upstream.
···133134- [`services.victorialogs.package`](#opt-services.victorialogs.package) now defaults to `victorialogs`, as `victoriametrics` no longer contains the VictoriaLogs binaries.
135136+- The `services.traccar.settings` attribute has been reworked. Instead of the previous flat attribute set the new implementation uses nested attribute sets. You need to update you configuration manually. For instance, `services.traccar.settings.loggerConsole` becomes `services.traccar.settings.logger.console`.
137+138- The `wstunnel` module was converted to RFC42-style settings, you will need to update your NixOS config if you make use of this module.
139140- [private-gpt](https://github.com/zylon-ai/private-gpt) service has been removed by lack of maintenance upstream.
+1-2
nixos/modules/profiles/installation-device.nix
···102 boot.kernel.sysctl."vm.overcommit_memory" = "1";
103104 # To speed up installation a little bit, include the complete
105- # stdenv in the Nix store on the CD.
106 system.extraDependencies =
107 with pkgs;
108 [
109- stdenv
110 stdenvNoCC # for runCommand
111 busybox
112 # For boot.initrd.systemd
···102 boot.kernel.sysctl."vm.overcommit_memory" = "1";
103104 # To speed up installation a little bit, include the complete
105+ # stdenvNoCC in the Nix store on the CD.
106 system.extraDependencies =
107 with pkgs;
108 [
0109 stdenvNoCC # for runCommand
110 busybox
111 # For boot.initrd.systemd
···4 pkgs,
5 ...
6}:
7+let
8+ cfg = config.security.auditd;
910+ settingsType =
11+ with lib.types;
12+ nullOr (oneOf [
13+ bool
14+ nonEmptyStr
15+ path
16+ int
17+ ]);
18+19+ pluginOptions = lib.types.submodule {
20+ options = {
21+ active = lib.mkEnableOption "Whether to enable this plugin";
22+ direction = lib.mkOption {
23+ type = lib.types.enum [
24+ "in"
25+ "out"
26+ ];
27+ default = "out";
28+ description = ''
29+ The option is dictated by the plugin. In or out are the only choices.
30+ You cannot make a plugin operate in a way it wasn't designed just by
31+ changing this option. This option is to give a clue to the event dispatcher
32+ about which direction events flow.
33+34+ ::: {.note}
35+ Inbound events are not supported yet.
36+ :::
37+ '';
38+ };
39+ path = lib.mkOption {
40+ type = lib.types.path;
41+ description = "This is the absolute path to the plugin executable.";
42+ };
43+ type = lib.mkOption {
44+ type = lib.types.enum [ "always" ];
45+ readOnly = true;
46+ default = "always";
47+ description = ''
48+ This tells the dispatcher how the plugin wants to be run. There is only
49+ one valid option, `always`, which means the plugin is external and should
50+ always be run. The default is `always` since there are no more builtin plugins.
51+ '';
52+ };
53+ args = lib.mkOption {
54+ type = lib.types.nullOr (lib.types.listOf lib.types.nonEmptyStr);
55+ default = null;
56+ description = ''
57+ This allows you to pass arguments to the child program.
58+ Generally plugins do not take arguments and have their own
59+ config file that instructs them how they should be configured.
60+ '';
61+ };
62+ format = lib.mkOption {
63+ type = lib.types.enum [
64+ "binary"
65+ "string"
66+ ];
67+ default = "string";
68+ description = ''
69+ Binary passes the data exactly as the audit event dispatcher gets it from
70+ the audit daemon. The string option tells the dispatcher to completely change
71+ the event into a string suitable for parsing with the audit parsing library.
72+ '';
73+ };
74+ settings = lib.mkOption {
75+ type = lib.types.nullOr (
76+ lib.types.submodule {
77+ freeformType = lib.types.attrsOf settingsType;
78+ }
79+ );
80+ default = null;
81+ description = "Plugin-specific config file to link to /etc/audit/<plugin>.conf";
82+ };
83+ };
84+ };
85+86+ prepareConfigValue =
87+ v:
88+ if lib.isBool v then
89+ (if v then "yes" else "no")
90+ else if lib.isList v then
91+ lib.concatStringsSep " " (map prepareConfigValue v)
92+ else
93+ builtins.toString v;
94+ prepareConfigText =
95+ conf:
96+ lib.concatLines (
97+ lib.mapAttrsToList (k: v: if v == null then "#${k} =" else "${k} = ${prepareConfigValue v}") conf
98+ );
99+in
100{
101+ options.security.auditd = {
102+ enable = lib.mkEnableOption "the Linux Audit daemon";
103104+ settings = lib.mkOption {
105+ type = lib.types.submodule {
106+ freeformType = lib.types.attrsOf settingsType;
107+ options = {
108+ # space_left needs to be larger than admin_space_left, yet they default to be the same if left open.
109+ space_left = lib.mkOption {
110+ type = lib.types.either lib.types.int (lib.types.strMatching "[0-9]+%");
111+ default = 75;
112+ description = ''
113+ If the free space in the filesystem containing log_file drops below this value, the audit daemon takes the action specified by
114+ {option}`space_left_action`. If the value of {option}`space_left` is specified as a whole number, it is interpreted as an absolute size in mebibytes
115+ (MiB). If the value is specified as a number between 1 and 99 followed by a percentage sign (e.g., 5%), the audit daemon calculates
116+ the absolute size in megabytes based on the size of the filesystem containing {option}`log_file`. (E.g., if the filesystem containing
117+ {option}`log_file` is 2 gibibytes in size, and {option}`space_left` is set to 25%, then the audit daemon sets {option}`space_left` to approximately 500 mebibytes.
118+119+ ::: {.note}
120+ This calculation is performed when the audit daemon starts, so if you resize the filesystem containing {option}`log_file` while the
121+ audit daemon is running, you should send the audit daemon SIGHUP to re-read the configuration file and recalculate the correct per‐
122+ centage.
123+ :::
124+ '';
125+ };
126+ admin_space_left = lib.mkOption {
127+ type = lib.types.either lib.types.int (lib.types.strMatching "[0-9]+%");
128+ default = 50;
129+ description = ''
130+ This is a numeric value in mebibytes (MiB) that tells the audit daemon when to perform a configurable action because the system is running
131+ low on disk space. This should be considered the last chance to do something before running out of disk space. The numeric value for
132+ this parameter should be lower than the number for {option}`space_left`. You may also append a percent sign (e.g. 1%) to the number to have
133+ the audit daemon calculate the number based on the disk partition size.
134+ '';
135+ };
136+ };
137+ };
138+139+ default = { };
140+ description = "auditd configuration file contents. See {auditd.conf} for supported values.";
141+ };
142+143+ plugins = lib.mkOption {
144+ type = lib.types.attrsOf pluginOptions;
145+ default = { };
146+ defaultText = lib.literalExpression ''
147+ {
148+ af_unix = {
149+ path = lib.getExe' pkgs.audit "audisp-af_unix";
150+ args = [
151+ "0640"
152+ "/var/run/audispd_events"
153+ "string"
154+ ];
155+ format = "binary";
156+ };
157+ remote = {
158+ path = lib.getExe' pkgs.audit "audisp-remote";
159+ settings = { };
160+ };
161+ filter = {
162+ path = lib.getExe' pkgs.audit "audisp-filter";
163+ args = [
164+ "allowlist"
165+ "/etc/audit/audisp-filter.conf"
166+ (lib.getExe' pkgs.audit "audisp-syslog")
167+ "LOG_USER"
168+ "LOG_INFO"
169+ "interpret"
170+ ];
171+ settings = { };
172+ };
173+ syslog = {
174+ path = lib.getExe' pkgs.audit "audisp-syslog";
175+ args = [ "LOG_INFO" ];
176+ };
177+ }
178+ '';
179+ description = "Plugin definitions to register with auditd";
180+ };
181+ };
182+183+ config = lib.mkIf cfg.enable {
184+ assertions = [
185+ {
186+ assertion =
187+ let
188+ cfg' = cfg.settings;
189+ in
190+ (
191+ (lib.isInt cfg'.space_left && lib.isInt cfg'.admin_space_left)
192+ -> cfg'.space_left > cfg'.admin_space_left
193+ )
194+ && (
195+ let
196+ get_percent = s: lib.toInt (lib.strings.removeSuffix "%" s);
197+ in
198+ (lib.isString cfg'.space_left && lib.isString cfg'.admin_space_left)
199+ -> (get_percent cfg'.space_left) > (get_percent cfg'.admin_space_left)
200+ );
201+ message = "`security.auditd.settings.space_left` must be larger than `security.auditd.settings.admin_space_left`";
202+ }
203+ ];
204+205 # Starting auditd should also enable loading the audit rules..
206 security.audit.enable = lib.mkDefault true;
207208 environment.systemPackages = [ pkgs.audit ];
209+210+ # setting this to anything other than /etc/audit/plugins.d will break, so we pin it here
211+ security.auditd.settings.plugin_dir = "/etc/audit/plugins.d";
212+213+ environment.etc = {
214+ "audit/auditd.conf".text = prepareConfigText cfg.settings;
215+ }
216+ // (lib.mapAttrs' (
217+ pluginName: pluginDefinitionConfigValue:
218+ lib.nameValuePair "audit/plugins.d/${pluginName}.conf" {
219+ text = prepareConfigText (lib.removeAttrs pluginDefinitionConfigValue [ "settings" ]);
220+ }
221+ ) cfg.plugins)
222+ // (lib.mapAttrs' (
223+ pluginName: pluginDefinitionConfigValue:
224+ lib.nameValuePair "audit/audisp-${pluginName}.conf" {
225+ text = prepareConfigText pluginDefinitionConfigValue.settings;
226+ }
227+ ) (lib.filterAttrs (_: v: v.settings != null) cfg.plugins));
228+229+ security.auditd.plugins = {
230+ af_unix = {
231+ path = lib.getExe' pkgs.audit "audisp-af_unix";
232+ args = [
233+ "0640"
234+ "/var/run/audispd_events"
235+ "string"
236+ ];
237+ format = "binary";
238+ };
239+ remote = {
240+ path = lib.getExe' pkgs.audit "audisp-remote";
241+ settings = { };
242+ };
243+ filter = {
244+ path = lib.getExe' pkgs.audit "audisp-filter";
245+ args = [
246+ "allowlist"
247+ "/etc/audit/audisp-filter.conf"
248+ (lib.getExe' pkgs.audit "audisp-syslog")
249+ "LOG_USER"
250+ "LOG_INFO"
251+ "interpret"
252+ ];
253+ settings = { };
254+ };
255+ syslog = {
256+ path = lib.getExe' pkgs.audit "audisp-syslog";
257+ args = [ "LOG_INFO" ];
258+ };
259+ };
260261 systemd.services.auditd = {
262 description = "Security Audit Logging Service";
+37-19
nixos/modules/services/monitoring/traccar.nix
···8 cfg = config.services.traccar;
9 stateDirectory = "/var/lib/traccar";
10 configFilePath = "${stateDirectory}/config.xml";
11- expandCamelCase = lib.replaceStrings lib.upperChars (map (s: ".${s}") lib.lowerChars);
12- mkConfigEntry = key: value: "<entry key='${expandCamelCase key}'>${value}</entry>";
000000013 mkConfig =
14 configurationOptions:
15 pkgs.writeText "traccar.xml" ''
16 <?xml version='1.0' encoding='UTF-8'?>
17 <!DOCTYPE properties SYSTEM 'http://java.sun.com/dtd/properties.dtd'>
18 <properties>
19- ${builtins.concatStringsSep "\n" (lib.mapAttrsToList mkConfigEntry configurationOptions)}
20 </properties>
21 '';
2223 defaultConfig = {
24- databaseDriver = "org.h2.Driver";
25- databasePassword = "";
26- databaseUrl = "jdbc:h2:${stateDirectory}/traccar";
27- databaseUser = "sa";
28- loggerConsole = "true";
29- mediaPath = "${stateDirectory}/media";
30- templatesRoot = "${stateDirectory}/templates";
0031 };
032in
33{
34 options.services.traccar = {
35 enable = lib.mkEnableOption "Traccar, an open source GPS tracking system";
000000036 settings = lib.mkOption {
37 apply = lib.recursiveUpdate defaultConfig;
38 default = defaultConfig;
39 description = ''
40 {file}`config.xml` configuration as a Nix attribute set.
41- Attribute names are translated from camelCase to dot-separated strings. For instance:
42- {option}`mailSmtpPort = "25"`
43- would result in the following configuration property:
044 `<entry key='mail.smtp.port'>25</entry>`
45- Configuration options should match those described in
46- [Traccar - Configuration File](https://www.traccar.org/configuration-file/).
47- Secret tokens should be specified using {option}`environmentFile`
48 instead of this world-readable attribute set.
049 '';
50 };
51 environmentFile = lib.mkOption {
···5657 Can be used for storing the secrets without making them available in the world-readable Nix store.
5859- For example, you can set {option}`services.traccar.settings.databasePassword = "$TRACCAR_DB_PASSWORD"`
60 and then specify `TRACCAR_DB_PASSWORD="<secret>"` in the environment file.
61 This value will get substituted in the configuration file.
62 '';
···6566 config =
67 let
68- configuration = mkConfig cfg.settings;
69 in
70 lib.mkIf cfg.enable {
71 systemd.services.traccar = {
···9293 serviceConfig = {
94 DynamicUser = true;
95- EnvironmentFile = cfg.environmentFile;
96 ExecStart = "${lib.getExe pkgs.traccar} ${configFilePath}";
97 LockPersonality = true;
98 NoNewPrivileges = true;
···8 cfg = config.services.traccar;
9 stateDirectory = "/var/lib/traccar";
10 configFilePath = "${stateDirectory}/config.xml";
11+12+ # Map leafs to XML <entry> elements as expected by traccar, using
13+ # dot-separated keys for nested attribute paths.
14+ mapLeafs = lib.mapAttrsRecursive (
15+ path: value: "<entry key='${lib.concatStringsSep "." path}'>${value}</entry>"
16+ );
17+18+ mkConfigEntry = config: lib.collect builtins.isString (mapLeafs config);
19+20 mkConfig =
21 configurationOptions:
22 pkgs.writeText "traccar.xml" ''
23 <?xml version='1.0' encoding='UTF-8'?>
24 <!DOCTYPE properties SYSTEM 'http://java.sun.com/dtd/properties.dtd'>
25 <properties>
26+ ${builtins.concatStringsSep "\n" (mkConfigEntry configurationOptions)}
27 </properties>
28 '';
2930 defaultConfig = {
31+ database = {
32+ driver = "org.h2.Driver";
33+ password = "";
34+ url = "jdbc:h2:${stateDirectory}/traccar";
35+ user = "sa";
36+ };
37+ logger.console = "true";
38+ media.path = "${stateDirectory}/media";
39+ templates.root = "${stateDirectory}/templates";
40 };
41+42in
43{
44 options.services.traccar = {
45 enable = lib.mkEnableOption "Traccar, an open source GPS tracking system";
46+ settingsFile = lib.mkOption {
47+ type = with lib.types; nullOr path;
48+ default = null;
49+ description = ''
50+ File used as configuration for traccar. When specified, {option}`settings` is ignored.
51+ '';
52+ };
53 settings = lib.mkOption {
54 apply = lib.recursiveUpdate defaultConfig;
55 default = defaultConfig;
56 description = ''
57 {file}`config.xml` configuration as a Nix attribute set.
58+ This option is ignored if `settingsFile` is set.
59+60+ Nested attributes get translated to a properties entry in the traccar configuration.
61+ For instance: `mail.smtp.port = "25"` results in the following entry:
62 `<entry key='mail.smtp.port'>25</entry>`
63+64+ Secrets should be specified using {option}`environmentFile`
065 instead of this world-readable attribute set.
66+ [Traccar - Configuration File](https://www.traccar.org/configuration-file/).
67 '';
68 };
69 environmentFile = lib.mkOption {
···7475 Can be used for storing the secrets without making them available in the world-readable Nix store.
7677+ For example, you can set {option}`services.traccar.settings.database.password = "$TRACCAR_DB_PASSWORD"`
78 and then specify `TRACCAR_DB_PASSWORD="<secret>"` in the environment file.
79 This value will get substituted in the configuration file.
80 '';
···8384 config =
85 let
86+ configuration = if cfg.settingsFile != null then cfg.settingsFile else mkConfig cfg.settings;
87 in
88 lib.mkIf cfg.enable {
89 systemd.services.traccar = {
···110111 serviceConfig = {
112 DynamicUser = true;
113+ EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
114 ExecStart = "${lib.getExe pkgs.traccar} ${configFilePath}";
115 LockPersonality = true;
116 NoNewPrivileges = true;
···709 system.extraDependencies =
710 with pkgs;
711 [
712+ # TODO: Remove this when we can install systems
713+ # without `stdenv`.
714+ stdenv
715+716 bintools
717 brotli
718 brotli.dev
···12 src = fetchFromGitHub {
13 owner = "kubernetes-sigs";
14 repo = "bom";
15- rev = "v${version}";
16 hash = "sha256-nYzBaFtOJhqO0O6MJsxTw/mxsIOa+cnU27nOFRe2/uI=";
17 # populate values that require us to use git. By doing this in postFetch we
18 # can delete .git afterwards and maintain better reproducibility of the src.
···12 src = fetchFromGitHub {
13 owner = "kubernetes-sigs";
14 repo = "bom";
15+ tag = "v${version}";
16 hash = "sha256-nYzBaFtOJhqO0O6MJsxTw/mxsIOa+cnU27nOFRe2/uI=";
17 # populate values that require us to use git. By doing this in postFetch we
18 # can delete .git afterwards and maintain better reproducibility of the src.
···12 src = fetchFromGitHub {
13 owner = "codecrafters-io";
14 repo = "cli";
15- rev = "v${version}";
16 hash = "sha256-YgQPDc5BUIoEd44NLpRluxCKooW99qvcSTrFPm6qJKM=";
17 # A shortened git commit hash is part of the version output, and is
18 # needed at build time. Use the `.git` directory to retrieve the
···12 src = fetchFromGitHub {
13 owner = "codecrafters-io";
14 repo = "cli";
15+ tag = "v${version}";
16 hash = "sha256-YgQPDc5BUIoEd44NLpRluxCKooW99qvcSTrFPm6qJKM=";
17 # A shortened git commit hash is part of the version output, and is
18 # needed at build time. Use the `.git` directory to retrieve the
···20 src = fetchFromGitHub {
21 owner = "sigstore";
22 repo = "fulcio";
23- rev = "v${version}";
24 hash = "sha256-UVUVT4RvNHvzIwV6azu2h1O9lnNu0PQnnkj4wbrY8BA=";
25 # populate values that require us to use git. By doing this in postFetch we
26 # can delete .git afterwards and maintain better reproducibility of the src.
···20 src = fetchFromGitHub {
21 owner = "sigstore";
22 repo = "fulcio";
23+ tag = "v${version}";
24 hash = "sha256-UVUVT4RvNHvzIwV6azu2h1O9lnNu0PQnnkj4wbrY8BA=";
25 # populate values that require us to use git. By doing this in postFetch we
26 # can delete .git afterwards and maintain better reproducibility of the src.
···14 src = fetchFromGitHub {
15 owner = "grdl";
16 repo = "git-get";
17- rev = "v${version}";
18 hash = "sha256-v98Ff7io7j1LLzciHNWJBU3LcdSr+lhwYrvON7QjyCI=";
19 # populate values that require us to use git. By doing this in postFetch we
20 # can delete .git afterwards and maintain better reproducibility of the src.
···14 src = fetchFromGitHub {
15 owner = "grdl";
16 repo = "git-get";
17+ tag = "v${version}";
18 hash = "sha256-v98Ff7io7j1LLzciHNWJBU3LcdSr+lhwYrvON7QjyCI=";
19 # populate values that require us to use git. By doing this in postFetch we
20 # can delete .git afterwards and maintain better reproducibility of the src.
···13 src = fetchFromGitHub {
14 owner = "quarkslab";
15 repo = "kdigger";
16- rev = "v${version}";
17 hash = "sha256-hpLhtTENtOBQjm+CZRAcx1BG9831JUFIsLL57wZIrso=";
18 # populate values that require us to use git. By doing this in postFetch we
19 # can delete .git afterwards and maintain better reproducibility of the src.
···13 src = fetchFromGitHub {
14 owner = "quarkslab";
15 repo = "kdigger";
16+ tag = "v${version}";
17 hash = "sha256-hpLhtTENtOBQjm+CZRAcx1BG9831JUFIsLL57wZIrso=";
18 # populate values that require us to use git. By doing this in postFetch we
19 # can delete .git afterwards and maintain better reproducibility of the src.
···30 src = fetchFromGitHub {
31 owner = "eclipse";
32 repo = "lemminx";
33- rev = version;
34 hash = "sha256-a+9RN1265fsmYAUMuUTxA+VqJv7xPlzuc8HqoZwmR4M=";
35 # Lemminx reads this git information at runtime from a git.properties
36 # file on the classpath
···30 src = fetchFromGitHub {
31 owner = "eclipse";
32 repo = "lemminx";
33+ tag = version;
34 hash = "sha256-a+9RN1265fsmYAUMuUTxA+VqJv7xPlzuc8HqoZwmR4M=";
35 # Lemminx reads this git information at runtime from a git.properties
36 # file on the classpath
···15 src = fetchFromGitHub {
16 owner = "Nitrokey";
17 repo = "libnitrokey";
18- rev = "v${finalAttrs.version}";
19 hash = "sha256-4PEZ31QyVOmdhpKqTN8fwcHoLuu+w+OJ3fZeqwlE+io=";
20 # On OSX, libnitrokey depends on a custom version of hidapi in a submodule.
21 # Monitor https://github.com/Nitrokey/libnitrokey/issues/140 to see if we
···15 src = fetchFromGitHub {
16 owner = "Nitrokey";
17 repo = "libnitrokey";
18+ tag = "v${finalAttrs.version}";
19 hash = "sha256-4PEZ31QyVOmdhpKqTN8fwcHoLuu+w+OJ3fZeqwlE+io=";
20 # On OSX, libnitrokey depends on a custom version of hidapi in a submodule.
21 # Monitor https://github.com/Nitrokey/libnitrokey/issues/140 to see if we
···45 src = fetchFromGitHub {
46 owner = "mltframework";
47 repo = "mlt";
48- rev = "v${version}";
49 hash = "sha256-z1bW+hcVeMeibC1PUS5XNpbkNB+75YLoOWZC2zuDol4=";
50 # The submodule contains glaxnimate code, since MLT uses internally some functions defined in glaxnimate.
51 # Since glaxnimate is not available as a library upstream, we cannot remove for now this dependency on
···45 src = fetchFromGitHub {
46 owner = "mltframework";
47 repo = "mlt";
48+ tag = "v${version}";
49 hash = "sha256-z1bW+hcVeMeibC1PUS5XNpbkNB+75YLoOWZC2zuDol4=";
50 # The submodule contains glaxnimate code, since MLT uses internally some functions defined in glaxnimate.
51 # Since glaxnimate is not available as a library upstream, we cannot remove for now this dependency on
···13 src = fetchFromGitHub {
14 owner = "pdfcpu";
15 repo = "pdfcpu";
16- rev = "v${version}";
17 hash = "sha256-HTqaFl/ug/4sdchZBD4VQiXbD1L0/DVf2efZ3BV/vx4=";
18 # Apparently upstream requires that the compiled executable will know the
19 # commit hash and the date of the commit. This information is also presented
···13 src = fetchFromGitHub {
14 owner = "pdfcpu";
15 repo = "pdfcpu";
16+ tag = "v${version}";
17 hash = "sha256-HTqaFl/ug/4sdchZBD4VQiXbD1L0/DVf2efZ3BV/vx4=";
18 # Apparently upstream requires that the compiled executable will know the
19 # commit hash and the date of the commit. This information is also presented
···16 src = fetchFromGitHub {
17 owner = "F1bonacc1";
18 repo = "process-compose";
19- rev = "v${version}";
20 hash = "sha256-qv/fVfuQD7Nan5Nn1RkwXoGZuPYSRWQaojEn6MCF9BQ=";
21 # populate values that require us to use git. By doing this in postFetch we
22 # can delete .git afterwards and maintain better reproducibility of the src.
···16 src = fetchFromGitHub {
17 owner = "F1bonacc1";
18 repo = "process-compose";
19+ tag = "v${version}";
20 hash = "sha256-qv/fVfuQD7Nan5Nn1RkwXoGZuPYSRWQaojEn6MCF9BQ=";
21 # populate values that require us to use git. By doing this in postFetch we
22 # can delete .git afterwards and maintain better reproducibility of the src.
···13 src = fetchFromGitHub {
14 owner = "mgechev";
15 repo = "revive";
16- rev = "v${version}";
17 hash = "sha256-89BlSc2tgxAJUGZM951fF+0H+SOsl0+xz/G18neRZxI=";
18 # populate values that require us to use git. By doing this in postFetch we
19 # can delete .git afterwards and maintain better reproducibility of the src.
···13 src = fetchFromGitHub {
14 owner = "mgechev";
15 repo = "revive";
16+ tag = "v${version}";
17 hash = "sha256-89BlSc2tgxAJUGZM951fF+0H+SOsl0+xz/G18neRZxI=";
18 # populate values that require us to use git. By doing this in postFetch we
19 # can delete .git afterwards and maintain better reproducibility of the src.
···4041 # if a release is tagged (which sometimes does not happen), it will
42 # be in the format below.
43- rev = "Release-${lib.replaceStrings [ "." ] [ "-" ] version}";
44 hash = "sha256-vrRIirWQLbbe1l07AqqHK/StWo0egKuivdKT5R8Rx58=";
4546 # the repository's .gitattributes file contains the lines "/Tst/
···4041 # if a release is tagged (which sometimes does not happen), it will
42 # be in the format below.
43+ tag = "Release-${lib.replaceStrings [ "." ] [ "-" ] version}";
44 hash = "sha256-vrRIirWQLbbe1l07AqqHK/StWo0egKuivdKT5R8Rx58=";
4546 # the repository's .gitattributes file contains the lines "/Tst/
···16 src = fetchFromGitHub {
17 owner = "aquasecurity";
18 repo = "starboard";
19- rev = "v${finalAttrs.version}";
20 hash = "sha256-yQ4ABzN8EvD5qs0yjTaihM145K79LglprC2nlqAw0XU=";
21 # populate values that require us to use git. By doing this in postFetch we
22 # can delete .git afterwards and maintain better reproducibility of the src.
···16 src = fetchFromGitHub {
17 owner = "aquasecurity";
18 repo = "starboard";
19+ tag = "v${finalAttrs.version}";
20 hash = "sha256-yQ4ABzN8EvD5qs0yjTaihM145K79LglprC2nlqAw0XU=";
21 # populate values that require us to use git. By doing this in postFetch we
22 # can delete .git afterwards and maintain better reproducibility of the src.
···11 log4cpp,
12 openldap,
13 sqlite,
14- nix-update-script,
15}:
1617stdenv.mkDerivation (finalAttrs: {
···25 hash = "sha256-hD1nTyv/t7MQdopqivfSE0o4Qk1ymG8zQVg56lY+t9o=";
26 };
2728- # src/common/logger.h:254:63: error: 'uint8_t' does not name a type
000029 postPatch = ''
30- sed -i "38i #include <cstdint>" src/common/logger.h
000000031 '';
3233 strictDeps = true;
···47 sqlite
48 ];
4950- # Currently doesn't build in `Release` since a macro is messing with some code
51- # when building in `Release`.
52- cmakeBuildType = "Debug";
5354- passthru.updateScript = nix-update-script { };
00005556 meta = {
57 description = "Configuration information distributed over LDAP in near realtime";
···11 log4cpp,
12 openldap,
13 sqlite,
14+ gitUpdater,
15}:
1617stdenv.mkDerivation (finalAttrs: {
···25 hash = "sha256-hD1nTyv/t7MQdopqivfSE0o4Qk1ymG8zQVg56lY+t9o=";
26 };
2728+ patches = [
29+ # https://gitlab.com/arpa2/steamworks/-/merge_requests/13
30+ ./1001-Add-missing-logger-methods.patch
31+ ];
32+33 postPatch = ''
34+ # src/common/logger.h:254:63: error: 'uint8_t' does not name a type
35+ # https://gitlab.com/arpa2/steamworks/-/merge_requests/11
36+ sed -i "40i #include <cstdint>" src/common/logger.h
37+38+ # ld: cannot find -lLog4cpp: No such file or directory
39+ # https://gitlab.com/arpa2/steamworks/-/merge_requests/12
40+ substituteInPlace src/common/CMakeLists.txt \
41+ --replace-fail 'Catch2::Catch2 Log4cpp' 'Catch2::Catch2 Log4cpp::Log4cpp'
42 '';
4344 strictDeps = true;
···58 sqlite
59 ];
6061+ checkInputs = [
62+ catch2
63+ ];
6465+ doCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
66+67+ passthru.updateScript = gitUpdater {
68+ rev-prefix = "v";
69+ };
7071 meta = {
72 description = "Configuration information distributed over LDAP in near realtime";
···58 # Non-NixOS package managers are not present in the build environment.
59 "test_parse_upgradable_list_apt"
60 "test_parse_upgradable_list_dnf"
0061 ];
6263 disabledTestPaths = [ "blocksatgui/tests/" ];
···58 # Non-NixOS package managers are not present in the build environment.
59 "test_parse_upgradable_list_apt"
60 "test_parse_upgradable_list_dnf"
61+ # Fails due to GPG clearsign output lacking trailing newline in some setups.
62+ "test_clearsign_verification"
63 ];
6465 disabledTestPaths = [ "blocksatgui/tests/" ];