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

controller: add PersistentVolumeClaimController #93

Merged
merged 1 commit into from
Jan 21, 2022

Conversation

Rakshith-R
Copy link
Member

This controller watches for annotation on PVC,
if matches with reclaimspace.csiaddons.openshift.io/schedule
which can specify a schedule, a reclaimspace cron job cr
is created for that PVC witha generated name having pvc-name
as prefix.

Signed-off-by: Rakshith R [email protected]

[open to changing name of controller 😉 ]

Reconciles only if create or update happens to `reclaimspace.csiaddons.openshift.io/schedule: "@everyday"` annotation

steps: 
- delete all old child jobs
- check annotation for schedule
- if not found, clear name annotation if it exists and  exit
- if found, continue
- generate unique name = pvc.name+time.Now().Unix()  (ex rbd-pvc-1642598479)
- construct rscronjob
- set controllerref, create rscronjob
- exit

@mergify mergify bot requested review from nixpanic, yati1998 and Yuggupta27 January 19, 2022 13:22
@Rakshith-R Rakshith-R requested a review from Madhu-1 January 19, 2022 13:23
@Rakshith-R
Copy link
Member Author

I'll add documentation for this by tomorrow.

Copy link
Collaborator

@nixpanic nixpanic left a comment

Choose a reason for hiding this comment

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

looks quite reasonable. Missing update to the documentation under doc/reclaimspace.md

controllers/persistentvolumeclaim_controller.go Outdated Show resolved Hide resolved
controllers/persistentvolumeclaim_controller.go Outdated Show resolved Hide resolved
controllers/persistentvolumeclaim_controller.go Outdated Show resolved Hide resolved
resources:
- persistentvolumeclaims
verbs:
- create
Copy link
Member

Choose a reason for hiding this comment

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

why create,delete and update permission is required?

Comment on lines 39 to 49
- persistentvolumeclaims/finalizers
verbs:
- update
- apiGroups:
- ""
resources:
- persistentvolumeclaims/status
verbs:
- get
- patch
- update
Copy link
Member

Choose a reason for hiding this comment

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

same here why this permission is required?


// SetupWithManager sets up the controller with the Manager.
func (r *PersistentVolumeClaimReconciler) SetupWithManager(mgr ctrl.Manager) error {
if err := mgr.GetFieldIndexer().IndexField(context.Background(), &csiaddonsv1alpha1.ReclaimSpaceCronJob{}, jobOwnerKey, func(rawObj client.Object) []string {
Copy link
Member

Choose a reason for hiding this comment

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

split this into multiple lines for better reading

Comment on lines 82 to 85
err = r.deleteChildCronJobs(ctx, &logger, &req)
if err != nil {
return ctrl.Result{}, err
}
Copy link
Member

Choose a reason for hiding this comment

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

one PVC will have only one Cron job why this is required?

Copy link
Member Author

Choose a reason for hiding this comment

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

one PVC will have only one Cron job why this is required?

yes, recreating Cron job each time simplifies the logic for a lot of scenarios.
This will also help in handling deletion when schedule is removed.

Copy link
Member

Choose a reason for hiding this comment

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

i still need to understand this one. what are childCronJobs referred here?

Copy link
Member Author

Choose a reason for hiding this comment

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

i still need to understand this one. what are childCronJobs referred here?

Just the cronjob created for this PVC previously.
Each reconcile will delete old cronjob and create new one with new name.
Using saved name led to lot of complexity.

Comment on lines 91 to 112
_, nameFound := annotations[rsCronJobNameAnnotation]
if nameFound {
delete(annotations, rsCronJobNameAnnotation)
pvc.SetAnnotations(annotations)
err = r.Client.Update(ctx, pvc)
if err != nil {
logger.Error(err, "Failed to update annotation")

return ctrl.Result{}, err
}
}
Copy link
Member

Choose a reason for hiding this comment

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

can you please explain a bit more why this block is required?

Copy link
Member Author

Choose a reason for hiding this comment

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

can you please explain a bit more why this block is required?

when schedule annotation is removed, we are checking if name annotation exists and removing it (since we added it).

Comment on lines 110 to 148
pvc.SetAnnotations(annotations)
err = r.Client.Update(ctx, pvc)
if err != nil {
logger.Error(err, "Failed to update annotation")

return ctrl.Result{}, err
}
Copy link
Member

Choose a reason for hiding this comment

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

set annotation only after creating the cronJob?

Copy link
Member Author

Choose a reason for hiding this comment

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

done

"testing"

csiaddonsv1alpha1 "github.com/csi-addons/kubernetes-csi-addons/api/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Copy link
Member

Choose a reason for hiding this comment

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

new line separation

@Madhu-1
Copy link
Member

Madhu-1 commented Jan 19, 2022

doc changes are required with examples/usage.

@Rakshith-R Rakshith-R force-pushed the Annotation-controller branch from befbf09 to be8eced Compare January 20, 2022 07:48
@Rakshith-R
Copy link
Member Author

Rakshith-R commented Jan 20, 2022

updated permissions, using patch, added doc and refactored the code
PTAL.
Thanks!

nixpanic
nixpanic previously approved these changes Jan 20, 2022
@humblec
Copy link

humblec commented Jan 20, 2022

if matches with reclaimspace.csiaddons.openshift.io/schedule
which can specify a schedule, a reclaimspace cron job cr
is created for that PVC witha generated name having pvc-name
as prefix.

What happens if the PVC get recreated with same name @Rakshith-R ?

Comment on lines 82 to 85
err = r.deleteChildCronJobs(ctx, &logger, &req)
if err != nil {
return ctrl.Result{}, err
}
Copy link
Member

Choose a reason for hiding this comment

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

i still need to understand this one. what are childCronJobs referred here?

}

annotations := pvc.GetAnnotations()
schedule, scheduleFound := getScheduleFromAnnotation(&logger, annotations)
Copy link
Member

Choose a reason for hiding this comment

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

one more question. if the annotations are found but the cronjob CR is not created are we going to recreate it with same name or a new one?

Copy link
Member Author

@Rakshith-R Rakshith-R Jan 20, 2022

Choose a reason for hiding this comment

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

one more question. if the annotations are found but the cronjob CR is not created are we going to recreate it with same name or a new one?

new name each time, using the same name causes pre-condition error since name/namespace remains same while uid changes for other controllers.

to PersistentVolumeClaim object.

```
$ kubectl get pvc pvc-1
Copy link
Member

Choose a reason for hiding this comment

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

use meaningful name instead of pvc-1, pvc-sample and pvc-1 names are not matching

$ kubectl annotate pvc pvc-sample "reclaimspace.csiaddons.openshift.io/schedule=@midnight"
persistentvolumeclaim/pvc-sample annotated

$ k get reclaimspacecronjobs.csiaddons.openshift.io
Copy link
Member

Choose a reason for hiding this comment

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

k get to kubectl get

$ kubectl annotate pvc pvc-sample "reclaimspace.csiaddons.openshift.io/schedule=*/1 * * * *" --overwrite=true
persistentvolumeclaim/pvc-sample annotated

$ k get reclaimspacecronjobs.csiaddons.openshift.io
Copy link
Member

Choose a reason for hiding this comment

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

k get to kubectl get

Copy link

@humblec humblec left a comment

Choose a reason for hiding this comment

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

any hiccups if the PVC get recreated with the same name?

@Rakshith-R
Copy link
Member Author

Rakshith-R commented Jan 20, 2022

any hiccups if the PVC get recreated with the same name?

Due to controllerOwnerRef, previous child cronjobs will get deleted

@Rakshith-R Rakshith-R force-pushed the Annotation-controller branch 2 times, most recently from 220258c to 3e71ef7 Compare January 20, 2022 14:11
@mergify mergify bot dismissed nixpanic’s stale review January 20, 2022 14:11

Pull request has been modified.

Copy link

@pkalever pkalever left a comment

Choose a reason for hiding this comment

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

I don't have a better naming suggestion at the moment but PersistentVolumeClaimController doesn't sound great.

}

// create cronjob name
rsCronJobName := fmt.Sprintf("%s-%v", pvc.Name, time.Now().Unix())

Choose a reason for hiding this comment

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

This can be moved into a new function getCronJobName()?

Copy link
Member Author

Choose a reason for hiding this comment

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

This can be moved into a new function getCronJobName()?

done, names it generateCronJobName()

Choose a reason for hiding this comment

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

Well you forget to use it :-)

Copy link
Member Author

Choose a reason for hiding this comment

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

🤣 its used now,

}

// add cronjob name in annotations.
patch := []byte(fmt.Sprintf(`{"metadata":{"annotations":{%q:%q}}}`, rsCronJobNameAnnotation, rsCronJobName))

Choose a reason for hiding this comment

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

may be name it annotations instead of patch?

Copy link
Member Author

Choose a reason for hiding this comment

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

may be name it annotations instead of patch?

annotations is already taken, just patch sounds fine to me

return ctrl.Result{}, err
}

logger.Info("Successfully created reclaimSpaceCronJob")

Choose a reason for hiding this comment

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

new line before return?

}
// reconcile only if schedule annotation is found.
_, ok := e.Object.GetAnnotations()[rsCronJobScheduleTimeAnnotation]
return ok

Choose a reason for hiding this comment

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

new line here too!

// reconcile only if schedule annotation between old and new objects have changed.
oldSchdeule, oldOk := e.ObjectOld.GetAnnotations()[rsCronJobScheduleTimeAnnotation]
newSchdeule, newOk := e.ObjectNew.GetAnnotations()[rsCronJobScheduleTimeAnnotation]
return oldOk != newOk || oldSchdeule != newSchdeule

Choose a reason for hiding this comment

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

new line here too!


return defaultSchedule, true
}
return schedule, true

Choose a reason for hiding this comment

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

new line

}
_, err := cron.ParseStandard(schedule)
if err != nil {
logger.Info(fmt.Sprintf("Parsing given schedule %q failed, using default schedule %q",

Choose a reason for hiding this comment

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

Sounds like logger.Warning?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sounds like logger.Warning?

Should be fine for now, there is no default logger.Warning,
We may add it the future.

// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
// This is triggered when `reclaimspace.csiaddons.openshift/schedule` annotation
// is found on newly created PVC or if there is a change in valude of the annotation.

Choose a reason for hiding this comment

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

s/valude/value

Copy link
Member Author

Choose a reason for hiding this comment

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

done @pkalever PTAL

@Rakshith-R Rakshith-R force-pushed the Annotation-controller branch from 3e71ef7 to 2612f1c Compare January 20, 2022 15:23
@Rakshith-R
Copy link
Member Author

I don't have a better naming suggestion at the moment but PersistentVolumeClaimController doesn't sound great.

😆 me too, check the pr description.

We can always come back and change it, this is completely internal.
I dont any reason to block this pr for that reason.
(needs to get merged by tomorrow)

Copy link

@pkalever pkalever left a comment

Choose a reason for hiding this comment

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

Well, I didn't block this PR for the naming part, but for the rest of the comments.

You have one more to take care of for now i.e use generateCronJobName

@Rakshith-R Rakshith-R force-pushed the Annotation-controller branch from 2612f1c to 50644f3 Compare January 21, 2022 04:54
@Rakshith-R
Copy link
Member Author

Well, I didn't block this PR for the naming part, but for the rest of the comments.

You have one more to take care of for now i.e use generateCronJobName

done 👍 thanks!

@Rakshith-R Rakshith-R requested a review from a team January 21, 2022 04:56
Copy link

@pkalever pkalever left a comment

Choose a reason for hiding this comment

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

Looks good to me, the only thing I don't like is the Controller name as mentioned before.

How about PVCAnnotationsController?

nixpanic
nixpanic previously approved these changes Jan 21, 2022
@Rakshith-R
Copy link
Member Author

making some changes to update child cronjob instead of recreating them

@Rakshith-R Rakshith-R marked this pull request as draft January 21, 2022 08:12
@Rakshith-R Rakshith-R force-pushed the Annotation-controller branch from 50644f3 to a86c379 Compare January 21, 2022 08:46
@mergify mergify bot dismissed nixpanic’s stale review January 21, 2022 08:47

Pull request has been modified.

@Rakshith-R Rakshith-R force-pushed the Annotation-controller branch 2 times, most recently from 2ebeffb to d87ed84 Compare January 21, 2022 09:07
@Rakshith-R Rakshith-R marked this pull request as ready for review January 21, 2022 09:07
@Rakshith-R
Copy link
Member Author

Reconciles if create or update happens to `reclaimspace.csiaddons.openshift.io/schedule: "@everyday"` annotation
Now controller also reacts to events on the child cronjob.


steps: 
- get first child cron job, delete other child jobs(precautionary, multiple child cronjobs should not exist)
- check annotation for schedule
- if not found, delete child cron job and clear name annotation if it exists and  exit
- if found, continue
- check default spec and child cronjob spec, update if necessary and cron job is present on the cluster.
- generate unique name = pvc.name+time.Now().Unix()  (ex rbd-pvc-1642598479)
- set name annotaion
- construct rscronjob
- set controllerref, create rscronjob
- exit

PTAL @csi-addons/kubernetes-csi-addons-reviewers @csi-addons/kubernetes-csi-addons-contributors

@Rakshith-R Rakshith-R force-pushed the Annotation-controller branch from d87ed84 to ca9ae69 Compare January 21, 2022 09:15
@Rakshith-R Rakshith-R requested a review from nixpanic January 21, 2022 09:16
logger.Error(err, "Failed to delete child reclaimSpaceCronJob",
"ReclaimSpaceCronJobName", job.Name)

return fmt.Errorf("Failed to delete child reclaimSpaceCronJob: %v", err)
Copy link
Member

Choose a reason for hiding this comment

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

use %w return childjob name also?

Copy link
Member Author

Choose a reason for hiding this comment

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

use %w return childjob name also?

done

@Rakshith-R Rakshith-R force-pushed the Annotation-controller branch from ca9ae69 to 611422e Compare January 21, 2022 09:25
@Rakshith-R
Copy link
Member Author

@Mergifyio rebase

This controller watches for annotation on PVC,
if matches with `reclaimspace.csiaddons.openshift.io/schedule`
which can specify a schedule, a reclaimspace cron job cr
is created for that PVC witha  generated name having pvc-name
as prefix.

Signed-off-by: Rakshith R <[email protected]>
@mergify
Copy link

mergify bot commented Jan 21, 2022

rebase

✅ Branch has been successfully rebased

@Rakshith-R Rakshith-R force-pushed the Annotation-controller branch from 611422e to e344894 Compare January 21, 2022 10:58
Copy link

@pkalever pkalever left a comment

Choose a reason for hiding this comment

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

Looks good to me, Thanks!


return ok
},
UpdateFunc: func(e event.UpdateEvent) bool {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this not require the update permission for the PVC/annotations? patch is there, is it not cleaner to patch it in any case?

Copy link
Member Author

Choose a reason for hiding this comment

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

Watch perm is enough to check for events.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah, sure. Thanks!

@Rakshith-R Rakshith-R requested a review from nixpanic January 21, 2022 12:27
@mergify mergify bot merged commit 7835881 into csi-addons:main Jan 21, 2022
nixpanic pushed a commit to nixpanic/kubernetes-csi-addons that referenced this pull request Jan 12, 2024
Syncing latest changes from main for kubernetes-csi-addons
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.

5 participants