Skip to content

Commit

Permalink
chore: support component lifecycle action postProvision (apecloud#6037)
Browse files Browse the repository at this point in the history
  • Loading branch information
Y-Rookie authored Dec 13, 2023
1 parent b206f61 commit 37ad128
Show file tree
Hide file tree
Showing 24 changed files with 2,012 additions and 155 deletions.
15 changes: 15 additions & 0 deletions apis/apps/v1alpha1/clusterdefinition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ type ClusterComponentDefinition struct {
// +optional
SwitchoverSpec *SwitchoverSpec `json:"switchoverSpec,omitempty"`

// postStartSpec defines the command to be executed when the component is ready, and the command will only be executed once after the component becomes ready.
// +optional
PostStartSpec *PostStartAction `json:"postStartSpec,omitempty"`

// +optional
VolumeProtectionSpec *VolumeProtectionSpec `json:"volumeProtectionSpec,omitempty"`

Expand Down Expand Up @@ -947,6 +951,17 @@ func (r *ReplicationSetSpec) FinalStsUpdateStrategy() (appsv1.PodManagementPolic
return appsv1.ParallelPodManagement, s
}

type PostStartAction struct {
// cmdExecutorConfig is the executor configuration of the post-start command.
// +kubebuilder:validation:Required
CmdExecutorConfig CmdExecutorConfig `json:"cmdExecutorConfig"`

// scriptSpecSelectors defines the selector of the scriptSpecs that need to be referenced.
// Once ScriptSpecSelectors is defined, the scripts defined in scriptSpecs can be referenced in the PostStartAction.CmdExecutorConfig.
// +optional
ScriptSpecSelectors []ScriptSpecSelector `json:"scriptSpecSelectors,omitempty"`
}

type SwitchoverSpec struct {
// withCandidate corresponds to the switchover of the specified candidate primary or leader instance.
// +optional
Expand Down
47 changes: 38 additions & 9 deletions apis/apps/v1alpha1/componentdefinition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ type ComponentDefinitionSpec struct {
// +optional
LifecycleActions *ComponentLifecycleActions `json:"lifecycleActions,omitempty"`

// serviceRefDeclarations is used to declare the service reference of the current component.
// ServiceRefDeclarations is used to declare the service reference of the current component.
// Cannot be updated.
// +optional
ServiceRefDeclarations []ServiceRefDeclaration `json:"serviceRefDeclarations,omitempty"`
Expand Down Expand Up @@ -401,6 +401,16 @@ type RetryPolicy struct {
RetryInterval time.Duration `json:"retryInterval,omitempty"`
}

// PreConditionType defines the preCondition type of the action execution.
type PreConditionType string

const (
ImmediatelyPreConditionType PreConditionType = "Immediately"
RuntimeReadyPreConditionType PreConditionType = "RuntimeReady"
ComponentReadyPreConditionType PreConditionType = "ComponentReady"
ClusterReadyPreConditionType PreConditionType = "ClusterReady"
)

// Action defines an operational action that can be performed by a component instance.
// There are some pre-defined environment variables that can be used when writing action commands, check @BuiltInVars for reference.
//
Expand Down Expand Up @@ -463,6 +473,19 @@ type Action struct {
// Cannot be updated.
// +optional
RetryPolicy *RetryPolicy `json:"retryPolicy,omitempty"`

// PreCondition defines the condition when the action will be executed.
// - Immediately: The Action is executed immediately after the Component object is created,
// without guaranteeing the availability of the Component and its underlying resources. only after the action is successfully executed will the Component's state turn to ready.
// - RuntimeReady: The Action is executed after the Component object is created and once all underlying Runtimes are ready.
// only after the action is successfully executed will the Component's state turn to ready.
// - ComponentReady: The Action is executed after the Component object is created and once the Component is ready.
// the execution process does not impact the state of the Component and the Cluster.
// - ClusterReady: The Action is executed after the Cluster object is created and once the Cluster is ready.
// the execution process does not impact the state of the Component and the Cluster.
// Cannot be updated.
// +optional
PreCondition *PreConditionType `json:"preCondition,omitempty"`
}

// BuiltinActionHandlerType defines build-in action handlers provided by Lorry.
Expand Down Expand Up @@ -495,20 +518,26 @@ type LifecycleActionHandler struct {

// ComponentLifecycleActions defines a set of operational actions for interacting with component services and processes.
type ComponentLifecycleActions struct {
// PostStart is called immediately after a component is created.
// PostProvision defines the actions to be executed and the corresponding policy when a component is created.
// You can define the preCondition for executing PostProvision using Action.PreCondition. The default PostProvision action preCondition is ComponentReady.
// The PostProvision Action will be executed only once.
// Dedicated env vars for the action:
// - KB_CLUSTER_COMPONENT_LIST: The list of all components in the cluster, joined by ',' (e.g., "comp1,comp2").
// Cannot be updated.
// +optional
PostStart *LifecycleActionHandler `json:"postStart,omitempty"`
PostProvision *LifecycleActionHandler `json:"postProvision,omitempty"`

// PreStop is called immediately before a component is terminated due to an API request.
// PreTerminate defines the actions to be executed when a component is terminated due to an API request.
// The PreTerminate Action will be executed only once. Upon receiving a scale-down command for the Component, it is executed immediately.
// Only after the preTerminate action is successfully executed, the destruction of the Component and its underlying resources proceeds.
// Cannot be updated.
// +optional
PreStop *LifecycleActionHandler `json:"preStop,omitempty"`
PreTerminate *LifecycleActionHandler `json:"preTerminate,omitempty"`

// RoleProbe defines how to probe the role of replicas.
// Cannot be updated.
// +optional
RoleProbe *RoleProbeSpec `json:"roleProbe,omitempty"`
RoleProbe *RoleProbe `json:"roleProbe,omitempty"`

// Switchover defines how to proactively switch the current leader to a new replica to minimize the impact on availability.
// This action is typically invoked when the leader is about to become unavailable due to events, such as:
Expand All @@ -527,7 +556,7 @@ type ComponentLifecycleActions struct {
// - KB_CONSENSUS_LEADER_POD_: The prefix of the environment variables of the original leader's Pod before switchover.
// Cannot be updated.
// +optional
Switchover *ComponentSwitchoverSpec `json:"switchover,omitempty"`
Switchover *ComponentSwitchover `json:"switchover,omitempty"`

// MemberJoin defines how to add a new replica to the replication group.
// This action is typically invoked when a new replica needs to be added, such as during scale-out.
Expand Down Expand Up @@ -587,7 +616,7 @@ type ComponentLifecycleActions struct {
AccountProvision *LifecycleActionHandler `json:"accountProvision,omitempty"`
}

type ComponentSwitchoverSpec struct {
type ComponentSwitchover struct {
// withCandidate corresponds to the switchover of the specified candidate primary or leader instance.
// Currently, only Action.Exec is supported, Action.HTTP is not supported.
// +optional
Expand All @@ -604,7 +633,7 @@ type ComponentSwitchoverSpec struct {
ScriptSpecSelectors []ScriptSpecSelector `json:"scriptSpecSelectors,omitempty"`
}

type RoleProbeSpec struct {
type RoleProbe struct {
LifecycleActionHandler `json:",inline"`

// Number of seconds after the container has started before liveness probes are initiated.
Expand Down
4 changes: 2 additions & 2 deletions apis/apps/v1alpha1/opsrequest_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ var _ = Describe("OpsRequest webhook", func() {
opsRequest.Spec.SwitchoverList = []Switchover{switchoverList[1]}
Expect(testCtx.CreateObj(ctx, opsRequest).Error()).To(ContainSubstring("switchover.instanceName"))

By("By testing switchover - componentDefinition has no ComponentSwitchoverSpec and do not support switchover")
By("By testing switchover - componentDefinition has no ComponentSwitchover and do not support switchover")
opsRequest = createTestOpsRequest(clusterName, opsRequestName, SwitchoverType)
opsRequest.Spec.SwitchoverList = []Switchover{switchoverList[3]}
Expect(testCtx.CreateObj(ctx, opsRequest).Error()).To(ContainSubstring("does not support switchover"))
Expand All @@ -544,7 +544,7 @@ var _ = Describe("OpsRequest webhook", func() {
},
}
lifeCycleAction := &ComponentLifecycleActions{
Switchover: &ComponentSwitchoverSpec{
Switchover: &ComponentSwitchover{
WithCandidate: &Action{
Image: commandExecutorEnvItem.Image,
Env: commandExecutorEnvItem.Env,
Expand Down
59 changes: 45 additions & 14 deletions apis/apps/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 37ad128

Please sign in to comment.