···99 problems.
100 :::
101102+`types.pkgs`
103+104+: A type for the top level Nixpkgs package set.
105+106### Numeric types {#sec-option-types-numeric}
107108`types.int`
+15-9
nixos/lib/eval-config.nix
···38in
3940let
0041 evalModulesMinimal = (import ./default.nix {
42 inherit lib;
43 # Implicit use of feature is noted in implementation.
···47 pkgsModule = rec {
48 _file = ./eval-config.nix;
49 key = _file;
50- config = {
51- # Explicit `nixpkgs.system` or `nixpkgs.localSystem` should override
52- # this. Since the latter defaults to the former, the former should
53- # default to the argument. That way this new default could propagate all
54- # they way through, but has the last priority behind everything else.
55- nixpkgs.system = lib.mkIf (system != null) (lib.mkDefault system);
56-57- _module.args.pkgs = lib.mkIf (pkgs_ != null) (lib.mkForce pkgs_);
58- };
000059 };
6061 withWarnings = x:
···38in
3940let
41+ inherit (lib) optional;
42+43 evalModulesMinimal = (import ./default.nix {
44 inherit lib;
45 # Implicit use of feature is noted in implementation.
···49 pkgsModule = rec {
50 _file = ./eval-config.nix;
51 key = _file;
52+ config = lib.mkMerge (
53+ (optional (system != null) {
54+ # Explicit `nixpkgs.system` or `nixpkgs.localSystem` should override
55+ # this. Since the latter defaults to the former, the former should
56+ # default to the argument. That way this new default could propagate all
57+ # they way through, but has the last priority behind everything else.
58+ nixpkgs.system = lib.mkDefault system;
59+ })
60+ ++
61+ (optional (pkgs_ != null) {
62+ _module.args.pkgs = lib.mkForce pkgs_;
63+ })
64+ );
65 };
6667 withWarnings = x:
+51-6
nixos/lib/testing/nodes.nix
···1testModuleArgs@{ config, lib, hostPkgs, nodes, ... }:
23let
4- inherit (lib) mkOption mkForce optional types mapAttrs mkDefault mdDoc;
5-6- system = hostPkgs.stdenv.hostPlatform.system;
00000000078 baseOS =
9 import ../eval-config.nix {
10- inherit system;
11 inherit (config.node) specialArgs;
12 modules = [ config.defaults ];
13 baseModules = (import ../../modules/module-list.nix) ++
···17 ({ config, ... }:
18 {
19 virtualisation.qemu.package = testModuleArgs.config.qemu.package;
20-00021 # Ensure we do not use aliases. Ideally this is only set
22 # when the test framework is used by Nixpkgs NixOS tests.
23 nixpkgs.config.allowAliases = false;
24- })
00025 testModuleArgs.config.extraBaseModules
26 ];
27 };
···68 default = { };
69 };
7000000000000000000000000071 node.specialArgs = mkOption {
72 type = types.lazyAttrsOf types.raw;
73 default = { };
···100 config.nodes;
101102 passthru.nodes = config.nodesCompat;
000000103 };
104}
···1testModuleArgs@{ config, lib, hostPkgs, nodes, ... }:
23let
4+ inherit (lib)
5+ literalExpression
6+ literalMD
7+ mapAttrs
8+ mdDoc
9+ mkDefault
10+ mkIf
11+ mkOption mkForce
12+ optional
13+ optionalAttrs
14+ types
15+ ;
1617 baseOS =
18 import ../eval-config.nix {
19+ system = null; # use modularly defined system
20 inherit (config.node) specialArgs;
21 modules = [ config.defaults ];
22 baseModules = (import ../../modules/module-list.nix) ++
···26 ({ config, ... }:
27 {
28 virtualisation.qemu.package = testModuleArgs.config.qemu.package;
29+ })
30+ (optionalAttrs (!config.node.pkgsReadOnly) {
31+ key = "nodes.nix-pkgs";
32+ config = {
33 # Ensure we do not use aliases. Ideally this is only set
34 # when the test framework is used by Nixpkgs NixOS tests.
35 nixpkgs.config.allowAliases = false;
36+ # TODO: switch to nixpkgs.hostPlatform and make sure containers-imperative test still evaluates.
37+ nixpkgs.system = hostPkgs.stdenv.hostPlatform.system;
38+ };
39+ })
40 testModuleArgs.config.extraBaseModules
41 ];
42 };
···83 default = { };
84 };
8586+ node.pkgs = mkOption {
87+ description = mdDoc ''
88+ The Nixpkgs to use for the nodes.
89+90+ Setting this will make the `nixpkgs.*` options read-only, to avoid mistakenly testing with a Nixpkgs configuration that diverges from regular use.
91+ '';
92+ type = types.nullOr types.pkgs;
93+ default = null;
94+ defaultText = literalMD ''
95+ `null`, so construct `pkgs` according to the `nixpkgs.*` options as usual.
96+ '';
97+ };
98+99+ node.pkgsReadOnly = mkOption {
100+ description = mdDoc ''
101+ Whether to make the `nixpkgs.*` options read-only. This is only relevant when [`node.pkgs`](#test-opt-node.pkgs) is set.
102+103+ Set this to `false` when any of the [`nodes`](#test-opt-nodes) needs to configure any of the `nixpkgs.*` options. This will slow down evaluation of your test a bit.
104+ '';
105+ type = types.bool;
106+ default = config.node.pkgs != null;
107+ defaultText = literalExpression ''node.pkgs != null'';
108+ };
109+110 node.specialArgs = mkOption {
111 type = types.lazyAttrsOf types.raw;
112 default = { };
···139 config.nodes;
140141 passthru.nodes = config.nodesCompat;
142+143+ defaults = mkIf config.node.pkgsReadOnly {
144+ nixpkgs.pkgs = config.node.pkgs;
145+ imports = [ ../../modules/misc/nixpkgs/read-only.nix ];
146+ };
147+148 };
149}
+3-3
nixos/modules/misc/nixpkgs.nix
···49 merge = lib.mergeOneOption;
50 };
5152- pkgsType = mkOptionType {
53- name = "nixpkgs";
054 description = "An evaluation of Nixpkgs; the top level attribute set of packages";
55- check = builtins.isAttrs;
56 };
5758 # Whether `pkgs` was constructed by this module - not if nixpkgs.pkgs or
···49 merge = lib.mergeOneOption;
50 };
5152+ pkgsType = types.pkgs // {
53+ # This type is only used by itself, so let's elaborate the description a bit
54+ # for the purpose of documentation.
55 description = "An evaluation of Nixpkgs; the top level attribute set of packages";
056 };
5758 # Whether `pkgs` was constructed by this module - not if nixpkgs.pkgs or
···1+# A replacement for the traditional nixpkgs module, such that none of the modules
2+# can add their own configuration. This ensures that the Nixpkgs configuration is
3+# exactly as the user intends.
4+# This may also be used as a performance optimization when evaluating multiple
5+# configurations at once, with a shared `pkgs`.
6+7+# This is a separate module, because merging this logic into the nixpkgs module
8+# is too burdensome, considering that it is already burdened with legacy.
9+# Moving this logic into a module does not lose any composition benefits, because
10+# its purpose is not something that composes anyway.
11+12+{ lib, config, ... }:
13+14+let
15+ cfg = config.nixpkgs;
16+ inherit (lib) mkOption types;
17+18+in
19+{
20+ disabledModules = [
21+ ../nixpkgs.nix
22+ ];
23+ options = {
24+ nixpkgs = {
25+ pkgs = mkOption {
26+ type = lib.types.pkgs;
27+ description = lib.mdDoc ''The pkgs module argument.'';
28+ };
29+ config = mkOption {
30+ internal = true;
31+ type = types.unique { message = "nixpkgs.config is set to read-only"; } types.anything;
32+ description = lib.mdDoc ''
33+ The Nixpkgs `config` that `pkgs` was initialized with.
34+ '';
35+ };
36+ overlays = mkOption {
37+ internal = true;
38+ type = types.unique { message = "nixpkgs.overlays is set to read-only"; } types.anything;
39+ description = lib.mdDoc ''
40+ The Nixpkgs overlays that `pkgs` was initialized with.
41+ '';
42+ };
43+ hostPlatform = mkOption {
44+ internal = true;
45+ readOnly = true;
46+ description = lib.mdDoc ''
47+ The platform of the machine that is running the NixOS configuration.
48+ '';
49+ };
50+ buildPlatform = mkOption {
51+ internal = true;
52+ readOnly = true;
53+ description = lib.mdDoc ''
54+ The platform of the machine that built the NixOS configuration.
55+ '';
56+ };
57+ # NOTE: do not add the legacy options such as localSystem here. Let's keep
58+ # this module simple and let module authors upgrade their code instead.
59+ };
60+ };
61+ config = {
62+ _module.args.pkgs =
63+ # find mistaken definitions
64+ builtins.seq cfg.config
65+ builtins.seq cfg.overlays
66+ builtins.seq cfg.hostPlatform
67+ builtins.seq cfg.buildPlatform
68+ cfg.pkgs;
69+ nixpkgs.config = cfg.pkgs.config;
70+ nixpkgs.overlays = cfg.pkgs.overlays;
71+ nixpkgs.hostPlatform = cfg.pkgs.stdenv.hostPlatform;
72+ nixpkgs.buildPlatform = cfg.pkgs.stdenv.buildPlatform;
73+ };
74+}
···46 inherit
47 (rec {
48 doRunTest = arg: ((import ../lib/testing-python.nix { inherit system pkgs; }).evalTest {
49+ imports = [ arg readOnlyPkgs ];
50 }).config.result;
51 findTests = tree:
52 if tree?recurseForDerivations && tree.recurseForDerivations
···64 runTest
65 runTestOn
66 ;
67+68+ # Using a single instance of nixpkgs makes test evaluation faster.
69+ # To make sure we don't accidentally depend on a modified pkgs, we make the
70+ # related options read-only. We need to test the right configuration.
71+ #
72+ # If your service depends on a nixpkgs setting, first try to avoid that, but
73+ # otherwise, you can remove the readOnlyPkgs import and test your service as
74+ # usual.
75+ readOnlyPkgs =
76+ # TODO: We currently accept this for nixosTests, so that the `pkgs` argument
77+ # is consistent with `pkgs` in `pkgs.nixosTests`. Can we reinitialize
78+ # it with `allowAliases = false`?
79+ # warnIf pkgs.config.allowAliases "nixosTests: pkgs includes aliases."
80+ {
81+ _class = "nixosTest";
82+ node.pkgs = pkgs;
83+ };
8485in {
86···284 gitdaemon = handleTest ./gitdaemon.nix {};
285 gitea = handleTest ./gitea.nix { giteaPackage = pkgs.gitea; };
286 github-runner = handleTest ./github-runner.nix {};
287+ gitlab = runTest ./gitlab.nix;
288 gitolite = handleTest ./gitolite.nix {};
289 gitolite-fcgiwrap = handleTest ./gitolite-fcgiwrap.nix {};
290 glusterfs = handleTest ./glusterfs.nix {};
···1516buildPythonPackage rec {
17 pname = "xhtml2pdf";
18- version = "0.2.9";
19 format = "setuptools";
2021 disabled = pythonOlder "3.7";
2223- # Tests are only available on GitHub
24 src = fetchFromGitHub {
25 owner = pname;
26 repo = pname;
27- # Currently it is not possible to fetch from version as there is a branch with the same name
28- rev = "refs/tags/${version}";
29- hash = "sha256-MrzAsa0AZX3+0LN/Can3QBoPBRxb0a/F2jLBd8rD5H4=";
30 };
3132 propagatedBuildInputs = [
···51 meta = with lib; {
52 description = "A PDF generator using HTML and CSS";
53 homepage = "https://github.com/xhtml2pdf/xhtml2pdf";
054 license = licenses.asl20;
55 maintainers = with maintainers; [ ];
56 };
···1516buildPythonPackage rec {
17 pname = "xhtml2pdf";
18+ version = "0.2.11";
19 format = "setuptools";
2021 disabled = pythonOlder "3.7";
22023 src = fetchFromGitHub {
24 owner = pname;
25 repo = pname;
26+ rev = "refs/tags/v${version}";
27+ hash = "sha256-L/HCw+O8bidtE5nDdO+cLS54m64dlJL+9Gjcye5gM+w=";
028 };
2930 propagatedBuildInputs = [
···49 meta = with lib; {
50 description = "A PDF generator using HTML and CSS";
51 homepage = "https://github.com/xhtml2pdf/xhtml2pdf";
52+ changelog = "https://github.com/xhtml2pdf/xhtml2pdf/releases/tag/v${version}";
53 license = licenses.asl20;
54 maintainers = with maintainers; [ ];
55 };
···1+From e00a5257a6ca5fedbf68b09eee7df3502971a057 Mon Sep 17 00:00:00 2001
2+From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= <joerg@thalheim.io>
3+Date: Sat, 24 Apr 2021 10:11:40 +0200
4+Subject: [PATCH 1/2] No impure bin sh
5+6+default_shell is used to populuate default shell used to execute jobs.
7+Unless SHELL is set to a different value this would be /bin/sh.
8+Our stdenv provides sh in form of bash anyway. Having this value not
9+hard-coded has some advantages:
10+11+- It would ensure that on all systems it uses sh from its PATH rather
12+ than /bin/sh, which helps as different systems might have different
13+ shells there (bash vs. dash)
14+- In the past I had issues with LD_PRELOAD with BEAR, where /bin/sh
15+ used a different glibc than BEAR which came from my development shell.
16+---
17+ src/job.c | 2 +-
18+ 1 file changed, 1 insertion(+), 1 deletion(-)
19+20+diff --git a/src/job.c b/src/job.c
21+index ae1f18b..6b4ddb3 100644
22+--- a/src/job.c
23++++ b/src/job.c
24+@@ -77,7 +77,7 @@ char * vms_strsignal (int status);
25+26+ #else
27+28+-const char *default_shell = "/bin/sh";
29++const char *default_shell = "sh";
30+ int batch_mode_shell = 0;
31+32+ #endif
33+--
34+2.31.1
35+