Skip to content

Commit 13e7e02

Browse files
committed
Pass snapshot source when creating volumes
This PR adds the logic to pass the snapshot source when creating the volume so that volume can be restored from snapshot if specified. Address comments This commit addressed the comments related to parameter names etc.
1 parent 7eee10d commit 13e7e02

File tree

5 files changed

+94
-28
lines changed

5 files changed

+94
-28
lines changed

pkg/gce-cloud-provider/compute/cloud-disk.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,14 @@ func (d *CloudDisk) GetZone() string {
134134
return ""
135135
}
136136
}
137+
138+
func (d *CloudDisk) GetSnapshotId() string {
139+
switch d.Type() {
140+
case Zonal:
141+
return d.ZonalDisk.SourceSnapshotId
142+
case Regional:
143+
return d.RegionalDisk.SourceSnapshotId
144+
default:
145+
return ""
146+
}
147+
}

pkg/gce-cloud-provider/compute/fake-gce.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ func (cloud *FakeCloudProvider) ValidateExistingDisk(ctx context.Context, resp *
188188
return nil
189189
}
190190

191-
func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string) error {
191+
func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId string) error {
192192
if disk, ok := cloud.disks[volKey.Name]; ok {
193193
err := cloud.ValidateExistingDisk(ctx, disk, diskType,
194194
int64(capacityRange.GetRequiredBytes()),
@@ -202,20 +202,22 @@ func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key
202202
switch volKey.Type() {
203203
case meta.Zonal:
204204
diskToCreateGA := &compute.Disk{
205-
Name: volKey.Name,
206-
SizeGb: common.BytesToGb(capBytes),
207-
Description: "Disk created by GCE-PD CSI Driver",
208-
Type: cloud.GetDiskTypeURI(volKey, diskType),
209-
SelfLink: fmt.Sprintf("projects/%s/zones/%s/disks/%s", cloud.project, volKey.Zone, volKey.Name),
205+
Name: volKey.Name,
206+
SizeGb: common.BytesToGb(capBytes),
207+
Description: "Disk created by GCE-PD CSI Driver",
208+
Type: cloud.GetDiskTypeURI(volKey, diskType),
209+
SelfLink: fmt.Sprintf("projects/%s/zones/%s/disks/%s", cloud.project, volKey.Zone, volKey.Name),
210+
SourceSnapshotId: snapshotId,
210211
}
211212
diskToCreate = ZonalCloudDisk(diskToCreateGA)
212213
case meta.Regional:
213214
diskToCreateBeta := &computebeta.Disk{
214-
Name: volKey.Name,
215-
SizeGb: common.BytesToGb(capBytes),
216-
Description: "Regional disk created by GCE-PD CSI Driver",
217-
Type: cloud.GetDiskTypeURI(volKey, diskType),
218-
SelfLink: fmt.Sprintf("projects/%s/regions/%s/disks/%s", cloud.project, volKey.Region, volKey.Name),
215+
Name: volKey.Name,
216+
SizeGb: common.BytesToGb(capBytes),
217+
Description: "Regional disk created by GCE-PD CSI Driver",
218+
Type: cloud.GetDiskTypeURI(volKey, diskType),
219+
SelfLink: fmt.Sprintf("projects/%s/regions/%s/disks/%s", cloud.project, volKey.Region, volKey.Name),
220+
SourceSnapshotId: snapshotId,
219221
}
220222
diskToCreate = RegionalCloudDisk(diskToCreateBeta)
221223
default:

pkg/gce-cloud-provider/compute/gce-compute.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ type GCECompute interface {
4242
GetDisk(ctx context.Context, volumeKey *meta.Key) (*CloudDisk, error)
4343
RepairUnderspecifiedVolumeKey(ctx context.Context, volumeKey *meta.Key) (*meta.Key, error)
4444
ValidateExistingDisk(ctx context.Context, disk *CloudDisk, diskType string, reqBytes, limBytes int64) error
45-
InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string) error
45+
InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId string) error
4646
DeleteDisk(ctx context.Context, volumeKey *meta.Key) error
4747
AttachDisk(ctx context.Context, volKey *meta.Key, readWrite, diskType, instanceZone, instanceName string) error
4848
DetachDisk(ctx context.Context, deviceName string, instanceZone, instanceName string) error
@@ -202,24 +202,27 @@ func (cloud *CloudProvider) ValidateExistingDisk(ctx context.Context, resp *Clou
202202
return nil
203203
}
204204

205-
func (cloud *CloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string) error {
205+
func (cloud *CloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId string) error {
206206
switch volKey.Type() {
207207
case meta.Zonal:
208-
return cloud.insertZonalDisk(ctx, volKey, diskType, capBytes, capacityRange)
208+
return cloud.insertZonalDisk(ctx, volKey, diskType, capBytes, capacityRange, snapshotId)
209209
case meta.Regional:
210-
return cloud.insertRegionalDisk(ctx, volKey, diskType, capBytes, capacityRange, replicaZones)
210+
return cloud.insertRegionalDisk(ctx, volKey, diskType, capBytes, capacityRange, replicaZones, snapshotId)
211211
default:
212212
return fmt.Errorf("could not insert disk, key was neither zonal nor regional, instead got: %v", volKey.String())
213213
}
214214
}
215215

216-
func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string) error {
216+
func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId string) error {
217217
diskToCreateBeta := &computebeta.Disk{
218218
Name: volKey.Name,
219219
SizeGb: common.BytesToGb(capBytes),
220220
Description: "Regional disk created by GCE-PD CSI Driver",
221221
Type: cloud.GetDiskTypeURI(volKey, diskType),
222222
}
223+
if snapshotId != "" {
224+
diskToCreateBeta.SourceSnapshot = snapshotId
225+
}
223226
if len(replicaZones) != 0 {
224227
diskToCreateBeta.ReplicaZones = replicaZones
225228
}
@@ -264,13 +267,16 @@ func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta
264267
return nil
265268
}
266269

267-
func (cloud *CloudProvider) insertZonalDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange) error {
270+
func (cloud *CloudProvider) insertZonalDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, snapshotId string) error {
268271
diskToCreate := &compute.Disk{
269272
Name: volKey.Name,
270273
SizeGb: common.BytesToGb(capBytes),
271274
Description: "Disk created by GCE-PD CSI Driver",
272275
Type: cloud.GetDiskTypeURI(volKey, diskType),
273276
}
277+
if snapshotId != "" {
278+
diskToCreate.SourceSnapshot = snapshotId
279+
}
274280

275281
op, err := cloud.service.Disks.Insert(cloud.project, volKey.Zone, diskToCreate).Context(ctx).Do()
276282

pkg/gce-pd-csi-driver/controller.go

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,15 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
145145
return nil, status.Error(codes.AlreadyExists, fmt.Sprintf("CreateVolume disk already exists with same name and is incompatible: %v", err))
146146
}
147147
// If there is no validation error, immediately return success
148-
return generateCreateVolumeResponse(existingDisk.GetSelfLink(), capBytes, zones), nil
148+
return generateCreateVolumeResponse(existingDisk, capBytes, zones), nil
149+
}
150+
151+
snapshotId := ""
152+
content := req.GetVolumeContentSource()
153+
if content != nil {
154+
if content.GetSnapshot() != nil {
155+
snapshotId = content.GetSnapshot().GetId()
156+
}
149157
}
150158

151159
// Create the disk
@@ -155,23 +163,22 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
155163
if len(zones) != 1 {
156164
return nil, status.Errorf(codes.Internal, fmt.Sprintf("CreateVolume failed to get a single zone for creating zonal disk, instead got: %v", zones))
157165
}
158-
disk, err = createSingleZoneDisk(ctx, gceCS.CloudProvider, name, zones, diskType, capacityRange, capBytes)
166+
disk, err = createSingleZoneDisk(ctx, gceCS.CloudProvider, name, zones, diskType, capacityRange, capBytes, snapshotId)
159167
if err != nil {
160168
return nil, status.Error(codes.Internal, fmt.Sprintf("CreateVolume failed to create single zonal disk %#v: %v", name, err))
161169
}
162170
case replicationTypeRegionalPD:
163171
if len(zones) != 2 {
164172
return nil, status.Errorf(codes.Internal, fmt.Sprintf("CreateVolume failed to get a 2 zones for creating regional disk, instead got: %v", zones))
165173
}
166-
disk, err = createRegionalDisk(ctx, gceCS.CloudProvider, name, zones, diskType, capacityRange, capBytes)
174+
disk, err = createRegionalDisk(ctx, gceCS.CloudProvider, name, zones, diskType, capacityRange, capBytes, snapshotId)
167175
if err != nil {
168176
return nil, status.Error(codes.Internal, fmt.Sprintf("CreateVolume failed to create regional disk %#v: %v", name, err))
169177
}
170178
default:
171179
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("CreateVolume replication type '%s' is not supported", replicationType))
172180
}
173-
174-
return generateCreateVolumeResponse(disk.GetSelfLink(), capBytes, zones), nil
181+
return generateCreateVolumeResponse(disk, capBytes, zones), nil
175182

176183
}
177184

@@ -798,7 +805,7 @@ func getDefaultZonesInRegion(gceCS *GCEControllerServer, existingZones []string,
798805
return ret, nil
799806
}
800807

801-
func generateCreateVolumeResponse(selfLink string, capBytes int64, zones []string) *csi.CreateVolumeResponse {
808+
func generateCreateVolumeResponse(disk *gce.CloudDisk, capBytes int64, zones []string) *csi.CreateVolumeResponse {
802809
tops := []*csi.Topology{}
803810
for _, zone := range zones {
804811
tops = append(tops, &csi.Topology{
@@ -808,11 +815,23 @@ func generateCreateVolumeResponse(selfLink string, capBytes int64, zones []strin
808815
createResp := &csi.CreateVolumeResponse{
809816
Volume: &csi.Volume{
810817
CapacityBytes: capBytes,
811-
Id: cleanSelfLink(selfLink),
818+
Id: cleanSelfLink(disk.GetSelfLink()),
812819
Attributes: nil,
813820
AccessibleTopology: tops,
814821
},
815822
}
823+
snapshotId := disk.GetSnapshotId()
824+
if snapshotId != "" {
825+
source := &csi.VolumeContentSource{
826+
Type: &csi.VolumeContentSource_Snapshot{
827+
Snapshot: &csi.VolumeContentSource_SnapshotSource{
828+
Id: snapshotId,
829+
},
830+
},
831+
}
832+
createResp.Volume.ContentSource = source
833+
834+
}
816835
return createResp
817836
}
818837

@@ -821,7 +840,7 @@ func cleanSelfLink(selfLink string) string {
821840
return strings.TrimPrefix(temp, gce.GCEComputeBetaAPIEndpoint)
822841
}
823842

824-
func createRegionalDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, diskType string, capacityRange *csi.CapacityRange, capBytes int64) (*gce.CloudDisk, error) {
843+
func createRegionalDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, diskType string, capacityRange *csi.CapacityRange, capBytes int64, snapshotId string) (*gce.CloudDisk, error) {
825844
region, err := common.GetRegionFromZones(zones)
826845
if err != nil {
827846
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
833852
fullyQualifiedReplicaZones, cloudProvider.GetReplicaZoneURI(replicaZone))
834853
}
835854

836-
err = cloudProvider.InsertDisk(ctx, meta.RegionalKey(name, region), diskType, capBytes, capacityRange, fullyQualifiedReplicaZones)
855+
err = cloudProvider.InsertDisk(ctx, meta.RegionalKey(name, region), diskType, capBytes, capacityRange, fullyQualifiedReplicaZones, snapshotId)
837856
if err != nil {
838857
return nil, fmt.Errorf("failed to insert regional disk: %v", err)
839858
}
@@ -847,12 +866,12 @@ func createRegionalDisk(ctx context.Context, cloudProvider gce.GCECompute, name
847866
return disk, nil
848867
}
849868

850-
func createSingleZoneDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, diskType string, capacityRange *csi.CapacityRange, capBytes int64) (*gce.CloudDisk, error) {
869+
func createSingleZoneDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, diskType string, capacityRange *csi.CapacityRange, capBytes int64, snapshotId string) (*gce.CloudDisk, error) {
851870
if len(zones) != 1 {
852871
return nil, fmt.Errorf("got wrong number of zones for zonal create volume: %v", len(zones))
853872
}
854873
diskZone := zones[0]
855-
err := cloudProvider.InsertDisk(ctx, meta.ZonalKey(name, diskZone), diskType, capBytes, capacityRange, nil)
874+
err := cloudProvider.InsertDisk(ctx, meta.ZonalKey(name, diskZone), diskType, capBytes, capacityRange, nil, snapshotId)
856875
if err != nil {
857876
return nil, fmt.Errorf("failed to insert zonal disk: %v", err)
858877
}

pkg/gce-pd-csi-driver/controller_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,34 @@ func TestCreateVolumeArguments(t *testing.T) {
570570
},
571571
},
572572
},
573+
{
574+
name: "success with data source of snapshot type",
575+
req: &csi.CreateVolumeRequest{
576+
Name: "test-name",
577+
CapacityRange: stdCapRange,
578+
VolumeCapabilities: stdVolCap,
579+
VolumeContentSource: &csi.VolumeContentSource{
580+
Type: &csi.VolumeContentSource_Snapshot{
581+
Snapshot: &csi.VolumeContentSource_SnapshotSource{
582+
Id: "snapshot-source",
583+
},
584+
},
585+
},
586+
},
587+
expVol: &csi.Volume{
588+
CapacityBytes: common.GbToBytes(20),
589+
Id: testVolumeId,
590+
Attributes: nil,
591+
AccessibleTopology: stdTopology,
592+
ContentSource: &csi.VolumeContentSource{
593+
Type: &csi.VolumeContentSource_Snapshot{
594+
Snapshot: &csi.VolumeContentSource_SnapshotSource{
595+
Id: "snapshot-source",
596+
},
597+
},
598+
},
599+
},
600+
},
573601
}
574602

575603
// Run test cases

0 commit comments

Comments
 (0)