Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions nixos/doc/manual/from_md/release-notes/rl-2305.section.xml
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,15 @@
been fixed to allow more than one plugin in the path.
</para>
</listitem>
<listitem>
<para>
A new option was added to the virtualisation module that
enables specifying explicitly named network interfaces in QEMU
VMs. The existing <literal>virtualisation.vlans</literal> is
still supported for cases where the name of the network
interface is irrelevant.
</para>
</listitem>
</itemizedlist>
</section>
</section>
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2305.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,5 @@ In addition to numerous new and upgraded packages, this release has the followin
- `nixos-version` now accepts `--configuration-revision` to display more information about the current generation revision

- The option `services.nomad.extraSettingsPlugins` has been fixed to allow more than one plugin in the path.

- A new option was added to the virtualisation module that enables specifying explicitly named network interfaces in QEMU VMs. The existing `virtualisation.vlans` is still supported for cases where the name of the network interface is irrelevant.
4 changes: 3 additions & 1 deletion nixos/lib/testing/driver.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ let
};


vlans = map (m: m.virtualisation.vlans) (lib.attrValues config.nodes);
vlans = map (m: (
m.virtualisation.vlans ++
(lib.mapAttrsToList (_: v: v.vlan) m.virtualisation.interfaces))) (lib.attrValues config.nodes);
vms = map (m: m.system.build.vm) (lib.attrValues config.nodes);

nodeHostNames =
Expand Down
41 changes: 27 additions & 14 deletions nixos/lib/testing/network.nix
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,40 @@ let

networkModule = { config, nodes, pkgs, ... }:
let
interfacesNumbered = zipLists config.virtualisation.vlans (range 1 255);
interfaces = forEach interfacesNumbered ({ fst, snd }:
nameValuePair "eth${toString snd}" {
ipv4.addresses =
[{
address = "192.168.${toString fst}.${toString config.virtualisation.test.nodeNumber}";
qemu-common = import ../qemu-common.nix { inherit lib pkgs; };

# Convert legacy VLANs to named interfaces and merge with explicit interfaces.
vlansNumbered = forEach (zipLists config.virtualisation.vlans (range 1 255)) (v: {
name = "eth${toString v.snd}";
vlan = v.fst;
assignIP = true;
});
explicitInterfaces = lib.mapAttrsToList (n: v: v // { name = n; }) config.virtualisation.interfaces;
interfaces = vlansNumbered ++ explicitInterfaces;
interfacesNumbered = zipLists interfaces (range 1 255);

# Automatically assign IP addresses to requested interfaces.
assignIPs = lib.filter (i: i.assignIP) interfaces;
ipInterfaces = forEach assignIPs (i:
nameValuePair i.name { ipv4.addresses =
[ { address = "192.168.${toString i.vlan}.${toString config.virtualisation.test.nodeNumber}";
prefixLength = 24;
}];
});

qemuOptions = lib.flatten (forEach interfacesNumbered ({ fst, snd }:
qemu-common.qemuNICFlags snd fst.vlan config.virtualisation.test.nodeNumber));
udevRules = forEach interfacesNumbered ({ fst, snd }:
"SUBSYSTEM==\"net\",ACTION==\"add\",ATTR{address}==\"${qemu-common.qemuNicMac fst.vlan config.virtualisation.test.nodeNumber}\",NAME=\"${fst.name}\"");

networkConfig =
{
networking.hostName = mkDefault config.virtualisation.test.nodeName;

networking.interfaces = listToAttrs interfaces;
networking.interfaces = listToAttrs ipInterfaces;

networking.primaryIPAddress =
optionalString (interfaces != [ ]) (head (head interfaces).value.ipv4.addresses).address;
optionalString (ipInterfaces != [ ]) (head (head ipInterfaces).value.ipv4.addresses).address;

# Put the IP addresses of all VMs in this machine's
# /etc/hosts file. If a machine has multiple
Expand All @@ -51,16 +67,13 @@ let
"${config.networking.hostName}.${config.networking.domain} " +
"${config.networking.hostName}\n"));

virtualisation.qemu.options =
let qemu-common = import ../qemu-common.nix { inherit lib pkgs; };
in
flip concatMap interfacesNumbered
({ fst, snd }: qemu-common.qemuNICFlags snd fst config.virtualisation.test.nodeNumber);
virtualisation.qemu.options = qemuOptions;
boot.initrd.services.udev.rules = concatMapStrings (x: x + "\n") udevRules;
};

in
{
key = "ip-address";
key = "network-interfaces";
config = networkConfig // {
# Expose the networkConfig items for tests like nixops
# that need to recreate the network config.
Expand Down
32 changes: 31 additions & 1 deletion nixos/modules/virtualisation/qemu-vm.nix
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,8 @@ in
virtualisation.vlans =
mkOption {
type = types.listOf types.ints.unsigned;
default = [ 1 ];
default = if config.virtualisation.interfaces == {} then [ 1 ] else [ ];
defaultText = lib.literalExpression ''if config.virtualisation.interfaces == {} then [ 1 ] else [ ]'';
example = [ 1 2 ];
description =
lib.mdDoc ''
Expand All @@ -560,6 +561,35 @@ in
'';
};

virtualisation.interfaces = mkOption {
default = {};
example = {
enp1s0.vlan = 1;
};
description = lib.mdDoc ''
Network interfaces to add to the VM.
'';
type = with types; attrsOf (submodule {
options = {
vlan = mkOption {
type = types.ints.unsigned;
description = lib.mdDoc ''
VLAN to which the network interface is connected.
'';
};

assignIP = mkOption {
type = types.bool;
default = false;
description = lib.mdDoc ''
Automatically assign an IP address to the network interface using the same scheme as
virtualisation.vlans.
'';
};
};
});
};

virtualisation.writableStore =
mkOption {
type = types.bool;
Expand Down
Loading