added wwctl clean to remove cache/dead overlays
Signed-off-by: Christian Goll <cgoll@suse.com>
This commit is contained in:
committed by
Jonathon Anderson
parent
511938ac5c
commit
ff84974506
@@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Add support to render template using `host` or `$(uname -n)` as the value of `overlay show --render`. #623
|
||||
- Added command line parameters for credentials of a container registry
|
||||
- Add flag `--build` to `wwctl container copy`. #1378
|
||||
- Add `wwctl clean` to remove OCI cache and overlays from deleted nodes
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
13
internal/app/wwctl/clean/main.go
Normal file
13
internal/app/wwctl/clean/main.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package clean
|
||||
|
||||
import (
|
||||
"github.com/warewulf/warewulf/internal/pkg/api/clean"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err error) {
|
||||
return func(cmd *cobra.Command, args []string) (err error) {
|
||||
return clean.Clean()
|
||||
}
|
||||
}
|
||||
33
internal/app/wwctl/clean/main_test.go
Normal file
33
internal/app/wwctl/clean/main_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package clean
|
||||
|
||||
import (
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/warewulf/warewulf/internal/pkg/testenv"
|
||||
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
||||
)
|
||||
|
||||
func Test_Clean(t *testing.T) {
|
||||
wwlog.SetLogLevel(wwlog.DEBUG)
|
||||
env := testenv.New(t)
|
||||
env.WriteFile(t, "etc/warewulf/nodes.conf",
|
||||
`WW_INTERNAL: 45
|
||||
nodeprofiles: {}
|
||||
nodes:
|
||||
node1: {}
|
||||
`)
|
||||
wwconf := warewulfconf.Get()
|
||||
env.WriteFileAbs(t, path.Join(wwconf.Paths.WWProvisiondir, "overlays/node1/__SYSTEM__.img"), "Fake System")
|
||||
env.WriteFileAbs(t, path.Join(wwconf.Paths.WWProvisiondir, "overlays/node2/__SYSTEM__.img"), "Fake System")
|
||||
env.WriteFileAbs(t, path.Join(wwconf.Paths.Cachedir, "warewulf/test"), "Nothing to see here")
|
||||
baseCmd := GetCommand()
|
||||
err := baseCmd.Execute()
|
||||
assert.NoError(t, err)
|
||||
assert.FileExists(t, path.Join(wwconf.Paths.WWProvisiondir, "overlays/node1/__SYSTEM__.img"))
|
||||
assert.NoFileExists(t, path.Join(wwconf.Paths.WWProvisiondir, "overlays/node2/__SYSTEM__.img"))
|
||||
assert.NoDirExists(t, path.Join(wwconf.Paths.Cachedir, "warewulf"))
|
||||
}
|
||||
20
internal/app/wwctl/clean/root.go
Normal file
20
internal/app/wwctl/clean/root.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package clean
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type variables struct {
|
||||
}
|
||||
|
||||
func GetCommand() *cobra.Command {
|
||||
vars := variables{}
|
||||
baseCmd := &cobra.Command{
|
||||
DisableFlagsInUseLine: true,
|
||||
Use: "clean",
|
||||
Short: "Clean up",
|
||||
Long: "This command cleans the OCI cache and removes leftovers from deleted nodes",
|
||||
RunE: CobraRunE(&vars),
|
||||
}
|
||||
return baseCmd
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/warewulf/warewulf/internal/app/wwctl/clean"
|
||||
"github.com/warewulf/warewulf/internal/app/wwctl/configure"
|
||||
"github.com/warewulf/warewulf/internal/app/wwctl/container"
|
||||
"github.com/warewulf/warewulf/internal/app/wwctl/genconf"
|
||||
@@ -58,6 +59,7 @@ func init() {
|
||||
rootCmd.AddCommand(version.GetCommand())
|
||||
rootCmd.AddCommand(ssh.GetCommand())
|
||||
rootCmd.AddCommand(genconf.GetCommand())
|
||||
rootCmd.AddCommand(clean.GetCommand())
|
||||
}
|
||||
|
||||
// GetRootCommand returns the root cobra.Command for the application.
|
||||
|
||||
47
internal/pkg/api/clean/Clean.go
Normal file
47
internal/pkg/api/clean/Clean.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package clean
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
_ "golang.org/x/exp/slices"
|
||||
|
||||
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
|
||||
"github.com/warewulf/warewulf/internal/pkg/node"
|
||||
"github.com/warewulf/warewulf/internal/pkg/util"
|
||||
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
||||
)
|
||||
|
||||
/*
|
||||
Cleans up the OCI cache and remains of deleted nodes
|
||||
*/
|
||||
func Clean() (err error) {
|
||||
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()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nodes := nodeDB.ListAllNodes()
|
||||
dirList, err := os.ReadDir(path.Join(warewulfconf.Paths.WWProvisiondir, "overlays/"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range dirList {
|
||||
if !item.IsDir() {
|
||||
continue
|
||||
}
|
||||
if !util.InSlice(nodes, item.Name()) {
|
||||
wwlog.Verbose("removing overlays of delete node: %s", item.Name())
|
||||
err = os.RemoveAll(path.Join(warewulfconf.Paths.WWProvisiondir, "overlays/", item.Name()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -41,6 +42,7 @@ const Systemddir = "usr/lib/systemd/system"
|
||||
const WWOverlaydir = "var/lib/warewulf/overlays"
|
||||
const WWChrootdir = "var/lib/warewulf/chroots"
|
||||
const WWProvisiondir = "srv/warewulf"
|
||||
const Cachedir = "cache"
|
||||
|
||||
// New creates a test environment in a temporary directory and configures
|
||||
// Warewulf to use it.
|
||||
@@ -76,6 +78,7 @@ func New(t *testing.T) (env *TestEnv) {
|
||||
conf.Paths.WWOverlaydir = env.GetPath(WWOverlaydir)
|
||||
conf.Paths.WWChrootdir = env.GetPath(WWChrootdir)
|
||||
conf.Paths.WWProvisiondir = env.GetPath(WWProvisiondir)
|
||||
conf.Paths.Cachedir = env.GetPath(Cachedir)
|
||||
conf.Paths.WWClientdir = "/warewulf"
|
||||
|
||||
for _, confPath := range []string{
|
||||
@@ -161,3 +164,26 @@ func (env *TestEnv) RemoveAll(t *testing.T) {
|
||||
err := os.RemoveAll(env.BaseDir)
|
||||
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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user