Merge pull request #1395 from mslacken/FixPanicContList
Fix panic when getting a long container list before building the container
This commit is contained in:
@@ -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
|
- Return non-zero exit code on container sub-commands #1414
|
||||||
- Fix excessive line spacing issue when listing nodes. #1241
|
- Fix excessive line spacing issue when listing nodes. #1241
|
||||||
- Return non-zero exit code on node sub-commands #1421
|
- 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
|
## v4.5.8, unreleased
|
||||||
|
|
||||||
|
|||||||
4
Makefile
4
Makefile
@@ -82,13 +82,13 @@ vet: $(config)
|
|||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test: $(config)
|
test: $(config)
|
||||||
go test ./...
|
TZ=UTC go test ./...
|
||||||
|
|
||||||
.PHONY: test-cover
|
.PHONY: test-cover
|
||||||
test-cover: $(config)
|
test-cover: $(config)
|
||||||
rm -rf coverage
|
rm -rf coverage
|
||||||
mkdir coverage
|
mkdir coverage
|
||||||
go list -f '{{if gt (len .TestGoFiles) 0}}"go test -covermode count -coverprofile {{.Name}}.coverprofile -coverpkg ./... {{.ImportPath}}"{{end}}' ./... | xargs -I {} bash -c {}
|
go list -f '{{if gt (len .TestGoFiles) 0}}"TZ=UTC go test -covermode count -coverprofile {{.Name}}.coverprofile -coverpkg ./... {{.ImportPath}}"{{end}}' ./... | xargs -I {} bash -c {}
|
||||||
echo "mode: count" >coverage/cover.out
|
echo "mode: count" >coverage/cover.out
|
||||||
grep -h -v "^mode:" *.coverprofile >>"coverage/cover.out"
|
grep -h -v "^mode:" *.coverprofile >>"coverage/cover.out"
|
||||||
rm *.coverprofile
|
rm *.coverprofile
|
||||||
|
|||||||
@@ -4,68 +4,57 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1"
|
"github.com/warewulf/warewulf/internal/pkg/testenv"
|
||||||
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
|
|
||||||
"github.com/warewulf/warewulf/internal/pkg/node"
|
|
||||||
"github.com/warewulf/warewulf/internal/pkg/warewulfd"
|
"github.com/warewulf/warewulf/internal/pkg/warewulfd"
|
||||||
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
"github.com/warewulf/warewulf/internal/pkg/wwlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_List(t *testing.T) {
|
func Test_List_Args(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
args []string
|
||||||
args []string
|
output string
|
||||||
stdout string
|
fail bool
|
||||||
inDb string
|
|
||||||
mockFunc func()
|
|
||||||
}{
|
}{
|
||||||
{
|
{args: []string{""},
|
||||||
name: "container list test",
|
output: ` CONTAINER NAME
|
||||||
args: []string{"-l"},
|
test
|
||||||
stdout: `test 1 kernel`,
|
|
||||||
inDb: `WW_INTERNAL: 45
|
|
||||||
nodeprofiles:
|
|
||||||
default: {}
|
|
||||||
nodes:
|
|
||||||
n01:
|
|
||||||
profiles:
|
|
||||||
- default
|
|
||||||
`,
|
`,
|
||||||
mockFunc: func() {
|
fail: false,
|
||||||
containerList = func() (containerInfo []*wwapiv1.ContainerInfo, err error) {
|
},
|
||||||
containerInfo = append(containerInfo, &wwapiv1.ContainerInfo{
|
{args: []string{"-l"},
|
||||||
Name: "test",
|
output: ` CONTAINER NAME NODES KERNEL VERSION CREATION TIME MODIFICATION TIME SIZE
|
||||||
NodeCount: 1,
|
test 0 02 Jan 00 03:04 UTC 01 Jan 70 00:00 UTC 0 B
|
||||||
KernelVersion: "kernel",
|
`,
|
||||||
CreateDate: uint64(time.Unix(0, 0).Unix()),
|
fail: false,
|
||||||
ModDate: uint64(time.Unix(0, 0).Unix()),
|
},
|
||||||
Size: uint64(1),
|
{args: []string{"-c"},
|
||||||
})
|
output: ` CONTAINER NAME NODES SIZE
|
||||||
return
|
test 0 37 B
|
||||||
}
|
`,
|
||||||
},
|
fail: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
env := testenv.New(t)
|
||||||
conf_yml := `
|
env.WriteFile(t, path.Join(testenv.WWChrootdir, "test/rootfs/bin/sh"), `This is a fake shell, no pearls here.`)
|
||||||
WW_INTERNAL: 0
|
// 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
|
||||||
conf := warewulfconf.Get()
|
// so we have to make it constant *after* its creation.
|
||||||
err := conf.Parse([]byte(conf_yml))
|
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)
|
assert.NoError(t, err)
|
||||||
|
defer env.RemoveAll(t)
|
||||||
warewulfd.SetNoDaemon()
|
warewulfd.SetNoDaemon()
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
_, err = node.Parse([]byte(tt.inDb))
|
t.Run(strings.Join(tt.args, "_"), func(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
|
||||||
t.Logf("Running test: %s\n", tt.name)
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
tt.mockFunc()
|
|
||||||
baseCmd := GetCommand()
|
baseCmd := GetCommand()
|
||||||
baseCmd.SetArgs(tt.args)
|
baseCmd.SetArgs(tt.args)
|
||||||
stdoutR, stdoutW, _ := os.Pipe()
|
stdoutR, stdoutW, _ := os.Pipe()
|
||||||
@@ -73,10 +62,11 @@ WW_INTERNAL: 0
|
|||||||
wwlog.SetLogWriter(os.Stdout)
|
wwlog.SetLogWriter(os.Stdout)
|
||||||
baseCmd.SetOut(os.Stdout)
|
baseCmd.SetOut(os.Stdout)
|
||||||
baseCmd.SetErr(os.Stdout)
|
baseCmd.SetErr(os.Stdout)
|
||||||
err = baseCmd.Execute()
|
err := baseCmd.Execute()
|
||||||
if err != nil {
|
if tt.fail {
|
||||||
t.Errorf("Received error when running command, err: %v", err)
|
assert.Error(t, err)
|
||||||
t.FailNow()
|
} else {
|
||||||
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
stdoutC := make(chan string)
|
stdoutC := make(chan string)
|
||||||
go func() {
|
go func() {
|
||||||
@@ -85,13 +75,12 @@ WW_INTERNAL: 0
|
|||||||
stdoutC <- buf.String()
|
stdoutC <- buf.String()
|
||||||
}()
|
}()
|
||||||
stdoutW.Close()
|
stdoutW.Close()
|
||||||
|
|
||||||
stdout := <-stdoutC
|
stdout := <-stdoutC
|
||||||
assert.NotEmpty(t, stdout, "os.stdout should not be empty")
|
assert.Equal(t, tt.output, stdout)
|
||||||
if !strings.Contains(stdout, tt.stdout) {
|
assert.Equal(t,
|
||||||
t.Errorf("Got wrong output, got:\n '%s'\n, but want:\n '%s'\n", stdout, tt.stdout)
|
strings.ReplaceAll(strings.TrimSpace(tt.output), " ", ""),
|
||||||
t.FailNow()
|
strings.ReplaceAll(strings.TrimSpace(stdout), " ", ""))
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,5 @@ func GetCommand() *cobra.Command {
|
|||||||
baseCmd.PersistentFlags().BoolVarP(&vars.size, "size", "s", false, "show size information")
|
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().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().BoolVar(&vars.compressed, "compressed", false, "show size of the compressed image")
|
||||||
|
|
||||||
return baseCmd
|
return baseCmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -318,6 +318,7 @@ func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) {
|
|||||||
_, kernelVersion, _ := kernel.FindKernel(container.RootFsDir(source))
|
_, kernelVersion, _ := kernel.FindKernel(container.RootFsDir(source))
|
||||||
var creationTime uint64
|
var creationTime uint64
|
||||||
sourceStat, err := os.Stat(container.SourceDir(source))
|
sourceStat, err := os.Stat(container.SourceDir(source))
|
||||||
|
wwlog.Debug("Checking creation time for: %s,%v", container.SourceDir(source), sourceStat.ModTime())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
wwlog.Error("%s\n", err)
|
wwlog.Error("%s\n", err)
|
||||||
} else {
|
} else {
|
||||||
@@ -332,13 +333,13 @@ func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
wwlog.Error("%s\n", err)
|
wwlog.Error("%s\n", err)
|
||||||
}
|
}
|
||||||
imgF, err := os.Stat(container.ImageFile(source))
|
imgSize := 0
|
||||||
if err != nil {
|
if imgF, err := os.Stat(container.ImageFile(source)); err == nil {
|
||||||
wwlog.Error("%s\n", err)
|
imgSize = int(imgF.Size())
|
||||||
}
|
}
|
||||||
imgFC, err := os.Stat(container.ImageFile(source) + ".gz")
|
imgCSize := 0
|
||||||
if err != nil {
|
if imgFC, err := os.Stat(container.ImageFile(source) + ".gz"); err == nil {
|
||||||
wwlog.Error("%s\n", err)
|
imgCSize = int(imgFC.Size())
|
||||||
}
|
}
|
||||||
containerInfo = append(containerInfo, &wwapiv1.ContainerInfo{
|
containerInfo = append(containerInfo, &wwapiv1.ContainerInfo{
|
||||||
Name: source,
|
Name: source,
|
||||||
@@ -347,8 +348,8 @@ func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) {
|
|||||||
CreateDate: creationTime,
|
CreateDate: creationTime,
|
||||||
ModDate: modTime,
|
ModDate: modTime,
|
||||||
Size: uint64(size),
|
Size: uint64(size),
|
||||||
ImgSize: uint64(imgF.Size()),
|
ImgSize: uint64(imgSize),
|
||||||
ImgSizeComp: uint64(imgFC.Size()),
|
ImgSizeComp: uint64(imgCSize),
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
|
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()
|
defer f.Close()
|
||||||
_, err = f.WriteString(content)
|
_, err = f.WriteString(content)
|
||||||
assert.NoError(t, err)
|
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
|
// ReadFile returns the content of fileName as converted to a
|
||||||
|
|||||||
Reference in New Issue
Block a user