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

@@ -3,7 +3,9 @@ package nfs
import (
"fmt"
"os"
"path"
"github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/warewulfconf"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
@@ -33,7 +35,7 @@ func Configure(show bool) error {
}
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 {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
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(), "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(), "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(), "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(), "Init", node.Init.Source(), node.Init.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,
Use: "set [OPTIONS] PATTERN [PATTERN ...]",
Short: "Configure node properties",
Long: "This command sets configuration properties for nodes matching PATTERN.\n\n" +
"Note: use the string 'UNSET' to remove a configuration",
Args: cobra.MinimumNArgs(1),
RunE: CobraRunE,
Long: "This command sets configuration properties for nodes matching PATTERN.\n\nNote: use the string 'UNSET' to remove a configuration",
Args: cobra.MinimumNArgs(1),
RunE: CobraRunE,
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
@@ -48,6 +47,7 @@ var (
SetNetDevDel bool
SetClusterName string
SetIpxe string
SetInitOverlay string
SetRuntimeOverlay string
SetSystemOverlay string
SetIpmiIpaddr string
@@ -93,16 +93,17 @@ func init() {
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().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")
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
}); err != nil {
log.Println(err)
}
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) {
list, _ := overlay.FindSystemOverlays()
list, _ := overlay.FindOverlays()
return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil {
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(&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().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")

View File

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

View File

@@ -5,17 +5,15 @@ import "github.com/spf13/cobra"
var (
baseCmd = &cobra.Command{
DisableFlagsInUseLine: true,
Use: "build [OPTIONS] {system|runtime} OVERLAY_NAME",
Short: "(Re)build an overlay",
Long: "This command builds a new system or runtime overlay named OVERLAY_NAME.",
RunE: CobraRunE,
Args: cobra.RangeArgs(0, 2),
Use: "build [OPTIONS] NODENAME...",
Short: "(Re)build node overlays",
Long: "This command builds overlays for given nodes.",
RunE: CobraRunE,
}
BuildAll bool
)
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.

View File

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

View File

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

View File

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

View File

@@ -4,12 +4,12 @@ import "github.com/spf13/cobra"
var (
baseCmd = &cobra.Command{
Use: "chown [OPTIONS] {system|runtime} OVERLAY_NAME FILE UID [GID]",
Short: "Change file ownership within an overlay",
Long: "This command changes the ownership of a FILE within the system or runtime OVERLAY_NAME\n" +
"to the user specified by UID. Optionally, it will also change group ownership to GID.",
RunE: CobraRunE,
Args: cobra.RangeArgs(4, 5),
DisableFlagsInUseLine: true,
Use: "chown [OPTIONS] OVERLAY_NAME FILE UID [GID]",
Short: "Change file ownership within an overlay",
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,
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/wwlog"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
overlayKind := args[0]
overlayName := args[1]
if overlayKind != "system" && overlayKind != "runtime" {
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)
}
err := overlay.OverlayInit(args[0])
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1)
}
return nil

View File

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

View File

@@ -5,8 +5,7 @@ import (
"os"
"path"
"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/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors"
@@ -17,22 +16,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
var overlayPath string
var fileName string
overlayKind := args[0]
overlayName := args[1]
overlayName := args[0]
if len(args) == 3 {
fileName = args[2]
if len(args) == 2 {
fileName = args[1]
}
if overlayKind != "system" && overlayKind != "runtime" {
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)
}
overlayPath = overlay.OverlaySourceDir(overlayName)
if overlayPath == "" {
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) {
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)
}
if fileName == "" {
if overlayName == "default" {
return errors.New("refusing to delete the default overlay")
if overlayName == "wwinit" {
return errors.New("refusing to delete the Warewulf overlay")
}
if Force {
err := os.RemoveAll(overlayPath)
@@ -61,31 +51,6 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
}
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 {
removePath := path.Join(overlayPath, fileName)
@@ -97,14 +62,14 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
if Force {
err := os.RemoveAll(removePath)
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)
os.Exit(1)
}
} else {
err := os.Remove(removePath)
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)
os.Exit(1)
}

View File

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

View File

@@ -6,10 +6,9 @@ import (
"path"
"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/wwlog"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -17,26 +16,17 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
editor := os.Getenv("EDITOR")
var overlaySourceDir string
overlayKind := args[0]
overlayName := args[1]
fileName := args[2]
if overlayKind != "system" && overlayKind != "runtime" {
return errors.New("overlay kind must be of type 'system' or 'runtime'")
}
overlayName := args[0]
fileName := args[1]
if editor == "" {
editor = "/bin/vi"
}
if overlayKind == "system" {
overlaySourceDir = config.SystemOverlaySource(overlayName)
} else if overlayKind == "runtime" {
overlaySourceDir = config.RuntimeOverlaySource(overlayName)
}
overlaySourceDir = overlay.OverlaySourceDir(overlayName)
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)
}
@@ -59,7 +49,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
}
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))
if err != nil {

View File

@@ -7,13 +7,11 @@ import (
var (
baseCmd = &cobra.Command{
DisableFlagsInUseLine: true,
Use: "edit [OPTIONS] {system|runtime} OVERLAY_NAME FILE",
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" +
"OVERLAY_NAME. Note: files created with a '.ww' suffix will always be\n" +
"parsed as Warewulf template files, and the suffix will be removed automatically.",
RunE: CobraRunE,
Args: cobra.ExactArgs(3),
Use: "edit [OPTIONS] OVERLAY_NAME FILE",
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\nOVERLAY_NAME. Note: files created with a '.ww' suffix will always be\nparsed as Warewulf template files, and the suffix will be removed automatically.",
RunE: CobraRunE,
Args: cobra.ExactArgs(2),
}
ListFiles bool
CreateDirs bool

View File

@@ -4,7 +4,6 @@ import (
"os"
"path"
"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/util"
@@ -17,30 +16,20 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
var dest string
var overlaySource string
overlayKind := args[0]
overlayName := args[1]
source := args[2]
overlayName := args[0]
source := args[1]
if overlayKind != "system" && overlayKind != "runtime" {
return errors.New("overlay kind must be of type 'system' or 'runtime'")
}
if len(args) == 4 {
dest = args[3]
if len(args) == 3 {
dest = args[2]
} else {
dest = source
}
if overlayKind == "system" {
wwlog.Printf(wwlog.VERBOSE, "Copying '%s' into system overlay '%s:%s'\n", source, overlayName, dest)
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)
}
wwlog.Printf(wwlog.VERBOSE, "Copying '%s' into overlay '%s:%s'\n", source, overlayName, dest)
overlaySource = overlay.OverlaySourceDir(overlayName)
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)
}
@@ -49,7 +38,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
}
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)
}
@@ -74,21 +63,14 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
var updateNodes []node.NodeInfo
for _, node := range nodes {
if overlayKind == "system" && node.SystemOverlay.Get() == overlayName {
if node.SystemOverlay.Get() == overlayName {
updateNodes = append(updateNodes, node)
} else if overlayKind == "runtime" && node.RuntimeOverlay.Get() == overlayName {
} else if node.RuntimeOverlay.Get() == overlayName {
updateNodes = append(updateNodes, node)
}
}
if overlayKind == "system" {
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 overlay.BuildSpecificOverlays(updateNodes, overlayName)
}
return nil

View File

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

View File

@@ -5,8 +5,6 @@ import (
"os"
"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/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
@@ -15,79 +13,27 @@ import (
)
func CobraRunE(cmd *cobra.Command, args []string) error {
set := make(map[string]int)
var o []string
var err error
var nodeList []node.NodeInfo
var overlayName string
var overlays []string
overlayKind := args[0]
if len(args) > 1 {
overlayName = args[1]
}
if overlayKind != "system" && overlayKind != "runtime" {
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()]++
}
if len(args) > 0 {
overlays = args
} else {
var err error
overlays, err = overlay.FindOverlays()
if err != nil {
return errors.Wrap(err, "could not obtain list of overlays from system")
}
}
for overlay := range o {
var path string
name := o[overlay]
if ListLong {
fmt.Printf("%-10s %5s %-5s %-18s %s\n", "PERM MODE", "UID", "GID", "SYSTEM-OVERLAY", "FILE PATH")
} else {
fmt.Printf("%-30s %-12s\n", "OVERLAY NAME", "FILES/DIRS")
}
if overlayName != "" && overlayName != name {
continue
}
if overlayKind == "system" {
path = config.SystemOverlaySource(o[overlay])
} else if overlayKind == "runtime" {
path = config.RuntimeOverlaySource(o[overlay])
}
for o := range overlays {
name := overlays[o]
path := overlay.OverlaySourceDir(name)
if util.IsDir(path) {
files := util.FindFiles(path)
@@ -96,11 +42,11 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
if ListContents {
var fileCount int
for file := range files {
fmt.Printf("%-30s %-12d /%-12s\n", name, set[name], files[file])
fmt.Printf("%-30s /%-12s\n", name, files[file])
fileCount++
}
if fileCount == 0 {
fmt.Printf("%-30s %-12d %-12d\n", name, set[name], 0)
fmt.Printf("%-30s %-12d\n", name, 0)
}
} else if ListLong {
for file := range files {
@@ -114,15 +60,15 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
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 {
fmt.Printf("%-30s %-12d %-12d\n", name, set[name], len(files))
fmt.Printf("%-30s %-12d\n", name, len(files))
}
} 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 (
baseCmd = &cobra.Command{
DisableFlagsInUseLine: true,
Use: "list [OPTIONS] {system|runtime} [OVERLAY_NAME]",
Short: "List Warewulf Overlays and files",
Long: "This command displays information about all Warewulf overlays or the specified\n" +
"OVERLAY_NAME. It also supports listing overlay content information.",
RunE: CobraRunE,
Args: cobra.MinimumNArgs(1),
Aliases: []string{"ls"},
ValidArgs: []string{"system", "runtime"},
Use: "list [OPTIONS] OVERLAY_NAME",
Short: "List Warewulf Overlays and files",
Long: "This command displays information about all Warewulf overlays or the specified\nOVERLAY_NAME. It also supports listing overlay content information.",
RunE: CobraRunE,
Args: cobra.MinimumNArgs(0),
Aliases: []string{"ls"},
ValidArgs: []string{"system", "runtime"},
}
ListContents bool
ListLong bool

View File

@@ -4,38 +4,28 @@ import (
"os"
"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/wwlog"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
var overlaySourceDir string
overlayKind := args[0]
overlayName := args[1]
dirName := args[2]
overlayName := args[0]
dirName := args[1]
if overlayKind != "system" && overlayKind != "runtime" {
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)
}
overlaySourceDir = overlay.OverlaySourceDir(overlayName)
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)
}
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))
if err != nil {

View File

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

View File

@@ -6,29 +6,19 @@ import (
"os"
"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/wwlog"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
var overlaySourceDir string
overlayKind := args[0]
overlayName := args[1]
fileName := args[2]
overlayName := args[0]
fileName := args[1]
if overlayKind != "system" && overlayKind != "runtime" {
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)
}
overlaySourceDir = overlay.OverlaySourceDir(overlayName)
if !util.IsDir(overlaySourceDir) {
wwlog.Printf(wwlog.ERROR, "Overlay does not exist: %s\n", overlayName)

View File

@@ -6,12 +6,13 @@ import (
var (
baseCmd = &cobra.Command{
Use: "show [OPTIONS] {system|runtime} OVERLAY_NAME FILE",
Short: "Show (cat) a file within a Warewulf Overlay",
Long: "This command displays the contents of FILE within OVERLAY_NAME.",
RunE: CobraRunE,
Aliases: []string{"cat"},
Args: cobra.ExactArgs(3),
DisableFlagsInUseLine: true,
Use: "show [OPTIONS] OVERLAY_NAME FILE",
Short: "Show (cat) a file within a Warewulf Overlay",
Long: "This command displays the contents of FILE within OVERLAY_NAME.",
RunE: CobraRunE,
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(), "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(), "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(), "IpmiNetmask", profile.IpmiNetmask.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "IpmiPort", profile.IpmiPort.Print())

View File

@@ -41,6 +41,7 @@ var (
SetKernelArgs string
SetClusterName string
SetIpxe string
SetInitOverlay string
SetRuntimeOverlay string
SetSystemOverlay string
SetIpmiNetmask string
@@ -91,7 +92,7 @@ func init() {
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) {
list, _ := overlay.FindRuntimeOverlays()
list, _ := overlay.FindOverlays()
return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil {
log.Println(err)
@@ -99,7 +100,7 @@ func init() {
}
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) {
list, _ := overlay.FindSystemOverlays()
list, _ := overlay.FindOverlays()
return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil {
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(&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().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")