From 82e4a865dad8f8121297ee7483b9d69ee7b1c469 Mon Sep 17 00:00:00 2001
From: Cyrill Troxler <cyrilltroxler@gmail.com>
Date: Fri, 3 Aug 2018 20:30:46 +0200
Subject: [PATCH] Add ci pipeline with GitLab (#3)

* Add automated testing
* Create loop device while staging s3backer
---
 .gitlab-ci.yml                 | 30 ++++++++++++++++++++++++++++++
 Makefile                       |  2 +-
 pkg/s3/mounter_s3backer.go     |  6 ++++++
 pkg/s3/s3-driver_suite_test.go |  2 ++
 pkg/s3/util.go                 | 18 ++++++++++++++++++
 test/Dockerfile                | 12 ++++++++++--
 test/test.sh                   |  4 +++-
 7 files changed, 70 insertions(+), 4 deletions(-)
 create mode 100644 .gitlab-ci.yml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..109ed80
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,30 @@
+image:
+  name: ctrox/csi-s3:test
+  entrypoint: [""]
+
+variables:
+  DOCKER_HOST: tcp://docker:2375
+  DOCKER_DRIVER: overlay2
+  GO_PROJECT_BASE: /go/src/github.com/ctrox
+  GO_PROJECT_DIR: $GO_PROJECT_BASE/csi-s3
+
+stages:
+  - build
+  - test
+
+build:
+  stage: build
+  before_script:
+  - mkdir -p $GO_PROJECT_BASE
+  - ln -s $CI_PROJECT_DIR $GO_PROJECT_BASE
+  - cd $GO_PROJECT_DIR
+  script:
+    - make build
+
+test:
+  stage: test
+  image: docker:stable
+  services:
+    - docker:dind
+  script:
+    - docker run --rm --privileged -v $(pwd):$GO_PROJECT_DIR --device /dev/fuse ctrox/$CI_PROJECT_NAME:test
diff --git a/Makefile b/Makefile
index c7a5820..9696208 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ build:
 	CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' -o _output/s3driver ./cmd/s3driver
 test:
 	docker build -t $(TEST_IMAGE_TAG) -f test/Dockerfile .
-	docker run --rm --privileged -v $(PWD):$(PROJECT_DIR):ro -v /dev:/dev $(TEST_IMAGE_TAG)
+	docker run --rm --privileged -v $(PWD):$(PROJECT_DIR):ro --device /dev/fuse $(TEST_IMAGE_TAG)
 container: build
 	docker build -t $(IMAGE_TAG) -f cmd/s3driver/Dockerfile .
 push: container
diff --git a/pkg/s3/mounter_s3backer.go b/pkg/s3/mounter_s3backer.go
index 55d0379..25cac24 100644
--- a/pkg/s3/mounter_s3backer.go
+++ b/pkg/s3/mounter_s3backer.go
@@ -27,6 +27,8 @@ const (
 	// blockSize to use in k
 	s3backerBlockSize   = "128k"
 	s3backerDefaultSize = 1024 * 1024 * 1024 // 1GiB
+	// S3backerLoopDevice the loop device required by s3backer
+	S3backerLoopDevice = "/dev/loop0"
 )
 
 func newS3backerMounter(bucket *bucket, cfg *Config) (Mounter, error) {
@@ -55,6 +57,10 @@ func (s3backer *s3backerMounter) String() string {
 }
 
 func (s3backer *s3backerMounter) Stage(stageTarget string) error {
+	// s3backer uses the loop device
+	if err := createLoopDevice(S3backerLoopDevice); err != nil {
+		return err
+	}
 	// s3backer requires two mounts
 	// first mount will fuse mount the bucket to a single 'file'
 	if err := s3backer.mountInit(stageTarget); err != nil {
diff --git a/pkg/s3/s3-driver_suite_test.go b/pkg/s3/s3-driver_suite_test.go
index 97504ca..eb77f5c 100644
--- a/pkg/s3/s3-driver_suite_test.go
+++ b/pkg/s3/s3-driver_suite_test.go
@@ -121,6 +121,8 @@ var _ = Describe("S3Driver", func() {
 		if err := os.Remove(socket); err != nil && !os.IsNotExist(err) {
 			Expect(err).NotTo(HaveOccurred())
 		}
+		// Clear loop device so we cover the creation of it
+		os.Remove(s3.S3backerLoopDevice)
 		driver, err := s3.NewS3("test-node", csiEndpoint, cfg)
 		if err != nil {
 			log.Fatal(err)
diff --git a/pkg/s3/util.go b/pkg/s3/util.go
index 3022b8e..d85d86c 100644
--- a/pkg/s3/util.go
+++ b/pkg/s3/util.go
@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"io/ioutil"
 	"os"
+	"os/exec"
 	"strings"
 	"syscall"
 	"time"
@@ -67,3 +68,20 @@ func getCmdLine(pid int) (string, error) {
 	}
 	return string(cmdLine), nil
 }
+
+func createLoopDevice(device string) error {
+	if _, err := os.Stat(device); !os.IsNotExist(err) {
+		return nil
+	}
+	args := []string{
+		device,
+		"b", "7", "0",
+	}
+	cmd := exec.Command("mknod", args...)
+
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("Error configuring loop device: %s", out)
+	}
+	return nil
+}
diff --git a/test/Dockerfile b/test/Dockerfile
index 8d103fe..feeb4cb 100644
--- a/test/Dockerfile
+++ b/test/Dockerfile
@@ -4,17 +4,25 @@ LABEL description="csi-s3 testing image"
 
 RUN apt-get update && \
     apt-get install -y \
-      git wget && \
+      git wget make && \
     rm -rf /var/lib/apt/lists/*
 
 RUN wget -q https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz && \
     tar -xf go1.10.3.linux-amd64.tar.gz && \
+    rm go1.10.3.linux-amd64.tar.gz && \
     mv go /usr/local
 
 ENV GOROOT /usr/local/go
 ENV GOPATH /go
 ENV PATH=$GOPATH/bin:$GOROOT/bin:$PATH
 
+# install dep
+RUN wget -q https://raw.githubusercontent.com/golang/dep/master/install.sh && \
+    mkdir -p /go/bin && \
+    sh ./install.sh
+
 RUN go get -u github.com/minio/minio && go install github.com/minio/minio/cmd
 
-ENTRYPOINT ["/go/src/github.com/ctrox/csi-s3/test/test.sh"]
+ADD test/test.sh /usr/local/bin
+
+ENTRYPOINT ["/usr/local/bin/test.sh"]
diff --git a/test/test.sh b/test/test.sh
index fafb5f5..07cc30d 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -3,6 +3,8 @@ export MINIO_ACCESS_KEY=FJDSJ
 export MINIO_SECRET_KEY=DSG643HGDS
 
 mkdir -p /tmp/minio
-minio server --quiet /tmp/minio &
+minio server --quiet /tmp/minio &>/dev/null &
 sleep 5
+cd $GOPATH/src/github.com/ctrox/csi-s3
+if [ ! -d ./vendor ]; then dep ensure -vendor-only; fi
 go test github.com/ctrox/csi-s3/pkg/s3 -cover