Skip to content

Commit 1a298e4

Browse files
authored
Merge pull request #1 from serverscom/init
init csi driver
2 parents ea78c7b + e29ab01 commit 1a298e4

33 files changed

+4345
-0
lines changed

.github/workflows/goreleaser.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
name: goreleaser
3+
on:
4+
push:
5+
tags:
6+
- v*
7+
jobs:
8+
goreleaser:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout
12+
uses: actions/checkout@v5
13+
with:
14+
fetch-depth: 0
15+
- name: Set up Go
16+
uses: actions/setup-go@v5
17+
with:
18+
go-version: "1.24"
19+
- name: Set up QEMU
20+
uses: docker/setup-qemu-action@v2
21+
- name: Setup Docker Buildx
22+
uses: docker/setup-buildx-action@v2
23+
- name: Login to GHCR
24+
uses: docker/login-action@v2
25+
with:
26+
registry: ghcr.io
27+
username: ${{ github.actor }}
28+
password: ${{ secrets.GITHUB_TOKEN }}
29+
- name: Run GoReleaser for tag
30+
if: "startsWith(github.ref, 'refs/tags/')"
31+
uses: goreleaser/goreleaser-action@v6
32+
with:
33+
version: latest
34+
args: release --clean
35+
env:
36+
GORELEASER_CURRENT_TAG: ${{ github.ref_name }}
37+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38+
- name: Clear
39+
if: always()
40+
run: rm -f ${HOME}/.docker/config.json

.github/workflows/test.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
on: [push, pull_request]
2+
name: Test
3+
jobs:
4+
test:
5+
strategy:
6+
matrix:
7+
go-version: [1.24.x, 1.25.x]
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Install Go
11+
uses: actions/setup-go@v2
12+
with:
13+
go-version: ${{ matrix.go-version }}
14+
- name: Checkout code
15+
uses: actions/checkout@v2
16+
- name: Test
17+
run: go test ./...

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
vendor
2+
dist

.goreleaser.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
version: 2
3+
4+
before:
5+
hooks:
6+
- go mod tidy
7+
- ./scripts/build-deploy-manifest.sh {{ .Version }}
8+
9+
builds:
10+
- id: controller
11+
main: ./cmd/controller
12+
binary: rbs-csi-controller
13+
goos:
14+
- linux
15+
goarch:
16+
- amd64
17+
- arm64
18+
ldflags:
19+
- -s -w
20+
- -X main.version={{ .Version }}
21+
- -X main.gitCommit={{ .ShortCommit }}
22+
- id: node
23+
main: ./cmd/node
24+
binary: rbs-csi-node
25+
goos:
26+
- linux
27+
goarch:
28+
- amd64
29+
- arm64
30+
ldflags:
31+
- -s -w
32+
- -X main.version={{ .Version }}
33+
- -X main.gitCommit={{ .ShortCommit }}
34+
35+
dockers:
36+
- dockerfile: Dockerfile
37+
build_flag_templates:
38+
- "--platform=linux/amd64"
39+
goarch: amd64
40+
image_templates: ["ghcr.io/serverscom/rbs-csi-driver:v{{ .Version }}-amd64"]
41+
use: buildx
42+
ids:
43+
- controller
44+
- node
45+
- dockerfile: Dockerfile
46+
build_flag_templates:
47+
- "--platform=linux/arm64"
48+
goarch: arm64
49+
image_templates: ["ghcr.io/serverscom/rbs-csi-driver:v{{ .Version }}-arm64v8"]
50+
use: buildx
51+
ids:
52+
- controller
53+
- node
54+
55+
docker_manifests:
56+
- name_template: ghcr.io/serverscom/rbs-csi-driver:v{{ .Version }}
57+
image_templates:
58+
- ghcr.io/serverscom/rbs-csi-driver:v{{ .Version }}-amd64
59+
- ghcr.io/serverscom/rbs-csi-driver:v{{ .Version }}-arm64v8
60+
61+
release:
62+
draft: true
63+
extra_files:
64+
- glob: "rbs-csi-deploy-*.yaml"

Dockerfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM debian:bookworm-slim
2+
3+
# Install necessary packages for iSCSI support
4+
RUN apt-get update && apt-get install -y \
5+
open-iscsi \
6+
util-linux \
7+
e2fsprogs \
8+
xfsprogs \
9+
ca-certificates \
10+
&& rm -rf /var/lib/apt/lists/*
11+
12+
# Copy the binaries (GoReleaser automatically copies them)
13+
COPY rbs-csi-controller /bin/rbs-csi-controller
14+
COPY rbs-csi-node /bin/rbs-csi-node
15+
16+
# Default entrypoint (can be overridden)
17+
ENTRYPOINT ["/bin/rbs-csi-controller"]

README.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# RBS CSI Driver
2+
3+
Kubernetes CSI driver for Remote Block Storage (RBS) - dynamic provisioning and management of iSCSI block volumes.
4+
5+
## Features
6+
7+
- Dynamic volume provisioning via RBS API
8+
- iSCSI block device attachment
9+
- Online volume expansion
10+
- Multiple filesystems: ext4, ext3, xfs, btrfs
11+
- CHAP authentication
12+
- **PVC naming** - volumes named by PVC instead of UUID
13+
- **Label propagation** - StorageClass → PVC → RBS volume labels
14+
- **Idempotent operations** - safe retries via label lookup
15+
16+
## Quick Start
17+
18+
```bash
19+
# 1. Create credentials secret
20+
kubectl create secret generic rbs-csi-secret \
21+
--from-literal=api-url="https://api.servers.com/v1" \
22+
--from-literal=api-token="your-api-token" \
23+
--namespace=kube-system
24+
25+
# 2. Deploy driver
26+
kubectl apply -f deploy/rbac.yaml
27+
kubectl apply -f deploy/csi-driver.yaml
28+
kubectl apply -f deploy/controller.yaml
29+
kubectl apply -f deploy/node-daemonset.yaml
30+
31+
# 3. Create StorageClass
32+
kubectl apply -f examples/storageclass.yaml
33+
34+
# 4. Create PVC
35+
kubectl apply -f examples/pvc.yaml
36+
```
37+
38+
## Configuration
39+
40+
### StorageClass Parameters
41+
42+
```yaml
43+
apiVersion: storage.k8s.io/v1
44+
kind: StorageClass
45+
metadata:
46+
name: rbs-ssd
47+
labels:
48+
environment: production
49+
provisioner: rbs.csi.servers.com
50+
parameters:
51+
rbs.csi.servers.com/location: "40"
52+
rbs.csi.servers.com/flavor: "16997"
53+
# names for location and flavor also supported
54+
# rbs.csi.servers.com/flavor: "SSD-High"
55+
# rbs.csi.servers.com/location: "AMS1"
56+
rbs.csi.servers.com/labels: |
57+
{
58+
"managed-by": "kubernetes"
59+
}
60+
allowVolumeExpansion: true
61+
volumeBindingMode: WaitForFirstConsumer
62+
```
63+
64+
## Label Propagation
65+
66+
Labels merge with priority: **System > PVC > StorageClass**
67+
68+
Example:
69+
```yaml
70+
# StorageClass labels
71+
metadata:
72+
labels:
73+
environment: production
74+
75+
---
76+
# PVC labels
77+
metadata:
78+
labels:
79+
app: database
80+
environment: staging # Overrides StorageClass
81+
82+
# Result on RBS volume:
83+
# {
84+
# "pvc-uuid": "abc-123",
85+
# "pvc-namespace": "default",
86+
# "app": "database",
87+
# "environment": "staging"
88+
# }
89+
```
90+
91+
## Architecture
92+
93+
**CSI Controller** (Deployment):
94+
- CreateVolume, DeleteVolume, ExpandVolume
95+
- RBS API integration
96+
97+
**CSI Node** (DaemonSet):
98+
- StageVolume, UnstageVolume
99+
- iSCSI discovery and login
100+
- Filesystem formatting and mounting
101+
102+
## Examples
103+
104+
### Basic PVC
105+
106+
```yaml
107+
apiVersion: v1
108+
kind: PersistentVolumeClaim
109+
metadata:
110+
name: my-data
111+
labels:
112+
app: nginx
113+
spec:
114+
accessModes:
115+
- ReadWriteOnce
116+
storageClassName: rbs-ssd
117+
resources:
118+
requests:
119+
storage: 10Gi
120+
```
121+
122+
### Volume Expansion
123+
124+
```yaml
125+
spec:
126+
resources:
127+
requests:
128+
storage: 20Gi # Increased from 10Gi
129+
```
130+
131+
132+
## License
133+
134+
Apache 2.0

cmd/controller/main.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"flag"
6+
"os"
7+
"os/signal"
8+
"syscall"
9+
10+
"github.com/serverscom/rbs-csi-driver/pkg/controller"
11+
"github.com/serverscom/rbs-csi-driver/pkg/util"
12+
"k8s.io/klog/v2"
13+
)
14+
15+
var (
16+
endpoint = flag.String("endpoint", "unix:///var/lib/csi/sockets/pluginproxy/csi.sock", "CSI endpoint")
17+
version = "dev"
18+
gitCommit = "none"
19+
)
20+
21+
func main() {
22+
klog.InitFlags(nil)
23+
flag.Parse()
24+
defer klog.Flush()
25+
26+
apiToken := os.Getenv(util.ScTokenEnvKey)
27+
if apiToken == "" {
28+
klog.Fatalf("environment variable %q is required", util.ScTokenEnvKey)
29+
}
30+
31+
apiBaseURL := os.Getenv(util.ScBaseUrlEnvKey)
32+
33+
klog.V(1).InfoS("Starting RBS CSI Controller",
34+
"csi_endpoint", endpoint,
35+
"api_base_url", apiBaseURL,
36+
"version", version,
37+
"commit", gitCommit,
38+
)
39+
40+
config := &controller.Config{
41+
Endpoint: *endpoint,
42+
RBSAPIUrl: apiBaseURL,
43+
RBSAPIToken: apiToken,
44+
}
45+
46+
ctrl, err := controller.NewController(config)
47+
if err != nil {
48+
klog.Fatalf("Failed to create controller: %v", err)
49+
}
50+
51+
ctx, cancel := context.WithCancel(context.Background())
52+
defer cancel()
53+
54+
sigCh := make(chan os.Signal, 1)
55+
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
56+
go func() {
57+
<-sigCh
58+
klog.Info("Received shutdown signal")
59+
cancel()
60+
}()
61+
62+
klog.Info("Starting CSI controller service...")
63+
if err := ctrl.Run(ctx); err != nil {
64+
klog.Fatalf("Failed to run CSI controller: %v", err)
65+
}
66+
}

0 commit comments

Comments
 (0)