Skip to content

Commit

Permalink
chore: refine data dump/load actions (apecloud#6820)
Browse files Browse the repository at this point in the history
  • Loading branch information
leon-inf authored Mar 28, 2024
1 parent 9e31c02 commit ea1cfd2
Show file tree
Hide file tree
Showing 16 changed files with 251 additions and 53 deletions.
10 changes: 5 additions & 5 deletions apis/apps/v1alpha1/componentdefinition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ type ComponentLifecycleActions struct {
// +optional
Readwrite *LifecycleActionHandler `json:"readwrite,omitempty"`

// Defines the method to populate the data to create new replicas.
// Defines the method to dump the data from a replica.
// This action is typically used when a new replica needs to be constructed, such as:
//
// - scale-out
Expand All @@ -800,21 +800,21 @@ type ComponentLifecycleActions struct {
// This field cannot be updated.
//
// +optional
DataPopulate *LifecycleActionHandler `json:"dataPopulate,omitempty"`
DataDump *LifecycleActionHandler `json:"dataDump,omitempty"`

// Defines the method to assemble data synchronized from external before starting the service for a new replica.
// Defines the method to load data into a replica.
// This action is typically used when creating a new replica, such as:
//
// - scale-out
// - rebuild
// - clone
//
// The data will be streamed in via stdin. If any error occurs during the assembly process,
// The data will be streamed in via stdin. If any error occurs during the process,
// the action must be able to guarantee idempotence to allow for retries from the beginning.
// This field cannot be updated.
//
// +optional
DataAssemble *LifecycleActionHandler `json:"dataAssemble,omitempty"`
DataLoad *LifecycleActionHandler `json:"dataLoad,omitempty"`

// Defines the method to notify the replica service that there is a configuration update.
// This field cannot be updated.
Expand Down
8 changes: 4 additions & 4 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.

27 changes: 13 additions & 14 deletions config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -524,14 +524,12 @@ spec:
type: integer
type: object
type: object
dataAssemble:
description: "Defines the method to assemble data synchronized
from external before starting the service for a new replica.
This action is typically used when creating a new replica, such
as: \n - scale-out - rebuild - clone \n The data will be streamed
in via stdin. If any error occurs during the assembly process,
the action must be able to guarantee idempotence to allow for
retries from the beginning. This field cannot be updated."
dataDump:
description: "Defines the method to dump the data from a replica.
This action is typically used when a new replica needs to be
constructed, such as: \n - scale-out - rebuild - clone \n It
should write the valid data to stdout without including any
extraneous information. This field cannot be updated."
properties:
builtinHandler:
description: BuiltinHandler specifies the builtin action handler
Expand Down Expand Up @@ -819,12 +817,13 @@ spec:
type: integer
type: object
type: object
dataPopulate:
description: "Defines the method to populate the data to create
new replicas. This action is typically used when a new replica
needs to be constructed, such as: \n - scale-out - rebuild -
clone \n It should write the valid data to stdout without including
any extraneous information. This field cannot be updated."
dataLoad:
description: "Defines the method to load data into a replica.
This action is typically used when creating a new replica, such
as: \n - scale-out - rebuild - clone \n The data will be streamed
in via stdin. If any error occurs during the process, the action
must be able to guarantee idempotence to allow for retries from
the beginning. This field cannot be updated."
properties:
builtinHandler:
description: BuiltinHandler specifies the builtin action handler
Expand Down
4 changes: 2 additions & 2 deletions controllers/apps/componentdefinition_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,8 @@ func (r *ComponentDefinitionReconciler) validateLifecycleActionBuiltInHandlers(l
{lifecycleActions.MemberLeave},
{lifecycleActions.Readonly},
{lifecycleActions.Readwrite},
{lifecycleActions.DataPopulate},
{lifecycleActions.DataAssemble},
{lifecycleActions.DataDump},
{lifecycleActions.DataLoad},
{lifecycleActions.Reconfigure},
{lifecycleActions.AccountProvision},
}
Expand Down
27 changes: 13 additions & 14 deletions deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -524,14 +524,12 @@ spec:
type: integer
type: object
type: object
dataAssemble:
description: "Defines the method to assemble data synchronized
from external before starting the service for a new replica.
This action is typically used when creating a new replica, such
as: \n - scale-out - rebuild - clone \n The data will be streamed
in via stdin. If any error occurs during the assembly process,
the action must be able to guarantee idempotence to allow for
retries from the beginning. This field cannot be updated."
dataDump:
description: "Defines the method to dump the data from a replica.
This action is typically used when a new replica needs to be
constructed, such as: \n - scale-out - rebuild - clone \n It
should write the valid data to stdout without including any
extraneous information. This field cannot be updated."
properties:
builtinHandler:
description: BuiltinHandler specifies the builtin action handler
Expand Down Expand Up @@ -819,12 +817,13 @@ spec:
type: integer
type: object
type: object
dataPopulate:
description: "Defines the method to populate the data to create
new replicas. This action is typically used when a new replica
needs to be constructed, such as: \n - scale-out - rebuild -
clone \n It should write the valid data to stdout without including
any extraneous information. This field cannot be updated."
dataLoad:
description: "Defines the method to load data into a replica.
This action is typically used when creating a new replica, such
as: \n - scale-out - rebuild - clone \n The data will be streamed
in via stdin. If any error occurs during the process, the action
must be able to guarantee idempotence to allow for retries from
the beginning. This field cannot be updated."
properties:
builtinHandler:
description: BuiltinHandler specifies the builtin action handler
Expand Down
10 changes: 5 additions & 5 deletions docs/developer_docs/api-reference/cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -7724,7 +7724,7 @@ LifecycleActionHandler
</tr>
<tr>
<td>
<code>dataPopulate</code><br/>
<code>dataDump</code><br/>
<em>
<a href="#apps.kubeblocks.io/v1alpha1.LifecycleActionHandler">
LifecycleActionHandler
Expand All @@ -7733,7 +7733,7 @@ LifecycleActionHandler
</td>
<td>
<em>(Optional)</em>
<p>Defines the method to populate the data to create new replicas.
<p>Defines the method to dump the data from a replica.
This action is typically used when a new replica needs to be constructed, such as:</p>
<ul>
<li>scale-out</li>
Expand All @@ -7746,7 +7746,7 @@ This field cannot be updated.</p>
</tr>
<tr>
<td>
<code>dataAssemble</code><br/>
<code>dataLoad</code><br/>
<em>
<a href="#apps.kubeblocks.io/v1alpha1.LifecycleActionHandler">
LifecycleActionHandler
Expand All @@ -7755,14 +7755,14 @@ LifecycleActionHandler
</td>
<td>
<em>(Optional)</em>
<p>Defines the method to assemble data synchronized from external before starting the service for a new replica.
<p>Defines the method to load data into a replica.
This action is typically used when creating a new replica, such as:</p>
<ul>
<li>scale-out</li>
<li>rebuild</li>
<li>clone</li>
</ul>
<p>The data will be streamed in via stdin. If any error occurs during the assembly process,
<p>The data will be streamed in via stdin. If any error occurs during the process,
the action must be able to guarantee idempotence to allow for retries from the beginning.
This field cannot be updated.</p>
</td>
Expand Down
2 changes: 2 additions & 0 deletions pkg/constant/lorry.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ const (
ReadWriteAction = "readwrite"
PostProvisionAction = "postProvision"
PreTerminateAction = "preTerminate"
DataDumpAction = "dataDump"
DataLoadAction = "dataLoad"
)

// action envs
Expand Down
4 changes: 2 additions & 2 deletions pkg/controller/component/component_definition_convertor.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,8 +580,8 @@ func (c *compDefLifecycleActionsConvertor) convert(args ...any) (any, error) {
lifecycleActions.MemberLeave = nil
lifecycleActions.Readonly = nil
lifecycleActions.Readwrite = nil
lifecycleActions.DataPopulate = nil
lifecycleActions.DataAssemble = nil
lifecycleActions.DataDump = nil
lifecycleActions.DataLoad = nil
lifecycleActions.Reconfigure = nil
lifecycleActions.AccountProvision = nil

Expand Down
10 changes: 5 additions & 5 deletions pkg/controller/component/lorry_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,8 @@ func getBuiltinActionHandler(synthesizeComp *SynthesizedComponent) appsv1alpha1.
synthesizeComp.LifecycleActions.MemberLeave,
synthesizeComp.LifecycleActions.Readonly,
synthesizeComp.LifecycleActions.Readwrite,
synthesizeComp.LifecycleActions.DataPopulate,
synthesizeComp.LifecycleActions.DataAssemble,
synthesizeComp.LifecycleActions.DataDump,
synthesizeComp.LifecycleActions.DataLoad,
synthesizeComp.LifecycleActions.Reconfigure,
// synthesizeComp.LifecycleActions.AccountProvision,
}
Expand Down Expand Up @@ -438,9 +438,9 @@ func getActionCommandsWithExecImageOrContainerName(synthesizeComp *SynthesizedCo
constant.MemberLeaveAction: synthesizeComp.LifecycleActions.MemberLeave,
constant.ReadonlyAction: synthesizeComp.LifecycleActions.Readonly,
constant.ReadWriteAction: synthesizeComp.LifecycleActions.Readwrite,
// "dataPopulate": synthesizeComp.LifecycleActions.DataPopulate,
// "dataAssemble": synthesizeComp.LifecycleActions.DataAssemble,
// "reconfigure": synthesizeComp.LifecycleActions.Reconfigure,
constant.DataDumpAction: synthesizeComp.LifecycleActions.DataDump,
constant.DataLoadAction: synthesizeComp.LifecycleActions.DataLoad,
// "reconfigure": synthesizeComp.LifecycleActions.Reconfigure,
// "accountProvision": synthesizeComp.LifecycleActions.AccountProvision,
}

Expand Down
10 changes: 10 additions & 0 deletions pkg/lorry/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,16 @@ func (cli *lorryClient) PreTerminate(ctx context.Context) error {
return err
}

func (cli *lorryClient) DataDump(ctx context.Context) error {
_, err := cli.Request(ctx, string(DataDumpOperation), http.MethodPost, nil)
return err
}

func (cli *lorryClient) DataLoad(ctx context.Context) error {
_, err := cli.Request(ctx, string(DataLoadOperation), http.MethodPost, nil)
return err
}

func (cli *lorryClient) Request(ctx context.Context, operation, method string, req map[string]any) (map[string]any, error) {
if cli.requester == nil {
return nil, errors.New("lorry client's requester must be set")
Expand Down
28 changes: 28 additions & 0 deletions pkg/lorry/client/client_mock.go

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

3 changes: 3 additions & 0 deletions pkg/lorry/client/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,7 @@ type Client interface {
Unlock(ctx context.Context) error
PostProvision(ctx context.Context, componentNames, podNames, podIPs, podHostNames, podHostIPs string) error
PreTerminate(ctx context.Context) error

DataDump(ctx context.Context) error
DataLoad(ctx context.Context) error
}
83 changes: 83 additions & 0 deletions pkg/lorry/operations/replica/data_dump.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
Copyright (C) 2022-2024 ApeCloud Co., Ltd
This file is part of KubeBlocks project
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package replica

import (
"context"
"encoding/json"
"strings"

"github.com/go-logr/logr"
"github.com/spf13/viper"

"github.com/apecloud/kubeblocks/pkg/constant"
"github.com/apecloud/kubeblocks/pkg/lorry/operations"
"github.com/apecloud/kubeblocks/pkg/lorry/util"
)

type dataDump struct {
operations.Base
logger logr.Logger
Command []string
}

func init() {
err := operations.Register(strings.ToLower(string(util.DataDumpOperation)), &dataDump{})
if err != nil {
panic(err.Error())
}
}

func (s *dataDump) Init(_ context.Context) error {
actionJSON := viper.GetString(constant.KBEnvActionCommands)
if actionJSON != "" {
actionCommands := map[string][]string{}
err := json.Unmarshal([]byte(actionJSON), &actionCommands)
if err != nil {
s.logger.Info("get action commands failed", "error", err.Error())
return err
}
cmd, ok := actionCommands[constant.DataDumpAction]
if ok && len(cmd) > 0 {
s.Command = cmd
}
}
return nil
}

func (s *dataDump) PreCheck(ctx context.Context, req *operations.OpsRequest) error {
return nil
}

func (s *dataDump) Do(ctx context.Context, req *operations.OpsRequest) (*operations.OpsResponse, error) {
return nil, doCommonAction(ctx, s.logger, "dataDump", s.Command)
}

func doCommonAction(ctx context.Context, logger logr.Logger, action string, commands []string) error {
envs, err := util.GetGlobalSharedEnvs()
if err != nil {
return err
}
output, err := util.ExecCommand(ctx, commands, envs)
if output != "" {
logger.Info(action, "output", output)
}
return err
}
Loading

0 comments on commit ea1cfd2

Please sign in to comment.