From c209dadc1f1feef78db9cfd8e7f67bf4d71f63ae Mon Sep 17 00:00:00 2001 From: Jonathon Anderson Date: Mon, 20 Jan 2025 19:50:29 -0700 Subject: [PATCH] Update network interface bonding configuration and documentation - Closes: #1482 - Closes: #1280 This also corrects poor handling of whitespace around the "file" function throughout the templates, given experiences with the network templates while implementing the bond behavior. Since the file function actually does produce output (that is parsed by Warewulf itself) it should not collaps prefix whitespace. Signed-off-by: Jonathon Anderson --- CHANGELOG.md | 1 + internal/pkg/overlay/overlay_test.go | 4 +- .../internal/networkmanager_test.go | 19 +++--- .../NetworkManager/conf.d/ww4-unmanaged.ww | 3 +- .../system-connections/ww4-managed.ww | 65 +++++++++---------- .../internal/debian_interfaces_test.go | 2 + .../etc/network/interfaces.d/default.ww | 2 +- overlays/ifcfg/internal/ifcfg_test.go | 16 +++-- overlays/ifcfg/internal/nodes.conf | 3 + .../etc/sysconfig/network-scripts/ifcfg.ww | 15 +++-- .../etc/sysconfig/network-scripts/route.ww | 3 +- overlays/ignition/internal/ignition_test.go | 2 + .../rootfs/etc/systemd/system/ww4-mounts.ww | 3 +- .../rootfs/etc/netplan/01-netcfg.yaml.ww | 3 +- .../systemd/network/10-ww4-netname.link.ww | 3 +- overlays/wicked/internal/wicked_test.go | 4 ++ .../rootfs/etc/wicked/ifconfig/ifcfg.xml.ww | 2 +- userdocs/contents/nodeconfig.rst | 37 +++++++---- userdocs/contents/overlays.rst | 2 +- userdocs/contents/templating.rst | 2 +- 20 files changed, 103 insertions(+), 88 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce84f15e..9fd1c01a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -97,6 +97,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Added note about dnsmasq interface options in Rocky 9. - Added retries to curl in wwinit dracut module. #1631 - Added ip= argument to dracut ipxe script. #1630 +- Updated network interface bonding configuration and documentation. #1482, #1280 ### Removed diff --git a/internal/pkg/overlay/overlay_test.go b/internal/pkg/overlay/overlay_test.go index 0fd21556..5835cee3 100644 --- a/internal/pkg/overlay/overlay_test.go +++ b/internal/pkg/overlay/overlay_test.go @@ -173,7 +173,7 @@ func Test_BuildOverlayIndir(t *testing.T) { overlays: []string{"o1"}, overlayFiles: map[string]string{ "/var/lib/warewulf/overlays/o1/rootfs/file.txt.ww": ` -{{- file "t1.txt" }} +{{ file "t1.txt" }} T1 {{ file "t2.txt" }} T2 @@ -183,7 +183,7 @@ T3 }, outputDir: "/image", outputFiles: map[string]string{ - "t1.txt": "T1\n", + "t1.txt": "\nT1\n", "t2.txt": "T2\n", "t3.txt": "T3\n", }, diff --git a/overlays/NetworkManager/internal/networkmanager_test.go b/overlays/NetworkManager/internal/networkmanager_test.go index 9f2e01f7..d1714669 100644 --- a/overlays/NetworkManager/internal/networkmanager_test.go +++ b/overlays/NetworkManager/internal/networkmanager_test.go @@ -95,6 +95,7 @@ unmanaged-devices=except:mac:e6:92:39:49:7b:03,except:interface-name:wwnet0,exce const networkmanager_managed string = `backupFile: true writeFile: true Filename: warewulf-default.conf + # This file is autogenerated by warewulf [connection] @@ -102,14 +103,12 @@ id=default interface-name=wwnet0 type=ethernet autoconnect=true - [ethernet] mac-address=e6:92:39:49:7b:03 - [ipv4] +method=manual address=192.168.3.21/24 gateway=192.168.3.1 -method=manual [ipv6] addr-gen-mode=stable-privacy @@ -125,14 +124,12 @@ id=secondary interface-name=wwnet1 type=ethernet autoconnect=true - [ethernet] mac-address=9a:77:29:73:14:f1 - [ipv4] +method=manual address=192.168.3.22/24 gateway=192.168.3.1 -method=manual dns=8.8.8.8;8.8.4.4; [ipv6] @@ -144,6 +141,7 @@ never-default=true const networkmanager_managed_with_vlan string = `backupFile: true writeFile: true Filename: warewulf-tagged.conf + # This file is autogenerated by warewulf [connection] @@ -151,12 +149,11 @@ id=tagged interface-name=eth0.902 type=vlan autoconnect=true - +[ethernet] [ipv4] -address= method=manual +address= route1=192.168.1.0/24,192.168.2.254 - [vlan] interface-name=eth0.902 parent=eth0 @@ -176,10 +173,10 @@ id=untagged interface-name=eth0 type=ethernet autoconnect=true - +[ethernet] [ipv4] -address= method=manual +address= [ipv6] addr-gen-mode=stable-privacy diff --git a/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww b/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww index a8edc267..1afa9491 100644 --- a/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww +++ b/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww @@ -1,5 +1,4 @@ -{{- $filename := print "warewulf-unmanaged.conf" }} -{{- file $filename }} +{{ file "warewulf-unmanaged.conf" }} # This file is autogenerated by warewulf [main] diff --git a/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww b/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww index 1c0e5c7c..e1f8dc51 100644 --- a/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww +++ b/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww @@ -1,60 +1,53 @@ -{{- range $connection_id, $netdev := .NetDevs }} -{{- $filename := print "warewulf-" $connection_id ".conf" }} -{{- file $filename }} +{{- range $devname, $netdev := .NetDevs }} +{{ file (print "warewulf-" $devname ".conf") }} # This file is autogenerated by warewulf [connection] -id={{ $connection_id }} +id={{ $devname }} interface-name={{ $netdev.Device }} -{{- if eq $netdev.Type "bond-slave" }} +type={{ default "ethernet" (lower $netdev.Type) }} +{{- if $netdev.Tags.master }} +master={{ $netdev.Tags.master }} slave-type=bond -{{- $conn := split "_" $connection_id }} -{{- $master := $conn._0 }} -master={{ $master }} -type=ethernet -{{- else }} -type={{if $netdev.Type}}{{ $netdev.Type }}{{ else }}ethernet{{end}} +{{- end }} {{- if $netdev.OnBoot }} autoconnect=true {{- end }} -{{- end }} -{{- if $netdev.Hwaddr }} -{{- if or (eq $netdev.Type "ethernet") (not $netdev.Type ) }} - -[ethernet] -mac-address={{ $netdev.Hwaddr }} -{{- if $netdev.MTU }} -mtu={{ $netdev.MTU }} -{{- end }} -{{- end }} -{{- end }} -{{- if eq $netdev.Type "bond" }} +{{- if eq (lower $netdev.Type) "bond" }} [bond] -downdelay=0 -miimon=100 -mode=802.3ad -xmit_hash_policy=layer2+3 -updelay=0 +downdelay={{ default 0 $netdev.Tags.downdelay }} +miimon={{ default 100 $netdev.Tags.miimon }} +mode={{ default "balance-rr" $netdev.Tags.mode }} +xmit_hash_policy={{ default "layer2+3" $netdev.Tags.xmit_hash_policy }} +updelay={{ default 0 $netdev.Tags.updelay }} {{- end }} -{{- if eq $netdev.Type "infiniband" }} +{{- if eq (lower $netdev.Type) "infiniband" }} [infiniband] transport-mode=datagram {{- if $netdev.MTU }} mtu={{ $netdev.MTU }} {{- end }} +{{- else }} +[ethernet] +{{- if $netdev.Hwaddr }} +mac-address={{ $netdev.Hwaddr }} +{{- end }} +{{- if $netdev.MTU }} +mtu={{ $netdev.MTU }} +{{- end }} {{- end }} -{{- if ne $netdev.Type "bond-slave" }} +{{- if not $netdev.Tags.master }} [ipv4] -{{- if not (eq $netdev.IpCIDR nil) }} +method=manual +{{- if $netdev.IpCIDR }} address={{ $netdev.IpCIDR }} {{- end }} {{- if $netdev.Gateway }} gateway={{ $netdev.Gateway }} {{- end }} -method=manual {{- $dns := "" }} {{- range $tk, $tv := $netdev.Tags }} {{- if eq (substr 0 3 $tk) "DNS" }} @@ -63,12 +56,12 @@ method=manual {{$tk}}={{$tv}} {{- end }} {{- end }} -{{- if ne $dns "" }} +{{- if $dns }} dns={{$dns}} {{- end }} {{- end }} -{{- if eq $netdev.Type "vlan" }} +{{- if eq $netdev.Type "vlan" }} [vlan] interface-name={{ $netdev.Device }} parent={{ $netdev.Tags.parent_device }} @@ -79,7 +72,7 @@ id={{ $netdev.Tags.vlan_id }} addr-gen-mode=stable-privacy method=ignore never-default=true -{{ if $netdev.Ipaddr6 -}} +{{- if $netdev.Ipaddr6 }} ipaddr="{{ $netdev.Ipaddr6 }}" {{- end }} -{{- end -}} +{{- end }} diff --git a/overlays/debian.interfaces/internal/debian_interfaces_test.go b/overlays/debian.interfaces/internal/debian_interfaces_test.go index 9973d6df..a94da343 100644 --- a/overlays/debian.interfaces/internal/debian_interfaces_test.go +++ b/overlays/debian.interfaces/internal/debian_interfaces_test.go @@ -52,6 +52,7 @@ func Test_wickedOverlay(t *testing.T) { const debian_interfaces string = `backupFile: true writeFile: true Filename: default + # This file is autogenerated by warewulf allow-hotplug wwnet0 iface wwnet0 inet static @@ -59,6 +60,7 @@ iface wwnet0 inet static netmask 255.255.255.0 gateway 192.168.3.1 mtu 1500 + backupFile: true writeFile: true Filename: secondary diff --git a/overlays/debian.interfaces/rootfs/etc/network/interfaces.d/default.ww b/overlays/debian.interfaces/rootfs/etc/network/interfaces.d/default.ww index e1fe1cdb..302536db 100644 --- a/overlays/debian.interfaces/rootfs/etc/network/interfaces.d/default.ww +++ b/overlays/debian.interfaces/rootfs/etc/network/interfaces.d/default.ww @@ -1,5 +1,5 @@ {{- range $devname, $netdev := .ThisNode.NetDevs }} -{{- file $devname }} +{{ file $devname }} # This file is autogenerated by warewulf {{- if $netdev.OnBoot }} auto {{ $netdev.Device }} diff --git a/overlays/ifcfg/internal/ifcfg_test.go b/overlays/ifcfg/internal/ifcfg_test.go index 6d694c8a..cd77cc9a 100644 --- a/overlays/ifcfg/internal/ifcfg_test.go +++ b/overlays/ifcfg/internal/ifcfg_test.go @@ -72,9 +72,9 @@ func Test_ifcfgOverlay(t *testing.T) { const ifcfg string = `backupFile: true writeFile: true Filename: ifcfg-default.conf -# This file is autogenerated by warewulf -TYPE=ethernet +# This file is autogenerated by warewulf +TYPE=Ethernet DEVICE=wwnet0 NAME=default BOOTPROTO=static @@ -87,12 +87,13 @@ IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no +DNS1=1.1.1.1 +DNS2=1.0.0.1 backupFile: true writeFile: true Filename: ifcfg-secondary.conf # This file is autogenerated by warewulf - -TYPE=ethernet +TYPE=Ethernet DEVICE=wwnet1 NAME=secondary BOOTPROTO=static @@ -119,8 +120,8 @@ HOSTNAME=node1 const ifcfg_vlan string = `backupFile: true writeFile: true Filename: ifcfg-tagged.conf -# This file is autogenerated by warewulf +# This file is autogenerated by warewulf VLAN=yes DEVICE=eth0.902 NAME=tagged @@ -135,8 +136,7 @@ backupFile: true writeFile: true Filename: ifcfg-untagged.conf # This file is autogenerated by warewulf - -TYPE=ethernet +TYPE=Ethernet DEVICE=eth0 NAME=untagged BOOTPROTO=static @@ -151,8 +151,10 @@ IPV6_FAILURE_FATAL=no const ifcfg_routes string = `backupFile: true writeFile: true Filename: route-tagged.conf + # This file is autogenerated by warewulf 192.168.1.0/24 via 192.168.2.254 + backupFile: true writeFile: true Filename: route-untagged.conf diff --git a/overlays/ifcfg/internal/nodes.conf b/overlays/ifcfg/internal/nodes.conf index 59a1dfa8..bfc08d69 100644 --- a/overlays/ifcfg/internal/nodes.conf +++ b/overlays/ifcfg/internal/nodes.conf @@ -7,6 +7,9 @@ nodes: ipaddr: 192.168.3.21 netmask: 255.255.255.0 gateway: 192.168.3.1 + tags: + DNS1: 1.1.1.1 + DNS2: 1.0.0.1 secondary: device: wwnet1 hwaddr: 9a:77:29:73:14:f1 diff --git a/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww b/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww index f89b7c36..53206e73 100644 --- a/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww +++ b/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww @@ -1,12 +1,13 @@ {{- range $devname, $netdev := .NetDevs }} -{{- $filename := print "ifcfg-" $devname ".conf" }} -{{- file $filename }} +{{ file (print "ifcfg-" $devname ".conf") }} # This file is autogenerated by warewulf - -{{ if eq $netdev.Type "vlan" -}} +{{- if eq $netdev.Type "vlan" }} VLAN=yes -{{- else -}} -TYPE={{ default "ethernet" $netdev.Type }} +{{- else }} +TYPE={{ default "Ethernet" $netdev.Type }} +{{- end }} +{{- if $netdev.Tags.master }} +MASTER={{ $netdev.Tags.master }} {{- end }} DEVICE={{ $netdev.Device }} NAME={{ $devname }} @@ -42,4 +43,4 @@ IPV6ADDR="{{ $netdev.Ipaddr6 }}" {{ $tk }}={{ $tv }} {{- end }} {{- end }} -{{ end -}} +{{- end }} diff --git a/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/route.ww b/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/route.ww index 12127fcc..5c01e854 100644 --- a/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/route.ww +++ b/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/route.ww @@ -1,6 +1,5 @@ {{- range $devname, $netdev := .NetDevs }} -{{- $filename := print "route-" $devname ".conf" }} -{{- file $filename }} +{{ file (print "route-" $devname ".conf") }} # This file is autogenerated by warewulf {{- range $tk, $tv := $netdev.Tags }} {{- if eq (substr 0 5 $tk) "route" }} diff --git a/overlays/ignition/internal/ignition_test.go b/overlays/ignition/internal/ignition_test.go index 69d4b566..3bfa27eb 100644 --- a/overlays/ignition/internal/ignition_test.go +++ b/overlays/ignition/internal/ignition_test.go @@ -86,6 +86,7 @@ const ignition_mounts string = `backupFile: true writeFile: true Filename: scratch.mount + # This file is autogenerated by warewulf [Unit] ConditionPathExists=/warewulf/ignition.json @@ -97,6 +98,7 @@ What=/dev/disk/by-partlabel/scratch Type=btrfs [Install] RequiredBy=local-fs.target + backupFile: true writeFile: true Filename: dev-disk-by\x2dpartlabel-swap.swap diff --git a/overlays/ignition/rootfs/etc/systemd/system/ww4-mounts.ww b/overlays/ignition/rootfs/etc/systemd/system/ww4-mounts.ww index 371dce7f..dd4050a6 100644 --- a/overlays/ignition/rootfs/etc/systemd/system/ww4-mounts.ww +++ b/overlays/ignition/rootfs/etc/systemd/system/ww4-mounts.ww @@ -5,8 +5,7 @@ {{ $suffix := "mount"}} {{- if $fs.Label }}{{ $prefix = $fs.Label }}{{ end }} {{- if eq $fs.Format "swap" }}{{ $prefix = replace "/dev/disk/by-partlabel/" "dev-disk-by\\x2dpartlabel-" $fsdevice }}{{ $suffix = "swap" }}{{ end }} -{{- $filename := print $prefix "." $suffix }} -{{- file $filename }} +{{ file (print $prefix "." $suffix) }} # This file is autogenerated by warewulf {{- if eq $fs.Format "swap"}} [Unit] diff --git a/overlays/netplan/rootfs/etc/netplan/01-netcfg.yaml.ww b/overlays/netplan/rootfs/etc/netplan/01-netcfg.yaml.ww index dd7252dd..7bc5572e 100644 --- a/overlays/netplan/rootfs/etc/netplan/01-netcfg.yaml.ww +++ b/overlays/netplan/rootfs/etc/netplan/01-netcfg.yaml.ww @@ -1,6 +1,5 @@ {{range $devname, $netdev := .NetDevs -}} -{{- $filename := print "01-netcfg.yaml" }} -{{- file $filename }} +{{ file "01-netcfg.yaml" }} # This file is autogenerated by warewulf network: version: 2 diff --git a/overlays/systemd.netname/rootfs/etc/systemd/network/10-ww4-netname.link.ww b/overlays/systemd.netname/rootfs/etc/systemd/network/10-ww4-netname.link.ww index 2047d56f..725221f4 100644 --- a/overlays/systemd.netname/rootfs/etc/systemd/network/10-ww4-netname.link.ww +++ b/overlays/systemd.netname/rootfs/etc/systemd/network/10-ww4-netname.link.ww @@ -1,6 +1,5 @@ {{ range $devname, $netdev := .NetDevs -}} -{{- $filename := print "10-ww4-netname-" $devname ".link" }} -{{- file $filename }} +{{ file (print "10-ww4-netname-" $devname ".link") }} # This file is autogenerated by warewulf {{- if and $netdev.Hwaddr $netdev.Device }} [Match] diff --git a/overlays/wicked/internal/wicked_test.go b/overlays/wicked/internal/wicked_test.go index 0d0403e8..1963780f 100644 --- a/overlays/wicked/internal/wicked_test.go +++ b/overlays/wicked/internal/wicked_test.go @@ -58,6 +58,7 @@ func Test_wickedOverlay(t *testing.T) { const wicked string = `backupFile: true writeFile: true Filename: ifcfg-default.xml + @@ -89,6 +90,7 @@ This file is autogenerated by warewulf false + backupFile: true writeFile: true Filename: ifcfg-secondary.xml @@ -128,6 +130,7 @@ This file is autogenerated by warewulf const wicked_vlans string = `backupFile: true writeFile: true Filename: ifcfg-tagged.xml + @@ -165,6 +168,7 @@ This file is autogenerated by warewulf false + backupFile: true writeFile: true Filename: ifcfg-untagged.xml diff --git a/overlays/wicked/rootfs/etc/wicked/ifconfig/ifcfg.xml.ww b/overlays/wicked/rootfs/etc/wicked/ifconfig/ifcfg.xml.ww index 4fd01a6a..fe32bb33 100644 --- a/overlays/wicked/rootfs/etc/wicked/ifconfig/ifcfg.xml.ww +++ b/overlays/wicked/rootfs/etc/wicked/ifconfig/ifcfg.xml.ww @@ -1,6 +1,6 @@ {{- $NetDevs := .NetDevs }} {{- range $devname, $netdev := .ThisNode.NetDevs }} -{{- file (print "ifcfg-" $devname ".xml") }} +{{ file (print "ifcfg-" $devname ".xml") }} diff --git a/userdocs/contents/nodeconfig.rst b/userdocs/contents/nodeconfig.rst index 085e468f..ba2fc3ac 100644 --- a/userdocs/contents/nodeconfig.rst +++ b/userdocs/contents/nodeconfig.rst @@ -204,17 +204,6 @@ image and network: We recommend the use of the original predictable names assigned to the interfaces (`eno1, ...`), as otherwise an interface may remain unconfigured if its name conflicts with the name of an already existing interface during boot. -To configure a bonded (link aggregation) network interface the following commands can be used: - -.. code-block:: console - - # wwctl node set --netname=bond0_member_1 --netdev=eth2 --type=bond-slave n001 - # wwctl node set --netname=bond0_member_2 --netdev=eth3 --type=bond-slave n001 - # wwctl node set --netname=bond0 --netdev=bond0 --onboot=true --type=bond --ipaddr 10.0.3.1 --netmask=255.255.255.0 --mtu=9000 n001 - -Note: the netnames of the member interterfaces need to match the "netname" of the bonded interface until the first "_" (in the example bond0) - - Additional networks ------------------- @@ -232,6 +221,32 @@ You will have provide all the necessary network information. --type infiniband \ n001 +Bonding +------- + +Support for bonded / link aggregation network interfaces depends on the network overlay being used. + +The ``ifcfg`` and ``NetworkManager`` overlays can configure a network bond like this: + +.. code-block:: yaml + + network devices: + bond0: + type: Bond + device: bond0 + ipaddr: 192.168.3.100 + netmask: 255.255.255.0 + en1: + device: en1 + hwaddr: e6:92:39:49:7b:03 + tags: + master: bond0 + en2: + device: en2 + hwaddr: 9a:77:29:73:14:f1 + tags: + master: bond0 + VLAN ---- diff --git a/userdocs/contents/overlays.rst b/userdocs/contents/overlays.rst index 473d32f0..32810e7f 100644 --- a/userdocs/contents/overlays.rst +++ b/userdocs/contents/overlays.rst @@ -312,7 +312,7 @@ more than once in a template to write content to multiple files. {{- range $devname, $netdev := .NetDevs }} {{- $filename := print "ifcfg-" $devname ".conf" }} - {{- file $filename }} + {{ file $filename }} {{/* content here */}} {{- end }} diff --git a/userdocs/contents/templating.rst b/userdocs/contents/templating.rst index 574e74c5..a5459a42 100644 --- a/userdocs/contents/templating.rst +++ b/userdocs/contents/templating.rst @@ -87,7 +87,7 @@ The following template will create a file called {{- $source := .BuildSource }} {{range $devname, $netdev := .NetDevs -}} {{- $filename := print "ifcfg-" $devname ".xml" }} - {{- file $filename }} + {{ file $filename }}