First pass at a rework of the overlay subsystem in Warewulf
This commit is contained in:
7
Makefile
7
Makefile
@@ -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'\
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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),
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|
||||||
|
|||||||
@@ -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")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user