show used Tags for overlays
This commit is contained in:
committed by
Jonathon Anderson
parent
649c80af6d
commit
5d284b1c61
@@ -49,6 +49,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
### Added
|
||||
|
||||
- `wwctl overlay show -l` will now also list the used tags in a template
|
||||
- Initial support for EL10 using `dnsmasq` in place of `dhcpd-server`. #1974
|
||||
- `make rpm` for local development rpm builds. #1974
|
||||
- `wwclient --once` prompts wwclient to run once. #1226
|
||||
|
||||
@@ -3,6 +3,7 @@ package list
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@@ -33,7 +34,7 @@ func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) error {
|
||||
locationStr = "PATH"
|
||||
}
|
||||
if vars.ListLong {
|
||||
t.AddHeader("PERM MODE", "UID", "GID", "OVERLAY", "FILE PATH", locationStr)
|
||||
t.AddHeader("PERM MODE", "UID", "GID", "OVERLAY", "FILE PATH", locationStr, "VARS")
|
||||
} else {
|
||||
t.AddHeader("OVERLAY NAME", "FILES/DIRS", locationStr)
|
||||
}
|
||||
@@ -50,10 +51,14 @@ func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
wwlog.Debug("Iterating overlay rootfs: %s", overlay_.Rootfs())
|
||||
if vars.ListLong {
|
||||
for file := range files {
|
||||
s, err := os.Stat(overlay_.File(files[file]))
|
||||
for _, file := range files {
|
||||
templateVars := []string{}
|
||||
if !strings.HasSuffix(file, "/") {
|
||||
templateVars = overlay_.ParseVars(file)
|
||||
}
|
||||
s, err := os.Stat(overlay_.File(file))
|
||||
if err != nil {
|
||||
wwlog.Warn("%s: %s: %s", name, files[file], err)
|
||||
wwlog.Warn("%s: %s: %s", name, file, err)
|
||||
continue
|
||||
}
|
||||
fileMode := s.Mode()
|
||||
@@ -63,7 +68,7 @@ func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) error {
|
||||
if vars.ShowPath {
|
||||
locLine = overlay_.Path()
|
||||
}
|
||||
t.AddLine(perms, sys.(*syscall.Stat_t).Uid, sys.(*syscall.Stat_t).Gid, name, files[file], locLine)
|
||||
t.AddLine(perms, sys.(*syscall.Stat_t).Uid, sys.(*syscall.Stat_t).Gid, name, file, locLine, templateVars)
|
||||
}
|
||||
} else {
|
||||
locLine := strconv.FormatBool(overlay_.IsSiteOverlay())
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
"text/template/parse"
|
||||
|
||||
"github.com/Masterminds/sprig/v3"
|
||||
"github.com/coreos/go-systemd/v22/unit"
|
||||
@@ -272,6 +273,82 @@ func (overlay Overlay) Mkdir(path string, mode int32) (err error) {
|
||||
return os.MkdirAll(fullPath, os.FileMode(mode))
|
||||
}
|
||||
|
||||
// returns a list of the variable names for the given template
|
||||
func (overlay Overlay) ParseVars(file string) []string {
|
||||
if !strings.HasSuffix(file, ".ww") {
|
||||
return nil
|
||||
}
|
||||
fullPath := overlay.File(file)
|
||||
if !util.IsFile(fullPath) {
|
||||
wwlog.Error("Template file does not exist in overlay %s: %s", overlay.Name(), file)
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
writeFile bool
|
||||
backupFile bool
|
||||
)
|
||||
funcMap := getTemplateFuncMap(fullPath, TemplateStruct{}, &writeFile, &backupFile)
|
||||
tmpl, err := template.New(path.Base(fullPath)).Option("missingkey=default").Funcs(funcMap).ParseFiles(fullPath)
|
||||
if err != nil {
|
||||
wwlog.Error("Could not parse template file %s: %s", fullPath, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
vars := make(map[string]bool)
|
||||
if tmpl.Tree != nil && tmpl.Tree.Root != nil {
|
||||
walkParseTree(tmpl.Tree.Root, vars)
|
||||
}
|
||||
|
||||
result := make([]string, 0, len(vars))
|
||||
for v := range vars {
|
||||
if v != "" {
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// walkParseTree recursively traverses the template's parse tree to find variables.
|
||||
func walkParseTree(node parse.Node, vars map[string]bool) {
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch n := node.(type) {
|
||||
case *parse.ActionNode:
|
||||
walkParseTree(n.Pipe, vars)
|
||||
case *parse.IfNode:
|
||||
walkParseTree(n.Pipe, vars)
|
||||
walkParseTree(n.List, vars)
|
||||
walkParseTree(n.ElseList, vars)
|
||||
case *parse.ListNode:
|
||||
if n != nil {
|
||||
for _, child := range n.Nodes {
|
||||
walkParseTree(child, vars)
|
||||
}
|
||||
}
|
||||
case *parse.RangeNode:
|
||||
walkParseTree(n.Pipe, vars)
|
||||
walkParseTree(n.List, vars)
|
||||
case *parse.WithNode:
|
||||
walkParseTree(n.Pipe, vars)
|
||||
walkParseTree(n.List, vars)
|
||||
case *parse.PipeNode:
|
||||
if n != nil {
|
||||
for _, cmd := range n.Cmds {
|
||||
for _, arg := range cmd.Args {
|
||||
walkParseTree(arg, vars)
|
||||
}
|
||||
}
|
||||
}
|
||||
case *parse.VariableNode, *parse.FieldNode:
|
||||
if strings.Contains(n.String(), "Tags") {
|
||||
vars[n.String()] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BuildAllOverlays(nodes []node.Node, allNodes []node.Node, workerCount int) error {
|
||||
nodeChan := make(chan node.Node, len(nodes))
|
||||
errChan := make(chan error, len(nodes)*2)
|
||||
@@ -668,19 +745,9 @@ func CarefulWriteBuffer(destFile string, buffer bytes.Buffer, backupFile bool, p
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
Parses the template with the given filename, variables must be in data. Returns the
|
||||
parsed template as bytes.Buffer, and the bool variables for backupFile and writeFile.
|
||||
If something goes wrong an error is returned.
|
||||
*/
|
||||
func RenderTemplateFile(fileName string, data TemplateStruct) (
|
||||
buffer bytes.Buffer,
|
||||
backupFile bool,
|
||||
writeFile bool,
|
||||
err error,
|
||||
) {
|
||||
backupFile = true
|
||||
writeFile = true
|
||||
// getTemplateFuncMap returns a template.FuncMap with all the functions
|
||||
// for warewulf templates.
|
||||
func getTemplateFuncMap(fileName string, data TemplateStruct, writeFile *bool, backupFile *bool) template.FuncMap {
|
||||
// Build our FuncMap
|
||||
funcMap := template.FuncMap{
|
||||
"Include": templateFileInclude,
|
||||
@@ -698,12 +765,12 @@ func RenderTemplateFile(fileName string, data TemplateStruct) (
|
||||
},
|
||||
"abort": func() string {
|
||||
wwlog.Debug("abort file called in %s", fileName)
|
||||
writeFile = false
|
||||
*writeFile = false
|
||||
return ""
|
||||
},
|
||||
"nobackup": func() string {
|
||||
wwlog.Debug("not backup for %s", fileName)
|
||||
backupFile = false
|
||||
*backupFile = false
|
||||
return ""
|
||||
},
|
||||
"UniqueField": UniqueField,
|
||||
@@ -715,6 +782,24 @@ func RenderTemplateFile(fileName string, data TemplateStruct) (
|
||||
for key, value := range sprig.TxtFuncMap() {
|
||||
funcMap[key] = value
|
||||
}
|
||||
return funcMap
|
||||
}
|
||||
|
||||
/*
|
||||
Parses the template with the given filename, variables must be in data. Returns the
|
||||
parsed template as bytes.Buffer, and the bool variables for backupFile and writeFile.
|
||||
If something goes wrong an error is returned.
|
||||
*/
|
||||
func RenderTemplateFile(fileName string, data TemplateStruct) (
|
||||
buffer bytes.Buffer,
|
||||
backupFile bool,
|
||||
writeFile bool,
|
||||
err error,
|
||||
) {
|
||||
backupFile = true
|
||||
writeFile = true
|
||||
|
||||
funcMap := getTemplateFuncMap(fileName, data, &writeFile, &backupFile)
|
||||
|
||||
// Create the template with the merged FuncMap
|
||||
tmpl, err := template.New(path.Base(fileName)).Option("missingkey=default").Funcs(funcMap).ParseGlob(fileName)
|
||||
|
||||
Reference in New Issue
Block a user