diff --git a/Makefile b/Makefile index 4354ea04..718bc898 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,14 @@ CMDS=nfsplugin DEPLOY_FOLDER = ./deploy/kubernetes CMDS=nfsplugin +PKG = github.com/kubernetes-csi/csi-driver-nfs +IMAGE_VERSION ?= v0.5.0 +LDFLAGS ?= "-X ${PKG}/pkg/nfs.driverVersion=${IMAGE_VERSION} -X -s -w -extldflags '-static'" +IMAGE_NAME ?= nfsplugin +REGISTRY ?= andyzhangx +IMAGE_TAG = $(REGISTRY)/$(IMAGE_NAME):$(IMAGE_VERSION) + + all: build include release-tools/build.make @@ -44,3 +52,47 @@ local-k8s-uninstall: kubectl delete -f $(DEPLOY_FOLDER)/csi-nfs-driverinfo.yaml --ignore-not-found kubectl delete -f $(DEPLOY_FOLDER)/rbac-csi-nfs-controller.yaml --ignore-not-found echo "Uninstalled NFS driver" + +.PHONY: nfs +nfs: + CGO_ENABLED=0 GOOS=linux go build -a -ldflags ${LDFLAGS} -o _output/nfsplugin ./cmd/nfsplugin + +.PHONY: nfs-container +nfs-container: + docker buildx rm container-builder || true + docker buildx create --use --name=container-builder +ifdef CI + make nfs + docker buildx build --no-cache --build-arg LDFLAGS=${LDFLAGS} -t $(IMAGE_TAG)-linux-amd64 . --platform="linux/amd64" --push . +ifdef PUBLISH + docker manifest create $(IMAGE_TAG_LATEST) $(IMAGE_TAG)-linux-amd64 + docker manifest inspect $(IMAGE_TAG_LATEST) +endif +endif + +.PHONY: install-nfs-server +install-nfs-server: + kubectl apply -f ./examples/kubernetes/nfs-server/nfs-server.yaml + +.PHONY: install-helm +install-helm: + curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash + +.PHONY: push +push: +ifdef CI + docker manifest push --purge $(IMAGE_TAG) +else + docker push $(IMAGE_TAG) +endif + +.PHONY: e2e-bootstrap +e2e-bootstrap: install-helm + docker pull $(IMAGE_TAG) || make nfs-container push + helm install -n csi-driver-nfs ./charts/csi-driver-nfs --namespace kube-system --wait --timeout=15m -v=5 --debug \ + --set image.nfs.repository=$(REGISTRY)/$(IMAGE_NAME) \ + --set image.smb.tag=$(IMAGE_VERSION) + +.PHONY: e2e-teardown +e2e-teardown: + helm delete csi-driver-nfs --namespace kube-system \ No newline at end of file diff --git a/go.mod b/go.mod index fde94b12..1705437f 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,8 @@ require ( github.com/container-storage-interface/spec v1.2.0 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/kubernetes-csi/csi-lib-utils v0.2.0 + github.com/onsi/ginkgo v1.11.0 + github.com/onsi/gomega v1.7.0 github.com/spf13/cobra v0.0.5 golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 golang.org/x/text v0.3.3 // indirect diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go new file mode 100644 index 00000000..5762a575 --- /dev/null +++ b/test/e2e/e2e_suite_test.go @@ -0,0 +1,124 @@ +package e2e + +import ( + "flag" + "log" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + + "github.com/kubernetes-csi/csi-driver-nfs/pkg/nfs" + testutil "github.com/kubernetes-csi/csi-driver-nfs/test/utils/testutils" + "github.com/onsi/ginkgo" + "github.com/onsi/gomega" + "k8s.io/kubernetes/test/e2e/framework" + "k8s.io/kubernetes/test/e2e/framework/config" +) + +const ( + kubeconfigEnvVar = "KUBECONFIG" + reportDirEnv = "ARTIFACTS" + defaultReportDir = "test/e2e" +) + +var ( + nodeID = os.Getenv("NODE_ID") + perm *uint32 + nfsDriver = nfs.NewNFSdriver(nodeID, "unix:///csi/csi.sock", perm) + defaultStorageClassParameters = map[string]string{ + "server": "nfs-server.default.svc.cluster.loca", + "share": "/", + } +) + +type testCmd struct { + command string + args []string + startLog string + endLog string +} + +var _ = ginkgo.BeforeSuite(func() { + // k8s.io/kubernetes/test/e2e/framework requires env KUBECONFIG to be set + // it does not fall back to defaults + if os.Getenv(kubeconfigEnvVar) == "" { + kubeconfig := filepath.Join(os.Getenv("HOME"), ".kube", "config") + os.Setenv(kubeconfigEnvVar, kubeconfig) + } + handleFlags() + framework.AfterReadingAllFlags(&framework.TestContext) + + if testutil.IsRunningInProw() { + // install nfs server + installNFSServer := testCmd{ + command: "make", + args: []string{"install-nfs-server"}, + startLog: "Installing NFS Server...", + endLog: "NFS Server successfully installed", + } + + e2eBootstrap := testCmd{ + command: "make", + args: []string{"e2e-bootstrap"}, + startLog: "Installing NFS CSI Driver...", + endLog: "NFS CSI Driver Installed", + } + // todo: Install metrics server once added to this driver + + execTestCmd([]testCmd{installNFSServer, e2eBootstrap}) + go func() { + nfsDriver.Run() + }() + } +}) + +var _ = ginkgo.AfterSuite(func() { + if testutil.IsRunningInProw() { + e2eTeardown := testCmd{ + command: "make", + args: []string{"e2e-teardown"}, + startLog: "Uninstalling SMB CSI Driver...", + endLog: "SMB Driver uninstalled", + } + execTestCmd([]testCmd{e2eTeardown}) + } +}) + +// handleFlags sets up all flags and parses the command line. +func handleFlags() { + config.CopyFlags(config.Flags, flag.CommandLine) + framework.RegisterCommonFlags(flag.CommandLine) + framework.RegisterClusterFlags(flag.CommandLine) + flag.Parse() +} + +func execTestCmd(cmds []testCmd) { + err := os.Chdir("../..") + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + defer func() { + err := os.Chdir("test/e2e") + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + }() + + projectRoot, err := os.Getwd() + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + gomega.Expect(strings.HasSuffix(projectRoot, "csi-driver-nfs")).To(gomega.Equal(true)) + + for _, cmd := range cmds { + log.Println(cmd.startLog) + cmdSh := exec.Command(cmd.command, cmd.args...) + cmdSh.Dir = projectRoot + cmdSh.Stdout = os.Stdout + cmdSh.Stderr = os.Stderr + err = cmdSh.Run() + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + log.Println(cmd.endLog) + } +} + +func TestE2E(t *testing.T) { + gomega.RegisterFailHandler(ginkgo.Fail) + ginkgo.RunSpecs(t, "E2e Suite") +} diff --git a/test/utils/testutils/testutils.go b/test/utils/testutils/testutils.go new file mode 100644 index 00000000..38d3705a --- /dev/null +++ b/test/utils/testutils/testutils.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 The Kubernetes Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testutil + +import "os" + +func IsRunningInProw() bool { + _, ok := os.LookupEnv("AZURE_CREDENTIALS") + return ok +}