Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
2224e80d
Commit
2224e80d
authored
Nov 03, 2016
by
Jan Safranek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix race when two provisioner create two PVs for a single claim.
parent
18de83c6
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
60 additions
and
0 deletions
+60
-0
delete_test.go
pkg/controller/volume/persistentvolume/delete_test.go
+43
-0
pv_controller.go
pkg/controller/volume/persistentvolume/pv_controller.go
+17
-0
No files found.
pkg/controller/volume/persistentvolume/delete_test.go
View file @
2224e80d
...
@@ -148,6 +148,49 @@ func TestDeleteSync(t *testing.T) {
...
@@ -148,6 +148,49 @@ func TestDeleteSync(t *testing.T) {
return
testSyncVolume
(
ctrl
,
reactor
,
test
)
return
testSyncVolume
(
ctrl
,
reactor
,
test
)
},
},
},
},
{
// delete success - two PVs are provisioned for a single claim.
// One of the PVs is deleted.
"8-11 - two PVs provisioned for a single claim"
,
[]
*
api
.
PersistentVolume
{
newVolume
(
"volume8-11-1"
,
"1Gi"
,
"uid8-11"
,
"claim8-11"
,
api
.
VolumeBound
,
api
.
PersistentVolumeReclaimDelete
,
annDynamicallyProvisioned
),
newVolume
(
"volume8-11-2"
,
"1Gi"
,
"uid8-11"
,
"claim8-11"
,
api
.
VolumeBound
,
api
.
PersistentVolumeReclaimDelete
,
annDynamicallyProvisioned
),
},
[]
*
api
.
PersistentVolume
{
newVolume
(
"volume8-11-2"
,
"1Gi"
,
"uid8-11"
,
"claim8-11"
,
api
.
VolumeBound
,
api
.
PersistentVolumeReclaimDelete
,
annDynamicallyProvisioned
),
},
// the claim is bound to volume8-11-2 -> volume8-11-1 has lost the race and will be deleted
newClaimArray
(
"claim8-11"
,
"uid8-11"
,
"10Gi"
,
"volume8-11-2"
,
api
.
ClaimBound
),
newClaimArray
(
"claim8-11"
,
"uid8-11"
,
"10Gi"
,
"volume8-11-2"
,
api
.
ClaimBound
),
noevents
,
noerrors
,
// Inject deleter into the controller and call syncVolume. The
// deleter simulates one delete() call that succeeds.
wrapTestWithReclaimCalls
(
operationDelete
,
[]
error
{
nil
},
testSyncVolume
),
},
{
// delete success - two PVs are externally provisioned for a single
// claim. One of the PVs is marked as Released to be deleted by the
// external provisioner.
"8-12 - two PVs externally provisioned for a single claim"
,
[]
*
api
.
PersistentVolume
{
newVolume
(
"volume8-12-1"
,
"1Gi"
,
"uid8-12"
,
"claim8-12"
,
api
.
VolumeBound
,
api
.
PersistentVolumeReclaimDelete
,
annDynamicallyProvisioned
),
newVolume
(
"volume8-12-2"
,
"1Gi"
,
"uid8-12"
,
"claim8-12"
,
api
.
VolumeBound
,
api
.
PersistentVolumeReclaimDelete
,
annDynamicallyProvisioned
),
},
[]
*
api
.
PersistentVolume
{
newVolume
(
"volume8-12-1"
,
"1Gi"
,
"uid8-12"
,
"claim8-12"
,
api
.
VolumeReleased
,
api
.
PersistentVolumeReclaimDelete
,
annDynamicallyProvisioned
),
newVolume
(
"volume8-12-2"
,
"1Gi"
,
"uid8-12"
,
"claim8-12"
,
api
.
VolumeBound
,
api
.
PersistentVolumeReclaimDelete
,
annDynamicallyProvisioned
),
},
// the claim is bound to volume8-12-2 -> volume8-12-1 has lost the race and will be "Released"
newClaimArray
(
"claim8-12"
,
"uid8-12"
,
"10Gi"
,
"volume8-12-2"
,
api
.
ClaimBound
),
newClaimArray
(
"claim8-12"
,
"uid8-12"
,
"10Gi"
,
"volume8-12-2"
,
api
.
ClaimBound
),
noevents
,
noerrors
,
func
(
ctrl
*
PersistentVolumeController
,
reactor
*
volumeReactor
,
test
controllerTest
)
error
{
// Inject external deleter annotation
test
.
initialVolumes
[
0
]
.
Annotations
[
annDynamicallyProvisioned
]
=
"external.io/test"
test
.
expectedVolumes
[
0
]
.
Annotations
[
annDynamicallyProvisioned
]
=
"external.io/test"
return
testSyncVolume
(
ctrl
,
reactor
,
test
)
},
},
}
}
runSyncTests
(
t
,
tests
,
[]
*
storage
.
StorageClass
{})
runSyncTests
(
t
,
tests
,
[]
*
storage
.
StorageClass
{})
}
}
...
...
pkg/controller/volume/persistentvolume/pv_controller.go
View file @
2224e80d
...
@@ -492,6 +492,17 @@ func (ctrl *PersistentVolumeController) syncVolume(volume *api.PersistentVolume)
...
@@ -492,6 +492,17 @@ func (ctrl *PersistentVolumeController) syncVolume(volume *api.PersistentVolume)
// This volume was dynamically provisioned for this claim. The
// This volume was dynamically provisioned for this claim. The
// claim got bound elsewhere, and thus this volume is not
// claim got bound elsewhere, and thus this volume is not
// needed. Delete it.
// needed. Delete it.
// Mark the volume as Released for external deleters and to let
// the user know. Don't overwrite existing Failed status!
if
volume
.
Status
.
Phase
!=
api
.
VolumeReleased
&&
volume
.
Status
.
Phase
!=
api
.
VolumeFailed
{
// Also, log this only once:
glog
.
V
(
2
)
.
Infof
(
"dynamically volume %q is released and it will be deleted"
,
volume
.
Name
)
if
volume
,
err
=
ctrl
.
updateVolumePhase
(
volume
,
api
.
VolumeReleased
,
""
);
err
!=
nil
{
// Nothing was saved; we will fall back into the same condition
// in the next call to this method
return
err
}
}
if
err
=
ctrl
.
reclaimVolume
(
volume
);
err
!=
nil
{
if
err
=
ctrl
.
reclaimVolume
(
volume
);
err
!=
nil
{
// Deletion failed, we will fall back into the same condition
// Deletion failed, we will fall back into the same condition
// in the next call to this method
// in the next call to this method
...
@@ -1131,6 +1142,12 @@ func (ctrl *PersistentVolumeController) isVolumeReleased(volume *api.PersistentV
...
@@ -1131,6 +1142,12 @@ func (ctrl *PersistentVolumeController) isVolumeReleased(volume *api.PersistentV
}
}
if
claim
!=
nil
&&
claim
.
UID
==
volume
.
Spec
.
ClaimRef
.
UID
{
if
claim
!=
nil
&&
claim
.
UID
==
volume
.
Spec
.
ClaimRef
.
UID
{
// the claim still exists and has the right UID
// the claim still exists and has the right UID
if
len
(
claim
.
Spec
.
VolumeName
)
>
0
&&
claim
.
Spec
.
VolumeName
!=
volume
.
Name
{
// the claim is bound to another PV, this PV *is* released
return
true
,
nil
}
glog
.
V
(
4
)
.
Infof
(
"isVolumeReleased[%s]: ClaimRef is still valid, volume is not released"
,
volume
.
Name
)
glog
.
V
(
4
)
.
Infof
(
"isVolumeReleased[%s]: ClaimRef is still valid, volume is not released"
,
volume
.
Name
)
return
false
,
nil
return
false
,
nil
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment