Skip to content

Commit 2d59b9f

Browse files
[feature] PVC template (#162)
* basic pvc template support * support PVC Retention policy * add pvc template unit test * add pvc utils unit test * add file header lisences * supprt pvc with replace update * rephrase some typo * pvc compatible with replace update + scale in * support retain pvc when update pvc template * fix:re-mount the old pvc when pvc template rollback * sort inported packages, correct new files Copyright 2024 * pass caller's context * remove redundant DeepCopy() * validating webhook: denied delete pvc while pending * validating webhook: denied delete pvc (must be mounted) while pending * rename files * fix: support persistent ownerReference for owned pvcs * fix: use latest available version * fix:reclaim pvcs in 1 reconcile * type * import files * always adopt pvcs * add some comment
1 parent 72fb78d commit 2d59b9f

24 files changed

+1736
-69
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ help: ## Display this help.
4545

4646
.PHONY: manifests
4747
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
48-
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
48+
$(CONTROLLER_GEN) rbac:roleName=manager-role crd:generateEmbeddedObjectMeta=true webhook paths="./..." output:crd:artifacts:config=config/crd/bases
4949

5050
.PHONY: generate
5151
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.

apis/apps/v1alpha1/well_known_labels.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ const (
4646
PodReplacePairOriginName = "collaset.kusionstack.io/replace-pair-origin-name" // used to indicate the original Pod name for replacement.
4747

4848
PodReplacePairNewId = "collaset.kusionstack.io/replace-pair-new-id" // used to indicate the new created Pod instance ID for replacement.
49+
50+
PvcTemplateHashLabelKey = "collaset.kusionstack.io/pvc-template-hash" // used to attach hash of pvc template to pvc resource
51+
4952
)
5053

5154
const (

config/crd/bases/apps.kusionstack.io_collasets.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,23 @@ spec:
255255
type: string
256256
metadata:
257257
description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata'
258+
properties:
259+
annotations:
260+
additionalProperties:
261+
type: string
262+
type: object
263+
finalizers:
264+
items:
265+
type: string
266+
type: array
267+
labels:
268+
additionalProperties:
269+
type: string
270+
type: object
271+
name:
272+
type: string
273+
namespace:
274+
type: string
258275
type: object
259276
spec:
260277
description: 'Spec defines the desired characteristics of a

config/crd/bases/apps.kusionstack.io_poddecorations.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4213,6 +4213,23 @@ spec:
42134213
that will be copied into the PVC when creating
42144214
it. No other fields are allowed and will be rejected
42154215
during validation.
4216+
properties:
4217+
annotations:
4218+
additionalProperties:
4219+
type: string
4220+
type: object
4221+
finalizers:
4222+
items:
4223+
type: string
4224+
type: array
4225+
labels:
4226+
additionalProperties:
4227+
type: string
4228+
type: object
4229+
name:
4230+
type: string
4231+
namespace:
4232+
type: string
42164233
type: object
42174234
spec:
42184235
description: The specification for the PersistentVolumeClaim.

config/rbac/role.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,18 @@ rules:
131131
- create
132132
- patch
133133
- update
134+
- apiGroups:
135+
- ""
136+
resources:
137+
- persistentvolumeclaims
138+
verbs:
139+
- create
140+
- delete
141+
- get
142+
- list
143+
- patch
144+
- update
145+
- watch
134146
- apiGroups:
135147
- ""
136148
resources:

config/webhook/webhook.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,31 @@ webhooks:
8686
operator: In
8787
values:
8888
- 'true'
89+
- name: validating-pvc.apps.kusionstack.io
90+
sideEffects: NoneOnDryRun
91+
admissionReviewVersions: ["v1", "v1beta1"]
92+
clientConfig:
93+
service:
94+
namespace: kusionstack-system
95+
name: controller-manager
96+
path: /validating-generic
97+
failurePolicy: Fail
98+
rules:
99+
- apiGroups:
100+
- "*"
101+
apiVersions:
102+
- v1
103+
operations:
104+
- DELETE
105+
resources:
106+
- persistentvolumeclaims
107+
scope: '*'
108+
objectSelector:
109+
matchExpressions:
110+
- key: kusionstack.io/control
111+
operator: In
112+
values:
113+
- 'true'
89114
- name: validating-generic.apps.kusionstack.io
90115
sideEffects: NoneOnDryRun
91116
admissionReviewVersions: ["v1", "v1beta1"]

pkg/controllers/collaset/collaset_controller.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
appsv1alpha1 "kusionstack.io/operating/apis/apps/v1alpha1"
3535
"kusionstack.io/operating/pkg/controllers/collaset/podcontext"
3636
"kusionstack.io/operating/pkg/controllers/collaset/podcontrol"
37+
"kusionstack.io/operating/pkg/controllers/collaset/pvccontrol"
3738
"kusionstack.io/operating/pkg/controllers/collaset/synccontrol"
3839
"kusionstack.io/operating/pkg/controllers/collaset/utils"
3940
collasetutils "kusionstack.io/operating/pkg/controllers/collaset/utils"
@@ -71,7 +72,7 @@ func NewReconciler(mgr ctrl.Manager) reconcile.Reconciler {
7172
return &CollaSetReconciler{
7273
ReconcilerMixin: mixin,
7374
revisionManager: revision.NewRevisionManager(mixin.Client, mixin.Scheme, NewRevisionOwnerAdapter(podcontrol.NewRealPodControl(mixin.Client, mixin.Scheme))),
74-
syncControl: synccontrol.NewRealSyncControl(mixin.Client, mixin.Logger, podcontrol.NewRealPodControl(mixin.Client, mixin.Scheme), mixin.Recorder),
75+
syncControl: synccontrol.NewRealSyncControl(mixin.Client, mixin.Logger, podcontrol.NewRealPodControl(mixin.Client, mixin.Scheme), pvccontrol.NewRealPvcControl(mixin.Client, mixin.Scheme), mixin.Recorder),
7576
}
7677
}
7778

@@ -112,6 +113,7 @@ func AddToMgr(mgr ctrl.Manager, r reconcile.Reconciler) error {
112113
// +kubebuilder:rbac:groups=apps.kusionstack.io,resources=resourcecontexts,verbs=get;list;watch;create;update;patch;delete
113114
// +kubebuilder:rbac:groups=apps.kusionstack.io,resources=resourcecontexts/status,verbs=get;update;patch
114115
// +kubebuilder:rbac:groups=apps.kusionstack.io,resources=resourcecontexts/finalizers,verbs=update
116+
// +kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=get;list;watch;create;update;patch;delete
115117
// +kubebuilder:rbac:groups=apps,resources=controllerrevisions,verbs=get;list;watch;create;update;patch;delete
116118
// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete
117119
// +kubebuilder:rbac:groups=core,resources=events,verbs=create;update;patch
@@ -140,6 +142,10 @@ func (r *CollaSetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
140142
}
141143

142144
if instance.DeletionTimestamp != nil {
145+
if err := r.ensureReclaimPvcs(ctx, instance); err != nil {
146+
// reclaim pvcs before remove finalizers
147+
return ctrl.Result{}, err
148+
}
143149
if controllerutil.ContainsFinalizer(instance, preReclaimFinalizer) {
144150
// reclaim owner IDs in ResourceContext
145151
if err := r.reclaimResourceContext(instance); err != nil {
@@ -325,3 +331,23 @@ func requeueResult(requeueTime *time.Duration) reconcile.Result {
325331
}
326332
return reconcile.Result{}
327333
}
334+
335+
func (r *CollaSetReconciler) ensureReclaimPvcs(ctx context.Context, cls *appsv1alpha1.CollaSet) error {
336+
var needReclaimPvcs []*corev1.PersistentVolumeClaim
337+
pvcControl := pvccontrol.NewRealPvcControl(r.Client, r.Scheme)
338+
pvcs, err := pvcControl.GetFilteredPvcs(ctx, cls)
339+
if err != nil {
340+
return err
341+
}
342+
// reclaim pvcs according to whenDelete retention policy
343+
for i := range pvcs {
344+
owned := pvcs[i].OwnerReferences != nil && len(pvcs[i].OwnerReferences) > 0
345+
if owned && collasetutils.PvcPolicyWhenDelete(cls) == appsv1alpha1.RetainPersistentVolumeClaimRetentionPolicyType {
346+
needReclaimPvcs = append(needReclaimPvcs, pvcs[i])
347+
}
348+
}
349+
if len(needReclaimPvcs) > 0 {
350+
_, err = pvcControl.ReleasePvcsOwnerRef(cls, needReclaimPvcs)
351+
}
352+
return err
353+
}

0 commit comments

Comments
 (0)