Merge pull request #102526 from pohly/csi-driver-pod-events

storage e2e: capture driver pod events
This commit is contained in:
Kubernetes Prow Robot 2021-06-02 16:15:09 -07:00 committed by GitHub
commit babe9cd4a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 15 deletions

View File

@ -33,6 +33,7 @@ import (
"regexp" "regexp"
"strings" "strings"
"sync" "sync"
"time"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -266,18 +267,42 @@ func logsForPod(ctx context.Context, cs clientset.Interface, ns, pod string, opt
} }
// WatchPods prints pod status events for a certain namespace or all namespaces // WatchPods prints pod status events for a certain namespace or all namespaces
// when namespace name is empty. // when namespace name is empty. The closer can be nil if the caller doesn't want
func WatchPods(ctx context.Context, cs clientset.Interface, ns string, to io.Writer) error { // the file to be closed when watching stops.
watcher, err := cs.CoreV1().Pods(ns).Watch(context.TODO(), meta.ListOptions{}) func WatchPods(ctx context.Context, cs clientset.Interface, ns string, to io.Writer, toCloser io.Closer) (finalErr error) {
defer func() {
if finalErr != nil && toCloser != nil {
toCloser.Close()
}
}()
pods, err := cs.CoreV1().Pods(ns).Watch(context.Background(), meta.ListOptions{})
if err != nil { if err != nil {
return errors.Wrap(err, "cannot create Pod event watcher") return fmt.Errorf("cannot create Pod watcher: %w", err)
}
defer func() {
if finalErr != nil {
pods.Stop()
}
}()
events, err := cs.CoreV1().Events(ns).Watch(context.Background(), meta.ListOptions{})
if err != nil {
return fmt.Errorf("cannot create Event watcher: %w", err)
} }
go func() { go func() {
defer watcher.Stop() defer func() {
pods.Stop()
events.Stop()
if toCloser != nil {
toCloser.Close()
}
}()
timeFormat := "15:04:05.000"
for { for {
select { select {
case e := <-watcher.ResultChan(): case e := <-pods.ResultChan():
if e.Object == nil { if e.Object == nil {
continue continue
} }
@ -288,7 +313,8 @@ func WatchPods(ctx context.Context, cs clientset.Interface, ns string, to io.Wri
} }
buffer := new(bytes.Buffer) buffer := new(bytes.Buffer)
fmt.Fprintf(buffer, fmt.Fprintf(buffer,
"pod event: %s: %s/%s %s: %s %s\n", "%s pod: %s: %s/%s %s: %s %s\n",
time.Now().Format(timeFormat),
e.Type, e.Type,
pod.Namespace, pod.Namespace,
pod.Name, pod.Name,
@ -314,7 +340,29 @@ func WatchPods(ctx context.Context, cs clientset.Interface, ns string, to io.Wri
fmt.Fprintf(buffer, "\n") fmt.Fprintf(buffer, "\n")
} }
to.Write(buffer.Bytes()) to.Write(buffer.Bytes())
case e := <-events.ResultChan():
if e.Object == nil {
continue
}
event, ok := e.Object.(*v1.Event)
if !ok {
continue
}
to.Write([]byte(fmt.Sprintf("%s event: %s/%s %s: %s %s: %s (%v - %v)\n",
time.Now().Format(timeFormat),
event.InvolvedObject.APIVersion,
event.InvolvedObject.Kind,
event.InvolvedObject.Name,
event.Source.Component,
event.Type,
event.Message,
event.FirstTimestamp,
event.LastTimestamp,
)))
case <-ctx.Done(): case <-ctx.Done():
to.Write([]byte(fmt.Sprintf("%s ==== stopping pod watch ====\n",
time.Now().Format(timeFormat))))
return return
} }
} }

View File

@ -19,6 +19,9 @@ package utils
import ( import (
"context" "context"
"fmt" "fmt"
"io"
"os"
"path"
"regexp" "regexp"
"strings" "strings"
"time" "time"
@ -46,6 +49,8 @@ func StartPodLogs(f *framework.Framework, driverNamespace *v1.Namespace) func()
ns := driverNamespace.Name ns := driverNamespace.Name
podEventLog := ginkgo.GinkgoWriter
var podEventLogCloser io.Closer
to := podlogs.LogOutput{ to := podlogs.LogOutput{
StatusWriter: ginkgo.GinkgoWriter, StatusWriter: ginkgo.GinkgoWriter,
} }
@ -69,17 +74,22 @@ func StartPodLogs(f *framework.Framework, driverNamespace *v1.Namespace) func()
// keeps each directory name smaller (the full test // keeps each directory name smaller (the full test
// name at one point exceeded 256 characters, which was // name at one point exceeded 256 characters, which was
// too much for some filesystems). // too much for some filesystems).
to.LogPathPrefix = framework.TestContext.ReportDir + "/" + logDir := framework.TestContext.ReportDir + "/" + strings.Join(components, "/")
strings.Join(components, "/") + "/" to.LogPathPrefix = logDir + "/"
err := os.MkdirAll(logDir, 0755)
framework.ExpectNoError(err, "create pod log directory")
f, err := os.Create(path.Join(logDir, "pod-event.log"))
framework.ExpectNoError(err, "create pod events log file")
podEventLog = f
podEventLogCloser = f
} }
podlogs.CopyAllLogs(ctx, cs, ns, to) podlogs.CopyAllLogs(ctx, cs, ns, to)
// pod events are something that the framework already collects itself // The framework doesn't know about the driver pods because of
// after a failed test. Logging them live is only useful for interactive // the separate namespace. Therefore we always capture the
// debugging, not when we collect reports. // events ourselves.
if framework.TestContext.ReportDir == "" { podlogs.WatchPods(ctx, cs, ns, podEventLog, podEventLogCloser)
podlogs.WatchPods(ctx, cs, ns, ginkgo.GinkgoWriter)
}
return cancel return cancel
} }