mirror of https://github.com/k3s-io/k3s
Update all tests to account for BlockVolume enabled by default
parent
7a6acefd21
commit
dd517c9ff2
|
@ -403,11 +403,15 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
|
||||||
pv.Status.Message = c.RandString()
|
pv.Status.Message = c.RandString()
|
||||||
reclamationPolicies := []core.PersistentVolumeReclaimPolicy{core.PersistentVolumeReclaimRecycle, core.PersistentVolumeReclaimRetain}
|
reclamationPolicies := []core.PersistentVolumeReclaimPolicy{core.PersistentVolumeReclaimRecycle, core.PersistentVolumeReclaimRetain}
|
||||||
pv.Spec.PersistentVolumeReclaimPolicy = reclamationPolicies[c.Rand.Intn(len(reclamationPolicies))]
|
pv.Spec.PersistentVolumeReclaimPolicy = reclamationPolicies[c.Rand.Intn(len(reclamationPolicies))]
|
||||||
|
volumeModes := []core.PersistentVolumeMode{core.PersistentVolumeFilesystem, core.PersistentVolumeBlock}
|
||||||
|
pv.Spec.VolumeMode = &volumeModes[c.Rand.Intn(len(volumeModes))]
|
||||||
},
|
},
|
||||||
func(pvc *core.PersistentVolumeClaim, c fuzz.Continue) {
|
func(pvc *core.PersistentVolumeClaim, c fuzz.Continue) {
|
||||||
c.FuzzNoCustom(pvc) // fuzz self without calling this function again
|
c.FuzzNoCustom(pvc) // fuzz self without calling this function again
|
||||||
types := []core.PersistentVolumeClaimPhase{core.ClaimBound, core.ClaimPending, core.ClaimLost}
|
types := []core.PersistentVolumeClaimPhase{core.ClaimBound, core.ClaimPending, core.ClaimLost}
|
||||||
pvc.Status.Phase = types[c.Rand.Intn(len(types))]
|
pvc.Status.Phase = types[c.Rand.Intn(len(types))]
|
||||||
|
volumeModes := []core.PersistentVolumeMode{core.PersistentVolumeFilesystem, core.PersistentVolumeBlock}
|
||||||
|
pvc.Spec.VolumeMode = &volumeModes[c.Rand.Intn(len(volumeModes))]
|
||||||
},
|
},
|
||||||
func(obj *core.AzureDiskVolumeSource, c fuzz.Continue) {
|
func(obj *core.AzureDiskVolumeSource, c fuzz.Continue) {
|
||||||
if obj.CachingMode == nil {
|
if obj.CachingMode == nil {
|
||||||
|
|
|
@ -27,8 +27,10 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
|
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
utilpointer "k8s.io/utils/pointer"
|
utilpointer "k8s.io/utils/pointer"
|
||||||
|
|
||||||
// enforce that all types are installed
|
// enforce that all types are installed
|
||||||
|
@ -803,6 +805,7 @@ func TestSetDefaultSecret(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetDefaultPersistentVolume(t *testing.T) {
|
func TestSetDefaultPersistentVolume(t *testing.T) {
|
||||||
|
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, false)()
|
||||||
pv := &v1.PersistentVolume{}
|
pv := &v1.PersistentVolume{}
|
||||||
obj2 := roundTrip(t, runtime.Object(pv))
|
obj2 := roundTrip(t, runtime.Object(pv))
|
||||||
pv2 := obj2.(*v1.PersistentVolume)
|
pv2 := obj2.(*v1.PersistentVolume)
|
||||||
|
@ -834,15 +837,10 @@ func TestSetDefaultPersistentVolume(t *testing.T) {
|
||||||
} else if *outputMode3 != defaultMode {
|
} else if *outputMode3 != defaultMode {
|
||||||
t.Errorf("Expected VolumeMode to be defaulted to: %+v, got: %+v", defaultMode, outputMode3)
|
t.Errorf("Expected VolumeMode to be defaulted to: %+v, got: %+v", defaultMode, outputMode3)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to disable feature gate for BlockVolume: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetDefaultPersistentVolumeClaim(t *testing.T) {
|
func TestSetDefaultPersistentVolumeClaim(t *testing.T) {
|
||||||
|
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, false)()
|
||||||
pvc := &v1.PersistentVolumeClaim{}
|
pvc := &v1.PersistentVolumeClaim{}
|
||||||
obj2 := roundTrip(t, runtime.Object(pvc))
|
obj2 := roundTrip(t, runtime.Object(pvc))
|
||||||
pvc2 := obj2.(*v1.PersistentVolumeClaim)
|
pvc2 := obj2.(*v1.PersistentVolumeClaim)
|
||||||
|
@ -871,11 +869,6 @@ func TestSetDefaultPersistentVolumeClaim(t *testing.T) {
|
||||||
} else if *outputMode3 != defaultMode {
|
} else if *outputMode3 != defaultMode {
|
||||||
t.Errorf("Expected VolumeMode to be defaulted to: %+v, got: %+v", defaultMode, outputMode3)
|
t.Errorf("Expected VolumeMode to be defaulted to: %+v, got: %+v", defaultMode, outputMode3)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to disable feature gate for BlockVolume: %v", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetDefaulEndpointsProtocol(t *testing.T) {
|
func TestSetDefaulEndpointsProtocol(t *testing.T) {
|
||||||
|
|
|
@ -66,9 +66,11 @@ func testVolume(name string, namespace string, spec core.PersistentVolumeSpec) *
|
||||||
|
|
||||||
func TestValidatePersistentVolumes(t *testing.T) {
|
func TestValidatePersistentVolumes(t *testing.T) {
|
||||||
validMode := core.PersistentVolumeFilesystem
|
validMode := core.PersistentVolumeFilesystem
|
||||||
|
invalidMode := core.PersistentVolumeMode("fakeVolumeMode")
|
||||||
scenarios := map[string]struct {
|
scenarios := map[string]struct {
|
||||||
isExpectedFailure bool
|
isExpectedFailure bool
|
||||||
volume *core.PersistentVolume
|
volume *core.PersistentVolume
|
||||||
|
disableBlockVolume bool
|
||||||
}{
|
}{
|
||||||
"good-volume": {
|
"good-volume": {
|
||||||
isExpectedFailure: false,
|
isExpectedFailure: false,
|
||||||
|
@ -147,6 +149,22 @@ func TestValidatePersistentVolumes(t *testing.T) {
|
||||||
PersistentVolumeReclaimPolicy: core.PersistentVolumeReclaimRetain,
|
PersistentVolumeReclaimPolicy: core.PersistentVolumeReclaimRetain,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
"good-volume-with-volume-mode": {
|
||||||
|
isExpectedFailure: false,
|
||||||
|
volume: testVolume("foo", "", core.PersistentVolumeSpec{
|
||||||
|
Capacity: core.ResourceList{
|
||||||
|
core.ResourceName(core.ResourceStorage): resource.MustParse("10G"),
|
||||||
|
},
|
||||||
|
AccessModes: []core.PersistentVolumeAccessMode{core.ReadWriteOnce},
|
||||||
|
PersistentVolumeSource: core.PersistentVolumeSource{
|
||||||
|
HostPath: &core.HostPathVolumeSource{
|
||||||
|
Path: "/foo",
|
||||||
|
Type: newHostPathType(string(core.HostPathDirectory)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
VolumeMode: &validMode,
|
||||||
|
}),
|
||||||
|
},
|
||||||
"invalid-accessmode": {
|
"invalid-accessmode": {
|
||||||
isExpectedFailure: true,
|
isExpectedFailure: true,
|
||||||
volume: testVolume("foo", "", core.PersistentVolumeSpec{
|
volume: testVolume("foo", "", core.PersistentVolumeSpec{
|
||||||
|
@ -178,6 +196,22 @@ func TestValidatePersistentVolumes(t *testing.T) {
|
||||||
PersistentVolumeReclaimPolicy: "fakeReclaimPolicy",
|
PersistentVolumeReclaimPolicy: "fakeReclaimPolicy",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
"invalid-volume-mode": {
|
||||||
|
isExpectedFailure: true,
|
||||||
|
volume: testVolume("foo", "", core.PersistentVolumeSpec{
|
||||||
|
Capacity: core.ResourceList{
|
||||||
|
core.ResourceName(core.ResourceStorage): resource.MustParse("10G"),
|
||||||
|
},
|
||||||
|
AccessModes: []core.PersistentVolumeAccessMode{core.ReadWriteOnce},
|
||||||
|
PersistentVolumeSource: core.PersistentVolumeSource{
|
||||||
|
HostPath: &core.HostPathVolumeSource{
|
||||||
|
Path: "/foo",
|
||||||
|
Type: newHostPathType(string(core.HostPathDirectory)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
VolumeMode: &invalidMode,
|
||||||
|
}),
|
||||||
|
},
|
||||||
"unexpected-namespace": {
|
"unexpected-namespace": {
|
||||||
isExpectedFailure: true,
|
isExpectedFailure: true,
|
||||||
volume: testVolume("foo", "unexpected-namespace", core.PersistentVolumeSpec{
|
volume: testVolume("foo", "unexpected-namespace", core.PersistentVolumeSpec{
|
||||||
|
@ -336,9 +370,8 @@ func TestValidatePersistentVolumes(t *testing.T) {
|
||||||
StorageClassName: "-invalid-",
|
StorageClassName: "-invalid-",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
// VolumeMode alpha feature disabled
|
"feature disabled valid volume mode": {
|
||||||
// TODO: remove when no longer alpha
|
disableBlockVolume: true,
|
||||||
"alpha disabled valid volume mode": {
|
|
||||||
isExpectedFailure: true,
|
isExpectedFailure: true,
|
||||||
volume: testVolume("foo", "", core.PersistentVolumeSpec{
|
volume: testVolume("foo", "", core.PersistentVolumeSpec{
|
||||||
Capacity: core.ResourceList{
|
Capacity: core.ResourceList{
|
||||||
|
@ -400,6 +433,10 @@ func TestValidatePersistentVolumes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, scenario := range scenarios {
|
for name, scenario := range scenarios {
|
||||||
|
var restore func()
|
||||||
|
if scenario.disableBlockVolume {
|
||||||
|
restore = utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, false)
|
||||||
|
}
|
||||||
errs := ValidatePersistentVolume(scenario.volume)
|
errs := ValidatePersistentVolume(scenario.volume)
|
||||||
if len(errs) == 0 && scenario.isExpectedFailure {
|
if len(errs) == 0 && scenario.isExpectedFailure {
|
||||||
t.Errorf("Unexpected success for scenario: %s", name)
|
t.Errorf("Unexpected success for scenario: %s", name)
|
||||||
|
@ -407,6 +444,9 @@ func TestValidatePersistentVolumes(t *testing.T) {
|
||||||
if len(errs) > 0 && !scenario.isExpectedFailure {
|
if len(errs) > 0 && !scenario.isExpectedFailure {
|
||||||
t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs)
|
t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs)
|
||||||
}
|
}
|
||||||
|
if scenario.disableBlockVolume {
|
||||||
|
restore()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -791,10 +831,12 @@ func testVolumeClaimStorageClassInAnnotationAndSpec(name, namespace, scNameInAnn
|
||||||
func TestValidatePersistentVolumeClaim(t *testing.T) {
|
func TestValidatePersistentVolumeClaim(t *testing.T) {
|
||||||
invalidClassName := "-invalid-"
|
invalidClassName := "-invalid-"
|
||||||
validClassName := "valid"
|
validClassName := "valid"
|
||||||
|
invalidMode := core.PersistentVolumeMode("fakeVolumeMode")
|
||||||
validMode := core.PersistentVolumeFilesystem
|
validMode := core.PersistentVolumeFilesystem
|
||||||
scenarios := map[string]struct {
|
scenarios := map[string]struct {
|
||||||
isExpectedFailure bool
|
isExpectedFailure bool
|
||||||
claim *core.PersistentVolumeClaim
|
claim *core.PersistentVolumeClaim
|
||||||
|
disableBlockVolume bool
|
||||||
}{
|
}{
|
||||||
"good-claim": {
|
"good-claim": {
|
||||||
isExpectedFailure: false,
|
isExpectedFailure: false,
|
||||||
|
@ -817,6 +859,7 @@ func TestValidatePersistentVolumeClaim(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
StorageClassName: &validClassName,
|
StorageClassName: &validClassName,
|
||||||
|
VolumeMode: &validMode,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
"invalid-claim-zero-capacity": {
|
"invalid-claim-zero-capacity": {
|
||||||
|
@ -988,9 +1031,8 @@ func TestValidatePersistentVolumeClaim(t *testing.T) {
|
||||||
StorageClassName: &invalidClassName,
|
StorageClassName: &invalidClassName,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
// VolumeMode alpha feature disabled
|
"feature disabled valid volume mode": {
|
||||||
// TODO: remove when no longer alpha
|
disableBlockVolume: true,
|
||||||
"disabled alpha valid volume mode": {
|
|
||||||
isExpectedFailure: true,
|
isExpectedFailure: true,
|
||||||
claim: testVolumeClaim("foo", "ns", core.PersistentVolumeClaimSpec{
|
claim: testVolumeClaim("foo", "ns", core.PersistentVolumeClaimSpec{
|
||||||
Selector: &metav1.LabelSelector{
|
Selector: &metav1.LabelSelector{
|
||||||
|
@ -1014,9 +1056,28 @@ func TestValidatePersistentVolumeClaim(t *testing.T) {
|
||||||
VolumeMode: &validMode,
|
VolumeMode: &validMode,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
"invalid-volume-mode": {
|
||||||
|
isExpectedFailure: true,
|
||||||
|
claim: testVolumeClaim("foo", "ns", core.PersistentVolumeClaimSpec{
|
||||||
|
AccessModes: []core.PersistentVolumeAccessMode{
|
||||||
|
core.ReadWriteOnce,
|
||||||
|
core.ReadOnlyMany,
|
||||||
|
},
|
||||||
|
Resources: core.ResourceRequirements{
|
||||||
|
Requests: core.ResourceList{
|
||||||
|
core.ResourceName(core.ResourceStorage): resource.MustParse("10G"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
VolumeMode: &invalidMode,
|
||||||
|
}),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, scenario := range scenarios {
|
for name, scenario := range scenarios {
|
||||||
|
var restore func()
|
||||||
|
if scenario.disableBlockVolume {
|
||||||
|
restore = utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, false)
|
||||||
|
}
|
||||||
errs := ValidatePersistentVolumeClaim(scenario.claim)
|
errs := ValidatePersistentVolumeClaim(scenario.claim)
|
||||||
if len(errs) == 0 && scenario.isExpectedFailure {
|
if len(errs) == 0 && scenario.isExpectedFailure {
|
||||||
t.Errorf("Unexpected success for scenario: %s", name)
|
t.Errorf("Unexpected success for scenario: %s", name)
|
||||||
|
@ -1024,6 +1085,9 @@ func TestValidatePersistentVolumeClaim(t *testing.T) {
|
||||||
if len(errs) > 0 && !scenario.isExpectedFailure {
|
if len(errs) > 0 && !scenario.isExpectedFailure {
|
||||||
t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs)
|
t.Errorf("Unexpected failure for scenario: %s - %+v", name, errs)
|
||||||
}
|
}
|
||||||
|
if scenario.disableBlockVolume {
|
||||||
|
restore()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ import (
|
||||||
storage "k8s.io/api/storage/v1"
|
storage "k8s.io/api/storage/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
|
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test single call to syncClaim and syncVolume methods.
|
// Test single call to syncClaim and syncVolume methods.
|
||||||
|
@ -35,8 +37,6 @@ func TestSync(t *testing.T) {
|
||||||
"foo": "true",
|
"foo": "true",
|
||||||
"bar": "false",
|
"bar": "false",
|
||||||
}
|
}
|
||||||
modeBlock := v1.PersistentVolumeBlock
|
|
||||||
modeFile := v1.PersistentVolumeFilesystem
|
|
||||||
|
|
||||||
tests := []controllerTest{
|
tests := []controllerTest{
|
||||||
// [Unit test set 1] User did not care which PV they get.
|
// [Unit test set 1] User did not care which PV they get.
|
||||||
|
@ -589,9 +589,22 @@ func TestSync(t *testing.T) {
|
||||||
newClaimArray("claim13-5", "uid13-5", "1Gi", "volume13-5", v1.ClaimBound, nil, annBoundByController, annBindCompleted),
|
newClaimArray("claim13-5", "uid13-5", "1Gi", "volume13-5", v1.ClaimBound, nil, annBoundByController, annBindCompleted),
|
||||||
noevents, noerrors, testSyncClaim,
|
noevents, noerrors, testSyncClaim,
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
runSyncTests(t, tests, []*storage.StorageClass{
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: classWait},
|
||||||
|
VolumeBindingMode: &modeWait,
|
||||||
|
},
|
||||||
|
}, []*v1.Pod{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSyncBlockVolumeDisabled(t *testing.T) {
|
||||||
|
modeBlock := v1.PersistentVolumeBlock
|
||||||
|
modeFile := v1.PersistentVolumeFilesystem
|
||||||
// All of these should bind as feature set is not enabled for BlockVolume
|
// All of these should bind as feature set is not enabled for BlockVolume
|
||||||
// meaning volumeMode will be ignored and dropped
|
// meaning volumeMode will be ignored and dropped
|
||||||
|
tests := []controllerTest{
|
||||||
{
|
{
|
||||||
// syncVolume binds a requested block claim to a block volume
|
// syncVolume binds a requested block claim to a block volume
|
||||||
"14-1 - binding to volumeMode block",
|
"14-1 - binding to volumeMode block",
|
||||||
|
@ -639,6 +652,7 @@ func TestSync(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, false)()
|
||||||
runSyncTests(t, tests, []*storage.StorageClass{
|
runSyncTests(t, tests, []*storage.StorageClass{
|
||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: classWait},
|
ObjectMeta: metav1.ObjectMeta{Name: classWait},
|
||||||
|
@ -647,7 +661,7 @@ func TestSync(t *testing.T) {
|
||||||
}, []*v1.Pod{})
|
}, []*v1.Pod{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSyncAlphaBlockVolume(t *testing.T) {
|
func TestSyncBlockVolume(t *testing.T) {
|
||||||
modeBlock := v1.PersistentVolumeBlock
|
modeBlock := v1.PersistentVolumeBlock
|
||||||
modeFile := v1.PersistentVolumeFilesystem
|
modeFile := v1.PersistentVolumeFilesystem
|
||||||
|
|
||||||
|
@ -827,12 +841,7 @@ func TestSyncAlphaBlockVolume(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := utilfeature.DefaultFeatureGate.Set("BlockVolume=true")
|
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, true)()
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Failed to enable feature gate for BlockVolume: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer utilfeature.DefaultFeatureGate.Set("BlockVolume=false")
|
|
||||||
|
|
||||||
runSyncTests(t, tests, []*storage.StorageClass{}, []*v1.Pod{})
|
runSyncTests(t, tests, []*storage.StorageClass{}, []*v1.Pod{})
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/util/diff"
|
"k8s.io/apimachinery/pkg/util/diff"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
@ -48,6 +49,7 @@ import (
|
||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
"k8s.io/kubernetes/pkg/api/testapi"
|
"k8s.io/kubernetes/pkg/api/testapi"
|
||||||
"k8s.io/kubernetes/pkg/controller"
|
"k8s.io/kubernetes/pkg/controller"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
vol "k8s.io/kubernetes/pkg/volume"
|
vol "k8s.io/kubernetes/pkg/volume"
|
||||||
"k8s.io/kubernetes/pkg/volume/util/recyclerclient"
|
"k8s.io/kubernetes/pkg/volume/util/recyclerclient"
|
||||||
)
|
)
|
||||||
|
@ -179,6 +181,12 @@ func (r *volumeReactor) React(action core.Action) (handled bool, ret runtime.Obj
|
||||||
return true, nil, fmt.Errorf("Cannot create volume %s: volume already exists", volume.Name)
|
return true, nil, fmt.Errorf("Cannot create volume %s: volume already exists", volume.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mimic apiserver defaulting
|
||||||
|
if volume.Spec.VolumeMode == nil && utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
|
||||||
|
volume.Spec.VolumeMode = new(v1.PersistentVolumeMode)
|
||||||
|
*volume.Spec.VolumeMode = v1.PersistentVolumeFilesystem
|
||||||
|
}
|
||||||
|
|
||||||
// Store the updated object to appropriate places.
|
// Store the updated object to appropriate places.
|
||||||
r.volumes[volume.Name] = volume
|
r.volumes[volume.Name] = volume
|
||||||
r.changedObjects = append(r.changedObjects, volume)
|
r.changedObjects = append(r.changedObjects, volume)
|
||||||
|
@ -630,6 +638,7 @@ func newTestController(kubeClient clientset.Interface, informerFactory informers
|
||||||
|
|
||||||
// newVolume returns a new volume with given attributes
|
// newVolume returns a new volume with given attributes
|
||||||
func newVolume(name, capacity, boundToClaimUID, boundToClaimName string, phase v1.PersistentVolumePhase, reclaimPolicy v1.PersistentVolumeReclaimPolicy, class string, annotations ...string) *v1.PersistentVolume {
|
func newVolume(name, capacity, boundToClaimUID, boundToClaimName string, phase v1.PersistentVolumePhase, reclaimPolicy v1.PersistentVolumeReclaimPolicy, class string, annotations ...string) *v1.PersistentVolume {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
volume := v1.PersistentVolume{
|
volume := v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -645,6 +654,7 @@ func newVolume(name, capacity, boundToClaimUID, boundToClaimName string, phase v
|
||||||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce, v1.ReadOnlyMany},
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce, v1.ReadOnlyMany},
|
||||||
PersistentVolumeReclaimPolicy: reclaimPolicy,
|
PersistentVolumeReclaimPolicy: reclaimPolicy,
|
||||||
StorageClassName: class,
|
StorageClassName: class,
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: phase,
|
Phase: phase,
|
||||||
|
@ -740,6 +750,7 @@ func newVolumeArray(name, capacity, boundToClaimUID, boundToClaimName string, ph
|
||||||
|
|
||||||
// newClaim returns a new claim with given attributes
|
// newClaim returns a new claim with given attributes
|
||||||
func newClaim(name, claimUID, capacity, boundToVolume string, phase v1.PersistentVolumeClaimPhase, class *string, annotations ...string) *v1.PersistentVolumeClaim {
|
func newClaim(name, claimUID, capacity, boundToVolume string, phase v1.PersistentVolumeClaimPhase, class *string, annotations ...string) *v1.PersistentVolumeClaim {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
claim := v1.PersistentVolumeClaim{
|
claim := v1.PersistentVolumeClaim{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -756,6 +767,7 @@ func newClaim(name, claimUID, capacity, boundToVolume string, phase v1.Persisten
|
||||||
},
|
},
|
||||||
VolumeName: boundToVolume,
|
VolumeName: boundToVolume,
|
||||||
StorageClassName: class,
|
StorageClassName: class,
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeClaimStatus{
|
Status: v1.PersistentVolumeClaimStatus{
|
||||||
Phase: phase,
|
Phase: phase,
|
||||||
|
@ -1226,6 +1238,7 @@ func (plugin *mockVolumePlugin) Provision(selectedNode *v1.Node, allowedTopologi
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
pv.Spec.VolumeMode = plugin.provisionOptions.PVC.Spec.VolumeMode
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin.provisionCallCounter++
|
plugin.provisionCallCounter++
|
||||||
|
|
|
@ -158,13 +158,13 @@ func findMatchingVolume(
|
||||||
|
|
||||||
volumeQty := volume.Spec.Capacity[v1.ResourceStorage]
|
volumeQty := volume.Spec.Capacity[v1.ResourceStorage]
|
||||||
|
|
||||||
// check if volumeModes do not match (Alpha and feature gate protected)
|
// check if volumeModes do not match (feature gate protected)
|
||||||
isMisMatch, err := checkVolumeModeMisMatches(&claim.Spec, &volume.Spec)
|
isMismatch, err := checkVolumeModeMismatches(&claim.Spec, &volume.Spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error checking if volumeMode was a mismatch: %v", err)
|
return nil, fmt.Errorf("error checking if volumeMode was a mismatch: %v", err)
|
||||||
}
|
}
|
||||||
// filter out mismatching volumeModes
|
// filter out mismatching volumeModes
|
||||||
if isMisMatch {
|
if isMismatch {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,18 +258,16 @@ func findMatchingVolume(
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkVolumeModeMatches is a convenience method that checks volumeMode for PersistentVolume
|
// checkVolumeModeMismatches is a convenience method that checks volumeMode for PersistentVolume
|
||||||
// and PersistentVolumeClaims along with making sure that the Alpha feature gate BlockVolume is
|
// and PersistentVolumeClaims along with making sure that the feature gate BlockVolume is enabled.
|
||||||
// enabled.
|
func checkVolumeModeMismatches(pvcSpec *v1.PersistentVolumeClaimSpec, pvSpec *v1.PersistentVolumeSpec) (bool, error) {
|
||||||
// This is Alpha and could change in the future.
|
|
||||||
func checkVolumeModeMisMatches(pvcSpec *v1.PersistentVolumeClaimSpec, pvSpec *v1.PersistentVolumeSpec) (bool, error) {
|
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
|
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
|
||||||
if pvSpec.VolumeMode != nil && pvcSpec.VolumeMode != nil {
|
if pvSpec.VolumeMode != nil && pvcSpec.VolumeMode != nil {
|
||||||
requestedVolumeMode := *pvcSpec.VolumeMode
|
requestedVolumeMode := *pvcSpec.VolumeMode
|
||||||
pvVolumeMode := *pvSpec.VolumeMode
|
pvVolumeMode := *pvSpec.VolumeMode
|
||||||
return requestedVolumeMode != pvVolumeMode, nil
|
return requestedVolumeMode != pvVolumeMode, nil
|
||||||
} else {
|
} else {
|
||||||
// This also should retrun an error, this means that
|
// This also should return an error, this means that
|
||||||
// the defaulting has failed.
|
// the defaulting has failed.
|
||||||
return true, fmt.Errorf("api defaulting for volumeMode failed")
|
return true, fmt.Errorf("api defaulting for volumeMode failed")
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func makePVC(size string, modfn func(*v1.PersistentVolumeClaim)) *v1.PersistentVolumeClaim {
|
func makePVC(size string, modfn func(*v1.PersistentVolumeClaim)) *v1.PersistentVolumeClaim {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
pvc := v1.PersistentVolumeClaim{
|
pvc := v1.PersistentVolumeClaim{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "claim01",
|
Name: "claim01",
|
||||||
|
@ -45,6 +46,7 @@ func makePVC(size string, modfn func(*v1.PersistentVolumeClaim)) *v1.PersistentV
|
||||||
v1.ResourceName(v1.ResourceStorage): resource.MustParse(size),
|
v1.ResourceName(v1.ResourceStorage): resource.MustParse(size),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if modfn != nil {
|
if modfn != nil {
|
||||||
|
@ -197,6 +199,7 @@ func TestMatchVolume(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMatchingWithBoundVolumes(t *testing.T) {
|
func TestMatchingWithBoundVolumes(t *testing.T) {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
volumeIndex := newPersistentVolumeOrderedIndex()
|
volumeIndex := newPersistentVolumeOrderedIndex()
|
||||||
// two similar volumes, one is bound
|
// two similar volumes, one is bound
|
||||||
pv1 := &v1.PersistentVolume{
|
pv1 := &v1.PersistentVolume{
|
||||||
|
@ -214,6 +217,7 @@ func TestMatchingWithBoundVolumes(t *testing.T) {
|
||||||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce, v1.ReadOnlyMany},
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce, v1.ReadOnlyMany},
|
||||||
// this one we're pretending is already bound
|
// this one we're pretending is already bound
|
||||||
ClaimRef: &v1.ObjectReference{UID: "abc123"},
|
ClaimRef: &v1.ObjectReference{UID: "abc123"},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeBound,
|
Phase: v1.VolumeBound,
|
||||||
|
@ -233,6 +237,7 @@ func TestMatchingWithBoundVolumes(t *testing.T) {
|
||||||
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{},
|
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{},
|
||||||
},
|
},
|
||||||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce, v1.ReadOnlyMany},
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce, v1.ReadOnlyMany},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -254,6 +259,7 @@ func TestMatchingWithBoundVolumes(t *testing.T) {
|
||||||
v1.ResourceName(v1.ResourceStorage): resource.MustParse("1G"),
|
v1.ResourceName(v1.ResourceStorage): resource.MustParse("1G"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,6 +334,7 @@ func TestAllPossibleAccessModes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFindingVolumeWithDifferentAccessModes(t *testing.T) {
|
func TestFindingVolumeWithDifferentAccessModes(t *testing.T) {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
gce := &v1.PersistentVolume{
|
gce := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{UID: "001", Name: "gce"},
|
ObjectMeta: metav1.ObjectMeta{UID: "001", Name: "gce"},
|
||||||
Spec: v1.PersistentVolumeSpec{
|
Spec: v1.PersistentVolumeSpec{
|
||||||
|
@ -337,6 +344,7 @@ func TestFindingVolumeWithDifferentAccessModes(t *testing.T) {
|
||||||
v1.ReadWriteOnce,
|
v1.ReadWriteOnce,
|
||||||
v1.ReadOnlyMany,
|
v1.ReadOnlyMany,
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -351,6 +359,7 @@ func TestFindingVolumeWithDifferentAccessModes(t *testing.T) {
|
||||||
AccessModes: []v1.PersistentVolumeAccessMode{
|
AccessModes: []v1.PersistentVolumeAccessMode{
|
||||||
v1.ReadWriteOnce,
|
v1.ReadWriteOnce,
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -367,6 +376,7 @@ func TestFindingVolumeWithDifferentAccessModes(t *testing.T) {
|
||||||
v1.ReadOnlyMany,
|
v1.ReadOnlyMany,
|
||||||
v1.ReadWriteMany,
|
v1.ReadWriteMany,
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -381,6 +391,7 @@ func TestFindingVolumeWithDifferentAccessModes(t *testing.T) {
|
||||||
Spec: v1.PersistentVolumeClaimSpec{
|
Spec: v1.PersistentVolumeClaimSpec{
|
||||||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||||
Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceName(v1.ResourceStorage): resource.MustParse("1G")}},
|
Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceName(v1.ResourceStorage): resource.MustParse("1G")}},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,6 +451,7 @@ func TestFindingVolumeWithDifferentAccessModes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestVolumes() []*v1.PersistentVolume {
|
func createTestVolumes() []*v1.PersistentVolume {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
// these volumes are deliberately out-of-order to test indexing and sorting
|
// these volumes are deliberately out-of-order to test indexing and sorting
|
||||||
return []*v1.PersistentVolume{
|
return []*v1.PersistentVolume{
|
||||||
{
|
{
|
||||||
|
@ -458,6 +470,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
v1.ReadWriteOnce,
|
v1.ReadWriteOnce,
|
||||||
v1.ReadOnlyMany,
|
v1.ReadOnlyMany,
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -481,6 +494,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
},
|
},
|
||||||
// this one we're pretending is already bound
|
// this one we're pretending is already bound
|
||||||
ClaimRef: &v1.ObjectReference{UID: "def456"},
|
ClaimRef: &v1.ObjectReference{UID: "def456"},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeBound,
|
Phase: v1.VolumeBound,
|
||||||
|
@ -503,6 +517,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
v1.ReadOnlyMany,
|
v1.ReadOnlyMany,
|
||||||
v1.ReadWriteMany,
|
v1.ReadWriteMany,
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -526,6 +541,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
},
|
},
|
||||||
// this one we're pretending is already bound
|
// this one we're pretending is already bound
|
||||||
ClaimRef: &v1.ObjectReference{UID: "abc123"},
|
ClaimRef: &v1.ObjectReference{UID: "abc123"},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeBound,
|
Phase: v1.VolumeBound,
|
||||||
|
@ -548,6 +564,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
v1.ReadOnlyMany,
|
v1.ReadOnlyMany,
|
||||||
v1.ReadWriteMany,
|
v1.ReadWriteMany,
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -569,6 +586,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
v1.ReadWriteOnce,
|
v1.ReadWriteOnce,
|
||||||
v1.ReadOnlyMany,
|
v1.ReadOnlyMany,
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -591,6 +609,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
v1.ReadOnlyMany,
|
v1.ReadOnlyMany,
|
||||||
v1.ReadWriteMany,
|
v1.ReadWriteMany,
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -614,6 +633,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
AccessModes: []v1.PersistentVolumeAccessMode{
|
AccessModes: []v1.PersistentVolumeAccessMode{
|
||||||
v1.ReadWriteOnce,
|
v1.ReadWriteOnce,
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -638,6 +658,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
v1.ReadWriteOnce,
|
v1.ReadWriteOnce,
|
||||||
},
|
},
|
||||||
StorageClassName: classSilver,
|
StorageClassName: classSilver,
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -659,6 +680,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
v1.ReadWriteOnce,
|
v1.ReadWriteOnce,
|
||||||
},
|
},
|
||||||
StorageClassName: classSilver,
|
StorageClassName: classSilver,
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -680,6 +702,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
v1.ReadWriteOnce,
|
v1.ReadWriteOnce,
|
||||||
},
|
},
|
||||||
StorageClassName: classGold,
|
StorageClassName: classGold,
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -703,6 +726,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
v1.ReadWriteMany,
|
v1.ReadWriteMany,
|
||||||
},
|
},
|
||||||
StorageClassName: classLarge,
|
StorageClassName: classLarge,
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -726,6 +750,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
v1.ReadWriteMany,
|
v1.ReadWriteMany,
|
||||||
},
|
},
|
||||||
StorageClassName: classLarge,
|
StorageClassName: classLarge,
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -749,6 +774,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
},
|
},
|
||||||
StorageClassName: classWait,
|
StorageClassName: classWait,
|
||||||
NodeAffinity: getVolumeNodeAffinity("key1", "value1"),
|
NodeAffinity: getVolumeNodeAffinity("key1", "value1"),
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -772,6 +798,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
},
|
},
|
||||||
StorageClassName: classWait,
|
StorageClassName: classWait,
|
||||||
NodeAffinity: getVolumeNodeAffinity("key1", "value1"),
|
NodeAffinity: getVolumeNodeAffinity("key1", "value1"),
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -796,6 +823,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
StorageClassName: classWait,
|
StorageClassName: classWait,
|
||||||
ClaimRef: &v1.ObjectReference{Name: "claim02", Namespace: "myns"},
|
ClaimRef: &v1.ObjectReference{Name: "claim02", Namespace: "myns"},
|
||||||
NodeAffinity: getVolumeNodeAffinity("key1", "value1"),
|
NodeAffinity: getVolumeNodeAffinity("key1", "value1"),
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -819,6 +847,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
},
|
},
|
||||||
StorageClassName: classWait,
|
StorageClassName: classWait,
|
||||||
NodeAffinity: getVolumeNodeAffinity("key1", "value3"),
|
NodeAffinity: getVolumeNodeAffinity("key1", "value3"),
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -842,6 +871,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
},
|
},
|
||||||
StorageClassName: classWait,
|
StorageClassName: classWait,
|
||||||
NodeAffinity: getVolumeNodeAffinity("key1", "value4"),
|
NodeAffinity: getVolumeNodeAffinity("key1", "value4"),
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumePending,
|
Phase: v1.VolumePending,
|
||||||
|
@ -865,6 +895,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
},
|
},
|
||||||
StorageClassName: classWait,
|
StorageClassName: classWait,
|
||||||
NodeAffinity: getVolumeNodeAffinity("key1", "value4"),
|
NodeAffinity: getVolumeNodeAffinity("key1", "value4"),
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeFailed,
|
Phase: v1.VolumeFailed,
|
||||||
|
@ -888,6 +919,7 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
},
|
},
|
||||||
StorageClassName: classWait,
|
StorageClassName: classWait,
|
||||||
NodeAffinity: getVolumeNodeAffinity("key1", "value4"),
|
NodeAffinity: getVolumeNodeAffinity("key1", "value4"),
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeReleased,
|
Phase: v1.VolumeReleased,
|
||||||
|
@ -911,12 +943,14 @@ func createTestVolumes() []*v1.PersistentVolume {
|
||||||
},
|
},
|
||||||
StorageClassName: classWait,
|
StorageClassName: classWait,
|
||||||
NodeAffinity: getVolumeNodeAffinity("key1", "value4"),
|
NodeAffinity: getVolumeNodeAffinity("key1", "value4"),
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testVolume(name, size string) *v1.PersistentVolume {
|
func testVolume(name, size string) *v1.PersistentVolume {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
return &v1.PersistentVolume{
|
return &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -926,6 +960,7 @@ func testVolume(name, size string) *v1.PersistentVolume {
|
||||||
Capacity: v1.ResourceList{v1.ResourceName(v1.ResourceStorage): resource.MustParse(size)},
|
Capacity: v1.ResourceList{v1.ResourceName(v1.ResourceStorage): resource.MustParse(size)},
|
||||||
PersistentVolumeSource: v1.PersistentVolumeSource{HostPath: &v1.HostPathVolumeSource{}},
|
PersistentVolumeSource: v1.PersistentVolumeSource{HostPath: &v1.HostPathVolumeSource{}},
|
||||||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -1009,28 +1044,7 @@ func createTestVolOrderedIndex(pv *v1.PersistentVolume) persistentVolumeOrderedI
|
||||||
return volFile
|
return volFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleFeature(toggleFlag bool, featureName string, t *testing.T) {
|
func TestVolumeModeCheck(t *testing.T) {
|
||||||
var valueStr string
|
|
||||||
if toggleFlag {
|
|
||||||
// Enable feature
|
|
||||||
valueStr = featureName + "=true"
|
|
||||||
err := utilfeature.DefaultFeatureGate.Set(valueStr)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Failed to enable feature gate for %s: %v", featureName, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Disable feature
|
|
||||||
valueStr = featureName + "=false"
|
|
||||||
err := utilfeature.DefaultFeatureGate.Set(valueStr)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Failed to disable feature gate for %s: %v", featureName, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAlphaVolumeModeCheck(t *testing.T) {
|
|
||||||
|
|
||||||
blockMode := v1.PersistentVolumeBlock
|
blockMode := v1.PersistentVolumeBlock
|
||||||
filesystemMode := v1.PersistentVolumeFilesystem
|
filesystemMode := v1.PersistentVolumeFilesystem
|
||||||
|
@ -1038,55 +1052,55 @@ func TestAlphaVolumeModeCheck(t *testing.T) {
|
||||||
// If feature gate is enabled, VolumeMode will always be defaulted
|
// If feature gate is enabled, VolumeMode will always be defaulted
|
||||||
// If feature gate is disabled, VolumeMode is dropped by API and ignored
|
// If feature gate is disabled, VolumeMode is dropped by API and ignored
|
||||||
scenarios := map[string]struct {
|
scenarios := map[string]struct {
|
||||||
isExpectedMisMatch bool
|
isExpectedMismatch bool
|
||||||
vol *v1.PersistentVolume
|
vol *v1.PersistentVolume
|
||||||
pvc *v1.PersistentVolumeClaim
|
pvc *v1.PersistentVolumeClaim
|
||||||
enableBlock bool
|
enableBlock bool
|
||||||
}{
|
}{
|
||||||
"feature enabled - pvc block and pv filesystem": {
|
"feature enabled - pvc block and pv filesystem": {
|
||||||
isExpectedMisMatch: true,
|
isExpectedMismatch: true,
|
||||||
vol: createVolumeModeFilesystemTestVolume(),
|
vol: createVolumeModeFilesystemTestVolume(),
|
||||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||||
enableBlock: true,
|
enableBlock: true,
|
||||||
},
|
},
|
||||||
"feature enabled - pvc filesystem and pv block": {
|
"feature enabled - pvc filesystem and pv block": {
|
||||||
isExpectedMisMatch: true,
|
isExpectedMismatch: true,
|
||||||
vol: createVolumeModeBlockTestVolume(),
|
vol: createVolumeModeBlockTestVolume(),
|
||||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||||
enableBlock: true,
|
enableBlock: true,
|
||||||
},
|
},
|
||||||
"feature enabled - pvc block and pv block": {
|
"feature enabled - pvc block and pv block": {
|
||||||
isExpectedMisMatch: false,
|
isExpectedMismatch: false,
|
||||||
vol: createVolumeModeBlockTestVolume(),
|
vol: createVolumeModeBlockTestVolume(),
|
||||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||||
enableBlock: true,
|
enableBlock: true,
|
||||||
},
|
},
|
||||||
"feature enabled - pvc filesystem and pv filesystem": {
|
"feature enabled - pvc filesystem and pv filesystem": {
|
||||||
isExpectedMisMatch: false,
|
isExpectedMismatch: false,
|
||||||
vol: createVolumeModeFilesystemTestVolume(),
|
vol: createVolumeModeFilesystemTestVolume(),
|
||||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||||
enableBlock: true,
|
enableBlock: true,
|
||||||
},
|
},
|
||||||
"feature disabled - pvc block and pv filesystem": {
|
"feature disabled - pvc block and pv filesystem": {
|
||||||
isExpectedMisMatch: false,
|
isExpectedMismatch: false,
|
||||||
vol: createVolumeModeFilesystemTestVolume(),
|
vol: createVolumeModeFilesystemTestVolume(),
|
||||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||||
enableBlock: false,
|
enableBlock: false,
|
||||||
},
|
},
|
||||||
"feature disabled - pvc filesystem and pv block": {
|
"feature disabled - pvc filesystem and pv block": {
|
||||||
isExpectedMisMatch: false,
|
isExpectedMismatch: false,
|
||||||
vol: createVolumeModeBlockTestVolume(),
|
vol: createVolumeModeBlockTestVolume(),
|
||||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||||
enableBlock: false,
|
enableBlock: false,
|
||||||
},
|
},
|
||||||
"feature disabled - pvc block and pv block": {
|
"feature disabled - pvc block and pv block": {
|
||||||
isExpectedMisMatch: false,
|
isExpectedMismatch: false,
|
||||||
vol: createVolumeModeBlockTestVolume(),
|
vol: createVolumeModeBlockTestVolume(),
|
||||||
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
pvc: makeVolumeModePVC("8G", &blockMode, nil),
|
||||||
enableBlock: false,
|
enableBlock: false,
|
||||||
},
|
},
|
||||||
"feature disabled - pvc filesystem and pv filesystem": {
|
"feature disabled - pvc filesystem and pv filesystem": {
|
||||||
isExpectedMisMatch: false,
|
isExpectedMismatch: false,
|
||||||
vol: createVolumeModeFilesystemTestVolume(),
|
vol: createVolumeModeFilesystemTestVolume(),
|
||||||
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
pvc: makeVolumeModePVC("8G", &filesystemMode, nil),
|
||||||
enableBlock: false,
|
enableBlock: false,
|
||||||
|
@ -1094,25 +1108,23 @@ func TestAlphaVolumeModeCheck(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, scenario := range scenarios {
|
for name, scenario := range scenarios {
|
||||||
toggleFeature(scenario.enableBlock, "BlockVolume", t)
|
recover := utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, scenario.enableBlock)
|
||||||
expectedMisMatch, err := checkVolumeModeMisMatches(&scenario.pvc.Spec, &scenario.vol.Spec)
|
expectedMismatch, err := checkVolumeModeMismatches(&scenario.pvc.Spec, &scenario.vol.Spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected failure for checkVolumeModeMisMatches: %v", err)
|
t.Errorf("Unexpected failure for checkVolumeModeMismatches: %v", err)
|
||||||
}
|
}
|
||||||
// expected to match but either got an error or no returned pvmatch
|
// expected to match but either got an error or no returned pvmatch
|
||||||
if expectedMisMatch && !scenario.isExpectedMisMatch {
|
if expectedMismatch && !scenario.isExpectedMismatch {
|
||||||
t.Errorf("Unexpected failure for scenario, expected not to mismatch on modes but did: %s", name)
|
t.Errorf("Unexpected failure for scenario, expected not to mismatch on modes but did: %s", name)
|
||||||
}
|
}
|
||||||
if !expectedMisMatch && scenario.isExpectedMisMatch {
|
if !expectedMismatch && scenario.isExpectedMismatch {
|
||||||
t.Errorf("Unexpected failure for scenario, did not mismatch on mode when expected to mismatch: %s", name)
|
t.Errorf("Unexpected failure for scenario, did not mismatch on mode when expected to mismatch: %s", name)
|
||||||
}
|
}
|
||||||
|
recover()
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure feature gate is turned off
|
|
||||||
toggleFeature(false, "BlockVolume", t)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAlphaFilteringVolumeModes(t *testing.T) {
|
func TestFilteringVolumeModes(t *testing.T) {
|
||||||
blockMode := v1.PersistentVolumeBlock
|
blockMode := v1.PersistentVolumeBlock
|
||||||
filesystemMode := v1.PersistentVolumeFilesystem
|
filesystemMode := v1.PersistentVolumeFilesystem
|
||||||
|
|
||||||
|
@ -1187,7 +1199,7 @@ func TestAlphaFilteringVolumeModes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, scenario := range scenarios {
|
for name, scenario := range scenarios {
|
||||||
toggleFeature(scenario.enableBlock, "BlockVolume", t)
|
recover := utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.BlockVolume, scenario.enableBlock)
|
||||||
pvmatch, err := scenario.vol.findBestMatchForClaim(scenario.pvc, false)
|
pvmatch, err := scenario.vol.findBestMatchForClaim(scenario.pvc, false)
|
||||||
// expected to match but either got an error or no returned pvmatch
|
// expected to match but either got an error or no returned pvmatch
|
||||||
if pvmatch == nil && scenario.isExpectedMatch {
|
if pvmatch == nil && scenario.isExpectedMatch {
|
||||||
|
@ -1203,13 +1215,12 @@ func TestAlphaFilteringVolumeModes(t *testing.T) {
|
||||||
if err != nil && !scenario.isExpectedMatch {
|
if err != nil && !scenario.isExpectedMatch {
|
||||||
t.Errorf("Unexpected failure for scenario: %s - %+v", name, err)
|
t.Errorf("Unexpected failure for scenario: %s - %+v", name, err)
|
||||||
}
|
}
|
||||||
|
recover()
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure feature gate is turned off
|
|
||||||
toggleFeature(false, "BlockVolume", t)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStorageObjectInUseProtectionFiltering(t *testing.T) {
|
func TestStorageObjectInUseProtectionFiltering(t *testing.T) {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
pv := &v1.PersistentVolume{
|
pv := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "pv1",
|
Name: "pv1",
|
||||||
|
@ -1219,6 +1230,7 @@ func TestStorageObjectInUseProtectionFiltering(t *testing.T) {
|
||||||
Capacity: v1.ResourceList{v1.ResourceName(v1.ResourceStorage): resource.MustParse("1G")},
|
Capacity: v1.ResourceList{v1.ResourceName(v1.ResourceStorage): resource.MustParse("1G")},
|
||||||
PersistentVolumeSource: v1.PersistentVolumeSource{HostPath: &v1.HostPathVolumeSource{}},
|
PersistentVolumeSource: v1.PersistentVolumeSource{HostPath: &v1.HostPathVolumeSource{}},
|
||||||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
@ -1237,6 +1249,7 @@ func TestStorageObjectInUseProtectionFiltering(t *testing.T) {
|
||||||
Spec: v1.PersistentVolumeClaimSpec{
|
Spec: v1.PersistentVolumeClaimSpec{
|
||||||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||||
Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceName(v1.ResourceStorage): resource.MustParse("1G")}},
|
Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceName(v1.ResourceStorage): resource.MustParse("1G")}},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1343,6 +1356,7 @@ func TestStorageObjectInUseProtectionFiltering(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFindingPreboundVolumes(t *testing.T) {
|
func TestFindingPreboundVolumes(t *testing.T) {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
claim := &v1.PersistentVolumeClaim{
|
claim := &v1.PersistentVolumeClaim{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "claim01",
|
Name: "claim01",
|
||||||
|
@ -1352,6 +1366,7 @@ func TestFindingPreboundVolumes(t *testing.T) {
|
||||||
Spec: v1.PersistentVolumeClaimSpec{
|
Spec: v1.PersistentVolumeClaimSpec{
|
||||||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
|
||||||
Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceName(v1.ResourceStorage): resource.MustParse("1Gi")}},
|
Resources: v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceName(v1.ResourceStorage): resource.MustParse("1Gi")}},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
claimRef, err := ref.GetReference(scheme.Scheme, claim)
|
claimRef, err := ref.GetReference(scheme.Scheme, claim)
|
||||||
|
|
|
@ -270,11 +270,11 @@ func checkVolumeSatisfyClaim(volume *v1.PersistentVolume, claim *v1.PersistentVo
|
||||||
return fmt.Errorf("storageClassName does not match")
|
return fmt.Errorf("storageClassName does not match")
|
||||||
}
|
}
|
||||||
|
|
||||||
isMisMatch, err := checkVolumeModeMisMatches(&claim.Spec, &volume.Spec)
|
isMismatch, err := checkVolumeModeMismatches(&claim.Spec, &volume.Spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error checking volumeMode: %v", err)
|
return fmt.Errorf("error checking volumeMode: %v", err)
|
||||||
}
|
}
|
||||||
if isMisMatch {
|
if isMismatch {
|
||||||
return fmt.Errorf("incompatible volumeMode")
|
return fmt.Errorf("incompatible volumeMode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,7 +613,7 @@ func (ctrl *PersistentVolumeController) syncVolume(volume *v1.PersistentVolume)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else if claim.Spec.VolumeName == "" {
|
} else if claim.Spec.VolumeName == "" {
|
||||||
if isMisMatch, err := checkVolumeModeMisMatches(&claim.Spec, &volume.Spec); err != nil || isMisMatch {
|
if isMismatch, err := checkVolumeModeMismatches(&claim.Spec, &volume.Spec); err != nil || isMismatch {
|
||||||
// Binding for the volume won't be called in syncUnboundClaim,
|
// Binding for the volume won't be called in syncUnboundClaim,
|
||||||
// because findBestMatchForClaim won't return the volume due to volumeMode mismatch.
|
// because findBestMatchForClaim won't return the volume due to volumeMode mismatch.
|
||||||
volumeMsg := fmt.Sprintf("Cannot bind PersistentVolume to requested PersistentVolumeClaim %q due to incompatible volumeMode.", claim.Name)
|
volumeMsg := fmt.Sprintf("Cannot bind PersistentVolume to requested PersistentVolumeClaim %q due to incompatible volumeMode.", claim.Name)
|
||||||
|
|
|
@ -426,6 +426,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeTestPVC(name, size, node string, pvcBoundState int, pvName, resourceVersion string, className *string) *v1.PersistentVolumeClaim {
|
func makeTestPVC(name, size, node string, pvcBoundState int, pvName, resourceVersion string, className *string) *v1.PersistentVolumeClaim {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
pvc := &v1.PersistentVolumeClaim{
|
pvc := &v1.PersistentVolumeClaim{
|
||||||
TypeMeta: metav1.TypeMeta{
|
TypeMeta: metav1.TypeMeta{
|
||||||
Kind: "PersistentVolumeClaim",
|
Kind: "PersistentVolumeClaim",
|
||||||
|
@ -445,6 +446,7 @@ func makeTestPVC(name, size, node string, pvcBoundState int, pvName, resourceVer
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
StorageClassName: className,
|
StorageClassName: className,
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,6 +464,7 @@ func makeTestPVC(name, size, node string, pvcBoundState int, pvName, resourceVer
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeBadPVC() *v1.PersistentVolumeClaim {
|
func makeBadPVC() *v1.PersistentVolumeClaim {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
return &v1.PersistentVolumeClaim{
|
return &v1.PersistentVolumeClaim{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "bad-pvc",
|
Name: "bad-pvc",
|
||||||
|
@ -477,11 +480,13 @@ func makeBadPVC() *v1.PersistentVolumeClaim {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
StorageClassName: &waitClass,
|
StorageClassName: &waitClass,
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeTestPV(name, node, capacity, version string, boundToPVC *v1.PersistentVolumeClaim, className string) *v1.PersistentVolume {
|
func makeTestPV(name, node, capacity, version string, boundToPVC *v1.PersistentVolumeClaim, className string) *v1.PersistentVolume {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
pv := &v1.PersistentVolume{
|
pv := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -492,6 +497,7 @@ func makeTestPV(name, node, capacity, version string, boundToPVC *v1.PersistentV
|
||||||
v1.ResourceName(v1.ResourceStorage): resource.MustParse(capacity),
|
v1.ResourceName(v1.ResourceStorage): resource.MustParse(capacity),
|
||||||
},
|
},
|
||||||
StorageClassName: className,
|
StorageClassName: className,
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeStatus{
|
Status: v1.PersistentVolumeStatus{
|
||||||
Phase: v1.VolumeAvailable,
|
Phase: v1.VolumeAvailable,
|
||||||
|
|
|
@ -46,12 +46,14 @@ import (
|
||||||
|
|
||||||
func TestFindAndAddNewPods_FindAndRemoveDeletedPods(t *testing.T) {
|
func TestFindAndAddNewPods_FindAndRemoveDeletedPods(t *testing.T) {
|
||||||
// create dswp
|
// create dswp
|
||||||
|
mode := v1.PersistentVolumeFilesystem
|
||||||
pv := &v1.PersistentVolume{
|
pv := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "dswp-test-volume-name",
|
Name: "dswp-test-volume-name",
|
||||||
},
|
},
|
||||||
Spec: v1.PersistentVolumeSpec{
|
Spec: v1.PersistentVolumeSpec{
|
||||||
ClaimRef: &v1.ObjectReference{Namespace: "ns", Name: "file-bound"},
|
ClaimRef: &v1.ObjectReference{Namespace: "ns", Name: "file-bound"},
|
||||||
|
VolumeMode: &mode,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
pvc := &v1.PersistentVolumeClaim{
|
pvc := &v1.PersistentVolumeClaim{
|
||||||
|
@ -453,6 +455,7 @@ func TestCreateVolumeSpec_Invalid_Block_VolumeMounts(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCheckVolumeFSResize(t *testing.T) {
|
func TestCheckVolumeFSResize(t *testing.T) {
|
||||||
|
mode := v1.PersistentVolumeFilesystem
|
||||||
pv := &v1.PersistentVolume{
|
pv := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "dswp-test-volume-name",
|
Name: "dswp-test-volume-name",
|
||||||
|
@ -461,6 +464,7 @@ func TestCheckVolumeFSResize(t *testing.T) {
|
||||||
PersistentVolumeSource: v1.PersistentVolumeSource{RBD: &v1.RBDPersistentVolumeSource{}},
|
PersistentVolumeSource: v1.PersistentVolumeSource{RBD: &v1.RBDPersistentVolumeSource{}},
|
||||||
Capacity: volumeCapacity(1),
|
Capacity: volumeCapacity(1),
|
||||||
ClaimRef: &v1.ObjectReference{Namespace: "ns", Name: "file-bound"},
|
ClaimRef: &v1.ObjectReference{Namespace: "ns", Name: "file-bound"},
|
||||||
|
VolumeMode: &mode,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
pvc := &v1.PersistentVolumeClaim{
|
pvc := &v1.PersistentVolumeClaim{
|
||||||
|
|
|
@ -949,6 +949,7 @@ func Test_GenerateUnmapDeviceFunc_Plugin_Not_Found(t *testing.T) {
|
||||||
func Test_Run_Positive_VolumeFSResizeControllerAttachEnabled(t *testing.T) {
|
func Test_Run_Positive_VolumeFSResizeControllerAttachEnabled(t *testing.T) {
|
||||||
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandInUsePersistentVolumes, true)()
|
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandInUsePersistentVolumes, true)()
|
||||||
|
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
pv := &v1.PersistentVolume{
|
pv := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "pv",
|
Name: "pv",
|
||||||
|
@ -956,6 +957,7 @@ func Test_Run_Positive_VolumeFSResizeControllerAttachEnabled(t *testing.T) {
|
||||||
},
|
},
|
||||||
Spec: v1.PersistentVolumeSpec{
|
Spec: v1.PersistentVolumeSpec{
|
||||||
ClaimRef: &v1.ObjectReference{Name: "pvc"},
|
ClaimRef: &v1.ObjectReference{Name: "pvc"},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
pvc := &v1.PersistentVolumeClaim{
|
pvc := &v1.PersistentVolumeClaim{
|
||||||
|
@ -965,6 +967,7 @@ func Test_Run_Positive_VolumeFSResizeControllerAttachEnabled(t *testing.T) {
|
||||||
},
|
},
|
||||||
Spec: v1.PersistentVolumeClaimSpec{
|
Spec: v1.PersistentVolumeClaimSpec{
|
||||||
VolumeName: "pv",
|
VolumeName: "pv",
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
pod := &v1.Pod{
|
pod := &v1.Pod{
|
||||||
|
|
|
@ -167,6 +167,7 @@ func TestGetExtraSupplementalGroupsForPod(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
pv := &v1.PersistentVolume{
|
pv := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "pvA",
|
Name: "pvA",
|
||||||
|
@ -183,6 +184,7 @@ func TestGetExtraSupplementalGroupsForPod(t *testing.T) {
|
||||||
ClaimRef: &v1.ObjectReference{
|
ClaimRef: &v1.ObjectReference{
|
||||||
Name: claim.ObjectMeta.Name,
|
Name: claim.ObjectMeta.Name,
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
kubeClient := fake.NewSimpleClientset(node, pod, pv, claim)
|
kubeClient := fake.NewSimpleClientset(node, pod, pv, claim)
|
||||||
|
@ -273,6 +275,7 @@ func createObjects() (*v1.Node, *v1.Pod, *v1.PersistentVolume, *v1.PersistentVol
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
pv := &v1.PersistentVolume{
|
pv := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "pvA",
|
Name: "pvA",
|
||||||
|
@ -286,6 +289,7 @@ func createObjects() (*v1.Node, *v1.Pod, *v1.PersistentVolume, *v1.PersistentVol
|
||||||
ClaimRef: &v1.ObjectReference{
|
ClaimRef: &v1.ObjectReference{
|
||||||
Name: "claimA",
|
Name: "claimA",
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
claim := &v1.PersistentVolumeClaim{
|
claim := &v1.PersistentVolumeClaim{
|
||||||
|
|
|
@ -254,6 +254,7 @@ func TestPluginVolume(t *testing.T) {
|
||||||
|
|
||||||
func TestPluginPersistentVolume(t *testing.T) {
|
func TestPluginPersistentVolume(t *testing.T) {
|
||||||
lun := int32(0)
|
lun := int32(0)
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
vol := &v1.PersistentVolume{
|
vol := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "vol1",
|
Name: "vol1",
|
||||||
|
@ -266,6 +267,7 @@ func TestPluginPersistentVolume(t *testing.T) {
|
||||||
Lun: &lun,
|
Lun: &lun,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false))
|
doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false))
|
||||||
|
@ -285,6 +287,7 @@ func TestPluginVolumeWWIDs(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPluginPersistentVolumeWWIDs(t *testing.T) {
|
func TestPluginPersistentVolumeWWIDs(t *testing.T) {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
vol := &v1.PersistentVolume{
|
vol := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "vol1",
|
Name: "vol1",
|
||||||
|
@ -296,6 +299,7 @@ func TestPluginPersistentVolumeWWIDs(t *testing.T) {
|
||||||
FSType: "ext4",
|
FSType: "ext4",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false))
|
doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false))
|
||||||
|
@ -314,6 +318,7 @@ func TestPluginVolumeNoDiskInfo(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPluginPersistentVolumeNoDiskInfo(t *testing.T) {
|
func TestPluginPersistentVolumeNoDiskInfo(t *testing.T) {
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
vol := &v1.PersistentVolume{
|
vol := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "vol1",
|
Name: "vol1",
|
||||||
|
@ -324,6 +329,7 @@ func TestPluginPersistentVolumeNoDiskInfo(t *testing.T) {
|
||||||
FSType: "ext4",
|
FSType: "ext4",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
doTestPluginNilMounter(t, volume.NewSpecFromPersistentVolume(vol, false))
|
doTestPluginNilMounter(t, volume.NewSpecFromPersistentVolume(vol, false))
|
||||||
|
@ -337,6 +343,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
lun := int32(0)
|
lun := int32(0)
|
||||||
|
fs := v1.PersistentVolumeFilesystem
|
||||||
pv := &v1.PersistentVolume{
|
pv := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "pvA",
|
Name: "pvA",
|
||||||
|
@ -352,6 +359,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
|
||||||
ClaimRef: &v1.ObjectReference{
|
ClaimRef: &v1.ObjectReference{
|
||||||
Name: "claimA",
|
Name: "claimA",
|
||||||
},
|
},
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,6 +370,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
|
||||||
},
|
},
|
||||||
Spec: v1.PersistentVolumeClaimSpec{
|
Spec: v1.PersistentVolumeClaimSpec{
|
||||||
VolumeName: "pvA",
|
VolumeName: "pvA",
|
||||||
|
VolumeMode: &fs,
|
||||||
},
|
},
|
||||||
Status: v1.PersistentVolumeClaimStatus{
|
Status: v1.PersistentVolumeClaimStatus{
|
||||||
Phase: v1.ClaimBound,
|
Phase: v1.ClaimBound,
|
||||||
|
|
Loading…
Reference in New Issue