Skip to content

Instantly share code, notes, and snippets.

@ddebroy
Last active December 3, 2018 19:07
Show Gist options
  • Select an option

  • Save ddebroy/113e17e23abe427d6d877fb457ace22c to your computer and use it in GitHub Desktop.

Select an option

Save ddebroy/113e17e23abe427d6d877fb457ace22c to your computer and use it in GitHub Desktop.
gce-csi-patch
diff --git a/deploy/kubernetes/delete-driver.sh b/deploy/kubernetes/delete-driver.sh
index c56a0e0..c711d87 100755
--- a/deploy/kubernetes/delete-driver.sh
+++ b/deploy/kubernetes/delete-driver.sh
@@ -9,7 +9,8 @@
set -o nounset
set -o errexit
-readonly PKGDIR="${GOPATH}/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver"
+# readonly PKGDIR="${GOPATH}/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver"
+readonly PKGDIR="/home/ddebroy/v2/gcp-compute-persistent-disk-csi-driver"
source "${PKGDIR}/deploy/common.sh"
ensure_var GCE_PD_DRIVER_VERSION
@@ -19,4 +20,4 @@ readonly KUBEDEPLOY="${PKGDIR}/deploy/kubernetes/${GCE_PD_DRIVER_VERSION}"
kubectl delete -f "${KUBEDEPLOY}/node.yaml" --ignore-not-found
kubectl delete -f "${KUBEDEPLOY}/controller.yaml" --ignore-not-found
kubectl delete -f "${KUBEDEPLOY}/setup-cluster.yaml" --ignore-not-found
-kubectl delete secret cloud-sa --ignore-not-found
\ No newline at end of file
+kubectl delete secret cloud-sa --ignore-not-found
diff --git a/deploy/kubernetes/deploy-driver.sh b/deploy/kubernetes/deploy-driver.sh
index 5a7edad..d37b49e 100755
--- a/deploy/kubernetes/deploy-driver.sh
+++ b/deploy/kubernetes/deploy-driver.sh
@@ -14,7 +14,8 @@
set -o nounset
set -o errexit
-readonly PKGDIR="${GOPATH}/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver"
+#readonly PKGDIR="${GOPATH}/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver"
+readonly PKGDIR="/home/ddebroy/v2/gcp-compute-persistent-disk-csi-driver"
source "${PKGDIR}/deploy/common.sh"
ensure_var GCE_PD_SA_DIR
@@ -47,7 +48,7 @@ function check_service_account()
fi
}
-check_service_account
+# check_service_account
if ! kubectl get secret cloud-sa;
then
diff --git a/deploy/kubernetes/stable/controller.yaml b/deploy/kubernetes/stable/controller.yaml
index 658ef36..7db19e6 100644
--- a/deploy/kubernetes/stable/controller.yaml
+++ b/deploy/kubernetes/stable/controller.yaml
@@ -15,6 +15,18 @@ spec:
spec:
serviceAccount: csi-controller-sa
containers:
+ - name: csi-snapshotter
+ imagePullPolicy: Always
+ image: quay.io/k8scsi/csi-snapshotter:v0.4.0
+ args:
+ - "--v=5"
+ - "--csi-address=$(ADDRESS)"
+ env:
+ - name: ADDRESS
+ value: /csi/csi.sock
+ volumeMounts:
+ - name: socket-dir
+ mountPath: /csi
- name: csi-provisioner
imagePullPolicy: Always
image: quay.io/k8scsi/csi-provisioner:v0.4.1
@@ -42,15 +54,13 @@ spec:
mountPath: /csi
- name: gce-pd-driver
imagePullPolicy: Always
- image: gcr.io/google-containers/volume-csi/gcp-compute-persistent-disk-csi-driver:v0.2.0.beta
+ image: ddebroy/gce-snap:0.2.1
args:
- "--v=5"
- "--endpoint=$(CSI_ENDPOINT)"
env:
- name: CSI_ENDPOINT
value: unix:/csi/csi.sock
- - name: GOOGLE_APPLICATION_CREDENTIALS
- value: "/etc/cloud-sa/cloud-sa.json"
volumeMounts:
- name: socket-dir
mountPath: /csi
@@ -62,4 +72,4 @@ spec:
emptyDir: {}
- name: cloud-sa-volume
secret:
- secretName: cloud-sa
\ No newline at end of file
+ secretName: cloud-sa
diff --git a/deploy/kubernetes/stable/node.yaml b/deploy/kubernetes/stable/node.yaml
index d9e2ec9..f059a8f 100644
--- a/deploy/kubernetes/stable/node.yaml
+++ b/deploy/kubernetes/stable/node.yaml
@@ -37,7 +37,7 @@ spec:
securityContext:
privileged: true
imagePullPolicy: Always
- image: gcr.io/google-containers/volume-csi/gcp-compute-persistent-disk-csi-driver:v0.2.0.beta
+ image: ddebroy/gce-snap:0.2.1
args:
- "--v=5"
- "--endpoint=$(CSI_ENDPOINT)"
diff --git a/deploy/kubernetes/stable/setup-cluster.yaml b/deploy/kubernetes/stable/setup-cluster.yaml
index 24ae7f1..8268a68 100644
--- a/deploy/kubernetes/stable/setup-cluster.yaml
+++ b/deploy/kubernetes/stable/setup-cluster.yaml
@@ -1,3 +1,32 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: system:csi-external-snapshotter
+rules:
+- apiGroups: ["snapshot.storage.k8s.io"]
+ resources: ["volumesnapshotclasses"]
+ verbs: ["get", "list", "watch"]
+- apiGroups: ["snapshot.storage.k8s.io"]
+ resources: ["volumesnapshotcontents"]
+ verbs: ["create", "get", "list", "watch", "update", "delete"]
+- apiGroups: ["snapshot.storage.k8s.io"]
+ resources: ["volumesnapshots"]
+ verbs: ["get", "list", "watch", "update"]
+- apiGroups: ["apiextensions.k8s.io"]
+ resources: ["customresourcedefinitions"]
+ verbs: ["create", "list", "watch", "delete"]
+- apiGroups: [""]
+ resources: ["events"]
+ verbs: ["list", "watch", "create", "update", "patch"]
+- apiGroups: ["storage.k8s.io"]
+ resources: ["storageclasses"]
+ verbs: ["watch", "get", "list"]
+- apiGroups: ["admissionregistration.k8s.io"]
+ resources: ["mutatingwebhookconfigurations"]
+ verbs: ["create"]
+
+---
+
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
@@ -59,6 +88,21 @@ roleRef:
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
+ name: csi-controller-snapshotter-binding
+subjects:
+ - kind: ServiceAccount
+ name: csi-controller-sa
+ namespace: default
+roleRef:
+ kind: ClusterRole
+ name: system:csi-external-snapshotter
+ apiGroup: rbac.authorization.k8s.io
+
+---
+
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
name: csi-controller-provisioner-binding
subjects:
- kind: ServiceAccount
@@ -67,4 +111,4 @@ subjects:
roleRef:
kind: ClusterRole
name: system:csi-external-provisioner
- apiGroup: rbac.authorization.k8s.io
\ No newline at end of file
+ apiGroup: rbac.authorization.k8s.io
diff --git a/pkg/gce-cloud-provider/compute/cloud-disk.go b/pkg/gce-cloud-provider/compute/cloud-disk.go
index 33992e1..7d35670 100644
--- a/pkg/gce-cloud-provider/compute/cloud-disk.go
+++ b/pkg/gce-cloud-provider/compute/cloud-disk.go
@@ -134,3 +134,14 @@ func (d *CloudDisk) GetZone() string {
return ""
}
}
+
+func (d *CloudDisk) GetSnapshotId() string {
+ switch d.Type() {
+ case Zonal:
+ return d.ZonalDisk.SourceSnapshotId
+ case Regional:
+ return d.RegionalDisk.SourceSnapshotId
+ default:
+ return ""
+ }
+}
diff --git a/pkg/gce-cloud-provider/compute/fake-gce.go b/pkg/gce-cloud-provider/compute/fake-gce.go
index c272c5b..6febee0 100644
--- a/pkg/gce-cloud-provider/compute/fake-gce.go
+++ b/pkg/gce-cloud-provider/compute/fake-gce.go
@@ -188,7 +188,7 @@ func (cloud *FakeCloudProvider) ValidateExistingDisk(ctx context.Context, resp *
return nil
}
-func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string) error {
+func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId string) error {
if disk, ok := cloud.disks[volKey.Name]; ok {
err := cloud.ValidateExistingDisk(ctx, disk, diskType,
int64(capacityRange.GetRequiredBytes()),
@@ -202,20 +202,22 @@ func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key
switch volKey.Type() {
case meta.Zonal:
diskToCreateGA := &compute.Disk{
- Name: volKey.Name,
- SizeGb: common.BytesToGb(capBytes),
- Description: "Disk created by GCE-PD CSI Driver",
- Type: cloud.GetDiskTypeURI(volKey, diskType),
- SelfLink: fmt.Sprintf("projects/%s/zones/%s/disks/%s", cloud.project, volKey.Zone, volKey.Name),
+ Name: volKey.Name,
+ SizeGb: common.BytesToGb(capBytes),
+ Description: "Disk created by GCE-PD CSI Driver",
+ Type: cloud.GetDiskTypeURI(volKey, diskType),
+ SelfLink: fmt.Sprintf("projects/%s/zones/%s/disks/%s", cloud.project, volKey.Zone, volKey.Name),
+ SourceSnapshotId: snapshotId,
}
diskToCreate = ZonalCloudDisk(diskToCreateGA)
case meta.Regional:
diskToCreateBeta := &computebeta.Disk{
- Name: volKey.Name,
- SizeGb: common.BytesToGb(capBytes),
- Description: "Regional disk created by GCE-PD CSI Driver",
- Type: cloud.GetDiskTypeURI(volKey, diskType),
- SelfLink: fmt.Sprintf("projects/%s/regions/%s/disks/%s", cloud.project, volKey.Region, volKey.Name),
+ Name: volKey.Name,
+ SizeGb: common.BytesToGb(capBytes),
+ Description: "Regional disk created by GCE-PD CSI Driver",
+ Type: cloud.GetDiskTypeURI(volKey, diskType),
+ SelfLink: fmt.Sprintf("projects/%s/regions/%s/disks/%s", cloud.project, volKey.Region, volKey.Name),
+ SourceSnapshotId: snapshotId,
}
diskToCreate = RegionalCloudDisk(diskToCreateBeta)
default:
diff --git a/pkg/gce-cloud-provider/compute/gce-compute.go b/pkg/gce-cloud-provider/compute/gce-compute.go
index c745f1a..ab9eb25 100644
--- a/pkg/gce-cloud-provider/compute/gce-compute.go
+++ b/pkg/gce-cloud-provider/compute/gce-compute.go
@@ -42,7 +42,7 @@ type GCECompute interface {
GetDisk(ctx context.Context, volumeKey *meta.Key) (*CloudDisk, error)
RepairUnderspecifiedVolumeKey(ctx context.Context, volumeKey *meta.Key) (*meta.Key, error)
ValidateExistingDisk(ctx context.Context, disk *CloudDisk, diskType string, reqBytes, limBytes int64) error
- InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string) error
+ InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId string) error
DeleteDisk(ctx context.Context, volumeKey *meta.Key) error
AttachDisk(ctx context.Context, volKey *meta.Key, readWrite, diskType, instanceZone, instanceName string) error
DetachDisk(ctx context.Context, deviceName string, instanceZone, instanceName string) error
@@ -202,24 +202,27 @@ func (cloud *CloudProvider) ValidateExistingDisk(ctx context.Context, resp *Clou
return nil
}
-func (cloud *CloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string) error {
+func (cloud *CloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId string) error {
switch volKey.Type() {
case meta.Zonal:
- return cloud.insertZonalDisk(ctx, volKey, diskType, capBytes, capacityRange)
+ return cloud.insertZonalDisk(ctx, volKey, diskType, capBytes, capacityRange, snapshotId)
case meta.Regional:
- return cloud.insertRegionalDisk(ctx, volKey, diskType, capBytes, capacityRange, replicaZones)
+ return cloud.insertRegionalDisk(ctx, volKey, diskType, capBytes, capacityRange, replicaZones, snapshotId)
default:
return fmt.Errorf("could not insert disk, key was neither zonal nor regional, instead got: %v", volKey.String())
}
}
-func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string) error {
+func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId string) error {
diskToCreateBeta := &computebeta.Disk{
Name: volKey.Name,
SizeGb: common.BytesToGb(capBytes),
Description: "Regional disk created by GCE-PD CSI Driver",
Type: cloud.GetDiskTypeURI(volKey, diskType),
}
+ if snapshotId != "" {
+ diskToCreateBeta.SourceSnapshot = snapshotId
+ }
if len(replicaZones) != 0 {
diskToCreateBeta.ReplicaZones = replicaZones
}
@@ -264,13 +267,16 @@ func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta
return nil
}
-func (cloud *CloudProvider) insertZonalDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange) error {
+func (cloud *CloudProvider) insertZonalDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, snapshotId string) error {
diskToCreate := &compute.Disk{
Name: volKey.Name,
SizeGb: common.BytesToGb(capBytes),
Description: "Disk created by GCE-PD CSI Driver",
Type: cloud.GetDiskTypeURI(volKey, diskType),
}
+ if snapshotId != "" {
+ diskToCreate.SourceSnapshot = snapshotId
+ }
op, err := cloud.service.Disks.Insert(cloud.project, volKey.Zone, diskToCreate).Context(ctx).Do()
diff --git a/pkg/gce-pd-csi-driver/controller.go b/pkg/gce-pd-csi-driver/controller.go
index 1cbd809..489a27d 100644
--- a/pkg/gce-pd-csi-driver/controller.go
+++ b/pkg/gce-pd-csi-driver/controller.go
@@ -145,7 +145,15 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
return nil, status.Error(codes.AlreadyExists, fmt.Sprintf("CreateVolume disk already exists with same name and is incompatible: %v", err))
}
// If there is no validation error, immediately return success
- return generateCreateVolumeResponse(existingDisk.GetSelfLink(), capBytes, zones), nil
+ return generateCreateVolumeResponse(existingDisk, capBytes, zones), nil
+ }
+
+ snapshotId := ""
+ content := req.GetVolumeContentSource()
+ if content != nil {
+ if content.GetSnapshot() != nil {
+ snapshotId = content.GetSnapshot().GetId()
+ }
}
// Create the disk
@@ -155,7 +163,7 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
if len(zones) != 1 {
return nil, status.Errorf(codes.Internal, fmt.Sprintf("CreateVolume failed to get a single zone for creating zonal disk, instead got: %v", zones))
}
- disk, err = createSingleZoneDisk(ctx, gceCS.CloudProvider, name, zones, diskType, capacityRange, capBytes)
+ disk, err = createSingleZoneDisk(ctx, gceCS.CloudProvider, name, zones, diskType, capacityRange, capBytes, snapshotId)
if err != nil {
return nil, status.Error(codes.Internal, fmt.Sprintf("CreateVolume failed to create single zonal disk %#v: %v", name, err))
}
@@ -163,15 +171,14 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
if len(zones) != 2 {
return nil, status.Errorf(codes.Internal, fmt.Sprintf("CreateVolume failed to get a 2 zones for creating regional disk, instead got: %v", zones))
}
- disk, err = createRegionalDisk(ctx, gceCS.CloudProvider, name, zones, diskType, capacityRange, capBytes)
+ disk, err = createRegionalDisk(ctx, gceCS.CloudProvider, name, zones, diskType, capacityRange, capBytes, snapshotId)
if err != nil {
return nil, status.Error(codes.Internal, fmt.Sprintf("CreateVolume failed to create regional disk %#v: %v", name, err))
}
default:
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("CreateVolume replication type '%s' is not supported", replicationType))
}
-
- return generateCreateVolumeResponse(disk.GetSelfLink(), capBytes, zones), nil
+ return generateCreateVolumeResponse(disk, capBytes, zones), nil
}
@@ -798,7 +805,7 @@ func getDefaultZonesInRegion(gceCS *GCEControllerServer, existingZones []string,
return ret, nil
}
-func generateCreateVolumeResponse(selfLink string, capBytes int64, zones []string) *csi.CreateVolumeResponse {
+func generateCreateVolumeResponse(disk *gce.CloudDisk, capBytes int64, zones []string) *csi.CreateVolumeResponse {
tops := []*csi.Topology{}
for _, zone := range zones {
tops = append(tops, &csi.Topology{
@@ -808,11 +815,23 @@ func generateCreateVolumeResponse(selfLink string, capBytes int64, zones []strin
createResp := &csi.CreateVolumeResponse{
Volume: &csi.Volume{
CapacityBytes: capBytes,
- Id: cleanSelfLink(selfLink),
+ Id: cleanSelfLink(disk.GetSelfLink()),
Attributes: nil,
AccessibleTopology: tops,
},
}
+ snapshotId := disk.GetSnapshotId()
+ if snapshotId != "" {
+ source := &csi.VolumeContentSource{
+ Type: &csi.VolumeContentSource_Snapshot{
+ Snapshot: &csi.VolumeContentSource_SnapshotSource{
+ Id: snapshotId,
+ },
+ },
+ }
+ createResp.Volume.ContentSource = source
+
+ }
return createResp
}
@@ -821,7 +840,7 @@ func cleanSelfLink(selfLink string) string {
return strings.TrimPrefix(temp, gce.GCEComputeBetaAPIEndpoint)
}
-func createRegionalDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, diskType string, capacityRange *csi.CapacityRange, capBytes int64) (*gce.CloudDisk, error) {
+func createRegionalDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, diskType string, capacityRange *csi.CapacityRange, capBytes int64, snapshotId string) (*gce.CloudDisk, error) {
region, err := common.GetRegionFromZones(zones)
if err != nil {
return nil, fmt.Errorf("failed to get region from zones: %v", err)
@@ -833,7 +852,7 @@ func createRegionalDisk(ctx context.Context, cloudProvider gce.GCECompute, name
fullyQualifiedReplicaZones, cloudProvider.GetReplicaZoneURI(replicaZone))
}
- err = cloudProvider.InsertDisk(ctx, meta.RegionalKey(name, region), diskType, capBytes, capacityRange, fullyQualifiedReplicaZones)
+ err = cloudProvider.InsertDisk(ctx, meta.RegionalKey(name, region), diskType, capBytes, capacityRange, fullyQualifiedReplicaZones, snapshotId)
if err != nil {
return nil, fmt.Errorf("failed to insert regional disk: %v", err)
}
@@ -847,12 +866,12 @@ func createRegionalDisk(ctx context.Context, cloudProvider gce.GCECompute, name
return disk, nil
}
-func createSingleZoneDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, diskType string, capacityRange *csi.CapacityRange, capBytes int64) (*gce.CloudDisk, error) {
+func createSingleZoneDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, diskType string, capacityRange *csi.CapacityRange, capBytes int64, snapshotId string) (*gce.CloudDisk, error) {
if len(zones) != 1 {
return nil, fmt.Errorf("got wrong number of zones for zonal create volume: %v", len(zones))
}
diskZone := zones[0]
- err := cloudProvider.InsertDisk(ctx, meta.ZonalKey(name, diskZone), diskType, capBytes, capacityRange, nil)
+ err := cloudProvider.InsertDisk(ctx, meta.ZonalKey(name, diskZone), diskType, capBytes, capacityRange, nil, snapshotId)
if err != nil {
return nil, fmt.Errorf("failed to insert zonal disk: %v", err)
}
diff --git a/pkg/gce-pd-csi-driver/controller_test.go b/pkg/gce-pd-csi-driver/controller_test.go
index c62e943..e1ee7e8 100644
--- a/pkg/gce-pd-csi-driver/controller_test.go
+++ b/pkg/gce-pd-csi-driver/controller_test.go
@@ -570,6 +570,34 @@ func TestCreateVolumeArguments(t *testing.T) {
},
},
},
+ {
+ name: "success with data source of snapshot type",
+ req: &csi.CreateVolumeRequest{
+ Name: "test-name",
+ CapacityRange: stdCapRange,
+ VolumeCapabilities: stdVolCap,
+ VolumeContentSource: &csi.VolumeContentSource{
+ Type: &csi.VolumeContentSource_Snapshot{
+ Snapshot: &csi.VolumeContentSource_SnapshotSource{
+ Id: "snapshot-source",
+ },
+ },
+ },
+ },
+ expVol: &csi.Volume{
+ CapacityBytes: common.GbToBytes(20),
+ Id: testVolumeId,
+ Attributes: nil,
+ AccessibleTopology: stdTopology,
+ ContentSource: &csi.VolumeContentSource{
+ Type: &csi.VolumeContentSource_Snapshot{
+ Snapshot: &csi.VolumeContentSource_SnapshotSource{
+ Id: "snapshot-source",
+ },
+ },
+ },
+ },
+ },
}
// Run test cases
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment