mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
Add CSIDriverSpec.SELinuxMount
The new field tells Kubernetes if the CSI driver supports mounting of volumes with -o context=XYZ or not.
This commit is contained in:
parent
34dc6b2587
commit
3efeeef346
@ -390,6 +390,27 @@ type CSIDriverSpec struct {
|
|||||||
//
|
//
|
||||||
// +optional
|
// +optional
|
||||||
RequiresRepublish *bool
|
RequiresRepublish *bool
|
||||||
|
|
||||||
|
// SELinuxMount specifies if the CSI driver supports "-o context"
|
||||||
|
// mount option.
|
||||||
|
//
|
||||||
|
// When "true", the CSI driver must ensure that all volumes provided by this CSI
|
||||||
|
// driver can be mounted separately with different `-o context` options. This is
|
||||||
|
// typical for storage backends that provide volumes as filesystems on block
|
||||||
|
// devices or as independent shared volumes.
|
||||||
|
// Kubernetes will call NodeStage / NodePublish with "-o context=xyz" mount
|
||||||
|
// option when mounting a ReadWriteOncePod volume used in Pod that has
|
||||||
|
// explicitly set SELinux context. In the future, it may be expanded to other
|
||||||
|
// volume AccessModes. In any case, Kubernetes will ensure that the volume is
|
||||||
|
// mounted only with a single SELinux context.
|
||||||
|
//
|
||||||
|
// When "false", Kubernetes won't pass any special SELinux mount options to the driver.
|
||||||
|
// This is typical for volumes that represent subdirectories of a bigger shared filesystem.
|
||||||
|
//
|
||||||
|
// Default is "false".
|
||||||
|
//
|
||||||
|
// +optional
|
||||||
|
SELinuxMount *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// FSGroupPolicy specifies if a CSI Driver supports modifying
|
// FSGroupPolicy specifies if a CSI Driver supports modifying
|
||||||
|
@ -64,4 +64,8 @@ func SetDefaults_CSIDriver(obj *storagev1.CSIDriver) {
|
|||||||
obj.Spec.RequiresRepublish = new(bool)
|
obj.Spec.RequiresRepublish = new(bool)
|
||||||
*(obj.Spec.RequiresRepublish) = false
|
*(obj.Spec.RequiresRepublish) = false
|
||||||
}
|
}
|
||||||
|
if obj.Spec.SELinuxMount == nil && utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
||||||
|
obj.Spec.SELinuxMount = new(bool)
|
||||||
|
*(obj.Spec.SELinuxMount) = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,3 +122,30 @@ func TestSetDefaultCSIDriver(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetDefaultSELinuxMountReadWriteOncePodEnabled(t *testing.T) {
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)()
|
||||||
|
driver := &storagev1.CSIDriver{}
|
||||||
|
|
||||||
|
// field should be defaulted
|
||||||
|
defaultSELinuxMount := false
|
||||||
|
output := roundTrip(t, runtime.Object(driver)).(*storagev1.CSIDriver)
|
||||||
|
outSELinuxMount := output.Spec.SELinuxMount
|
||||||
|
if outSELinuxMount == nil {
|
||||||
|
t.Errorf("Expected SELinuxMount to be defaulted to: %+v, got: nil", defaultSELinuxMount)
|
||||||
|
} else if *outSELinuxMount != defaultSELinuxMount {
|
||||||
|
t.Errorf("Expected SELinuxMount to be defaulted to: %+v, got: %+v", defaultSELinuxMount, outSELinuxMount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetDefaultSELinuxMountReadWriteOncePodDisabled(t *testing.T) {
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, false)()
|
||||||
|
driver := &storagev1.CSIDriver{}
|
||||||
|
|
||||||
|
// field should not be defaulted
|
||||||
|
output := roundTrip(t, runtime.Object(driver)).(*storagev1.CSIDriver)
|
||||||
|
outSELinuxMount := output.Spec.SELinuxMount
|
||||||
|
if outSELinuxMount != nil {
|
||||||
|
t.Errorf("Expected SELinuxMount to remain nil, got: %+v", outSELinuxMount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -64,4 +64,8 @@ func SetDefaults_CSIDriver(obj *storagev1beta1.CSIDriver) {
|
|||||||
obj.Spec.RequiresRepublish = new(bool)
|
obj.Spec.RequiresRepublish = new(bool)
|
||||||
*(obj.Spec.RequiresRepublish) = false
|
*(obj.Spec.RequiresRepublish) = false
|
||||||
}
|
}
|
||||||
|
if obj.Spec.SELinuxMount == nil && utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
||||||
|
obj.Spec.SELinuxMount = new(bool)
|
||||||
|
*(obj.Spec.SELinuxMount) = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,3 +165,30 @@ func TestSetDefaultCSIDriver(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetDefaultSELinuxMountReadWriteOncePodEnabled(t *testing.T) {
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)()
|
||||||
|
driver := &storagev1beta1.CSIDriver{}
|
||||||
|
|
||||||
|
// field should be defaulted
|
||||||
|
defaultSELinuxMount := false
|
||||||
|
output := roundTrip(t, runtime.Object(driver)).(*storagev1beta1.CSIDriver)
|
||||||
|
outSELinuxMount := output.Spec.SELinuxMount
|
||||||
|
if outSELinuxMount == nil {
|
||||||
|
t.Errorf("Expected SELinuxMount to be defaulted to: %+v, got: nil", defaultSELinuxMount)
|
||||||
|
} else if *outSELinuxMount != defaultSELinuxMount {
|
||||||
|
t.Errorf("Expected SELinuxMount to be defaulted to: %+v, got: %+v", defaultSELinuxMount, outSELinuxMount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetDefaultSELinuxMountReadWriteOncePodDisabled(t *testing.T) {
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, false)()
|
||||||
|
driver := &storagev1beta1.CSIDriver{}
|
||||||
|
|
||||||
|
// field should not be defaulted
|
||||||
|
output := roundTrip(t, runtime.Object(driver)).(*storagev1beta1.CSIDriver)
|
||||||
|
outSELinuxMount := output.Spec.SELinuxMount
|
||||||
|
if outSELinuxMount != nil {
|
||||||
|
t.Errorf("Expected SELinuxMount remain nil, got: %+v", outSELinuxMount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -50,6 +50,9 @@ func (csiDriverStrategy) PrepareForCreate(ctx context.Context, obj runtime.Objec
|
|||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
|
||||||
csiDriver.Spec.VolumeLifecycleModes = nil
|
csiDriver.Spec.VolumeLifecycleModes = nil
|
||||||
}
|
}
|
||||||
|
if !utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
||||||
|
csiDriver.Spec.SELinuxMount = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (csiDriverStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
func (csiDriverStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
||||||
@ -87,6 +90,11 @@ func (csiDriverStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.
|
|||||||
if !apiequality.Semantic.DeepEqual(oldCSIDriver.Spec.TokenRequests, newCSIDriver.Spec.TokenRequests) || !apiequality.Semantic.DeepEqual(oldCSIDriver.Spec.RequiresRepublish, newCSIDriver.Spec.RequiresRepublish) {
|
if !apiequality.Semantic.DeepEqual(oldCSIDriver.Spec.TokenRequests, newCSIDriver.Spec.TokenRequests) || !apiequality.Semantic.DeepEqual(oldCSIDriver.Spec.RequiresRepublish, newCSIDriver.Spec.RequiresRepublish) {
|
||||||
newCSIDriver.Generation = oldCSIDriver.Generation + 1
|
newCSIDriver.Generation = oldCSIDriver.Generation + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if oldCSIDriver.Spec.SELinuxMount == nil &&
|
||||||
|
!utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
||||||
|
newCSIDriver.Spec.SELinuxMount = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (csiDriverStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
func (csiDriverStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
||||||
|
@ -211,18 +211,36 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
|||||||
RequiresRepublish: &enabled,
|
RequiresRepublish: &enabled,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
driverWithSELinuxMountEnabled := &storage.CSIDriver{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "foo",
|
||||||
|
},
|
||||||
|
Spec: storage.CSIDriverSpec{
|
||||||
|
SELinuxMount: &enabled,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
driverWithSELinuxMountDisabled := &storage.CSIDriver{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "foo",
|
||||||
|
},
|
||||||
|
Spec: storage.CSIDriverSpec{
|
||||||
|
SELinuxMount: &disabled,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
resultPersistent := []storage.VolumeLifecycleMode{storage.VolumeLifecyclePersistent}
|
resultPersistent := []storage.VolumeLifecycleMode{storage.VolumeLifecyclePersistent}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
old, update *storage.CSIDriver
|
old, update *storage.CSIDriver
|
||||||
csiInlineVolumeEnabled bool
|
csiInlineVolumeEnabled bool
|
||||||
wantCapacity *bool
|
seLinuxMountReadWriteOncePodEnabled bool
|
||||||
wantModes []storage.VolumeLifecycleMode
|
wantCapacity *bool
|
||||||
wantTokenRequests []storage.TokenRequest
|
wantModes []storage.VolumeLifecycleMode
|
||||||
wantRequiresRepublish *bool
|
wantTokenRequests []storage.TokenRequest
|
||||||
wantGeneration int64
|
wantRequiresRepublish *bool
|
||||||
|
wantGeneration int64
|
||||||
|
wantSELinuxMount *bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "capacity feature enabled, before: none, update: enabled",
|
name: "capacity feature enabled, before: none, update: enabled",
|
||||||
@ -237,20 +255,20 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
|||||||
wantCapacity: &disabled,
|
wantCapacity: &disabled,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "inline feature enabled, before: none, update: persitent",
|
name: "inline feature enabled, before: none, update: persistent",
|
||||||
csiInlineVolumeEnabled: true,
|
csiInlineVolumeEnabled: true,
|
||||||
old: driverWithNothing,
|
old: driverWithNothing,
|
||||||
update: driverWithPersistent,
|
update: driverWithPersistent,
|
||||||
wantModes: resultPersistent,
|
wantModes: resultPersistent,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "inline feature disabled, before: none, update: persitent",
|
name: "inline feature disabled, before: none, update: persistent",
|
||||||
old: driverWithNothing,
|
old: driverWithNothing,
|
||||||
update: driverWithPersistent,
|
update: driverWithPersistent,
|
||||||
wantModes: nil,
|
wantModes: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "inline feature disabled, before: ephemeral, update: persitent",
|
name: "inline feature disabled, before: ephemeral, update: persistent",
|
||||||
old: driverWithEphemeral,
|
old: driverWithEphemeral,
|
||||||
update: driverWithPersistent,
|
update: driverWithPersistent,
|
||||||
wantModes: resultPersistent,
|
wantModes: resultPersistent,
|
||||||
@ -263,11 +281,54 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
|||||||
wantRequiresRepublish: &enabled,
|
wantRequiresRepublish: &enabled,
|
||||||
wantGeneration: 1,
|
wantGeneration: 1,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "SELinux mount support feature enabled, before: nil, update: on",
|
||||||
|
seLinuxMountReadWriteOncePodEnabled: true,
|
||||||
|
old: driverWithNothing,
|
||||||
|
update: driverWithSELinuxMountEnabled,
|
||||||
|
wantSELinuxMount: &enabled,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SELinux mount support feature enabled, before: off, update: on",
|
||||||
|
seLinuxMountReadWriteOncePodEnabled: true,
|
||||||
|
old: driverWithSELinuxMountDisabled,
|
||||||
|
update: driverWithSELinuxMountEnabled,
|
||||||
|
wantSELinuxMount: &enabled,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SELinux mount support feature enabled, before: on, update: off",
|
||||||
|
seLinuxMountReadWriteOncePodEnabled: true,
|
||||||
|
old: driverWithSELinuxMountEnabled,
|
||||||
|
update: driverWithSELinuxMountDisabled,
|
||||||
|
wantSELinuxMount: &disabled,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SELinux mount support feature disabled, before: nil, update: on",
|
||||||
|
seLinuxMountReadWriteOncePodEnabled: false,
|
||||||
|
old: driverWithNothing,
|
||||||
|
update: driverWithSELinuxMountEnabled,
|
||||||
|
wantSELinuxMount: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SELinux mount support feature disabled, before: off, update: on",
|
||||||
|
seLinuxMountReadWriteOncePodEnabled: false,
|
||||||
|
old: driverWithSELinuxMountDisabled,
|
||||||
|
update: driverWithSELinuxMountEnabled,
|
||||||
|
wantSELinuxMount: &enabled,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SELinux mount support feature enabled, before: on, update: off",
|
||||||
|
seLinuxMountReadWriteOncePodEnabled: false,
|
||||||
|
old: driverWithSELinuxMountEnabled,
|
||||||
|
update: driverWithSELinuxMountDisabled,
|
||||||
|
wantSELinuxMount: &disabled,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.csiInlineVolumeEnabled)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, test.csiInlineVolumeEnabled)()
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, test.seLinuxMountReadWriteOncePodEnabled)()
|
||||||
|
|
||||||
csiDriver := test.update.DeepCopy()
|
csiDriver := test.update.DeepCopy()
|
||||||
Strategy.PrepareForUpdate(ctx, csiDriver, test.old)
|
Strategy.PrepareForUpdate(ctx, csiDriver, test.old)
|
||||||
@ -276,9 +337,9 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
|
|||||||
require.Equal(t, test.wantModes, csiDriver.Spec.VolumeLifecycleModes)
|
require.Equal(t, test.wantModes, csiDriver.Spec.VolumeLifecycleModes)
|
||||||
require.Equal(t, test.wantTokenRequests, csiDriver.Spec.TokenRequests)
|
require.Equal(t, test.wantTokenRequests, csiDriver.Spec.TokenRequests)
|
||||||
require.Equal(t, test.wantRequiresRepublish, csiDriver.Spec.RequiresRepublish)
|
require.Equal(t, test.wantRequiresRepublish, csiDriver.Spec.RequiresRepublish)
|
||||||
|
require.Equal(t, test.wantSELinuxMount, csiDriver.Spec.SELinuxMounted)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCSIDriverValidation(t *testing.T) {
|
func TestCSIDriverValidation(t *testing.T) {
|
||||||
|
@ -392,6 +392,27 @@ type CSIDriverSpec struct {
|
|||||||
//
|
//
|
||||||
// +optional
|
// +optional
|
||||||
RequiresRepublish *bool `json:"requiresRepublish,omitempty" protobuf:"varint,7,opt,name=requiresRepublish"`
|
RequiresRepublish *bool `json:"requiresRepublish,omitempty" protobuf:"varint,7,opt,name=requiresRepublish"`
|
||||||
|
|
||||||
|
// SELinuxMount specifies if the CSI driver supports "-o context"
|
||||||
|
// mount option.
|
||||||
|
//
|
||||||
|
// When "true", the CSI driver must ensure that all volumes provided by this CSI
|
||||||
|
// driver can be mounted separately with different `-o context` options. This is
|
||||||
|
// typical for storage backends that provide volumes as filesystems on block
|
||||||
|
// devices or as independent shared volumes.
|
||||||
|
// Kubernetes will call NodeStage / NodePublish with "-o context=xyz" mount
|
||||||
|
// option when mounting a ReadWriteOncePod volume used in Pod that has
|
||||||
|
// explicitly set SELinux context. In the future, it may be expanded to other
|
||||||
|
// volume AccessModes. In any case, Kubernetes will ensure that the volume is
|
||||||
|
// mounted only with a single SELinux context.
|
||||||
|
//
|
||||||
|
// When "false", Kubernetes won't pass any special SELinux mount options to the driver.
|
||||||
|
// This is typical for volumes that represent subdirectories of a bigger shared filesystem.
|
||||||
|
//
|
||||||
|
// Default is "false".
|
||||||
|
//
|
||||||
|
// +optional
|
||||||
|
SELinuxMount *bool `json:"seLinuxMount,omitempty" protobuf:"varint,8,opt,name=seLinuxMount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FSGroupPolicy specifies if a CSI Driver supports modifying
|
// FSGroupPolicy specifies if a CSI Driver supports modifying
|
||||||
|
@ -410,6 +410,27 @@ type CSIDriverSpec struct {
|
|||||||
//
|
//
|
||||||
// +optional
|
// +optional
|
||||||
RequiresRepublish *bool `json:"requiresRepublish,omitempty" protobuf:"varint,7,opt,name=requiresRepublish"`
|
RequiresRepublish *bool `json:"requiresRepublish,omitempty" protobuf:"varint,7,opt,name=requiresRepublish"`
|
||||||
|
|
||||||
|
// SELinuxMount specifies if the CSI driver supports "-o context"
|
||||||
|
// mount option.
|
||||||
|
//
|
||||||
|
// When "true", the CSI driver must ensure that all volumes provided by this CSI
|
||||||
|
// driver can be mounted separately with different `-o context` options. This is
|
||||||
|
// typical for storage backends that provide volumes as filesystems on block
|
||||||
|
// devices or as independent shared volumes.
|
||||||
|
// Kubernetes will call NodeStage / NodePublish with "-o context=xyz" mount
|
||||||
|
// option when mounting a ReadWriteOncePod volume used in Pod that has
|
||||||
|
// explicitly set SELinux context. In the future, it may be expanded to other
|
||||||
|
// volume AccessModes. In any case, Kubernetes will ensure that the volume is
|
||||||
|
// mounted only with a single SELinux context.
|
||||||
|
//
|
||||||
|
// When "false", Kubernetes won't pass any special SELinux mount options to the driver.
|
||||||
|
// This is typical for volumes that represent subdirectories of a bigger shared filesystem.
|
||||||
|
//
|
||||||
|
// Default is "false".
|
||||||
|
//
|
||||||
|
// +optional
|
||||||
|
SELinuxMount *bool `json:"seLinuxMount,omitempty" protobuf:"varint,8,opt,name=seLinuxMount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FSGroupPolicy specifies if a CSI Driver supports modifying
|
// FSGroupPolicy specifies if a CSI Driver supports modifying
|
||||||
|
Loading…
Reference in New Issue
Block a user