Skip to content

Commit cb15d04

Browse files
Merge pull request #3 from nikhilkathare/master
Pull changes from master HEAD to shared-pd branch
2 parents bfa815b + 4473873 commit cb15d04

File tree

8 files changed

+187
-2
lines changed

8 files changed

+187
-2
lines changed

OWNERS

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ reviewers:
77
approvers:
88
- davidz627
99
- saad-ali
10-
- msau42
10+
- msau42
11+
- verult

deploy/kubernetes/overlays/prow-gke-release-staging-head/kustomization.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,9 @@ patchesJson6902:
1111
kind: Deployment
1212
name: csi-gce-pd-controller
1313
path: leader-election-flag.yaml
14+
- target:
15+
group: apps
16+
version: v1
17+
kind: Deployment
18+
name: csi-gce-pd-controller
19+
path: volume-inuse-error-handler.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- op: add
2+
path: /spec/template/spec/containers/2/args/-
3+
value: "--handle-volume-inuse-error=false"

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

+11
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,17 @@ func (d *CloudDisk) GetKind() string {
127127
}
128128
}
129129

130+
func (d *CloudDisk) GetStatus() string {
131+
switch d.Type() {
132+
case Zonal:
133+
return d.ZonalDisk.Status
134+
case Regional:
135+
return d.RegionalDisk.Status
136+
default:
137+
return "Unknown"
138+
}
139+
}
140+
130141
// GetPDType returns the type of the PD as either 'pd-standard' or 'pd-ssd' The
131142
// "Type" field on the compute disk is stored as a url like
132143
// projects/project/zones/zone/diskTypes/pd-standard

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

+11
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ type FakeCloudProvider struct {
4848
pageTokens map[string]sets.String
4949
instances map[string]*computev1.Instance
5050
snapshots map[string]*computev1.Snapshot
51+
52+
// marker to set disk status during InsertDisk operation.
53+
mockDiskStatus string
5154
}
5255

5356
var _ GCECompute = &FakeCloudProvider{}
@@ -60,6 +63,8 @@ func CreateFakeCloudProvider(project, zone string, cloudDisks []*CloudDisk) (*Fa
6063
instances: map[string]*computev1.Instance{},
6164
snapshots: map[string]*computev1.Snapshot{},
6265
pageTokens: map[string]sets.String{},
66+
// A newly created disk is marked READY by default.
67+
mockDiskStatus: "READY",
6368
}
6469
for _, d := range cloudDisks {
6570
fcp.disks[d.GetName()] = d
@@ -265,6 +270,7 @@ func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key
265270
Type: cloud.GetDiskTypeURI(volKey, params.DiskType),
266271
SelfLink: fmt.Sprintf("projects/%s/zones/%s/disks/%s", cloud.project, volKey.Zone, volKey.Name),
267272
SourceSnapshotId: snapshotID,
273+
Status: cloud.mockDiskStatus,
268274
}
269275
if params.DiskEncryptionKMSKey != "" {
270276
diskToCreateGA.DiskEncryptionKey = &computev1.CustomerEncryptionKey{
@@ -280,6 +286,7 @@ func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key
280286
Type: cloud.GetDiskTypeURI(volKey, params.DiskType),
281287
SelfLink: fmt.Sprintf("projects/%s/regions/%s/disks/%s", cloud.project, volKey.Region, volKey.Name),
282288
SourceSnapshotId: snapshotID,
289+
Status: cloud.mockDiskStatus,
283290
}
284291
if params.DiskEncryptionKMSKey != "" {
285292
diskToCreateV1.DiskEncryptionKey = &computev1.CustomerEncryptionKey{
@@ -481,6 +488,10 @@ func (cloud *FakeCloudProvider) getGlobalSnapshotURI(snapshotName string) string
481488
snapshotName)
482489
}
483490

491+
func (cloud *FakeCloudProvider) UpdateDiskStatus(s string) {
492+
cloud.mockDiskStatus = s
493+
}
494+
484495
type FakeBlockingCloudProvider struct {
485496
*FakeCloudProvider
486497
ReadyToExecute chan chan struct{}

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

+42
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,29 @@ const (
6262
replicationTypeRegionalPD = "regional-pd"
6363
)
6464

65+
func isDiskReady(disk *gce.CloudDisk) (bool, error) {
66+
status := disk.GetStatus()
67+
switch status {
68+
case "READY":
69+
return true, nil
70+
case "FAILED":
71+
return false, fmt.Errorf("Disk %s status is FAILED", disk.GetName())
72+
case "CREATING":
73+
klog.V(4).Infof("Disk %s status is CREATING", disk.GetName())
74+
return false, nil
75+
case "DELETING":
76+
klog.V(4).Infof("Disk %s status is DELETING", disk.GetName())
77+
return false, nil
78+
case "RESTORING":
79+
klog.V(4).Infof("Disk %s status is RESTORING", disk.GetName())
80+
return false, nil
81+
default:
82+
klog.V(4).Infof("Disk %s status is: %s", disk.GetName(), status)
83+
}
84+
85+
return false, nil
86+
}
87+
6588
func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
6689
var err error
6790
// Validate arguments
@@ -150,6 +173,16 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
150173
if err != nil {
151174
return nil, status.Error(codes.AlreadyExists, fmt.Sprintf("CreateVolume disk already exists with same name and is incompatible: %v", err))
152175
}
176+
177+
ready, err := isDiskReady(existingDisk)
178+
if err != nil {
179+
return nil, status.Error(codes.Internal, fmt.Sprintf("CreateVolume disk %v had error checking ready status: %v", volKey, err))
180+
}
181+
182+
if !ready {
183+
return nil, status.Error(codes.Internal, fmt.Sprintf("CreateVolume disk %v is not ready", volKey))
184+
}
185+
153186
// If there is no validation error, immediately return success
154187
klog.V(4).Infof("CreateVolume succeeded for disk %v, it already exists and was compatible", volKey)
155188
return generateCreateVolumeResponse(existingDisk, capBytes, zones), nil
@@ -194,6 +227,15 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
194227
default:
195228
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("CreateVolume replication type '%s' is not supported", params.ReplicationType))
196229
}
230+
231+
ready, err := isDiskReady(disk)
232+
if err != nil {
233+
return nil, status.Error(codes.Internal, fmt.Sprintf("CreateVolume disk %v had error checking ready status: %v", volKey, err))
234+
}
235+
if !ready {
236+
return nil, status.Error(codes.Internal, fmt.Sprintf("CreateVolume disk %v is not ready", volKey))
237+
}
238+
197239
klog.V(4).Infof("CreateVolume succeeded for disk %v", volKey)
198240
return generateCreateVolumeResponse(disk, capBytes, zones), nil
199241

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

+108
Original file line numberDiff line numberDiff line change
@@ -1555,3 +1555,111 @@ func TestVolumeOperationConcurrency(t *testing.T) {
15551555
t.Errorf("Unexpected error: %v", err)
15561556
}
15571557
}
1558+
1559+
func TestCreateVolumeDiskReady(t *testing.T) {
1560+
// Define test cases
1561+
testCases := []struct {
1562+
name string
1563+
diskStatus string
1564+
req *csi.CreateVolumeRequest
1565+
expVol *csi.Volume
1566+
expErrCode codes.Code
1567+
}{
1568+
{
1569+
name: "disk status RESTORING",
1570+
diskStatus: "RESTORING",
1571+
req: &csi.CreateVolumeRequest{
1572+
Name: "test-name",
1573+
CapacityRange: stdCapRange,
1574+
VolumeCapabilities: stdVolCaps,
1575+
Parameters: stdParams,
1576+
},
1577+
expErrCode: codes.Internal,
1578+
},
1579+
{
1580+
name: "disk status CREATING",
1581+
diskStatus: "CREATING",
1582+
req: &csi.CreateVolumeRequest{
1583+
Name: "test-name",
1584+
CapacityRange: stdCapRange,
1585+
VolumeCapabilities: stdVolCaps,
1586+
Parameters: stdParams,
1587+
},
1588+
expErrCode: codes.Internal,
1589+
},
1590+
{
1591+
name: "disk status DELETING",
1592+
diskStatus: "DELETING",
1593+
req: &csi.CreateVolumeRequest{
1594+
Name: "test-name",
1595+
CapacityRange: stdCapRange,
1596+
VolumeCapabilities: stdVolCaps,
1597+
Parameters: stdParams,
1598+
},
1599+
expErrCode: codes.Internal,
1600+
},
1601+
{
1602+
name: "disk status FAILED",
1603+
diskStatus: "FAILED",
1604+
req: &csi.CreateVolumeRequest{
1605+
Name: "test-name",
1606+
CapacityRange: stdCapRange,
1607+
VolumeCapabilities: stdVolCaps,
1608+
Parameters: stdParams,
1609+
},
1610+
expErrCode: codes.Internal,
1611+
},
1612+
{
1613+
name: "success default",
1614+
diskStatus: "READY",
1615+
req: &csi.CreateVolumeRequest{
1616+
Name: "test-name",
1617+
CapacityRange: stdCapRange,
1618+
VolumeCapabilities: stdVolCaps,
1619+
Parameters: stdParams,
1620+
},
1621+
expVol: &csi.Volume{
1622+
CapacityBytes: common.GbToBytes(20),
1623+
VolumeId: testVolumeID,
1624+
VolumeContext: nil,
1625+
AccessibleTopology: stdTopology,
1626+
},
1627+
},
1628+
}
1629+
1630+
// Run test cases
1631+
for _, tc := range testCases {
1632+
t.Run(tc.name, func(t *testing.T) {
1633+
fcp, err := gce.CreateFakeCloudProvider(project, zone, nil)
1634+
if err != nil {
1635+
t.Fatalf("Failed to create fake cloud provider: %v", err)
1636+
}
1637+
1638+
// Setup hook to create new disks with given status.
1639+
fcp.UpdateDiskStatus(tc.diskStatus)
1640+
// Setup new driver each time so no interference
1641+
gceDriver := initGCEDriverWithCloudProvider(t, fcp)
1642+
// Start Test
1643+
resp, err := gceDriver.cs.CreateVolume(context.Background(), tc.req)
1644+
//check response
1645+
if err != nil {
1646+
serverError, ok := status.FromError(err)
1647+
if !ok {
1648+
t.Fatalf("Could not get error status code from err: %v", serverError)
1649+
}
1650+
if serverError.Code() != tc.expErrCode {
1651+
t.Fatalf("Expected error code: %v, got: %v. err : %v", tc.expErrCode, serverError.Code(), err)
1652+
}
1653+
return
1654+
}
1655+
if tc.expErrCode != codes.OK {
1656+
t.Fatalf("Expected error: %v, got no error", tc.expErrCode)
1657+
}
1658+
1659+
vol := resp.GetVolume()
1660+
if !reflect.DeepEqual(vol, tc.expVol) {
1661+
t.Fatalf("Mismatch in expected vol %v, current volume: %v\n", tc.expVol, vol)
1662+
}
1663+
})
1664+
}
1665+
}

test/k8s-integration/cluster.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,14 @@ func clusterUpGKE(gceZone, gceRegion string, numNodes int, imageType string, use
155155

156156
var cmd *exec.Cmd
157157
cmdParams := []string{"container", "clusters", "create", gkeTestClusterName,
158-
locationArg, locationVal, "--num-nodes", strconv.Itoa(numNodes)}
158+
locationArg, locationVal, "--num-nodes", strconv.Itoa(numNodes),
159+
"--quiet", "--machine-type", "n1-standard-2", "--image-type", imageType}
159160
if isVariableSet(gkeClusterVer) {
160161
cmdParams = append(cmdParams, "--cluster-version", *gkeClusterVer)
161162
} else {
162163
cmdParams = append(cmdParams, "--release-channel", *gkeReleaseChannel)
164+
// release channel based GKE clusters require autorepair to be enabled.
165+
cmdParams = append(cmdParams, "--enable-autorepair")
163166
}
164167

165168
if useManagedDriver {

0 commit comments

Comments
 (0)