blob: 39d9eea24f3dca4a3b63dd25a3dec1ab58d94e66 (
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
|
# This module defines networking options for virtual machines and containers.
# It is intended to be used with systemd-nspawn containers and QEMU virtual machines.
{ config, lib, ... }:
let
inherit (lib) types;
interfaceType = types.submodule (
{ name, ... }:
{
options = {
name = lib.mkOption {
type = types.str;
default = name;
description = ''
Interface name
'';
};
vlan = lib.mkOption {
type = types.ints.unsigned;
description = ''
VLAN to which the network interface is connected.
'';
};
assignIP = lib.mkOption {
type = types.bool;
default = false;
description = ''
Automatically assign an IP address to the network interface using the same scheme as
virtualisation.vlans.
'';
};
};
}
);
cfg = config.virtualisation;
# Convert legacy VLANs to named interfaces.
vlansNumbered = lib.listToAttrs (
lib.forEach (lib.zipLists cfg.vlans (lib.range 1 255)) (
v:
let
name = "eth${toString v.snd}";
in
lib.nameValuePair name {
inherit name;
vlan = v.fst;
assignIP = true;
}
)
);
in
{
options = {
networking.primaryIPAddress = lib.mkOption {
type = types.str;
default = "";
internal = true;
description = "Primary IP address used in /etc/hosts.";
};
networking.primaryIPv6Address = lib.mkOption {
type = types.str;
default = "";
internal = true;
description = "Primary IPv6 address used in /etc/hosts.";
};
virtualisation.vlans = lib.mkOption {
type = types.listOf types.ints.unsigned;
default = if cfg.interfaces == { } then [ 1 ] else [ ];
defaultText = lib.literalExpression "if config.virtualisation.interfaces == {} then [ 1 ] else [ ]";
example = [
1
2
];
description = ''
Virtual networks to which the container or VM is connected. Each number «N» in
this list causes the container to have a virtual Ethernet interface
attached to a separate virtual network on which it will be assigned IP
address `192.168.«N».«M»`, where «M» is the index of this container in
the list of containers.
'';
};
virtualisation.interfaces = lib.mkOption {
default = { };
example = {
enp1s0.vlan = 1;
};
description = ''
Extra network interfaces to add to the container or VM in addition to the ones
created by {option}`virtualisation.vlans`.
'';
type = types.attrsOf interfaceType;
};
virtualisation.allInterfaces = lib.mkOption {
type = types.attrsOf interfaceType;
readOnly = true;
description = ''
All network interfaces for the container or VM. Combines
{option}`virtualisation.vlans` and {option}`virtualisation.interfaces`.
'';
default = vlansNumbered // cfg.interfaces;
};
};
config = {
assertions = [
(
let
conflictingKeys = lib.intersectAttrs vlansNumbered cfg.interfaces;
in
{
assertion = conflictingKeys == { };
message = ''
`virtualisation.vlans` and `virtualisation.interfaces` have conflicting keys: ${lib.concatStringsSep "," (lib.attrNames conflictingKeys)}
'';
}
)
(
let
allInterfaceNames =
(lib.mapAttrsToList (k: i: i.name) vlansNumbered)
++ (lib.mapAttrsToList (k: i: i.name) cfg.interfaces);
in
{
assertion = lib.allUnique allInterfaceNames;
message = ''
`virtualisation.vlans` and `virtualisation.interfaces` have conflicting interface names: ${lib.concatStringsSep "," allInterfaceNames}
'';
}
)
];
};
}
|