Recommended refactors

- make sure spec sets new cache dir
- move clean out of api
- capture warewulfconf.Paths.Cachedir+"/warewulf" in once place
- split Clean() into multiple functions
- remove WriteFileAbs

Signed-off-by: Jonathon Anderson <janderson@ciq.com>
This commit is contained in:
Jonathon Anderson
2024-10-25 17:46:42 -06:00
parent ff84974506
commit fbd5ca9895
11 changed files with 54 additions and 64 deletions

View File

@@ -27,14 +27,13 @@ ifdef PREFIX
endif endif
# System directory paths # System directory paths
VARLIST += PREFIX BINDIR SYSCONFDIR SRVDIR DATADIR MANDIR DOCDIR LOCALSTATEDIR RELEASE VARLIST += PREFIX BINDIR SYSCONFDIR SRVDIR DATADIR MANDIR DOCDIR LOCALSTATEDIR RELEASE CACHEDIR
PREFIX ?= /usr/local PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin BINDIR ?= $(PREFIX)/bin
SYSCONFDIR ?= $(PREFIX)/etc SYSCONFDIR ?= $(PREFIX)/etc
DATADIR ?= $(PREFIX)/share DATADIR ?= $(PREFIX)/share
MANDIR ?= $(DATADIR)/man MANDIR ?= $(DATADIR)/man
DOCDIR ?= $(DATADIR)/doc DOCDIR ?= $(DATADIR)/doc
CACHEDIR ?= /var/cache
ifeq ($(USE_LSB_PATHS),true) ifeq ($(USE_LSB_PATHS),true)
SRVDIR ?= /srv SRVDIR ?= /srv
@@ -43,6 +42,7 @@ else
SRVDIR ?= $(PREFIX)/srv SRVDIR ?= $(PREFIX)/srv
LOCALSTATEDIR ?= $(PREFIX)/var LOCALSTATEDIR ?= $(PREFIX)/var
endif endif
CACHEDIR ?= $(LOCALSTATEDIR)/cache
# OS-Specific Service Locations # OS-Specific Service Locations
VARLIST += TFTPDIR FIREWALLDDIR SYSTEMDDIR BASHCOMPDIR LOGROTATEDIR DRACUTMODDIR VARLIST += TFTPDIR FIREWALLDDIR SYSTEMDDIR BASHCOMPDIR LOGROTATEDIR DRACUTMODDIR

View File

@@ -1,13 +1,19 @@
package clean package clean
import ( import (
"github.com/warewulf/warewulf/internal/pkg/api/clean" "github.com/warewulf/warewulf/internal/pkg/clean"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err error) { func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err error) {
return func(cmd *cobra.Command, args []string) (err error) { return func(cmd *cobra.Command, args []string) (err error) {
return clean.Clean() if err = clean.CleanOciBlobCacheDir(); err != nil {
return err
} else if err = clean.CleanOverlays(); err != nil {
return err
} else {
return nil
}
} }
} }

View File

@@ -1,11 +1,8 @@
package clean package clean
import ( import (
"path"
"testing" "testing"
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/warewulf/warewulf/internal/pkg/testenv" "github.com/warewulf/warewulf/internal/pkg/testenv"
"github.com/warewulf/warewulf/internal/pkg/wwlog" "github.com/warewulf/warewulf/internal/pkg/wwlog"
@@ -20,14 +17,13 @@ nodeprofiles: {}
nodes: nodes:
node1: {} node1: {}
`) `)
wwconf := warewulfconf.Get() env.WriteFile(t, "srv/warewulf/overlays/node1/__SYSTEM__.img", "Fake System")
env.WriteFileAbs(t, path.Join(wwconf.Paths.WWProvisiondir, "overlays/node1/__SYSTEM__.img"), "Fake System") env.WriteFile(t, "srv/warewulf/overlays/node2/__SYSTEM__.img", "Fake System")
env.WriteFileAbs(t, path.Join(wwconf.Paths.WWProvisiondir, "overlays/node2/__SYSTEM__.img"), "Fake System") env.WriteFile(t, "var/cache/warewulf/test", "Nothing to see here")
env.WriteFileAbs(t, path.Join(wwconf.Paths.Cachedir, "warewulf/test"), "Nothing to see here")
baseCmd := GetCommand() baseCmd := GetCommand()
err := baseCmd.Execute() err := baseCmd.Execute()
assert.NoError(t, err) assert.NoError(t, err)
assert.FileExists(t, path.Join(wwconf.Paths.WWProvisiondir, "overlays/node1/__SYSTEM__.img")) assert.FileExists(t, env.GetPath("srv/warewulf/overlays/node1/__SYSTEM__.img"))
assert.NoFileExists(t, path.Join(wwconf.Paths.WWProvisiondir, "overlays/node2/__SYSTEM__.img")) assert.NoFileExists(t, env.GetPath("srv/warewulf/overlays/node2/__SYSTEM__.img"))
assert.NoDirExists(t, path.Join(wwconf.Paths.Cachedir, "warewulf")) assert.NoFileExists(t, env.GetPath("/var/cache/warewulf/test"))
} }

View File

@@ -4,8 +4,6 @@ import (
"os" "os"
"path" "path"
_ "golang.org/x/exp/slices"
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config" warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
"github.com/warewulf/warewulf/internal/pkg/node" "github.com/warewulf/warewulf/internal/pkg/node"
"github.com/warewulf/warewulf/internal/pkg/util" "github.com/warewulf/warewulf/internal/pkg/util"
@@ -15,19 +13,20 @@ import (
/* /*
Cleans up the OCI cache and remains of deleted nodes Cleans up the OCI cache and remains of deleted nodes
*/ */
func Clean() (err error) { func CleanOciBlobCacheDir() error {
warewulfconf := warewulfconf.Get()
wwlog.Verbose("removing oci cache dir: %s", warewulfconf.Paths.OciBlobCachedir())
return os.RemoveAll(warewulfconf.Paths.OciBlobCachedir())
}
func CleanOverlays() error {
warewulfconf := warewulfconf.Get() warewulfconf := warewulfconf.Get()
wwlog.Verbose("removing oci cache dir: %s", path.Join(warewulfconf.Paths.Cachedir+"/warewulf"))
err = os.RemoveAll(path.Join(warewulfconf.Paths.Cachedir + "/warewulf"))
if err != nil {
return err
}
nodeDB, err := node.New() nodeDB, err := node.New()
if err != nil { if err != nil {
return err return err
} }
nodes := nodeDB.ListAllNodes() nodes := nodeDB.ListAllNodes()
dirList, err := os.ReadDir(path.Join(warewulfconf.Paths.WWProvisiondir, "overlays/")) dirList, err := os.ReadDir(warewulfconf.Paths.OverlayProvisiondir())
if err != nil { if err != nil {
return err return err
} }
@@ -37,11 +36,11 @@ func Clean() (err error) {
} }
if !util.InSlice(nodes, item.Name()) { if !util.InSlice(nodes, item.Name()) {
wwlog.Verbose("removing overlays of delete node: %s", item.Name()) wwlog.Verbose("removing overlays of delete node: %s", item.Name())
err = os.RemoveAll(path.Join(warewulfconf.Paths.WWProvisiondir, "overlays/", item.Name())) err = os.RemoveAll(path.Join(warewulfconf.Paths.OverlayProvisiondir(), item.Name()))
if err != nil { if err != nil {
return err return err
} }
} }
} }
return return nil
} }

View File

@@ -1,5 +1,9 @@
package config package config
import (
"path"
)
var ConfigFile = "@SYSCONFDIR@/warewulf/warewulf.conf" var ConfigFile = "@SYSCONFDIR@/warewulf/warewulf.conf"
type BuildConfig struct { type BuildConfig struct {
@@ -43,3 +47,11 @@ type WarewulfConf struct {
DataStore string `yaml:"datastore" default:"@DATADIR@"` DataStore string `yaml:"datastore" default:"@DATADIR@"`
GrubBoot bool `yaml:"grubboot" default:"false"` GrubBoot bool `yaml:"grubboot" default:"false"`
} }
func (paths BuildConfig) OciBlobCachedir() string {
return path.Join(paths.Cachedir, "warewulf")
}
func (paths BuildConfig) OverlayProvisiondir() string {
return path.Join(paths.WWProvisiondir, "overlays")
}

View File

@@ -16,7 +16,7 @@ import (
) )
func ImportDocker(uri string, name string, sCtx *types.SystemContext) error { func ImportDocker(uri string, name string, sCtx *types.SystemContext) error {
OciBlobCacheDir := path.Join(warewulfconf.Get().Paths.Cachedir + "/warewulf") OciBlobCacheDir := warewulfconf.Get().Paths.OciBlobCachedir()
err := os.MkdirAll(OciBlobCacheDir, 0755) err := os.MkdirAll(OciBlobCacheDir, 0755)
if err != nil { if err != nil {

View File

@@ -55,5 +55,5 @@ func OverlayImage(nodeName string, context string, overlayNames []string) string
} }
conf := warewulfconf.Get() conf := warewulfconf.Get()
return path.Join(conf.Paths.WWProvisiondir, "overlays/", nodeName, name) return path.Join(conf.Paths.OverlayProvisiondir(), nodeName, name)
} }

View File

@@ -9,7 +9,6 @@ import (
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"strings"
"testing" "testing"
"time" "time"
@@ -42,7 +41,7 @@ const Systemddir = "usr/lib/systemd/system"
const WWOverlaydir = "var/lib/warewulf/overlays" const WWOverlaydir = "var/lib/warewulf/overlays"
const WWChrootdir = "var/lib/warewulf/chroots" const WWChrootdir = "var/lib/warewulf/chroots"
const WWProvisiondir = "srv/warewulf" const WWProvisiondir = "srv/warewulf"
const Cachedir = "cache" const Cachedir = "var/cache"
// New creates a test environment in a temporary directory and configures // New creates a test environment in a temporary directory and configures
// Warewulf to use it. // Warewulf to use it.
@@ -164,26 +163,3 @@ func (env *TestEnv) RemoveAll(t *testing.T) {
err := os.RemoveAll(env.BaseDir) err := os.RemoveAll(env.BaseDir)
assert.NoError(t, err) assert.NoError(t, err)
} }
// Writes to absolute path, but checks if given file name
// is within testenv.
//
// Asserts no errors occur.
func (env *TestEnv) WriteFileAbs(t *testing.T, fileName string, content string) {
ok := strings.HasPrefix(fileName, env.BaseDir)
if !ok {
assert.Fail(t, "given filename is not in testenv")
}
dirName := filepath.Dir(fileName)
err := os.MkdirAll(dirName, 0755)
assert.NoError(t, err)
f, err := os.Create(fileName)
assert.NoError(t, err)
defer f.Close()
_, err = f.WriteString(content)
assert.NoError(t, err)
err = os.Chtimes(fileName,
time.Date(2006, time.February, 1, 3, 4, 5, 0, time.UTC),
time.Date(2006, time.February, 1, 3, 4, 5, 0, time.UTC))
assert.NoError(t, err)
}

View File

@@ -103,10 +103,10 @@ nodes:
assert.NoError(t, dbErr) assert.NoError(t, dbErr)
conf.Warewulf.Secure = false conf.Warewulf.Secure = false
assert.NoError(t, os.MkdirAll(path.Join(conf.Paths.WWProvisiondir, "overlays", "n1"), 0700)) assert.NoError(t, os.MkdirAll(path.Join(conf.Paths.OverlayProvisiondir(), "n1"), 0700))
assert.NoError(t, os.WriteFile(path.Join(conf.Paths.WWProvisiondir, "overlays", "n1", "__SYSTEM__.img"), []byte("system overlay"), 0600)) assert.NoError(t, os.WriteFile(path.Join(conf.Paths.OverlayProvisiondir(), "n1", "__SYSTEM__.img"), []byte("system overlay"), 0600))
assert.NoError(t, os.WriteFile(path.Join(conf.Paths.WWProvisiondir, "overlays", "n1", "__RUNTIME__.img"), []byte("runtime overlay"), 0600)) assert.NoError(t, os.WriteFile(path.Join(conf.Paths.OverlayProvisiondir(), "n1", "__RUNTIME__.img"), []byte("runtime overlay"), 0600))
assert.NoError(t, os.WriteFile(path.Join(conf.Paths.WWProvisiondir, "overlays", "n1", "o1.img"), []byte("specific overlay"), 0600)) assert.NoError(t, os.WriteFile(path.Join(conf.Paths.OverlayProvisiondir(), "n1", "o1.img"), []byte("specific overlay"), 0600))
wwlog.SetLogLevel(wwlog.DEBUG) wwlog.SetLogLevel(wwlog.DEBUG)
for _, tt := range provisionSendTests { for _, tt := range provisionSendTests {

View File

@@ -37,42 +37,42 @@ var getOverlayFileTests = []struct {
node: "", node: "",
context: "", context: "",
overlays: []string{"o1", "o2"}, overlays: []string{"o1", "o2"},
result: "overlays/node1/o1-o2.img", result: "node1/o1-o2.img",
}, },
{ {
description: "system overlay for a node points to the node's system overlay image", description: "system overlay for a node points to the node's system overlay image",
node: "node1", node: "node1",
context: "system", context: "system",
overlays: []string{"o1"}, overlays: []string{"o1"},
result: "overlays/node1/__SYSTEM__.img", result: "node1/__SYSTEM__.img",
}, },
{ {
description: "runtime overlay for a node points to the node's runtime overlay image", description: "runtime overlay for a node points to the node's runtime overlay image",
node: "node1", node: "node1",
context: "runtime", context: "runtime",
overlays: nil, overlays: nil,
result: "overlays/node1/__RUNTIME__.img", result: "node1/__RUNTIME__.img",
}, },
{ {
description: "a specific overlay for a node points to that specific overlay image for that node", description: "a specific overlay for a node points to that specific overlay image for that node",
node: "node1", node: "node1",
context: "", context: "",
overlays: []string{"o1"}, overlays: []string{"o1"},
result: "overlays/node1/o1.img", result: "node1/o1.img",
}, },
{ {
description: "a specific set of overlays for a node points to a combined overlay image for that node", description: "a specific set of overlays for a node points to a combined overlay image for that node",
node: "node1", node: "node1",
context: "", context: "",
overlays: []string{"o1", "o2"}, overlays: []string{"o1", "o2"},
result: "overlays/node1/o1-o2.img", result: "node1/o1-o2.img",
}, },
{ {
description: "a specific set of overlays for a node while also specifying a context points to the contextual overlay image for that node", description: "a specific set of overlays for a node while also specifying a context points to the contextual overlay image for that node",
node: "node1", node: "node1",
context: "system", context: "system",
overlays: []string{"o1", "o2"}, overlays: []string{"o1", "o2"},
result: "overlays/node1/__SYSTEM__.img", result: "node1/__SYSTEM__.img",
}, },
} }
@@ -96,7 +96,7 @@ nodes:
result, err := getOverlayFile(nodeInfo, tt.context, tt.overlays, false) result, err := getOverlayFile(nodeInfo, tt.context, tt.overlays, false)
assert.NoError(t, err) assert.NoError(t, err)
if tt.result != "" { if tt.result != "" {
tt.result = path.Join(conf.Paths.WWProvisiondir, tt.result) tt.result = path.Join(conf.Paths.OverlayProvisiondir(), tt.result)
} }
assert.Equal(t, tt.result, result) assert.Equal(t, tt.result, result)
}) })

View File

@@ -128,7 +128,8 @@ make defaults \
FIREWALLDDIR=/usr/lib/firewalld/services \ FIREWALLDDIR=/usr/lib/firewalld/services \
WWCLIENTDIR=/warewulf \ WWCLIENTDIR=/warewulf \
IPXESOURCE=/usr/share/ipxe \ IPXESOURCE=/usr/share/ipxe \
DRACUTMODDIR=/usr/lib/dracut/modules.d DRACUTMODDIR=/usr/lib/dracut/modules.d \
CACHEDIR=%{_localstatedir}/cache
make make
%if %{api} %if %{api}
make api make api