First pass at a rework of the overlay subsystem in Warewulf

This commit is contained in:
Gregory Kurtzer
2021-12-29 16:11:25 -08:00
parent 02a5de3873
commit 00d8d42e9d
62 changed files with 405 additions and 628 deletions

View File

@@ -29,10 +29,7 @@ export GOPROXY
# built tags needed for wwbuild binary # built tags needed for wwbuild binary
WW_BUILD_GO_BUILD_TAGS := containers_image_openpgp containers_image_ostree WW_BUILD_GO_BUILD_TAGS := containers_image_openpgp containers_image_ostree
# system-overlay directories for install_wwclient # all build targets
OVERLAY_DIR ?= $(DESTDIR)/var/warewulf/overlays/system/
overlays = ${dir ${wildcard ${OVERLAY_DIR}*/}}
all: vendor wwctl wwclient bash_completion.d man_pages all: vendor wwctl wwclient bash_completion.d man_pages
build: lint test-it vet all build: lint test-it vet all
@@ -128,7 +125,7 @@ wwclient:
cd cmd/wwclient; CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -ldflags '-extldflags -static' -o ../../wwclient cd cmd/wwclient; CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -ldflags '-extldflags -static' -o ../../wwclient
install_wwclient: wwclient install_wwclient: wwclient
$(foreach overlay, ${overlays}, install -D -m 0755 wwclient ${overlay}warewulf/bin/wwclient;) install -m 0755 wwclient $(DESSTDIR)/var/warewulf/overlays/wwinit/bin/wwclient
bash_completion: bash_completion:
cd cmd/bash_completion && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=$(CONFIG)/etc/warewulf.conf'\ cd cmd/bash_completion && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=$(CONFIG)/etc/warewulf.conf'\

View File

@@ -11,12 +11,13 @@ echo
set base http://{{.Ipaddr}}:{{.Port}} set base http://{{.Ipaddr}}:{{.Port}}
kernel --name kernel ${base}/kernel/{{.Hwaddr}} || goto reboot kernel --name kernel ${base}/kernel/{{.Hwaddr}} || goto reboot
initrd --name container ${base}/container/{{.Hwaddr}} || goto reboot initrd --name container ${base}/container/{{.Hwaddr}} || goto reboot
initrd --name kmods ${base}/kmods/{{.Hwaddr}} || goto reboot initrd --name kmods ${base}/kmods/{{.Hwaddr}} || goto reboot
initrd --name system ${base}/overlay-system/{{.Hwaddr}} || goto reboot initrd --name system ${base}/overlay-system/{{.Hwaddr}} || goto reboot
initrd --name runtime ${base}/overlay-runtime/{{.Hwaddr}} || goto reboot
boot kernel initrd=container initrd=kmods initrd=system {{.KernelArgs}} || goto reboot boot kernel initrd=container initrd=kmods initrd=system initrd=runtime {{.KernelArgs}} || goto reboot
:reboot :reboot
echo echo

View File

@@ -2,7 +2,7 @@ ipaddr: 192.168.200.1
netmask: 255.255.255.0 netmask: 255.255.255.0
warewulf: warewulf:
port: 9873 port: 9873
secure: true secure: false
autobuild overlays: true autobuild overlays: true
update interval: 60 update interval: 60
syslog: false syslog: false

View File

@@ -3,7 +3,9 @@ package nfs
import ( import (
"fmt" "fmt"
"os" "os"
"path"
"github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/warewulfconf" "github.com/hpcng/warewulf/internal/pkg/warewulfconf"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/wwlog"
@@ -33,7 +35,7 @@ func Configure(show bool) error {
} }
if !SetShow { if !SetShow {
fstab, err := os.OpenFile("/var/warewulf/overlays/system/default/etc/fstab", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) fstab, err := os.OpenFile(path.Join(overlay.OverlaySourceDir("wwinit"), "etc/fstab"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil { if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err) wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1) os.Exit(1)

View File

@@ -43,8 +43,8 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Container", node.ContainerName.Source(), node.ContainerName.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Container", node.ContainerName.Source(), node.ContainerName.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Kernel", node.KernelVersion.Source(), node.KernelVersion.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Kernel", node.KernelVersion.Source(), node.KernelVersion.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "KernelArgs", node.KernelArgs.Source(), node.KernelArgs.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "KernelArgs", node.KernelArgs.Source(), node.KernelArgs.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "RuntimeOverlay", node.RuntimeOverlay.Source(), node.RuntimeOverlay.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "SystemOverlay", node.SystemOverlay.Source(), node.SystemOverlay.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "SystemOverlay", node.SystemOverlay.Source(), node.SystemOverlay.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "RuntimeOverlay", node.RuntimeOverlay.Source(), node.RuntimeOverlay.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Ipxe", node.Ipxe.Source(), node.Ipxe.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Ipxe", node.Ipxe.Source(), node.Ipxe.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Init", node.Init.Source(), node.Init.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Init", node.Init.Source(), node.Init.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Root", node.Root.Source(), node.Root.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Root", node.Root.Source(), node.Root.Print())

View File

@@ -15,10 +15,9 @@ var (
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Use: "set [OPTIONS] PATTERN [PATTERN ...]", Use: "set [OPTIONS] PATTERN [PATTERN ...]",
Short: "Configure node properties", Short: "Configure node properties",
Long: "This command sets configuration properties for nodes matching PATTERN.\n\n" + Long: "This command sets configuration properties for nodes matching PATTERN.\n\nNote: use the string 'UNSET' to remove a configuration",
"Note: use the string 'UNSET' to remove a configuration", Args: cobra.MinimumNArgs(1),
Args: cobra.MinimumNArgs(1), RunE: CobraRunE,
RunE: CobraRunE,
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 { if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
@@ -48,6 +47,7 @@ var (
SetNetDevDel bool SetNetDevDel bool
SetClusterName string SetClusterName string
SetIpxe string SetIpxe string
SetInitOverlay string
SetRuntimeOverlay string SetRuntimeOverlay string
SetSystemOverlay string SetSystemOverlay string
SetIpmiIpaddr string SetIpmiIpaddr string
@@ -93,16 +93,17 @@ func init() {
baseCmd.PersistentFlags().StringVar(&SetIpxe, "ipxe", "", "Set the node's iPXE template name") baseCmd.PersistentFlags().StringVar(&SetIpxe, "ipxe", "", "Set the node's iPXE template name")
baseCmd.PersistentFlags().StringVarP(&SetInit, "init", "i", "", "Define the init process to boot the container") baseCmd.PersistentFlags().StringVarP(&SetInit, "init", "i", "", "Define the init process to boot the container")
baseCmd.PersistentFlags().StringVar(&SetRoot, "root", "", "Define the rootfs") baseCmd.PersistentFlags().StringVar(&SetRoot, "root", "", "Define the rootfs")
baseCmd.PersistentFlags().StringVarP(&SetInitOverlay, "wwinit", "O", "", "Set the node's initialization overlay")
baseCmd.PersistentFlags().StringVarP(&SetRuntimeOverlay, "runtime", "R", "", "Set the node's runtime overlay") baseCmd.PersistentFlags().StringVarP(&SetRuntimeOverlay, "runtime", "R", "", "Set the node's runtime overlay")
if err := baseCmd.RegisterFlagCompletionFunc("runtime", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if err := baseCmd.RegisterFlagCompletionFunc("runtime", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := overlay.FindRuntimeOverlays() list, _ := overlay.FindOverlays()
return list, cobra.ShellCompDirectiveNoFileComp return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil { }); err != nil {
log.Println(err) log.Println(err)
} }
baseCmd.PersistentFlags().StringVarP(&SetSystemOverlay, "system", "S", "", "Set the node's system overlay") baseCmd.PersistentFlags().StringVarP(&SetSystemOverlay, "system", "S", "", "Set the node's system overlay")
if err := baseCmd.RegisterFlagCompletionFunc("system", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if err := baseCmd.RegisterFlagCompletionFunc("system", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := overlay.FindSystemOverlays() list, _ := overlay.FindOverlays()
return list, cobra.ShellCompDirectiveNoFileComp return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil { }); err != nil {
log.Println(err) log.Println(err)
@@ -136,7 +137,7 @@ func init() {
baseCmd.PersistentFlags().StringVarP(&SetGateway, "gateway", "G", "", "Set the node's network device gateway") baseCmd.PersistentFlags().StringVarP(&SetGateway, "gateway", "G", "", "Set the node's network device gateway")
baseCmd.PersistentFlags().StringVarP(&SetHwaddr, "hwaddr", "H", "", "Set the node's network device HW address") baseCmd.PersistentFlags().StringVarP(&SetHwaddr, "hwaddr", "H", "", "Set the node's network device HW address")
baseCmd.PersistentFlags().StringVarP(&SetType, "type", "T", "", "Set the node's network device type") baseCmd.PersistentFlags().StringVarP(&SetType, "type", "T", "", "Set the node's network device type")
baseCmd.PersistentFlags().StringVar(&SetNetOnBoot, "onboot", "yes", "Enable/disable device (yes/no)") baseCmd.PersistentFlags().StringVar(&SetNetOnBoot, "onboot", "", "Enable/disable device (yes/no)")
baseCmd.PersistentFlags().BoolVar(&SetNetDevDel, "netdel", false, "Delete the node's network device") baseCmd.PersistentFlags().BoolVar(&SetNetDevDel, "netdel", false, "Delete the node's network device")

View File

@@ -6,71 +6,33 @@ import (
"github.com/hpcng/warewulf/internal/pkg/node" "github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/overlay" "github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors" "github.com/hpcng/warewulf/pkg/hostlist"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func CobraRunE(cmd *cobra.Command, args []string) error { func CobraRunE(cmd *cobra.Command, args []string) error {
var updateNodes []node.NodeInfo
var overlayKind string
var overlayName string
if len(args) == 2 { nodeDB, err := node.New()
overlayKind = args[0]
overlayName = args[1]
} else if len(args) == 1 {
overlayKind = args[0]
}
if (overlayKind != "system" && overlayKind != "runtime") && !BuildAll {
return errors.New("overlay kind must be of type 'system' or 'runtime'")
}
n, err := node.New()
if err != nil { if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err) wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
os.Exit(1) os.Exit(1)
} }
if overlayName != "" { nodes, err := nodeDB.FindAllNodes()
nodes, err := n.FindAllNodes() if err != nil {
if err != nil { wwlog.Printf(wwlog.ERROR, "Could not get node list: %s\n", err)
wwlog.Printf(wwlog.ERROR, "Could not get node list: %s\n", err) os.Exit(1)
os.Exit(1) }
}
for _, node := range nodes { if len(args) > 0 {
if overlayKind == "system" && node.SystemOverlay.Get() == overlayName { args = hostlist.Expand(args)
updateNodes = append(updateNodes, node) err = overlay.BuildAllOverlays(node.FilterByName(nodes, args))
} else if overlayKind == "runtime" && node.RuntimeOverlay.Get() == overlayName {
updateNodes = append(updateNodes, node)
}
}
} else { } else {
var err error err = overlay.BuildAllOverlays(nodes)
updateNodes, err = n.FindAllNodes()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not get node list: %s\n", err)
os.Exit(1)
}
} }
wwlog.Printf(wwlog.DEBUG, "Checking on system overlay update\n") if err != nil {
if overlayKind == "system" || BuildAll { wwlog.Printf(wwlog.WARN, "Some system overlays failed to be generated: %s\n", err)
wwlog.Printf(wwlog.INFO, "Updating System Overlays...\n")
err := overlay.BuildSystemOverlay(updateNodes)
if err != nil {
wwlog.Printf(wwlog.WARN, "Some system overlays failed to be generated: %s\n", err)
}
}
wwlog.Printf(wwlog.DEBUG, "Checking on runtime overlay update\n")
if overlayKind == "runtime" || BuildAll {
wwlog.Printf(wwlog.INFO, "Updating Runtime Overlays...\n")
err := overlay.BuildRuntimeOverlay(updateNodes)
if err != nil {
wwlog.Printf(wwlog.WARN, "Some runtime overlays failed to be generated\n")
}
} }
return nil return nil

View File

@@ -5,17 +5,15 @@ import "github.com/spf13/cobra"
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Use: "build [OPTIONS] {system|runtime} OVERLAY_NAME", Use: "build [OPTIONS] NODENAME...",
Short: "(Re)build an overlay", Short: "(Re)build node overlays",
Long: "This command builds a new system or runtime overlay named OVERLAY_NAME.", Long: "This command builds overlays for given nodes.",
RunE: CobraRunE, RunE: CobraRunE,
Args: cobra.RangeArgs(0, 2),
} }
BuildAll bool
) )
func init() { func init() {
baseCmd.PersistentFlags().BoolVarP(&BuildAll, "all", "a", false, "Build all overlays (runtime and system)") //baseCmd.PersistentFlags().BoolVarP(&BuildAll, "all", "a", false, "Build overlays for all nodes")
} }
// GetRootCommand returns the root cobra.Command for the application. // GetRootCommand returns the root cobra.Command for the application.

View File

@@ -5,23 +5,17 @@ import (
"path" "path"
"strconv" "strconv"
"github.com/hpcng/warewulf/internal/pkg/config" "github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func CobraRunE(cmd *cobra.Command, args []string) error { func CobraRunE(cmd *cobra.Command, args []string) error {
var overlaySourceDir string var overlaySourceDir string
overlayKind := args[0] overlayName := args[0]
overlayName := args[1] fileName := args[1]
fileName := args[2]
if overlayKind != "system" && overlayKind != "runtime" {
return errors.New("overlay kind must be of type 'system' or 'runtime'")
}
permissionMode, err := strconv.ParseInt(args[3], 8, 32) permissionMode, err := strconv.ParseInt(args[3], 8, 32)
if err != nil { if err != nil {
@@ -29,11 +23,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
os.Exit(1) os.Exit(1)
} }
if overlayKind == "system" { overlaySourceDir = overlay.OverlaySourceDir(overlayName)
overlaySourceDir = config.SystemOverlaySource(overlayName)
} else if overlayKind == "runtime" {
overlaySourceDir = config.RuntimeOverlaySource(overlayName)
}
if !util.IsDir(overlaySourceDir) { if !util.IsDir(overlaySourceDir) {
wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s\n", overlayName) wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s\n", overlayName)

View File

@@ -7,15 +7,12 @@ import (
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Use: "chmod [OPTIONS] {runtime|system} OVERLAY_NAME FILENAME MODE", Use: "chmod [OPTIONS] OVERLAY_NAME FILENAME MODE",
Short: "Change file permissions in an overlay", Short: "Change file permissions in an overlay",
Long: `Changes the permissions of a single FILENAME within an overlay specified by Long: "Changes the permissions of a single FILENAME within an overlay.\nYou can use any MODE format supported by the chmod command.",
overlay type (system or runtime) and its OVERLAY_NAME. Example: "wwctl overlay chmod default /etc/hostname.ww 0660",
RunE: CobraRunE,
You can use any MODE format supported by the chmod command.`, Args: cobra.ExactArgs(3),
Example: "wwctl overlay chmod system default /etc/hostname.ww 0660",
RunE: CobraRunE,
Args: cobra.ExactArgs(4),
} }
) )

View File

@@ -5,11 +5,10 @@ import (
"path" "path"
"strconv" "strconv"
"github.com/hpcng/warewulf/internal/pkg/config" "github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@@ -19,13 +18,8 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
var gid int var gid int
var err error var err error
overlayKind := args[0] overlayName := args[0]
overlayName := args[1] fileName := args[1]
fileName := args[2]
if overlayKind != "system" && overlayKind != "runtime" {
return errors.New("overlay kind must be of type 'system' or 'runtime'")
}
uid, err = strconv.Atoi(args[3]) uid, err = strconv.Atoi(args[3])
if err != nil { if err != nil {
@@ -43,11 +37,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
gid = 0 gid = 0
} }
if overlayKind == "system" { overlaySourceDir = overlay.OverlaySourceDir(overlayName)
overlaySourceDir = config.SystemOverlaySource(overlayName)
} else if overlayKind == "runtime" {
overlaySourceDir = config.RuntimeOverlaySource(overlayName)
}
if !util.IsDir(overlaySourceDir) { if !util.IsDir(overlaySourceDir) {
wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s\n", overlayName) wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s\n", overlayName)

View File

@@ -4,12 +4,12 @@ import "github.com/spf13/cobra"
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
Use: "chown [OPTIONS] {system|runtime} OVERLAY_NAME FILE UID [GID]", DisableFlagsInUseLine: true,
Short: "Change file ownership within an overlay", Use: "chown [OPTIONS] OVERLAY_NAME FILE UID [GID]",
Long: "This command changes the ownership of a FILE within the system or runtime OVERLAY_NAME\n" + Short: "Change file ownership within an overlay",
"to the user specified by UID. Optionally, it will also change group ownership to GID.", Long: "This command changes the ownership of a FILE within the system or runtime OVERLAY_NAME\nto the user specified by UID. Optionally, it will also change group ownership to GID.",
RunE: CobraRunE, RunE: CobraRunE,
Args: cobra.RangeArgs(4, 5), Args: cobra.RangeArgs(3, 4),
} }
) )

View File

@@ -5,32 +5,15 @@ import (
"github.com/hpcng/warewulf/internal/pkg/overlay" "github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func CobraRunE(cmd *cobra.Command, args []string) error { func CobraRunE(cmd *cobra.Command, args []string) error {
overlayKind := args[0] err := overlay.OverlayInit(args[0])
overlayName := args[1] if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
if overlayKind != "system" && overlayKind != "runtime" { os.Exit(1)
return errors.New("overlay kind must be of type 'system' or 'runtime'")
}
if overlayKind == "system" {
err := overlay.SystemOverlayInit(overlayName)
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1)
}
wwlog.Printf(wwlog.INFO, "Created new system overlay: %s\n", overlayName)
} else {
err := overlay.RuntimeOverlayInit(overlayName)
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1)
}
} }
return nil return nil

View File

@@ -7,11 +7,11 @@ import (
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Use: "create [OPTIONS] {system|runtime} OVERLAY_NAME", Use: "create [OPTIONS] OVERLAY_NAME",
Short: "Initialize a new Overlay", Short: "Initialize a new Overlay",
Long: "This command creates a new empty system or runtime overlay named OVERLAY_NAME.", Long: "This command creates a new empty overlay with the given OVERLAY_NAME.",
RunE: CobraRunE, RunE: CobraRunE,
Args: cobra.ExactArgs(2), Args: cobra.ExactArgs(2),
} }
) )

View File

@@ -5,8 +5,7 @@ import (
"os" "os"
"path" "path"
"github.com/hpcng/warewulf/internal/pkg/config" "github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors" "github.com/pkg/errors"
@@ -17,22 +16,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
var overlayPath string var overlayPath string
var fileName string var fileName string
overlayKind := args[0] overlayName := args[0]
overlayName := args[1]
if len(args) == 3 { if len(args) == 2 {
fileName = args[2] fileName = args[1]
} }
if overlayKind != "system" && overlayKind != "runtime" { overlayPath = overlay.OverlaySourceDir(overlayName)
return errors.New("overlay kind must be of type 'system' or 'runtime'")
}
if overlayKind == "system" {
overlayPath = config.SystemOverlaySource(overlayName)
} else if overlayKind == "runtime" {
overlayPath = config.RuntimeOverlaySource(overlayName)
}
if overlayPath == "" { if overlayPath == "" {
wwlog.Printf(wwlog.ERROR, "Overlay name did not resolve: '%s'\n", overlayName) wwlog.Printf(wwlog.ERROR, "Overlay name did not resolve: '%s'\n", overlayName)
@@ -40,13 +30,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
} }
if !util.IsDir(overlayPath) { if !util.IsDir(overlayPath) {
wwlog.Printf(wwlog.ERROR, "Overlay does not exist: '%s:%s'\n", overlayKind, overlayName) wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s\n", overlayName)
os.Exit(1) os.Exit(1)
} }
if fileName == "" { if fileName == "" {
if overlayName == "default" { if overlayName == "wwinit" {
return errors.New("refusing to delete the default overlay") return errors.New("refusing to delete the Warewulf overlay")
} }
if Force { if Force {
err := os.RemoveAll(overlayPath) err := os.RemoveAll(overlayPath)
@@ -61,31 +51,6 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
} }
fmt.Printf("Deleted overlay: %s\n", args[0]) fmt.Printf("Deleted overlay: %s\n", args[0])
n, err := node.New()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
os.Exit(1)
}
nodes, err := n.FindAllNodes()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not get node list: %s\n", err)
os.Exit(1)
}
for _, node := range nodes {
if overlayKind == "system" && node.SystemOverlay.Get() == overlayName {
node.SystemOverlay.Set("default")
} else if overlayKind == "runtime" && node.RuntimeOverlay.Get() == overlayName {
node.RuntimeOverlay.Set("default")
}
}
err = n.Persist()
if err != nil {
return errors.Wrap(err, "failed to persist node updates")
}
} else { } else {
removePath := path.Join(overlayPath, fileName) removePath := path.Join(overlayPath, fileName)
@@ -97,14 +62,14 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
if Force { if Force {
err := os.RemoveAll(removePath) err := os.RemoveAll(removePath)
if err != nil { if err != nil {
wwlog.Printf(wwlog.ERROR, "Failed deleting file from overlay: %s:%s:%s\n", overlayKind, overlayName, overlayPath) wwlog.Printf(wwlog.ERROR, "Failed deleting file from overlay: %s:%s\n", overlayName, overlayPath)
wwlog.Printf(wwlog.ERROR, "%s\n", err) wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1) os.Exit(1)
} }
} else { } else {
err := os.Remove(removePath) err := os.Remove(removePath)
if err != nil { if err != nil {
wwlog.Printf(wwlog.ERROR, "Failed deleting overlay: %s:%s:%s\n", overlayKind, overlayName, overlayPath) wwlog.Printf(wwlog.ERROR, "Failed deleting overlay: %s:%s\n", overlayName, overlayPath)
wwlog.Printf(wwlog.ERROR, "%s\n", err) wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1) os.Exit(1)
} }

View File

@@ -7,13 +7,12 @@ import (
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Use: "delete [OPTIONS] {runtime|system} OVERLAY_NAME [FILE [FILE ...]]", Use: "delete [OPTIONS] OVERLAY_NAME [FILE [FILE ...]]",
Short: "Delete Warewulf Overlay or files", Short: "Delete Warewulf Overlay or files",
Long: "This command will delete FILEs within OVERLAY_NAME or the entire OVERLAY_NAME if no\n" + Long: "This command will delete FILEs within OVERLAY_NAME or the entire OVERLAY_NAME if no\nfiles are listed. Use with caution!",
"files are listed. Use with caution!", RunE: CobraRunE,
RunE: CobraRunE, Args: cobra.RangeArgs(1, 2),
Args: cobra.RangeArgs(2, 3), Aliases: []string{"rm", "del"},
Aliases: []string{"rm", "del"},
} }
Force bool Force bool
Parents bool Parents bool

View File

@@ -6,10 +6,9 @@ import (
"path" "path"
"path/filepath" "path/filepath"
"github.com/hpcng/warewulf/internal/pkg/config" "github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@@ -17,26 +16,17 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
editor := os.Getenv("EDITOR") editor := os.Getenv("EDITOR")
var overlaySourceDir string var overlaySourceDir string
overlayKind := args[0] overlayName := args[0]
overlayName := args[1] fileName := args[1]
fileName := args[2]
if overlayKind != "system" && overlayKind != "runtime" {
return errors.New("overlay kind must be of type 'system' or 'runtime'")
}
if editor == "" { if editor == "" {
editor = "/bin/vi" editor = "/bin/vi"
} }
if overlayKind == "system" { overlaySourceDir = overlay.OverlaySourceDir(overlayName)
overlaySourceDir = config.SystemOverlaySource(overlayName)
} else if overlayKind == "runtime" {
overlaySourceDir = config.RuntimeOverlaySource(overlayName)
}
if !util.IsDir(overlaySourceDir) { if !util.IsDir(overlaySourceDir) {
wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s:%s\n", overlayKind, overlayName) wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s\n", overlayName)
os.Exit(1) os.Exit(1)
} }
@@ -59,7 +49,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
} }
if !util.IsFile(overlayFile) && filepath.Ext(overlayFile) == ".ww" { if !util.IsFile(overlayFile) && filepath.Ext(overlayFile) == ".ww" {
wwlog.Printf(wwlog.WARN, "This is a new file, creating some default content\n") wwlog.Printf(wwlog.VERBOSE, "This is a new file, creating some default content\n")
w, err := os.OpenFile(overlayFile, os.O_RDWR|os.O_CREATE, os.FileMode(PermMode)) w, err := os.OpenFile(overlayFile, os.O_RDWR|os.O_CREATE, os.FileMode(PermMode))
if err != nil { if err != nil {

View File

@@ -7,13 +7,11 @@ import (
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Use: "edit [OPTIONS] {system|runtime} OVERLAY_NAME FILE", Use: "edit [OPTIONS] OVERLAY_NAME FILE",
Short: "Edit or create a file within a Warewulf Overlay", Short: "Edit or create a file within a Warewulf Overlay",
Long: "This command will open the FILE for editing or create a new file within the\n" + Long: "This command will open the FILE for editing or create a new file within the\nOVERLAY_NAME. Note: files created with a '.ww' suffix will always be\nparsed as Warewulf template files, and the suffix will be removed automatically.",
"OVERLAY_NAME. Note: files created with a '.ww' suffix will always be\n" + RunE: CobraRunE,
"parsed as Warewulf template files, and the suffix will be removed automatically.", Args: cobra.ExactArgs(2),
RunE: CobraRunE,
Args: cobra.ExactArgs(3),
} }
ListFiles bool ListFiles bool
CreateDirs bool CreateDirs bool

View File

@@ -4,7 +4,6 @@ import (
"os" "os"
"path" "path"
"github.com/hpcng/warewulf/internal/pkg/config"
"github.com/hpcng/warewulf/internal/pkg/node" "github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/overlay" "github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/util"
@@ -17,30 +16,20 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
var dest string var dest string
var overlaySource string var overlaySource string
overlayKind := args[0] overlayName := args[0]
overlayName := args[1] source := args[1]
source := args[2]
if overlayKind != "system" && overlayKind != "runtime" { if len(args) == 3 {
return errors.New("overlay kind must be of type 'system' or 'runtime'") dest = args[2]
}
if len(args) == 4 {
dest = args[3]
} else { } else {
dest = source dest = source
} }
if overlayKind == "system" { wwlog.Printf(wwlog.VERBOSE, "Copying '%s' into overlay '%s:%s'\n", source, overlayName, dest)
wwlog.Printf(wwlog.VERBOSE, "Copying '%s' into system overlay '%s:%s'\n", source, overlayName, dest) overlaySource = overlay.OverlaySourceDir(overlayName)
overlaySource = config.SystemOverlaySource(overlayName)
} else if overlayKind == "runtime" {
wwlog.Printf(wwlog.VERBOSE, "Copying '%s' into runtime overlay '%s:%s'\n", source, overlayName, dest)
overlaySource = config.RuntimeOverlaySource(overlayName)
}
if !util.IsDir(overlaySource) { if !util.IsDir(overlaySource) {
wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s:%s\n", overlayKind, overlayName) wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s\n", overlayName)
os.Exit(1) os.Exit(1)
} }
@@ -49,7 +38,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
} }
if util.IsFile(path.Join(overlaySource, dest)) { if util.IsFile(path.Join(overlaySource, dest)) {
wwlog.Printf(wwlog.ERROR, "A file with that name already exists in the %s overlay %s\n:", overlayKind, overlayName) wwlog.Printf(wwlog.ERROR, "A file with that name already exists in the overlay %s\n:", overlayName)
os.Exit(1) os.Exit(1)
} }
@@ -74,21 +63,14 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
var updateNodes []node.NodeInfo var updateNodes []node.NodeInfo
for _, node := range nodes { for _, node := range nodes {
if overlayKind == "system" && node.SystemOverlay.Get() == overlayName { if node.SystemOverlay.Get() == overlayName {
updateNodes = append(updateNodes, node) updateNodes = append(updateNodes, node)
} else if overlayKind == "runtime" && node.RuntimeOverlay.Get() == overlayName { } else if node.RuntimeOverlay.Get() == overlayName {
updateNodes = append(updateNodes, node) updateNodes = append(updateNodes, node)
} }
} }
if overlayKind == "system" { return overlay.BuildSpecificOverlays(updateNodes, overlayName)
wwlog.Printf(wwlog.INFO, "Updating System Overlays...\n")
return overlay.BuildSystemOverlay(updateNodes)
} else if overlayKind == "runtime" {
wwlog.Printf(wwlog.INFO, "Updating Runtime Overlays...\n")
return overlay.BuildRuntimeOverlay(updateNodes)
}
} }
return nil return nil

View File

@@ -5,13 +5,12 @@ import "github.com/spf13/cobra"
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Use: "import [OPTIONS] {system|runtime} OVERLAY_NAME FILE [NEW_NAME]", Use: "import [OPTIONS] OVERLAY_NAME FILE [NEW_NAME]",
Short: "Import a file into a Warewulf Overlay", Short: "Import a file into a Warewulf Overlay",
Long: "This command imports the FILE into the Warewulf OVERLAY_NAME.\n" + Long: "This command imports the FILE into the Warewulf OVERLAY_NAME.\nOptionally, the file can be renamed to NEW_NAME",
"Optionally, the file can be renamed to NEW_NAME", RunE: CobraRunE,
RunE: CobraRunE, Args: cobra.RangeArgs(2, 3),
Args: cobra.RangeArgs(3, 4), Aliases: []string{"cp"},
Aliases: []string{"cp"},
} }
PermMode int32 PermMode int32
NoOverlayUpdate bool NoOverlayUpdate bool

View File

@@ -5,8 +5,6 @@ import (
"os" "os"
"syscall" "syscall"
"github.com/hpcng/warewulf/internal/pkg/config"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/overlay" "github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/wwlog"
@@ -15,79 +13,27 @@ import (
) )
func CobraRunE(cmd *cobra.Command, args []string) error { func CobraRunE(cmd *cobra.Command, args []string) error {
set := make(map[string]int) var overlays []string
var o []string
var err error
var nodeList []node.NodeInfo
var overlayName string
overlayKind := args[0] if len(args) > 0 {
overlays = args
if len(args) > 1 { } else {
overlayName = args[1] var err error
} overlays, err = overlay.FindOverlays()
if err != nil {
if overlayKind != "system" && overlayKind != "runtime" { return errors.Wrap(err, "could not obtain list of overlays from system")
return errors.New("overlay kind must be of type 'system' or 'runtime'")
}
n, err := node.New()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
os.Exit(1)
}
if overlayKind == "system" {
if !ListLong {
fmt.Printf("%-30s %-12s %-12s\n", "SYSTEM OVERLAY NAME", "NODES", "FILES/DIRS")
} else {
fmt.Printf("%-10s %5s %-5s %-18s %s\n", "PERM MODE", "UID", "GID", "SYSTEM-OVERLAY", "FILE PATH")
}
o, err = overlay.FindSystemOverlays()
} else if overlayKind == "runtime" {
if !ListLong {
fmt.Printf("%-30s %-12s %-12s\n", "RUNTIME OVERLAY NAME", "NODES", "FILES/DIRS")
} else {
fmt.Printf("%-10s %5s %-5s %-18s %s\n", "PERM MODE", "UID", "GID", "RUNTIME-OVERLAY", "FILE PATH")
}
o, err = overlay.FindRuntimeOverlays()
}
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not get system overlays: %s\n", err)
return err
}
nodeList, err = n.FindAllNodes()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not get node configuration: %s\n", err)
return err
}
for _, node := range nodeList {
if overlayKind == "system" {
if node.SystemOverlay.Get() != "" {
set[node.SystemOverlay.Get()]++
}
} else if overlayKind == "runtime" {
if node.RuntimeOverlay.Get() != "" {
set[node.RuntimeOverlay.Get()]++
}
} }
} }
for overlay := range o { if ListLong {
var path string fmt.Printf("%-10s %5s %-5s %-18s %s\n", "PERM MODE", "UID", "GID", "SYSTEM-OVERLAY", "FILE PATH")
name := o[overlay] } else {
fmt.Printf("%-30s %-12s\n", "OVERLAY NAME", "FILES/DIRS")
}
if overlayName != "" && overlayName != name { for o := range overlays {
continue name := overlays[o]
} path := overlay.OverlaySourceDir(name)
if overlayKind == "system" {
path = config.SystemOverlaySource(o[overlay])
} else if overlayKind == "runtime" {
path = config.RuntimeOverlaySource(o[overlay])
}
if util.IsDir(path) { if util.IsDir(path) {
files := util.FindFiles(path) files := util.FindFiles(path)
@@ -96,11 +42,11 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
if ListContents { if ListContents {
var fileCount int var fileCount int
for file := range files { for file := range files {
fmt.Printf("%-30s %-12d /%-12s\n", name, set[name], files[file]) fmt.Printf("%-30s /%-12s\n", name, files[file])
fileCount++ fileCount++
} }
if fileCount == 0 { if fileCount == 0 {
fmt.Printf("%-30s %-12d %-12d\n", name, set[name], 0) fmt.Printf("%-30s %-12d\n", name, 0)
} }
} else if ListLong { } else if ListLong {
for file := range files { for file := range files {
@@ -114,15 +60,15 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
sys := s.Sys() sys := s.Sys()
fmt.Printf("%v %5d %-5d %-18s /%s\n", perms, sys.(*syscall.Stat_t).Uid, sys.(*syscall.Stat_t).Gid, o[overlay], files[file]) fmt.Printf("%v %5d %-5d %-18s /%s\n", perms, sys.(*syscall.Stat_t).Uid, sys.(*syscall.Stat_t).Gid, overlays[o], files[file])
} }
} else { } else {
fmt.Printf("%-30s %-12d %-12d\n", name, set[name], len(files)) fmt.Printf("%-30s %-12d\n", name, len(files))
} }
} else { } else {
wwlog.Printf(wwlog.ERROR, "system/%s (path not found:%s)\n", o[overlay], path) wwlog.Printf(wwlog.ERROR, "system/%s (path not found:%s)\n", overlays[o], path)
} }
} }

View File

@@ -7,14 +7,13 @@ import (
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Use: "list [OPTIONS] {system|runtime} [OVERLAY_NAME]", Use: "list [OPTIONS] OVERLAY_NAME",
Short: "List Warewulf Overlays and files", Short: "List Warewulf Overlays and files",
Long: "This command displays information about all Warewulf overlays or the specified\n" + Long: "This command displays information about all Warewulf overlays or the specified\nOVERLAY_NAME. It also supports listing overlay content information.",
"OVERLAY_NAME. It also supports listing overlay content information.", RunE: CobraRunE,
RunE: CobraRunE, Args: cobra.MinimumNArgs(0),
Args: cobra.MinimumNArgs(1), Aliases: []string{"ls"},
Aliases: []string{"ls"}, ValidArgs: []string{"system", "runtime"},
ValidArgs: []string{"system", "runtime"},
} }
ListContents bool ListContents bool
ListLong bool ListLong bool

View File

@@ -4,38 +4,28 @@ import (
"os" "os"
"path" "path"
"github.com/hpcng/warewulf/internal/pkg/config" "github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func CobraRunE(cmd *cobra.Command, args []string) error { func CobraRunE(cmd *cobra.Command, args []string) error {
var overlaySourceDir string var overlaySourceDir string
overlayKind := args[0] overlayName := args[0]
overlayName := args[1] dirName := args[1]
dirName := args[2]
if overlayKind != "system" && overlayKind != "runtime" { overlaySourceDir = overlay.OverlaySourceDir(overlayName)
return errors.New("overlay kind must be of type 'system' or 'runtime'")
}
if overlayKind == "system" {
overlaySourceDir = config.SystemOverlaySource(overlayName)
} else if overlayKind == "runtime" {
overlaySourceDir = config.RuntimeOverlaySource(overlayName)
}
if !util.IsDir(overlaySourceDir) { if !util.IsDir(overlaySourceDir) {
wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s:%s\n", overlayKind, overlayName) wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s\n", overlayName)
os.Exit(1) os.Exit(1)
} }
overlayDir := path.Join(overlaySourceDir, dirName) overlayDir := path.Join(overlaySourceDir, dirName)
wwlog.Printf(wwlog.DEBUG, "Will create directory in overlay: %s:%s:%s\n", overlayKind, overlayName, dirName) wwlog.Printf(wwlog.DEBUG, "Will create directory in overlay: %s:%s\n", overlayName, dirName)
err := os.MkdirAll(overlayDir, os.FileMode(PermMode)) err := os.MkdirAll(overlayDir, os.FileMode(PermMode))
if err != nil { if err != nil {

View File

@@ -7,11 +7,11 @@ import (
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Use: "mkdir [OPTIONS] {system|runtime} OVERLAY_NAME DIRECTORY", Use: "mkdir [OPTIONS] OVERLAY_NAME DIRECTORY",
Short: "Create a new directory within an Overlay", Short: "Create a new directory within an Overlay",
Long: "This command creates a new directory within the Warewulf OVERLAY_NAME.", Long: "This command creates a new directory within the Warewulf OVERLAY_NAME.",
RunE: CobraRunE, RunE: CobraRunE,
Args: cobra.MinimumNArgs(3), Args: cobra.MinimumNArgs(3),
} }
PermMode int32 PermMode int32
) )

View File

@@ -6,29 +6,19 @@ import (
"os" "os"
"path" "path"
"github.com/hpcng/warewulf/internal/pkg/config" "github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func CobraRunE(cmd *cobra.Command, args []string) error { func CobraRunE(cmd *cobra.Command, args []string) error {
var overlaySourceDir string var overlaySourceDir string
overlayKind := args[0] overlayName := args[0]
overlayName := args[1] fileName := args[1]
fileName := args[2]
if overlayKind != "system" && overlayKind != "runtime" { overlaySourceDir = overlay.OverlaySourceDir(overlayName)
return errors.New("overlay kind must be of type 'system' or 'runtime'")
}
if overlayKind == "system" {
overlaySourceDir = config.SystemOverlaySource(overlayName)
} else if overlayKind == "runtime" {
overlaySourceDir = config.RuntimeOverlaySource(overlayName)
}
if !util.IsDir(overlaySourceDir) { if !util.IsDir(overlaySourceDir) {
wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s\n", overlayName) wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s\n", overlayName)

View File

@@ -6,12 +6,13 @@ import (
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
Use: "show [OPTIONS] {system|runtime} OVERLAY_NAME FILE", DisableFlagsInUseLine: true,
Short: "Show (cat) a file within a Warewulf Overlay", Use: "show [OPTIONS] OVERLAY_NAME FILE",
Long: "This command displays the contents of FILE within OVERLAY_NAME.", Short: "Show (cat) a file within a Warewulf Overlay",
RunE: CobraRunE, Long: "This command displays the contents of FILE within OVERLAY_NAME.",
Aliases: []string{"cat"}, RunE: CobraRunE,
Args: cobra.ExactArgs(3), Aliases: []string{"cat"},
Args: cobra.ExactArgs(2),
} }
) )

View File

@@ -38,8 +38,8 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Init", profile.Init.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Init", profile.Init.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Root", profile.Root.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Root", profile.Root.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "RuntimeOverlay", profile.RuntimeOverlay.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "SystemOverlay", profile.SystemOverlay.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "SystemOverlay", profile.SystemOverlay.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "RuntimeOverlay", profile.RuntimeOverlay.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Ipxe", profile.Ipxe.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Ipxe", profile.Ipxe.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "IpmiNetmask", profile.IpmiNetmask.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "IpmiNetmask", profile.IpmiNetmask.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "IpmiPort", profile.IpmiPort.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "IpmiPort", profile.IpmiPort.Print())

View File

@@ -41,6 +41,7 @@ var (
SetKernelArgs string SetKernelArgs string
SetClusterName string SetClusterName string
SetIpxe string SetIpxe string
SetInitOverlay string
SetRuntimeOverlay string SetRuntimeOverlay string
SetSystemOverlay string SetSystemOverlay string
SetIpmiNetmask string SetIpmiNetmask string
@@ -91,7 +92,7 @@ func init() {
baseCmd.PersistentFlags().StringVarP(&SetRuntimeOverlay, "runtime", "R", "", "Set the node's runtime overlay") baseCmd.PersistentFlags().StringVarP(&SetRuntimeOverlay, "runtime", "R", "", "Set the node's runtime overlay")
if err := baseCmd.RegisterFlagCompletionFunc("runtime", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if err := baseCmd.RegisterFlagCompletionFunc("runtime", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := overlay.FindRuntimeOverlays() list, _ := overlay.FindOverlays()
return list, cobra.ShellCompDirectiveNoFileComp return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil { }); err != nil {
log.Println(err) log.Println(err)
@@ -99,7 +100,7 @@ func init() {
} }
baseCmd.PersistentFlags().StringVarP(&SetSystemOverlay, "system", "S", "", "Set the node's system overlay") baseCmd.PersistentFlags().StringVarP(&SetSystemOverlay, "system", "S", "", "Set the node's system overlay")
if err := baseCmd.RegisterFlagCompletionFunc("system", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if err := baseCmd.RegisterFlagCompletionFunc("system", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := overlay.FindSystemOverlays() list, _ := overlay.FindOverlays()
return list, cobra.ShellCompDirectiveNoFileComp return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil { }); err != nil {
log.Println(err) log.Println(err)
@@ -119,7 +120,7 @@ func init() {
baseCmd.PersistentFlags().StringVarP(&SetGateway, "gateway", "G", "", "Set the node's network device gateway") baseCmd.PersistentFlags().StringVarP(&SetGateway, "gateway", "G", "", "Set the node's network device gateway")
baseCmd.PersistentFlags().StringVarP(&SetHwaddr, "hwaddr", "H", "", "Set the node's network device HW address") baseCmd.PersistentFlags().StringVarP(&SetHwaddr, "hwaddr", "H", "", "Set the node's network device HW address")
baseCmd.PersistentFlags().StringVarP(&SetType, "type", "T", "", "Set the node's network device type") baseCmd.PersistentFlags().StringVarP(&SetType, "type", "T", "", "Set the node's network device type")
baseCmd.PersistentFlags().StringVar(&SetNetOnBoot, "onboot", "yes", "Enable/disable device (yes/no)") baseCmd.PersistentFlags().StringVar(&SetNetOnBoot, "onboot", "", "Enable/disable device (yes/no)")
baseCmd.PersistentFlags().BoolVar(&SetNetDevDel, "netdel", false, "Delete the node's network device") baseCmd.PersistentFlags().BoolVar(&SetNetDevDel, "netdel", false, "Delete the node's network device")

View File

@@ -42,8 +42,8 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
wwlog.Printf(wwlog.DEBUG, "In node loop: %s\n", nodename) wwlog.Printf(wwlog.DEBUG, "In node loop: %s\n", nodename)
n.NetDevs = make(map[string]*NetDevEntry) n.NetDevs = make(map[string]*NetDevEntry)
n.Keys = make(map[string]*Entry) n.Keys = make(map[string]*Entry)
n.SystemOverlay.SetDefault("default") n.SystemOverlay.SetDefault("wwinit")
n.RuntimeOverlay.SetDefault("default") n.RuntimeOverlay.SetDefault("generic")
n.Ipxe.SetDefault("default") n.Ipxe.SetDefault("default")
n.Init.SetDefault("/sbin/init") n.Init.SetDefault("/sbin/init")
n.Root.SetDefault("initramfs") n.Root.SetDefault("initramfs")
@@ -266,5 +266,5 @@ func (config *nodeYaml) FindDiscoverableNode() (NodeInfo, string, error) {
} }
} }
return ret, "", errors.New("No unconfigured nodes found") return ret, "", errors.New("no unconfigured nodes found")
} }

View File

@@ -6,6 +6,7 @@ import (
"strings" "strings"
"github.com/hpcng/warewulf/internal/pkg/container" "github.com/hpcng/warewulf/internal/pkg/container"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/wwlog"
) )
@@ -19,15 +20,15 @@ func templateFileInclude(path string) string {
} }
func templateContainerFileInclude(containername string, filepath string) string { func templateContainerFileInclude(containername string, filepath string) string {
wwlog.Printf(wwlog.DEBUG, "Including VNFS file into template: %s: %s\n", containername, filepath) wwlog.Printf(wwlog.VERBOSE, "Including file from Container into template: %s:%s\n", containername, filepath)
if containername == "" { if containername == "" {
wwlog.Printf(wwlog.WARN, "VNFS not set for template import request: %s: %s\n", containername, filepath) wwlog.Printf(wwlog.WARN, "Container is not defined for node: %s\n", filepath)
return "" return ""
} }
if !container.ValidSource(containername) { if !container.ValidSource(containername) {
wwlog.Printf(wwlog.WARN, "Template required VNFS does not exist: %s\n", containername) wwlog.Printf(wwlog.WARN, "Template requires file(s) from non-existant container: %s:%s\n", containername, filepath)
return "" return ""
} }
@@ -35,10 +36,15 @@ func templateContainerFileInclude(containername string, filepath string) string
wwlog.Printf(wwlog.DEBUG, "Including file from container: %s:%s\n", containerDir, filepath) wwlog.Printf(wwlog.DEBUG, "Including file from container: %s:%s\n", containerDir, filepath)
if !util.IsFile(path.Join(containerDir, filepath)) {
wwlog.Printf(wwlog.WARN, "Requested file from container does not exist: %s:%s\n", containername, filepath)
return ""
}
content, err := ioutil.ReadFile(path.Join(containerDir, filepath)) content, err := ioutil.ReadFile(path.Join(containerDir, filepath))
if err != nil { if err != nil {
wwlog.Printf(wwlog.ERROR, "Template include: %s\n", err) wwlog.Printf(wwlog.ERROR, "Template include failed: %s\n", err)
} }
return strings.TrimSuffix(string(content), "\n") return strings.TrimSuffix(string(content), "\n")
} }

View File

@@ -8,7 +8,6 @@ import (
"os/exec" "os/exec"
"path" "path"
"path/filepath" "path/filepath"
"regexp"
"strconv" "strconv"
"strings" "strings"
"text/template" "text/template"
@@ -39,14 +38,17 @@ type TemplateStruct struct {
AllNodes []node.NodeInfo AllNodes []node.NodeInfo
} }
/*
func BuildSystemOverlay(nodeList []node.NodeInfo) error { func BuildSystemOverlay(nodeList []node.NodeInfo) error {
return buildOverlay(nodeList, "system") return nil
} }
func BuildRuntimeOverlay(nodeList []node.NodeInfo) error { func BuildRuntimeOverlay(nodeList []node.NodeInfo) error {
return buildOverlay(nodeList, "runtime") return nil
} }
func FindSystemOverlays() ([]string, error) { func FindSystemOverlays() ([]string, error) {
return findAllOverlays("system") return findAllOverlays("system")
} }
@@ -54,33 +56,60 @@ func FindSystemOverlays() ([]string, error) {
func FindRuntimeOverlays() ([]string, error) { func FindRuntimeOverlays() ([]string, error) {
return findAllOverlays("runtime") return findAllOverlays("runtime")
} }
*/
func SystemOverlayInit(name string) error { func OverlaySourceTopDir() string {
return overlayInit(name, "system") return path.Join(config.LocalStateDir, "overlays/")
} }
func RuntimeOverlayInit(name string) error { func OverlaySourceDir(overlayName string) string {
return overlayInit(name, "runtime") return path.Join(OverlaySourceTopDir(), overlayName)
} }
func findAllOverlays(overlayType string) ([]string, error) { func OverlayImage(nodename string, overlayname string) string {
return fmt.Sprintf("%s/provision/overlays/%s/%s.img", config.LocalStateDir, nodename, overlayname)
}
func BuildAllOverlays(nodes []node.NodeInfo) error {
for _, n := range nodes {
var overlays []string
overlays = append(overlays, "wwinit")
overlays = append(overlays, n.RuntimeOverlay.Get())
for _, overlay := range overlays {
wwlog.Printf(wwlog.INFO, "Building overlay for %s: %s\n", n.Id.Get(), overlay)
err := BuildOverlay(n, overlay)
if err != nil {
return errors.Wrap(err, "could not build overlay "+n.Id.Get()+"/"+overlay+".img")
}
}
}
return nil
}
// TODO: Add an Overlay Delete for both sourcedir and image
func BuildSpecificOverlays(nodes []node.NodeInfo, overlayName string) error {
for _, n := range nodes {
wwlog.Printf(wwlog.INFO, "Building overlay for %s: %s\n", n.Id.Get(), overlayName)
err := BuildOverlay(n, overlayName)
if err != nil {
return errors.Wrap(err, "could not build overlay "+n.Id.Get()+"/"+overlayName+".img")
}
}
return nil
}
func FindOverlays() ([]string, error) {
var ret []string var ret []string
var files []os.FileInfo var files []os.FileInfo
var err error
if overlayType == "system" {
wwlog.Printf(wwlog.DEBUG, "Looking for system overlays...")
files, err = ioutil.ReadDir(config.SystemOverlayDir())
} else if overlayType == "runtime" {
wwlog.Printf(wwlog.DEBUG, "Looking for runtime overlays...")
files, err = ioutil.ReadDir(config.RuntimeOverlayDir())
} else {
wwlog.Printf(wwlog.ERROR, "overlayType requested is not supported: %s\n", overlayType)
os.Exit(1)
}
files, err := ioutil.ReadDir(OverlaySourceTopDir())
if err != nil { if err != nil {
return ret, err return ret, errors.Wrap(err, "could not get list of overlays")
} }
for _, file := range files { for _, file := range files {
@@ -93,22 +122,11 @@ func findAllOverlays(overlayType string) ([]string, error) {
return ret, nil return ret, nil
} }
func overlayInit(name string, overlayType string) error { func OverlayInit(overlayName string) error {
var path string path := OverlaySourceDir(overlayName)
if overlayType == "system" {
wwlog.Printf(wwlog.DEBUG, "Looking for system overlays...")
path = config.SystemOverlaySource(name)
} else if overlayType == "runtime" {
wwlog.Printf(wwlog.DEBUG, "Looking for runtime overlays...")
path = config.RuntimeOverlaySource(name)
} else {
wwlog.Printf(wwlog.ERROR, "overlayType requested is not supported: %s\n", overlayType)
os.Exit(1)
}
if util.IsDir(path) { if util.IsDir(path) {
return errors.New("Overlay already exists: " + name) return errors.New("Overlay already exists: " + overlayName)
} }
err := os.MkdirAll(path, 0755) err := os.MkdirAll(path, 0755)
@@ -116,208 +134,183 @@ func overlayInit(name string, overlayType string) error {
return err return err
} }
func buildOverlay(nodeList []node.NodeInfo, overlayType string) error { func BuildOverlay(nodeInfo node.NodeInfo, overlayName string) error {
nodeDB, _ := node.New() nodeDB, _ := node.New()
allNodes, _ := nodeDB.FindAllNodes() allNodes, _ := nodeDB.FindAllNodes()
var tstruct TemplateStruct
OverlaySourceDir := OverlaySourceDir(overlayName)
OverlayImage := OverlayImage(nodeInfo.Id.Get(), overlayName)
OverlayImageDir := path.Dir(OverlayImage)
for _, n := range nodeList { if !util.ValidString(overlayName, "^[a-zA-Z0-9-._:]+$") {
var t TemplateStruct return errors.New("overlay name contains illegal characters: " + overlayName)
var OverlayDir string }
var OverlayFile string
if overlayType == "runtime" { wwlog.Printf(wwlog.DEBUG, "Checking to see if overlay directory exists: %s\n", OverlaySourceDir)
wwlog.Printf(wwlog.DEBUG, "Building runtime overlay for: %s\n", n.Id.Get()) if !util.IsDir(OverlaySourceDir) {
return errors.New("overlay does not exist: " + overlayName)
}
OverlayDir = config.RuntimeOverlaySource(n.RuntimeOverlay.Get()) err := os.MkdirAll(OverlayImageDir, 0755)
OverlayFile = config.RuntimeOverlayImage(n.Id.Get()) if err == nil {
} else if overlayType == "system" { wwlog.Printf(wwlog.DEBUG, "Created parent directory for Overlay Images: %s\n", OverlayImageDir)
wwlog.Printf(wwlog.DEBUG, "Building system overlay for: %s\n", n.Id.Get()) } else {
return errors.Wrap(err, "could not create overlay image directory")
}
OverlayDir = config.SystemOverlaySource(n.SystemOverlay.Get()) tmpDir, err := ioutil.TempDir(os.TempDir(), ".wwctl-overlay-")
OverlayFile = config.SystemOverlayImage(n.Id.Get()) if err == nil {
} else { wwlog.Printf(wwlog.DEBUG, "Creating temporary directory for overlay files: %s\n", tmpDir)
wwlog.Printf(wwlog.ERROR, "overlayType requested is not supported: %s\n", overlayType) } else {
os.Exit(1) return errors.Wrap(err, "could not create overlay temporary directory")
} }
wwlog.Printf(wwlog.DEBUG, "Processing overlay for node: %s\n", n.Id.Get()) wwlog.Printf(wwlog.VERBOSE, "Processing node/overlay: %s/%s\n", nodeInfo.Id.Get(), overlayName)
t.Id = n.Id.Get() tstruct.Id = nodeInfo.Id.Get()
t.Hostname = n.Id.Get() tstruct.Hostname = nodeInfo.Id.Get()
t.ClusterName = n.ClusterName.Get() tstruct.Id = nodeInfo.Id.Get()
t.Container = n.ContainerName.Get() tstruct.Hostname = nodeInfo.Id.Get()
t.Init = n.Init.Get() tstruct.ClusterName = nodeInfo.ClusterName.Get()
t.Root = n.Root.Get() tstruct.Container = nodeInfo.ContainerName.Get()
t.IpmiIpaddr = n.IpmiIpaddr.Get() tstruct.Init = nodeInfo.Init.Get()
t.IpmiNetmask = n.IpmiNetmask.Get() tstruct.Root = nodeInfo.Root.Get()
t.IpmiPort = n.IpmiPort.Get() tstruct.IpmiIpaddr = nodeInfo.IpmiIpaddr.Get()
t.IpmiGateway = n.IpmiGateway.Get() tstruct.IpmiNetmask = nodeInfo.IpmiNetmask.Get()
t.IpmiUserName = n.IpmiUserName.Get() tstruct.IpmiPort = nodeInfo.IpmiPort.Get()
t.IpmiPassword = n.IpmiPassword.Get() tstruct.IpmiGateway = nodeInfo.IpmiGateway.Get()
t.IpmiInterface = n.IpmiInterface.Get() tstruct.IpmiUserName = nodeInfo.IpmiUserName.Get()
t.NetDevs = make(map[string]*node.NetDevs) tstruct.IpmiPassword = nodeInfo.IpmiPassword.Get()
t.Keys = make(map[string]string) tstruct.IpmiInterface = nodeInfo.IpmiInterface.Get()
for devname, netdev := range n.NetDevs { tstruct.NetDevs = make(map[string]*node.NetDevs)
var nd node.NetDevs tstruct.Keys = make(map[string]string)
t.NetDevs[devname] = &nd for devname, netdev := range nodeInfo.NetDevs {
t.NetDevs[devname].Name = devname var nd node.NetDevs
t.NetDevs[devname].Device = netdev.Device.Get() tstruct.NetDevs[devname] = &nd
t.NetDevs[devname].Hwaddr = netdev.Hwaddr.Get() tstruct.NetDevs[devname].Name = devname
t.NetDevs[devname].Ipaddr = netdev.Ipaddr.Get() tstruct.NetDevs[devname].Device = netdev.Device.Get()
t.NetDevs[devname].Netmask = netdev.Netmask.Get() tstruct.NetDevs[devname].Hwaddr = netdev.Hwaddr.Get()
t.NetDevs[devname].Gateway = netdev.Gateway.Get() tstruct.NetDevs[devname].Ipaddr = netdev.Ipaddr.Get()
t.NetDevs[devname].Type = netdev.Type.Get() tstruct.NetDevs[devname].Netmask = netdev.Netmask.Get()
t.NetDevs[devname].OnBoot = netdev.OnBoot.GetB() tstruct.NetDevs[devname].Gateway = netdev.Gateway.Get()
tstruct.NetDevs[devname].Type = netdev.Type.Get()
tstruct.NetDevs[devname].OnBoot = netdev.OnBoot.GetB()
mask := net.IPMask(net.ParseIP(netdev.Netmask.Get()).To4()) mask := net.IPMask(net.ParseIP(netdev.Netmask.Get()).To4())
ipaddr := net.ParseIP(netdev.Ipaddr.Get()).To4() ipaddr := net.ParseIP(netdev.Ipaddr.Get()).To4()
netaddr := net.IPNet{IP: ipaddr, Mask: mask} netaddr := net.IPNet{IP: ipaddr, Mask: mask}
netPrefix, _ := net.IPMask(net.ParseIP(netdev.Netmask.Get()).To4()).Size() netPrefix, _ := net.IPMask(net.ParseIP(netdev.Netmask.Get()).To4()).Size()
t.NetDevs[devname].Prefix = strconv.Itoa(netPrefix) tstruct.NetDevs[devname].Prefix = strconv.Itoa(netPrefix)
t.NetDevs[devname].IpCIDR = netaddr.String() tstruct.NetDevs[devname].IpCIDR = netaddr.String()
}
for keyname, key := range n.Keys {
t.Keys[keyname] = key.Get()
}
t.AllNodes = allNodes
if overlayType == "runtime" && !n.RuntimeOverlay.Defined() {
wwlog.Printf(wwlog.WARN, "Undefined runtime overlay, skipping node: %s\n", n.Id.Get())
}
if overlayType == "system" && !n.SystemOverlay.Defined() {
wwlog.Printf(wwlog.WARN, "Undefined system overlay, skipping node: %s\n", n.Id.Get())
}
wwlog.Printf(wwlog.DEBUG, "Checking to see if overlay directory exists: %s\n", OverlayDir)
if !util.IsDir(OverlayDir) {
wwlog.Printf(wwlog.WARN, "%-35s: Skipped (runtime overlay template not found)\n", n.Id.Get())
continue
}
wwlog.Printf(wwlog.DEBUG, "Creating parent directory for OverlayFile: %s\n", path.Dir(OverlayFile))
err := os.MkdirAll(path.Dir(OverlayFile), 0755)
if err != nil {
return err
}
wwlog.Printf(wwlog.DEBUG, "Changing directory to OverlayDir: %s\n", OverlayDir)
err = os.Chdir(OverlayDir)
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not chdir() to OverlayDir: %s\n", OverlayDir)
continue
}
wwlog.Printf(wwlog.DEBUG, "Creating temporary directory for overlay files\n")
tmpDir, err := ioutil.TempDir(os.TempDir(), ".wwctl-overlay-")
if err != nil {
return err
}
wwlog.Printf(wwlog.DEBUG, "Walking the file system: %s\n", OverlayDir)
err = filepath.Walk(".", func(location string, info os.FileInfo, err error) error {
if err != nil {
return err
}
wwlog.Printf(wwlog.DEBUG, "Overlay Walk for '%s': OVERLAY:/%s\n", n.Id.Get(), location)
if info.IsDir() {
wwlog.Printf(wwlog.DEBUG, "Found directory: %s\n", location)
err = os.MkdirAll(path.Join(tmpDir, location), info.Mode())
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
return err
}
err = util.CopyUIDGID(location, path.Join(tmpDir, location))
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
return err
}
} else if filepath.Ext(location) == ".ww" {
wwlog.Printf(wwlog.DEBUG, "Found template file: %s\n", location)
destFile := strings.TrimSuffix(location, ".ww")
tmpl, err := template.New(path.Base(location)).Funcs(template.FuncMap{
"Include": templateFileInclude,
"IncludeFrom": templateContainerFileInclude,
"inc": func(i int) int { return i + 1 },
"dec": func(i int) int { return i - 1 },
}).ParseGlob(path.Join(OverlayDir, destFile+".ww*"))
if err != nil {
wwlog.Printf(wwlog.ERROR, "template.New %s\n", err)
return nil
}
w, err := os.OpenFile(path.Join(tmpDir, destFile), os.O_RDWR|os.O_CREATE, info.Mode())
if err != nil {
wwlog.Printf(wwlog.ERROR, "path.Join %s\n", err)
return err
}
defer w.Close()
wwlog.Printf(wwlog.DEBUG, "Writing overlay template: OVERLAY:/%s\n", destFile)
err = tmpl.Execute(w, t)
if err != nil {
wwlog.Printf(wwlog.ERROR, "tmpl.Execute %s\n", err)
return nil
}
err = util.CopyUIDGID(location, path.Join(tmpDir, destFile))
if err != nil {
return err
}
} else if b, _ := regexp.MatchString(`\.ww[a-zA-Z0-9\-\._]*$`, location); b {
wwlog.Printf(wwlog.DEBUG, "Ignoring WW template file: %s\n", location)
} else {
wwlog.Printf(wwlog.DEBUG, "Found file: %s\n", location)
err := util.CopyFile(path.Join(OverlayDir, location), path.Join(tmpDir, location))
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
return err
}
}
return nil
})
if err != nil {
return errors.Wrap(err, "failed to open dir")
}
if err != nil {
wwlog.Printf(wwlog.ERROR, "Error with filepath walk: %s\n", err)
os.Exit(1)
}
wwlog.Printf(wwlog.DEBUG, "Finished generating overlay directory for: %s\n", n.Id.Get())
compressor, err := exec.LookPath("pigz")
if err != nil {
wwlog.Printf(wwlog.DEBUG, "Could not locate PIGZ, using GZIP\n")
compressor = "gzip"
} else {
wwlog.Printf(wwlog.DEBUG, "Using PIGZ to compress the overlay: %s\n", compressor)
}
cmd := fmt.Sprintf("cd \"%s\"; find . | cpio --quiet -o -H newc | %s -c > \"%s\"", tmpDir, compressor, OverlayFile)
wwlog.Printf(wwlog.DEBUG, "RUNNING: %s\n", cmd)
err = exec.Command("/bin/sh", "-c", cmd).Run()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not generate runtime image overlay: %s\n", err)
continue
}
wwlog.Printf(wwlog.VERBOSE, "%-35s: Done\n", n.Id.Get())
wwlog.Printf(wwlog.DEBUG, "Removing temporary directory: %s\n", tmpDir)
os.RemoveAll(tmpDir)
} }
for keyname, key := range nodeInfo.Keys {
tstruct.Keys[keyname] = key.Get()
}
tstruct.AllNodes = allNodes
wwlog.Printf(wwlog.DEBUG, "Changing directory to OverlayDir: %s\n", OverlaySourceDir)
err = os.Chdir(OverlaySourceDir)
if err != nil {
return errors.Wrap(err, "could not change directory to overlay dir")
}
wwlog.Printf(wwlog.VERBOSE, "Walking the overlay structure: %s\n", OverlaySourceDir)
err = filepath.Walk(".", func(location string, info os.FileInfo, err error) error {
if err != nil {
return err
}
wwlog.Printf(wwlog.DEBUG, "Found overlay file: %s\n", location)
if info.IsDir() {
wwlog.Printf(wwlog.DEBUG, "Found directory: %s\n", location)
err = os.MkdirAll(path.Join(tmpDir, location), info.Mode())
if err != nil {
return errors.Wrap(err, "could not create directory within overlay")
}
err = util.CopyUIDGID(location, path.Join(tmpDir, location))
if err != nil {
return errors.Wrap(err, "failed setting permissions on overlay directory")
}
wwlog.Printf(wwlog.DEBUG, "Created directory in overlay: %s\n", location)
} else if filepath.Ext(location) == ".ww" {
wwlog.Printf(wwlog.VERBOSE, "Evaluating overlay template file: %s\n", location)
destFile := strings.TrimSuffix(location, ".ww")
tmpl, err := template.New(path.Base(location)).Option("missingkey=default").Funcs(template.FuncMap{
// TODO: Fix for missingkey=zero
"Include": templateFileInclude,
"IncludeFrom": templateContainerFileInclude,
"inc": func(i int) int { return i + 1 },
"dec": func(i int) int { return i - 1 },
// }).ParseGlob(path.Join(OverlayDir, destFile+".ww*"))
}).ParseGlob(location)
if err != nil {
return errors.Wrap(err, "could not parse template "+location)
}
w, err := os.OpenFile(path.Join(tmpDir, destFile), os.O_RDWR|os.O_CREATE, info.Mode())
if err != nil {
return errors.Wrap(err, "could not open new file for template")
}
defer w.Close()
err = tmpl.Execute(w, tstruct)
if err != nil {
return errors.Wrap(err, "could not execute template")
}
err = util.CopyUIDGID(location, path.Join(tmpDir, destFile))
if err != nil {
return errors.Wrap(err, "failed setting permissions on template output file")
}
wwlog.Printf(wwlog.DEBUG, "Wrote template file into overlay: %s\n", destFile)
// } else if b, _ := regexp.MatchString(`\.ww[a-zA-Z0-9\-\._]*$`, location); b {
// wwlog.Printf(wwlog.DEBUG, "Ignoring WW template file: %s\n", location)
} else {
err := util.CopyFile(location, path.Join(tmpDir, location))
if err == nil {
wwlog.Printf(wwlog.DEBUG, "Copied file into overlay: %s\n", location)
} else {
return errors.Wrap(err, "could not copy file into overlay")
}
}
return nil
})
if err != nil {
return errors.Wrap(err, "failed to build overlay working directory")
}
wwlog.Printf(wwlog.DEBUG, "Finished generating overlay working directory for: %s/%s\n", nodeInfo.Id.Get(), overlayName)
compressor, err := exec.LookPath("pigz")
if err != nil {
wwlog.Printf(wwlog.DEBUG, "Could not locate PIGZ, using GZIP\n")
compressor = "gzip"
} else {
wwlog.Printf(wwlog.DEBUG, "Using PIGZ to compress the overlay: %s\n", compressor)
}
cmd := fmt.Sprintf("cd \"%s\"; find . | cpio --quiet -o -H newc | %s -c > \"%s\"", tmpDir, compressor, OverlayImage)
wwlog.Printf(wwlog.DEBUG, "RUNNING: %s\n", cmd)
err = exec.Command("/bin/sh", "-c", cmd).Run()
if err != nil {
return errors.Wrap(err, "could not generate compressed runtime image overlay")
}
wwlog.Printf(wwlog.VERBOSE, "Completed building overlay image: %s\n", OverlayImage)
wwlog.Printf(wwlog.DEBUG, "Removing temporary directory: %s\n", tmpDir)
os.RemoveAll(tmpDir)
return nil return nil
} }

View File

@@ -83,8 +83,7 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) {
unconfiguredNode = true unconfiguredNode = true
} else { } else {
nodeobj = n nodeobj = n
_ = overlay.BuildSystemOverlay([]node.NodeInfo{n}) _ = overlay.BuildAllOverlays([]node.NodeInfo{n})
_ = overlay.BuildRuntimeOverlay([]node.NodeInfo{n})
daemonLogf("IPXEREQ: %s (node automatically configured)\n", hwaddr) daemonLogf("IPXEREQ: %s (node automatically configured)\n", hwaddr)

View File

@@ -5,7 +5,6 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/hpcng/warewulf/internal/pkg/config"
"github.com/hpcng/warewulf/internal/pkg/node" "github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/overlay" "github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/util"
@@ -64,12 +63,12 @@ func RuntimeOverlaySend(w http.ResponseWriter, req *http.Request) {
} }
if n.RuntimeOverlay.Defined() { if n.RuntimeOverlay.Defined() {
fileName := config.RuntimeOverlayImage(n.Id.Get()) fileName := overlay.OverlayImage(n.Id.Get(), n.RuntimeOverlay.Get())
if conf.Warewulf.AutobuildOverlays { if conf.Warewulf.AutobuildOverlays {
if !util.IsFile(fileName) || util.PathIsNewer(fileName, node.ConfigFile) || util.PathIsNewer(fileName, config.RuntimeOverlaySource(n.RuntimeOverlay.Get())) { if !util.IsFile(fileName) || util.PathIsNewer(fileName, node.ConfigFile) || util.PathIsNewer(fileName, overlay.OverlaySourceDir(n.RuntimeOverlay.Get())) {
daemonLogf("BUILD: %15s: Runtime Overlay\n", n.Id.Get()) daemonLogf("BUILD: %15s: Runtime Overlay\n", n.Id.Get())
_ = overlay.BuildRuntimeOverlay([]node.NodeInfo{n}) _ = overlay.BuildOverlay(n, n.RuntimeOverlay.Get())
} }
} }

View File

@@ -3,7 +3,6 @@ package warewulfd
import ( import (
"net/http" "net/http"
"github.com/hpcng/warewulf/internal/pkg/config"
"github.com/hpcng/warewulf/internal/pkg/node" "github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/overlay" "github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/util"
@@ -26,12 +25,12 @@ func SystemOverlaySend(w http.ResponseWriter, req *http.Request) {
} }
if n.SystemOverlay.Defined() { if n.SystemOverlay.Defined() {
fileName := config.SystemOverlayImage(n.Id.Get()) fileName := overlay.OverlayImage(n.Id.Get(), n.SystemOverlay.Get())
if conf.Warewulf.AutobuildOverlays { if conf.Warewulf.AutobuildOverlays {
if !util.IsFile(fileName) || util.PathIsNewer(fileName, node.ConfigFile) || util.PathIsNewer(fileName, config.SystemOverlaySource(n.SystemOverlay.Get())) { if !util.IsFile(fileName) || util.PathIsNewer(fileName, node.ConfigFile) || util.PathIsNewer(fileName, overlay.OverlaySourceDir(n.SystemOverlay.Get())) {
daemonLogf("BUILD: %15s: System Overlay\n", n.Id.Get()) daemonLogf("BUILD: %15s: System Overlay\n", n.Id.Get())
_ = overlay.BuildSystemOverlay([]node.NodeInfo{n}) _ = overlay.BuildOverlay(n, n.SystemOverlay.Get())
} }
} }