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: cleanup lvm resources on delete #146

Merged
merged 1 commit into from
Apr 13, 2022
Merged

feat: cleanup lvm resources on delete #146

merged 1 commit into from
Apr 13, 2022

Conversation

nbalacha
Copy link
Contributor

@nbalacha nbalacha commented Apr 6, 2022

The vgmanager will now remove the vg and the lvmd.conf
file when the LVMCluster is deleted.

Signed-off-by: N Balachandran [email protected]

@openshift-ci openshift-ci bot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Apr 6, 2022
// Has the VG been cleaned up on all hosts?
exists, _ := doesVGExistOnHosts(ctx, existingLvmVg.Name, lvmCluster)
if !exists {
//remove finalizer
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
//remove finalizer
// remove finalizer

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

r.Log.Info("failed to remove finalizer from LvmCluster")
return reconcile.Result{}, err
}
//Check for existing LogicalVolumes
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
//Check for existing LogicalVolumes
// Check for existing LogicalVolumes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

//Check for existing LogicalVolumes
lvsExist, err := r.logicalVolumesExist(ctx, instance)
if err != nil {
r.Log.Error(err, "failed to get LogicalVolumeList")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
r.Log.Error(err, "failed to get LogicalVolumeList")
r.Log.Error(err, "failed to check if logicalVolumes exist")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

//Check for existing LogicalVolumes
lvsExist, err := r.logicalVolumesExist(ctx, instance)
if err != nil {
r.Log.Error(err, "failed to get LogicalVolumeList")
Copy link
Contributor

Choose a reason for hiding this comment

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

return this error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

@leelavg leelavg left a comment

Choose a reason for hiding this comment

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

  • there are some commented out log lines, can those be removed?

@@ -27,7 +28,8 @@ import (
)

const (
lvmVGName = "lvmvg-manager"
lvmVGName = "lvmvg-manager"
lvmvgFinalizer = "lvm.openshift.com/volumegroup"
Copy link
Contributor

Choose a reason for hiding this comment

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

  • minor: i think openshift.io is used more often

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -115,14 +118,15 @@ func (r *LVMClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request)
result, reconcileError := r.reconcile(ctx, lvmCluster)

statusError := r.updateLVMClusterStatus(ctx, lvmCluster)
if statusError != nil {
/* if statusError != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

commented out block can be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done


logicalVolumeList := &topolvmv1.LogicalVolumeList{}

if err := r.Client.List(ctx, logicalVolumeList); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if err := r.Client.List(ctx, logicalVolumeList); err != nil {
if err := r.Client.List(ctx, logicalVolumeList, &client.ListOptions{Limit: int64(1)}); err != nil {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What is the advantage of this?

Copy link
Contributor

Choose a reason for hiding this comment

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

  • we are checking the existence of logicalvolume crs so why not limit the request to list only one item

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does it make any difference from a performance point of view?

Copy link
Contributor

Choose a reason for hiding this comment

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

Afaik, yes as the underlying rest call will be paginated.

Copy link
Contributor

Choose a reason for hiding this comment

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

  • leaving this then, even though we might be reading from cache I think limiting entries doesn't harm anything for the operation that we are doing in this func

r.Log.Error(statuserr, "failed to update status", "VGName", volumeGroup.Name)
return reconcileAgain, nil
Copy link
Contributor

Choose a reason for hiding this comment

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

  • shouldn't nil be statuserr here?
  • same comment in this file

@@ -208,11 +216,11 @@ func (r *VGReconciler) reconcile(ctx context.Context, req ctrl.Request, volumeGr
r.Log.Info("updated lvmd config", "VGName", volumeGroup.Name)
}

volGrpHostInfo, err := GetVolumeGroup(r.executor, volumeGroup.Name)
// volGrpHostInfo, err := GetVolumeGroup(r.executor, volumeGroup.Name)
Copy link
Contributor

Choose a reason for hiding this comment

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

  • this wasn't being used even before this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed.

return vgNodeStatus, nil
}

func (r *VGReconciler) updateStatus(ctx context.Context, lvmdConfig *lvmdCMD.Config) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

  • I don't see lvmdConfig is being used directly in this func or other funcs being called in this func
  • If it's intentional we don't need this param at all?
  • I was thinking this can be used to filter the vgs that lvmo is managing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had initially iterated over the entries in lvmconf to get the VGs but moved directly to querying the VGs from the host.( when I asked about tagging the lvm objects the LVMO created) . I forgot to remove the argument.
I dropped the idea of using the lvmdconfig to get the list of VGs because that may not be consistent (in case writing to the file failed).

Copy link
Contributor

Choose a reason for hiding this comment

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

ack, makes sense, we can use tags then if that's still an options, maybe in another pr.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the function signatures.

if err != nil {
r.Log.Error(err, "failed to create or update lvmvolumegroupnodestatus", "name", vgNodeStatus.Name)
return err
} else if result != controllerutil.OperationResultNone {
Copy link
Contributor

Choose a reason for hiding this comment

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

any reason for not checking against OperationResultUpdated

Copy link
Contributor Author

Choose a reason for hiding this comment

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

result != controllerutil.OperationResultNone means the object was either created or modified. IMO, there is no need to check in greater detail.

Copy link
Contributor

Choose a reason for hiding this comment

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

ack, I read the log lvmvolumegroupnodestatus modified and thought this condition is checking solely the modification.

Comment on lines 265 to 258
if err != ErrVolumeGroupNotFound {
return fmt.Errorf("failed to get volume group. %v, %v", volumeGroup.Name, err)
}
return nil
Copy link
Contributor

Choose a reason for hiding this comment

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

  • why can't directly return err?
  • if not above, why return nil in line 268?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • why can't directly return err?
    There would not be a log message then.
  • if not above, why return nil in line 268?
    If the error is ErrVolumeGroupNotFound , there is nothing more to be done.

Copy link
Contributor

Choose a reason for hiding this comment

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

ErrVolumeGroupNotFound , there is nothing more to be done.

  • ya, missed this detail

@@ -108,6 +108,12 @@ var reconcileAgain ctrl.Result = ctrl.Result{Requeue: true, RequeueAfter: reconc

func (r *VGReconciler) reconcile(ctx context.Context, req ctrl.Request, volumeGroup *lvmv1alpha1.LVMVolumeGroup) (ctrl.Result, error) {

//The LVMVolumeGroup resource was deleted
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
//The LVMVolumeGroup resource was deleted
// The LVMVolumeGroup resource was deleted

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

@@ -226,6 +234,71 @@ func (r *VGReconciler) reconcile(ctx context.Context, req ctrl.Request, volumeGr
return ctrl.Result{RequeueAfter: requeueAfter}, nil
}

func (r *VGReconciler) processDelete(ctx context.Context, volumeGroup *lvmv1alpha1.LVMVolumeGroup) error {

//Read the lvmd config file
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
//Read the lvmd config file
// Read the lvmd config file

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done


err = vg.Delete(r.executor)
if err != nil {
return fmt.Errorf("failed to delete volume group. %v, %v", volumeGroup.Name, err)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return fmt.Errorf("failed to delete volume group. %v, %v", volumeGroup.Name, err)
return fmt.Errorf("failed to delete volume group %q. %v", volumeGroup.Name, err)

@@ -113,3 +136,14 @@ func (c lvmVG) getLvmVolumeGroups(r *LVMClusterReconciler, instance *lvmv1alpha1
}
return lvmVolumeGroups
}

func doesVGExistOnHosts(ctx context.Context, volumeGroup string, instance *lvmv1alpha1.LVMCluster) (bool, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

  • it seems error is always nil and can be removed
  • not a time limited func so ctx can be removed as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed error.


dcStatuses := instance.Status.DeviceClassStatuses
for _, dc := range dcStatuses {
if dc.Name == volumeGroup {
Copy link
Contributor

Choose a reason for hiding this comment

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

  • only for my understanding, we are finding whether VG exists or not by means of status of lvmcluster cr which inturn gets the info from groupnodestatus cr right?
  • is it possible to club volumegroup and groupnodestatus crd? (if past discussions were a no, then nntr)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • only for my understanding, we are finding whether VG exists or not by means of status of lvmcluster cr which inturn gets the info from groupnodestatus cr right?
    Correct
  • is it possible to club volumegroup and groupnodestatus crd? (if past discussions were a no, then nntr)
    Can you elaborate?

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you elaborate?

  • not related to this PR, can be taken up separately
  • in this single function either directly or indirectly we are using all the three CRs with some duplicate info, even though we discussed in length about the current state, if possible we want to re-look in reducing the duplicate info there by reducing num of CRs


logicalVolumeList := &topolvmv1.LogicalVolumeList{}

if err := r.Client.List(ctx, logicalVolumeList); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

  • we are checking the existence of logicalvolume crs so why not limit the request to list only one item

@nbalacha nbalacha changed the title [WIP] feat: cleanup lvm resources on delete feat: cleanup lvm resources on delete Apr 12, 2022
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 12, 2022
This commit cleans up the LVM resources created by the vgmanager
when the LVMCluster is deleted. All PVCs provisioned by topolvm
must be deleted before the LVMCluster is deleted. The LVMCluster
controller will wait until there are no existing LogicalVolumes before
it proceeds to remove the resources.
When the LVMCluster is deleted, the LVMCluster controller deletes the
LVMVolumeGroup resource. The resource is not removed immediately because
of the finalizer. The vg-manager deletes the vg on the host and updates
the LVMVolumeGroupNodeStatus, which triggers the LVMCluster
reconciliation to update the status. When the VG is removed from the
LVMCluster.status, the LVMCluster controller removes the finalizer on
the LVMVolumeGroup.

Signed-off-by: N Balachandran <[email protected]>
Copy link
Contributor

@leelavg leelavg left a comment

Choose a reason for hiding this comment

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

/lgtm


dcStatuses := instance.Status.DeviceClassStatuses
for _, dc := range dcStatuses {
if dc.Name == volumeGroup {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you elaborate?

  • not related to this PR, can be taken up separately
  • in this single function either directly or indirectly we are using all the three CRs with some duplicate info, even though we discussed in length about the current state, if possible we want to re-look in reducing the duplicate info there by reducing num of CRs


logicalVolumeList := &topolvmv1.LogicalVolumeList{}

if err := r.Client.List(ctx, logicalVolumeList); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

  • leaving this then, even though we might be reading from cache I think limiting entries doesn't harm anything for the operation that we are doing in this func

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Apr 13, 2022
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Apr 13, 2022

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: leelavg, nbalacha

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-robot openshift-merge-robot merged commit 2366c24 into openshift:main Apr 13, 2022

// Reconcile errors have higher priority than status update errors
if reconcileError != nil {
return result, reconcileError
} else if statusError != nil && errors.IsNotFound(statusError) {
} else if statusError != nil && !errors.IsNotFound(statusError) {

Choose a reason for hiding this comment

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

Do we don't need to return errors in the case of NotFound scenarios now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this was originally a mistake (as Nitin pointed out).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants