2018-01-31 05:33:16 +00:00
/ *
Copyright 2018 The Kubernetes Authors .
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package storage
import (
2018-08-16 23:20:56 +00:00
"time"
2018-01-31 05:33:16 +00:00
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/util/slice"
volumeutil "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/storage/utils"
)
2018-02-23 15:59:22 +00:00
var _ = utils . SIGDescribe ( "PV Protection" , func ( ) {
2018-01-31 05:33:16 +00:00
var (
client clientset . Interface
nameSpace string
err error
pvc * v1 . PersistentVolumeClaim
pv * v1 . PersistentVolume
pvConfig framework . PersistentVolumeConfig
pvcConfig framework . PersistentVolumeClaimConfig
volLabel labels . Set
selector * metav1 . LabelSelector
)
f := framework . NewDefaultFramework ( "pv-protection" )
BeforeEach ( func ( ) {
client = f . ClientSet
nameSpace = f . Namespace . Name
framework . ExpectNoError ( framework . WaitForAllNodesSchedulable ( client , framework . TestContext . NodeSchedulableTimeout ) )
// Enforce binding only within test space via selector labels
volLabel = labels . Set { framework . VolumeSelectorKey : nameSpace }
selector = metav1 . SetAsLabelSelector ( volLabel )
pvConfig = framework . PersistentVolumeConfig {
NamePrefix : "hostpath-" ,
Labels : volLabel ,
PVSource : v1 . PersistentVolumeSource {
HostPath : & v1 . HostPathVolumeSource {
Path : "/tmp/data" ,
} ,
} ,
}
2018-04-10 07:29:08 +00:00
emptyStorageClass := ""
2018-01-31 05:33:16 +00:00
pvcConfig = framework . PersistentVolumeClaimConfig {
2018-04-10 07:29:08 +00:00
Selector : selector ,
StorageClassName : & emptyStorageClass ,
2018-01-31 05:33:16 +00:00
}
By ( "Creating a PV" )
// make the pv definitions
pv = framework . MakePersistentVolume ( pvConfig )
// create the PV
pv , err = client . CoreV1 ( ) . PersistentVolumes ( ) . Create ( pv )
Expect ( err ) . NotTo ( HaveOccurred ( ) , "Error creating PV" )
2018-08-16 23:20:56 +00:00
By ( "Waiting for PV to enter phase Available" )
framework . ExpectNoError ( framework . WaitForPersistentVolumePhase ( v1 . VolumeAvailable , client , pv . Name , 1 * time . Second , 30 * time . Second ) )
2018-01-31 05:33:16 +00:00
By ( "Checking that PV Protection finalizer is set" )
pv , err = client . CoreV1 ( ) . PersistentVolumes ( ) . Get ( pv . Name , metav1 . GetOptions { } )
Expect ( err ) . NotTo ( HaveOccurred ( ) , "While getting PV status" )
2018-10-09 21:15:45 +00:00
Expect ( slice . ContainsString ( pv . ObjectMeta . Finalizers , volumeutil . PVProtectionFinalizer , nil ) ) . To ( BeTrue ( ) , "PV Protection finalizer(%v) is not set in %v" , volumeutil . PVProtectionFinalizer , pv . ObjectMeta . Finalizers )
2018-01-31 05:33:16 +00:00
} )
AfterEach ( func ( ) {
framework . Logf ( "AfterEach: Cleaning up test resources." )
if errs := framework . PVPVCCleanup ( client , nameSpace , pv , pvc ) ; len ( errs ) > 0 {
framework . Failf ( "AfterEach: Failed to delete PVC and/or PV. Errors: %v" , utilerrors . NewAggregate ( errs ) )
}
} )
It ( "Verify \"immediate\" deletion of a PV that is not bound to a PVC" , func ( ) {
By ( "Deleting the PV" )
err = client . CoreV1 ( ) . PersistentVolumes ( ) . Delete ( pv . Name , metav1 . NewDeleteOptions ( 0 ) )
Expect ( err ) . NotTo ( HaveOccurred ( ) , "Error deleting PV" )
framework . WaitForPersistentVolumeDeleted ( client , pv . Name , framework . Poll , framework . PVDeletingTimeout )
} )
It ( "Verify that PV bound to a PVC is not removed immediately" , func ( ) {
By ( "Creating a PVC" )
pvc = framework . MakePersistentVolumeClaim ( pvcConfig , nameSpace )
pvc , err = client . CoreV1 ( ) . PersistentVolumeClaims ( pvc . Namespace ) . Create ( pvc )
Expect ( err ) . NotTo ( HaveOccurred ( ) , "Error creating PVC" )
By ( "Waiting for PVC to become Bound" )
err = framework . WaitForPersistentVolumeClaimPhase ( v1 . ClaimBound , client , nameSpace , pvc . Name , framework . Poll , framework . ClaimBindingTimeout )
Expect ( err ) . NotTo ( HaveOccurred ( ) , "Failed waiting for PVC to be bound %v" , err )
By ( "Deleting the PV, however, the PV must not be removed from the system as it's bound to a PVC" )
err = client . CoreV1 ( ) . PersistentVolumes ( ) . Delete ( pv . Name , metav1 . NewDeleteOptions ( 0 ) )
Expect ( err ) . NotTo ( HaveOccurred ( ) , "Error deleting PV" )
By ( "Checking that the PV status is Terminating" )
pv , err = client . CoreV1 ( ) . PersistentVolumes ( ) . Get ( pv . Name , metav1 . GetOptions { } )
Expect ( err ) . NotTo ( HaveOccurred ( ) , "While checking PV status" )
Expect ( pv . ObjectMeta . DeletionTimestamp ) . NotTo ( Equal ( nil ) )
By ( "Deleting the PVC that is bound to the PV" )
err = client . CoreV1 ( ) . PersistentVolumeClaims ( pvc . Namespace ) . Delete ( pvc . Name , metav1 . NewDeleteOptions ( 0 ) )
Expect ( err ) . NotTo ( HaveOccurred ( ) , "Error deleting PVC" )
By ( "Checking that the PV is automatically removed from the system because it's no longer bound to a PVC" )
framework . WaitForPersistentVolumeDeleted ( client , pv . Name , framework . Poll , framework . PVDeletingTimeout )
} )
} )