diff --git a/internal/app/wwctl/overlay/chmod/main.go b/internal/app/wwctl/overlay/chmod/main.go index 552b53d9..11b2b8ef 100644 --- a/internal/app/wwctl/overlay/chmod/main.go +++ b/internal/app/wwctl/overlay/chmod/main.go @@ -21,11 +21,11 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("could not convert requested mode: %s", err) } - err = overlay.CreateSiteOverlay(overlayName) + err = overlay.CloneSiteOverlay(overlayName) if err != nil { return err } - overlaySourceDir, _ = overlay.OverlaySourceDir(overlayName) + overlaySourceDir, _ = overlay.GetOverlay(overlayName) if !util.IsDir(overlaySourceDir) { return fmt.Errorf("overlay does not exist: %s", overlayName) diff --git a/internal/app/wwctl/overlay/chown/main.go b/internal/app/wwctl/overlay/chown/main.go index f7b80c89..b32b8122 100644 --- a/internal/app/wwctl/overlay/chown/main.go +++ b/internal/app/wwctl/overlay/chown/main.go @@ -34,11 +34,11 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } else { gid = -1 } - err = overlay.CreateSiteOverlay(overlayName) + err = overlay.CloneSiteOverlay(overlayName) if err != nil { return err } - overlaySourceDir, _ = overlay.OverlaySourceDir(overlayName) + overlaySourceDir, _ = overlay.GetOverlay(overlayName) if !util.IsDir(overlaySourceDir) { return fmt.Errorf("overlay does not exist: %s", overlayName) diff --git a/internal/app/wwctl/overlay/create/main.go b/internal/app/wwctl/overlay/create/main.go index 966f43f7..3ab4ba4f 100644 --- a/internal/app/wwctl/overlay/create/main.go +++ b/internal/app/wwctl/overlay/create/main.go @@ -6,6 +6,6 @@ import ( ) func CobraRunE(cmd *cobra.Command, args []string) (err error) { - err = overlay.OverlayInit(args[0]) - return + _, err = overlay.CreateSiteOverlay(args[0]) + return err } diff --git a/internal/app/wwctl/overlay/delete/main.go b/internal/app/wwctl/overlay/delete/main.go index 19c708b1..0b8576d7 100644 --- a/internal/app/wwctl/overlay/delete/main.go +++ b/internal/app/wwctl/overlay/delete/main.go @@ -22,7 +22,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { fileName = args[1] } - overlayPath, isSite := overlay.OverlaySourceDir(overlayName) + overlayPath, isSite := overlay.GetOverlay(overlayName) if !isSite { return fmt.Errorf("distribution overlay can't deleted") diff --git a/internal/app/wwctl/overlay/edit/main.go b/internal/app/wwctl/overlay/edit/main.go index fa778ef9..62e8cb44 100644 --- a/internal/app/wwctl/overlay/edit/main.go +++ b/internal/app/wwctl/overlay/edit/main.go @@ -36,9 +36,9 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { overlayName := args[0] fileName := args[1] createdSite := false - overlaySourceDir, isSite := overlay.OverlaySourceDir(overlayName) + overlaySourceDir, isSite := overlay.GetOverlay(overlayName) if !isSite { - err = overlay.CreateSiteOverlay(overlayName) + err = overlay.CloneSiteOverlay(overlayName) if err != nil { return err } diff --git a/internal/app/wwctl/overlay/imprt/main.go b/internal/app/wwctl/overlay/imprt/main.go index 21288502..d22aa115 100644 --- a/internal/app/wwctl/overlay/imprt/main.go +++ b/internal/app/wwctl/overlay/imprt/main.go @@ -27,7 +27,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } wwlog.Verbose("Copying '%s' into overlay '%s:%s'", source, overlayName, dest) - overlaySource, _ = overlay.OverlaySourceDir(overlayName) + overlaySource, _ = overlay.GetOverlay(overlayName) if !util.IsDir(overlaySource) { return fmt.Errorf("overlay does not exist: %s", overlayName) diff --git a/internal/app/wwctl/overlay/list/main.go b/internal/app/wwctl/overlay/list/main.go index 4852aaf8..1089b940 100644 --- a/internal/app/wwctl/overlay/list/main.go +++ b/internal/app/wwctl/overlay/list/main.go @@ -32,7 +32,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { for o := range overlays { name := overlays[o] - path, isSite := overlay.OverlaySourceDir(name) + path, isSite := overlay.GetOverlay(name) if util.IsDir(path) { files := util.FindFiles(path) diff --git a/internal/app/wwctl/overlay/mkdir/main.go b/internal/app/wwctl/overlay/mkdir/main.go index 2c2c8206..32d16006 100644 --- a/internal/app/wwctl/overlay/mkdir/main.go +++ b/internal/app/wwctl/overlay/mkdir/main.go @@ -16,11 +16,11 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { overlayName := args[0] dirName := args[1] - err = overlay.CreateSiteOverlay(overlayName) + err = overlay.CloneSiteOverlay(overlayName) if err != nil { return err } - overlaySourceDir, _ = overlay.OverlaySourceDir(overlayName) + overlaySourceDir, _ = overlay.GetOverlay(overlayName) if !util.IsDir(overlaySourceDir) { return fmt.Errorf("overlay does not exist: %s", overlayName) diff --git a/internal/app/wwctl/overlay/show/main.go b/internal/app/wwctl/overlay/show/main.go index 2a62709b..ea3041f4 100644 --- a/internal/app/wwctl/overlay/show/main.go +++ b/internal/app/wwctl/overlay/show/main.go @@ -22,7 +22,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { overlayName := args[0] fileName := args[1] - overlaySourceDir, _ = overlay.OverlaySourceDir(overlayName) + overlaySourceDir, _ = overlay.GetOverlay(overlayName) if !util.IsDir(overlaySourceDir) { return fmt.Errorf("overlay dir: %s does not exist", overlaySourceDir) diff --git a/internal/pkg/config/buildconfig.go.in b/internal/pkg/config/buildconfig.go.in index e5c5c0e6..45dd5969 100644 --- a/internal/pkg/config/buildconfig.go.in +++ b/internal/pkg/config/buildconfig.go.in @@ -79,11 +79,11 @@ func (paths BuildConfig) OciBlobCachedir() string { return path.Join(paths.Cachedir, "warewulf") } -func (paths BuildConfig) SiteOverlaySourcedir() string { +func (paths BuildConfig) SiteOverlaydir() string { return paths.WWOverlaydir } -func (paths BuildConfig) DistributionOverlaySourcedir() string { +func (paths BuildConfig) DistributionOverlaydir() string { return path.Join(paths.Datadir, "warewulf", "overlays") } diff --git a/internal/pkg/configure/hostfile.go b/internal/pkg/configure/hostfile.go index e2a0309e..1f5057e6 100644 --- a/internal/pkg/configure/hostfile.go +++ b/internal/pkg/configure/hostfile.go @@ -14,7 +14,7 @@ import ( Creates '/etc/hosts' from the host template. */ func Hostfile() (err error) { - overlaySourceDir, _ := overlay.OverlaySourceDir("host") + overlaySourceDir, _ := overlay.GetOverlay("host") hostTemplate := path.Join(overlaySourceDir, "/etc/hosts.ww") if !(util.IsFile(hostTemplate)) { return fmt.Errorf("'the overlay template '/etc/hosts.ww' does not exists in 'host' overlay") diff --git a/internal/pkg/overlay/config.go b/internal/pkg/overlay/config.go index 60eeaab9..0d92bb92 100644 --- a/internal/pkg/overlay/config.go +++ b/internal/pkg/overlay/config.go @@ -13,28 +13,82 @@ import ( "github.com/warewulf/warewulf/internal/pkg/wwlog" ) -/* -Return the path for the base of the overlay, adds rootfs -prefix in the overlay dir if this it exists -*/ -func OverlaySourceDir(overlayName string) (overlaypath string, isSite bool) { +// GetOverlay returns the filesystem path of an overlay identified by its name, +// along with a boolean indicating whether the returned overlayPath corresponds +// to a site-specific overlay. +func GetOverlay(name string) (overlayPath string, isSite bool) { + overlayPath = GetSiteOverlay(name) + if _, err := os.Stat(overlayPath); err == nil { + return overlayPath, true + } + overlayPath = GetDistributionOverlay(name) + return overlayPath, false +} + +// GetDistributionOverlay returns the filesystem path of a distribution overlay +// identified by the given name. +func GetDistributionOverlay(name string) (overlayPath string) { controller := warewulfconf.Get() + return getOverlay(controller.Paths.DistributionOverlaydir(), name) +} + +// GetSiteOverlay returns the filesystem path of a site-specific overlay +// identified by the given name. +func GetSiteOverlay(name string) (overlayPath string) { + controller := warewulfconf.Get() + return getOverlay(controller.Paths.SiteOverlaydir(), name) +} + +// getOverlay constructs the filesystem path of an overlay based on the given +// overlay directory and overlay name. +// +// The returned path will include a "rootfs" directory if it exists. +func getOverlay(overlaydir, name string) (overlayPath string) { /* Assume using old style overlay dir without rootfs */ - overlaypath = path.Join(controller.Paths.SiteOverlaySourcedir(), overlayName) - if _, err := os.Stat(path.Join(overlaypath, "rootfs")); err == nil { + overlayPath = path.Join(overlaydir, name) + if _, err := os.Stat(path.Join(overlayPath, "rootfs")); err == nil { /* rootfs exists, use it. */ - overlaypath = path.Join(overlaypath, "rootfs") + overlayPath = path.Join(overlayPath, "rootfs") } - if _, err := os.Stat(overlaypath); err == nil { - return overlaypath, true + return overlayPath +} + +// CreateSiteOverlay creates a new site overlay directory with the specified name. +// +// This function constructs the path for the new overlay based on the site's overlay directory +// configuration and checks if the directory already exists. If the overlay already exists, +// it returns an error. Otherwise, it creates the necessary directory structure, including a +// rootfs directory. +// +// Parameters: +// - overlayName: The name of the site overlay to be created. +// +// Returns: +// - overlayPath: The full path to the created site overlay directory. +// - err: An error if the overlay already exists or if directory creation fails. +func CreateSiteOverlay(overlayName string) (overlayPath string, err error) { + controller := warewulfconf.Get() + overlayPath = path.Join(controller.Paths.SiteOverlaydir(), overlayName) + if util.IsDir(overlayPath) { + return overlayPath, fmt.Errorf("overlay already exists: %s", overlayName) } - overlaypath = path.Join(controller.Paths.DistributionOverlaySourcedir(), overlayName) - if _, err := os.Stat(path.Join(overlaypath, "rootfs")); err == nil { - /* rootfs exists, use it. */ - overlaypath = path.Join(overlaypath, "rootfs") + overlayPath = path.Join(overlayPath, "rootfs") + err = os.MkdirAll(overlayPath, 0755) + return overlayPath, err +} + +// Creates a site overlay from an existing distribution overlay. +// +// If the distribution overlay doesn't exist, return an OverlayDoesNotExist error. +func CloneSiteOverlay(name string) (err error) { + controller := warewulfconf.Get() + distroPath := path.Join(controller.Paths.DistributionOverlaydir(), name) + sitePath := path.Join(controller.Paths.SiteOverlaydir(), name) + if !util.IsDir(distroPath) { + return &OverlayDoesNotExist{Name: name} } - wwlog.Debug("found overlay %s in path: %s", overlayName, overlaypath) - return overlaypath, false + err = copy.DirCopy(distroPath, sitePath, copy.Content, true) + return err } // OverlayImage returns the full path to an overlay image based on the @@ -74,16 +128,3 @@ type OverlayDoesNotExist struct { func (e *OverlayDoesNotExist) Error() string { return fmt.Sprintf("overlay %s does not exist", e.Name) } - -// Creates a site overlay from an existing overlay and give back -// OverlayDoesNotExist error if distribution overlay doesn't exsist -func CreateSiteOverlay(name string) (err error) { - controller := warewulfconf.Get() - distroPath := path.Join(controller.Paths.DistributionOverlaySourcedir(), name) - sitePath := path.Join(controller.Paths.SiteOverlaySourcedir(), name) - if !util.IsDir(distroPath) { - return &OverlayDoesNotExist{Name: name} - } - err = copy.DirCopy(distroPath, sitePath, copy.Content, true) - return err -} diff --git a/internal/pkg/overlay/overlay.go b/internal/pkg/overlay/overlay.go index 4095ffd8..d7f1f84b 100644 --- a/internal/pkg/overlay/overlay.go +++ b/internal/pkg/overlay/overlay.go @@ -71,7 +71,7 @@ func BuildHostOverlay() error { hostname, _ := os.Hostname() hostData := node.NewNode(hostname) wwlog.Info("Building overlay for %s: host", hostname) - hostdir, _ := OverlaySourceDir("host") + hostdir, _ := GetOverlay("host") stats, err := os.Stat(hostdir) if err != nil { return fmt.Errorf("could not build host overlay: %w ", err) @@ -89,10 +89,10 @@ func FindOverlays() (overlayList []string, err error) { dotfilecheck, _ := regexp.Compile(`^\..*`) controller := warewulfconf.Get() var files []fs.DirEntry - if distfiles, err := os.ReadDir(controller.Paths.DistributionOverlaySourcedir()); err == nil { + if distfiles, err := os.ReadDir(controller.Paths.DistributionOverlaydir()); err == nil { files = append(files, distfiles...) } - if sitefiles, err := os.ReadDir(path.Join(controller.Paths.SiteOverlaySourcedir())); err == nil { + if sitefiles, err := os.ReadDir(path.Join(controller.Paths.SiteOverlaydir())); err == nil { files = append(files, sitefiles...) } for _, file := range files { @@ -107,21 +107,6 @@ func FindOverlays() (overlayList []string, err error) { return overlayList, nil } -/* -Creates an empty overlay -*/ -func OverlayInit(overlayName string) error { - controller := warewulfconf.Get() - overlayPath := path.Join(controller.Paths.Sysconfdir, "overlays", overlayName) - if util.IsDir(overlayPath) { - return fmt.Errorf("overlay already exists: %s", overlayName) - } - - err := os.MkdirAll(path.Join(overlayPath, "rootfs"), 0755) - - return err -} - /* Build the given overlays for a node and create a Image for them */ @@ -192,7 +177,7 @@ func BuildOverlayIndir(nodeData node.Node, overlayNames []string, outputDir stri wwlog.Verbose("Processing node/overlay: %s/%s", nodeData.Id(), strings.Join(overlayNames, "-")) for _, overlayName := range overlayNames { wwlog.Verbose("Building overlay %s for node %s in %s", overlayName, nodeData.Id(), outputDir) - overlaySourceDir, _ := OverlaySourceDir(overlayName) + overlaySourceDir, _ := GetOverlay(overlayName) wwlog.Debug("Changing directory to OverlayDir: %s", overlaySourceDir) err := os.Chdir(overlaySourceDir) if err != nil { @@ -431,7 +416,7 @@ func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) { // Get all the files as a string slice for a given overlay func OverlayGetFiles(name string) (files []string, err error) { - baseDir, _ := OverlaySourceDir(name) + baseDir, _ := GetOverlay(name) if !util.IsDir(baseDir) { err = fmt.Errorf("overlay %s doesn't exist", name) return diff --git a/internal/pkg/warewulfd/util.go b/internal/pkg/warewulfd/util.go index 59f916aa..06bcaa5a 100644 --- a/internal/pkg/warewulfd/util.go +++ b/internal/pkg/warewulfd/util.go @@ -54,7 +54,7 @@ func getOverlayFile(n node.Node, context string, stage_overlays []string, autobu build = util.PathIsNewer(stage_file, config.Get().Paths.NodesConf()) for _, overlayname := range stage_overlays { - overlayDir, _ := overlay.OverlaySourceDir(overlayname) + overlayDir, _ := overlay.GetOverlay(overlayname) build = build || util.PathIsNewer(stage_file, overlayDir) } }