@@ -23,6 +23,7 @@ import (
23
23
24
24
"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta"
25
25
csi "github.com/container-storage-interface/spec/lib/go/csi"
26
+ computealpha "google.golang.org/api/compute/v0.alpha"
26
27
computev1 "google.golang.org/api/compute/v1"
27
28
"google.golang.org/grpc/codes"
28
29
"google.golang.org/grpc/status"
@@ -42,7 +43,7 @@ type GCECompute interface {
42
43
GetDisk (ctx context.Context , volumeKey * meta.Key ) (* CloudDisk , error )
43
44
RepairUnderspecifiedVolumeKey (ctx context.Context , volumeKey * meta.Key ) (* meta.Key , error )
44
45
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 , snapshotID , diskEncryptionKmsKey string ) error
46
+ InsertDisk (ctx context.Context , volKey * meta.Key , diskType string , capBytes int64 , capacityRange * csi.CapacityRange , replicaZones []string , snapshotID , diskEncryptionKmsKey string , multiWriter bool ) error
46
47
DeleteDisk (ctx context.Context , volumeKey * meta.Key ) error
47
48
AttachDisk (ctx context.Context , volKey * meta.Key , readWrite , diskType , instanceZone , instanceName string ) error
48
49
DetachDisk (ctx context.Context , deviceName string , instanceZone , instanceName string ) error
@@ -217,13 +218,21 @@ func (cloud *CloudProvider) ValidateExistingDisk(ctx context.Context, resp *Clou
217
218
return nil
218
219
}
219
220
220
- func (cloud * CloudProvider ) InsertDisk (ctx context.Context , volKey * meta.Key , diskType string , capBytes int64 , capacityRange * csi.CapacityRange , replicaZones []string , snapshotID , diskEncryptionKmsKey string ) error {
221
+ func (cloud * CloudProvider ) InsertDisk (ctx context.Context , volKey * meta.Key , diskType string , capBytes int64 , capacityRange * csi.CapacityRange , replicaZones []string , snapshotID , diskEncryptionKmsKey string , multiWriter bool ) error {
221
222
klog .V (5 ).Infof ("Inserting disk %v" , volKey )
222
223
switch volKey .Type () {
223
224
case meta .Zonal :
224
- return cloud .insertZonalDisk (ctx , volKey , diskType , capBytes , capacityRange , snapshotID , diskEncryptionKmsKey )
225
+ if multiWriter {
226
+ return cloud .insertZonalAlphaDisk (ctx , volKey , diskType , capBytes , capacityRange , snapshotID , diskEncryptionKmsKey , multiWriter )
227
+ } else {
228
+ return cloud .insertZonalDisk (ctx , volKey , diskType , capBytes , capacityRange , snapshotID , diskEncryptionKmsKey )
229
+ }
225
230
case meta .Regional :
226
- return cloud .insertRegionalDisk (ctx , volKey , diskType , capBytes , capacityRange , replicaZones , snapshotID , diskEncryptionKmsKey )
231
+ if multiWriter {
232
+ return cloud .insertRegionalAlphaDisk (ctx , volKey , diskType , capBytes , capacityRange , replicaZones , snapshotID , diskEncryptionKmsKey , multiWriter )
233
+ } else {
234
+ return cloud .insertRegionalDisk (ctx , volKey , diskType , capBytes , capacityRange , replicaZones , snapshotID , diskEncryptionKmsKey )
235
+ }
227
236
default :
228
237
return fmt .Errorf ("could not insert disk, key was neither zonal nor regional, instead got: %v" , volKey .String ())
229
238
}
@@ -288,6 +297,66 @@ func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta
288
297
return nil
289
298
}
290
299
300
+ func (cloud * CloudProvider ) insertRegionalAlphaDisk (ctx context.Context , volKey * meta.Key , diskType string , capBytes int64 , capacityRange * csi.CapacityRange , replicaZones []string , snapshotID , diskEncryptionKmsKey string , multiWriter bool ) error {
301
+ diskToCreateAlpha := & computealpha.Disk {
302
+ Name : volKey .Name ,
303
+ SizeGb : common .BytesToGb (capBytes ),
304
+ Description : "Regional disk created by GCE-PD CSI Driver" ,
305
+ Type : cloud .GetDiskTypeURI (volKey , diskType ),
306
+ MultiWriter : multiWriter ,
307
+ }
308
+ if snapshotID != "" {
309
+ diskToCreateAlpha .SourceSnapshot = snapshotID
310
+ }
311
+ if len (replicaZones ) != 0 {
312
+ diskToCreateAlpha .ReplicaZones = replicaZones
313
+ }
314
+ if diskEncryptionKmsKey != "" {
315
+ diskToCreateAlpha .DiskEncryptionKey = & computealpha.CustomerEncryptionKey {
316
+ KmsKeyName : diskEncryptionKmsKey ,
317
+ }
318
+ }
319
+
320
+ insertOp , err := cloud .alphaService .RegionDisks .Insert (cloud .project , volKey .Region , diskToCreateAlpha ).Context (ctx ).Do ()
321
+ if err != nil {
322
+ if IsGCEError (err , "alreadyExists" ) {
323
+ disk , err := cloud .GetDisk (ctx , volKey )
324
+ if err != nil {
325
+ return err
326
+ }
327
+ err = cloud .ValidateExistingDisk (ctx , disk , diskType ,
328
+ int64 (capacityRange .GetRequiredBytes ()),
329
+ int64 (capacityRange .GetLimitBytes ()))
330
+ if err != nil {
331
+ return err
332
+ }
333
+ klog .Warningf ("GCE PD %s already exists, reusing" , volKey .Name )
334
+ return nil
335
+ }
336
+ return status .Error (codes .Internal , fmt .Sprintf ("unkown Insert disk error: %v" , err ))
337
+ }
338
+
339
+ err = cloud .waitForRegionalAlphaOp (ctx , insertOp , volKey .Region )
340
+ if err != nil {
341
+ if IsGCEError (err , "alreadyExists" ) {
342
+ disk , err := cloud .GetDisk (ctx , volKey )
343
+ if err != nil {
344
+ return err
345
+ }
346
+ err = cloud .ValidateExistingDisk (ctx , disk , diskType ,
347
+ int64 (capacityRange .GetRequiredBytes ()),
348
+ int64 (capacityRange .GetLimitBytes ()))
349
+ if err != nil {
350
+ return err
351
+ }
352
+ klog .Warningf ("GCE PD %s already exists after wait, reusing" , volKey .Name )
353
+ return nil
354
+ }
355
+ return fmt .Errorf ("unkown Insert disk operation error: %v" , err )
356
+ }
357
+ return nil
358
+ }
359
+
291
360
func (cloud * CloudProvider ) insertZonalDisk (ctx context.Context , volKey * meta.Key , diskType string , capBytes int64 , capacityRange * csi.CapacityRange , snapshotID , diskEncryptionKmsKey string ) error {
292
361
diskToCreate := & computev1.Disk {
293
362
Name : volKey .Name ,
@@ -348,6 +417,67 @@ func (cloud *CloudProvider) insertZonalDisk(ctx context.Context, volKey *meta.Ke
348
417
return nil
349
418
}
350
419
420
+ func (cloud * CloudProvider ) insertZonalAlphaDisk (ctx context.Context , volKey * meta.Key , diskType string , capBytes int64 , capacityRange * csi.CapacityRange , snapshotID , diskEncryptionKmsKey string , multiWriter bool ) error {
421
+ diskToCreateAlpha := & computealpha.Disk {
422
+ Name : volKey .Name ,
423
+ SizeGb : common .BytesToGb (capBytes ),
424
+ Description : "Disk created by GCE-PD CSI Driver" ,
425
+ Type : cloud .GetDiskTypeURI (volKey , diskType ),
426
+ MultiWriter : multiWriter ,
427
+ }
428
+
429
+ if snapshotID != "" {
430
+ diskToCreateAlpha .SourceSnapshot = snapshotID
431
+ }
432
+
433
+ if diskEncryptionKmsKey != "" {
434
+ diskToCreateAlpha .DiskEncryptionKey = & computealpha.CustomerEncryptionKey {
435
+ KmsKeyName : diskEncryptionKmsKey ,
436
+ }
437
+ }
438
+
439
+ op , err := cloud .alphaService .Disks .Insert (cloud .project , volKey .Zone , diskToCreateAlpha ).Context (ctx ).Do ()
440
+
441
+ if err != nil {
442
+ if IsGCEError (err , "alreadyExists" ) {
443
+ disk , err := cloud .GetDisk (ctx , volKey )
444
+ if err != nil {
445
+ return err
446
+ }
447
+ err = cloud .ValidateExistingDisk (ctx , disk , diskType ,
448
+ int64 (capacityRange .GetRequiredBytes ()),
449
+ int64 (capacityRange .GetLimitBytes ()))
450
+ if err != nil {
451
+ return err
452
+ }
453
+ klog .Warningf ("GCE PD %s already exists, reusing" , volKey .Name )
454
+ return nil
455
+ }
456
+ return fmt .Errorf ("unkown Insert disk error: %v" , err )
457
+ }
458
+
459
+ err = cloud .waitForZonalAlphaOp (ctx , op , volKey .Zone )
460
+
461
+ if err != nil {
462
+ if IsGCEError (err , "alreadyExists" ) {
463
+ disk , err := cloud .GetDisk (ctx , volKey )
464
+ if err != nil {
465
+ return err
466
+ }
467
+ err = cloud .ValidateExistingDisk (ctx , disk , diskType ,
468
+ int64 (capacityRange .GetRequiredBytes ()),
469
+ int64 (capacityRange .GetLimitBytes ()))
470
+ if err != nil {
471
+ return err
472
+ }
473
+ klog .Warningf ("GCE PD %s already exists after wait, reusing" , volKey .Name )
474
+ return nil
475
+ }
476
+ return fmt .Errorf ("unkown Insert disk operation error: %v" , err )
477
+ }
478
+ return nil
479
+ }
480
+
351
481
func (cloud * CloudProvider ) DeleteDisk (ctx context.Context , volKey * meta.Key ) error {
352
482
klog .V (5 ).Infof ("Deleting disk: %v" , volKey )
353
483
switch volKey .Type () {
@@ -492,6 +622,20 @@ func (cloud *CloudProvider) waitForZonalOp(ctx context.Context, op *computev1.Op
492
622
})
493
623
}
494
624
625
+ func (cloud * CloudProvider ) waitForZonalAlphaOp (ctx context.Context , op * computealpha.Operation , zone string ) error {
626
+ svc := cloud .alphaService
627
+ project := cloud .project
628
+ return wait .Poll (3 * time .Second , 5 * time .Minute , func () (bool , error ) {
629
+ pollOp , err := svc .ZoneOperations .Get (project , zone , op .Name ).Context (ctx ).Do ()
630
+ if err != nil {
631
+ klog .Errorf ("WaitForOp(op: %#v, zone: %#v) failed to poll the operation" , op , zone )
632
+ return false , err
633
+ }
634
+ done , err := alphaOpIsDone (pollOp )
635
+ return done , err
636
+ })
637
+ }
638
+
495
639
func (cloud * CloudProvider ) waitForRegionalOp (ctx context.Context , op * computev1.Operation , region string ) error {
496
640
return wait .Poll (3 * time .Second , 5 * time .Minute , func () (bool , error ) {
497
641
pollOp , err := cloud .service .RegionOperations .Get (cloud .project , region , op .Name ).Context (ctx ).Do ()
@@ -504,6 +648,18 @@ func (cloud *CloudProvider) waitForRegionalOp(ctx context.Context, op *computev1
504
648
})
505
649
}
506
650
651
+ func (cloud * CloudProvider ) waitForRegionalAlphaOp (ctx context.Context , op * computealpha.Operation , region string ) error {
652
+ return wait .Poll (3 * time .Second , 5 * time .Minute , func () (bool , error ) {
653
+ pollOp , err := cloud .alphaService .RegionOperations .Get (cloud .project , region , op .Name ).Context (ctx ).Do ()
654
+ if err != nil {
655
+ klog .Errorf ("WaitForOp(op: %#v, region: %#v) failed to poll the operation" , op , region )
656
+ return false , err
657
+ }
658
+ done , err := alphaOpIsDone (pollOp )
659
+ return done , err
660
+ })
661
+ }
662
+
507
663
func (cloud * CloudProvider ) waitForGlobalOp (ctx context.Context , op * computev1.Operation ) error {
508
664
svc := cloud .service
509
665
project := cloud .project
@@ -551,6 +707,16 @@ func opIsDone(op *computev1.Operation) (bool, error) {
551
707
return true , nil
552
708
}
553
709
710
+ func alphaOpIsDone (op * computealpha.Operation ) (bool , error ) {
711
+ if op == nil || op .Status != operationStatusDone {
712
+ return false , nil
713
+ }
714
+ if op .Error != nil && len (op .Error .Errors ) > 0 && op .Error .Errors [0 ] != nil {
715
+ return true , fmt .Errorf ("operation %v failed (%v): %v" , op .Name , op .Error .Errors [0 ].Code , op .Error .Errors [0 ].Message )
716
+ }
717
+ return true , nil
718
+ }
719
+
554
720
func (cloud * CloudProvider ) GetInstanceOrError (ctx context.Context , instanceZone , instanceName string ) (* computev1.Instance , error ) {
555
721
klog .V (5 ).Infof ("Getting instance %v from zone %v" , instanceName , instanceZone )
556
722
svc := cloud .service
0 commit comments