Skip to content

Commit 9e88845

Browse files
committed
Feature(copy tool): add copy tool2 command
Signed-off-by: 0fatal <2816813070@qq.com>
1 parent a703f1e commit 9e88845

File tree

7 files changed

+274
-1
lines changed

7 files changed

+274
-1
lines changed

cli/command/cmd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/opencurve/curveadm/cli/command/client"
3232
"github.com/opencurve/curveadm/cli/command/cluster"
3333
"github.com/opencurve/curveadm/cli/command/config"
34+
copycmd "github.com/opencurve/curveadm/cli/command/copy"
3435
"github.com/opencurve/curveadm/cli/command/hosts"
3536
"github.com/opencurve/curveadm/cli/command/monitor"
3637
"github.com/opencurve/curveadm/cli/command/pfs"
@@ -66,6 +67,7 @@ func addSubCommands(cmd *cobra.Command, curveadm *cli.CurveAdm) {
6667
target.NewTargetCommand(curveadm), // curveadm target ...
6768
pfs.NewPFSCommand(curveadm), // curveadm pfs ...
6869
monitor.NewMonitorCommand(curveadm), // curveadm monitor ...
70+
copycmd.NewCopyCommand(curveadm), // curveadm copy ...
6971

7072
NewAuditCommand(curveadm), // curveadm audit
7173
NewCleanCommand(curveadm), // curveadm clean

cli/command/copy/cmd.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2023 NetEase Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/*
18+
* Project: CurveAdm
19+
* Created Date: 2023-12-25
20+
* Author: Xinyu Zhuo (0fatal)
21+
*/
22+
23+
package copy
24+
25+
import (
26+
"github.com/opencurve/curveadm/cli/cli"
27+
cliutil "github.com/opencurve/curveadm/internal/utils"
28+
"github.com/spf13/cobra"
29+
)
30+
31+
func NewCopyCommand(curveadm *cli.CurveAdm) *cobra.Command {
32+
cmd := &cobra.Command{
33+
Use: "copy",
34+
Short: "Manage copy",
35+
Args: cliutil.NoArgs,
36+
RunE: cliutil.ShowHelp(curveadm.Err()),
37+
}
38+
39+
cmd.AddCommand(
40+
NewCopyTool2Command(curveadm),
41+
)
42+
return cmd
43+
}

cli/command/copy/tool.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright (c) 2023 NetEase Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/*
18+
* Project: CurveAdm
19+
* Created Date: 2023-12-25
20+
* Author: Xinyu Zhuo (0fatal)
21+
*/
22+
23+
package copy
24+
25+
import (
26+
"github.com/fatih/color"
27+
"github.com/opencurve/curveadm/cli/cli"
28+
comm "github.com/opencurve/curveadm/internal/common"
29+
"github.com/opencurve/curveadm/internal/configure/topology"
30+
"github.com/opencurve/curveadm/internal/errno"
31+
"github.com/opencurve/curveadm/internal/playbook"
32+
cliutil "github.com/opencurve/curveadm/internal/utils"
33+
"github.com/spf13/cobra"
34+
)
35+
36+
var (
37+
COPY_TOOL_PLAYBOOK_STEPS = []int{
38+
playbook.COPY_TOOL,
39+
}
40+
)
41+
42+
type copyOptions struct {
43+
host string
44+
path string
45+
confPath string
46+
}
47+
48+
func NewCopyTool2Command(curveadm *cli.CurveAdm) *cobra.Command {
49+
var options copyOptions
50+
51+
cmd := &cobra.Command{
52+
Use: "tool [OPTIONS]",
53+
Short: "Copy tool v2 on the specified host",
54+
Args: cliutil.NoArgs,
55+
RunE: func(cmd *cobra.Command, args []string) error {
56+
return runCopyTool(curveadm, options)
57+
},
58+
DisableFlagsInUseLine: true,
59+
}
60+
61+
flags := cmd.Flags()
62+
flags.StringVar(&options.host, "host", "localhost", "Specify target host")
63+
flags.StringVar(&options.path, "path", "/usr/local/bin/curve", "Specify target copy path of tool v2")
64+
flags.StringVar(&options.confPath, "confPath", "/etc/curve/curve.yaml", "Specify target config path of tool v2")
65+
66+
return cmd
67+
}
68+
69+
func genCopyToolPlaybook(curveadm *cli.CurveAdm,
70+
dcs []*topology.DeployConfig,
71+
options copyOptions,
72+
) (*playbook.Playbook, error) {
73+
configs := curveadm.FilterDeployConfig(dcs, topology.FilterOption{Id: "*", Role: "*", Host: options.host})[:1]
74+
if len(configs) == 0 {
75+
return nil, errno.ERR_NO_SERVICES_MATCHED
76+
}
77+
steps := COPY_TOOL_PLAYBOOK_STEPS
78+
pb := playbook.NewPlaybook(curveadm)
79+
for _, step := range steps {
80+
pb.AddStep(&playbook.PlaybookStep{
81+
Type: step,
82+
Configs: configs,
83+
Options: map[string]interface{}{
84+
comm.KEY_COPY_PATH: options.path,
85+
comm.KEY_COPY_CONF_PATH: options.confPath,
86+
},
87+
})
88+
}
89+
return pb, nil
90+
}
91+
92+
func runCopyTool(curveadm *cli.CurveAdm, options copyOptions) error {
93+
dcs, err := curveadm.ParseTopology()
94+
if err != nil {
95+
return err
96+
}
97+
98+
pb, err := genCopyToolPlaybook(curveadm, dcs, options)
99+
if err != nil {
100+
return err
101+
}
102+
103+
err = pb.Run()
104+
if err != nil {
105+
return err
106+
}
107+
108+
curveadm.WriteOutln(color.GreenString("Copy %s to %s success."),
109+
"curve tool v2", options.host)
110+
return nil
111+
}

internal/common/common.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ const (
117117
KEY_SERVICE_HOSTS = "SERVICE_HOSTS"
118118
KEY_MONITOR_STATUS = "MONITOR_STATUS"
119119
CLEANED_MONITOR_CONF = "-"
120+
121+
// copy
122+
KEY_COPY_PATH = "COPY_PATH"
123+
KEY_COPY_CONF_PATH = "COPY_CONF_PATH"
120124
)
121125

122126
// others

internal/playbook/factory.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ const (
8484
INSTALL_CLIENT
8585
UNINSTALL_CLIENT
8686
ATTACH_LEADER_OR_RANDOM_CONTAINER
87+
COPY_TOOL
8788

8889
// bs
8990
FORMAT_CHUNKFILE_POOL
@@ -250,6 +251,8 @@ func (p *Playbook) createTasks(step *PlaybookStep) (*tasks.Tasks, error) {
250251
t, err = comm.NewInstallClientTask(curveadm, config.GetCC(i))
251252
case UNINSTALL_CLIENT:
252253
t, err = comm.NewUninstallClientTask(curveadm, nil)
254+
case COPY_TOOL:
255+
t, err = comm.NewCopyToolTask(curveadm, config.GetDC(i))
253256
// bs
254257
case FORMAT_CHUNKFILE_POOL:
255258
t, err = bs.NewFormatChunkfilePoolTask(curveadm, config.GetFC(i))
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright (c) 2023 NetEase Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/*
18+
* Project: CurveAdm
19+
* Created Date: 2023-12-25
20+
* Author: Xinyu Zhuo (0fatal)
21+
*/
22+
23+
package common
24+
25+
import (
26+
"fmt"
27+
"github.com/opencurve/curveadm/cli/cli"
28+
comm "github.com/opencurve/curveadm/internal/common"
29+
"github.com/opencurve/curveadm/internal/configure/topology"
30+
"github.com/opencurve/curveadm/internal/errno"
31+
"github.com/opencurve/curveadm/internal/task/step"
32+
"github.com/opencurve/curveadm/internal/task/task"
33+
tui "github.com/opencurve/curveadm/internal/tui/common"
34+
"github.com/opencurve/curveadm/pkg/module"
35+
"path/filepath"
36+
)
37+
38+
func checkPathExist(path string, sshConfig *module.SSHConfig, curveadm *cli.CurveAdm) error {
39+
sshClient, err := module.NewSSHClient(*sshConfig)
40+
if err != nil {
41+
return errno.ERR_SSH_CONNECT_FAILED.E(err)
42+
}
43+
44+
module := module.NewModule(sshClient)
45+
cmd := module.Shell().Stat(path)
46+
if _, err := cmd.Execute(curveadm.ExecOptions()); err == nil {
47+
if pass := tui.ConfirmYes(tui.PromptPathExist(path)); !pass {
48+
return errno.ERR_CANCEL_OPERATION
49+
}
50+
}
51+
return nil
52+
}
53+
54+
func NewCopyToolTask(curveadm *cli.CurveAdm, dc *topology.DeployConfig) (*task.Task, error) {
55+
layout := dc.GetProjectLayout()
56+
path := curveadm.MemStorage().Get(comm.KEY_COPY_PATH).(string)
57+
confPath := curveadm.MemStorage().Get(comm.KEY_COPY_CONF_PATH).(string)
58+
hc, err := curveadm.GetHost(dc.GetHost())
59+
if err != nil {
60+
return nil, err
61+
}
62+
63+
serviceId := curveadm.GetServiceId(dc.GetId())
64+
containerId, err := curveadm.GetContainerId(serviceId)
65+
if err != nil {
66+
return nil, err
67+
}
68+
69+
if err = checkPathExist(path, hc.GetSSHConfig(), curveadm); err != nil {
70+
return nil, err
71+
}
72+
if err = checkPathExist(confPath, hc.GetSSHConfig(), curveadm); err != nil {
73+
return nil, err
74+
}
75+
76+
subname := fmt.Sprintf("host=%s", dc.GetHost())
77+
t := task.NewTask("Copy version 2 tool to host", subname, hc.GetSSHConfig())
78+
79+
t.AddStep(&step.CreateDirectory{
80+
Paths: []string{filepath.Dir(path)},
81+
ExecOptions: curveadm.ExecOptions(),
82+
})
83+
t.AddStep(&step.CopyFromContainer{
84+
ContainerSrcPath: layout.ToolsV2BinaryPath,
85+
ContainerId: containerId,
86+
HostDestPath: path,
87+
ExecOptions: curveadm.ExecOptions(),
88+
})
89+
t.AddStep(&step.CreateDirectory{
90+
Paths: []string{filepath.Dir(confPath)},
91+
ExecOptions: curveadm.ExecOptions(),
92+
})
93+
t.AddStep(&step.CopyFromContainer{
94+
ContainerSrcPath: layout.ToolsV2ConfSystemPath,
95+
ContainerId: containerId,
96+
HostDestPath: confPath,
97+
ExecOptions: curveadm.ExecOptions(),
98+
})
99+
100+
return t, nil
101+
}

internal/tui/common/prompt.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ to watch the formatting progress.
7171
`
7272
PROMPT_CANCEL_OPERATION = `[x] {{.operation}} canceled`
7373

74+
PROMPT_PATH_EXIST = `{{.path}} already exists.
75+
`
76+
7477
DEFAULT_CONFIRM_PROMPT = "Do you want to continue?"
7578
)
7679

@@ -210,7 +213,7 @@ func PromptErrorCode(code int, description, clue, logpath string) string {
210213
if len(clue) > 0 {
211214
prompt.data["clue"] = prettyClue(clue)
212215
}
213-
prompt.data["website"] = fmt.Sprintf("https://github.com/opencurve/curveadm/wiki/errno%d#%06d", code / 100000, code)
216+
prompt.data["website"] = fmt.Sprintf("https://github.com/opencurve/curveadm/wiki/errno%d#%06d", code/100000, code)
214217
if len(logpath) > 0 {
215218
prompt.data["logpath"] = logpath
216219
}
@@ -230,3 +233,9 @@ func PromptAutoUpgrade(version string) string {
230233
prompt.data["version"] = version
231234
return prompt.Build()
232235
}
236+
237+
func PromptPathExist(path string) string {
238+
prompt := NewPrompt(color.YellowString(PROMPT_PATH_EXIST) + DEFAULT_CONFIRM_PROMPT)
239+
prompt.data["path"] = path
240+
return prompt.Build()
241+
}

0 commit comments

Comments
 (0)