-
Notifications
You must be signed in to change notification settings - Fork 1
/
flake-module.nix
159 lines (141 loc) · 4.74 KB
/
flake-module.nix
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
152
153
154
155
156
157
158
159
toplevel@{ pkgs, config, inputs, lib, withSystem, ... }:
let
inherit (builtins) listToAttrs attrNames attrValues foldl' length filter;
inherit (lib)
mkIf mkOption mkDefault mkMerge mapAttrs mkEnableOption types
recursiveUpdateUntil isDerivation literalExpression;
cfg = config.flake-containers;
overlayType = types.uniq
(types.functionTo (types.functionTo (types.lazyAttrsOf types.unspecified)));
containerOptionType = types.submodule {
options = {
configuration = mkOption {};
volumes-ro = mkOption {
default = [];
};
volumes = mkOption {
default = [];
};
runCommand = mkOption {
default = null;
};
};
};
nixpkgsOptionType = types.submodule {
options = {
nixpkgs = mkOption {
type = types.path;
default = inputs.nixpkgs;
defaultText = literalExpression "inputs.nixpkgs";
description = ''
The nixpkgs flake to use.
This option needs to set if the nixpkgs that you want to use is under a different name
in flake inputs.
'';
};
config = mkOption {
default = { };
type = types.attrs;
description = ''
The configuration of the Nix Packages collection.
'';
example = literalExpression ''
{ allowUnfree = true; }
'';
};
overlays = mkOption {
default = [ ];
type = types.uniq (types.listOf overlayType);
description = ''
List of overlays to use with the Nix Packages collection.
'';
example = literalExpression ''
[
inputs.fenix.overlays.default
]
'';
};
};
};
flakeContainersConfigType = types.submodule {
options = {
enable = mkEnableOption "flake containers";
nixpkgs = mkOption {
type = nixpkgsOptionType;
default = { };
description = ''
Config about the nixpkgs used by flake containers.
'';
};
containers = mkOption {
type = types.attrsOf containerOptionType;
default = { };
description = ''
Container configuration. Defines the system modules, volumes etc
'';
};
};
};
in {
options.flake-containers = mkOption {
type = flakeContainersConfigType;
default = { };
description = ''
The config for flake-containers.
'';
};
config = mkIf cfg.enable {
perSystem = perSystemScope@{ config, self', lib, pkgs, system, ... }:
let
mergeIntoSet = lib.foldr (a: b: a // b) { };
# Fot the moment, map containers to private adresses
allocatedAdresses = mergeIntoSet (lib.imap1 (i: name: {
"${name}" = let ipPrefix = "10.233.${builtins.toString i}";
in {
hostAddress = "${ipPrefix}.1";
localAddress = "${ipPrefix}.2";
};
}) ((lib.mapAttrsToList (name: config: name)) cfg.containers));
# Create a the commands that manage the containers
mkContainer =
import ./src/mkContainer.nix { inherit lib pkgs perSystemScope; };
# Create all containers
containers = lib.mapAttrsToList (name: container:
mkContainer name container allocatedAdresses."${name}".localAddress
allocatedAdresses."${name}".hostAddress) cfg.containers;
# Create a list to be add to the buildInputs
to-list = lib.concatMap
# Create a list from the set
(lib.mapAttrsToList (name: command: command))
# Get the commands attribute for each container
(lib.forEach containers (container: container.commands));
to-attribute-set = mergeIntoSet
# Get the commands attribute for each container
(lib.forEach containers (container: container.commands));
selectedPkgs = import cfg.nixpkgs.nixpkgs {
inherit system;
overlays = cfg.nixpkgs.overlays;
config = cfg.nixpkgs.config;
};
shellHookHelpStr = let
commands-list = lib.foldr (a: b: a + "\n" + b) " " (lib.flatten
(lib.forEach containers
(container: builtins.attrNames container.commands)));
in ''
flake-containers Shell Hook!
The following commands are available (sudo is required for the up commands):
${commands-list}
'';
in {
# flake-part way to specify nixpkgs
_module.args.pkgs = selectedPkgs;
# Create packages so they can be used directly from nix run
packages = to-attribute-set;
# Empty for the example
devShells.flake-containers = pkgs.mkShell {
shellHook = ''echo "${shellHookHelpStr}"'';
nativeBuildInputs = lib.flatten to-list;
};
};
};
}