new overlay variables command

This commit is contained in:
Christian Goll
2025-10-13 17:07:14 +02:00
committed by Jonathon Anderson
parent 847a4386e1
commit facde98fb5
4 changed files with 171 additions and 0 deletions

View File

@@ -12,6 +12,7 @@ import (
"github.com/warewulf/warewulf/internal/app/wwctl/overlay/list"
"github.com/warewulf/warewulf/internal/app/wwctl/overlay/mkdir"
"github.com/warewulf/warewulf/internal/app/wwctl/overlay/show"
"github.com/warewulf/warewulf/internal/app/wwctl/overlay/variables"
)
var (
@@ -35,6 +36,7 @@ func init() {
baseCmd.AddCommand(imprt.GetCommand())
baseCmd.AddCommand(chmod.GetCommand())
baseCmd.AddCommand(chown.GetCommand())
baseCmd.AddCommand(variables.GetCommand())
}
// GetRootCommand returns the root cobra.Command for the application.

View File

@@ -0,0 +1,30 @@
package variables
import (
"fmt"
"strings"
"github.com/spf13/cobra"
"github.com/warewulf/warewulf/internal/pkg/overlay"
"github.com/warewulf/warewulf/internal/pkg/wwlog"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
overlayName := args[0]
filePath := args[1]
ov, err := overlay.Get(overlayName)
if err != nil {
wwlog.Error("Failed to get overlay %s: %s", overlayName, err)
return err
}
vars := ov.ParseVars(filePath)
if vars == nil {
return fmt.Errorf("could not parse variables for %s in overlay %s", filePath, overlayName)
}
fmt.Println(strings.Join(vars, "\n"))
return nil
}

View File

@@ -0,0 +1,100 @@
package variables
import (
"bytes"
"io"
"os"
"path"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/warewulf/warewulf/internal/pkg/testenv"
"github.com/warewulf/warewulf/internal/pkg/wwlog"
)
func Test_Overlay_Variables(t *testing.T) {
env := testenv.New(t)
defer env.RemoveAll()
conf := env.Configure()
// be quiet
wwlog.SetLogFormatter(func(int, *wwlog.LogRecord) string { return "" })
overlayDir := path.Join(conf.Paths.SiteOverlaydir(), "test-overlay")
err := os.MkdirAll(overlayDir, 0755)
if err != nil {
t.Fatalf("could not create overlay dir: %v", err)
}
templateContent := `
{{ .Kernel.Tags.foo }}
{{ .Node.Tags.bar }}
{{ .Cluster.Tags.baz }}
`
templatePath := path.Join(overlayDir, "test.ww")
err = os.WriteFile(templatePath, []byte(templateContent), 0644)
if err != nil {
t.Fatalf("could not write template file: %v", err)
}
// Redirect stdout
old := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
baseCmd.SetArgs([]string{"test-overlay", "test.ww"})
err = baseCmd.Execute()
assert.NoError(t, err)
// Restore stdout
w.Close()
os.Stdout = old
var buf bytes.Buffer
_, err = io.Copy(&buf, r)
if err != nil {
t.Fatalf("could not read stdout: %v", err)
}
output := strings.TrimSpace(buf.String())
expected := []string{
".Kernel.Tags.foo",
".Node.Tags.bar",
".Cluster.Tags.baz",
}
outputLines := strings.Split(output, "\n")
assert.ElementsMatch(t, expected, outputLines)
}
func Test_Overlay_Variables_No_File(t *testing.T) {
env := testenv.New(t)
defer env.RemoveAll()
conf := env.Configure()
// be quiet
wwlog.SetLogFormatter(func(int, *wwlog.LogRecord) string { return "" })
overlayDir := path.Join(conf.Paths.SiteOverlaydir(), "test-overlay")
err := os.MkdirAll(overlayDir, 0755)
if err != nil {
t.Fatalf("could not create overlay dir: %v", err)
}
baseCmd.SetArgs([]string{"test-overlay", "test.ww"})
err = baseCmd.Execute()
assert.Error(t, err)
}
func Test_Overlay_Variables_No_Overlay(t *testing.T) {
env := testenv.New(t)
defer env.RemoveAll()
env.Configure()
// be quiet
wwlog.SetLogFormatter(func(int, *wwlog.LogRecord) string { return "" })
baseCmd.SetArgs([]string{"no-overlay", "test.ww"})
err := baseCmd.Execute()
assert.Error(t, err)
}

View File

@@ -0,0 +1,39 @@
package variables
import (
"github.com/spf13/cobra"
"github.com/warewulf/warewulf/internal/pkg/overlay"
)
var (
baseCmd = &cobra.Command{
Use: "variables [flags] OVERLAY_NAME FILE_PATH",
Short: "Show variables for a template file in an overlay",
Long: "This command will show the variables for a given template file in a given\n" + "overlay.",
Aliases: []string{"vars", "tags"},
Args: cobra.ExactArgs(2),
RunE: CobraRunE,
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) == 0 {
return overlay.FindOverlays(), cobra.ShellCompDirectiveNoFileComp
} else if len(args) == 1 {
ov, err := overlay.Get(args[0])
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
files, err := ov.GetFiles()
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
return files, cobra.ShellCompDirectiveNoFileComp
}
return nil, cobra.ShellCompDirectiveNoFileComp
},
}
)
// GetCommand returns the root cobra.Command for this application.
func GetCommand() *cobra.Command {
return baseCmd
}