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

add cspc-operator #1

Merged

Conversation

sonasingh46
Copy link
Contributor

@sonasingh46 sonasingh46 commented Feb 19, 2020

This PR adds cspc-operator.
Following are pending items :

  1. Add cspi operator

NOTES: The Second commit contains the vendor code.
Signed-off-by: Ashutosh Kumar [email protected]

@sonasingh46 sonasingh46 force-pushed the cspc-operator-patch1 branch 4 times, most recently from 7a08de6 to 22271a3 Compare February 19, 2020 12:27
Copy link
Contributor

@mittachaitu mittachaitu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will continue reviewing tomorrow...

cspc-operator/app/start.go Outdated Show resolved Hide resolved
cspc-operator/app/start.go Outdated Show resolved Hide resolved
cspc-operator/examples/crds/cspccrd.yaml Outdated Show resolved Hide resolved
cspc-operator/examples/crds/cspicrd.yaml Outdated Show resolved Hide resolved
pkg/controllers/cspc-controller/controller.go Outdated Show resolved Hide resolved
pkg/cspc/algorithm/select_node.go Show resolved Hide resolved
pkg/cspc/algorithm/build_csp.go Outdated Show resolved Hide resolved
WithName(ac.CSPC.Name + "-" + rand.String(4)).
WithNamespace(ac.Namespace).
WithNodeSelectorByReference(poolSpec.NodeSelector).
WithNodeName(nodeName).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is saying WithNodeName but it is really setting HostName.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WithNodeSelectorByReference(poolSpec.NodeSelector).
WithNodeName(nodeName).
WithPoolConfig(poolSpec.PoolConfig).
WithRaidGroups(poolSpec.DataRaidGroups).
Copy link
Contributor

@mittachaitu mittachaitu Feb 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We missed poolSpec.WriteCacheRaidGroups?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WriteCache things will be taken in a separate PR.

for _, bd := range group.BlockDevices {
BDList = append(BDList, bd.BlockDeviceName)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here also we missed iterating over WriteCacheRaidGroups.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WriteCache things will be taken in a separate PR.

pkg/controllers/cspc-controller/scale.go Outdated Show resolved Hide resolved

const (
// StoragePoolKindCSPC holds the value of CStorPoolCluster
StoragePoolKindCSPC = "CStorPoolCluster"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about moving them to openebs/api/pkg/apis/types?

}

// GetBDListForNode returns a list of BD from the pool spec.
func GetBDListForNode(pool cstor.PoolSpec) []string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about moving to API repo because it looks like tightly coupled with PoolSpec. IMO looks like a getter method from the spec.

pkg/cspc/algorithm/build_deploy.go Outdated Show resolved Hide resolved
klog.Errorf("could not use node for selectors {%v}", pool.NodeSelector)
continue
}
if ac.VisitedNodes[nodeName] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ac.VisitedNodes[nodeName] will be always false because we are initializing Config inside loop

for poolCount := 1; poolCount <= pendingPoolCount; poolCount++ {
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed this.

return nil
}

// getOrphanedCStorPools returns a list of CSPI names that should be deleted.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getOrphanedCStorPools need to revisit when the migration of pools from one node to another node when the same data disks were attached to other nodes.

c.recorder.Event(cspc, corev1.EventTypeNormal,
"DownScale", "De-provisioning pool "+cspiName)

// TODO : As part of deleting a CSP, do we need to delete associated BDCs ?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove TODO because of cleanupCSPIResources is doing a cleanup work of CSPI.

Signed-off-by: Ashutosh Kumar <[email protected]>
Signed-off-by: Ashutosh Kumar <[email protected]>
return newNodeList
}

func NewFixture() *fixture {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change this to the package scope? IMO outside the package, no one should see the test code.

return nil, errors.Errorf("failed to select a node as empty node name received from SelectNode")
}

// ToDo: Move following to mutating webhook.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we really need to move to mutate webhooks?
cc: @prateekpandey14

// If multiple controllers happen to call this AddToScheme same time,
// it causes panic with error saying concurrent map access.
// This lock is used to serialize the AddToScheme call of all controllers.
//controllerMtx.Lock()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this lock is really required?

return cb.Controller, nil
}

// addSpc is the add event handler for cspc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addSpc --> addCSPC

pkg/controllers/cspc-controller/controller.go Show resolved Hide resolved
Copy link
Contributor

@mittachaitu mittachaitu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good to go for merging to unblock other PRs(Volume replated PRs). But I will be reviewing after merging also.

Ashutosh Kumar added 2 commits February 28, 2020 16:10
Signed-off-by: Ashutosh Kumar <[email protected]>
This commit removes some of the maya dependencies

Signed-off-by: Ashutosh Kumar <[email protected]>
// EstimateCSPCVersion returns the cspi version if any cspi is present for the cspc or
// returns the maya version as the new cspi created will be of maya version
func (c *Controller) EstimateCSPCVersion(cspc *cstor.CStorPoolCluster) (string, error) {
cspiList, err := c.clientset.CstorV1().
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we can use c.GetCSPIListForCSPC(cspcObj)

func NewBuilder() *Builder {
return &Builder{
ConfigObj: &Config{
CSPC: &cstor.CStorPoolCluster{},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to allocated unnecessary memory(to be safe from crashes)? IMO caller should use WithCSPC func.

pc := NewPoolConfig().WithAlgorithmConfig(ac).WithController(c)

// Create pools if required.
if len(cspiList.Items) < len(cspc.Spec.Pools) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here chances are there to crash because caller code didn't handle error case when cspiList API call failed.


// Deep-copy otherwise we are mutating our cache.
cspcGot := cspc.DeepCopy()
cspiList, _ := c.GetCSPIListForCSPC(cspcGot)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If an error occurs we should log and return from here else if sync() is making use of cspiList chances will be there for process crash.

// If the block device(s) is/are already calimed for the same CSPC -- it is left as it is and can be used for
// pool provisioning.
// If the block device(s) is/are unclaimed, then those are claimed.
func (ac *Config) ClaimBDsForNode(BD []string) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change BD ---> bdNameList?

var err error
for _, cspcRaidGroup := range cspcPoolSpec.DataRaidGroups {
cspcRaidGroup := cspcRaidGroup
cspiRaidGroup := getReplacedCSPIRaidGroup(&cspcRaidGroup, cspi)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This piece of code needs to be updated properly may be in subsequent PR's for code readability purpose

	raidGroupIndex, cspiRaidGroup := getReplacedCSPIRaidGroup(&cspcRaidGroup, cspi)
       if raidGroupIndex != -1 {
            replacedRaidGroup, err := pc.getReplaceRaidGroup(cspcRaidGroup, cspiRaidGroup)
            if err != nil {
               // RETUR error
           }
             cspi.Spec.RaidGroup[raidGroupIndex] = replacedRaidGroup

       }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example please....

}

// replaceBlockDevice replaces block devices in cStor pools as specified in CSPC.
func (pc *PoolConfig) replaceBlockDevice() error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Events need to be added

pool-manager/app/start.go Outdated Show resolved Hide resolved
// CheckForZreplInitial is blocking call for checking status of zrepl in cstor-pool container.
func CheckForZreplInitial(ZreplRetryInterval time.Duration) {
for {
_, err := RunnerVar.RunCombinedOutput(zpool.PoolOperator, "status")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: We can use a builder pattern to execute zpool & zfs commands.

return err
}

if IsReconcileDisabled(cspi) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have cspi as a receiver type?

name: cspi-stripe
namespace: openebs
spec:
pools:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CStorPoolInstance spec does not have pools field and each CSPI will have only one pool spec. Please update the yaml with correct fields.

name: cspi-stripe-1
namespace: openebs
spec:
pools:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above.

Copy link
Contributor

@mittachaitu mittachaitu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes are good didn't go through all the builders of ZFS & ZPOOL.....

}

// addPoolProtectionFinalizer is to add PoolProtectionFinalizer finalizer of cstorpoolinstance resource.
func (c *CStorPoolInstanceController) addPoolProtectionFinalizer(cspi *cstor.CStorPoolInstance) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we should return the updated object...

"k8s.io/klog"
)

// Import will import pool for given CSP object.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given CSPI object.

return false, err
}

klog.Infof("Importing pool %s %s", string(cspi.GetUID()), PoolName(cspi))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change PoolName(cspi) ---> cspi.GetPoolName()?

klog.Errorf("Failed to import pool : %s : %s", cmdOut, err.Error())
return false, err
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here If the pool is imported we have to set the value of common.SyncResources.IsImported = true

return usedPath, nil
}

if len(oldPaths) == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Existing code comments: comments required saying specifcally for pool expansion case.

// If raidGroup doesn't have any blockdevice then remove that raidGroup
// and set isObjChanged
if isRaidGroupChanged {
if len(raidGroup.BlockDevices) == 0 {
Copy link
Contributor

@mittachaitu mittachaitu Mar 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why raidGroup exists without blockdevices? Are there any such cases? Are we are supporting removing devices from raidGroups?

status.Phase = cstor.CStorPoolInstancePhase(state)
}

freeSize, er := zpool.GetPoolCapacity(pool, "free")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO: Instead of making multiple calls to zfs good to get all the details in one call.


devID := pool.GetDevPathIfNotSlashDev(bdPath[0])
if len(devID) != 0 {
cmdOut, err = zfs.NewPoolImport().WithDirectory(devID).Execute()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it good to log the error message?

@@ -0,0 +1,36 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO better to have this in openebs/api/pkg/util/hash.go repo ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other way is i am going to raise a PR in api repo and we can import this later as well.

@@ -0,0 +1,271 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can name it to pkg/controller-utils as its a generics things can be used by cvr and cv controllers ? or have it inside controllers dir i.e. pkg/controllers/utils

Signed-off-by: Ashutosh Kumar <[email protected]>
@sonasingh46
Copy link
Contributor Author

I have incorporated some review comments. Few will be incorporated in the next PR.

Signed-off-by: Ashutosh Kumar <[email protected]>
Copy link
Contributor

@prateekpandey14 prateekpandey14 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm , further changes will taken up in upcoming PR's

@prateekpandey14 prateekpandey14 merged commit aa7353d into openebs-archive:master Mar 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants