Skip to content

Commit 6edbdaa

Browse files
committed
Implementation updates for CSI Spec v1.0.0-rc2
1 parent 7c106db commit 6edbdaa

File tree

14 files changed

+180
-140
lines changed

14 files changed

+180
-140
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
"strconv"
2020
"strings"
2121

22-
csi "github.com/container-storage-interface/spec/lib/go/csi/v0"
22+
csi "github.com/container-storage-interface/spec/lib/go/csi"
2323
"github.com/golang/glog"
2424
"golang.org/x/net/context"
2525
computebeta "google.golang.org/api/compute/v0.beta"

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
"strings"
2020
"time"
2121

22-
csi "github.com/container-storage-interface/spec/lib/go/csi/v0"
22+
csi "github.com/container-storage-interface/spec/lib/go/csi"
2323
"github.com/golang/glog"
2424
"golang.org/x/net/context"
2525
computebeta "google.golang.org/api/compute/v0.beta"

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

Lines changed: 123 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ import (
2121
"strings"
2222
"time"
2323

24-
csi "github.com/container-storage-interface/spec/lib/go/csi/v0"
24+
"github.com/golang/protobuf/ptypes"
25+
26+
csi "github.com/container-storage-interface/spec/lib/go/csi"
2527
"github.com/golang/glog"
2628
"golang.org/x/net/context"
2729
compute "google.golang.org/api/compute/v1"
@@ -152,7 +154,8 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
152154
content := req.GetVolumeContentSource()
153155
if content != nil {
154156
if content.GetSnapshot() != nil {
155-
snapshotId = content.GetSnapshot().GetId()
157+
// TODO(#161): Add support for Volume Source (cloning) introduced in CSI v1.0.0
158+
snapshotId = content.GetSnapshot().GetSnapshotId()
156159
}
157160
}
158161

@@ -241,7 +244,7 @@ func (gceCS *GCEControllerServer) ControllerPublishVolume(ctx context.Context, r
241244
// TODO(#94): Check volume capability matches
242245

243246
pubVolResp := &csi.ControllerPublishVolumeResponse{
244-
PublishInfo: nil,
247+
PublishContext: nil,
245248
}
246249

247250
_, err = gceCS.CloudProvider.GetDisk(ctx, volKey)
@@ -352,6 +355,8 @@ func (gceCS *GCEControllerServer) ControllerUnpublishVolume(ctx context.Context,
352355

353356
func (gceCS *GCEControllerServer) ValidateVolumeCapabilities(ctx context.Context, req *csi.ValidateVolumeCapabilitiesRequest) (*csi.ValidateVolumeCapabilitiesResponse, error) {
354357
// TODO(#94): Factor out the volume capability functionality and use as validation in all other functions as well
358+
// TODO(#162): Implement ValidateVolumeCapabilities
359+
355360
glog.V(5).Infof("Using default ValidateVolumeCapabilities")
356361
// Validate Arguments
357362
if req.GetVolumeCapabilities() == nil || len(req.GetVolumeCapabilities()) == 0 {
@@ -373,63 +378,68 @@ func (gceCS *GCEControllerServer) ValidateVolumeCapabilities(ctx context.Context
373378
return nil, status.Error(codes.Internal, fmt.Sprintf("Unknown get disk error: %v", err))
374379
}
375380

376-
for _, c := range req.GetVolumeCapabilities() {
377-
found := false
378-
for _, c1 := range gceCS.Driver.vcap {
379-
if c1.Mode == c.GetAccessMode().Mode {
380-
found = true
381+
return &csi.ValidateVolumeCapabilitiesResponse{
382+
Message: "ValidateVolumeCapabilities is currently unimplemented for CSI v1.0.0",
383+
}, nil
384+
/*
385+
for _, c := range req.GetVolumeCapabilities() {
386+
found := false
387+
for _, c1 := range gceCS.Driver.vcap {
388+
if c1.Mode == c.GetAccessMode().Mode {
389+
found = true
390+
}
381391
}
382-
}
383-
if !found {
384-
return &csi.ValidateVolumeCapabilitiesResponse{
385-
Supported: false,
386-
Message: "Driver does not support mode:" + c.GetAccessMode().Mode.String(),
387-
}, status.Error(codes.InvalidArgument, "Driver does not support mode:"+c.GetAccessMode().Mode.String())
388-
}
389-
// TODO: Ignoring mount & block types for now.
390-
}
391-
392-
for _, top := range req.GetAccessibleTopology() {
393-
for k, v := range top.GetSegments() {
394-
switch k {
395-
case common.TopologyKeyZone:
396-
switch volKey.Type() {
397-
case meta.Zonal:
398-
if v == volKey.Zone {
399-
// Accessible zone matches with storage zone
400-
return &csi.ValidateVolumeCapabilitiesResponse{
401-
Supported: true,
402-
}, nil
403-
}
404-
case meta.Regional:
405-
// TODO: This should more accurately check the disks replica Zones but that involves
406-
// GET-ing the disk
407-
region, err := common.GetRegionFromZones([]string{v})
408-
if err != nil {
409-
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("ValidateVolumeCapabilities could not extract topology region from zone %v: %v", v, err))
410-
}
411-
if region == volKey.Region {
412-
// Accessible region matches with storage region
392+
if !found {
393+
return &csi.ValidateVolumeCapabilitiesResponse{
394+
Supported: false,
395+
Message: "Driver does not support mode:" + c.GetAccessMode().Mode.String(),
396+
}, status.Error(codes.InvalidArgument, "Driver does not support mode:"+c.GetAccessMode().Mode.String())
397+
}
398+
// TODO: Ignoring mount & block types for now.
399+
}
400+
401+
for _, top := range req.GetAccessibleTopology() {
402+
for k, v := range top.GetSegments() {
403+
switch k {
404+
case common.TopologyKeyZone:
405+
switch volKey.Type() {
406+
case meta.Zonal:
407+
if v == volKey.Zone {
408+
// Accessible zone matches with storage zone
409+
return &csi.ValidateVolumeCapabilitiesResponse{
410+
Supported: true,
411+
}, nil
412+
}
413+
case meta.Regional:
414+
// TODO: This should more accurately check the disks replica Zones but that involves
415+
// GET-ing the disk
416+
region, err := common.GetRegionFromZones([]string{v})
417+
if err != nil {
418+
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("ValidateVolumeCapabilities could not extract topology region from zone %v: %v", v, err))
419+
}
420+
if region == volKey.Region {
421+
// Accessible region matches with storage region
422+
return &csi.ValidateVolumeCapabilitiesResponse{
423+
Supported: true,
424+
}, nil
425+
}
426+
default:
427+
// Accessible zone does not match
413428
return &csi.ValidateVolumeCapabilitiesResponse{
414-
Supported: true,
429+
Supported: false,
430+
Message: fmt.Sprintf("Volume %s is not accesible from topology %s:%s", volumeID, k, v),
415431
}, nil
416432
}
417433
default:
418-
// Accessible zone does not match
419-
return &csi.ValidateVolumeCapabilitiesResponse{
420-
Supported: false,
421-
Message: fmt.Sprintf("Volume %s is not accesible from topology %s:%s", volumeID, k, v),
422-
}, nil
434+
return nil, status.Error(codes.InvalidArgument, "ValidateVolumeCapabilities unknown topology segment key")
423435
}
424-
default:
425-
return nil, status.Error(codes.InvalidArgument, "ValidateVolumeCapabilities unknown topology segment key")
426436
}
427437
}
428-
}
429438
430-
return &csi.ValidateVolumeCapabilitiesResponse{
431-
Supported: true,
432-
}, nil
439+
return &csi.ValidateVolumeCapabilitiesResponse{
440+
Supported: true,
441+
}, nil
442+
*/
433443
}
434444

435445
func (gceCS *GCEControllerServer) ListVolumes(ctx context.Context, req *csi.ListVolumesRequest) (*csi.ListVolumesResponse, error) {
@@ -467,13 +477,23 @@ func (gceCS *GCEControllerServer) CreateSnapshot(ctx context.Context, req *csi.C
467477
return nil, status.Error(codes.NotFound, fmt.Sprintf("Could not find volume with ID %v: %v", volumeID, err))
468478
}
469479

470-
snapshot, err := gceCS.CloudProvider.CreateSnapshot(ctx, volKey, req.Name)
480+
// Check if snapshot already exists
481+
var snapshot *compute.Snapshot
482+
snapshot, err = gceCS.CloudProvider.GetSnapshot(ctx, req.Name)
471483
if err != nil {
472-
if gce.IsGCEError(err, "notFound") {
473-
return nil, status.Error(codes.NotFound, fmt.Sprintf("Could not find volume with ID %v: %v", volKey.String(), err))
484+
if !gce.IsGCEError(err, "notFound") {
485+
return nil, status.Error(codes.Internal, fmt.Sprintf("Unknown get snapshot error: %v", err))
486+
}
487+
// If we could not find the snapshot, we create a new one
488+
snapshot, err = gceCS.CloudProvider.CreateSnapshot(ctx, volKey, req.Name)
489+
if err != nil {
490+
if gce.IsGCEError(err, "notFound") {
491+
return nil, status.Error(codes.NotFound, fmt.Sprintf("Could not find volume with ID %v: %v", volKey.String(), err))
492+
}
493+
return nil, status.Error(codes.Internal, fmt.Sprintf("Unknown create snapshot error: %v", err))
474494
}
475-
return nil, status.Error(codes.Internal, fmt.Sprintf("Unknown create snapshot error: %v", err))
476495
}
496+
477497
err = gceCS.validateExistingSnapshot(snapshot, volKey)
478498
if err != nil {
479499
return nil, status.Error(codes.AlreadyExists, fmt.Sprintf("Error in creating snapshot: %v", err))
@@ -482,15 +502,24 @@ func (gceCS *GCEControllerServer) CreateSnapshot(ctx context.Context, req *csi.C
482502
if err != nil {
483503
return nil, status.Error(codes.Internal, fmt.Sprintf("Failed to covert creation timestamp: %v", err))
484504
}
505+
506+
tp, err := ptypes.TimestampProto(t)
507+
if err != nil {
508+
return nil, status.Error(codes.Internal, fmt.Sprintf("Failed to covert creation timestamp: %v", err))
509+
}
510+
511+
ready, err := isCSISnapshotReady(snapshot.Status)
512+
if err != nil {
513+
return nil, status.Error(codes.Internal, fmt.Sprintf("Snapshot had error checking ready status: %v", err))
514+
}
515+
485516
createResp := &csi.CreateSnapshotResponse{
486517
Snapshot: &csi.Snapshot{
487518
SizeBytes: common.GbToBytes(snapshot.DiskSizeGb),
488-
Id: cleanSelfLink(snapshot.SelfLink),
519+
SnapshotId: cleanSelfLink(snapshot.SelfLink),
489520
SourceVolumeId: volumeID,
490-
CreatedAt: t.UnixNano(),
491-
Status: &csi.SnapshotStatus{
492-
Type: convertCSISnapshotStatus(snapshot.Status),
493-
},
521+
CreationTime: tp,
522+
ReadyToUse: ready,
494523
},
495524
}
496525
return createResp, nil
@@ -514,22 +543,18 @@ func (gceCS *GCEControllerServer) validateExistingSnapshot(snapshot *compute.Sna
514543
return nil
515544
}
516545

517-
func convertCSISnapshotStatus(status string) csi.SnapshotStatus_Type {
518-
var csiStatus csi.SnapshotStatus_Type
546+
func isCSISnapshotReady(status string) (bool, error) {
519547
switch status {
520548
case "READY":
521-
csiStatus = csi.SnapshotStatus_READY
522-
case "UPLOADING":
523-
csiStatus = csi.SnapshotStatus_UPLOADING
549+
return true, nil
524550
case "FAILED":
525-
csiStatus = csi.SnapshotStatus_ERROR_UPLOADING
551+
return false, fmt.Errorf("snapshot status is FAILED")
526552
case "DELETING":
527-
csiStatus = csi.SnapshotStatus_UNKNOWN
528553
glog.V(4).Infof("snapshot is in DELETING")
554+
fallthrough
529555
default:
530-
csiStatus = csi.SnapshotStatus_UNKNOWN
556+
return false, nil
531557
}
532-
return csiStatus
533558
}
534559

535560
func (gceCS *GCEControllerServer) DeleteSnapshot(ctx context.Context, req *csi.DeleteSnapshotRequest) (*csi.DeleteSnapshotResponse, error) {
@@ -587,7 +612,10 @@ func (gceCS *GCEControllerServer) getSnapshots(ctx context.Context, req *csi.Lis
587612
entries := []*csi.ListSnapshotsResponse_Entry{}
588613

589614
for _, snapshot := range snapshots {
590-
entry := generateSnapshotEntry(snapshot)
615+
entry, err := generateSnapshotEntry(snapshot)
616+
if err != nil {
617+
return nil, fmt.Errorf("failed to generate snapshot entry: %v", err)
618+
}
591619
entries = append(entries, entry)
592620
}
593621
listSnapshotResp := &csi.ListSnapshotsResponse{
@@ -614,28 +642,42 @@ func (gceCS *GCEControllerServer) getSnapshotById(ctx context.Context, snapshotI
614642
}
615643
return nil, status.Error(codes.Internal, fmt.Sprintf("Unknown list snapshot error: %v", err))
616644
}
617-
entries := []*csi.ListSnapshotsResponse_Entry{generateSnapshotEntry(snapshot)}
645+
e, err := generateSnapshotEntry(snapshot)
646+
if err != nil {
647+
return nil, fmt.Errorf("failed to generate snapshot entry: %v", err)
648+
}
649+
650+
entries := []*csi.ListSnapshotsResponse_Entry{e}
618651
//entries[0] = entry
619652
listSnapshotResp := &csi.ListSnapshotsResponse{
620653
Entries: entries,
621654
}
622655
return listSnapshotResp, nil
623656
}
624657

625-
func generateSnapshotEntry(snapshot *compute.Snapshot) *csi.ListSnapshotsResponse_Entry {
658+
func generateSnapshotEntry(snapshot *compute.Snapshot) (*csi.ListSnapshotsResponse_Entry, error) {
626659
t, _ := time.Parse(time.RFC3339, snapshot.CreationTimestamp)
660+
661+
tp, err := ptypes.TimestampProto(t)
662+
if err != nil {
663+
return nil, fmt.Errorf("Failed to covert creation timestamp: %v", err)
664+
}
665+
666+
// We ignore the error intentionally here since we are just listing snapshots
667+
// TODO: If the snapshot is in "FAILED" state we need to think through what this
668+
// should actually look like.
669+
ready, _ := isCSISnapshotReady(snapshot.Status)
670+
627671
entry := &csi.ListSnapshotsResponse_Entry{
628672
Snapshot: &csi.Snapshot{
629673
SizeBytes: common.GbToBytes(snapshot.DiskSizeGb),
630-
Id: cleanSelfLink(snapshot.SelfLink),
674+
SnapshotId: cleanSelfLink(snapshot.SelfLink),
631675
SourceVolumeId: cleanSelfLink(snapshot.SourceDisk),
632-
CreatedAt: t.UnixNano(),
633-
Status: &csi.SnapshotStatus{
634-
Type: convertCSISnapshotStatus(snapshot.Status),
635-
},
676+
CreationTime: tp,
677+
ReadyToUse: ready,
636678
},
637679
}
638-
return entry
680+
return entry, nil
639681
}
640682

641683
func getRequestCapacity(capRange *csi.CapacityRange) (int64, error) {
@@ -815,8 +857,8 @@ func generateCreateVolumeResponse(disk *gce.CloudDisk, capBytes int64, zones []s
815857
createResp := &csi.CreateVolumeResponse{
816858
Volume: &csi.Volume{
817859
CapacityBytes: capBytes,
818-
Id: cleanSelfLink(disk.GetSelfLink()),
819-
Attributes: nil,
860+
VolumeId: cleanSelfLink(disk.GetSelfLink()),
861+
VolumeContext: nil,
820862
AccessibleTopology: tops,
821863
},
822864
}
@@ -825,7 +867,7 @@ func generateCreateVolumeResponse(disk *gce.CloudDisk, capBytes int64, zones []s
825867
source := &csi.VolumeContentSource{
826868
Type: &csi.VolumeContentSource_Snapshot{
827869
Snapshot: &csi.VolumeContentSource_SnapshotSource{
828-
Id: snapshotId,
870+
SnapshotId: snapshotId,
829871
},
830872
},
831873
}

0 commit comments

Comments
 (0)