Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,3 @@ examples/
helpers/
scripts/
test/
go.mod
go.sum
Dockerfile
Makefile
VERSION
175 changes: 175 additions & 0 deletions .github/workflows/csi-integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
name: CSI Integration Tests

on:
push:
branches:
- master

pull_request:

# Allow to run this workflow manually from the Actions tab
workflow_dispatch:

# Run this regularly, to get integration tests results against new
# Kubernetes releases.
schedule:
- cron: '15 3 * * *'

permissions:
contents: read

jobs:
test-matrix:
name: "Get Kubernetes Releases"
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: "Generate Test Matrix"
id: list
run: 'echo "tests=$(helpers/test-matrix)" >> $GITHUB_OUTPUT'

outputs:
tests: ${{ steps.list.outputs.tests }}

build-image:
name: "Build Container Image"
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Evaluate image name
run: 'helpers/image-from-ref >> $GITHUB_ENV'

- name: Extract version
run: echo "VERSION=$(cat VERSION)" >> $GITHUB_ENV

- name: Build image
run: make build

- name: Export image
run: 'docker image save "$IMAGE" -o image.tar'

- name: Store hash
run: 'shasum -a 256 image.tar | tee image.tar.sha256'

- name: Store image
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: tested-image
path: |
image.tar
image.tar.sha256
retention-days: 30d

check-csi-integration:
# Preflight: verify the CLOUDSCALE_API_TOKEN at step-level and set an output
# so the integration job can be skipped.
#
# GitHub Actions limitations motivating this:
# - `secrets` are NOT available in `jobs.<id>.if` (job-level `if`), so you cannot
# directly gate/skip a job by testing a secret there.
name: Check CSI Integration Configuration
runs-on: ubuntu-latest

outputs:
integration-enabled: ${{ steps.check.outputs.enabled }}

steps:
- id: check
name: Verify CLOUDSCALE_API_TOKEN is present
env:
CLOUDSCALE_API_TOKEN: ${{ secrets.CLOUDSCALE_API_TOKEN }}
run: |
if [ -n "$CLOUDSCALE_API_TOKEN" ]; then
echo "enabled=true" >> $GITHUB_OUTPUT
echo "CLOUDSCALE_API_TOKEN found — integration will run."
else
echo "enabled=false" >> $GITHUB_OUTPUT
echo "CLOUDSCALE_API_TOKEN not configured — skipping integration."
fi

integration:
name: "Kubernetes ${{ matrix.kubernetes }}"
runs-on: ubuntu-latest

needs:
- test-matrix
- build-image
- check-csi-integration
if: needs.check-csi-integration.outputs.integration-enabled == 'true'

strategy:
fail-fast: false
max-parallel: 1
matrix:
include: "${{ fromJson(needs.test-matrix.outputs.tests) }}"

env:
CLOUDSCALE_API_TOKEN: ${{ secrets.CLOUDSCALE_API_TOKEN }}
KUBERNETES: '${{ matrix.kubernetes }}'
SUBNET: '${{ matrix.subnet }}'
CLUSTER_PREFIX: '${{ matrix.cluster_prefix }}'
IMAGE_SOURCE: import

# Prevent integration tests from running in parallel. Ideally this should
# be seuqential, but that won't work due to the following issue:
#
# https://github.com/orgs/community/discussions/5435
#
# Instead we ensure that only one integration test per supported version
# is run at any given time.
concurrency:
group: integration-${{ matrix.kubernetes }}

steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Load image
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
with:
name: tested-image

- name: Validate hash
run: 'shasum --check image.tar.sha256'

- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod

- name: Setup Helm
uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5
with:
version: v4.2.4

- name: Evaluate image name
run: 'helpers/image-from-ref >> $GITHUB_ENV'

- name: Cleanup Leftovers
if: always()
run: helpers/cleanup

- name: Create Test Cluster
run: helpers/run-in-test-cluster

- name: Wait For CCM/CSI Startup
run: sleep 60

- name: Run Integration Tests
run: make test-integration

- name: Wait For Kubernetes-Internal Cleanup
if: always()
run: sleep 30

- name: Destroy Test Cluster
if: always()
run: helpers/cleanup
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ charts/csi-cloudscale/charts
cmd/cloudscale-csi-plugin/cloudscale-csi-plugin
k8test/
bin/

__pycache__/
26 changes: 14 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
NAME=cloudscale-csi-plugin
OS ?= linux
GO_VERSION := $(shell awk '/^go/ {print $$2}' go.mod)
ifeq ($(strip $(shell git status --porcelain 2>/dev/null)),)
GIT_TREE_STATE=clean
else
GIT_TREE_STATE=dirty
endif
GIT_TREE_STATE ?= $(shell git status --porcelain 2>/dev/null | grep -q . && echo "dirty" || echo "clean")
COMMIT ?= $(shell git rev-parse HEAD)
BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD)
LDFLAGS ?= -X github.com/cloudscale-ch/csi-cloudscale/driver.version=${VERSION} -X github.com/cloudscale-ch/csi-cloudscale/driver.commit=${COMMIT} -X github.com/cloudscale-ch/csi-cloudscale/driver.gitTreeState=${GIT_TREE_STATE}
Expand All @@ -14,6 +10,7 @@ PKG ?= github.com/cloudscale-ch/csi-cloudscale/cmd/cloudscale-csi-plugin
VERSION ?= $(shell cat VERSION)
CHART_VERSION ?= $(shell awk '/^version:/ {print $$2}' charts/csi-cloudscale/Chart.yaml)
DOCKER_REPO ?= quay.io/cloudscalech/cloudscale-csi-plugin
IMAGE ?= $(DOCKER_REPO):$(VERSION)

# Setting SHELL to bash allows bash commands to be executed by recipes.
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
Expand Down Expand Up @@ -115,13 +112,18 @@ govulncheck: govulncheck-tool ## Run govulncheck (advisory only)

.PHONY: compile
compile: ## Build the project binary
@echo "==> Building the project"
@docker run --rm -it -e GOOS=${OS} -e GOARCH=amd64 -v ${PWD}/:/app -w /app golang:${GO_VERSION}-alpine sh -c 'apk add git && go build -o cmd/cloudscale-csi-plugin/${NAME} -ldflags "$(LDFLAGS)" ${PKG}'
@echo "==> Building the binary"
CGO_ENABLED=0 go build -o cmd/cloudscale-csi-plugin/$(NAME) -ldflags "$(LDFLAGS)" $(PKG)

.PHONY: build
build: compile ## Build the docker image
build: ## Build the docker image
@echo "==> Building the docker image"
@docker build --platform linux/amd64 -t $(DOCKER_REPO):$(VERSION) cmd/cloudscale-csi-plugin -f cmd/cloudscale-csi-plugin/Dockerfile
docker build --platform linux/amd64 \
-t $(IMAGE) \
--build-arg VERSION="$(VERSION)" \
--build-arg COMMIT="$(COMMIT)" \
--build-arg GIT_TREE_STATE="$(GIT_TREE_STATE)" \
-f cmd/cloudscale-csi-plugin/Dockerfile .

.PHONY: push
push: ## Push docker image to registry
Expand All @@ -132,9 +134,9 @@ ifeq ($(DOCKER_REPO),quay.io/cloudscalech/cloudscale-csi-plugin)
endif
endif
endif
@echo "==> Publishing $(DOCKER_REPO):$(VERSION)"
@docker push $(DOCKER_REPO):$(VERSION)
@echo "==> Your image is now available at $(DOCKER_REPO):$(VERSION)"
@echo "==> Publishing $(IMAGE)"
@docker push $(IMAGE)
@echo "==> Your image is now available at $(IMAGE)"

.PHONY: publish
publish: build push clean ## Build, push, and clean
Expand Down
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,11 +418,31 @@ This will create a binary with version `dev` and docker image pushed to
`cloudscalech/cloudscale-csi-plugin:dev`


To run the integration tests run the following:
To run the integration tests locally with your local CSI build:

```
$ export KUBECONFIG=$(pwd)/kubeconfig
```bash
# 1. Build and export the CSI image
$ VERSION=dev make publish

# 2. Create a test cluster with CCM and CSI
$ export CLOUDSCALE_API_TOKEN=your-token
$ export IMAGE=quay.io/cloudscalech/cloudscale-csi-plugin:dev
$ helpers/run-in-test-cluster

# This will:
# - Create a Kubernetes cluster on cloudscale.ch
# - Deploy CCM from the latest official release
# - Deploy CSI from your local build

# 3. Run integration tests
$ export KUBECONFIG=$(pwd)/k8test/cluster/admin.conf
$ make test-integration

# Run a single test
$ TESTARGS='-run TestPod_Single_SSD_Volume' make test-integration

# 4. Clean up
$ helpers/cleanup
```


Expand Down
57 changes: 34 additions & 23 deletions cmd/cloudscale-csi-plugin/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
# Copyright 2018 DigitalOcean
#
# 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.
FROM golang:1.27-alpine AS builder

RUN apk add --no-cache git make bash

WORKDIR /src

# Copy go.mod/go.sum first for better layer caching
COPY go.mod go.sum ./
RUN go mod download

# Copy all source code
COPY . .

# Build arguments for version information
ARG VERSION=dev
ARG COMMIT=unknown
ARG GIT_TREE_STATE=unknown

# Build using make (ensures consistent build logic)
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 make compile \
VERSION="${VERSION}" \
COMMIT="${COMMIT}" \
GIT_TREE_STATE="${GIT_TREE_STATE}"

FROM alpine:3.23.3

# e2fsprogs-extra is required for resize2fs used for the resize operation
# blkid: block device identification tool from util-linux
RUN apk add --no-cache ca-certificates \
e2fsprogs \
findmnt \
xfsprogs \
cryptsetup \
udev \
blkid \
e2fsprogs-extra

ADD cloudscale-csi-plugin /bin/
ADD csi-diskinfo.sh /bin/
e2fsprogs \
findmnt \
xfsprogs \
cryptsetup \
udev \
blkid \
e2fsprogs-extra

COPY --from=builder /src/cmd/cloudscale-csi-plugin/cloudscale-csi-plugin /bin/
COPY --from=builder /src/cmd/cloudscale-csi-plugin/csi-diskinfo.sh /bin/

ENTRYPOINT ["/bin/cloudscale-csi-plugin"]
Loading
Loading