summary refs log tree commit diff
path: root/nixos/modules/config/nix-channel.nix
blob: 3f8e088ede9294de0e445180a3e4ad85a6a1f196 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
  Manages the things that are needed for a traditional nix-channel based
  configuration to work.

  See also
  - ./nix.nix
  - ./nix-flakes.nix
 */
{ config, lib, ... }:
let
  inherit (lib)
    mkDefault
    mkIf
    mkOption
    stringAfter
    types
    ;

  cfg = config.nix;

in
{
  options = {
    nix = {
      channel = {
        enable = mkOption {
          description = lib.mdDoc ''
            Whether the `nix-channel` command and state files are made available on the machine.

            The following files are initialized when enabled:
              - `/nix/var/nix/profiles/per-user/root/channels`
              - `/root/.nix-channels`
              - `$HOME/.nix-defexpr/channels` (on login)

            Disabling this option will not remove the state files from the system.
          '';
          type = types.bool;
          default = true;
        };
      };

      nixPath = mkOption {
        type = types.listOf types.str;
        default =
          if cfg.channel.enable
          then [
            "nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
            "nixos-config=/etc/nixos/configuration.nix"
            "/nix/var/nix/profiles/per-user/root/channels"
          ]
          else [ ];
        defaultText = ''
          if nix.channel.enable
          then [
            "nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
            "nixos-config=/etc/nixos/configuration.nix"
            "/nix/var/nix/profiles/per-user/root/channels"
          ]
          else [];
        '';
        description = lib.mdDoc ''
          The default Nix expression search path, used by the Nix
          evaluator to look up paths enclosed in angle brackets
          (e.g. `<nixpkgs>`).
        '';
      };
    };

    system = {
      defaultChannel = mkOption {
        internal = true;
        type = types.str;
        default = "https://nixos.org/channels/nixos-unstable";
        description = lib.mdDoc "Default NixOS channel to which the root user is subscribed.";
      };
    };
  };

  config = mkIf cfg.enable {

    environment.extraInit =
      mkIf cfg.channel.enable ''
        if [ -e "$HOME/.nix-defexpr/channels" ]; then
          export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}"
        fi
      '';

    environment.extraSetup = mkIf (!cfg.channel.enable) ''
      rm --force $out/bin/nix-channel
    '';

    # NIX_PATH has a non-empty default according to Nix docs, so we don't unset
    # it when empty.
    environment.sessionVariables = {
      NIX_PATH = cfg.nixPath;
    };

    nix.settings.nix-path = mkIf (! cfg.channel.enable) (mkDefault "");

    system.activationScripts.nix-channel = mkIf cfg.channel.enable
      (stringAfter [ "etc" "users" ] ''
        # Subscribe the root user to the NixOS channel by default.
        if [ ! -e "/root/.nix-channels" ]; then
            echo "${config.system.defaultChannel} nixos" > "/root/.nix-channels"
        fi
      '');
  };
}