Skip to content

Commit

Permalink
Add CSIDriverSpec.SELinuxMount
Browse files Browse the repository at this point in the history
The new field tells Kubernetes if the CSI driver supports mounting of
volumes with -o context=XYZ or not.
  • Loading branch information
jsafrane committed Aug 4, 2022
1 parent 34dc6b2 commit 3efeeef
Show file tree
Hide file tree
Showing 9 changed files with 206 additions and 12 deletions.
21 changes: 21 additions & 0 deletions pkg/apis/storage/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,27 @@ type CSIDriverSpec struct {
//
// +optional
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
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/storage/v1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,8 @@ func SetDefaults_CSIDriver(obj *storagev1.CSIDriver) {
obj.Spec.RequiresRepublish = new(bool)
*(obj.Spec.RequiresRepublish) = false
}
if obj.Spec.SELinuxMount == nil && utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
obj.Spec.SELinuxMount = new(bool)
*(obj.Spec.SELinuxMount) = false
}
}
27 changes: 27 additions & 0 deletions pkg/apis/storage/v1/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
4 changes: 4 additions & 0 deletions pkg/apis/storage/v1beta1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,8 @@ func SetDefaults_CSIDriver(obj *storagev1beta1.CSIDriver) {
obj.Spec.RequiresRepublish = new(bool)
*(obj.Spec.RequiresRepublish) = false
}
if obj.Spec.SELinuxMount == nil && utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
obj.Spec.SELinuxMount = new(bool)
*(obj.Spec.SELinuxMount) = false
}
}
27 changes: 27 additions & 0 deletions pkg/apis/storage/v1beta1/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
8 changes: 8 additions & 0 deletions pkg/registry/storage/csidriver/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ func (csiDriverStrategy) PrepareForCreate(ctx context.Context, obj runtime.Objec
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
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 {
Expand Down Expand Up @@ -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) {
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 {
Expand Down
85 changes: 73 additions & 12 deletions pkg/registry/storage/csidriver/strategy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,18 +211,36 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
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}

tests := []struct {
name string
old, update *storage.CSIDriver
csiInlineVolumeEnabled bool
wantCapacity *bool
wantModes []storage.VolumeLifecycleMode
wantTokenRequests []storage.TokenRequest
wantRequiresRepublish *bool
wantGeneration int64
name string
old, update *storage.CSIDriver
csiInlineVolumeEnabled bool
seLinuxMountReadWriteOncePodEnabled bool
wantCapacity *bool
wantModes []storage.VolumeLifecycleMode
wantTokenRequests []storage.TokenRequest
wantRequiresRepublish *bool
wantGeneration int64
wantSELinuxMount *bool
}{
{
name: "capacity feature enabled, before: none, update: enabled",
Expand All @@ -237,20 +255,20 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
wantCapacity: &disabled,
},
{
name: "inline feature enabled, before: none, update: persitent",
name: "inline feature enabled, before: none, update: persistent",
csiInlineVolumeEnabled: true,
old: driverWithNothing,
update: driverWithPersistent,
wantModes: resultPersistent,
},
{
name: "inline feature disabled, before: none, update: persitent",
name: "inline feature disabled, before: none, update: persistent",
old: driverWithNothing,
update: driverWithPersistent,
wantModes: nil,
},
{
name: "inline feature disabled, before: ephemeral, update: persitent",
name: "inline feature disabled, before: ephemeral, update: persistent",
old: driverWithEphemeral,
update: driverWithPersistent,
wantModes: resultPersistent,
Expand All @@ -263,11 +281,54 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
wantRequiresRepublish: &enabled,
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 {
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.SELinuxMountReadWriteOncePod, test.seLinuxMountReadWriteOncePodEnabled)()

csiDriver := test.update.DeepCopy()
Strategy.PrepareForUpdate(ctx, csiDriver, test.old)
Expand All @@ -276,9 +337,9 @@ func TestCSIDriverPrepareForUpdate(t *testing.T) {
require.Equal(t, test.wantModes, csiDriver.Spec.VolumeLifecycleModes)
require.Equal(t, test.wantTokenRequests, csiDriver.Spec.TokenRequests)
require.Equal(t, test.wantRequiresRepublish, csiDriver.Spec.RequiresRepublish)
require.Equal(t, test.wantSELinuxMount, csiDriver.Spec.SELinuxMounted)
})
}

}

func TestCSIDriverValidation(t *testing.T) {
Expand Down
21 changes: 21 additions & 0 deletions staging/src/k8s.io/api/storage/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,27 @@ type CSIDriverSpec struct {
//
// +optional
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
Expand Down
21 changes: 21 additions & 0 deletions staging/src/k8s.io/api/storage/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,27 @@ type CSIDriverSpec struct {
//
// +optional
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
Expand Down

0 comments on commit 3efeeef

Please sign in to comment.