no panic if listing non existing container image

Signed-off-by: Christian Goll <cgoll@suse.com>
This commit is contained in:
Christian Goll
2024-09-16 12:10:51 +02:00
committed by Jonathon Anderson
parent c0c93b153a
commit 883de9c4fc
6 changed files with 66 additions and 65 deletions

View File

@@ -46,6 +46,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Return non-zero exit code on container sub-commands #1414
- Fix excessive line spacing issue when listing nodes. #1241
- Return non-zero exit code on node sub-commands #1421
- Fix panic when getting a long container list before building the container. #1391
## v4.5.8, unreleased

View File

@@ -27,6 +27,10 @@ func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err err
for i := 0; i < len(containerInfo); i++ {
createTime := time.Unix(int64(containerInfo[i].CreateDate), 0)
modTime := time.Unix(int64(containerInfo[i].ModDate), 0)
if vars.utc {
createTime = createTime.UTC()
modTime = modTime.UTC()
}
sz := util.ByteToString(int64(containerInfo[i].ImgSize))
if vars.compressed {
sz = util.ByteToString(int64(containerInfo[i].ImgSizeComp))

View File

@@ -4,68 +4,57 @@ import (
"bytes"
"io"
"os"
"os/exec"
"path"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1"
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
"github.com/warewulf/warewulf/internal/pkg/node"
"github.com/warewulf/warewulf/internal/pkg/testenv"
"github.com/warewulf/warewulf/internal/pkg/warewulfd"
"github.com/warewulf/warewulf/internal/pkg/wwlog"
)
func Test_List(t *testing.T) {
func Test_List_Args(t *testing.T) {
tests := []struct {
name string
args []string
stdout string
inDb string
mockFunc func()
args []string
output string
fail bool
}{
{
name: "container list test",
args: []string{"-l"},
stdout: `test 1 kernel`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
default: {}
nodes:
n01:
profiles:
- default
{args: []string{""},
output: ` CONTAINER NAME
test
`,
mockFunc: func() {
containerList = func() (containerInfo []*wwapiv1.ContainerInfo, err error) {
containerInfo = append(containerInfo, &wwapiv1.ContainerInfo{
Name: "test",
NodeCount: 1,
KernelVersion: "kernel",
CreateDate: uint64(time.Unix(0, 0).Unix()),
ModDate: uint64(time.Unix(0, 0).Unix()),
Size: uint64(1),
})
return
}
},
fail: false,
},
{args: []string{"-ul"},
output: ` CONTAINER NAME NODES KERNEL VERSION CREATION TIME MODIFICATION TIME SIZE
test 0 02 Jan 00 03:04 UTC 01 Jan 70 00:00 UTC 0 B
`,
fail: false,
},
{args: []string{"-c"},
output: ` CONTAINER NAME NODES SIZE
test 0 37 B
`,
fail: false,
},
}
conf_yml := `
WW_INTERNAL: 0
`
conf := warewulfconf.Get()
err := conf.Parse([]byte(conf_yml))
env := testenv.New(t)
env.WriteFile(t, path.Join(testenv.WWChrootdir, "test/rootfs/bin/sh"), `This is a fake shell, no pearls here.`)
// need to touch the files, so that the creation date of the container is constant,
// modification date of `../chroots/containername` is used as creation date.
// modification dates of directories change every time a file or subdir is added
// so we have to make it constant *after* its creation.
cmd := exec.Command("touch", "-d", "2000-01-02 03:04:05 UTC",
env.GetPath(path.Join(testenv.WWChrootdir, "test/rootfs")),
env.GetPath(path.Join(testenv.WWChrootdir, "test")))
err := cmd.Run()
assert.NoError(t, err)
defer env.RemoveAll(t)
warewulfd.SetNoDaemon()
for _, tt := range tests {
_, err = node.Parse([]byte(tt.inDb))
assert.NoError(t, err)
t.Logf("Running test: %s\n", tt.name)
t.Run(tt.name, func(t *testing.T) {
tt.mockFunc()
t.Run(strings.Join(tt.args, "_"), func(t *testing.T) {
baseCmd := GetCommand()
baseCmd.SetArgs(tt.args)
stdoutR, stdoutW, _ := os.Pipe()
@@ -73,10 +62,11 @@ WW_INTERNAL: 0
wwlog.SetLogWriter(os.Stdout)
baseCmd.SetOut(os.Stdout)
baseCmd.SetErr(os.Stdout)
err = baseCmd.Execute()
if err != nil {
t.Errorf("Received error when running command, err: %v", err)
t.FailNow()
err := baseCmd.Execute()
if tt.fail {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
stdoutC := make(chan string)
go func() {
@@ -85,13 +75,12 @@ WW_INTERNAL: 0
stdoutC <- buf.String()
}()
stdoutW.Close()
stdout := <-stdoutC
assert.NotEmpty(t, stdout, "os.stdout should not be empty")
if !strings.Contains(stdout, tt.stdout) {
t.Errorf("Got wrong output, got:\n '%s'\n, but want:\n '%s'\n", stdout, tt.stdout)
t.FailNow()
}
assert.Equal(t, tt.output, stdout)
assert.Equal(t,
strings.ReplaceAll(strings.TrimSpace(tt.output), " ", ""),
strings.ReplaceAll(strings.TrimSpace(stdout), " ", ""))
})
}
}

View File

@@ -10,6 +10,7 @@ type variables struct {
kernel bool
chroot bool
compressed bool
utc bool
}
// GetRootCommand returns the root cobra.Command for the application.
@@ -28,6 +29,6 @@ func GetCommand() *cobra.Command {
baseCmd.PersistentFlags().BoolVarP(&vars.size, "size", "s", false, "show size information")
baseCmd.PersistentFlags().BoolVarP(&vars.chroot, "chroot", "c", false, "show size of chroot")
baseCmd.PersistentFlags().BoolVar(&vars.compressed, "compressed", false, "show size of the compressed image")
baseCmd.PersistentFlags().BoolVarP(&vars.utc, "utc", "u", false, "use UTC for time output")
return baseCmd
}

View File

@@ -318,6 +318,7 @@ func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) {
_, kernelVersion, _ := kernel.FindKernel(container.RootFsDir(source))
var creationTime uint64
sourceStat, err := os.Stat(container.SourceDir(source))
wwlog.Debug("Checking creation time for: %s,%v", container.SourceDir(source), sourceStat.ModTime())
if err != nil {
wwlog.Error("%s\n", err)
} else {
@@ -332,13 +333,13 @@ func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) {
if err != nil {
wwlog.Error("%s\n", err)
}
imgF, err := os.Stat(container.ImageFile(source))
if err != nil {
wwlog.Error("%s\n", err)
imgSize := 0
if imgF, err := os.Stat(container.ImageFile(source)); err == nil {
imgSize = int(imgF.Size())
}
imgFC, err := os.Stat(container.ImageFile(source) + ".gz")
if err != nil {
wwlog.Error("%s\n", err)
imgCSize := 0
if imgFC, err := os.Stat(container.ImageFile(source) + ".gz"); err == nil {
imgCSize = int(imgFC.Size())
}
containerInfo = append(containerInfo, &wwapiv1.ContainerInfo{
Name: source,
@@ -347,8 +348,8 @@ func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) {
CreateDate: creationTime,
ModDate: modTime,
Size: uint64(size),
ImgSize: uint64(imgF.Size()),
ImgSizeComp: uint64(imgFC.Size()),
ImgSize: uint64(imgSize),
ImgSizeComp: uint64(imgCSize),
})
}

View File

@@ -10,6 +10,7 @@ import (
"path"
"path/filepath"
"testing"
"time"
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
@@ -131,6 +132,10 @@ func (env *TestEnv) WriteFile(t *testing.T, fileName string, content string) {
defer f.Close()
_, err = f.WriteString(content)
assert.NoError(t, err)
err = os.Chtimes(env.GetPath(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)
}
// ReadFile returns the content of fileName as converted to a