summaryrefslogtreecommitdiffstats
path: root/nixos/modules/profiles/clone-config.nix
blob: 2c6377e65c88369abf3cbe0ae358db96b5d19e9c (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
{
  config,
  lib,
  pkgs,
  modules,
  ...
}:

with lib;

let

  # Location of the repository on the harddrive
  nixosPath = toString ../..;

  # Check if the path is from the NixOS repository
  isNixOSFile =
    path:
    let
      s = toString path;
    in
    removePrefix nixosPath s != s;

  # Copy modules given as extra configuration files.  Unfortunately, we
  # cannot serialized attribute set given in the list of modules (that's why
  # you should use files).
  moduleFiles =
    # FIXME: use typeOf (Nix 1.6.1).
    filter (x: !isAttrs x && !lib.isFunction x) modules;

  # Partition module files because between NixOS and non-NixOS files.  NixOS
  # files may change if the repository is updated.
  partitionedModuleFiles =
    let
      p = partition isNixOSFile moduleFiles;
    in
    {
      nixos = p.right;
      others = p.wrong;
    };

  # Path transformed to be valid on the installation device.  Thus the
  # device configuration could be rebuild.
  relocatedModuleFiles =
    let
      relocateNixOS = path: "<nixpkgs/nixos" + removePrefix nixosPath (toString path) + ">";
    in
    {
      nixos = map relocateNixOS partitionedModuleFiles.nixos;
      others = [ ]; # TODO: copy the modules to the install-device repository.
    };

  # A dummy /etc/nixos/configuration.nix in the booted CD that
  # rebuilds the CD's configuration (and allows the configuration to
  # be modified, of course, providing a true live CD).  Problem is
  # that we don't really know how the CD was built - the Nix
  # expression language doesn't allow us to query the expression being
  # evaluated.  So we'll just hope for the best.
  configClone = pkgs.writeText "configuration.nix" ''
    { config, pkgs, ... }:

    {
      imports = [ ${toString config.installer.cloneConfigIncludes} ];

      ${config.installer.cloneConfigExtra}
    }
  '';

in

{

  options = {

    installer.cloneConfig = mkOption {
      default = true;
      description = ''
        Try to clone the installation-device configuration by re-using it's
        profile from the list of imported modules.
      '';
    };

    installer.cloneConfigIncludes = mkOption {
      default = [ ];
      example = [ "./nixos/modules/hardware/network/rt73.nix" ];
      description = ''
        List of modules used to re-build this installation device profile.
      '';
    };

    installer.cloneConfigExtra = mkOption {
      default = "";
      description = ''
        Extra text to include in the cloned configuration.nix included in this
        installer.
      '';
    };
  };

  config = {

    installer.cloneConfigIncludes = relocatedModuleFiles.nixos ++ relocatedModuleFiles.others;

    boot.postBootCommands = ''
      # Provide a mount point for nixos-install.
      mkdir -p /mnt

      ${optionalString config.installer.cloneConfig ''
        # Provide a configuration for the CD/DVD itself, to allow users
        # to run nixos-rebuild to change the configuration of the
        # running system on the CD/DVD.
        if ! [ -e /etc/nixos/configuration.nix ]; then
          cp ${configClone} /etc/nixos/configuration.nix
        fi
      ''}
    '';

  };

}