diff --git a/CHANGELOG.md b/CHANGELOG.md index 78190dea..257efc40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added https://github.com/Masterminds/sprig functions to templates #1030 - Add multiple output formats (yaml & json) support. #447 - More aliases for many wwctl commands +- Add support to render template using `host` or `$(uname -n)` as the value of `overlay show --render`. #623 ### Changed diff --git a/internal/app/wwctl/overlay/show/main.go b/internal/app/wwctl/overlay/show/main.go index 6b9713ff..91daae4e 100644 --- a/internal/app/wwctl/overlay/show/main.go +++ b/internal/app/wwctl/overlay/show/main.go @@ -64,10 +64,19 @@ func CobraRunE(cmd *cobra.Command, args []string) error { os.Exit(1) } filteredNodes := node.FilterByName(nodes, []string{NodeName}) - if len(filteredNodes) != 1 { + if hostName, err := os.Hostname(); err != nil { + wwlog.Error("Could not get host name: %s", err) + } else if len(filteredNodes) == 0 && (NodeName == "host" || NodeName == hostName) { + // rendering the host template + hostNodeInfo := new(node.NodeInfo) + hostNodeInfo.Id.Set(hostName) + hostNodeInfo.ClusterName.Set(hostName) + filteredNodes = append(filteredNodes, *hostNodeInfo) + } else if len(filteredNodes) != 1 { wwlog.Error("%v does not identify a single node", NodeName) os.Exit(1) } + tstruct := overlay.InitStruct(&filteredNodes[0]) tstruct.BuildSource = overlayFile buffer, backupFile, writeFile, err := overlay.RenderTemplateFile(overlayFile, tstruct) diff --git a/internal/app/wwctl/overlay/show/main_test.go b/internal/app/wwctl/overlay/show/main_test.go index 47e87a89..8b32eef0 100644 --- a/internal/app/wwctl/overlay/show/main_test.go +++ b/internal/app/wwctl/overlay/show/main_test.go @@ -2,6 +2,7 @@ package show import ( "bytes" + "os" "path" "testing" @@ -85,3 +86,69 @@ nodes: assert.Contains(t, buf.String(), "noMail") }) } + +func TestShowServerTemplate(t *testing.T) { + const template = ` + Id: {{.Id}} + ClusterName: {{.ClusterName}} + BuildHost: {{.BuildHost}} + ` + + env := testenv.New(t) + env.WriteFile(t, "etc/warewulf/nodes.conf", + `WW_INTERNAL: 45 +nodeprofiles: + default: + tags: + email: admin@localhost + empty: {} +nodes: + node1: + tags: + email: admin@node1 + node2: {} + node3: + profiles: + - empty +`) + + env.WriteFile(t, path.Join(testenv.WWOverlaydir, "testoverlay/template.ww"), template) + defer env.RemoveAll(t) + warewulfd.SetNoDaemon() + + host, err := os.Hostname() + if err != nil { + t.Fatal(err) + } + t.Run("overlay render host template using 'host' value", func(t *testing.T) { + baseCmd.SetArgs([]string{"-r", "host", "testoverlay", "template.ww"}) + baseCmd := GetCommand() + buf := new(bytes.Buffer) + baseCmd.SetOut(buf) + baseCmd.SetErr(buf) + wwlog.SetLogWriter(buf) + err := baseCmd.Execute() + assert.NoError(t, err) + assert.Contains(t, buf.String(), "Id: "+host) + assert.Contains(t, buf.String(), "ClusterName: "+host) + assert.Contains(t, buf.String(), "BuildHost: "+host) + }) + + t.Run("overlay render host template using host domain value", func(t *testing.T) { + host, err := os.Hostname() + if err != nil { + t.Fatal(err) + } + baseCmd.SetArgs([]string{"-r", host, "testoverlay", "template.ww"}) + baseCmd := GetCommand() + buf := new(bytes.Buffer) + baseCmd.SetOut(buf) + baseCmd.SetErr(buf) + wwlog.SetLogWriter(buf) + err = baseCmd.Execute() + assert.NoError(t, err) + assert.Contains(t, buf.String(), "Id: "+host) + assert.Contains(t, buf.String(), "ClusterName: "+host) + assert.Contains(t, buf.String(), "BuildHost: "+host) + }) +}