create soft link with template

Add the the function softlink to the template rendering, so that
{{ softlink: "/bin/bash" }} for the file `/bin/run.ww` will create
a soft link to `/bin/bash`
It's also possible to "import" soft links from the host, e.g. the
template
{{ ImportLink "/etc/localtime" }}
set the timezone from the host

Signed-off-by: Christian Goll <cgoll@suse.com>
This commit is contained in:
Christian Goll
2024-07-12 15:05:04 +02:00
committed by Jonathon Anderson
parent b0d0e26b4a
commit 9ff5c60505
2 changed files with 20 additions and 3 deletions

View File

@@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"os" "os"
"path" "path"
"path/filepath"
"strings" "strings"
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config" warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
@@ -122,3 +123,12 @@ func createIgnitionJson(node *node.Node) string {
tmpYaml, _ := json.Marshal(&conf) tmpYaml, _ := json.Marshal(&conf)
return string(tmpYaml) return string(tmpYaml)
} }
func importSoftlink(lnk string) string {
path, err := filepath.EvalSymlinks(lnk)
if err != nil {
return "abort"
}
wwlog.Debug("importing softlink pointing to: %s", path)
return fmt.Sprintf("{{ /* softlink \"%s\" */ }}", path)
}

View File

@@ -238,12 +238,17 @@ func BuildOverlayIndir(nodeData node.Node, overlayNames []string, outputDir stri
// search for magic file name comment // search for magic file name comment
fileScanner := bufio.NewScanner(bytes.NewReader(buffer.Bytes())) fileScanner := bufio.NewScanner(bytes.NewReader(buffer.Bytes()))
fileScanner.Split(ScanLines) fileScanner.Split(ScanLines)
reg := regexp.MustCompile(`.*{{\s*/\*\s*file\s*["'](.*)["']\s*\*/\s*}}.*`) regFile := regexp.MustCompile(`.*{{\s*/\*\s*file\s*["'](.*)["']\s*\*/\s*}}.*`)
regLink := regexp.MustCompile(`.*{{\s*/\*\s*softlink\s*["'](.*)["']\s*\*/\s*}}.*`)
foundFileComment := false foundFileComment := false
for fileScanner.Scan() { for fileScanner.Scan() {
line := fileScanner.Text() line := fileScanner.Text()
filenameFromTemplate := reg.FindAllStringSubmatch(line, -1) filenameFromTemplate := regFile.FindAllStringSubmatch(line, -1)
if len(filenameFromTemplate) != 0 { softlinkFromTemplate := regLink.FindAllStringSubmatch(line, -1)
if len(softlinkFromTemplate) != 0 {
wwlog.Debug("Creating soft link %s -> %s", destFileName, softlinkFromTemplate[0][1])
return os.Symlink(softlinkFromTemplate[0][1], path.Join(outputDir, destFileName))
} else if len(filenameFromTemplate) != 0 {
wwlog.Debug("Found multiple comment, new filename %s", filenameFromTemplate[0][1]) wwlog.Debug("Found multiple comment, new filename %s", filenameFromTemplate[0][1])
if foundFileComment { if foundFileComment {
err = CarefulWriteBuffer(path.Join(outputDir, destFileName), err = CarefulWriteBuffer(path.Join(outputDir, destFileName),
@@ -371,10 +376,12 @@ func RenderTemplateFile(fileName string, data TemplateStruct) (
"Include": templateFileInclude, "Include": templateFileInclude,
"IncludeFrom": templateContainerFileInclude, "IncludeFrom": templateContainerFileInclude,
"IncludeBlock": templateFileBlock, "IncludeBlock": templateFileBlock,
"ImportLink": importSoftlink,
"basename": path.Base, "basename": path.Base,
"inc": func(i int) int { return i + 1 }, "inc": func(i int) int { return i + 1 },
"dec": func(i int) int { return i - 1 }, "dec": func(i int) int { return i - 1 },
"file": func(str string) string { return fmt.Sprintf("{{ /* file \"%s\" */ }}", str) }, "file": func(str string) string { return fmt.Sprintf("{{ /* file \"%s\" */ }}", str) },
"softlink": func(str string) string { return fmt.Sprintf("{{ /* softlink \"%s\" */ }}", str) },
"IgnitionJson": func() string { "IgnitionJson": func() string {
str := createIgnitionJson(data.ThisNode) str := createIgnitionJson(data.ThisNode)
if str != "" { if str != "" {