Skip to content

Commit 0f17a09

Browse files
committed
Bring up driver in k8s-integration framework instead of in e2e tests. This runs deploy-driver.sh, which handles secret creation and kustomize
1 parent 12cef7b commit 0f17a09

File tree

3 files changed

+173
-63
lines changed

3 files changed

+173
-63
lines changed

test/k8s-integration/main.go

Lines changed: 166 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"path/filepath"
2323
"strings"
2424
"syscall"
25+
"time"
2526

2627
"github.com/golang/glog"
2728

@@ -31,10 +32,15 @@ import (
3132
)
3233

3334
var (
34-
teardownCluster = flag.Bool("teardown-cluster", true, "teardown the cluster after the e2e test")
35-
stagingImage = flag.String("staging-image", "", "name of image to stage to")
36-
kubeVersion = flag.String("kube-version", "master", "version of Kubernetes to download and use")
37-
inProw = flag.Bool("run-in-prow", false, "is the test running in PROW")
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+
stagingImage = flag.String("staging-image", "", "name of image to stage to")
39+
kubeVersion = flag.String("kube-version", "master", "version of Kubernetes to download and use")
40+
inProw = flag.Bool("run-in-prow", false, "is the test running in PROW")
41+
saFile = flag.String("service-account-file", "", "path of service account file")
42+
deployOverlayName = flag.String("deploy-overlay-name", "", "which kustomize overlay to deploy the driver with")
43+
localK8sDir = flag.String("local-k8s-dir", "", "local kubernetes/kubernetes directory to run e2e tests from")
3844
)
3945

4046
func init() {
@@ -47,6 +53,14 @@ func main() {
4753
glog.Fatalf("staging-image is a required flag, please specify the name of image to stage to")
4854
}
4955

56+
if len(*saFile) == 0 {
57+
glog.Fatalf("service-account-file is a required flag")
58+
}
59+
60+
if len(*deployOverlayName) == 0 {
61+
glog.Fatalf("deploy-overlay-name is a required flag")
62+
}
63+
5064
err := handle()
5165
if err != nil {
5266
glog.Fatalf("Failed to run integration test: %v", err)
@@ -86,7 +100,15 @@ func handle() error {
86100
}
87101
}()
88102

89-
*stagingImage = fmt.Sprintf("gcr.io/%s/csi/gce-pd-driver", project)
103+
*stagingImage = fmt.Sprintf("gcr.io/%s/gcp-persistent-disk-csi-driver", project)
104+
105+
// TODO: once https://github.com/kubernetes-sigs/kustomize/issues/402 is implemented,
106+
// we no longer need to do this templating work and can just edit the image registry directly.
107+
overlayDir := getOverlayDir(pkgDir, *deployOverlayName)
108+
err = fillinOverlayTemplate(overlayDir, *stagingImage)
109+
if err != nil {
110+
return fmt.Errorf("tmpOverlayDir setup failed: %v", err)
111+
}
90112

91113
if _, ok := os.LookupEnv("USER"); !ok {
92114
err = os.Setenv("USER", "prow")
@@ -101,31 +123,31 @@ func handle() error {
101123
return fmt.Errorf("failed pushing image: %v", err)
102124
}
103125
defer func() {
104-
err = deleteImage(*stagingImage, stagingVersion)
105-
if err != nil {
106-
glog.Errorf("failed to delete image: %v", err)
126+
if *teardownCluster {
127+
err = deleteImage(*stagingImage, stagingVersion)
128+
if err != nil {
129+
glog.Errorf("failed to delete image: %v", err)
130+
}
107131
}
108132
}()
109133

110-
err = downloadKubernetesSource(pkgDir, k8sIoDir, *kubeVersion)
111-
if err != nil {
112-
return fmt.Errorf("failed to download Kubernetes source: %v", err)
113-
}
134+
if *bringupCluster {
135+
err = downloadKubernetesSource(pkgDir, k8sIoDir, *kubeVersion)
136+
if err != nil {
137+
return fmt.Errorf("failed to download Kubernetes source: %v", err)
138+
}
114139

115-
err = prepareManifests(pkgDir, k8sDir, *stagingImage, stagingVersion)
116-
if err != nil {
117-
return fmt.Errorf("failed to prepare manifests: %v", err)
118-
}
140+
err = buildKubernetes(k8sDir)
141+
if err != nil {
142+
return fmt.Errorf("failed to build Kubernetes: %v", err)
143+
}
119144

120-
err = buildKubernetes(k8sDir)
121-
if err != nil {
122-
return fmt.Errorf("failed to build Kubernetes: %v", err)
145+
err = clusterUp(k8sDir)
146+
if err != nil {
147+
return fmt.Errorf("failed to cluster up: %v", err)
148+
}
123149
}
124150

125-
err = clusterUp(k8sDir)
126-
if err != nil {
127-
return fmt.Errorf("failed to cluster up: %v", err)
128-
}
129151
if *teardownCluster {
130152
defer func() {
131153
err = clusterDown(k8sDir)
@@ -135,6 +157,22 @@ func handle() error {
135157
}()
136158
}
137159

160+
err = installDriver(goPath, pkgDir, k8sDir, *stagingImage, stagingVersion, *deployOverlayName)
161+
if *teardownDriver {
162+
defer func() {
163+
// TODO (#140): collect driver logs
164+
if teardownErr := deleteDriver(goPath, pkgDir, *deployOverlayName); teardownErr != nil {
165+
glog.Errorf("failed to delete driver: %v", teardownErr)
166+
}
167+
}()
168+
}
169+
if err != nil {
170+
return fmt.Errorf("failed to install CSI Driver: %v", err)
171+
}
172+
173+
if len(*localK8sDir) != 0 {
174+
k8sDir = *localK8sDir
175+
}
138176
err = runTests(k8sDir)
139177
if err != nil {
140178
return fmt.Errorf("failed to run tests: %v", err)
@@ -161,21 +199,23 @@ func runTests(k8sDir string) error {
161199
if err != nil {
162200
return err
163201
}
164-
testArgs := "--test_args=--ginkgo.focus=CSI\\sdriver:\\sgcePD"
202+
testArgs := "--test_args=--ginkgo.focus=CSI\\sdriver:.*gcePD-external"
165203
cmd := exec.Command("go", "run", "hack/e2e.go", "--", "--check-version-skew=false", "--test", testArgs)
166-
err = runLongRunningCommand("Running Tests", cmd)
204+
err = runCommand("Running Tests", cmd)
167205
if err != nil {
168206
return fmt.Errorf("failed to run tests on e2e cluster: %v", err)
169207
}
170208

171209
return nil
172210
}
173211

174-
func runLongRunningCommand(action string, cmd *exec.Cmd) error {
212+
func runCommand(action string, cmd *exec.Cmd) error {
175213
cmd.Stdout = os.Stdout
176214
cmd.Stdin = os.Stdin
177215
cmd.Stderr = os.Stderr
178216

217+
fmt.Printf("%s\n", action)
218+
179219
err := cmd.Start()
180220
if err != nil {
181221
return err
@@ -190,7 +230,7 @@ func runLongRunningCommand(action string, cmd *exec.Cmd) error {
190230

191231
func clusterDown(k8sDir string) error {
192232
cmd := exec.Command(filepath.Join(k8sDir, "hack", "e2e-internal", "e2e-down.sh"))
193-
err := runLongRunningCommand("Bringing Down E2E Cluster", cmd)
233+
err := runCommand("Bringing Down E2E Cluster", cmd)
194234
if err != nil {
195235
return fmt.Errorf("failed to bring down kubernetes e2e cluster: %v", err)
196236
}
@@ -199,7 +239,7 @@ func clusterDown(k8sDir string) error {
199239

200240
func buildKubernetes(k8sDir string) error {
201241
cmd := exec.Command("make", "-C", k8sDir, "quick-release")
202-
err := runLongRunningCommand("Building Kubernetes", cmd)
242+
err := runCommand("Building Kubernetes", cmd)
203243
if err != nil {
204244
return fmt.Errorf("failed to build Kubernetes: %v", err)
205245
}
@@ -208,63 +248,113 @@ func buildKubernetes(k8sDir string) error {
208248

209249
func clusterUp(k8sDir string) error {
210250
cmd := exec.Command(filepath.Join(k8sDir, "hack", "e2e-internal", "e2e-up.sh"))
211-
err := runLongRunningCommand("Starting E2E Cluster", cmd)
251+
err := runCommand("Starting E2E Cluster", cmd)
212252
if err != nil {
213253
return fmt.Errorf("failed to bring up kubernetes e2e cluster: %v", err)
214254
}
215255

216256
return nil
217257
}
218258

219-
func prepareManifests(pkgDir, k8sDir, stagingImage, stagingVersion string) error {
220-
// Copy manifests to manifest directory
221-
controllerFile := filepath.Join(pkgDir, "deploy", "kubernetes", "dev", "controller.yaml")
222-
nodeFile := filepath.Join(pkgDir, "deploy", "kubernetes", "dev", "node.yaml")
223-
224-
kubeManifestDir := filepath.Join(k8sDir, "test", "e2e", "testing-manifests", "storage-csi", "gce-pd")
259+
func getOverlayDir(pkgDir, deployOverlayName string) string {
260+
return filepath.Join(pkgDir, "deploy", "kubernetes", "overlays", deployOverlayName)
261+
}
225262

226-
out, err := exec.Command("cp", controllerFile, filepath.Join(kubeManifestDir, "controller_ss.yaml")).CombinedOutput()
263+
func installDriver(goPath, pkgDir, k8sDir, stagingImage, stagingVersion, deployOverlayName string) error {
264+
// Install kustomize
265+
out, err := exec.Command(filepath.Join(pkgDir, "deploy", "kubernetes", "install-kustomize.sh")).CombinedOutput()
227266
if err != nil {
228-
return fmt.Errorf("failed to copy controller manifest: %s, err: %v", out, err)
267+
return fmt.Errorf("failed to install kustomize: %s, err: %v", out, err)
229268
}
230269

231-
out, err = exec.Command("cp", nodeFile, filepath.Join(kubeManifestDir, "node_ds.yaml")).CombinedOutput()
270+
// Edit ci kustomization to use given image tag
271+
overlayDir := getOverlayDir(pkgDir, deployOverlayName)
272+
err = os.Chdir(overlayDir)
232273
if err != nil {
233-
return fmt.Errorf("failed to copy node manifest: %s, err: %v", out, err)
274+
return fmt.Errorf("failed to change to overlay directory: %s, err: %v", out, err)
234275
}
235276

236-
// Change manifest container to staging image and version
237-
err = mutateManifests(filepath.Join(kubeManifestDir, "node_ds.yaml"), filepath.Join(kubeManifestDir, "controller_ss.yaml"), stagingImage, stagingVersion)
277+
// TODO (#138): in a local environment this is going to modify the actual kustomize files.
278+
// maybe a copy should be made instead
279+
out, err = exec.Command(
280+
filepath.Join(pkgDir, "bin", "kustomize"),
281+
"edit",
282+
"set",
283+
"imagetag",
284+
fmt.Sprintf("%s:%s", stagingImage, stagingVersion)).CombinedOutput()
238285
if err != nil {
239-
return err
286+
return fmt.Errorf("failed to edit kustomize: %s, err: %v", out, err)
240287
}
241-
return nil
242-
}
243288

244-
func mutateManifests(nodeFile, controllerFile, stagingImage, stagingVersion string) error {
245-
// TODO: Make this existing image configurable, ideally we aren't actually reliant on
246-
// a hardcoded image to replace.
289+
// setup service account file for secret creation
290+
tmpSaFile := fmt.Sprintf("/tmp/%s/cloud-sa.json", string(uuid.NewUUID()))
247291

248-
// The actual solution we need to look into doing this is using Kustomize
249-
// to mutate the YAML files
250-
existingImage := "gcr.io/dyzz-csi-staging/csi/gce-pd-driver:latest"
292+
os.MkdirAll(filepath.Dir(tmpSaFile), 0750)
293+
defer os.Remove(filepath.Dir(tmpSaFile))
251294

252-
escapedImage := strings.Replace(stagingImage, "/", "\\/", -1)
253-
escapedVersion := strings.Replace(stagingVersion, "/", "\\/", -1)
254-
escapedExistingImage := strings.Replace(existingImage, "/", "\\/", -1)
295+
// Need to copy it to name the file "cloud-sa.json"
296+
out, err = exec.Command("cp", *saFile, tmpSaFile).CombinedOutput()
297+
if err != nil {
298+
return fmt.Errorf("error copying service account key: %s, err: %v", out, err)
299+
}
300+
defer shredFile(tmpSaFile)
301+
302+
// deploy driver
303+
deployCmd := exec.Command(filepath.Join(pkgDir, "deploy", "kubernetes", "deploy-driver.sh"), "--skip-sa-check")
304+
deployCmd.Env = append(os.Environ(),
305+
fmt.Sprintf("GOPATH=%s", goPath),
306+
fmt.Sprintf("GCE_PD_SA_DIR=%s", filepath.Dir(tmpSaFile)),
307+
fmt.Sprintf("GCE_PD_DRIVER_VERSION=%s", deployOverlayName),
308+
)
309+
err = runCommand("Deploying driver", deployCmd)
310+
if err != nil {
311+
return fmt.Errorf("failed to deploy driver: %v", err)
312+
}
255313

256-
sedCommand := fmt.Sprintf("s/%s/%s:%s/g", escapedExistingImage, escapedImage, escapedVersion)
314+
// TODO (#139): wait for driver to be running
315+
time.Sleep(10 * time.Second)
316+
statusCmd := exec.Command("kubectl", "describe", "pods", "-n", "default")
317+
err = runCommand("Checking driver pods", statusCmd)
318+
if err != nil {
319+
return fmt.Errorf("failed to check driver pods: %v", err)
320+
}
257321

258-
out, err := exec.Command("sed", "-i", "-e", sedCommand, nodeFile).CombinedOutput()
322+
return nil
323+
}
324+
325+
func deleteDriver(goPath, pkgDir, deployOverlayName string) error {
326+
deleteCmd := exec.Command(filepath.Join(pkgDir, "deploy", "kubernetes", "delete-driver.sh"))
327+
deleteCmd.Env = append(os.Environ(),
328+
fmt.Sprintf("GOPATH=%s", goPath),
329+
fmt.Sprintf("GCE_PD_DRIVER_VERSION=%s", deployOverlayName),
330+
)
331+
err := runCommand("Deleting driver", deleteCmd)
259332
if err != nil {
260-
return fmt.Errorf("failed to sed node file %s: %s, err: %v", nodeFile, out, err)
333+
return fmt.Errorf("failed to delete driver: %v", err)
261334
}
262-
out, err = exec.Command("sed", "-i", "-e", sedCommand, controllerFile).CombinedOutput()
335+
return nil
336+
}
337+
338+
func shredFile(filePath string) {
339+
if _, err := os.Stat(filePath); os.IsNotExist(err) {
340+
glog.V(4).Infof("File %v was not found, skipping shredding", filePath)
341+
return
342+
}
343+
glog.V(4).Infof("Shredding file %v", filePath)
344+
out, err := exec.Command("shred", "--remove", filePath).CombinedOutput()
263345
if err != nil {
264-
return fmt.Errorf("failed to sed controller file %s: %s, err: %v", controllerFile, out, err)
346+
glog.V(4).Infof("Failed to shred file %v: %v\nOutput:%v", filePath, err, out)
347+
}
348+
if _, err := os.Stat(filePath); os.IsNotExist(err) {
349+
glog.V(4).Infof("File %v successfully shredded", filePath)
350+
return
265351
}
266352

267-
return nil
353+
// Shred failed Try to remove the file for good meausure
354+
err = os.Remove(filePath)
355+
if err != nil {
356+
glog.V(4).Infof("Failed to remove service account file %s: %v", filePath, err)
357+
}
268358
}
269359

270360
func downloadKubernetesSource(pkgDir, k8sIoDir, kubeVersion string) error {
@@ -335,7 +425,7 @@ func pushImage(pkgDir, stagingImage, stagingVersion string) error {
335425
cmd := exec.Command("make", "-C", pkgDir, "push-container",
336426
fmt.Sprintf("GCE_PD_CSI_STAGING_VERSION=%s", stagingVersion),
337427
fmt.Sprintf("GCE_PD_CSI_STAGING_IMAGE=%s", stagingImage))
338-
err = runLongRunningCommand("Pushing GCP Container", cmd)
428+
err = runCommand("Pushing GCP Container", cmd)
339429
if err != nil {
340430
return fmt.Errorf("failed to run make command: err: %v", err)
341431
}
@@ -344,9 +434,24 @@ func pushImage(pkgDir, stagingImage, stagingVersion string) error {
344434

345435
func deleteImage(stagingImage, stagingVersion string) error {
346436
cmd := exec.Command("gcloud", "container", "images", "delete", fmt.Sprintf("%s:%s", stagingImage, stagingVersion), "--quiet")
347-
err := runLongRunningCommand("Deleting GCR Container", cmd)
437+
err := runCommand("Deleting GCR Container", cmd)
348438
if err != nil {
349439
return fmt.Errorf("failed to delete container image %s:%s: %s", stagingImage, stagingVersion, err)
350440
}
351441
return nil
352442
}
443+
444+
func fillinOverlayTemplate(overlayDir, stagingImage string) error {
445+
// Substitute the PROW_GCEPD_IMAGE env with stagingImage for every file in the directory
446+
escapedStagingImage := strings.Replace(stagingImage, "/", "\\/", -1)
447+
out, err := exec.Command(
448+
"bash",
449+
"-c",
450+
fmt.Sprintf("find %s -name *.yaml | xargs %s",
451+
overlayDir,
452+
fmt.Sprintf("sed -i -e 's/PROW_GCEPD_IMAGE/%s/g'", escapedStagingImage))).CombinedOutput()
453+
if err != nil {
454+
return fmt.Errorf("error substituting staging image env: %s, err: %v", out, err)
455+
}
456+
return nil
457+
}

test/run-k8s-integration-local.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ set -o nounset
44
set -o errexit
55

66
readonly PKGDIR=${GOPATH}/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver
7+
source "${PKGDIR}/deploy/common.sh"
8+
9+
ensure_var GCE_PD_CSI_STAGING_IMAGE
10+
ensure_var GCE_PD_SA_DIR
711

812
make -C ${PKGDIR} test-k8s-integration
9-
${PKGDIR}/bin/k8s-integration-test --kube-version=master --run-in-prow=false --staging-image=${GCE_PD_CSI_STAGING_IMAGE}
13+
${PKGDIR}/bin/k8s-integration-test --kube-version=master --run-in-prow=false --staging-image=${GCE_PD_CSI_STAGING_IMAGE} --service-account-file=${GCE_PD_SA_DIR}/cloud-sa.json --deploy-overlay-name=dev
14+
#${PKGDIR}/bin/k8s-integration-test --kube-version=master --run-in-prow=false --staging-image=${GCE_PD_CSI_STAGING_IMAGE} --service-account-file=${GCE_PD_SA_DIR}/cloud-sa.json --deploy-overlay-name=dev --bringup-cluster=false --teardown-cluster=false --local-k8s-dir=$KTOP

test/run-k8s-integration.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ set -o errexit
66
readonly PKGDIR=${GOPATH}/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver
77

88
make -C ${PKGDIR} test-k8s-integration
9-
${PKGDIR}/bin/k8s-integration-test --kube-version=master --run-in-prow=true
9+
${PKGDIR}/bin/k8s-integration-test --kube-version=master --run-in-prow=true --deploy-overlay-name=prow-head-template --service-account-file=${E2E_GOOGLE_APPLICATION_CREDENTIALS}

0 commit comments

Comments
 (0)