Skip to content

Commit 677055a

Browse files
committed
add support for deletesnaps & CRDs required for volume snapshot
1 parent 739333b commit 677055a

File tree

8 files changed

+1010
-7
lines changed

8 files changed

+1010
-7
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
**Fork Notice:**
2+
3+
This repo is a fork of the Leaseweb's maitained cloudstack-csi-driver, which is in-turn a fork of Apalia's cloudstack-csi-driver
4+
15
# CloudStack CSI Driver
26

37
[![Go Reference](https://pkg.go.dev/badge/github.com/shapeblue/cloudstack-csi-driver.svg)](https://pkg.go.dev/github.com/shapeblue/cloudstack-csi-driver)
@@ -83,6 +87,17 @@ disk offerings to Kubernetes storage classes.
8387

8488
[More info...](./cmd/cloudstack-csi-sc-syncer/README.md)
8589

90+
> **Note:** The VolumeSnapshot CRDs (CustomResourceDefinitions) of version 8.3.0 are installed in this deployment. If you use a different version, please ensure compatibility with your Kubernetes cluster and CSI sidecars.
91+
92+
// TODO: Ask Wei / Rohit - should we have the crds locally or manually install it from:
93+
94+
```
95+
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.3.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
96+
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.3.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
97+
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.3.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
98+
99+
```
100+
86101
### Usage
87102

88103
Example:

deploy/snapshot-cdrs.yaml

Lines changed: 955 additions & 0 deletions
Large diffs are not rendered by default.

examples/k8s/snapshot/pvc.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ spec:
88
resources:
99
requests:
1010
storage: 10Gi
11-
storageClassName: cloudstack-custom
11+
storageClassName: cloudstack-custom

examples/k8s/snapshot/snapshot.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ metadata:
55
spec:
66
volumeSnapshotClassName: cloudstack-snapshot
77
source:
8-
persistentVolumeClaimName: my-pvc
8+
persistentVolumeClaimName: my-pvc

pkg/cloud/cloud.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type Interface interface {
2525
ExpandVolume(ctx context.Context, volumeID string, newSizeInGB int64) error
2626

2727
CreateVolumeFromSnapshot(ctx context.Context, diskOfferingID, zoneID, name, domainID, projectID, snapshotID string, sizeInGB int64) (string, error)
28+
GetSnapshotByID(ctx context.Context, snapshotID ...string) (*Snapshot, error)
2829
CreateSnapshot(ctx context.Context, volumeID string) (*Snapshot, error)
2930
DeleteSnapshot(ctx context.Context, snapshotID string) error
3031
}

pkg/cloud/fake/fake.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
)
1313

1414
const zoneID = "a1887604-237c-4212-a9cd-94620b7880fa"
15+
const snapshotID = "9d076136-657b-4c84-b279-455da3ea484c"
1516

1617
type fakeConnector struct {
1718
node *cloud.VM
@@ -41,7 +42,7 @@ func New() cloud.Interface {
4142
ID: "9d076136-657b-4c84-b279-455da3ea484c",
4243
Name: "pvc-vol-snap-1",
4344
DomainID: "51f0fcb5-db16-4637-94f5-30131010214f",
44-
ZoneID: "bdab539f-651e-431a-979d-5d3c48b54fcf",
45+
ZoneID: zoneID,
4546
VolumeID: "4f1f610d-6f17-4ff9-9228-e4062af93e54",
4647
CreatedAt: "2025-07-07 16:13:06",
4748
}
@@ -140,6 +141,10 @@ func (f *fakeConnector) CreateVolumeFromSnapshot(ctx context.Context, diskOfferi
140141
return "1", nil
141142
}
142143

144+
func (f *fakeConnector) GetSnapshotByID(ctx context.Context, snapshotID ...string) (*cloud.Snapshot, error) {
145+
return f.snapshot, nil
146+
}
147+
143148
func (f *fakeConnector) CreateSnapshot(ctx context.Context, volumeID string) (*cloud.Snapshot, error) {
144149
return f.snapshot, nil
145150
}

pkg/cloud/snapshots.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ import (
44
"context"
55
"strings"
66

7-
"github.com/apache/cloudstack-go/v2/cloudstack"
87
"google.golang.org/grpc/codes"
98
"google.golang.org/grpc/status"
109
)
1110

12-
func (c *client) ListSnapshots(p *cloudstack.ListSnapshotsParams) (*Snapshot, error) {
11+
func (c *client) GetSnapshotByID(ctx context.Context, snapshotID ...string) (*Snapshot, error) {
12+
p := c.Snapshot.NewListSnapshotsParams()
13+
if snapshotID != nil {
14+
p.SetId(snapshotID[0])
15+
}
1316
l, err := c.Snapshot.ListSnapshots(p)
1417
if err != nil {
1518
return nil, err

pkg/driver/controller.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ func (cs *controllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol
295295
return &csi.DeleteVolumeResponse{}, nil
296296
}
297297

298-
// CreateSnapshot call blockstorage SnapshotVolume.
299298
func (cs *controllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateSnapshotRequest) (*csi.CreateSnapshotResponse, error) {
300299
klog.V(4).Infof("CreateSnapshot")
301300

@@ -312,7 +311,7 @@ func (cs *controllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateS
312311
return nil, status.Errorf(codes.Internal, "Failed to create snapshot %s: %v", snapshot.ID, err.Error())
313312
}
314313

315-
t, err := time.Parse(time.RFC3339, snapshot.CreatedAt)
314+
t, err := time.Parse("2006-01-02T15:04:05-0700", snapshot.CreatedAt)
316315
if err != nil {
317316
panic(err)
318317
}
@@ -333,6 +332,31 @@ func (cs *controllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateS
333332

334333
}
335334

335+
func (cs *controllerServer) DeleteSnapshot(ctx context.Context, req *csi.DeleteSnapshotRequest) (*csi.DeleteSnapshotResponse, error) {
336+
klog.V(4).Infof("DeleteSnapshot")
337+
338+
snapshotID := req.GetSnapshotId()
339+
340+
if snapshotID == "" {
341+
return nil, status.Error(codes.InvalidArgument, "Snapshot ID missing in request")
342+
}
343+
344+
snapshot, err := cs.connector.GetSnapshotByID(ctx, snapshotID)
345+
if errors.Is(err, cloud.ErrNotFound) {
346+
return nil, status.Errorf(codes.NotFound, "Snapshot %v not found", snapshotID)
347+
} else if err != nil {
348+
// Error with CloudStack
349+
return nil, status.Errorf(codes.Internal, "Error %v", err)
350+
}
351+
352+
err = cs.connector.DeleteSnapshot(ctx, snapshot.ID)
353+
if err != nil && !errors.Is(err, cloud.ErrNotFound) {
354+
return nil, status.Errorf(codes.Internal, "Cannot delete snapshot %s: %s", snapshotID, err.Error())
355+
}
356+
357+
return &csi.DeleteSnapshotResponse{}, nil
358+
}
359+
336360
func (cs *controllerServer) ControllerPublishVolume(ctx context.Context, req *csi.ControllerPublishVolumeRequest) (*csi.ControllerPublishVolumeResponse, error) {
337361
logger := klog.FromContext(ctx)
338362
logger.V(6).Info("ControllerPublishVolume: called", "args", *req)

0 commit comments

Comments
 (0)