Skip to content

Commit

Permalink
Merge pull request warewulf#1395 from mslacken/FixPanicContList
Browse files Browse the repository at this point in the history
Fix panic when getting a long container list before building the container
  • Loading branch information
anderbubble authored Sep 27, 2024
2 parents c0c93b1 + 8d4cb37 commit acfbdbc
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 67 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ vet: $(config)

.PHONY: test
test: $(config)
go test ./...
TZ=UTC go test ./...

.PHONY: test-cover
test-cover: $(config)
rm -rf 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
grep -h -v "^mode:" *.coverprofile >>"coverage/cover.out"
rm *.coverprofile
Expand Down
101 changes: 45 additions & 56 deletions internal/app/wwctl/container/list/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,79 +4,69 @@ 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{"-l"},
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()
os.Stdout = stdoutW
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() {
Expand All @@ -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), " ", ""))

})
}
}
1 change: 0 additions & 1 deletion internal/app/wwctl/container/list/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,5 @@ 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")

return baseCmd
}
17 changes: 9 additions & 8 deletions internal/pkg/api/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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,
Expand All @@ -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),
})

}
Expand Down
5 changes: 5 additions & 0 deletions internal/pkg/testenv/testenv.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"path"
"path/filepath"
"testing"
"time"

warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit acfbdbc

Please sign in to comment.