Templating
Warewulf uses the text/template
engine to convert dynamic content
into static content and auto-populate files with the appropriate data
on demand.
In Warewulf, you can find templates both for the provisioning services
(e.g. /etc/warewulf/ipxe/
, /etc/warewulf/dhcp/
, and
/etc/warewulf/hosts.tmpl
) as well as within many of the provided
overlays.
(more documentation coming soon)
Examples
Comment
{{ /* This comment won't show up in file, but an empty line /* }}
{{ /* No empty line, line break removed at end of this line /* -}}
{{- /* No empty line, line break removed at front of this line /* }}
Range
iterate over elements of an array
{{ range $devname, $netdev := .NetDevs }}
# netdev = {{ $netdev.Hwaddr }}
{{ end }}
Increment Variable In Loop
iterate over elements of an array and increment i
each loop cycle
{{ $i := 0 }}
{{ range $devname, $netdev := .NetDevs }}
# netdev{{$i}} = {{ $netdev.Hwaddr }}
{{ $i = inc $i }}
{{ end }}
Decrement
iterate over elements of an array and decrement i
each loop cycle
{{ $i := 10 }}
{{ range $devname, $netdev := .NetDevs }}
# netdev{{$i}} = {{ $netdev.Hwaddr }}
{{ $i = dec $i }}
{{ end }}
Access Tag
Acces the value of an individual tag foo
foo: {{ index .Tags "foo" }}
{{ if eq (index .Tags "foo") "baar" -}}
foo: {{ index .Tags "foo" }}
{{ end -}}
Create Multiple Files
The following template will create a file called
ifcfg-NETWORKNAME.xml
for every network present on the node
{{- $host := .BuildHost }}
{{- $time := .BuildTime }}
{{- $source := .BuildSource }}
{{range $devname, $netdev := .NetDevs -}}
{{- $filename := print "ifcfg-" $devname ".xml" }}
{{- file $filename }}
<!--
This file is autogenerated by warewulf
Host: {{ $host }}
Time: {{ $time }}
Source: {{ $source }}
-->
<interface origin="static generated warewulf config">
<name>{{$netdev.Device}}</name>
{{ if $netdev.Type -}}
<link-type>{{ $netdev.Type }}</link-type>
{{ end -}}
<control>
<mode>boot</mode>
</control>
<firewall/>
<link/>
<ipv4>
<enabled>true</enabled>
<arp-verify>true</arp-verify>
</ipv4>
<ipv4:static>
<address>
<local>{{$netdev.Ipaddr}}/{{$netdev.Ipmask}}</local>
</address>
{{ if $netdev.Gateway -}}
<route>
<nexthop>
<gateway>{{$netdev.Gateway}}</gateway>
</nexthop>
</route>
{{ end -}}
</ipv4:static>
<ipv6>
<enabled>true</enabled>
<privacy>prefer-public</privacy>
<accept-redirects>false</accept-redirects>
</ipv6>
{{ if $netdev.Ipaddr6 -}}
<ipv6:static>
<address>
<local>{{ $netdev.Ipaddr6 }}</local>
</address>
</ipv6:static>
{{ end -}}
</interface>
{{ end -}}
Special Commands
Include
A file from the host can be include with following template
{{ Include file }}
IncludeFrom
With following snippet a file from a given container can be included
{{ IncludeFrom container file }}
IncludeBlock
Includes a file up to the line where a abort string is found. This is useful, e.g., for the hosts file, which can have local modifications which are not controlled by warewulf. For this example the abort string is “# Do not edit after this line”
{{ IncludeBlock "/etc/hosts" "# Do not edit after this line" }}
# This block is autogenerated by warewulf
# Host: {{.BuildHost}}
# Time: {{.BuildTime}}
# Source: {{.BuildSource}}
# Warewulf Server
{{$.Ipaddr}} warewulf {{$.BuildHost}}
{{- range $node := $.AllNodes}} {{/* for each node */}}
# Entry for {{$node.Id}}
{{- range $devname, $netdev := $node.NetDevs}} {{/* for each network device on the node */}}
{{- if $netdev.Ipaddr}} {{/* if we have an ip address on this network device */}}
{{- /* emit the node name as hostname if this is the primary */}}
{{$netdev.Ipaddr}} {{$node.Id}}-{{$devname}}
{{- if $netdev.Device}} {{$node.Id()}}-{{$netdev.Device}}{{end}}
{{- if $netdev.Primary}} {{$node.Id()}}{{end}}
{{- end}} {{/* end if ip */}}
{{- end}} {{/* end for each network device */}}
{{- end}} {{/* end for each node */}}
Abort
If {{ abort }}
is found in a template, the resulting file isn’t written.
Nobackup
If a file exists on the target, a backup file is written with the
suffix .wwbackup
. This only happens for the host
overlay, as
e.g. the /etc/hosts
exists on the host. If this is not the
intended behavior, the {{ nobackup }}
flag can be added to a
template.
Split
A given string can be split into substrings.
{{ $x := "a:b:c" -}}
{{ $y := (split $x ":") -}}
{{ range $y }} {{.}} {{ end }}
Node specific files
Sometimes there is the need to have specific files for every node which can’t be generated by a template. You can include these files with following template:
{{- $filename := print "/root/" .Id "-payload" }}
{{ Include $filename }}