Skip to content

Commit a97777b

Browse files
committed
Dump driver logs to test artifacts
1 parent 34964a7 commit a97777b

File tree

3 files changed

+105
-26
lines changed

3 files changed

+105
-26
lines changed

test/k8s-integration/cluster.go

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"strings"
1212

1313
apimachineryversion "k8s.io/apimachinery/pkg/version"
14+
"k8s.io/client-go/kubernetes"
15+
"k8s.io/client-go/tools/clientcmd"
1416
"k8s.io/klog"
1517
)
1618

@@ -43,7 +45,7 @@ func clusterDownGKE(gceZone, gceRegion string) error {
4345
return err
4446
}
4547

46-
cmd := exec.Command("gcloud", "container", "clusters", "delete", gkeTestClusterName,
48+
cmd := exec.Command("gcloud", "container", "clusters", "delete", *gkeTestClusterName,
4749
locationArg, locationVal, "--quiet")
4850
err = runCommand("Bringing Down E2E Cluster on GKE", cmd)
4951
if err != nil {
@@ -140,21 +142,21 @@ func clusterUpGKE(gceZone, gceRegion string, numNodes int, imageType string, use
140142
}
141143

142144
out, err := exec.Command("gcloud", "container", "clusters", "list", locationArg, locationVal,
143-
"--filter", fmt.Sprintf("name=%s", gkeTestClusterName)).CombinedOutput()
145+
"--filter", fmt.Sprintf("name=%s", *gkeTestClusterName)).CombinedOutput()
144146

145147
if err != nil {
146148
return fmt.Errorf("failed to check for previous test cluster: %v %s", err, out)
147149
}
148150
if len(out) > 0 {
149-
klog.Infof("Detected previous cluster %s. Deleting so a new one can be created...", gkeTestClusterName)
151+
klog.Infof("Detected previous cluster %s. Deleting so a new one can be created...", *gkeTestClusterName)
150152
err = clusterDownGKE(gceZone, gceRegion)
151153
if err != nil {
152154
return err
153155
}
154156
}
155157

156158
var cmd *exec.Cmd
157-
cmdParams := []string{"container", "clusters", "create", gkeTestClusterName,
159+
cmdParams := []string{"container", "clusters", "create", *gkeTestClusterName,
158160
locationArg, locationVal, "--num-nodes", strconv.Itoa(numNodes),
159161
"--quiet", "--machine-type", "n1-standard-2", "--image-type", imageType}
160162
if isVariableSet(gkeClusterVer) {
@@ -276,7 +278,7 @@ func getGKEKubeTestArgs(gceZone, gceRegion, imageType string) ([]string, error)
276278
"--deployment=gke",
277279
fmt.Sprintf("--gcp-node-image=%s", imageType),
278280
"--gcp-network=default",
279-
fmt.Sprintf("--cluster=%s", gkeTestClusterName),
281+
fmt.Sprintf("--cluster=%s", *gkeTestClusterName),
280282
fmt.Sprintf("--gke-environment=%s", gkeEnv),
281283
fmt.Sprintf("%s=%s", locationArg, locationVal),
282284
fmt.Sprintf("--gcp-project=%s", project[:len(project)-1]),
@@ -336,3 +338,36 @@ func mustGetKubeClusterVersion() string {
336338
}
337339
return ver
338340
}
341+
342+
// getKubeConfig returns the full path to the
343+
// kubeconfig file set in $KUBECONFIG env.
344+
// If unset, then it defaults to $HOME/.kube/config
345+
func getKubeConfig() (string, error) {
346+
config, ok := os.LookupEnv("KUBECONFIG")
347+
if ok {
348+
return config, nil
349+
}
350+
homeDir, ok := os.LookupEnv("HOME")
351+
if !ok {
352+
return "", fmt.Errorf("HOME env not set")
353+
}
354+
return filepath.Join(homeDir, ".kube/config"), nil
355+
}
356+
357+
// getKubeClient returns a Kubernetes client interface
358+
// for the test cluster
359+
func getKubeClient() (kubernetes.Interface, error) {
360+
kubeConfig, err := getKubeConfig()
361+
if err != nil {
362+
return nil, err
363+
}
364+
config, err := clientcmd.BuildConfigFromFlags("", kubeConfig)
365+
if err != nil {
366+
return nil, fmt.Errorf("failed to create config: %v", err)
367+
}
368+
kubeClient, err := kubernetes.NewForConfig(config)
369+
if err != nil {
370+
return nil, fmt.Errorf("failed to create client: %v", err)
371+
}
372+
return kubeClient, nil
373+
}

test/k8s-integration/driver.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package main
22

33
import (
4+
"context"
45
"fmt"
56
"os"
67
"os/exec"
78
"path/filepath"
89
"time"
10+
11+
"k8s.io/kubernetes/test/e2e/framework/podlogs"
912
)
1013

1114
func getOverlayDir(pkgDir, deployOverlayName string) string {
@@ -65,7 +68,7 @@ func installDriver(goPath, pkgDir, stagingImage, stagingVersion, deployOverlayNa
6568

6669
// TODO (#139): wait for driver to be running
6770
time.Sleep(time.Minute)
68-
statusCmd := exec.Command("kubectl", "describe", "pods", "-n", "default")
71+
statusCmd := exec.Command("kubectl", "describe", "pods", "-n", driverNamespace)
6972
err = runCommand("Checking driver pods", statusCmd)
7073
if err != nil {
7174
return fmt.Errorf("failed to check driver pods: %v", err)
@@ -121,3 +124,29 @@ func deleteImage(stagingImage, stagingVersion string) error {
121124
}
122125
return nil
123126
}
127+
128+
// dumpDriverLogs will watch all pods in the driver namespace
129+
// and copy its logs to the test artifacts directory, if set.
130+
// It returns a context.CancelFunc that needs to be invoked when
131+
// the test is finished.
132+
func dumpDriverLogs() (context.CancelFunc, error) {
133+
// Dump all driver logs to the test artifacts
134+
artifactsDir, ok := os.LookupEnv("ARTIFACTS")
135+
if ok {
136+
client, err := getKubeClient()
137+
if err != nil {
138+
return nil, fmt.Errorf("failed to get kubeclient: %v", err)
139+
}
140+
out := podlogs.LogOutput{
141+
StatusWriter: os.Stdout,
142+
LogPathPrefix: filepath.Join(artifactsDir, "pd-csi-driver") + "/",
143+
}
144+
ctx, cancel := context.WithCancel(context.Background())
145+
if err = podlogs.CopyAllLogs(ctx, client, driverNamespace, out); err != nil {
146+
return cancel, fmt.Errorf("failed to start pod logger: %v", err)
147+
}
148+
return cancel, nil
149+
}
150+
return nil, nil
151+
152+
}

test/k8s-integration/main.go

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,29 @@ import (
2525

2626
"k8s.io/apimachinery/pkg/util/uuid"
2727
apimachineryversion "k8s.io/apimachinery/pkg/util/version"
28+
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
2829
"k8s.io/klog"
2930
testutils "sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/test/e2e/utils"
3031
)
3132

3233
var (
3334
// Kubernetes cluster flags
34-
teardownCluster = flag.Bool("teardown-cluster", true, "teardown the cluster after the e2e test")
35-
teardownDriver = flag.Bool("teardown-driver", true, "teardown the driver after the e2e test")
36-
bringupCluster = flag.Bool("bringup-cluster", true, "build kubernetes and bringup a cluster")
37-
platform = flag.String("platform", "linux", "platform that the tests will be run, either linux or windows")
38-
gceZone = flag.String("gce-zone", "", "zone that the gce k8s cluster is created/found in")
39-
gceRegion = flag.String("gce-region", "", "region that gke regional cluster should be created in")
40-
kubeVersion = flag.String("kube-version", "", "version of Kubernetes to download and use for the cluster")
41-
testVersion = flag.String("test-version", "", "version of Kubernetes to download and use for tests")
42-
kubeFeatureGates = flag.String("kube-feature-gates", "", "feature gates to set on new kubernetes cluster")
43-
localK8sDir = flag.String("local-k8s-dir", "", "local prebuilt kubernetes/kubernetes directory to use for cluster and test binaries")
44-
deploymentStrat = flag.String("deployment-strategy", "gce", "choose between deploying on gce or gke")
45-
gkeClusterVer = flag.String("gke-cluster-version", "", "version of Kubernetes master and node for gke")
46-
numNodes = flag.Int("num-nodes", -1, "the number of nodes in the test cluster")
47-
imageType = flag.String("image-type", "cos", "the image type to use for the cluster")
48-
gkeReleaseChannel = flag.String("gke-release-channel", "", "GKE release channel to be used for cluster deploy. One of 'rapid', 'stable' or 'regular'")
35+
teardownCluster = flag.Bool("teardown-cluster", true, "teardown the cluster after the e2e test")
36+
teardownDriver = flag.Bool("teardown-driver", true, "teardown the driver after the e2e test")
37+
bringupCluster = flag.Bool("bringup-cluster", true, "build kubernetes and bringup a cluster")
38+
platform = flag.String("platform", "linux", "platform that the tests will be run, either linux or windows")
39+
gceZone = flag.String("gce-zone", "", "zone that the gce k8s cluster is created/found in")
40+
gceRegion = flag.String("gce-region", "", "region that gke regional cluster should be created in")
41+
kubeVersion = flag.String("kube-version", "", "version of Kubernetes to download and use for the cluster")
42+
testVersion = flag.String("test-version", "", "version of Kubernetes to download and use for tests")
43+
kubeFeatureGates = flag.String("kube-feature-gates", "", "feature gates to set on new kubernetes cluster")
44+
localK8sDir = flag.String("local-k8s-dir", "", "local prebuilt kubernetes/kubernetes directory to use for cluster and test binaries")
45+
deploymentStrat = flag.String("deployment-strategy", "gce", "choose between deploying on gce or gke")
46+
gkeClusterVer = flag.String("gke-cluster-version", "", "version of Kubernetes master and node for gke")
47+
numNodes = flag.Int("num-nodes", -1, "the number of nodes in the test cluster")
48+
imageType = flag.String("image-type", "cos", "the image type to use for the cluster")
49+
gkeReleaseChannel = flag.String("gke-release-channel", "", "GKE release channel to be used for cluster deploy. One of 'rapid', 'stable' or 'regular'")
50+
gkeTestClusterName = flag.String("gke-cluster-name", "gcp-pd-csi-driver-test-cluster", "GKE cluster name")
4951

5052
// Test infrastructure flags
5153
boskosResourceType = flag.String("boskos-resource-type", "gce-project", "name of the boskos resource type to reserve")
@@ -69,7 +71,7 @@ const (
6971
pdImagePlaceholder = "gke.gcr.io/gcp-compute-persistent-disk-csi-driver"
7072
k8sInDockerBuildBinDir = "_output/dockerized/bin/linux/amd64"
7173
k8sOutOfDockerBuildBinDir = "_output/bin"
72-
gkeTestClusterName = "gcp-pd-csi-driver-test-cluster"
74+
driverNamespace = "gce-pd-csi-driver"
7375
)
7476

7577
func init() {
@@ -79,7 +81,7 @@ func init() {
7981
func main() {
8082
flag.Parse()
8183

82-
if !*inProw && !*useGKEManagedDriver {
84+
if !*inProw && *doDriverBuild {
8385
ensureVariable(stagingImage, true, "staging-image is a required flag, please specify the name of image to stage to")
8486
}
8587

@@ -302,7 +304,6 @@ func handle() error {
302304
err := installDriver(goPath, pkgDir, *stagingImage, stagingVersion, *deployOverlayName, *doDriverBuild)
303305
if *teardownDriver {
304306
defer func() {
305-
// TODO (#140): collect driver logs
306307
if teardownErr := deleteDriver(goPath, pkgDir, *deployOverlayName); teardownErr != nil {
307308
klog.Errorf("failed to delete driver: %v", teardownErr)
308309
}
@@ -311,6 +312,17 @@ func handle() error {
311312
if err != nil {
312313
return fmt.Errorf("failed to install CSI Driver: %v", err)
313314
}
315+
316+
// Dump all driver logs to the test artifacts
317+
cancel, err := dumpDriverLogs()
318+
if err != nil {
319+
return fmt.Errorf("failed to start driver logging: %v", err)
320+
}
321+
defer func() {
322+
if cancel != nil {
323+
cancel()
324+
}
325+
}()
314326
}
315327

316328
var cloudProviderArgs []string
@@ -423,8 +435,11 @@ func runTestsWithConfig(testDir, testFocus, testSkip, testConfigArg string, clou
423435
return err
424436
}
425437

426-
homeDir, _ := os.LookupEnv("HOME")
427-
os.Setenv("KUBECONFIG", filepath.Join(homeDir, ".kube/config"))
438+
kubeconfig, err := getKubeConfig()
439+
if err != nil {
440+
return err
441+
}
442+
os.Setenv("KUBECONFIG", kubeconfig)
428443

429444
artifactsDir, ok := os.LookupEnv("ARTIFACTS")
430445
reportArg := ""

0 commit comments

Comments
 (0)