Skip to content

Commit

Permalink
Merge reording asserts in NixOS eval (#47293)
Browse files Browse the repository at this point in the history
Changes the evaluation order in that it evaluates assertions before
warnings, so that eg. the following would work:

  { config, lib, ... }:

  {
    options.foo = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = "...";
    };

    options.bar = lib.mkOption {
      type = lib.types.bool;
      default = false;
      description = "...";
    };

    config = lib.mkMerge [
      (lib.mkIf config.bar {
        system.build.bar = "foobar";
      })
      (lib.mkIf config.foo {
        assertions = lib.singleton {
          assertion = config.bar;
          message = "Bar needs to be enabled";
        };
        systemd.services.foo = {
          description = "Foo";
          serviceConfig.ExecStart = config.system.build.bar;
        };
      })
    ];
  }

This is because the systemd module includes definitions for warnings
that would trigger evaluation of the config.system.build.bar definition.

The original pull request references a breakage due to the following:

  {
    services.nixosManual.enable = false;
    services.nixosManual.showManual = true;
  }

However, changing the eval order between asserts and warnings clearly is
a corner case here and it only happens because of the aforementioned
usage of warnings in the systemd module and needs more discussion.

Nevertheless, this is still useful because it lowers the evaluation time
whenever an assertion is hit, which is a hard failure anyway.
  • Loading branch information
aszlig committed Sep 25, 2018
2 parents 14a1907 + 563d5b1 commit 9bfd864
Showing 1 changed file with 37 additions and 34 deletions.
71 changes: 37 additions & 34 deletions nixos/modules/system/activation/top-level.nix
Expand Up @@ -93,49 +93,52 @@ let
${config.system.extraSystemBuilderCmds}
'';

# Handle assertions

failed = map (x: x.message) (filter (x: !x.assertion) config.assertions);

showWarnings = res: fold (w: x: builtins.trace "warning: ${w}" x) res config.warnings;

# Putting it all together. This builds a store path containing
# symlinks to the various parts of the built configuration (the
# kernel, systemd units, init scripts, etc.) as well as a script
# `switch-to-configuration' that activates the configuration and
# makes it bootable.
baseSystem = showWarnings (
if [] == failed then pkgs.stdenvNoCC.mkDerivation {
name = let hn = config.networking.hostName;
nn = if (hn != "") then hn else "unnamed";
in "nixos-system-${nn}-${config.system.nixos.label}";
preferLocalBuild = true;
allowSubstitutes = false;
buildCommand = systemBuilder;

inherit (pkgs) utillinux coreutils;
systemd = config.systemd.package;
shell = "${pkgs.bash}/bin/sh";

inherit children;
kernelParams = config.boot.kernelParams;
installBootLoader =
config.system.build.installBootLoader
or "echo 'Warning: do not know how to make this configuration bootable; please enable a boot loader.' 1>&2; true";
activationScript = config.system.activationScripts.script;
nixosLabel = config.system.nixos.label;

configurationName = config.boot.loader.grub.configurationName;

# Needed by switch-to-configuration.

perl = "${pkgs.perl}/bin/perl " + (concatMapStringsSep " " (lib: "-I${lib}/${pkgs.perl.libPrefix}") (with pkgs.perlPackages; [ FileSlurp NetDBus XMLParser XMLTwig ]));
} else throw "\nFailed assertions:\n${concatStringsSep "\n" (map (x: "- ${x}") failed)}");
baseSystem = pkgs.stdenvNoCC.mkDerivation {
name = let hn = config.networking.hostName;
nn = if (hn != "") then hn else "unnamed";
in "nixos-system-${nn}-${config.system.nixos.label}";
preferLocalBuild = true;
allowSubstitutes = false;
buildCommand = systemBuilder;

inherit (pkgs) utillinux coreutils;
systemd = config.systemd.package;
shell = "${pkgs.bash}/bin/sh";

inherit children;
kernelParams = config.boot.kernelParams;
installBootLoader =
config.system.build.installBootLoader
or "echo 'Warning: do not know how to make this configuration bootable; please enable a boot loader.' 1>&2; true";
activationScript = config.system.activationScripts.script;
nixosLabel = config.system.nixos.label;

configurationName = config.boot.loader.grub.configurationName;

# Needed by switch-to-configuration.

perl = "${pkgs.perl}/bin/perl " + (concatMapStringsSep " " (lib: "-I${lib}/${pkgs.perl.libPrefix}") (with pkgs.perlPackages; [ FileSlurp NetDBus XMLParser XMLTwig ]));
};

# Handle assertions and warnings

failedAssertions = map (x: x.message) (filter (x: !x.assertion) config.assertions);

showWarnings = res: fold (w: x: builtins.trace "warning: ${w}" x) res config.warnings;

baseSystemAssertWarn = if failedAssertions != []
then throw "\nFailed assertions:\n${concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}"
else showWarnings baseSystem;

# Replace runtime dependencies
system = fold ({ oldDependency, newDependency }: drv:
pkgs.replaceDependency { inherit oldDependency newDependency drv; }
) baseSystem config.system.replaceRuntimeDependencies;
) baseSystemAssertWarn config.system.replaceRuntimeDependencies;

in

Expand Down

0 comments on commit 9bfd864

Please sign in to comment.