Skip to content

Commit

Permalink
auto patch webhook objectSelector label on workload (#158)
Browse files Browse the repository at this point in the history
Signed-off-by: liheng.zms <liheng.zms@alibaba-inc.com>
  • Loading branch information
zmberg committed Jul 11, 2023
1 parent bc014ea commit e99c529
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 6 deletions.
22 changes: 22 additions & 0 deletions config/webhook/patch_manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,32 @@ webhooks:
matchExpressions:
- key: rollouts.kruise.io/workload-type
operator: Exists
- name: mcloneset.kb.io
objectSelector:
matchExpressions:
- key: rollouts.kruise.io/workload-type
operator: Exists
- name: mdaemonset.kb.io
objectSelector:
matchExpressions:
- key: rollouts.kruise.io/workload-type
operator: Exists
- name: mstatefulset.kb.io
objectSelector:
matchExpressions:
- key: rollouts.kruise.io/workload-type
operator: Exists
- name: madvancedstatefulset.kb.io
objectSelector:
matchExpressions:
- key: rollouts.kruise.io/workload-type
operator: Exists
- name: mdeployment.kb.io
objectSelector:
matchExpressions:
- key: control-plane
operator: NotIn
values:
- controller-manager
- key: rollouts.kruise.io/workload-type
operator: Exists
6 changes: 5 additions & 1 deletion pkg/controller/rollout/rollout_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,11 @@ func (r *RolloutReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
if err != nil {
return ctrl.Result{}, err
}

// Patch rollout webhook objectSelector in workload labels[rollouts.kruise.io/workload-type],
// then rollout only webhook the workload which contains labels[rollouts.kruise.io/workload-type].
if err = r.patchWorkloadRolloutWebhookLabel(rollout); err != nil {
return ctrl.Result{}, err
}
// sync rollout status
retry, newStatus, err := r.calculateRolloutStatus(rollout)
if err != nil {
Expand Down
41 changes: 38 additions & 3 deletions pkg/controller/rollout/rollout_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/openkruise/rollouts/api/v1alpha1"
"github.com/openkruise/rollouts/pkg/util"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/rand"
"k8s.io/client-go/util/retry"
Expand Down Expand Up @@ -80,14 +81,12 @@ func (r *RolloutReconciler) calculateRolloutStatus(rollout *v1alpha1.Rollout) (r
}
return false, newStatus, nil
}
klog.V(5).Infof("rollout(%s/%s) workload(%s)", rollout.Namespace, rollout.Name, util.DumpJSON(workload))
// todo, patch workload webhook labels
klog.V(5).Infof("rollout(%s/%s) fetch workload(%s)", rollout.Namespace, rollout.Name, util.DumpJSON(workload))
// workload status generation is not equal to workload.generation
if !workload.IsStatusConsistent {
klog.Infof("rollout(%s/%s) workload status is inconsistent, then wait a moment", rollout.Namespace, rollout.Name)
return true, nil, nil
}

// update workload generation to canaryStatus.ObservedWorkloadGeneration
// rollout is a target ref bypass, so there needs to be a field to identify the rollout execution process or results,
// which version of deployment is targeted, ObservedWorkloadGeneration that is to compare with the workload generation
Expand Down Expand Up @@ -249,6 +248,42 @@ func (r *RolloutReconciler) reconcileRolloutDisabling(rollout *v1alpha1.Rollout,
return c.RecheckTime, nil
}

func (r *RolloutReconciler) patchWorkloadRolloutWebhookLabel(rollout *v1alpha1.Rollout) error {
// get ref workload
workload, err := r.finder.GetWorkloadForRef(rollout)
if err != nil {
klog.Errorf("rollout(%s/%s) get workload failed: %s", rollout.Namespace, rollout.Name, err.Error())
return err
} else if workload == nil {
return nil
}

var workloadType util.WorkloadType
switch workload.Kind {
case util.ControllerKruiseKindCS.Kind:
workloadType = util.CloneSetType
case util.ControllerKindDep.Kind:
workloadType = util.DeploymentType
case util.ControllerKindSts.Kind:
workloadType = util.StatefulSetType
case util.ControllerKruiseKindDS.Kind:
workloadType = util.DaemonSetType
}
if workload.Annotations[util.WorkloadTypeLabel] == "" && workloadType != "" {
workloadGVK := schema.FromAPIVersionAndKind(workload.APIVersion, workload.Kind)
obj := util.GetEmptyWorkloadObject(workloadGVK)
obj.SetNamespace(workload.Namespace)
obj.SetName(workload.Name)
body := fmt.Sprintf(`{"metadata":{"labels":{"%s":"%s"}}}`, util.WorkloadTypeLabel, workloadType)
if err := r.Patch(context.TODO(), obj, client.RawPatch(types.MergePatchType, []byte(body))); err != nil {
klog.Errorf("rollout(%s/%s) patch workload(%s) failed: %s", rollout.Namespace, rollout.Name, workload.Name, err.Error())
return err
}
klog.Infof("rollout(%s/%s) patch workload(%s) labels[%s] success", rollout.Namespace, rollout.Name, workload.Name, util.WorkloadTypeLabel)
}
return nil
}

// handle adding and handle finalizer logic, it turns if we should continue to reconcile
func (r *RolloutReconciler) handleFinalizer(rollout *v1alpha1.Rollout) error {
// delete rollout crd, remove finalizer
Expand Down
6 changes: 4 additions & 2 deletions test/e2e/rollout_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ var _ = SIGDescribe("Rollout", func() {
Eventually(func() bool {
daemon := &appsv1alpha1.DaemonSet{}
Expect(GetObject(daemonset.Name, daemon)).NotTo(HaveOccurred())
klog.Infof("DaemonSet Generation(%d) ObservedGeneration(%d) DesiredNumberScheduled(%d) UpdatedNumberScheduled(%d) NumberReady(%d)",
daemon.Generation, daemon.Status.ObservedGeneration, daemon.Status.DesiredNumberScheduled, daemon.Status.UpdatedNumberScheduled, daemon.Status.NumberReady)
klog.Infof("DaemonSet updateStrategy(%s) Generation(%d) ObservedGeneration(%d) DesiredNumberScheduled(%d) UpdatedNumberScheduled(%d) NumberReady(%d)",
util.DumpJSON(daemon.Spec.UpdateStrategy), daemon.Generation, daemon.Status.ObservedGeneration, daemon.Status.DesiredNumberScheduled, daemon.Status.UpdatedNumberScheduled, daemon.Status.NumberReady)
return daemon.Status.ObservedGeneration == daemon.Generation && daemon.Status.DesiredNumberScheduled == daemon.Status.UpdatedNumberScheduled && daemon.Status.DesiredNumberScheduled == daemon.Status.NumberReady
}, 5*time.Minute, time.Second).Should(BeTrue())
}
Expand Down Expand Up @@ -5480,6 +5480,8 @@ var _ = SIGDescribe("Rollout", func() {
Expect(k8sClient.DeleteAllOf(context.TODO(), &v1alpha1.Rollout{}, client.InNamespace(namespace), client.PropagationPolicy(metav1.DeletePropagationForeground))).Should(Succeed())
WaitRolloutNotFound(rollout.Name)
Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
workload.Spec.UpdateStrategy.RollingUpdate.Partition = utilpointer.Int32(0)
UpdateDaemonSet(workload)
WaitDaemonSetAllPodsReady(workload)

// check daemonset
Expand Down

0 comments on commit e99c529

Please sign in to comment.