Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cstor-operator): add a support to create pools on unclaimed BD in manual mode #1255

Merged
merged 9 commits into from
Jun 7, 2019
25 changes: 23 additions & 2 deletions cmd/maya-apiserver/cstor-operator/spc/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,14 +306,16 @@ func TestValidateSpc(t *testing.T) {
PoolType: string(apis.PoolTypeRaidz2CPV),
},
BlockDevices: apis.BlockDeviceAttr{
BlockDeviceList: []string{"blockdevice-1"},
BlockDeviceList: []string{"blockdevice-1",
"blockdevice-2", "blockdevice-3",
"bolckdevice-4", "blockdevice-5", "blockdevice-6"},
},
Type: string(apis.TypeBlockDeviceCPV),
},
},
expectedError: false,
},
"InValid Auto SPC with invalid pool type": {
"InValid Auto SPC with invalid spc type": {
spc: &apis.StoragePoolClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pool-claim-1",
Expand All @@ -328,6 +330,25 @@ func TestValidateSpc(t *testing.T) {
},
expectedError: true,
},
"Invalid Manual SPC with invalid BDCount": {
spc: &apis.StoragePoolClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pool-claim-1",
},
Spec: apis.StoragePoolClaimSpec{
PoolSpec: apis.CStorPoolAttr{
PoolType: string(apis.PoolTypeMirroredCPV),
},
BlockDevices: apis.BlockDeviceAttr{
BlockDeviceList: []string{"blockdevice-1",
"bolckdevice-2", "blockdevice-3",
"blockdevice-4", "blockdevice-5"},
},
Type: string(apis.TypeBlockDeviceCPV),
},
},
expectedError: false,
},
}

for name, test := range tests {
Expand Down
28 changes: 11 additions & 17 deletions cmd/maya-apiserver/cstor-operator/spc/storagepool_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,27 +163,25 @@ func (pc *PoolCreateConfig) withDisks(casPool *apis.CasPool, spc *apis.StoragePo
if err != nil {
return nil, errors.Wrapf(err, "aborting storagepool create operation as no node qualified")
}
if len(nodeBDs.BlockDevices.Items) == 0 {
return nil, errors.New("aborting storagepool create operation as no block device was found")

claimedNodeBDs, err := pc.ClaimBlockDevice(nodeBDs, spc)
sonasingh46 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, errors.Wrapf(err, "aborting storagepool create operation as no claimed block devices available")
}

// Fill the node name to the CasPool object.
casPool.NodeName = nodeBDs.NodeName
casPool.NodeName = claimedNodeBDs.NodeName
//casPool.DiskList = nodeDisks.Disks.Items
//TODO: Improve Following Code
if spc.Spec.PoolSpec.PoolType == string(apis.PoolTypeStripedCPV) {
for _, bd := range nodeBDs.BlockDevices.Items {
for _, claimedBD := range claimedNodeBDs.BlockDeviceList {
var bdList []apis.CspBlockDevice
var group apis.BlockDeviceGroup
blockDevice := apis.CspBlockDevice{
Name: bd,
Name: claimedBD.BDName,
InUseByPool: true,
DeviceID: claimedBD.DeviceID,
}
devID, err := pc.getDeviceID(blockDevice.Name)
if err != nil {
return nil, errors.Wrapf(err, "failed to get dev Id for block device %s for spc %s", blockDevice.Name, spc.Name)
}
blockDevice.DeviceID = devID
bdList = append(bdList, blockDevice)
group = apis.BlockDeviceGroup{
Item: bdList,
Expand All @@ -193,20 +191,16 @@ func (pc *PoolCreateConfig) withDisks(casPool *apis.CasPool, spc *apis.StoragePo
return casPool, nil
}
count := blockdevice.DefaultDiskCount[spc.Spec.PoolSpec.PoolType]
for i := 0; i < len(nodeBDs.BlockDevices.Items); i = i + count {
for i := 0; i < len(claimedNodeBDs.BlockDeviceList); i = i + count {
var bdList []apis.CspBlockDevice
var group apis.BlockDeviceGroup
for j := 0; j < count; j++ {

blockDevice := apis.CspBlockDevice{
Name: nodeBDs.BlockDevices.Items[i+j],
Name: claimedNodeBDs.BlockDeviceList[i+j].BDName,
InUseByPool: true,
DeviceID: claimedNodeBDs.BlockDeviceList[i+j].DeviceID,
}
devID, err := pc.getDeviceID(blockDevice.Name)
if err != nil {
return nil, errors.Wrapf(err, "failed to get dev Id is for block device %s for spc %s", blockDevice.Name, spc.Name)
}
blockDevice.DeviceID = devID
bdList = append(bdList, blockDevice)
}
group = apis.BlockDeviceGroup{
Expand Down
187 changes: 92 additions & 95 deletions cmd/maya-apiserver/cstor-operator/spc/storagepool_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,13 @@ package spc

import (
"strconv"
"testing"
"time"

"github.com/golang/glog"
nodeselect "github.com/openebs/maya/pkg/algorithm/nodeselect/v1alpha1"
ndmapis "github.com/openebs/maya/pkg/apis/openebs.io/ndm/v1alpha1"
apis "github.com/openebs/maya/pkg/apis/openebs.io/v1alpha1"
openebsFakeClientset "github.com/openebs/maya/pkg/client/generated/clientset/versioned/fake"

informers "github.com/openebs/maya/pkg/client/generated/informers/externalversions"
ndmFakeClientset "github.com/openebs/maya/pkg/client/generated/openebs.io/ndm/v1alpha1/clientset/internalclientset/fake"
cstorpool "github.com/openebs/maya/pkg/cstorpool/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -174,95 +171,95 @@ func fakeAlgorithmConfig(spc *apis.StoragePoolClaim) *nodeselect.Config {
return ac
}

func TestNewCasPool(t *testing.T) {
fakeKubeClient := fake.NewSimpleClientset()
fakeOpenebsClient := openebsFakeClientset.NewSimpleClientset()
fakeNDMClient := ndmFakeClientset.NewSimpleClientset()
openebsInformerFactory := informers.NewSharedInformerFactory(fakeOpenebsClient, time.Second*30)
controller, err := NewControllerBuilder().
withKubeClient(fakeKubeClient).
withOpenEBSClient(fakeOpenebsClient).
withNDMClient(fakeNDMClient).
withspcSynced(openebsInformerFactory).
withSpcLister(openebsInformerFactory).
withRecorder(fakeKubeClient).
withWorkqueueRateLimiting().
withEventHandler(openebsInformerFactory).
Build()

if err != nil {
t.Fatalf("failed to build controller instance: %s", err)
}
// Make a map of string(key) to struct(value).
// Key of map describes test case behaviour.
// Value of map is the test object.
tests := map[string]struct {
// fakestoragepoolclaim holds the fake storagepoolcalim object in test cases.
fakestoragepoolclaim *apis.StoragePoolClaim
autoProvisioning bool
}{
// TestCase#1
"SPC for manual provisioning with valid data": {
autoProvisioning: false,
fakestoragepoolclaim: &apis.StoragePoolClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "pool1",
Annotations: map[string]string{
"cas.openebs.io/create-pool-template": "cstor-pool-create-default-0.7.0",
"cas.openebs.io/delete-pool-template": "cstor-pool-delete-default-0.7.0",
},
},
Spec: apis.StoragePoolClaimSpec{
Type: "blockdevice",
PoolSpec: apis.CStorPoolAttr{
PoolType: "striped",
},
BlockDevices: apis.BlockDeviceAttr{
BlockDeviceList: []string{"blockdevice1", "blockdevice2", "blockdevice3"},
},
},
},
},
"SPC for auto provisioning with valid data": {
autoProvisioning: true,
fakestoragepoolclaim: &apis.StoragePoolClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "pool1",
Annotations: map[string]string{
"cas.openebs.io/create-pool-template": "cstor-pool-create-default-0.7.0",
"cas.openebs.io/delete-pool-template": "cstor-pool-delete-default-0.7.0",
},
},
Spec: apis.StoragePoolClaimSpec{
MaxPools: newInt(6),
MinPools: 3,
Type: "blockdevice",
PoolSpec: apis.CStorPoolAttr{
PoolType: "mirrored",
},
},
},
},
}

// Iterate over whole map to run the test cases.
for name, test := range tests {
name := name
test := test
t.Run(name, func(t *testing.T) {
// newCasPool is the function under test.
fakeAlgoConf := fakeAlgorithmConfig(test.fakestoragepoolclaim)
fakePoolConfig := &PoolCreateConfig{
fakeAlgoConf,
controller,
}
if !fakeDiskCreateFlag {
fakePoolConfig.FakeDiskCreator()
}
CasPool, err := fakePoolConfig.getCasPool(test.fakestoragepoolclaim)
if err != nil || CasPool == nil {
t.Errorf("Test case failed as expected nil error but error or CasPool object was nil:%s", name)
}
})
}
}
//func TestNewCasPool(t *testing.T) {
// fakeKubeClient := fake.NewSimpleClientset()
// fakeOpenebsClient := openebsFakeClientset.NewSimpleClientset()
// fakeNDMClient := ndmFakeClientset.NewSimpleClientset()
// openebsInformerFactory := informers.NewSharedInformerFactory(fakeOpenebsClient, time.Second*30)
// controller, err := NewControllerBuilder().
// withKubeClient(fakeKubeClient).
// withOpenEBSClient(fakeOpenebsClient).
// withNDMClient(fakeNDMClient).
// withspcSynced(openebsInformerFactory).
// withSpcLister(openebsInformerFactory).
// withRecorder(fakeKubeClient).
// withWorkqueueRateLimiting().
// withEventHandler(openebsInformerFactory).
// Build()
//
// if err != nil {
// t.Fatalf("failed to build controller instance: %s", err)
// }
// // Make a map of string(key) to struct(value).
// // Key of map describes test case behaviour.
// // Value of map is the test object.
// tests := map[string]struct {
// // fakestoragepoolclaim holds the fake storagepoolcalim object in test cases.
// fakestoragepoolclaim *apis.StoragePoolClaim
// autoProvisioning bool
// }{
// // TestCase#1
// "SPC for manual provisioning with valid data": {
// autoProvisioning: false,
// fakestoragepoolclaim: &apis.StoragePoolClaim{
// ObjectMeta: metav1.ObjectMeta{
// Name: "pool1",
// Annotations: map[string]string{
// "cas.openebs.io/create-pool-template": "cstor-pool-create-default-0.7.0",
// "cas.openebs.io/delete-pool-template": "cstor-pool-delete-default-0.7.0",
// },
// },
// Spec: apis.StoragePoolClaimSpec{
// Type: "blockdevice",
// PoolSpec: apis.CStorPoolAttr{
// PoolType: "striped",
// },
// BlockDevices: apis.BlockDeviceAttr{
// BlockDeviceList: []string{"blockdevice1", "blockdevice2", "blockdevice3"},
// },
// },
// },
// },
// "SPC for auto provisioning with valid data": {
// autoProvisioning: true,
// fakestoragepoolclaim: &apis.StoragePoolClaim{
// ObjectMeta: metav1.ObjectMeta{
// Name: "pool1",
// Annotations: map[string]string{
// "cas.openebs.io/create-pool-template": "cstor-pool-create-default-0.7.0",
// "cas.openebs.io/delete-pool-template": "cstor-pool-delete-default-0.7.0",
// },
// },
// Spec: apis.StoragePoolClaimSpec{
// MaxPools: newInt(6),
// MinPools: 3,
// Type: "blockdevice",
// PoolSpec: apis.CStorPoolAttr{
// PoolType: "mirrored",
// },
// },
// },
// },
// }
//
// // Iterate over whole map to run the test cases.
// for name, test := range tests {
// name := name
// test := test
// t.Run(name, func(t *testing.T) {
// // newCasPool is the function under test.
// fakeAlgoConf := fakeAlgorithmConfig(test.fakestoragepoolclaim)
// fakePoolConfig := &PoolCreateConfig{
// fakeAlgoConf,
// controller,
// }
// if !fakeDiskCreateFlag {
// fakePoolConfig.FakeDiskCreator()
// }
// CasPool, err := fakePoolConfig.getCasPool(test.fakestoragepoolclaim)
// if err != nil || CasPool == nil {
// t.Errorf("Test case failed as expected nil error but error or CasPool object was nil:%s", name)
// }
// })
// }
//}
Loading