overlay.GetOverlay(name) returns now an error if the overlay doesn't exist. This is the most canonical way to act if there is no overlay.
119 lines
3.8 KiB
Go
119 lines
3.8 KiB
Go
package overlay
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/containers/storage/drivers/copy"
|
|
|
|
"github.com/warewulf/warewulf/internal/pkg/config"
|
|
"github.com/warewulf/warewulf/internal/pkg/util"
|
|
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
|
)
|
|
|
|
// GetOverlay returns the filesystem path of an overlay identified by its name,
|
|
func GetOverlay(name string) (overlay Overlay, err error) {
|
|
overlay = getSiteOverlayName(name)
|
|
if overlay.Exists() {
|
|
return overlay, nil
|
|
}
|
|
overlay = getDistributionOverlay(name)
|
|
if overlay.Exists() {
|
|
return overlay, nil
|
|
}
|
|
return "", ErrDoesNotExist
|
|
}
|
|
|
|
// Create creates a new overlay directory for the given overlay
|
|
//
|
|
// Returns an error if the overlay already exists or if directory creation fails.
|
|
func Create(name string) (overlay Overlay, err error) {
|
|
overlay = getSiteOverlayName(name)
|
|
if util.IsDir(overlay.Path()) {
|
|
return overlay, fmt.Errorf("overlay already exists: %s", name)
|
|
}
|
|
wwlog.Verbose("created site overlay under: %s", overlay.Path())
|
|
return overlay, os.MkdirAll(path.Join(overlay.Path(), "rootfs"), 0o755)
|
|
}
|
|
|
|
// GetDistributionOverlay returns the filesystem path of a distribution overlay
|
|
// identified by the given name.
|
|
func getDistributionOverlay(name string) Overlay {
|
|
return Overlay(path.Join(config.Get().Paths.DistributionOverlaydir(), name))
|
|
}
|
|
|
|
// GetSiteOverlay returns the filesystem path of a site-specific overlay
|
|
// identified by the given name.
|
|
func getSiteOverlayName(name string) (overlay Overlay) {
|
|
return Overlay(path.Join(config.Get().Paths.SiteOverlaydir(), name))
|
|
}
|
|
|
|
// Creates a site overlay from an existing distribution overlay.
|
|
//
|
|
// If the distribution overlay doesn't exist, return an error.
|
|
func (overlay Overlay) CloneSiteOverlay() (siteOverlay Overlay, err error) {
|
|
wwlog.Verbose("Creating site overlay: %s", overlay.Name())
|
|
siteOverlay = getSiteOverlayName(overlay.Name())
|
|
if !util.IsDir(overlay.Path()) {
|
|
return siteOverlay, fmt.Errorf("source overlay does not exist: %s", overlay.Name())
|
|
}
|
|
if siteOverlay.Exists() {
|
|
return siteOverlay, nil
|
|
}
|
|
if !util.IsDir(filepath.Dir(siteOverlay.Path())) {
|
|
if err := os.MkdirAll(filepath.Dir(siteOverlay.Path()), 0o755); err != nil {
|
|
return siteOverlay, err
|
|
}
|
|
}
|
|
err = copy.DirCopy(overlay.Path(), siteOverlay.Path(), copy.Content, true)
|
|
return siteOverlay, err
|
|
}
|
|
|
|
// OverlayImage returns the full path to an overlay image based on the
|
|
// context and the overlays contained in it.
|
|
//
|
|
// If a context is provided, the image file name is based on that
|
|
// context name, in the form __{CONTEXT}__.
|
|
//
|
|
// If the context is empty ("") the image file name is a concatenated
|
|
// list of the contained overlays joined by "-".
|
|
//
|
|
// If the context is empty and no overlays are specified, the empty
|
|
// string is returned.
|
|
func OverlayImage(nodeName string, context string, overlayNames []string) string {
|
|
var name string
|
|
if context != "" {
|
|
if len(overlayNames) > 0 {
|
|
wwlog.Debug("context(%v) and overlays(%v) specified: prioritizing context(%v)",
|
|
context, overlayNames, context)
|
|
}
|
|
name = "__" + strings.ToUpper(context) + "__.img"
|
|
} else if len(overlayNames) > 0 {
|
|
name = strings.Join(overlayNames, "-") + ".img"
|
|
} else {
|
|
wwlog.Warn("unable to generate overlay image path: no context or overlays specified")
|
|
return ""
|
|
}
|
|
|
|
return path.Join(config.Get().Paths.OverlayProvisiondir(), nodeName, name)
|
|
}
|
|
|
|
func ClearOverlayImage(nodeName string, context string, overlayNames []string) error {
|
|
imagePath := OverlayImage(nodeName, context, overlayNames)
|
|
if util.IsFile(imagePath) {
|
|
if err := os.Remove(imagePath); err != nil {
|
|
return fmt.Errorf("failed to remove overlay image: %w", err)
|
|
}
|
|
}
|
|
compressedImagePath := imagePath + ".gz"
|
|
if util.IsFile(compressedImagePath) {
|
|
if err := os.Remove(compressedImagePath); err != nil {
|
|
return fmt.Errorf("failed to remove compressed overlay image: %w", err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|