Skip to content

Commit c08bad5

Browse files
authored
Merge pull request #1983 from julianKatz/machine-serenity-non-allowedTopologies-method
Introduce Disk Topology Feature
2 parents 1c4bb8c + 3d848cf commit c08bad5

File tree

12 files changed

+190
-96
lines changed

12 files changed

+190
-96
lines changed

Diff for: cmd/gce-pd-csi-driver/main.go

+14-2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ var (
9494

9595
extraTagsStr = flag.String("extra-tags", "", "Extra tags to attach to each Compute Disk, Image, Snapshot created. It is a comma separated list of parent id, key and value like '<parent_id1>/<tag_key1>/<tag_value1>,...,<parent_idN>/<tag_keyN>/<tag_valueN>'. parent_id is the Organization or the Project ID or Project name where the tag key and the tag value resources exist. A maximum of 50 tags bindings is allowed for a resource. See https://cloud.google.com/resource-manager/docs/tags/tags-overview, https://cloud.google.com/resource-manager/docs/tags/tags-creating-and-managing for details")
9696

97+
diskTopology = flag.Bool("disk-topology", false, "If set to true, the driver will add a disk-type.gke.io/[some-disk-type] topology label to the Topologies returned in CreateVolumeResponse.")
98+
9799
version string
98100
)
99101

@@ -225,9 +227,15 @@ func handle() {
225227
if err != nil {
226228
klog.Fatalf("Failed to get cloud provider: %v", err.Error())
227229
}
230+
228231
initialBackoffDuration := time.Duration(*errorBackoffInitialDurationMs) * time.Millisecond
229232
maxBackoffDuration := time.Duration(*errorBackoffMaxDurationMs) * time.Millisecond
230-
controllerServer = driver.NewControllerServer(gceDriver, cloudProvider, initialBackoffDuration, maxBackoffDuration, fallbackRequisiteZones, *enableStoragePoolsFlag, *enableDataCacheFlag, multiZoneVolumeHandleConfig, listVolumesConfig, provisionableDisksConfig, *enableHdHAFlag)
233+
// TODO(2042): Move more of the constructor args into this struct
234+
args := &driver.GCEControllerServerArgs{
235+
EnableDiskTopology: *diskTopology,
236+
}
237+
238+
controllerServer = driver.NewControllerServer(gceDriver, cloudProvider, initialBackoffDuration, maxBackoffDuration, fallbackRequisiteZones, *enableStoragePoolsFlag, *enableDataCacheFlag, multiZoneVolumeHandleConfig, listVolumesConfig, provisionableDisksConfig, *enableHdHAFlag, args)
231239
} else if *cloudConfigFilePath != "" {
232240
klog.Warningf("controller service is disabled but cloud config given - it has no effect")
233241
}
@@ -239,6 +247,7 @@ func handle() {
239247
if err != nil {
240248
klog.Fatalf("Failed to get safe mounter: %v", err.Error())
241249
}
250+
242251
deviceUtils := deviceutils.NewDeviceUtils()
243252
statter := mountmanager.NewStatter(mounter)
244253
meta, err := metadataservice.NewMetadataService()
@@ -249,13 +258,16 @@ func handle() {
249258
if err != nil {
250259
klog.Fatalf("Failed to get node info from API server: %v", err.Error())
251260
}
252-
nsArgs := driver.NodeServerArgs{
261+
262+
// TODO(2042): Move more of the constructor args into this struct
263+
nsArgs := &driver.NodeServerArgs{
253264
EnableDeviceInUseCheck: *enableDeviceInUseCheck,
254265
DeviceInUseTimeout: *deviceInUseTimeout,
255266
EnableDataCache: *enableDataCacheFlag,
256267
DataCacheEnabledNodePool: isDataCacheEnabledNodePool,
257268
}
258269
nodeServer = driver.NewNodeServer(gceDriver, mounter, deviceUtils, meta, statter, nsArgs)
270+
259271
if *maxConcurrentFormatAndMount > 0 {
260272
nodeServer = nodeServer.WithSerializedFormatAndMount(*formatAndMountTimeout, *maxConcurrentFormatAndMount)
261273
}

Diff for: pkg/common/constants.go

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ const (
2020
// Keys for Topology. This key will be shared amongst drivers from GCP
2121
TopologyKeyZone = "topology.gke.io/zone"
2222

23+
// DiskTypeKeyPrefix is the prefix for the disk type label key used as part
24+
// of the Disk Topology feature.
25+
DiskTypeKeyPrefix = "disk-type.gke.io"
26+
2327
// VolumeAttributes for Partition
2428
VolumeAttributePartition = "partition"
2529

Diff for: pkg/common/utils.go

+4
Original file line numberDiff line numberDiff line change
@@ -764,3 +764,7 @@ func MapNumber(num int64) int64 {
764764
}
765765
return 0
766766
}
767+
768+
func DiskTypeLabelKey(diskType string) string {
769+
return fmt.Sprintf("%s/%s", DiskTypeKeyPrefix, diskType)
770+
}

Diff for: pkg/gce-cloud-provider/metadata/fake.go

+14-6
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ type fakeServiceManager struct{}
2020

2121
var _ MetadataService = &fakeServiceManager{}
2222

23-
const (
24-
FakeZone = "country-region-zone"
25-
FakeProject = "test-project"
23+
var (
24+
FakeMachineType = "n1-standard-1"
25+
FakeZone = "country-region-zone"
26+
FakeProject = "test-project"
27+
FakeName = "test-name"
2628
)
2729

28-
var FakeMachineType = "n1-standard-1"
29-
3030
func NewFakeService() MetadataService {
3131
return &fakeServiceManager{}
3232
}
@@ -40,7 +40,7 @@ func (manager *fakeServiceManager) GetProject() string {
4040
}
4141

4242
func (manager *fakeServiceManager) GetName() string {
43-
return "test-name"
43+
return FakeName
4444
}
4545

4646
func (manager *fakeServiceManager) GetMachineType() string {
@@ -50,3 +50,11 @@ func (manager *fakeServiceManager) GetMachineType() string {
5050
func SetMachineType(s string) {
5151
FakeMachineType = s
5252
}
53+
54+
func SetZone(s string) {
55+
FakeZone = s
56+
}
57+
58+
func SetName(s string) {
59+
FakeName = s
60+
}

Diff for: pkg/gce-pd-csi-driver/controller.go

+31-17
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ type GCEControllerServer struct {
120120
// Embed UnimplementedControllerServer to ensure the driver returns Unimplemented for any
121121
// new RPC methods that might be introduced in future versions of the spec.
122122
csi.UnimplementedControllerServer
123+
124+
EnableDiskTopology bool
125+
}
126+
127+
type GCEControllerServerArgs struct {
128+
EnableDiskTopology bool
123129
}
124130

125131
type MultiZoneVolumeHandleConfig struct {
@@ -320,7 +326,7 @@ func (gceCS *GCEControllerServer) createVolumeInternal(ctx context.Context, req
320326
if len(req.GetName()) == 0 {
321327
return nil, status.Error(codes.InvalidArgument, "CreateVolume Name must be provided")
322328
}
323-
if volumeCapabilities == nil || len(volumeCapabilities) == 0 {
329+
if len(volumeCapabilities) == 0 {
324330
return nil, status.Error(codes.InvalidArgument, "CreateVolume Volume capabilities must be provided")
325331
}
326332

@@ -465,9 +471,7 @@ func (gceCS *GCEControllerServer) getMultiZoneProvisioningZones(ctx context.Cont
465471
}
466472

467473
func (gceCS *GCEControllerServer) createMultiZoneDisk(ctx context.Context, req *csi.CreateVolumeRequest, params common.DiskParameters, dataCacheParams common.DataCacheParameters, enableDataCache bool) (*csi.CreateVolumeResponse, error) {
468-
// Determine the zones that are needed.
469474
var err error
470-
471475
// For multi-zone, we either select:
472476
// 1) The zones specified in requisite topology requirements
473477
// 2) All zones in the region that are compatible with the selected disk type
@@ -517,7 +521,8 @@ func (gceCS *GCEControllerServer) createMultiZoneDisk(ctx context.Context, req *
517521
// Use the first response as a template
518522
volumeId := fmt.Sprintf("projects/%s/zones/%s/disks/%s", gceCS.CloudProvider.GetDefaultProject(), common.MultiZoneValue, req.GetName())
519523
klog.V(4).Infof("CreateVolume succeeded for multi-zone disks in zones %s: %v", zones, multiZoneVolKey)
520-
return generateCreateVolumeResponseWithVolumeId(createdDisks[0], zones, params, dataCacheParams, enableDataCache, volumeId), nil
524+
525+
return gceCS.generateCreateVolumeResponseWithVolumeId(createdDisks[0], zones, params, dataCacheParams, enableDataCache, volumeId), nil
521526
}
522527

523528
func (gceCS *GCEControllerServer) getZonesWithDiskNameAndType(ctx context.Context, name string, diskType string) ([]string, error) {
@@ -617,13 +622,13 @@ func (gceCS *GCEControllerServer) createSingleDeviceDisk(ctx context.Context, re
617622
return nil, status.Errorf(codes.Aborted, common.VolumeOperationAlreadyExistsFmt, volumeID)
618623
}
619624
defer gceCS.volumeLocks.Release(volumeID)
620-
disk, err := gceCS.createSingleDisk(ctx, req, params, volKey, zones, accessMode)
621625

626+
disk, err := gceCS.createSingleDisk(ctx, req, params, volKey, zones, accessMode)
622627
if err != nil {
623628
return nil, common.LoggedError("CreateVolume failed: %v", err)
624629
}
625630

626-
return generateCreateVolumeResponseWithVolumeId(disk, zones, params, dataCacheParams, enableDataCache, volumeID), err
631+
return gceCS.generateCreateVolumeResponseWithVolumeId(disk, zones, params, dataCacheParams, enableDataCache, volumeID), nil
627632
}
628633

629634
func getAccessMode(req *csi.CreateVolumeRequest, params common.DiskParameters) (string, error) {
@@ -2396,21 +2401,30 @@ func extractVolumeContext(context map[string]string) (*PDCSIContext, error) {
23962401
case contextForceAttach:
23972402
b, err := common.ConvertStringToBool(val)
23982403
if err != nil {
2399-
return nil, fmt.Errorf("Bad volume context force attach: %v", err)
2404+
return nil, fmt.Errorf("bad volume context force attach: %w", err)
24002405
}
24012406
info.ForceAttach = b
24022407
}
24032408
}
24042409
return info, nil
24052410
}
24062411

2407-
func generateCreateVolumeResponseWithVolumeId(disk *gce.CloudDisk, zones []string, params common.DiskParameters, dataCacheParams common.DataCacheParameters, enableDataCache bool, volumeId string) *csi.CreateVolumeResponse {
2412+
func (gceCS *GCEControllerServer) generateCreateVolumeResponseWithVolumeId(disk *gce.CloudDisk, zones []string, params common.DiskParameters, dataCacheParams common.DataCacheParameters, enableDataCache bool, volumeId string) *csi.CreateVolumeResponse {
24082413
tops := []*csi.Topology{}
24092414
for _, zone := range zones {
2410-
tops = append(tops, &csi.Topology{
2411-
Segments: map[string]string{common.TopologyKeyZone: zone},
2412-
})
2415+
top := &csi.Topology{
2416+
Segments: map[string]string{
2417+
common.TopologyKeyZone: zone,
2418+
},
2419+
}
2420+
2421+
if gceCS.EnableDiskTopology {
2422+
top.Segments[common.DiskTypeLabelKey(params.DiskType)] = "true"
2423+
}
2424+
2425+
tops = append(tops, top)
24132426
}
2427+
24142428
realDiskSizeBytes := common.GbToBytes(disk.GetSizeGb())
24152429
createResp := &csi.CreateVolumeResponse{
24162430
Volume: &csi.Volume{
@@ -2468,10 +2482,10 @@ func generateCreateVolumeResponseWithVolumeId(disk *gce.CloudDisk, zones []strin
24682482
func getResourceId(resourceLink string) (string, error) {
24692483
url, err := neturl.Parse(resourceLink)
24702484
if err != nil {
2471-
return "", fmt.Errorf("Could not parse resource %s: %w", resourceLink, err)
2485+
return "", fmt.Errorf("could not parse resource %s: %w", resourceLink, err)
24722486
}
24732487
if url.Scheme != resourceApiScheme {
2474-
return "", fmt.Errorf("Unexpected API scheme for resource %s", resourceLink)
2488+
return "", fmt.Errorf("unexpected API scheme for resource %s", resourceLink)
24752489
}
24762490

24772491
// Note that the resource host can basically be anything, if we are running in
@@ -2480,16 +2494,16 @@ func getResourceId(resourceLink string) (string, error) {
24802494
// The path should be /compute/VERSION/project/....
24812495
elts := strings.Split(url.Path, "/")
24822496
if len(elts) < 4 {
2483-
return "", fmt.Errorf("Short resource path %s", resourceLink)
2497+
return "", fmt.Errorf("short resource path %s", resourceLink)
24842498
}
24852499
if elts[1] != resourceApiService {
2486-
return "", fmt.Errorf("Bad resource service %s in %s", elts[1], resourceLink)
2500+
return "", fmt.Errorf("bad resource service %s in %s", elts[1], resourceLink)
24872501
}
24882502
if _, ok := validResourceApiVersions[elts[2]]; !ok {
2489-
return "", fmt.Errorf("Bad version %s in %s", elts[2], resourceLink)
2503+
return "", fmt.Errorf("bad version %s in %s", elts[2], resourceLink)
24902504
}
24912505
if elts[3] != resourceProject {
2492-
return "", fmt.Errorf("Expected %v to start with %s in resource %s", elts[3:], resourceProject, resourceLink)
2506+
return "", fmt.Errorf("expected %v to start with %s in resource %s", elts[3:], resourceProject, resourceLink)
24932507
}
24942508
return strings.Join(elts[3:], "/"), nil
24952509
}

0 commit comments

Comments
 (0)