summaryrefslogtreecommitdiff
path: root/modules/system/default.nix
blob: a1862faeec4826aacfaa147ed49f0da8a1f79113 (plain)
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
{ config, lib, pkgs, ... }:

with lib;

let

  inherit (pkgs) stdenvNoCC;

  cfg = config.system;

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

  throwAssertions = res: if (failedAssertions != []) then throw "\nFailed assertions:\n${concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}" else res;
  showWarnings = res: fold (w: x: builtins.trace "warning: ${w}" x) res config.warnings;

in

{
  options = {

    system.build = mkOption {
      internal = true;
      type = types.attrsOf types.unspecified;
      default = {};
      description = ''
        Attribute set of derivation used to setup the system.
      '';
    };

    system.path = mkOption {
      internal = true;
      type = types.package;
      description = ''
        The packages you want in the system environment.
      '';
    };

    system.profile = mkOption {
      type = types.path;
      default = "/nix/var/nix/profiles/system";
      description = ''
        Profile to use for the system.
      '';
    };

    system.systemBuilderCommands = mkOption {
      internal = true;
      type = types.lines;
      default = "";
      description = ''
        This code will be added to the builder creating the system store path.
      '';
    };

    system.systemBuilderArgs = mkOption {
      internal = true;
      type = types.attrsOf types.unspecified;
      default = {};
      description = ''
        `lib.mkDerivation` attributes that will be passed to the top level system builder.
      '';
    };

    assertions = mkOption {
      type = types.listOf types.unspecified;
      internal = true;
      default = [];
      example = [ { assertion = false; message = "you can't enable this for that reason"; } ];
      description = ''
        This option allows modules to express conditions that must
        hold for the evaluation of the system configuration to
        succeed, along with associated error messages for the user.
      '';
    };

    warnings = mkOption {
      internal = true;
      default = [];
      type = types.listOf types.str;
      example = [ "The `foo' service is deprecated and will go away soon!" ];
      description = ''
        This option allows modules to show warnings to users during
        the evaluation of the system configuration.
      '';
    };

  };

  config = {

    system.build.toplevel = throwAssertions (showWarnings (stdenvNoCC.mkDerivation ({
      name = "darwin-system-${cfg.darwinLabel}";
      preferLocalBuild = true;

      nativeBuildInputs = [ pkgs.shellcheck ];

      activationScript = cfg.activationScripts.script.text;
      activationUserScript = cfg.activationScripts.userScript.text;
      inherit (cfg) darwinLabel;

      darwinVersionJson = (pkgs.formats.json {}).generate "darwin-version.json" (
        filterAttrs (k: v: v != null) {
          inherit (config.system) darwinRevision nixpkgsRevision configurationRevision darwinLabel;
        }
      );

      buildCommand = ''
        mkdir $out

        systemConfig=$out

        mkdir -p $out/darwin
        cp -f ${../../CHANGELOG} $out/darwin-changes

        ln -s ${cfg.build.patches}/patches $out/patches
        ln -s ${cfg.build.etc}/etc $out/etc
        ln -s ${cfg.path} $out/sw

        mkdir -p $out/Library
        ln -s ${cfg.build.applications}/Applications $out/Applications
        ln -s ${cfg.build.fonts}/Library/Fonts $out/Library/Fonts
        ln -s ${cfg.build.launchd}/Library/LaunchAgents $out/Library/LaunchAgents
        ln -s ${cfg.build.launchd}/Library/LaunchDaemons $out/Library/LaunchDaemons

        mkdir -p $out/user/Library
        ln -s ${cfg.build.launchd}/user/Library/LaunchAgents $out/user/Library/LaunchAgents

        echo "$activationScript" > $out/activate
        substituteInPlace $out/activate --subst-var out
        chmod u+x $out/activate
        unset activationScript

        echo "$activationUserScript" > $out/activate-user
        substituteInPlace $out/activate-user --subst-var out
        chmod u+x $out/activate-user
        unset activationUserScript

        shellcheck $out/activate $out/activate-user

        echo -n "$systemConfig" > $out/systemConfig

        echo -n "$darwinLabel" > $out/darwin-version
        ln -s $darwinVersionJson $out/darwin-version.json
        echo -n "$system" > $out/system

        ${cfg.systemBuilderCommands}
      '';
    } // cfg.systemBuilderArgs)));

  };
}