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

(WIP)feat(BDD): add positive BDD to perform CStorVolumeReplica ScaleUp/ScaleDown #1617

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ ifeq (${IMAGE_TAG}, )
export IMAGE_TAG
endif

ifeq (${DEBUG_IMAGE_TAG}, )
DEBUG_IMAGE_TAG = inject-ci
export DEBUG_IMAGE_TAG
endif

ifeq (${TRAVIS_TAG}, )
BASE_TAG = ci
export BASE_TAG
Expand Down
11 changes: 10 additions & 1 deletion buildscripts/cvc-operator/Makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,13 @@ cvc-operator-image.arm64:
@cd buildscripts/${CVC_OPERATOR} && sudo docker build -t ${HUB_USER}/${CSTOR_VOLUME_MGMT_REPO_NAME_ARM64}:${IMAGE_TAG} -f Dockerfile.arm64 --build-arg BUILD_DATE=${BUILD_DATE} .
@rm buildscripts/${CVC_OPERATOR}/${CVC_OPERATOR}


.PHONY: cvc-operator-debug-image
cvc-operator-debug-image:
@echo "----------------------------"
@echo -n "--> cvc-operator-debug image "
@echo "${HUB_USER}/${CVC_OPERATOR_REPO_NAME}:${DEBUG_IMAGE_TAG}"
@echo "----------------------------"
@PNAME=${CVC_OPERATOR} CTLNAME=${CVC_OPERATOR} BUILD_TAG="-tags=debug" sh -c "'$(PWD)/buildscripts/build.sh'"
@cp bin/${CVC_OPERATOR}/${CVC_OPERATOR} buildscripts/cvc-operator/
@cd buildscripts/${CVC_OPERATOR} && sudo docker build -t ${HUB_USER}/${CVC_OPERATOR_REPO_NAME}:${DEBUG_IMAGE_TAG} --build-arg BUILD_DATE=${BUILD_DATE} .
@rm buildscripts/${CVC_OPERATOR}/${CVC_OPERATOR}
5 changes: 5 additions & 0 deletions cmd/cvc-operator/controller/controller_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
informers "github.com/openebs/maya/pkg/client/generated/informers/externalversions"
listers "github.com/openebs/maya/pkg/client/generated/listers/openebs.io/v1alpha1"
ndmclientset "github.com/openebs/maya/pkg/client/generated/openebs.io/ndm/v1alpha1/clientset/internalclientset"
"github.com/openebs/maya/pkg/debug"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
Expand Down Expand Up @@ -246,6 +247,10 @@ func (c *CVCController) Run(threadiness int, stopCh <-chan struct{}) {
defer runtime.HandleCrash()
defer c.workqueue.ShutDown()

// Start server only in debug build
debug.LogBuildDetails()
debug.StartInjectionServer()

// Start the informer factories to begin populating the informer caches
klog.Info("Starting CstorVolumeClaim controller")

Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/openebs.io/v1alpha1/cstor_volume_claim.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ type CStorVolumeClaimStatus struct {
// Capacity the actual resources of the underlying volume.
Capacity corev1.ResourceList `json:"capacity,omitempty"`
Conditions []CStorVolumeClaimCondition `json:"condition,omitempty"`
// PoolInfo represents current pool names where volume replicas exists
PoolInfo []string `json:"poolInfo"`
}

// CStorVolumeClaimCondition contains details about state of cstor volume
Expand Down
16 changes: 16 additions & 0 deletions pkg/apis/openebs.io/v1alpha1/cstorvolume_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ type CStorVolumePolicySpec struct {
Target TargetSpec `json:"target"`
// ReplicaSpec represents configuration related to replicas resources
Replica ReplicaSpec `json:"replica"`
// ReplicaPool holds the pool information of volume replicas.
// Ex: If volume is provisioned on which CStor pool volume replicas exist
ReplicaPool ReplicaPoolSpec `json:"replicaPool"`
}

// TargetSpec represents configuration related to cstor target and its resources
Expand Down Expand Up @@ -95,13 +98,26 @@ type ReplicaSpec struct {
Affinity *corev1.PodAffinity `json:"affinity"`
}

// ReplicaPoolSpec represents the volume replicas pool information
type ReplicaPoolSpec struct {
// PoolInfo represents the pool information of replicas
PoolInfo []ReplicaPoolInfo `json:"poolInfo"`
}

// Provision represents volume provisioning configuration
type Provision struct {
// replicaAffinity is set to true then volume replica resources need to be
// distributed across the cstor pool instances based on the given topology
ReplicaAffinity bool `json:"replicaAffinity"`
}

// ReplicaPoolInfo represents the pool information of volume replica
type ReplicaPoolInfo struct {
// PoolName represents the pool name where volume replica exists
PoolName string `json:"poolName"`
// TODO: UID also can be added
}

// CStorVolumePolicyStatus is for handling status of CstorVolumePolicy
type CStorVolumePolicyStatus struct {
Phase string `json:"phase"`
Expand Down
43 changes: 43 additions & 0 deletions pkg/apis/openebs.io/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 39 additions & 1 deletion pkg/blockdevice/v1alpha2/blockdevice.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func IsSparse() Predicate {

// IsSparse returns true if the block device is of sparse type
func (bd *BlockDevice) IsSparse() bool {
return bd.Object.Spec.Details.DeviceType == string(apis.TypeBlockDeviceCPV)
return bd.Object.Spec.Details.DeviceType == string(apis.TypeSparseCPV)
}

// IsActive filters the block device based on the active status
Expand Down Expand Up @@ -329,3 +329,41 @@ func (bd *BlockDevice) GetPath() string {
func (l *BlockDeviceList) Len() int {
return len(l.ObjectList.Items)
}

// IsNonFSType filters the blockdeive based on empty file system
func IsNonFSType() Predicate {
return func(bd *BlockDevice) bool {
return bd.IsNonFSType()
}
}

// IsNonFSType returns true if blockdevice filesystem type is empty
func (bd *BlockDevice) IsNonFSType() bool {
return bd.Object.Spec.FileSystem.Type == ""
}

// IsClaimStateMatched filters the blockdeive based on provided
// claim type
func IsClaimStateMatched(claimType ndm.DeviceClaimState) Predicate {
return func(bd *BlockDevice) bool {
return bd.IsClaimStateMatched(claimType)
}
}

// IsClaimStateMatched return true if blockdeive claim state
// matches to provided claim type
func (bd *BlockDevice) IsClaimStateMatched(claimType ndm.DeviceClaimState) bool {
return bd.Object.Status.ClaimState == claimType
}

// NodeBlockDeviceTopology froms map of node name and blockdevices present in
// that node
func (l *BlockDeviceList) NodeBlockDeviceTopology() map[string][]string {
nodeBlockDevices := map[string][]string{}
for _, bdObj := range l.ObjectList.Items {
bdObj := bdObj
hostName := bdObj.GetLabels()[string(apis.HostNameCPK)]
nodeBlockDevices[hostName] = append(nodeBlockDevices[hostName], bdObj.Name)
}
return nodeBlockDevices
}
3 changes: 2 additions & 1 deletion pkg/cstor/poolcluster/v1alpha1/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ limitations under the License.
package v1alpha1

import (
"github.com/openebs/maya/pkg/debug"
"strings"

"github.com/openebs/maya/pkg/debug"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

kclient "github.com/openebs/maya/pkg/kubernetes/client/v1alpha1"
Expand Down
39 changes: 39 additions & 0 deletions pkg/cstorvolumeclaim/v1alpha1/cstor_volume_claim.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,42 @@ func NewForAPIObject(obj *apis.CStorVolumeClaim) *CStorVolumeClaim {
object: obj,
}
}

// IsCVCBounded returns true only if cvc is in bound state
func (cvc *CStorVolumeClaim) IsCVCBounded() bool {
return cvc.object.Status.Phase == apis.CStorVolumeClaimPhaseBound
}

// IsCVCBounded is a predicate to filter out cstorvolumeclaims based on bound
// state
func IsCVCBounded() Predicate {
return func(cvc *CStorVolumeClaim) bool {
return cvc.IsCVCBounded()
}
}

// IsCVCPending returns true only if cvc is in pending state
func (cvc *CStorVolumeClaim) IsCVCPending() bool {
return cvc.object.Status.Phase == apis.CStorVolumeClaimPhasePending
}

// IsCVCPending is a predicate to filter out cstorvolumeclaims based on pending state
func IsCVCPending() Predicate {
return func(cvc *CStorVolumeClaim) bool {
return cvc.IsCVCPending()
}
}

// HasAnnotation returns true only if cvc annotation has volume name matching to
// provided arguments
func (cvc *CStorVolumeClaim) HasAnnotation(key, value string) bool {
return cvc.object.GetAnnotations()[key] == value
}

// HasAnnotation is a predicate to filter out cstorvolumeclaims based on
// annotaion values
func HasAnnotation(key, value string) Predicate {
return func(cvc *CStorVolumeClaim) bool {
return cvc.HasAnnotation(key, value)
}
}
32 changes: 32 additions & 0 deletions pkg/debug/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,3 +334,35 @@ func (ei *ErrorInjection) IsCVRGetErrorInjected() bool {
func (ei *ErrorInjection) IsCVRUpdateErrorInjected() bool {
return false
}

// IsPDBCreateErrorInjected returns true if error is injected for PDB create command
func (ei *ErrorInjection) IsPDBCreateErrorInjected() bool {
if ei.PDBError.CRUDErrorInjection.InjectCreateError == Inject {
return true
}
return false
}

// IsPDBDeleteErrorInjected returns true if error is injected for PDB delete command
func (ei *ErrorInjection) IsPDBDeleteErrorInjected() bool {
if ei.PDBError.CRUDErrorInjection.InjectDeleteError == Inject {
return true
}
return false
}

// IsPDBGetErrorInjected returns true if error is injected for PDB get command
func (ei *ErrorInjection) IsPDBGetErrorInjected() bool {
if ei.PDBError.CRUDErrorInjection.InjectGetError == Inject {
return true
}
return false
}

// IsPDBListErrorInjected returns true if error is injected for PDB list command
func (ei *ErrorInjection) IsPDBListErrorInjected() bool {
if ei.PDBError.CRUDErrorInjection.InjectListError == Inject {
return true
}
return false
}
24 changes: 24 additions & 0 deletions pkg/debug/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,27 @@ func (ei *ErrorInjection) IsCVRGetErrorInjected() bool {
func (ei *ErrorInjection) IsCVRUpdateErrorInjected() bool {
return false
}

// IsPDBCreateErrorInjected is production alternative for the same function that
// exists in debug build
func (ei *ErrorInjection) IsPDBCreateErrorInjected() bool {
return false
}

// IsPDBDeleteErrorInjected is production alternative for the same function that
// exists in debug build
func (ei *ErrorInjection) IsPDBDeleteErrorInjected() bool {
return false
}

// IsPDBGetErrorInjected is production alternative for the same function that
// exists in debug build
func (ei *ErrorInjection) IsPDBGetErrorInjected() bool {
return false
}

// IsPDBListErrorInjected is production alternative for the same function that
// exists in debug build
func (ei *ErrorInjection) IsPDBListErrorInjected() bool {
return false
}
25 changes: 25 additions & 0 deletions pkg/debug/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type ErrorInjection struct {
DeploymentError DeploymentErrorInjection `json:"deploymentError"`
ZFSError ZFSErrorInjection `json:"zfsError"`
CVRError CVRErrorInjection `json:"cvrError"`
PDBError PDBErrorInjection `json:"pdbError"`
}

// CSPIErrorInjection is used to inject errors for CSPI related operations.
Expand Down Expand Up @@ -80,6 +81,12 @@ type CVRErrorInjection struct {
ErrorPercentage ErrorPercentageThreshold `json:"errorPercentage"`
}

// PDBErrorInjection is used to inject errors for PDB related operations.
type PDBErrorInjection struct {
CRUDErrorInjection CRUDErrorInjection `json:"crudErrorInjection"`
ErrorPercentage ErrorPercentageThreshold `json:"errorPercentage"`
}

// CRUDErrorInjection is used to inject CRUD errors.
type CRUDErrorInjection struct {
InjectDeleteCollectionError string `json:"injectDeleteCollectionError"`
Expand Down Expand Up @@ -345,3 +352,21 @@ func (ei *ErrorInjection) WithCVRUpdateError(ejectOrInject string) *ErrorInjecti
ei.CVRError.CRUDErrorInjection.InjectUpdateError = ejectOrInject
return ei
}

// WithPDBCreateError injects/ejects PDB create error.
func (ei *ErrorInjection) WithPDBCreateError(ejectOrInject string) *ErrorInjection {
ei.PDBError.CRUDErrorInjection.InjectCreateError = ejectOrInject
return ei
}

// WithPDBDeleteError injects/ejects PDB deletes error.
func (ei *ErrorInjection) WithPDBDeleteError(ejectOrInject string) *ErrorInjection {
ei.PDBError.CRUDErrorInjection.InjectDeleteError = ejectOrInject
return ei
}

// WithPDBListError injects/ejects PDB list error.
func (ei *ErrorInjection) WithPDBListError(ejectOrInject string) *ErrorInjection {
ei.PDBError.CRUDErrorInjection.InjectListError = ejectOrInject
return ei
}
Loading