Commit b3c1d8c9 authored by nikstur's avatar nikstur
Browse files

nixos: add system.switch.enable flag

This flag allows the user to optionally exclude
switch-to-confguration.pl from toplevel.

This is interesting for appliance images where you don't want to re-build
the system. This flag is called `rebuildable` because the standard
interface to do this is `nixos-rebuild` which will not work anymore with
this change.
parent f743f021
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1392,6 +1392,7 @@
  ./system/activation/activatable-system.nix
  ./system/activation/activation-script.nix
  ./system/activation/specialisation.nix
  ./system/activation/switchable-system.nix
  ./system/activation/bootspec.nix
  ./system/activation/top-level.nix
  ./system/boot/binfmt.nix
+26 −39
Original line number Diff line number Diff line
{ config, lib, pkgs, ... }:
{ options, config, lib, pkgs, ... }:

let
  inherit (lib)
    mkOption
    optionalString
    types
    ;

  perlWrapped = pkgs.perl.withPackages (p: with p; [ ConfigIniFiles FileSlurp ]);

  systemBuilderArgs = {
    activationScript = config.system.activationScripts.script;
    dryActivationScript = config.system.dryActivationScript;
  };

  systemBuilderCommands = ''
    echo "$activationScript" > $out/activate
    echo "$dryActivationScript" > $out/dry-activate
    substituteInPlace $out/activate --subst-var-by out ''${!toplevelVar}
    substituteInPlace $out/dry-activate --subst-var-by out ''${!toplevelVar}
    chmod u+x $out/activate $out/dry-activate
    unset activationScript dryActivationScript

    mkdir $out/bin
    substitute ${./switch-to-configuration.pl} $out/bin/switch-to-configuration \
      --subst-var out \
      --subst-var-by toplevel ''${!toplevelVar} \
      --subst-var-by coreutils "${pkgs.coreutils}" \
      --subst-var-by distroId ${lib.escapeShellArg config.system.nixos.distroId} \
      --subst-var-by installBootLoader ${lib.escapeShellArg config.system.build.installBootLoader} \
      --subst-var-by localeArchive "${config.i18n.glibcLocales}/lib/locale/locale-archive" \
      --subst-var-by perl "${perlWrapped}" \
      --subst-var-by shell "${pkgs.bash}/bin/sh" \
      --subst-var-by su "${pkgs.shadow.su}/bin/su" \
      --subst-var-by systemd "${config.systemd.package}" \
      --subst-var-by utillinux "${pkgs.util-linux}" \
      ;

    chmod +x $out/bin/switch-to-configuration
    ${optionalString (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) ''
      if ! output=$(${perlWrapped}/bin/perl -c $out/bin/switch-to-configuration 2>&1); then
        echo "switch-to-configuration syntax is not valid:"
        echo "$output"
        exit 1
      fi
    ''}
  '';

in
{
  options = {
@@ -60,6 +24,18 @@ in
        do, but for image based systems, this may not be needed or not be desirable.
      '';
    };
    system.activatableSystemBuilderCommands = options.system.systemBuilderCommands // {
      description = lib.mdDoc ''
        Like `system.systemBuilderCommands`, but only for the commands that are
        needed *both* when the system is activatable and when it isn't.

        Disclaimer: This option might go away in the future. It might be
        superseded by separating switch-to-configuration into a separate script
        which will make this option superfluous. See
        https://github.com/NixOS/nixpkgs/pull/263462#discussion_r1373104845 for
        a discussion.
      '';
    };
    system.build.separateActivationScript = mkOption {
      type = types.package;
      description = ''
@@ -71,7 +47,18 @@ in
    };
  };
  config = {
    system.systemBuilderCommands = lib.mkIf config.system.activatable systemBuilderCommands;
    system.activatableSystemBuilderCommands = ''
      echo "$activationScript" > $out/activate
      echo "$dryActivationScript" > $out/dry-activate
      substituteInPlace $out/activate --subst-var-by out ''${!toplevelVar}
      substituteInPlace $out/dry-activate --subst-var-by out ''${!toplevelVar}
      chmod u+x $out/activate $out/dry-activate
      unset activationScript dryActivationScript
    '';

    system.systemBuilderCommands = lib.mkIf
      config.system.activatable
      config.system.activatableSystemBuilderCommands;
    system.systemBuilderArgs = lib.mkIf config.system.activatable
      (systemBuilderArgs // {
        toplevelVar = "out";
@@ -86,7 +73,7 @@ in
        })
        ''
          mkdir $out
          ${systemBuilderCommands}
          ${config.system.activatableSystemBuilderCommands}
        '';
  };
}
+55 −0
Original line number Diff line number Diff line
{ config, lib, pkgs, ... }:

let

  perlWrapped = pkgs.perl.withPackages (p: with p; [ ConfigIniFiles FileSlurp ]);

in

{

  options = {
    system.switch.enable = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = lib.mdDoc ''
        Whether to include the capability to switch configurations.

        Disabling this makes the system unable to be reconfigured via `nixos-rebuild`.

        This is good for image based appliances where updates are handled
        outside the image. Reducing features makes the image lighter and
        slightly more secure.
      '';
    };
  };

  config = lib.mkIf config.system.switch.enable {
    system.activatableSystemBuilderCommands = ''
      mkdir $out/bin
      substitute ${./switch-to-configuration.pl} $out/bin/switch-to-configuration \
        --subst-var out \
        --subst-var-by toplevel ''${!toplevelVar} \
        --subst-var-by coreutils "${pkgs.coreutils}" \
        --subst-var-by distroId ${lib.escapeShellArg config.system.nixos.distroId} \
        --subst-var-by installBootLoader ${lib.escapeShellArg config.system.build.installBootLoader} \
        --subst-var-by localeArchive "${config.i18n.glibcLocales}/lib/locale/locale-archive" \
        --subst-var-by perl "${perlWrapped}" \
        --subst-var-by shell "${pkgs.bash}/bin/sh" \
        --subst-var-by su "${pkgs.shadow.su}/bin/su" \
        --subst-var-by systemd "${config.systemd.package}" \
        --subst-var-by utillinux "${pkgs.util-linux}" \
        ;

      chmod +x $out/bin/switch-to-configuration
      ${lib.optionalString (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) ''
        if ! output=$(${perlWrapped}/bin/perl -c $out/bin/switch-to-configuration 2>&1); then
          echo "switch-to-configuration syntax is not valid:"
          echo "$output"
          exit 1
        fi
      ''}
    '';
  };

}
+1 −0
Original line number Diff line number Diff line
@@ -571,6 +571,7 @@ in {
  node-red = handleTest ./node-red.nix {};
  nomad = handleTest ./nomad.nix {};
  non-default-filesystems = handleTest ./non-default-filesystems.nix {};
  non-switchable-system = runTest ./non-switchable-system.nix;
  noto-fonts = handleTest ./noto-fonts.nix {};
  noto-fonts-cjk-qt-default-weight = handleTest ./noto-fonts-cjk-qt-default-weight.nix {};
  novacomd = handleTestOn ["x86_64-linux"] ./novacomd.nix {};
+15 −0
Original line number Diff line number Diff line
{ lib, ... }:

{
  name = "non-switchable-system";

  meta.maintainers = with lib.maintainers; [ nikstur ];

  nodes.machine = {
    system.switch.enable = false;
  };

  testScript = ''
    machine.succeed("test ! -e /run/current-system/bin/switch-to-configuration")
  '';
}