Skip to content

Commit

Permalink
Unify common logic.
Browse files Browse the repository at this point in the history
  • Loading branch information
amwat committed Feb 10, 2020
1 parent 7ca4451 commit 9db34ac
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 105 deletions.
4 changes: 4 additions & 0 deletions pkg/cluster/internal/providers/docker/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,7 @@ func (c *nodeCmd) SetStderr(w io.Writer) exec.Cmd {
c.stderr = w
return c
}

func (n *node) SerialLogs(w io.Writer) error {
return exec.Command("docker", "logs", n.name).SetStdout(w).SetStderr(w).Run()
}
75 changes: 22 additions & 53 deletions pkg/cluster/internal/providers/docker/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package docker
import (
"fmt"
"net"
"os"
"path/filepath"
"strings"

Expand Down Expand Up @@ -181,27 +180,14 @@ func (p *Provider) node(name string) nodes.Node {

// CollectLogs will populate dir with cluster logs and other debug files
func (p *Provider) CollectLogs(dir string, nodes []nodes.Node) error {
prefixedPath := func(path string) string {
return filepath.Join(dir, path)
}
// helper to run a cmd and write the output to path
execToPath := func(cmd exec.Cmd, path string) error {
realPath := prefixedPath(path)
if err := os.MkdirAll(filepath.Dir(realPath), os.ModePerm); err != nil {
return err
}
f, err := os.Create(realPath)
if err != nil {
return err
}
defer f.Close()
cmd.SetStdout(f)
cmd.SetStderr(f)
return cmd.Run()
}
execToPathFn := func(cmd exec.Cmd, path string) func() error {
return func() error {
return execToPath(cmd, path)
f, err := common.FileOnHost(path)
if err != nil {
return err
}
defer f.Close()
return cmd.SetStdout(f).SetStderr(f).Run()
}
}
// construct a slice of methods to collect logs
Expand All @@ -210,49 +196,32 @@ func (p *Provider) CollectLogs(dir string, nodes []nodes.Node) error {
// record info about the host docker
execToPathFn(
exec.Command("docker", "info"),
"docker-info.txt",
filepath.Join(dir, "docker-info.txt"),
),
}

// collect /var/log for each node and plan collecting more logs
errs := []error{}
var errs []error
for _, n := range nodes {
node := n // https://golang.org/doc/faq#closures_and_goroutines
name := node.String()
if err := internallogs.DumpDir(p.logger, n, "/var/log", filepath.Join(dir, name)); err != nil {
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 errors.AggregateConcurrent([]func() error{
// record info about the node container
execToPathFn(
exec.Command("docker", "inspect", name),
filepath.Join(name, "inspect.json"),
),
// grab all of the node logs
execToPathFn(
exec.Command("docker", "logs", name),
filepath.Join(name, "serial.log"),
),
execToPathFn(
node.Command("cat", "/kind/version"),
filepath.Join(name, "kubernetes-version.txt"),
),
execToPathFn(
node.Command("journalctl", "--no-pager"),
filepath.Join(name, "journal.log"),
),
execToPathFn(
node.Command("journalctl", "--no-pager", "-u", "kubelet.service"),
filepath.Join(name, "kubelet.log"),
),
execToPathFn(
node.Command("journalctl", "--no-pager", "-u", "containerd.service"),
filepath.Join(name, "containerd.log"),
),
})
})
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
Expand Down
4 changes: 4 additions & 0 deletions pkg/cluster/internal/providers/podman/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,7 @@ func (c *nodeCmd) SetStderr(w io.Writer) exec.Cmd {
c.stderr = w
return c
}

func (n *node) SerialLogs(w io.Writer) error {
return exec.Command("podman", "logs", n.name).SetStdout(w).SetStderr(w).Run()
}
73 changes: 21 additions & 52 deletions pkg/cluster/internal/providers/podman/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,27 +205,14 @@ func (p *Provider) node(name string) nodes.Node {

// CollectLogs will populate dir with cluster logs and other debug files
func (p *Provider) CollectLogs(dir string, nodes []nodes.Node) error {
prefixedPath := func(path string) string {
return filepath.Join(dir, path)
}
// helper to run a cmd and write the output to path
execToPath := func(cmd exec.Cmd, path string) error {
realPath := prefixedPath(path)
if err := os.MkdirAll(filepath.Dir(realPath), os.ModePerm); err != nil {
return err
}
f, err := os.Create(realPath)
if err != nil {
return err
}
defer f.Close()
cmd.SetStdout(f)
cmd.SetStderr(f)
return cmd.Run()
}
execToPathFn := func(cmd exec.Cmd, path string) func() error {
return func() error {
return execToPath(cmd, path)
f, err := common.FileOnHost(path)
if err != nil {
return err
}
defer f.Close()
return cmd.SetStdout(f).SetStderr(f).Run()
}
}
// construct a slice of methods to collect logs
Expand All @@ -234,49 +221,31 @@ func (p *Provider) CollectLogs(dir string, nodes []nodes.Node) error {
// record info about the host podman
execToPathFn(
exec.Command("podman", "info"),
"podman-info.txt",
filepath.Join(dir, "podman-info.txt"),
),
}

// collect /var/log for each node and plan collecting more logs
errs := []error{}
var errs []error
for _, n := range nodes {
node := n // https://golang.org/doc/faq#closures_and_goroutines
name := node.String()
if err := internallogs.DumpDir(p.logger, n, "/var/log", filepath.Join(dir, name)); err != nil {
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 errors.AggregateConcurrent([]func() error{
// record info about the node container
execToPathFn(
exec.Command("podman", "inspect", name),
filepath.Join(name, "inspect.json"),
),
// grab all of the node logs
execToPathFn(
exec.Command("podman", "logs", name),
filepath.Join(name, "serial.log"),
),
execToPathFn(
node.Command("cat", "/kind/version"),
filepath.Join(name, "kubernetes-version.txt"),
),
execToPathFn(
node.Command("journalctl", "--no-pager"),
filepath.Join(name, "journal.log"),
),
execToPathFn(
node.Command("journalctl", "--no-pager", "-u", "kubelet.service"),
filepath.Join(name, "kubelet.log"),
),
execToPathFn(
node.Command("journalctl", "--no-pager", "-u", "containerd.service"),
filepath.Join(name, "containerd.log"),
),
})
})
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
Expand Down
54 changes: 54 additions & 0 deletions pkg/cluster/internal/providers/provider/common/logs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package common

import (
"os"
"path/filepath"

"sigs.k8s.io/kind/pkg/cluster/nodes"
"sigs.k8s.io/kind/pkg/errors"
"sigs.k8s.io/kind/pkg/exec"
)

// CollectLogs provides the common functionality
// to get various debug info from the node
func CollectLogs(n nodes.Node, dir string) error {
execToPathFn := func(cmd exec.Cmd, path string) func() error {
return func() error {
f, err := FileOnHost(filepath.Join(dir, path))
if err != nil {
return err
}
defer f.Close()
return cmd.SetStdout(f).SetStderr(f).Run()
}
}
return errors.AggregateConcurrent([]func() error{
// record info about the node container
execToPathFn(
n.Command("cat", "/kind/version"),
"kubernetes-version.txt",
),
execToPathFn(
n.Command("journalctl", "--no-pager"),
"journal.log",
),
execToPathFn(
n.Command("journalctl", "--no-pager", "-u", "kubelet.service"),
"kubelet.log",
),
execToPathFn(
n.Command("journalctl", "--no-pager", "-u", "containerd.service"),
"containerd.log",
),
})
}

// FileOnHost is a helper to create a file at path
// even if the parent directory doesn't exist
// in which case it will be created with ModePerm
func FileOnHost(path string) (*os.File, error) {
if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {
return nil, err
}
return os.Create(path)
}
4 changes: 4 additions & 0 deletions pkg/cluster/nodes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package nodes

import (
"io"

"sigs.k8s.io/kind/pkg/exec"
)

Expand All @@ -33,4 +35,6 @@ type Node interface {
// Possibly remove this method in favor of obtaining this detail with
// exec or from the provider
IP() (ipv4 string, ipv6 string, err error)
// SerialLogs collects the "node" container logs
SerialLogs(writer io.Writer) error
}

0 comments on commit 9db34ac

Please sign in to comment.