diff --git a/pkg/cluster/internal/providers/docker/provider.go b/pkg/cluster/internal/providers/docker/provider.go index b1786fbc..f840e5a9 100644 --- a/pkg/cluster/internal/providers/docker/provider.go +++ b/pkg/cluster/internal/providers/docker/provider.go @@ -254,34 +254,20 @@ func (p *provider) CollectLogs(dir string, nodes []nodes.Node) error { filepath.Join(dir, "docker-info.txt"), ), } - - // collect /var/log for each node and plan collecting more logs - var errs []error + // inspect each node for _, n := range nodes { node := n // https://golang.org/doc/faq#closures_and_goroutines name := node.String() path := filepath.Join(dir, name) - if err := internallogs.DumpDir(p.logger, node, "/var/log", path); err != nil { - errs = append(errs, err) - } - + fns = append(fns, func() error { + return internallogs.DumpDir(p.logger, node, "/var/log", path) + }) fns = append(fns, - func() error { return common.CollectLogs(node, path) }, execToPathFn(exec.Command("docker", "inspect", name), filepath.Join(path, "inspect.json")), - func() error { - f, err := common.FileOnHost(filepath.Join(path, "serial.log")) - if err != nil { - return err - } - defer f.Close() - return node.SerialLogs(f) - }, ) } - // run and collect up all errors - errs = append(errs, errors.AggregateConcurrent(fns)) - return errors.NewAggregate(errs) + return errors.AggregateConcurrent(fns) } // Info returns the provider info. diff --git a/pkg/cluster/internal/providers/nerdctl/provider.go b/pkg/cluster/internal/providers/nerdctl/provider.go index 0c79316f..71eb4166 100644 --- a/pkg/cluster/internal/providers/nerdctl/provider.go +++ b/pkg/cluster/internal/providers/nerdctl/provider.go @@ -30,7 +30,6 @@ import ( "sigs.k8s.io/kind/pkg/exec" "sigs.k8s.io/kind/pkg/log" - internallogs "sigs.k8s.io/kind/pkg/cluster/internal/logs" "sigs.k8s.io/kind/pkg/cluster/internal/providers" "sigs.k8s.io/kind/pkg/cluster/internal/providers/common" "sigs.k8s.io/kind/pkg/cluster/nodeutils" @@ -302,34 +301,17 @@ func (p *provider) CollectLogs(dir string, nodes []nodes.Node) error { filepath.Join(dir, "docker-info.txt"), ), } - - // collect /var/log for each node and plan collecting more logs - var errs []error + // inspect each node for _, n := range nodes { node := n // https://golang.org/doc/faq#closures_and_goroutines name := node.String() path := filepath.Join(dir, name) - if err := internallogs.DumpDir(p.logger, node, "/var/log", path); err != nil { - errs = append(errs, err) - } - fns = append(fns, - func() error { return common.CollectLogs(node, path) }, execToPathFn(exec.Command(p.Binary(), "inspect", name), filepath.Join(path, "inspect.json")), - func() error { - f, err := common.FileOnHost(filepath.Join(path, "serial.log")) - if err != nil { - return err - } - defer f.Close() - return node.SerialLogs(f) - }, ) } - // run and collect up all errors - errs = append(errs, errors.AggregateConcurrent(fns)) - return errors.NewAggregate(errs) + return errors.AggregateConcurrent(fns) } // Info returns the provider info. diff --git a/pkg/cluster/internal/providers/podman/provider.go b/pkg/cluster/internal/providers/podman/provider.go index fa311617..e4d105e2 100644 --- a/pkg/cluster/internal/providers/podman/provider.go +++ b/pkg/cluster/internal/providers/podman/provider.go @@ -31,7 +31,6 @@ import ( "sigs.k8s.io/kind/pkg/exec" "sigs.k8s.io/kind/pkg/log" - internallogs "sigs.k8s.io/kind/pkg/cluster/internal/logs" "sigs.k8s.io/kind/pkg/cluster/internal/providers" "sigs.k8s.io/kind/pkg/cluster/internal/providers/common" "sigs.k8s.io/kind/pkg/internal/apis/config" @@ -336,33 +335,17 @@ func (p *provider) CollectLogs(dir string, nodes []nodes.Node) error { filepath.Join(dir, "podman-info.txt"), ), } - - // collect /var/log for each node and plan collecting more logs - var errs []error + // inspect each node for _, n := range nodes { node := n // https://golang.org/doc/faq#closures_and_goroutines name := node.String() path := filepath.Join(dir, name) - if err := internallogs.DumpDir(p.logger, node, "/var/log", path); err != nil { - errs = append(errs, err) - } - fns = append(fns, - func() error { return common.CollectLogs(node, path) }, execToPathFn(exec.Command("podman", "inspect", name), filepath.Join(path, "inspect.json")), - func() error { - f, err := common.FileOnHost(filepath.Join(path, "serial.log")) - if err != nil { - return err - } - return node.SerialLogs(f) - }, ) } - // run and collect up all errors - errs = append(errs, errors.AggregateConcurrent(fns)) - return errors.NewAggregate(errs) + return errors.AggregateConcurrent(fns) } // Info returns the provider info. diff --git a/pkg/cluster/provider.go b/pkg/cluster/provider.go index f5c68e42..2c88e772 100644 --- a/pkg/cluster/provider.go +++ b/pkg/cluster/provider.go @@ -32,7 +32,9 @@ import ( internalcreate "sigs.k8s.io/kind/pkg/cluster/internal/create" internaldelete "sigs.k8s.io/kind/pkg/cluster/internal/delete" "sigs.k8s.io/kind/pkg/cluster/internal/kubeconfig" + internallogs "sigs.k8s.io/kind/pkg/cluster/internal/logs" internalproviders "sigs.k8s.io/kind/pkg/cluster/internal/providers" + "sigs.k8s.io/kind/pkg/cluster/internal/providers/common" "sigs.k8s.io/kind/pkg/cluster/internal/providers/docker" "sigs.k8s.io/kind/pkg/cluster/internal/providers/nerdctl" "sigs.k8s.io/kind/pkg/cluster/internal/providers/podman" @@ -236,14 +238,16 @@ func (p *Provider) ListInternalNodes(name string) ([]nodes.Node, error) { func (p *Provider) CollectLogs(name, dir string) error { // TODO: should use ListNodes and Collect should handle nodes differently // based on role ... - n, err := p.ListInternalNodes(name) + internalNodes, err := p.ListInternalNodes(name) if err != nil { return err } + // ensure directory if err := os.MkdirAll(dir, os.ModePerm); err != nil { return errors.Wrap(err, "failed to create logs directory") } + // write kind version if err := os.WriteFile( filepath.Join(dir, "kind-version.txt"), @@ -252,6 +256,34 @@ func (p *Provider) CollectLogs(name, dir string) error { ); err != nil { return errors.Wrap(err, "failed to write kind-version.txt") } - // collect and write cluster logs - return p.provider.CollectLogs(dir, n) + + // common portable log collection for the nodes + fns := []func() error{} + var errs []error + for _, n := range internalNodes { + node := n // https://golang.org/doc/faq#closures_and_goroutines + name := node.String() + path := filepath.Join(dir, name) + fns = append(fns, func() error { + return internallogs.DumpDir(p.logger, node, "/var/log", path) + }) + fns = append(fns, + func() error { return common.CollectLogs(node, path) }, + func() error { + f, err := common.FileOnHost(filepath.Join(path, "serial.log")) + if err != nil { + return err + } + defer f.Close() + return node.SerialLogs(f) + }, + ) + } + errs = append(errs, errors.AggregateConcurrent(fns)) + + // additional, provider specific log collection + errs = append(errs, p.provider.CollectLogs(dir, internalNodes)) + + // flatten + return errors.NewAggregate(errs) }