From f555f883d8b2beacae2bb21226562eb1e1079d25 Mon Sep 17 00:00:00 2001 From: kmova <kiran.mova@mayadata.io> Date: Sun, 5 Apr 2020 05:49:35 +0000 Subject: [PATCH 1/4] feat(localpv-device): allow local pv device on select devices Ref: https://github.com/openebs/openebs/issues/2916 This PR makes use of the Label Selector capability added in the BDC. More details: https://github.com/openebs/openebs/issues/2921 The BDC Label Selector feature makes it possible for administrators to group a set of block devices and use them for creating Local PV (device). To use the Label Selector feature with Local PV (Devices) the administrator is expected to group(or pool) a set of block devices by assigning them the label: openebs.io/block-device-pool=< pool-name >. The `<pool-name>` can be passed to Local PV storage class via cas annotations. If the value is present, then Local PV device provisioner will set the following additional selector on the BDC: `openebs.io/block-device-pool=< pool-name >` Signed-off-by: kmova <kiran.mova@mayadata.io> --- cmd/provisioner-localpv/app/config.go | 47 +++++++++++++++++++ .../app/helper_blockdevice.go | 16 +++++-- .../app/provisioner_blockdevice.go | 1 + pkg/blockdeviceclaim/v1alpha1/build.go | 30 ++++++++++++ 4 files changed, 91 insertions(+), 3 deletions(-) diff --git a/cmd/provisioner-localpv/app/config.go b/cmd/provisioner-localpv/app/config.go index 129d90a8b8..52253915e3 100644 --- a/cmd/provisioner-localpv/app/config.go +++ b/cmd/provisioner-localpv/app/config.go @@ -37,12 +37,45 @@ const ( //KeyPVStorageType defines if the PV should be backed // a hostpath ( sub directory or a storage device) KeyPVStorageType = "StorageType" + //KeyPVBasePath defines base directory for hostpath volumes // can be configured via the StorageClass annotations. KeyPVBasePath = "BasePath" + //KeyPVFSType defines filesystem type to be used with devices // and can be configured via the StorageClass annotations. KeyPVFSType = "FSType" + + //KeyBDPoolName defines the value for the Block Device Pool + //label selector configured via the StorageClass annotations. + //User can group block devices across nodes to form a block + //device pool, by setting the label on block devices as: + // openebs.io/block-device-pool=<pool-name> + // + //The <pool-name> used above can be passsed to the + //Local PV device provisioner via the StorageClass + //CAS annotations. + // + //Example: Local PV device StorageClass for picking devices + //labeled as: openebs.io/block-device-pool=pool-x + //will be as follows + // + // kind: StorageClass + // metadata: + // name: openebs-device-pool-x + // annotations: + // openebs.io/cas-type: local + // cas.openebs.io/config: | + // - name: StorageType + // value: "device" + // - name: BlockDevicePoolName + // value: "pool-x" + // provisioner: openebs.io/local + // volumeBindingMode: WaitForFirstConsumer + // reclaimPolicy: Delete + // + KeyBDPoolName = "BlockDevicePoolName" + //KeyPVRelativePath defines the alternate folder name under the BasePath // By default, the pv name will be used as the folder name. // KeyPVBasePath can be useful for providing the same underlying folder @@ -139,6 +172,20 @@ func (c *VolumeConfig) GetFSType() string { return fsType } +//GetBDPoolName returns the block device pool label +//value configured in StorageClass. +// +//Default is "", no device pool will be set and all +//the available block devices can be used for creating +//Local PV. +func (c *VolumeConfig) GetBDPoolName() string { + bdPoolName := c.getValue(KeyBDPoolName) + if len(strings.TrimSpace(bdPoolName)) == 0 { + return "" + } + return bdPoolName +} + //GetPath returns a valid PV path based on the configuration // or an error. The Path is constructed using the following rules: // If AbsolutePath is specified return it. (Future) diff --git a/cmd/provisioner-localpv/app/helper_blockdevice.go b/cmd/provisioner-localpv/app/helper_blockdevice.go index f2c3238278..71ad96eb5c 100644 --- a/cmd/provisioner-localpv/app/helper_blockdevice.go +++ b/cmd/provisioner-localpv/app/helper_blockdevice.go @@ -65,6 +65,10 @@ type HelperBlockDeviceOptions struct { bdcName string // volumeMode of PVC volumeMode corev1.PersistentVolumeMode + + //bdPoolName is the value passed for + // BlockDevicePoolName via StorageClass config + bdPoolName string } // validate checks that the required fields to create BDC @@ -120,14 +124,20 @@ func (p *Provisioner) createBlockDeviceClaim(blkDevOpts *HelperBlockDeviceOption return nil } - bdcObj, err := blockdeviceclaim.NewBuilder(). + bdcObjBuilder := blockdeviceclaim.NewBuilder(). WithNamespace(p.namespace). WithName(bdcName). WithHostName(blkDevOpts.nodeHostname). WithCapacity(blkDevOpts.capacity). WithFinalizer(LocalPVFinalizer). - WithBlockVolumeMode(blkDevOpts.volumeMode). - Build() + WithBlockVolumeMode(blkDevOpts.volumeMode) + + // If bdPoolName is configure, set it on the BDC + if len(blkDevOpts.bdPoolName) > 0 { + bdcObjBuilder.WithBlockDevicePoolName(blkDevOpts.bdPoolName) + } + + bdcObj, err := bdcObjBuilder.Build() if err != nil { //TODO : Need to relook at this error diff --git a/cmd/provisioner-localpv/app/provisioner_blockdevice.go b/cmd/provisioner-localpv/app/provisioner_blockdevice.go index 18bec2649e..4ad61468a7 100644 --- a/cmd/provisioner-localpv/app/provisioner_blockdevice.go +++ b/cmd/provisioner-localpv/app/provisioner_blockdevice.go @@ -45,6 +45,7 @@ func (p *Provisioner) ProvisionBlockDevice(opts pvController.VolumeOptions, volu name: name, capacity: capacity.String(), volumeMode: *opts.PVC.Spec.VolumeMode, + bdPoolName: volumeConfig.GetBDPoolName(), } path, blkPath, err := p.getBlockDevicePath(blkDevOpts) diff --git a/pkg/blockdeviceclaim/v1alpha1/build.go b/pkg/blockdeviceclaim/v1alpha1/build.go index eb896413ef..25b559f0f9 100644 --- a/pkg/blockdeviceclaim/v1alpha1/build.go +++ b/pkg/blockdeviceclaim/v1alpha1/build.go @@ -31,8 +31,13 @@ const ( // StoragePoolKindCSPC holds the value of CStorPoolCluster StoragePoolKindCSPC = "CStorPoolCluster" + // APIVersion holds the value of OpenEBS version APIVersion = "openebs.io/v1alpha1" + + // bdPoolKey defines the label selector key + // used for grouping block devices on a given node + bdPoolKey = "openebs.io/block-device-pool" ) // Builder is the builder object for BlockDeviceClaim @@ -323,3 +328,28 @@ func (b *Builder) WithBlockVolumeMode(mode corev1.PersistentVolumeMode) *Builder return b } + +// WithBlockDevicePoolName appends (or creates) the BDC Label Selector +// by setting the provided value to the fixed key +// openebs.io/block-device-pool +// This will enable the NDM to pick only devices that +// match the node (hostname) and block device pool label. +func (b *Builder) WithBlockDevicePoolName(bdPoolName string) *Builder { + if len(bdPoolName) == 0 { + b.errs = append( + b.errs, + errors.New("failed to build BDC object: missing block device pool name"), + ) + return b + } + + if b.BDC.Object.Spec.Selector == nil { + newmatchlabels := map[string]string{} + b.BDC.Object.Spec.Selector = &metav1.LabelSelector{ + MatchLabels: newmatchlabels, + } + } + + b.BDC.Object.Spec.Selector.MatchLabels[bdPoolKey] = bdPoolName + return b +} From 2f1d26386e2b47bcaa83a32d6abcaaa95d2fbc7a Mon Sep 17 00:00:00 2001 From: kmova <kiran.mova@mayadata.io> Date: Mon, 6 Apr 2020 06:01:27 +0000 Subject: [PATCH 2/4] ut(blockdeviceclaim): for method WithBlockDevicePoolName Signed-off-by: kmova <kiran.mova@mayadata.io> --- pkg/blockdeviceclaim/v1alpha1/build.go | 8 +-- pkg/blockdeviceclaim/v1alpha1/build_test.go | 63 ++++++++++++++++++++- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/pkg/blockdeviceclaim/v1alpha1/build.go b/pkg/blockdeviceclaim/v1alpha1/build.go index 25b559f0f9..6d967bd293 100644 --- a/pkg/blockdeviceclaim/v1alpha1/build.go +++ b/pkg/blockdeviceclaim/v1alpha1/build.go @@ -344,10 +344,10 @@ func (b *Builder) WithBlockDevicePoolName(bdPoolName string) *Builder { } if b.BDC.Object.Spec.Selector == nil { - newmatchlabels := map[string]string{} - b.BDC.Object.Spec.Selector = &metav1.LabelSelector{ - MatchLabels: newmatchlabels, - } + b.BDC.Object.Spec.Selector = &metav1.LabelSelector{} + } + if b.BDC.Object.Spec.Selector.MatchLabels == nil { + b.BDC.Object.Spec.Selector.MatchLabels = map[string]string{} } b.BDC.Object.Spec.Selector.MatchLabels[bdPoolKey] = bdPoolName diff --git a/pkg/blockdeviceclaim/v1alpha1/build_test.go b/pkg/blockdeviceclaim/v1alpha1/build_test.go index da1245747a..669a226b82 100644 --- a/pkg/blockdeviceclaim/v1alpha1/build_test.go +++ b/pkg/blockdeviceclaim/v1alpha1/build_test.go @@ -206,16 +206,46 @@ func TestBuildWithCapacity(t *testing.T) { } } +func TestBuilderWithBlockDevicePoolName(t *testing.T) { + tests := map[string]struct { + name string + expectErr bool + }{ + "Test Builder with pool name": { + name: "test", + expectErr: false, + }, + "Test Builder without pool name": { + name: "", + expectErr: true, + }, + } + for name, mock := range tests { + name, mock := name, mock + t.Run(name, func(t *testing.T) { + b := NewBuilder().WithBlockDevicePoolName(mock.name) + if mock.expectErr && len(b.errs) == 0 { + t.Fatalf("Test %q failed: expected error not to be nil", name) + } + if !mock.expectErr && len(b.errs) > 0 { + t.Fatalf("Test %q failed: expected error to be nil", name) + } + }) + } +} + func TestBuild(t *testing.T) { tests := map[string]struct { name string capacity string + poolName string expectedBDC *apis.BlockDeviceClaim expectedErr bool }{ "BDC with correct details": { name: "BDC1", capacity: "10Ti", + poolName: "", expectedBDC: &apis.BlockDeviceClaim{ ObjectMeta: metav1.ObjectMeta{Name: "BDC1"}, Spec: apis.DeviceClaimSpec{ @@ -228,9 +258,31 @@ func TestBuild(t *testing.T) { }, expectedErr: false, }, + "BDC with correct details, including device pool": { + name: "BDC1", + capacity: "10Ti", + poolName: "test", + expectedBDC: &apis.BlockDeviceClaim{ + ObjectMeta: metav1.ObjectMeta{Name: "BDC1"}, + Spec: apis.DeviceClaimSpec{ + Resources: apis.DeviceClaimResources{ + Requests: corev1.ResourceList{ + corev1.ResourceName(ndm.ResourceStorage): fakeCapacity("10Ti"), + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + bdPoolKey: "test", + }, + }, + }, + }, + expectedErr: false, + }, "BDC with error": { name: "", capacity: "500Gi", + poolName: "test", expectedBDC: nil, expectedErr: true, }, @@ -238,7 +290,16 @@ func TestBuild(t *testing.T) { for name, mock := range tests { name, mock := name, mock t.Run(name, func(t *testing.T) { - bdcObj, err := NewBuilder().WithName(mock.name).WithCapacity(mock.capacity).Build() + bdcObjBuilder := NewBuilder(). + WithName(mock.name). + WithCapacity(mock.capacity) + + if len(mock.poolName) > 0 { + bdcObjBuilder.WithBlockDevicePoolName(mock.poolName) + } + + bdcObj, err := bdcObjBuilder.Build() + if mock.expectedErr && err == nil { t.Fatalf("Test %q failed: expected error not to be nil", name) } From 41a4a8b6d5b344b2fec0f6f63e625ab00eb18fbc Mon Sep 17 00:00:00 2001 From: kmova <kiran.mova@mayadata.io> Date: Mon, 6 Apr 2020 17:48:12 +0000 Subject: [PATCH 3/4] feat(localpv-device): rename Block Device Pool to Tag Signed-off-by: kmova <kiran.mova@mayadata.io> --- cmd/provisioner-localpv/app/config.go | 40 ++++++++++--------- .../app/helper_blockdevice.go | 12 +++--- .../app/provisioner_blockdevice.go | 2 +- pkg/blockdeviceclaim/v1alpha1/build.go | 20 +++++----- pkg/blockdeviceclaim/v1alpha1/build_test.go | 28 ++++++------- 5 files changed, 52 insertions(+), 50 deletions(-) diff --git a/cmd/provisioner-localpv/app/config.go b/cmd/provisioner-localpv/app/config.go index 52253915e3..eac37cb518 100644 --- a/cmd/provisioner-localpv/app/config.go +++ b/cmd/provisioner-localpv/app/config.go @@ -46,35 +46,37 @@ const ( // and can be configured via the StorageClass annotations. KeyPVFSType = "FSType" - //KeyBDPoolName defines the value for the Block Device Pool + //KeyBDTag defines the value for the Block Device Tag //label selector configured via the StorageClass annotations. - //User can group block devices across nodes to form a block - //device pool, by setting the label on block devices as: - // openebs.io/block-device-pool=<pool-name> + //User can group block devices across nodes by setting the + //label on block devices as: + // openebs.io/block-device-tag=<tag-value> // - //The <pool-name> used above can be passsed to the + //The <tag-value> used above can be passsed to the //Local PV device provisioner via the StorageClass - //CAS annotations. + //CAS annotations, to specify that Local PV (device) + //should only make use of those block devices that + //tagged with the given <tag-value>. // //Example: Local PV device StorageClass for picking devices - //labeled as: openebs.io/block-device-pool=pool-x + //labeled as: openebs.io/block-device-tag=tag-x //will be as follows // // kind: StorageClass // metadata: - // name: openebs-device-pool-x + // name: openebs-device-tag-x // annotations: // openebs.io/cas-type: local // cas.openebs.io/config: | // - name: StorageType // value: "device" - // - name: BlockDevicePoolName - // value: "pool-x" + // - name: BlockDeviceTag + // value: "tag-x" // provisioner: openebs.io/local // volumeBindingMode: WaitForFirstConsumer // reclaimPolicy: Delete // - KeyBDPoolName = "BlockDevicePoolName" + KeyBDTag = "BlockDeviceTag" //KeyPVRelativePath defines the alternate folder name under the BasePath // By default, the pv name will be used as the folder name. @@ -172,18 +174,18 @@ func (c *VolumeConfig) GetFSType() string { return fsType } -//GetBDPoolName returns the block device pool label +//GetBDTagValue returns the block device tag //value configured in StorageClass. // -//Default is "", no device pool will be set and all -//the available block devices can be used for creating -//Local PV. -func (c *VolumeConfig) GetBDPoolName() string { - bdPoolName := c.getValue(KeyBDPoolName) - if len(strings.TrimSpace(bdPoolName)) == 0 { +//Default is "", no device tag will be set and any +//available block device (without labelled with tag) +//can be used for creating Local PV(device). +func (c *VolumeConfig) GetBDTagValue() string { + bdTagValue := c.getValue(KeyBDTag) + if len(strings.TrimSpace(bdTagValue)) == 0 { return "" } - return bdPoolName + return bdTagValue } //GetPath returns a valid PV path based on the configuration diff --git a/cmd/provisioner-localpv/app/helper_blockdevice.go b/cmd/provisioner-localpv/app/helper_blockdevice.go index 71ad96eb5c..1237a28d8f 100644 --- a/cmd/provisioner-localpv/app/helper_blockdevice.go +++ b/cmd/provisioner-localpv/app/helper_blockdevice.go @@ -66,9 +66,9 @@ type HelperBlockDeviceOptions struct { // volumeMode of PVC volumeMode corev1.PersistentVolumeMode - //bdPoolName is the value passed for - // BlockDevicePoolName via StorageClass config - bdPoolName string + //bdTagValue is the value passed for + // BlockDeviceTag via StorageClass config + bdTagValue string } // validate checks that the required fields to create BDC @@ -132,9 +132,9 @@ func (p *Provisioner) createBlockDeviceClaim(blkDevOpts *HelperBlockDeviceOption WithFinalizer(LocalPVFinalizer). WithBlockVolumeMode(blkDevOpts.volumeMode) - // If bdPoolName is configure, set it on the BDC - if len(blkDevOpts.bdPoolName) > 0 { - bdcObjBuilder.WithBlockDevicePoolName(blkDevOpts.bdPoolName) + // If bdTagValue is configure, set it on the BDC + if len(blkDevOpts.bdTagValue) > 0 { + bdcObjBuilder.WithBlockDeviceTag(blkDevOpts.bdTagValue) } bdcObj, err := bdcObjBuilder.Build() diff --git a/cmd/provisioner-localpv/app/provisioner_blockdevice.go b/cmd/provisioner-localpv/app/provisioner_blockdevice.go index 4ad61468a7..0c97088d90 100644 --- a/cmd/provisioner-localpv/app/provisioner_blockdevice.go +++ b/cmd/provisioner-localpv/app/provisioner_blockdevice.go @@ -45,7 +45,7 @@ func (p *Provisioner) ProvisionBlockDevice(opts pvController.VolumeOptions, volu name: name, capacity: capacity.String(), volumeMode: *opts.PVC.Spec.VolumeMode, - bdPoolName: volumeConfig.GetBDPoolName(), + bdTagValue: volumeConfig.GetBDTagValue(), } path, blkPath, err := p.getBlockDevicePath(blkDevOpts) diff --git a/pkg/blockdeviceclaim/v1alpha1/build.go b/pkg/blockdeviceclaim/v1alpha1/build.go index 6d967bd293..27b806d6d5 100644 --- a/pkg/blockdeviceclaim/v1alpha1/build.go +++ b/pkg/blockdeviceclaim/v1alpha1/build.go @@ -35,9 +35,9 @@ const ( // APIVersion holds the value of OpenEBS version APIVersion = "openebs.io/v1alpha1" - // bdPoolKey defines the label selector key - // used for grouping block devices on a given node - bdPoolKey = "openebs.io/block-device-pool" + // bdTagKey defines the label selector key + // used for grouping block devices using a tag. + bdTagKey = "openebs.io/block-device-tag" ) // Builder is the builder object for BlockDeviceClaim @@ -329,16 +329,16 @@ func (b *Builder) WithBlockVolumeMode(mode corev1.PersistentVolumeMode) *Builder return b } -// WithBlockDevicePoolName appends (or creates) the BDC Label Selector +// WithBlockDeviceTag appends (or creates) the BDC Label Selector // by setting the provided value to the fixed key -// openebs.io/block-device-pool +// openebs.io/block-device-tag // This will enable the NDM to pick only devices that -// match the node (hostname) and block device pool label. -func (b *Builder) WithBlockDevicePoolName(bdPoolName string) *Builder { - if len(bdPoolName) == 0 { +// match the node (hostname) and block device tag value. +func (b *Builder) WithBlockDeviceTag(bdTagValue string) *Builder { + if len(bdTagValue) == 0 { b.errs = append( b.errs, - errors.New("failed to build BDC object: missing block device pool name"), + errors.New("failed to build BDC object: missing block device tag value"), ) return b } @@ -350,6 +350,6 @@ func (b *Builder) WithBlockDevicePoolName(bdPoolName string) *Builder { b.BDC.Object.Spec.Selector.MatchLabels = map[string]string{} } - b.BDC.Object.Spec.Selector.MatchLabels[bdPoolKey] = bdPoolName + b.BDC.Object.Spec.Selector.MatchLabels[bdTagKey] = bdTagValue return b } diff --git a/pkg/blockdeviceclaim/v1alpha1/build_test.go b/pkg/blockdeviceclaim/v1alpha1/build_test.go index 669a226b82..916ede042d 100644 --- a/pkg/blockdeviceclaim/v1alpha1/build_test.go +++ b/pkg/blockdeviceclaim/v1alpha1/build_test.go @@ -206,24 +206,24 @@ func TestBuildWithCapacity(t *testing.T) { } } -func TestBuilderWithBlockDevicePoolName(t *testing.T) { +func TestBuilderWithBlockDeviceTag(t *testing.T) { tests := map[string]struct { - name string + tag string expectErr bool }{ - "Test Builder with pool name": { - name: "test", + "Test Builder with tag": { + tag: "test", expectErr: false, }, - "Test Builder without pool name": { - name: "", + "Test Builder without tag": { + tag: "", expectErr: true, }, } for name, mock := range tests { name, mock := name, mock t.Run(name, func(t *testing.T) { - b := NewBuilder().WithBlockDevicePoolName(mock.name) + b := NewBuilder().WithBlockDeviceTag(mock.tag) if mock.expectErr && len(b.errs) == 0 { t.Fatalf("Test %q failed: expected error not to be nil", name) } @@ -238,14 +238,14 @@ func TestBuild(t *testing.T) { tests := map[string]struct { name string capacity string - poolName string + tagValue string expectedBDC *apis.BlockDeviceClaim expectedErr bool }{ "BDC with correct details": { name: "BDC1", capacity: "10Ti", - poolName: "", + tagValue: "", expectedBDC: &apis.BlockDeviceClaim{ ObjectMeta: metav1.ObjectMeta{Name: "BDC1"}, Spec: apis.DeviceClaimSpec{ @@ -261,7 +261,7 @@ func TestBuild(t *testing.T) { "BDC with correct details, including device pool": { name: "BDC1", capacity: "10Ti", - poolName: "test", + tagValue: "test", expectedBDC: &apis.BlockDeviceClaim{ ObjectMeta: metav1.ObjectMeta{Name: "BDC1"}, Spec: apis.DeviceClaimSpec{ @@ -272,7 +272,7 @@ func TestBuild(t *testing.T) { }, Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - bdPoolKey: "test", + bdTagKey: "test", }, }, }, @@ -282,7 +282,7 @@ func TestBuild(t *testing.T) { "BDC with error": { name: "", capacity: "500Gi", - poolName: "test", + tagValue: "test", expectedBDC: nil, expectedErr: true, }, @@ -294,8 +294,8 @@ func TestBuild(t *testing.T) { WithName(mock.name). WithCapacity(mock.capacity) - if len(mock.poolName) > 0 { - bdcObjBuilder.WithBlockDevicePoolName(mock.poolName) + if len(mock.tagValue) > 0 { + bdcObjBuilder.WithBlockDeviceTag(mock.tagValue) } bdcObj, err := bdcObjBuilder.Build() From 9da0aa72554f05ec66fb93ae2a6bc2570d38fec9 Mon Sep 17 00:00:00 2001 From: kmova <kiran.mova@mayadata.io> Date: Tue, 7 Apr 2020 15:42:58 +0000 Subject: [PATCH 4/4] docs(localpv): update instruction on running bdd Signed-off-by: kmova <kiran.mova@mayadata.io> --- tests/localpv/README.md | 40 +++++++++++++++++++++++++++++++++++++ tests/localpv/suite_test.go | 3 ++- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tests/localpv/README.md diff --git a/tests/localpv/README.md b/tests/localpv/README.md new file mode 100644 index 0000000000..e4e0c99e7c --- /dev/null +++ b/tests/localpv/README.md @@ -0,0 +1,40 @@ +# Local PV Provisioner BDD + +Local PV Provisioner BDD tests are developed using ginkgo & gomega libraries. + +## How to run the tests? + +### Pre-requisites + +- Install Ginkgo and Gomega on your development machine. + ``` + $ go get github.com/onsi/ginkgo/ginkgo + $ go get github.com/onsi/gomega/... + ``` +- Get your Kubernetes Cluster ready and make sure you can run + kubectl from your development machine. + Note down the path to the `kubeconfig` file used by kubectl + to access your cluster. Example: /home/<user>/.kube/config + +- (Optional) Set the KUBECONFIG environment variable on your + development machine to point to the kubeconfig file. + Example: KUBECONFIG=/home/<user>/.kube/config + + If you do not set this ENV, you will have to pass the file + to the ginkgo CLI + +- Some of the tests require block devices (that are not mounted) + to be available in the cluster. + +- Install required OpenEBS components. + Example: `kubectl apply -f openebs-operator.yaml` + +### Run tests + +- Run the tests by being in the localpv tests folder. + `$ cd $GOPATH/src/github.com/openebs/maya/tests/localpv/` + `$ ginkgo -v --` + + In case the KUBECONFIG env is not configured, you can run: + `$ ginkgo -v -- -kubeconfig=/path/to/kubeconfig` + diff --git a/tests/localpv/suite_test.go b/tests/localpv/suite_test.go index 9c89cf38cf..fed54a348d 100644 --- a/tests/localpv/suite_test.go +++ b/tests/localpv/suite_test.go @@ -16,6 +16,7 @@ package localpv import ( "flag" + "os" "testing" . "github.com/onsi/ginkgo" @@ -45,7 +46,7 @@ func TestSource(t *testing.T) { } func init() { - flag.StringVar(&kubeConfigPath, "kubeconfig", "", "path to kubeconfig to invoke kubernetes API calls") + flag.StringVar(&kubeConfigPath, "kubeconfig", os.Getenv("KUBECONFIG"), "path to kubeconfig to invoke kubernetes API calls") } var ops *tests.Operations