mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
Merge pull request #84048 from jsafrane/kubelet-volumemode-checks
Check PV volumeMode in kubelet even when block feature is off
This commit is contained in:
commit
a005925a71
@ -505,19 +505,24 @@ func (dswp *desiredStateOfWorldPopulator) createVolumeSpec(
|
|||||||
pvcSource.ClaimName,
|
pvcSource.ClaimName,
|
||||||
pvcUID)
|
pvcUID)
|
||||||
|
|
||||||
// TODO: remove feature gate check after no longer needed
|
// TODO: replace this with util.GetVolumeMode() when features.BlockVolume is removed.
|
||||||
|
// The function will return the right value then.
|
||||||
|
volumeMode := v1.PersistentVolumeFilesystem
|
||||||
|
if volumeSpec.PersistentVolume != nil && volumeSpec.PersistentVolume.Spec.VolumeMode != nil {
|
||||||
|
volumeMode = *volumeSpec.PersistentVolume.Spec.VolumeMode
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove features.BlockVolume checks / comments after no longer needed
|
||||||
|
// Error if a container has volumeMounts but the volumeMode of PVC isn't Filesystem.
|
||||||
|
// Do not check feature gate here to make sure even when the feature is disabled in kubelet,
|
||||||
|
// because controller-manager / API server can already contain block PVs / PVCs.
|
||||||
|
if mounts.Has(podVolume.Name) && volumeMode != v1.PersistentVolumeFilesystem {
|
||||||
|
return nil, nil, "", fmt.Errorf(
|
||||||
|
"volume %s has volumeMode %s, but is specified in volumeMounts",
|
||||||
|
podVolume.Name,
|
||||||
|
volumeMode)
|
||||||
|
}
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
|
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
|
||||||
volumeMode, err := util.GetVolumeMode(volumeSpec)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, "", err
|
|
||||||
}
|
|
||||||
// Error if a container has volumeMounts but the volumeMode of PVC isn't Filesystem
|
|
||||||
if mounts.Has(podVolume.Name) && volumeMode != v1.PersistentVolumeFilesystem {
|
|
||||||
return nil, nil, "", fmt.Errorf(
|
|
||||||
"volume %s has volumeMode %s, but is specified in volumeMounts",
|
|
||||||
podVolume.Name,
|
|
||||||
volumeMode)
|
|
||||||
}
|
|
||||||
// Error if a container has volumeDevices but the volumeMode of PVC isn't Block
|
// Error if a container has volumeDevices but the volumeMode of PVC isn't Block
|
||||||
if devices.Has(podVolume.Name) && volumeMode != v1.PersistentVolumeBlock {
|
if devices.Has(podVolume.Name) && volumeMode != v1.PersistentVolumeBlock {
|
||||||
return nil, nil, "", fmt.Errorf(
|
return nil, nil, "", fmt.Errorf(
|
||||||
|
@ -389,6 +389,53 @@ func TestCreateVolumeSpec_Valid_File_VolumeMounts(t *testing.T) {
|
|||||||
pvc := &v1.PersistentVolumeClaim{
|
pvc := &v1.PersistentVolumeClaim{
|
||||||
Spec: v1.PersistentVolumeClaimSpec{
|
Spec: v1.PersistentVolumeClaimSpec{
|
||||||
VolumeName: "dswp-test-volume-name",
|
VolumeName: "dswp-test-volume-name",
|
||||||
|
VolumeMode: &mode,
|
||||||
|
},
|
||||||
|
Status: v1.PersistentVolumeClaimStatus{
|
||||||
|
Phase: v1.ClaimBound,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dswp, fakePodManager, _ := createDswpWithVolume(t, pv, pvc)
|
||||||
|
|
||||||
|
// create pod
|
||||||
|
containers := []v1.Container{
|
||||||
|
{
|
||||||
|
VolumeMounts: []v1.VolumeMount{
|
||||||
|
{
|
||||||
|
Name: "dswp-test-volume-name",
|
||||||
|
MountPath: "/mnt",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "file-bound", containers)
|
||||||
|
|
||||||
|
fakePodManager.AddPod(pod)
|
||||||
|
mountsMap, devicesMap := util.GetPodVolumeNames(pod)
|
||||||
|
_, volumeSpec, _, err :=
|
||||||
|
dswp.createVolumeSpec(pod.Spec.Volumes[0], pod.Name, pod.Namespace, mountsMap, devicesMap)
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
if volumeSpec == nil || err != nil {
|
||||||
|
t.Fatalf("Failed to create volumeSpec with combination of filesystem mode and volumeMounts. err: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateVolumeSpec_Valid_Nil_VolumeMounts(t *testing.T) {
|
||||||
|
// create dswp
|
||||||
|
pv := &v1.PersistentVolume{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "dswp-test-volume-name",
|
||||||
|
},
|
||||||
|
Spec: v1.PersistentVolumeSpec{
|
||||||
|
ClaimRef: &v1.ObjectReference{Namespace: "ns", Name: "file-bound"},
|
||||||
|
VolumeMode: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pvc := &v1.PersistentVolumeClaim{
|
||||||
|
Spec: v1.PersistentVolumeClaimSpec{
|
||||||
|
VolumeName: "dswp-test-volume-name",
|
||||||
|
VolumeMode: nil,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeClaimStatus{
|
Status: v1.PersistentVolumeClaimStatus{
|
||||||
Phase: v1.ClaimBound,
|
Phase: v1.ClaimBound,
|
||||||
@ -567,6 +614,56 @@ func TestCreateVolumeSpec_Invalid_Block_VolumeMounts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateVolumeSpec_Invalid_Block_VolumeMounts_Disabled(t *testing.T) {
|
||||||
|
// Enable BlockVolume feature gate
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, false)()
|
||||||
|
|
||||||
|
// create dswp
|
||||||
|
mode := v1.PersistentVolumeBlock
|
||||||
|
pv := &v1.PersistentVolume{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "dswp-test-volume-name",
|
||||||
|
},
|
||||||
|
Spec: v1.PersistentVolumeSpec{
|
||||||
|
ClaimRef: &v1.ObjectReference{Namespace: "ns", Name: "block-bound"},
|
||||||
|
VolumeMode: &mode,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pvc := &v1.PersistentVolumeClaim{
|
||||||
|
Spec: v1.PersistentVolumeClaimSpec{
|
||||||
|
VolumeName: "dswp-test-volume-name",
|
||||||
|
VolumeMode: &mode,
|
||||||
|
},
|
||||||
|
Status: v1.PersistentVolumeClaimStatus{
|
||||||
|
Phase: v1.ClaimBound,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dswp, fakePodManager, _ := createDswpWithVolume(t, pv, pvc)
|
||||||
|
|
||||||
|
// create pod
|
||||||
|
containers := []v1.Container{
|
||||||
|
{
|
||||||
|
VolumeMounts: []v1.VolumeMount{
|
||||||
|
{
|
||||||
|
Name: "dswp-test-volume-name",
|
||||||
|
MountPath: "/mnt",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "block-bound", containers)
|
||||||
|
|
||||||
|
fakePodManager.AddPod(pod)
|
||||||
|
mountsMap, devicesMap := util.GetPodVolumeNames(pod)
|
||||||
|
_, volumeSpec, _, err :=
|
||||||
|
dswp.createVolumeSpec(pod.Spec.Volumes[0], pod.Name, pod.Namespace, mountsMap, devicesMap)
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
if volumeSpec != nil || err == nil {
|
||||||
|
t.Fatalf("Unexpected volumeMode and volumeMounts/volumeDevices combination is accepted")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCheckVolumeFSResize(t *testing.T) {
|
func TestCheckVolumeFSResize(t *testing.T) {
|
||||||
setCapacity := func(pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim, capacity int) {
|
setCapacity := func(pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim, capacity int) {
|
||||||
pv.Spec.Capacity = volumeCapacity(capacity)
|
pv.Spec.Capacity = volumeCapacity(capacity)
|
||||||
|
Loading…
Reference in New Issue
Block a user