Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8cae16b

Browse files
committedAug 9, 2018
Regional PD Implementation
1 parent 14ab26f commit 8cae16b

File tree

16 files changed

+985
-353
lines changed

16 files changed

+985
-353
lines changed
 

‎cmd/main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ func init() {
3535
var (
3636
endpoint = flag.String("endpoint", "unix:/tmp/csi.sock", "CSI endpoint")
3737
driverName = flag.String("drivername", "com.google.csi.gcepd", "name of the driver")
38-
nodeID = flag.String("nodeid", "", "node id")
3938
vendorVersion string
4039
)
4140

@@ -68,7 +67,7 @@ func handle() {
6867
glog.Fatalf("Failed to set up metadata service: %v", err)
6968
}
7069

71-
err = gceDriver.SetupGCEDriver(cloudProvider, mounter, deviceUtils, ms, *driverName, *nodeID, vendorVersion)
70+
err = gceDriver.SetupGCEDriver(cloudProvider, mounter, deviceUtils, ms, *driverName, vendorVersion)
7271
if err != nil {
7372
glog.Fatalf("Failed to initialize GCE CSI Driver: %v", err)
7473
}

‎pkg/common/constants.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ package common
1818

1919
const (
2020
// Keys for Storage Class Parameters
21-
ParameterKeyZone = "zone"
22-
ParameterKeyType = "type"
21+
ParameterKeyType = "type"
22+
ParameterKeyReplicationType = "replication-type"
2323

2424
// Keys for Topology. This key will be shared amonst drivers from GCP
2525
TopologyKeyZone = "com.google.topology/zone"

‎pkg/common/utils.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ package common
1919
import (
2020
"fmt"
2121
"strings"
22+
23+
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta"
24+
)
25+
26+
const (
27+
volIDFmt = "projects/%s/zones/%s/disks/{}"
2228
)
2329

2430
func BytesToGb(bytes int64) int64 {
@@ -31,14 +37,40 @@ func GbToBytes(Gb int64) int64 {
3137
return Gb * 1024 * 1024 * 1024
3238
}
3339

34-
func SplitZoneNameId(id string) (string, string, error) {
40+
func VolumeIDToKey(id string) (*meta.Key, error) {
41+
splitId := strings.Split(id, "/")
42+
if len(splitId) != 6 {
43+
return nil, fmt.Errorf("failed to get id components. Expected projects/{project}/zones/{zone}/disks/{name}. Got: %s", id)
44+
}
45+
if splitId[2] == "zones" {
46+
return meta.ZonalKey(splitId[5], splitId[3]), nil
47+
} else if splitId[2] == "regions" {
48+
return meta.RegionalKey(splitId[5], splitId[3]), nil
49+
} else {
50+
return nil, fmt.Errorf("could not get id components, expected either zones or regions, got: %v", splitId[2])
51+
}
52+
}
53+
54+
func NodeIDToZoneAndName(id string) (string, string, error) {
3555
splitId := strings.Split(id, "/")
3656
if len(splitId) != 2 {
37-
return "", "", fmt.Errorf("Failed to get id components. Expected {zone}/{name}. Got: %s", id)
57+
return "", "", fmt.Errorf("failed to get id components. expected {zone}/{name}. Got: %s", id)
3858
}
3959
return splitId[0], splitId[1], nil
4060
}
4161

4262
func CombineVolumeId(zone, name string) string {
4363
return fmt.Sprintf("%s/%s", zone, name)
4464
}
65+
66+
func GetRegionFromZones(zones []string) (string, error) {
67+
if len(zones) < 1 {
68+
return "", fmt.Errorf("no zones specified")
69+
}
70+
zone := zones[0]
71+
splitZone := strings.Split(zone, "-")
72+
if len(splitZone) != 3 {
73+
return "", fmt.Errorf("zone in unexpected format, got %v", zone)
74+
}
75+
return strings.Join(splitZone[0:2], "-"), nil
76+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
Unless required by applicable law or agreed to in writing, software
9+
distributed under the License is distributed on an "AS IS" BASIS,
10+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
See the License for the specific language governing permissions and
12+
limitations under the License.
13+
*/
14+
15+
package gcecloudprovider
16+
17+
import (
18+
computebeta "google.golang.org/api/compute/v0.beta"
19+
compute "google.golang.org/api/compute/v1"
20+
)
21+
22+
type CloudDisk struct {
23+
ZonalDisk *compute.Disk
24+
RegionalDisk *computebeta.Disk
25+
}
26+
27+
type CloudDiskType string
28+
29+
const (
30+
// Zonal key type.
31+
Zonal = "zonal"
32+
// Regional key type.
33+
Regional = "regional"
34+
// Global key type.
35+
Global = "global"
36+
)
37+
38+
func ZonalCloudDisk(disk *compute.Disk) *CloudDisk {
39+
return &CloudDisk{
40+
ZonalDisk: disk,
41+
}
42+
}
43+
44+
func RegionalCloudDisk(disk *computebeta.Disk) *CloudDisk {
45+
return &CloudDisk{
46+
RegionalDisk: disk,
47+
}
48+
}
49+
50+
func (d *CloudDisk) Type() CloudDiskType {
51+
switch {
52+
case d.ZonalDisk != nil:
53+
return Zonal
54+
case d.RegionalDisk != nil:
55+
return Regional
56+
default:
57+
return Global
58+
}
59+
}
60+
61+
func (d *CloudDisk) GetUsers() []string {
62+
switch d.Type() {
63+
case Zonal:
64+
return d.ZonalDisk.Users
65+
case Regional:
66+
return d.RegionalDisk.Users
67+
default:
68+
return nil
69+
}
70+
}
71+
72+
func (d *CloudDisk) GetName() string {
73+
switch d.Type() {
74+
case Zonal:
75+
return d.ZonalDisk.Name
76+
case Regional:
77+
return d.RegionalDisk.Name
78+
default:
79+
return ""
80+
}
81+
}
82+
83+
func (d *CloudDisk) GetKind() string {
84+
switch d.Type() {
85+
case Zonal:
86+
return d.ZonalDisk.Kind
87+
case Regional:
88+
return d.RegionalDisk.Kind
89+
default:
90+
return ""
91+
}
92+
}
93+
94+
func (d *CloudDisk) GetType() string {
95+
switch d.Type() {
96+
case Zonal:
97+
return d.ZonalDisk.Type
98+
case Regional:
99+
return d.RegionalDisk.Type
100+
default:
101+
return ""
102+
}
103+
}
104+
105+
func (d *CloudDisk) GetSelfLink() string {
106+
switch d.Type() {
107+
case Zonal:
108+
return d.ZonalDisk.SelfLink
109+
case Regional:
110+
return d.RegionalDisk.SelfLink
111+
default:
112+
return ""
113+
}
114+
}
115+
116+
func (d *CloudDisk) GetSizeGb() int64 {
117+
switch d.Type() {
118+
case Zonal:
119+
return d.ZonalDisk.SizeGb
120+
case Regional:
121+
return d.RegionalDisk.SizeGb
122+
default:
123+
return -1
124+
}
125+
}

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

Lines changed: 105 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,21 @@ import (
1818
"fmt"
1919
"strings"
2020

21+
csi "github.com/container-storage-interface/spec/lib/go/csi/v0"
2122
"github.com/golang/glog"
2223
"golang.org/x/net/context"
24+
computebeta "google.golang.org/api/compute/v0.beta"
2325
compute "google.golang.org/api/compute/v1"
2426
"google.golang.org/api/googleapi"
25-
"google.golang.org/grpc/codes"
26-
"google.golang.org/grpc/status"
27+
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta"
2728
"sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/common"
2829
)
2930

3031
type FakeCloudProvider struct {
3132
project string
3233
zone string
3334

34-
disks map[string]*compute.Disk
35+
disks map[string]*CloudDisk
3536
instances map[string]*compute.Instance
3637
}
3738

@@ -41,130 +42,162 @@ func FakeCreateCloudProvider(project, zone string) (*FakeCloudProvider, error) {
4142
return &FakeCloudProvider{
4243
project: project,
4344
zone: zone,
44-
disks: map[string]*compute.Disk{},
45+
disks: map[string]*CloudDisk{},
4546
instances: map[string]*compute.Instance{},
4647
}, nil
4748

4849
}
4950

50-
// Getters
51-
func (cloud *FakeCloudProvider) GetProject() string {
52-
return cloud.project
53-
}
54-
func (cloud *FakeCloudProvider) GetZone() string {
55-
return cloud.zone
51+
func (cloud *FakeCloudProvider) ListZones(ctx context.Context, region string) ([]string, error) {
52+
return []string{cloud.zone, "fake-second-zone"}, nil
5653
}
5754

5855
// Disk Methods
59-
func (cloud *FakeCloudProvider) GetDiskOrError(ctx context.Context, volumeZone, volumeName string) (*compute.Disk, error) {
60-
disk, ok := cloud.disks[volumeName]
56+
func (cloud *FakeCloudProvider) GetDisk(ctx context.Context, volKey *meta.Key) (*CloudDisk, error) {
57+
disk, ok := cloud.disks[volKey.Name]
6158
if !ok {
6259
return nil, notFoundError()
6360
}
6461
return disk, nil
6562
}
6663

67-
func (cloud *FakeCloudProvider) GetAndValidateExistingDisk(ctx context.Context, configuredZone, name, diskType string, reqBytes, limBytes int64) (exists bool, err error) {
68-
disk, ok := cloud.disks[name]
69-
if !ok {
70-
// Disk doesn't exist
71-
return false, nil
64+
func (cloud *FakeCloudProvider) ValidateExistingDisk(ctx context.Context, resp *CloudDisk, diskType string, reqBytes, limBytes int64) error {
65+
if resp == nil {
66+
return fmt.Errorf("disk does not exist")
7267
}
73-
if disk != nil {
74-
// Check that disk is the same
75-
requestValid := common.GbToBytes(disk.SizeGb) >= reqBytes || reqBytes == 0
76-
responseValid := common.GbToBytes(disk.SizeGb) <= limBytes || limBytes == 0
77-
if !requestValid || !responseValid {
78-
return true, status.Error(codes.AlreadyExists, fmt.Sprintf(
79-
"Disk already exists with incompatible capacity. Need %v (Required) < %v (Existing) < %v (Limit)",
80-
reqBytes, common.GbToBytes(disk.SizeGb), limBytes))
81-
}
68+
requestValid := common.GbToBytes(resp.GetSizeGb()) >= reqBytes || reqBytes == 0
69+
responseValid := common.GbToBytes(resp.GetSizeGb()) <= limBytes || limBytes == 0
70+
if !requestValid || !responseValid {
71+
return fmt.Errorf(
72+
"disk already exists with incompatible capacity. Need %v (Required) < %v (Existing) < %v (Limit)",
73+
reqBytes, common.GbToBytes(resp.GetSizeGb()), limBytes)
74+
}
75+
76+
respType := strings.Split(resp.GetType(), "/")
77+
typeMatch := strings.TrimSpace(respType[len(respType)-1]) == strings.TrimSpace(diskType)
78+
typeDefault := diskType == "" && strings.TrimSpace(respType[len(respType)-1]) == "pd-standard"
79+
if !typeMatch && !typeDefault {
80+
return fmt.Errorf("disk already exists with incompatible type. Need %v. Got %v",
81+
diskType, respType[len(respType)-1])
82+
}
83+
84+
// Volume exists with matching name, capacity, type.
85+
glog.Infof("Compatible disk already exists. Reusing existing.")
86+
return nil
87+
}
8288

83-
respType := strings.Split(disk.Type, "/")
84-
typeMatch := respType[len(respType)-1] != diskType
85-
typeDefault := diskType == "" && respType[len(respType)-1] == "pd-standard"
86-
if !typeMatch && !typeDefault {
87-
return true, status.Error(codes.AlreadyExists, fmt.Sprintf(
88-
"Disk already exists with incompatible type. Need %v. Got %v",
89-
diskType, respType[len(respType)-1]))
89+
func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string) error {
90+
if disk, ok := cloud.disks[volKey.Name]; ok {
91+
err := cloud.ValidateExistingDisk(ctx, disk, diskType,
92+
int64(capacityRange.GetRequiredBytes()),
93+
int64(capacityRange.GetLimitBytes()))
94+
if err != nil {
95+
return err
9096
}
97+
}
9198

92-
// Volume exists with matching name, capacity, type.
93-
glog.Infof("Compatible disk already exists. Reusing existing.")
94-
return true, nil
99+
var diskToCreate *CloudDisk
100+
switch volKey.Type() {
101+
case meta.Zonal:
102+
diskToCreateGA := &compute.Disk{
103+
Name: volKey.Name,
104+
SizeGb: common.BytesToGb(capBytes),
105+
Description: "Disk created by GCE-PD CSI Driver",
106+
Type: cloud.GetDiskTypeURI(volKey, diskType),
107+
SelfLink: fmt.Sprintf("projects/%s/zones/%s/disks/%s", cloud.project, volKey.Zone, volKey.Name),
108+
}
109+
diskToCreate = ZonalCloudDisk(diskToCreateGA)
110+
case meta.Regional:
111+
diskToCreateBeta := &computebeta.Disk{
112+
Name: volKey.Name,
113+
SizeGb: common.BytesToGb(capBytes),
114+
Description: "Regional disk created by GCE-PD CSI Driver",
115+
Type: cloud.GetDiskTypeURI(volKey, diskType),
116+
SelfLink: fmt.Sprintf("projects/%s/regions/%s/disks/%s", cloud.project, volKey.Region, volKey.Name),
117+
}
118+
diskToCreate = RegionalCloudDisk(diskToCreateBeta)
119+
default:
120+
return fmt.Errorf("could not create disk, key was neither zonal nor regional, instead got: %v", volKey.String())
95121
}
96122

97-
return false, nil
123+
cloud.disks[volKey.Name] = diskToCreate
124+
return nil
98125
}
99126

100-
func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, zone string, diskToCreate *compute.Disk) (*compute.Operation, error) {
101-
cloud.disks[diskToCreate.Name] = diskToCreate
102-
return &compute.Operation{}, nil
127+
func (cloud *FakeCloudProvider) DeleteDisk(ctx context.Context, volKey *meta.Key) error {
128+
delete(cloud.disks, volKey.Name)
129+
return nil
103130
}
104131

105-
func (cloud *FakeCloudProvider) DeleteDisk(ctx context.Context, zone, name string) (*compute.Operation, error) {
106-
delete(cloud.disks, name)
107-
return &compute.Operation{}, nil
108-
}
132+
func (cloud *FakeCloudProvider) AttachDisk(ctx context.Context, disk *CloudDisk, volKey *meta.Key, readWrite, diskType, instanceZone, instanceName string) error {
133+
source := cloud.GetDiskSourceURI(disk, volKey)
109134

110-
func (cloud *FakeCloudProvider) AttachDisk(ctx context.Context, zone, instanceName string, attachedDisk *compute.AttachedDisk) (*compute.Operation, error) {
135+
attachedDiskV1 := &compute.AttachedDisk{
136+
DeviceName: disk.GetName(),
137+
Kind: disk.GetKind(),
138+
Mode: readWrite,
139+
Source: source,
140+
Type: diskType,
141+
}
111142
instance, ok := cloud.instances[instanceName]
112143
if !ok {
113-
return nil, fmt.Errorf("Failed to get instance %v", instanceName)
144+
return fmt.Errorf("Failed to get instance %v", instanceName)
114145
}
115-
instance.Disks = append(instance.Disks, attachedDisk)
116-
return nil, nil
146+
instance.Disks = append(instance.Disks, attachedDiskV1)
147+
return nil
117148
}
118149

119-
func (cloud *FakeCloudProvider) DetachDisk(ctx context.Context, volumeZone, instanceName, volumeName string) (*compute.Operation, error) {
150+
func (cloud *FakeCloudProvider) DetachDisk(ctx context.Context, volKey *meta.Key, instanceZone, instanceName string) error {
120151
instance, ok := cloud.instances[instanceName]
121152
if !ok {
122-
return nil, fmt.Errorf("Failed to get instance %v", instanceName)
153+
return fmt.Errorf("Failed to get instance %v", instanceName)
123154
}
124155
found := -1
125156
for i, disk := range instance.Disks {
126-
if disk.DeviceName == volumeName {
157+
if disk.DeviceName == volKey.Name {
127158
found = i
128159
break
129160
}
130161
}
131162
instance.Disks[found] = instance.Disks[len(instance.Disks)-1]
132163
instance.Disks = instance.Disks[:len(instance.Disks)-1]
133-
return nil, nil
164+
return nil
134165
}
135166

136-
/*
137-
func (cloud *CloudProvider) GetDiskSourceURI(disk *compute.Disk, zone string) string {
138-
projectsApiEndpoint := gceComputeAPIEndpoint + "projects/"
139-
if cloud.service != nil {
140-
projectsApiEndpoint = cloud.service.BasePath
141-
}
167+
func (cloud *FakeCloudProvider) GetDiskSourceURI(disk *CloudDisk, volKey *meta.Key) string {
168+
return ""
169+
}
142170

143-
return projectsApiEndpoint + fmt.Sprintf(
144-
diskSourceURITemplateSingleZone,
145-
cloud.project,
146-
zone,
147-
disk.Name)
171+
func (cloud *FakeCloudProvider) GetDiskTypeURI(volKey *meta.Key, diskType string) string {
172+
switch volKey.Type() {
173+
case meta.Zonal:
174+
return cloud.getZonalDiskTypeURI(volKey.Zone, diskType)
175+
case meta.Regional:
176+
return cloud.getRegionalDiskTypeURI(volKey.Region, diskType)
177+
default:
178+
return fmt.Sprintf("could not get disk type uri, key was neither zonal nor regional, instead got: %v", volKey.String())
179+
}
148180
}
149181

150-
func (cloud *CloudProvider) GetDiskTypeURI(zone, diskType string) string {
182+
func (cloud *FakeCloudProvider) getZonalDiskTypeURI(zone, diskType string) string {
151183
return fmt.Sprintf(diskTypeURITemplateSingleZone, cloud.project, zone, diskType)
152184
}
153-
*/
154-
func (cloud *FakeCloudProvider) GetDiskSourceURI(disk *compute.Disk, zone string) string {
155-
return ""
156-
}
157185

158-
func (cloud *FakeCloudProvider) GetDiskTypeURI(zone, diskType string) string {
159-
return ""
186+
func (cloud *FakeCloudProvider) getRegionalDiskTypeURI(region, diskType string) string {
187+
return fmt.Sprintf(diskTypeURITemplateRegional, cloud.project, region, diskType)
160188
}
161189

162-
func (cloud *FakeCloudProvider) WaitForAttach(ctx context.Context, zone, diskName, instanceName string) error {
190+
func (cloud *FakeCloudProvider) WaitForAttach(ctx context.Context, volKey *meta.Key, instanceZone, instanceName string) error {
163191
return nil
164192
}
165193

194+
// Regional Disk Methods
195+
func (cloud *FakeCloudProvider) GetReplicaZoneURI(zone string) string {
196+
return ""
197+
}
198+
166199
// Instance Methods
167-
func (cloud *FakeCloudProvider) InsertInstance(instance *compute.Instance, instanceName string) {
200+
func (cloud *FakeCloudProvider) InsertInstance(instance *compute.Instance, instanceZone, instanceName string) {
168201
cloud.instances[instanceName] = instance
169202
return
170203
}
@@ -177,11 +210,6 @@ func (cloud *FakeCloudProvider) GetInstanceOrError(ctx context.Context, instance
177210
return instance, nil
178211
}
179212

180-
// Operation Methods
181-
func (cloud *FakeCloudProvider) WaitForOp(ctx context.Context, op *compute.Operation, zone string) error {
182-
return nil
183-
}
184-
185213
func notFoundError() *googleapi.Error {
186214
return &googleapi.Error{
187215
Errors: []googleapi.ErrorItem{

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

Lines changed: 337 additions & 70 deletions
Large diffs are not rendered by default.

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

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,32 @@ import (
2525
"github.com/golang/glog"
2626
"golang.org/x/oauth2"
2727
"golang.org/x/oauth2/google"
28+
beta "google.golang.org/api/compute/v0.beta"
2829
compute "google.golang.org/api/compute/v1"
2930
"google.golang.org/api/googleapi"
3031
"k8s.io/apimachinery/pkg/util/wait"
3132
)
3233

3334
const (
3435
TokenURL = "https://accounts.google.com/o/oauth2/token"
35-
diskSourceURITemplateSingleZone = "%s/zones/%s/disks/%s" // {gce.projectID}/zones/{disk.Zone}/disks/{disk.Name}"
36-
diskTypeURITemplateSingleZone = "projects/%s/zones/%s/diskTypes/%s" // projects/{gce.projectID}/zones/{disk.Zone}/diskTypes/{disk.Type}"
36+
diskSourceURITemplateSingleZone = "%s/zones/%s/disks/%s" // {gce.projectID}/zones/{disk.Zone}/disks/{disk.Name}"
37+
diskSourceURITemplateRegional = "%s/regions/%s/disks/%s" //{gce.projectID}/regions/{disk.Region}/disks/repd"
38+
diskTypeURITemplateSingleZone = "%s/zones/%s/diskTypes/%s" // {gce.projectID}/zones/{disk.Zone}/diskTypes/{disk.Type}"
39+
diskTypeURITemplateRegional = "%s/regions/%s/diskTypes/%s" // {gce.projectID}/regions/{disk.Region}/diskTypes/{disk.Type}"
3740

38-
gceComputeAPIEndpoint = "https://www.googleapis.com/compute/v1/"
41+
regionURITemplate = "projects/%s/regions/%s"
42+
43+
GCEComputeAPIEndpoint = "https://www.googleapis.com/compute/v1/"
44+
GCEComputeBetaAPIEndpoint = "https://www.googleapis.com/compute/beta/"
45+
46+
replicaZoneURITemplateSingleZone = "%s/zones/%s" // {gce.projectID}/zones/{disk.Zone}
3947
)
4048

4149
type CloudProvider struct {
42-
service *compute.Service
43-
project string
44-
zone string
50+
service *compute.Service
51+
betaService *beta.Service
52+
project string
53+
zone string
4554
}
4655

4756
var _ GCECompute = &CloudProvider{}
@@ -52,19 +61,38 @@ func CreateCloudProvider(vendorVersion string) (*CloudProvider, error) {
5261
return nil, err
5362
}
5463

64+
betasvc, err := createBetaCloudService(vendorVersion)
65+
if err != nil {
66+
return nil, err
67+
}
68+
5569
project, zone, err := getProjectAndZoneFromMetadata()
5670
if err != nil {
5771
return nil, fmt.Errorf("Failed getting Project and Zone from Metadata server: %v", err)
5872
}
5973

6074
return &CloudProvider{
61-
service: svc,
62-
project: project,
63-
zone: zone,
75+
service: svc,
76+
betaService: betasvc,
77+
project: project,
78+
zone: zone,
6479
}, nil
6580

6681
}
6782

83+
func createBetaCloudService(vendorVersion string) (*beta.Service, error) {
84+
client, err := newDefaultOauthClient()
85+
if err != nil {
86+
return nil, err
87+
}
88+
service, err := beta.New(client)
89+
if err != nil {
90+
return nil, err
91+
}
92+
service.UserAgent = fmt.Sprintf("GCE CSI Driver/%s (%s %s)", vendorVersion, runtime.GOOS, runtime.GOARCH)
93+
return service, nil
94+
}
95+
6896
func createCloudService(vendorVersion string) (*compute.Service, error) {
6997
// TODO: support alternate methods of authentication
7098
svc, err := createCloudServiceWithDefaultServiceAccount(vendorVersion)

‎pkg/gce-cloud-provider/metadata/fake.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,24 @@ type fakeServiceManager struct{}
2020

2121
var _ MetadataService = &fakeServiceManager{}
2222

23+
const (
24+
FakeZone = "country-region-zone"
25+
FakeSecondZone = "country-region-zone2"
26+
FakeProject = "test-project"
27+
)
28+
2329
func NewFakeService() MetadataService {
2430
return &fakeServiceManager{}
2531
}
2632

2733
func (manager *fakeServiceManager) GetZone() string {
28-
return "test-location"
34+
return FakeZone
2935
}
3036

3137
func (manager *fakeServiceManager) GetProject() string {
32-
return "test-project"
38+
return FakeProject
39+
}
40+
41+
func (manager *fakeServiceManager) GetName() string {
42+
return "test-name"
3343
}

‎pkg/gce-cloud-provider/metadata/metadata.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@ import (
2727
type MetadataService interface {
2828
GetZone() string
2929
GetProject() string
30+
GetName() string
3031
}
3132

3233
type metadataServiceManager struct {
3334
// Current zone the driver is running in
3435
zone string
3536
project string
37+
name string
3638
}
3739

3840
var _ MetadataService = &metadataServiceManager{}
@@ -46,10 +48,15 @@ func NewMetadataService() (MetadataService, error) {
4648
if err != nil {
4749
return nil, fmt.Errorf("failed to get project: %v", err)
4850
}
51+
name, err := metadata.InstanceName()
52+
if err != nil {
53+
return nil, fmt.Errorf("failed to get instance name: %v", err)
54+
}
4955

5056
return &metadataServiceManager{
5157
project: projectID,
5258
zone: zone,
59+
name: name,
5360
}, nil
5461
}
5562

@@ -60,3 +67,7 @@ func (manager *metadataServiceManager) GetZone() string {
6067
func (manager *metadataServiceManager) GetProject() string {
6168
return manager.project
6269
}
70+
71+
func (manager *metadataServiceManager) GetName() string {
72+
return manager.name
73+
}

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

Lines changed: 299 additions & 169 deletions
Large diffs are not rendered by default.

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

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929

3030
type GCEDriver struct {
3131
name string
32-
nodeID string
3332
vendorVersion string
3433

3534
ids *GCEIdentityServer
@@ -46,16 +45,12 @@ func GetGCEDriver() *GCEDriver {
4645
}
4746

4847
func (gceDriver *GCEDriver) SetupGCEDriver(cloudProvider gce.GCECompute, mounter *mount.SafeFormatAndMount,
49-
deviceUtils mountmanager.DeviceUtils, meta metadataservice.MetadataService, name, nodeID, vendorVersion string) error {
48+
deviceUtils mountmanager.DeviceUtils, meta metadataservice.MetadataService, name, vendorVersion string) error {
5049
if name == "" {
5150
return fmt.Errorf("Driver name missing")
5251
}
53-
if nodeID == "" {
54-
return fmt.Errorf("NodeID missing")
55-
}
5652

5753
gceDriver.name = name
58-
gceDriver.nodeID = nodeID
5954
gceDriver.vendorVersion = vendorVersion
6055

6156
// Adding Capabilities
@@ -77,7 +72,7 @@ func (gceDriver *GCEDriver) SetupGCEDriver(cloudProvider gce.GCECompute, mounter
7772
// Set up RPC Servers
7873
gceDriver.ids = NewIdentityServer(gceDriver)
7974
gceDriver.ns = NewNodeServer(gceDriver, mounter, deviceUtils, meta)
80-
gceDriver.cs = NewControllerServer(gceDriver, cloudProvider)
75+
gceDriver.cs = NewControllerServer(gceDriver, cloudProvider, meta)
8176

8277
return nil
8378
}
@@ -141,10 +136,11 @@ func NewNodeServer(gceDriver *GCEDriver, mounter *mount.SafeFormatAndMount, devi
141136
}
142137
}
143138

144-
func NewControllerServer(gceDriver *GCEDriver, cloudProvider gce.GCECompute) *GCEControllerServer {
139+
func NewControllerServer(gceDriver *GCEDriver, cloudProvider gce.GCECompute, meta metadataservice.MetadataService) *GCEControllerServer {
145140
return &GCEControllerServer{
146-
Driver: gceDriver,
147-
CloudProvider: cloudProvider,
141+
Driver: gceDriver,
142+
CloudProvider: cloudProvider,
143+
MetadataService: meta,
148144
}
149145
}
150146

‎pkg/gce-pd-csi-driver/node.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package gceGCEDriver
1717
import (
1818
"fmt"
1919
"os"
20+
"strings"
2021
"sync"
2122

2223
csi "github.com/container-storage-interface/spec/lib/go/csi/v0"
@@ -71,7 +72,7 @@ func (ns *GCENodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePub
7172
return nil, err
7273
}
7374
if !notMnt {
74-
// TODO(dyzz): check if mount is compatible. Return OK if it is, or appropriate error.
75+
// TODO: check if mount is compatible. Return OK if it is, or appropriate error.
7576
return nil, nil
7677
}
7778

@@ -161,7 +162,7 @@ func (ns *GCENodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStage
161162
return nil, status.Error(codes.InvalidArgument, "NodeStageVolume Volume Capability must be provided")
162163
}
163164

164-
_, volumeName, err := common.SplitZoneNameId(volumeID)
165+
volumeKey, err := common.VolumeIDToKey(volumeID)
165166
if err != nil {
166167
return nil, err
167168
}
@@ -172,17 +173,17 @@ func (ns *GCENodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStage
172173
// TODO: Get real partitions
173174
partition := ""
174175

175-
devicePaths := ns.DeviceUtils.GetDiskByIdPaths(volumeName, partition)
176+
devicePaths := ns.DeviceUtils.GetDiskByIdPaths(volumeKey.Name, partition)
176177
devicePath, err := ns.DeviceUtils.VerifyDevicePath(devicePaths)
177178

178179
if err != nil {
179-
return nil, status.Error(codes.Internal, fmt.Sprintf("Error verifying GCE PD (%q) is attached: %v", volumeName, err))
180+
return nil, status.Error(codes.Internal, fmt.Sprintf("Error verifying GCE PD (%q) is attached: %v", volumeKey.Name, err))
180181
}
181182
if devicePath == "" {
182183
return nil, status.Error(codes.Internal, fmt.Sprintf("Unable to find device path out of attempted paths: %v", devicePaths))
183184
}
184185

185-
glog.Infof("Successfully found attached GCE PD %q at device path %s.", volumeName, devicePath)
186+
glog.Infof("Successfully found attached GCE PD %q at device path %s.", volumeKey.Name, devicePath)
186187

187188
// Part 2: Check if mount already exists at targetpath
188189
notMnt, err := ns.Mounter.Interface.IsLikelyNotMountPoint(stagingTargetPath)
@@ -256,8 +257,10 @@ func (ns *GCENodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUns
256257
func (ns *GCENodeServer) NodeGetId(ctx context.Context, req *csi.NodeGetIdRequest) (*csi.NodeGetIdResponse, error) {
257258
glog.Infof("NodeGetId called with req: %#v", req)
258259

260+
nodeID := strings.Join([]string{ns.MetadataService.GetZone(), ns.MetadataService.GetName()}, "/")
261+
259262
return &csi.NodeGetIdResponse{
260-
NodeId: ns.Driver.nodeID,
263+
NodeId: nodeID,
261264
}, nil
262265
}
263266

@@ -276,8 +279,10 @@ func (ns *GCENodeServer) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoRe
276279
Segments: map[string]string{common.TopologyKeyZone: ns.MetadataService.GetZone()},
277280
}
278281

282+
nodeID := strings.Join([]string{ns.MetadataService.GetZone(), ns.MetadataService.GetName()}, "/")
283+
279284
resp := &csi.NodeGetInfoResponse{
280-
NodeId: ns.Driver.nodeID,
285+
NodeId: nodeID,
281286
// TODO: Set MaxVolumesPerNode based on Node Type
282287
// Default of 0 means that CO Decides how many nodes can be published
283288
// Can get from metadata server "machine-type"

‎test/e2e/tests/multi_zone_e2e_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func testAttachWriteReadDetach(volId string, volName string, instance *remote.In
155155

156156
// Attach Disk
157157
err = client.ControllerPublishVolume(volId, instance.GetNodeID())
158-
Expect(err).To(BeNil(), "ControllerPublishVolume failed with error")
158+
Expect(err).To(BeNil(), "ControllerPublishVolume failed with error for disk %v on node %v", volId, instance.GetNodeID())
159159

160160
defer func() {
161161

‎test/e2e/utils/utils.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ func SetupProwConfig() (project, serviceAccount string) {
104104
// Default Compute Engine service account
105105
// [PROJECT_NUMBER]-compute@developer.gserviceaccount.com
106106
serviceAccount = fmt.Sprintf("%v-compute@developer.gserviceaccount.com", resp.ProjectNumber)
107+
glog.Infof("Using project %v", project)
107108
return project, serviceAccount
108109
}
109110

‎test/remote/instance.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ func (i *InstanceInfo) CreateOrGetInstance(serviceAccount string) error {
172172
glog.Warningf("SSH encountered an error: %v, output: %v", err, sshOut)
173173
return false, nil
174174
}
175-
glog.Infof("Instance %v in state RUNNING and vailable by SSH", i.name)
175+
glog.Infof("Instance %v in state RUNNING and available by SSH", i.name)
176176
return true, nil
177177
})
178178

‎test/run-e2e-local.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ set -o errexit
66
readonly PKGDIR=sigs.k8s.io/gcp-compute-persistent-disk-csi-driver
77

88

9-
ginkgo -v "test/e2e/tests" --logtostderr -- --project ${PROJECT} --service-account ${IAM_NAME}
9+
ginkgo --focus="RePD" -v "test/e2e/tests" --logtostderr -- --project ${PROJECT} --service-account ${IAM_NAME}

0 commit comments

Comments
 (0)
Please sign in to comment.