Skip to content

Commit 76f3e06

Browse files
authored
Merge pull request #150 from jingxu97/restorevolume
Pass snapshot source when creating volumes
2 parents 4e371e0 + 13e7e02 commit 76f3e06

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)