Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions apis/apps/v1/componentdefinition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1536,6 +1536,9 @@ type ComponentLifecycleActions struct {
// during events such as planned maintenance or when performing stop, shutdown, restart, or upgrade operations.
// In a typical consensus system, this action is used to transfer leader role to another replica.
//
// When a pod is about to be updated, a switchover action will be triggered for it. So addon implementation must determine
// if the pod's current role needs to be transferred.
//
// The container executing this action has access to following variables:
//
// - KB_SWITCHOVER_CANDIDATE_NAME: The name of the pod of the new role's candidate, which may not be specified (empty).
Expand Down Expand Up @@ -1717,6 +1720,9 @@ type ComponentLifecycleActions struct {
// designed to be invoked at predetermined points within the lifecycle of a Component instance.
// It provides a modular and extensible way to customize a Component's behavior through the execution of defined actions.
//
// Action should be idempotent if possible. In some circumstances (for example, an UPDATE to an k8s object fails due to concurrent updates),
// the action may be retried even after a success.
//
// Available Action triggers include:
//
// - `postProvision`: Defines the hook to be executed after the creation of a Component,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9802,6 +9802,10 @@ spec:
In a typical consensus system, this action is used to transfer leader role to another replica.


When a pod is about to be updated, a switchover action will be triggered for it. So addon implementation must determine
if the pod's current role needs to be transferred.


The container executing this action has access to following variables:


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func (t *componentAccountProvisionTransformer) lifecycleAction(transCtx *compone
return nil, err
}
lfa, err := lifecycle.New(synthesizedComp.Namespace, synthesizedComp.ClusterName, synthesizedComp.Name,
synthesizedComp.LifecycleActions, synthesizedComp.TemplateVars, nil, pods...)
synthesizedComp.LifecycleActions, synthesizedComp.TemplateVars, nil, pods)
if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func (t *componentPostProvisionTransformer) lifecycleAction4Component(transCtx *
return nil, fmt.Errorf("has no pods to running the post-provision action")
}
return lifecycle.New(synthesizedComp.Namespace, synthesizedComp.ClusterName, synthesizedComp.Name,
synthesizedComp.LifecycleActions, synthesizedComp.TemplateVars, nil, pods...)
synthesizedComp.LifecycleActions, synthesizedComp.TemplateVars, nil, pods)
}

func checkPostProvisionDone(transCtx *componentTransformContext) bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func (t *componentPreTerminateTransformer) lifecycleAction4Component(transCtx *c
return nil, fmt.Errorf("has no pods to running the pre-terminate action")
}
return lifecycle.New(synthesizedComp.Namespace, synthesizedComp.ClusterName, synthesizedComp.Name,
synthesizedComp.LifecycleActions, synthesizedComp.TemplateVars, nil, pods...)
synthesizedComp.LifecycleActions, synthesizedComp.TemplateVars, nil, pods)
}

func (t *componentPreTerminateTransformer) synthesizedComponent(transCtx *componentTransformContext, compDef *appsv1.ComponentDefinition) (*component.SynthesizedComponent, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func (r *componentWorkloadOps) leaveMemberForPod(pod *corev1.Pod, pods []*corev1
}

lfa, err := lifecycle.New(synthesizedComp.Namespace, synthesizedComp.ClusterName, synthesizedComp.Name,
lifecycleActions, synthesizedComp.TemplateVars, pod, pods...)
lifecycleActions, synthesizedComp.TemplateVars, pod, pods)
if err != nil {
return err
}
Expand Down Expand Up @@ -387,7 +387,7 @@ func (r *componentWorkloadOps) joinMember4ScaleOut() error {
func (r *componentWorkloadOps) joinMemberForPod(pod *corev1.Pod, pods []*corev1.Pod) error {
synthesizedComp := r.synthesizeComp
lfa, err := lifecycle.New(synthesizedComp.Namespace, synthesizedComp.ClusterName, synthesizedComp.Name,
synthesizedComp.LifecycleActions, synthesizedComp.TemplateVars, pod, pods...)
synthesizedComp.LifecycleActions, synthesizedComp.TemplateVars, pod, pods)
if err != nil {
return err
}
Expand Down
3 changes: 1 addition & 2 deletions controllers/apps/componentdefinition_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"slices"
"strings"

"github.com/pkg/errors"
k8sappsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -259,7 +258,7 @@ func (r *ComponentDefinitionReconciler) validateVars(cli client.Client, rctx int
continue
}
if err := component.ValidateDefNameRegexp(compDef); err != nil {
return errors.Wrapf(err, "invalid reference to component definition name pattern: %s", compDef)
return fmt.Errorf("invalid reference to component definition name pattern: %s: %w", compDef, err)
}
}
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9802,6 +9802,10 @@ spec:
In a typical consensus system, this action is used to transfer leader role to another replica.


When a pod is about to be updated, a switchover action will be triggered for it. So addon implementation must determine
if the pod's current role needs to be transferred.


The container executing this action has access to following variables:


Expand Down
2 changes: 2 additions & 0 deletions docs/developer_docs/api-reference/cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -5867,6 +5867,8 @@ Action
This approach aims to minimize downtime and maintain availability
during events such as planned maintenance or when performing stop, shutdown, restart, or upgrade operations.
In a typical consensus system, this action is used to transfer leader role to another replica.</p>
<p>When a pod is about to be updated, a switchover action will be triggered for it. So addon implementation must determine
if the pod&rsquo;s current role needs to be transferred.</p>
<p>The container executing this action has access to following variables:</p>
<ul>
<li>KB_SWITCHOVER_CANDIDATE_NAME: The name of the pod of the new role&rsquo;s candidate, which may not be specified (empty).</li>
Expand Down
3 changes: 2 additions & 1 deletion pkg/controller/instance/reconciler_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,8 @@ func (r *updateReconciler) switchover(tree *kubebuilderx.ObjectTree, inst *workl
return nil
}

lfa, err := newLifecycleAction(inst, nil, pod)
// FIXME: select all available pods
lfa, err := newLifecycleAction(inst, []*corev1.Pod{pod}, pod)
if err != nil {
return err
}
Expand Down
8 changes: 2 additions & 6 deletions pkg/controller/instance/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,19 +351,15 @@ func copyAndMerge(oldObj, newObj client.Object) client.Object {
}
}

func newLifecycleAction(inst *workloads.Instance, objects []client.Object, pod *corev1.Pod) (lifecycle.Lifecycle, error) {
func newLifecycleAction(inst *workloads.Instance, pods []*corev1.Pod, pod *corev1.Pod) (lifecycle.Lifecycle, error) {
var (
clusterName = inst.Labels[constant.AppInstanceLabelKey]
compName = inst.Labels[constant.KBAppComponentLabelKey]
lifecycleActions = &kbappsv1.ComponentLifecycleActions{
Switchover: inst.Spec.LifecycleActions.Switchover,
Reconfigure: inst.Spec.LifecycleActions.Reconfigure,
}
pods []*corev1.Pod
)
for i := range objects {
pods = append(pods, objects[i].(*corev1.Pod))
}
return lifecycle.New(inst.Namespace, clusterName, compName,
lifecycleActions, inst.Spec.LifecycleActions.TemplateVars, pod, pods...)
lifecycleActions, inst.Spec.LifecycleActions.TemplateVars, pod, pods)
}
4 changes: 2 additions & 2 deletions pkg/controller/instanceset/reconciler_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ func (r *updateReconciler) switchover(tree *kubebuilderx.ObjectTree, its *worklo
return nil
}

lfa, err := newLifecycleAction(its, nil, pod)
lfa, err := newLifecycleAction(its, tree, pod)
if err != nil {
return err
}
Expand Down Expand Up @@ -318,7 +318,7 @@ func (r *updateReconciler) reconfigureConfig(tree *kubebuilderx.ObjectTree, its
itsCopy.Spec.LifecycleActions = &workloads.LifecycleActions{}
}
itsCopy.Spec.LifecycleActions.Reconfigure = config.Reconfigure
lfa, err := newLifecycleAction(itsCopy, nil, pod)
lfa, err := newLifecycleAction(itsCopy, tree, pod)
if err != nil {
return err
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/controller/instanceset/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/utils/integer"
"sigs.k8s.io/controller-runtime/pkg/client"

kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
workloads "github.com/apecloud/kubeblocks/apis/workloads/v1"
"github.com/apecloud/kubeblocks/pkg/constant"
"github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx"
"github.com/apecloud/kubeblocks/pkg/controller/lifecycle"
)

Expand Down Expand Up @@ -203,19 +203,19 @@ func getMemberUpdateStrategy(its *workloads.InstanceSet) workloads.MemberUpdateS
return updateStrategy
}

func newLifecycleAction(its *workloads.InstanceSet, objects []client.Object, pod *corev1.Pod) (lifecycle.Lifecycle, error) {
func newLifecycleAction(its *workloads.InstanceSet, tree *kubebuilderx.ObjectTree, pod *corev1.Pod) (lifecycle.Lifecycle, error) {
var (
clusterName = its.Labels[constant.AppInstanceLabelKey]
compName = its.Labels[constant.KBAppComponentLabelKey]
lifecycleActions = &kbappsv1.ComponentLifecycleActions{
Switchover: its.Spec.LifecycleActions.Switchover,
Reconfigure: its.Spec.LifecycleActions.Reconfigure,
}
pods []*corev1.Pod
)
for i := range objects {
pods = append(pods, objects[i].(*corev1.Pod))
pods := make([]*corev1.Pod, 0)
for _, object := range tree.List(&corev1.Pod{}) {
pods = append(pods, object.(*corev1.Pod))
}
return lifecycle.New(its.Namespace, clusterName, compName,
lifecycleActions, its.Spec.LifecycleActions.TemplateVars, pod, pods...)
lifecycleActions, its.Spec.LifecycleActions.TemplateVars, pod, pods)
}
4 changes: 2 additions & 2 deletions pkg/controller/lifecycle/kbagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ type kbagent struct {
compName string
lifecycleActions *appsv1.ComponentLifecycleActions
templateVars map[string]string
pods []*corev1.Pod
pod *corev1.Pod
pods []*corev1.Pod // available pods to execute action, typically all pods of the component
pod *corev1.Pod // target pod the action will be effective on. Some actions, like postprovision, does not care about this field.
}

var _ Lifecycle = &kbagent{}
Expand Down
9 changes: 3 additions & 6 deletions pkg/controller/lifecycle/lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,13 @@ type Lifecycle interface {
}

func New(namespace, clusterName, compName string, lifecycleActions *appsv1.ComponentLifecycleActions,
templateVars map[string]string, pod *corev1.Pod, pods ...*corev1.Pod) (Lifecycle, error) {
if pod == nil && len(pods) == 0 {
return nil, fmt.Errorf("either pod or pods must be provided to call lifecycle actions")
templateVars map[string]string, pod *corev1.Pod, pods []*corev1.Pod) (Lifecycle, error) {
if len(pods) == 0 {
return nil, fmt.Errorf("pods must be provided to call lifecycle actions")
}
if pod == nil {
pod = pods[0]
}
if len(pods) == 0 {
pods = []*corev1.Pod{pod}
}
return &kbagent{
namespace: namespace,
clusterName: clusterName,
Expand Down
Loading