Merge pull request #1477 from anderbubble/vlans-and-static-route

Add support for tagged VLAN interfaces and static routes to network overlays
This commit is contained in:
Christian Goll
2024-11-07 11:48:45 +01:00
committed by GitHub
16 changed files with 447 additions and 164 deletions

View File

@@ -20,6 +20,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Add `wwctl clean` to remove OCI cache and overlays from deleted nodes
- Add `wwctl container import --platform`. #1381
- Read environment variables from `/etc/default/warewulfd` #725
- Add support for VLANs to NetworkManager, wicked, ifcfg, debian.network_interfaces overlays. #1257
- Add support for static routes to NetworkManager, wicked, ifcfg, debian.network_interfaces overlays. #1257
### Changed

View File

@@ -13,66 +13,44 @@ import (
func Test_networkmanagerOverlay(t *testing.T) {
env := testenv.New(t)
defer env.RemoveAll(t)
env.ImportFile(t, "etc/warewulf/nodes.conf", "nodes.conf")
env.ImportFile(t, "var/lib/warewulf/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww", "../rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww")
env.ImportFile(t, "var/lib/warewulf/overlays/NetworkManager/rootfs/etc/NetworkManager/system-connections/ww4-managed.ww", "../rootfs/etc/NetworkManager/system-connections/ww4-managed.ww")
tests := []struct {
name string
args []string
log string
name string
nodes_conf string
args []string
log string
}{
{
name: "NetworkManager:ww4-unmanaged.ww",
args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/conf.d/ww4-unmanaged.ww"},
log: networkmanager_unmanaged,
name: "NetworkManager:ww4-unmanaged.ww",
nodes_conf: "nodes.conf",
args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/conf.d/ww4-unmanaged.ww"},
log: networkmanager_unmanaged,
},
{
name: "NetworkManager:ww4-managed.ww",
args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/system-connections/ww4-managed.ww"},
log: networkmanager_managed,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cmd := show.GetCommand()
cmd.SetArgs(tt.args)
stdout := bytes.NewBufferString("")
stderr := bytes.NewBufferString("")
logbuf := bytes.NewBufferString("")
cmd.SetOut(stdout)
cmd.SetErr(stderr)
wwlog.SetLogWriter(logbuf)
err := cmd.Execute()
assert.NoError(t, err)
assert.Empty(t, stdout.String())
assert.Empty(t, stderr.String())
assert.Equal(t, tt.log, logbuf.String())
})
}
}
func Test_unmanaged_networkmanagerOverlay_with_empty_mac(t *testing.T) {
env := testenv.New(t)
defer env.RemoveAll(t)
env.ImportFile(t, "etc/warewulf/nodes.conf", "nodes_empty_mac.conf")
env.ImportFile(t, "var/lib/warewulf/overlays/NetworkManager/rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww", "../rootfs/etc/NetworkManager/conf.d/ww4-unmanaged.ww")
tests := []struct {
name string
args []string
log string
}{
{
name: "NetworkManager:ww4-unmanaged.ww",
args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/conf.d/ww4-unmanaged.ww"},
log: networkmanager_unmanaged_with_empty_mac,
name: "NetworkManager:ww4-managed.ww",
nodes_conf: "nodes.conf",
args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/system-connections/ww4-managed.ww"},
log: networkmanager_managed,
},
{
name: "NetworkManager:ww4-unmanaged.ww with empty mac address",
nodes_conf: "nodes_empty_mac.conf",
args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/conf.d/ww4-unmanaged.ww"},
log: networkmanager_unmanaged_with_empty_mac,
},
{
name: "NetworkManager:ww4-managed.ww with vlan",
nodes_conf: "nodes.conf-vlan",
args: []string{"--render", "node1", "NetworkManager", "etc/NetworkManager/system-connections/ww4-managed.ww"},
log: networkmanager_managed_with_vlan,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
env.ImportFile(t, "etc/warewulf/nodes.conf", tt.nodes_conf)
cmd := show.GetCommand()
cmd.SetArgs(tt.args)
stdout := bytes.NewBufferString("")
@@ -94,6 +72,7 @@ const networkmanager_unmanaged_with_empty_mac string = `backupFile: true
writeFile: true
Filename: warewulf-unmanaged.conf
# This file is autogenerated by warewulf
[main]
plugins=keyfile
@@ -105,6 +84,7 @@ const networkmanager_unmanaged string = `backupFile: true
writeFile: true
Filename: warewulf-unmanaged.conf
# This file is autogenerated by warewulf
[main]
plugins=keyfile
@@ -116,14 +96,16 @@ const networkmanager_managed string = `backupFile: true
writeFile: true
Filename: warewulf-default.conf
# This file is autogenerated by warewulf
[connection]
id=default
interface-name=wwnet0
type=ethernet
autoconnect=true
[ethernet]
mac-address=e6:92:39:49:7b:03
# bond
[ipv4]
address=192.168.3.21/24
gateway=192.168.3.1
@@ -137,14 +119,16 @@ backupFile: true
writeFile: true
Filename: warewulf-secondary.conf
# This file is autogenerated by warewulf
[connection]
id=secondary
interface-name=wwnet1
type=ethernet
autoconnect=true
[ethernet]
mac-address=9a:77:29:73:14:f1
# bond
[ipv4]
address=192.168.3.22/24
gateway=192.168.3.1
@@ -156,3 +140,49 @@ addr-gen-mode=stable-privacy
method=ignore
never-default=true
`
const networkmanager_managed_with_vlan string = `backupFile: true
writeFile: true
Filename: warewulf-tagged.conf
# This file is autogenerated by warewulf
[connection]
id=tagged
interface-name=eth0.902
type=vlan
autoconnect=true
[ipv4]
address=<nil>
method=manual
route1=192.168.1.0/24,192.168.2.254
[vlan]
interface-name=eth0.902
parent=eth0
id=902
[ipv6]
addr-gen-mode=stable-privacy
method=ignore
never-default=true
backupFile: true
writeFile: true
Filename: warewulf-untagged.conf
# This file is autogenerated by warewulf
[connection]
id=untagged
interface-name=eth0
type=ethernet
autoconnect=true
[ipv4]
address=<nil>
method=manual
[ipv6]
addr-gen-mode=stable-privacy
method=ignore
never-default=true
`

View File

@@ -0,0 +1,13 @@
nodes:
node1:
primary network: untagged
network devices:
untagged:
device: eth0
tagged:
type: vlan
device: eth0.902
tags:
vlan_id: 902
parent_device: eth0
route1: "192.168.1.0/24,192.168.2.254"

View File

@@ -1,6 +1,7 @@
{{- $filename := print "warewulf-unmanaged.conf" }}
{{- file $filename }}
# This file is autogenerated by warewulf
[main]
plugins=keyfile

View File

@@ -2,78 +2,84 @@
{{- $filename := print "warewulf-" $connection_id ".conf" }}
{{- file $filename }}
# This file is autogenerated by warewulf
[connection]
id={{ $connection_id }}
interface-name={{ $netdev.Device }}
{{ if eq $netdev.Type "bond-slave" -}}
{{- if eq $netdev.Type "bond-slave" }}
slave-type=bond
{{- $conn := split "_" $connection_id }}
{{- $master := $conn._0 }}
master={{ $master }}
type=ethernet
{{ else -}}
{{- else }}
type={{if $netdev.Type}}{{ $netdev.Type }}{{ else }}ethernet{{end}}
{{ if or $netdev.OnBoot (eq $netdev.OnBoot nil) -}}
{{- if or $netdev.OnBoot (eq $netdev.OnBoot nil) }}
autoconnect=true
{{ end -}}
{{ end -}}
{{ if $netdev.Hwaddr -}}
{{ if or (eq $netdev.Type "ethernet") (not $netdev.Type ) -}}
{{- end }}
{{- end }}
{{- if $netdev.Hwaddr }}
{{- if or (eq $netdev.Type "ethernet") (not $netdev.Type ) }}
[ethernet]
mac-address={{ $netdev.Hwaddr }}
{{ if $netdev.MTU -}}
{{- if $netdev.MTU }}
mtu={{ $netdev.MTU }}
{{ end -}}
{{ end -}}
{{ end -}}
{{- end }}
{{- end }}
{{- end }}
{{- if eq $netdev.Type "bond" }}
# bond
{{ if eq $netdev.Type "bond" -}}
[ethernet]
{{ if $netdev.MTU -}}
mtu={{ $netdev.MTU }}
{{ end -}}
[bond]
downdelay=0
miimon=100
mode=802.3ad
xmit_hash_policy=layer2+3
updelay=0
{{ end -}}
{{- end }}
{{- if eq $netdev.Type "infiniband" }}
{{ if eq $netdev.Type "infiniband" -}}
[infiniband]
transport-mode=datagram
{{ if $netdev.MTU -}}
{{- if $netdev.MTU }}
mtu={{ $netdev.MTU }}
{{ end -}}
{{ end -}}
{{- end }}
{{- end }}
{{- if ne $netdev.Type "bond-slave" }}
{{ if and ($netdev.IpCIDR) (ne $netdev.Type "bond-slave") -}}
[ipv4]
{{- if not (eq $netdev.IpCIDR nil) }}
address={{ $netdev.IpCIDR }}
{{ if $netdev.Gateway -}}
{{- end }}
{{- if $netdev.Gateway }}
gateway={{ $netdev.Gateway }}
{{ end -}}
{{- end }}
method=manual
{{- $dns := "" }}
{{range $tk, $tv := $netdev.Tags -}}
{{ $prefix := substr 0 3 $tk -}}
{{ if eq $prefix "DNS" -}}
{{ $dns = print $dns $tv ";" -}}
{{ end -}}
{{ end -}}
{{ if ne $dns "" -}}
{{- range $tk, $tv := $netdev.Tags }}
{{- if eq (substr 0 3 $tk) "DNS" }}
{{- $dns = print $dns $tv ";" }}
{{- else if eq (substr 0 5 $tk) "route" }}
{{$tk}}={{$tv}}
{{- end }}
{{- end }}
{{- if ne $dns "" }}
dns={{$dns}}
{{ end -}}
{{ end -}}
{{- end }}
{{- end }}
{{- if eq $netdev.Type "vlan" }}
[vlan]
interface-name={{ $netdev.Device }}
parent={{ $netdev.Tags.parent_device }}
id={{ $netdev.Tags.vlan_id }}
{{- end }}
{{/* always autoconfigure ipv6 */}}
[ipv6]
addr-gen-mode=stable-privacy
method=ignore
never-default=true
{{ if $netdev.Ipaddr6 -}}
ipaddr="{{ $netdev.Ipaddr6 }}"
{{ end -}}
{{ end -}}
{{- end }}
{{- end -}}

View File

@@ -13,23 +13,25 @@ import (
func Test_wickedOverlay(t *testing.T) {
env := testenv.New(t)
defer env.RemoveAll(t)
env.ImportFile(t, "etc/warewulf/nodes.conf", "nodes.conf")
env.ImportFile(t, "var/lib/warewulf/overlays/debian.interfaces/rootfs/etc/network/interfaces.d/default.ww", "../rootfs/etc/network/interfaces.d/default.ww")
tests := []struct {
name string
args []string
log string
name string
nodes_conf string
args []string
log string
}{
{
name: "debian.interfaces",
args: []string{"--render", "node1", "debian.interfaces", "etc/network/interfaces.d/default.ww"},
log: debian_interfaces,
name: "debian.interfaces",
nodes_conf: "nodes.conf",
args: []string{"--render", "node1", "debian.interfaces", "etc/network/interfaces.d/default.ww"},
log: debian_interfaces,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
env.ImportFile(t, "etc/warewulf/nodes.conf", tt.nodes_conf)
cmd := show.GetCommand()
cmd.SetArgs(tt.args)
stdout := bytes.NewBufferString("")
@@ -69,5 +71,5 @@ iface wwnet1 inet static
netmask 255.255.255.0
gateway 192.168.3.1
mtu 9000
up ifmetric wwnet1 30
up ip route add 192.168.1.0/24 via 192.168.3.254 dev wwnet1
`

View File

@@ -15,3 +15,5 @@ nodes:
netmask: 255.255.255.0
gateway: 192.168.3.1
mtu: 9000
tags:
route1: "192.168.1.0/24,192.168.3.254"

View File

@@ -1,15 +1,18 @@
{{range $devname, $netdev := .ThisNode.NetDevs -}}
{{- $filename := print $devname }}
{{- file $filename }}
{{- range $devname, $netdev := .ThisNode.NetDevs }}
{{- file $devname }}
# This file is autogenerated by warewulf
{{ if or $netdev.OnBoot (eq $netdev.OnBoot nil) -}}
auto {{$netdev.Device}}
{{- if or $netdev.OnBoot (eq $netdev.OnBoot nil) }}
auto {{ $netdev.Device }}
{{- end }}
allow-hotplug {{ $netdev.Device }}
iface {{ $netdev.Device }} inet static
address {{ $netdev.Ipaddr }}
netmask {{ $netdev.Netmask }}
{{ if $netdev.Gateway }}gateway {{ $netdev.Gateway }}{{ end }}
{{ if $netdev.MTU }}mtu {{ $netdev.MTU }}{{ end }}
{{- range $tk, $tv := $netdev.Tags }}
{{- if eq (substr 0 5 $tk) "route" }}
up ip route add {{ index (splitList "," $tv) 0 }} via {{ index (splitList "," $tv) 1 }} dev {{ $netdev.Device }}
{{- end }}
{{- end }}
{{ end -}}
allow-hotplug {{$netdev.Device}}
iface {{$netdev.Device}} inet static
address {{$netdev.Ipaddr}}
netmask {{$netdev.Netmask}}
{{ if $netdev.Gateway }}gateway {{$netdev.Gateway}}{{- end}}
{{ if $netdev.MTU }}mtu {{$netdev.MTU}}{{- end}}
up ifmetric {{$netdev.Device}} 30
{{- end}}

View File

@@ -13,29 +13,45 @@ import (
func Test_ifcfgOverlay(t *testing.T) {
env := testenv.New(t)
defer env.RemoveAll(t)
env.ImportFile(t, "etc/warewulf/nodes.conf", "nodes.conf")
env.ImportFile(t, "var/lib/warewulf/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/ifcfg.ww", "../rootfs/etc/sysconfig/network-scripts/ifcfg.ww")
env.ImportFile(t, "var/lib/warewulf/overlays/ifcfg/rootfs/etc/sysconfig/network-scripts/route.ww", "../rootfs/etc/sysconfig/network-scripts/route.ww")
env.ImportFile(t, "var/lib/warewulf/overlays/ifcfg/rootfs/etc/sysconfig/network.ww", "../rootfs/etc/sysconfig/network.ww")
tests := []struct {
name string
args []string
log string
name string
nodes_conf string
args []string
log string
}{
{
name: "ifcfg:ifcfg.ww",
args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network-scripts/ifcfg.ww"},
log: ifcfg,
name: "ifcfg:ifcfg.ww",
nodes_conf: "nodes.conf",
args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network-scripts/ifcfg.ww"},
log: ifcfg,
},
{
name: "ifcfg:network.ww",
args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network.ww"},
log: ifcfg_network,
name: "ifcfg:network.ww",
nodes_conf: "nodes.conf",
args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network.ww"},
log: ifcfg_network,
},
{
name: "ifcfg:ifcfg.ww (vlan)",
nodes_conf: "nodes.conf-vlan",
args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network-scripts/ifcfg.ww"},
log: ifcfg_vlan,
},
{
name: "ifcfg:route.ww",
nodes_conf: "nodes.conf-vlan",
args: []string{"--render", "node1", "ifcfg", "etc/sysconfig/network-scripts/route.ww"},
log: ifcfg_routes,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
env.ImportFile(t, "etc/warewulf/nodes.conf", tt.nodes_conf)
cmd := show.GetCommand()
cmd.SetArgs(tt.args)
stdout := bytes.NewBufferString("")
@@ -57,6 +73,7 @@ const ifcfg string = `backupFile: true
writeFile: true
Filename: ifcfg-default.conf
# This file is autogenerated by warewulf
TYPE=ethernet
DEVICE=wwnet0
NAME=default
@@ -75,6 +92,7 @@ backupFile: true
writeFile: true
Filename: ifcfg-secondary.conf
# This file is autogenerated by warewulf
TYPE=ethernet
DEVICE=wwnet1
NAME=secondary
@@ -99,3 +117,46 @@ Filename: etc/sysconfig/network
NETWORKING=yes
HOSTNAME=node1
`
const ifcfg_vlan string = `backupFile: true
writeFile: true
Filename: ifcfg-tagged.conf
# This file is autogenerated by warewulf
VLAN=yes
DEVICE=eth0.902
NAME=tagged
BOOTPROTO=static
DEVTIMEOUT=10
ONBOOT=true
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
backupFile: true
writeFile: true
Filename: ifcfg-untagged.conf
# This file is autogenerated by warewulf
TYPE=ethernet
DEVICE=eth0
NAME=untagged
BOOTPROTO=static
DEVTIMEOUT=10
ONBOOT=true
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
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
# This file is autogenerated by warewulf
`

View File

@@ -0,0 +1,11 @@
nodes:
node1:
primary network: untagged
network devices:
untagged:
device: eth0
tagged:
type: vlan
device: eth0.902
tags:
route1: "192.168.1.0/24,192.168.2.254"

View File

@@ -1,41 +1,45 @@
{{range $devname, $netdev := .NetDevs -}}
{{- range $devname, $netdev := .NetDevs }}
{{- $filename := print "ifcfg-" $devname ".conf" }}
{{- file $filename }}
# This file is autogenerated by warewulf
{{ if $netdev.Type -}}
TYPE={{ $netdev.Type }}
{{ else -}}
TYPE=ethernet
{{ end -}}
{{ if eq $netdev.Type "vlan" -}}
VLAN=yes
{{- else -}}
TYPE={{ default "ethernet" $netdev.Type }}
{{- end }}
DEVICE={{ $netdev.Device }}
NAME={{ $devname }}
{{ if $netdev.MTU -}}
{{- if $netdev.MTU }}
MTU={{ $netdev.MTU }}
{{ end -}}
{{- end }}
BOOTPROTO=static
DEVTIMEOUT=10
{{- if $netdev.Ipaddr }}
IPADDR={{ $netdev.Ipaddr }}
{{- end }}
{{- if $netdev.Netmask }}
NETMASK={{ $netdev.Netmask }}
{{ if $netdev.Gateway -}}
{{- end }}
{{- if $netdev.Gateway }}
GATEWAY={{ $netdev.Gateway }}
{{ end -}}
{{ if $netdev.Hwaddr -}}
{{- end }}
{{- if $netdev.Hwaddr }}
HWADDR={{ $netdev.Hwaddr }}
{{ end -}}
{{- end }}
{{ if or $netdev.OnBoot (eq $netdev.OnBoot nil) -}}
ONBOOT=true
{{ end -}}
{{- end }}
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
{{ if $netdev.Ipaddr6 -}}
{{- if $netdev.Ipaddr6 }}
IPV6ADDR="{{ $netdev.Ipaddr6 }}"
{{ end -}}
{{range $tk, $tv := $netdev.Tags -}}
{{ $prefix := substr 0 3 $tk -}}
{{ if eq $prefix "DNS" -}}
{{- end }}
{{- range $tk, $tv := $netdev.Tags }}
{{- if eq (substr 0 3 $tk) "DNS" }}
{{ $tk }}={{ $tv }}
{{ end -}}
{{ end -}}
{{- end }}
{{- end }}
{{ end -}}

View File

@@ -0,0 +1,10 @@
{{- range $devname, $netdev := .NetDevs }}
{{- $filename := print "route-" $devname ".conf" }}
{{- file $filename }}
# This file is autogenerated by warewulf
{{- range $tk, $tv := $netdev.Tags }}
{{- if eq (substr 0 5 $tk) "route" }}
{{ index (splitList "," $tv) 0 }} via {{ index (splitList "," $tv) 1 }}
{{- end }}
{{- end }}
{{ end -}}

View File

@@ -0,0 +1,13 @@
nodes:
node1:
primary network: untagged
network devices:
untagged:
device: eth0
tagged:
type: vlan
device: eth0.902
tags:
vlan_id: 902
parent_device: eth0
route1: "192.168.1.0/24,192.168.2.254"

View File

@@ -13,23 +13,31 @@ import (
func Test_wickedOverlay(t *testing.T) {
env := testenv.New(t)
defer env.RemoveAll(t)
env.ImportFile(t, "etc/warewulf/nodes.conf", "nodes.conf")
env.ImportFile(t, "var/lib/warewulf/overlays/wicked/rootfs/etc/wicked/ifconfig/ifcfg.xml.ww", "../rootfs/etc/wicked/ifconfig/ifcfg.xml.ww")
tests := []struct {
name string
args []string
log string
name string
nodes_conf string
args []string
log string
}{
{
name: "wicked",
args: []string{"--render", "node1", "wicked", "etc/wicked/ifconfig/ifcfg.xml.ww"},
log: wicked,
name: "wicked",
nodes_conf: "nodes.conf",
args: []string{"--render", "node1", "wicked", "etc/wicked/ifconfig/ifcfg.xml.ww"},
log: wicked,
},
{
name: "wicked-vlans",
nodes_conf: "nodes.conf-vlan",
args: []string{"--render", "node1", "wicked", "etc/wicked/ifconfig/ifcfg.xml.ww"},
log: wicked_vlans,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
env.ImportFile(t, "etc/warewulf/nodes.conf", tt.nodes_conf)
cmd := show.GetCommand()
cmd.SetArgs(tt.args)
stdout := bytes.NewBufferString("")
@@ -69,12 +77,12 @@ This file is autogenerated by warewulf
<address>
<local>192.168.3.21/24</local>
</address>
<route>
<route>
<nexthop>
<gateway>192.168.3.1</gateway>
</nexthop>
</route>
</ipv4:static>
</ipv4:static>
<ipv6>
<enabled>true</enabled>
<privacy>prefer-public</privacy>
@@ -103,12 +111,83 @@ This file is autogenerated by warewulf
<address>
<local>192.168.3.22/24</local>
</address>
<route>
<route>
<nexthop>
<gateway>192.168.3.1</gateway>
</nexthop>
</route>
</ipv4:static>
</ipv4:static>
<ipv6>
<enabled>true</enabled>
<privacy>prefer-public</privacy>
<accept-redirects>false</accept-redirects>
</ipv6>
</interface>
`
const wicked_vlans string = `backupFile: true
writeFile: true
Filename: ifcfg-tagged.xml
<!--
This file is autogenerated by warewulf
-->
<interface origin="static generated warewulf config">
<name>eth0.902</name>
<link-type>vlan</link-type>
<vlan>
<device>eth0</device>
<tag>902</tag>
<protocol>ieee802-1Q</protocol>
</vlan>
<control>
<mode>boot</mode>
</control>
<firewall/>
<link/>
<ipv4>
<enabled>true</enabled>
<arp-verify>true</arp-verify>
</ipv4>
<ipv4:static>
<address>
<local><nil></local>
</address>
<route>
<destination>192.168.1.0/24</destination>
<nexthop>
<gateway>192.168.2.254</gateway>
</nexthop>
</route>
</ipv4:static>
<ipv6>
<enabled>true</enabled>
<privacy>prefer-public</privacy>
<accept-redirects>false</accept-redirects>
</ipv6>
</interface>
backupFile: true
writeFile: true
Filename: ifcfg-untagged.xml
<!--
This file is autogenerated by warewulf
-->
<interface origin="static generated warewulf config">
<name>eth0</name>
<link-type>ethernet</link-type>
<control>
<mode>boot</mode>
</control>
<firewall/>
<link/>
<ipv4>
<enabled>true</enabled>
<arp-verify>true</arp-verify>
</ipv4>
<ipv4:static>
<address>
<local><nil></local>
</address>
</ipv4:static>
<ipv6>
<enabled>true</enabled>
<privacy>prefer-public</privacy>

View File

@@ -1,20 +1,22 @@
{{ $NetDevs := .NetDevs -}}{{/* FIX: 1413 */ -}}
{{range $devname, $netdev := .ThisNode.NetDevs -}}
{{- $filename := print "ifcfg-" $devname ".xml" }}
{{- file $filename }}
{{- $NetDevs := .NetDevs }}
{{- range $devname, $netdev := .ThisNode.NetDevs }}
{{- file (print "ifcfg-" $devname ".xml") }}
<!--
This file is autogenerated by warewulf
-->
<interface origin="static generated warewulf config">
<name>{{$netdev.Device}}</name>
{{ if $netdev.Type -}}
<link-type>{{ $netdev.Type }}</link-type>
{{ else -}}
<link-type>ethernet</link-type>
{{ end -}}
{{ if $netdev.MTU -}}
<name>{{ $netdev.Device }}</name>
<link-type>{{ default "ethernet" $netdev.Type }}</link-type>
{{- if eq $netdev.Type "vlan" }}
<vlan>
<device>{{ $netdev.Tags.parent_device }}</device>
<tag>{{ $netdev.Tags.vlan_id }}</tag>
<protocol>ieee802-1Q</protocol>
</vlan>
{{- end }}
{{- if $netdev.MTU }}
<mtu>{{ $netdev.MTU }}</mtu>
{{ end -}}
{{- end }}
<control>
<mode>{{ if or $netdev.OnBoot (eq $netdev.OnBoot nil) }}boot{{ else }}manual{{end}}</mode>
</control>
@@ -28,25 +30,35 @@ This file is autogenerated by warewulf
<address>
<local>{{$netdev.IpCIDR}}</local>
</address>
{{ if $netdev.Gateway -}}
{{- if $netdev.Gateway }}
<route>
<nexthop>
<gateway>{{$netdev.Gateway}}</gateway>
</nexthop>
</route>
{{ end -}}
{{- end }}
{{- range $tk, $tv := $netdev.Tags }}
{{- if eq (substr 0 5 $tk) "route" }}
<route>
<destination>{{ index (splitList "," $tv) 0 }}</destination>
<nexthop>
<gateway>{{ index (splitList "," $tv) 1 }}</gateway>
</nexthop>
</route>
{{- end }}
{{- end }}
</ipv4:static>
<ipv6>
<enabled>true</enabled>
<privacy>prefer-public</privacy>
<accept-redirects>false</accept-redirects>
</ipv6>
{{ if $netdev.Ipaddr6 -}}
{{- if $netdev.Ipaddr6 }}
<ipv6:static>
<address>
<local>{{ $netdev.Ipaddr6 }}</local>
</address>
</ipv6:static>
{{ end -}}
{{- end }}
</interface>
{{ end -}}

View File

@@ -261,6 +261,40 @@ You will have provide all the necessary network information.
--type infiniband \
n001
VLAN
----
You can set the type also to ``vlan``.
Some network configuration systems use the network device name
(e.g., of the form ``eno1.100``)
to configure VLANs.
Other network systems need additional network tags:
- ``vlan_id``: configures the VLAN ID of the interface
- ``parent_device``: configures which physical interface to use
.. code-block:: shell
wwctl node set \
--netdev vlan42 \
--ipaddr 10.0.42.1 \
--netmask 255.255.252.0 \
--netname iband \
--type vlan \
--nettagadd "vlan_id=42,parent_device=eth0" \
n001
Static Routes
-------------
The included Warewulf network overlays support the configuration of static routes
using a network tag of the form ``route<N>=<dest>,<gateway>``.
.. code-block:: shell
wwctl node set n001 \
--nettagadd "route1=192.168.2.0/24,192.168.1.254"
Node Discovery
--------------