Skip to content

Commit a52be8a

Browse files
committed
Feature(install tool): add install tool command
Signed-off-by: 0fatal <[email protected]>
1 parent a703f1e commit a52be8a

File tree

7 files changed

+209
-1
lines changed

7 files changed

+209
-1
lines changed

cli/command/cmd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/opencurve/curveadm/cli/command/cluster"
3333
"github.com/opencurve/curveadm/cli/command/config"
3434
"github.com/opencurve/curveadm/cli/command/hosts"
35+
"github.com/opencurve/curveadm/cli/command/install"
3536
"github.com/opencurve/curveadm/cli/command/monitor"
3637
"github.com/opencurve/curveadm/cli/command/pfs"
3738
"github.com/opencurve/curveadm/cli/command/playground"
@@ -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+
install.NewInstallCommand(curveadm), // curveadm install ...
6971

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

cli/command/install/cmd.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package install
2+
3+
import (
4+
"github.com/opencurve/curveadm/cli/cli"
5+
cliutil "github.com/opencurve/curveadm/internal/utils"
6+
"github.com/spf13/cobra"
7+
)
8+
9+
func NewInstallCommand(curveadm *cli.CurveAdm) *cobra.Command {
10+
cmd := &cobra.Command{
11+
Use: "install",
12+
Short: "Manage install",
13+
Args: cliutil.NoArgs,
14+
RunE: cliutil.ShowHelp(curveadm.Err()),
15+
}
16+
17+
cmd.AddCommand(
18+
NewInstallToolCommand(curveadm),
19+
)
20+
return cmd
21+
}

cli/command/install/tool.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package install
2+
3+
import (
4+
"github.com/fatih/color"
5+
"github.com/opencurve/curveadm/cli/cli"
6+
comm "github.com/opencurve/curveadm/internal/common"
7+
"github.com/opencurve/curveadm/internal/configure/topology"
8+
"github.com/opencurve/curveadm/internal/errno"
9+
"github.com/opencurve/curveadm/internal/playbook"
10+
cliutil "github.com/opencurve/curveadm/internal/utils"
11+
"github.com/spf13/cobra"
12+
)
13+
14+
var (
15+
INSTALL_TOOL_PLAYBOOK_STEPS = []int{
16+
playbook.INSTALL_TOOL,
17+
}
18+
)
19+
20+
type installOptions struct {
21+
host string
22+
path string
23+
confPath string
24+
}
25+
26+
func NewInstallToolCommand(curveadm *cli.CurveAdm) *cobra.Command {
27+
var options installOptions
28+
29+
cmd := &cobra.Command{
30+
Use: "tool [OPTIONS]",
31+
Short: "Install tool v2 on the specified host",
32+
Args: cliutil.NoArgs,
33+
RunE: func(cmd *cobra.Command, args []string) error {
34+
return runInstallTool(curveadm, options)
35+
},
36+
DisableFlagsInUseLine: true,
37+
}
38+
39+
flags := cmd.Flags()
40+
flags.StringVar(&options.host, "host", "localhost", "Specify target host")
41+
flags.StringVar(&options.path, "path", "/usr/local/bin/curve", "Specify target install path of tool v2")
42+
flags.StringVar(&options.confPath, "confPath", "/etc/curve/curve.yaml", "Specify target config path of tool v2")
43+
44+
return cmd
45+
}
46+
47+
func genInstallToolPlaybook(curveadm *cli.CurveAdm,
48+
dcs []*topology.DeployConfig,
49+
options installOptions,
50+
) (*playbook.Playbook, error) {
51+
configs := curveadm.FilterDeployConfig(dcs, topology.FilterOption{Id: "*", Role: "*", Host: options.host})[:1]
52+
if len(configs) == 0 {
53+
return nil, errno.ERR_NO_SERVICES_MATCHED
54+
}
55+
steps := INSTALL_TOOL_PLAYBOOK_STEPS
56+
pb := playbook.NewPlaybook(curveadm)
57+
for _, step := range steps {
58+
pb.AddStep(&playbook.PlaybookStep{
59+
Type: step,
60+
Configs: configs,
61+
Options: map[string]interface{}{
62+
comm.KEY_INSTALL_PATH: options.path,
63+
comm.KEY_INSTALL_CONF_PATH: options.confPath,
64+
},
65+
})
66+
}
67+
return pb, nil
68+
}
69+
70+
func runInstallTool(curveadm *cli.CurveAdm, options installOptions) error {
71+
dcs, err := curveadm.ParseTopology()
72+
if err != nil {
73+
return err
74+
}
75+
76+
pb, err := genInstallToolPlaybook(curveadm, dcs, options)
77+
if err != nil {
78+
return err
79+
}
80+
81+
err = pb.Run()
82+
if err != nil {
83+
return err
84+
}
85+
86+
curveadm.WriteOutln(color.GreenString("Install %s to %s success."),
87+
"curve tool v2", options.host)
88+
return nil
89+
}

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+
// install
122+
KEY_INSTALL_PATH = "INSTALL_PATH"
123+
KEY_INSTALL_CONF_PATH = "INSTALL_CONF_PATH"
120124
)
121125

122126
// others

internal/playbook/factory.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/opencurve/curveadm/internal/task/task/checker"
3232
comm "github.com/opencurve/curveadm/internal/task/task/common"
3333
"github.com/opencurve/curveadm/internal/task/task/fs"
34+
"github.com/opencurve/curveadm/internal/task/task/install"
3435
"github.com/opencurve/curveadm/internal/task/task/monitor"
3536
pg "github.com/opencurve/curveadm/internal/task/task/playground"
3637
"github.com/opencurve/curveadm/internal/tasks"
@@ -84,6 +85,7 @@ const (
8485
INSTALL_CLIENT
8586
UNINSTALL_CLIENT
8687
ATTACH_LEADER_OR_RANDOM_CONTAINER
88+
INSTALL_TOOL
8789

8890
// bs
8991
FORMAT_CHUNKFILE_POOL
@@ -250,6 +252,8 @@ func (p *Playbook) createTasks(step *PlaybookStep) (*tasks.Tasks, error) {
250252
t, err = comm.NewInstallClientTask(curveadm, config.GetCC(i))
251253
case UNINSTALL_CLIENT:
252254
t, err = comm.NewUninstallClientTask(curveadm, nil)
255+
case INSTALL_TOOL:
256+
t, err = install.NewInstallToolTask(curveadm, config.GetDC(i))
253257
// bs
254258
case FORMAT_CHUNKFILE_POOL:
255259
t, err = bs.NewFormatChunkfilePoolTask(curveadm, config.GetFC(i))
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package install
2+
3+
import (
4+
"fmt"
5+
"github.com/opencurve/curveadm/cli/cli"
6+
comm "github.com/opencurve/curveadm/internal/common"
7+
"github.com/opencurve/curveadm/internal/configure/topology"
8+
"github.com/opencurve/curveadm/internal/errno"
9+
"github.com/opencurve/curveadm/internal/task/step"
10+
"github.com/opencurve/curveadm/internal/task/task"
11+
tui "github.com/opencurve/curveadm/internal/tui/common"
12+
"github.com/opencurve/curveadm/pkg/module"
13+
"path/filepath"
14+
)
15+
16+
func checkPathExist(path string, sshConfig *module.SSHConfig, curveadm *cli.CurveAdm) error {
17+
sshClient, err := module.NewSSHClient(*sshConfig)
18+
if err != nil {
19+
return errno.ERR_SSH_CONNECT_FAILED.E(err)
20+
}
21+
22+
module := module.NewModule(sshClient)
23+
cmd := module.Shell().Stat(path)
24+
if _, err := cmd.Execute(curveadm.ExecOptions()); err == nil {
25+
if pass := tui.ConfirmYes(tui.PromptPathExist(path)); !pass {
26+
return errno.ERR_CANCEL_OPERATION
27+
}
28+
}
29+
return nil
30+
}
31+
32+
func NewInstallToolTask(curveadm *cli.CurveAdm, dc *topology.DeployConfig) (*task.Task, error) {
33+
layout := dc.GetProjectLayout()
34+
path := curveadm.MemStorage().Get(comm.KEY_INSTALL_PATH).(string)
35+
confPath := curveadm.MemStorage().Get(comm.KEY_INSTALL_CONF_PATH).(string)
36+
hc, err := curveadm.GetHost(dc.GetHost())
37+
if err != nil {
38+
return nil, err
39+
}
40+
41+
serviceId := curveadm.GetServiceId(dc.GetId())
42+
containerId, err := curveadm.GetContainerId(serviceId)
43+
if err != nil {
44+
return nil, err
45+
}
46+
47+
if err = checkPathExist(path, hc.GetSSHConfig(), curveadm); err != nil {
48+
return nil, err
49+
}
50+
if err = checkPathExist(confPath, hc.GetSSHConfig(), curveadm); err != nil {
51+
return nil, err
52+
}
53+
54+
subname := fmt.Sprintf("host=%s", dc.GetHost())
55+
t := task.NewTask("Install tool v2", subname, hc.GetSSHConfig())
56+
57+
t.AddStep(&step.CreateDirectory{
58+
Paths: []string{filepath.Dir(path)},
59+
ExecOptions: curveadm.ExecOptions(),
60+
})
61+
t.AddStep(&step.CopyFromContainer{
62+
ContainerSrcPath: layout.ToolsV2BinaryPath,
63+
ContainerId: containerId,
64+
HostDestPath: path,
65+
ExecOptions: curveadm.ExecOptions(),
66+
})
67+
t.AddStep(&step.CreateDirectory{
68+
Paths: []string{filepath.Dir(confPath)},
69+
ExecOptions: curveadm.ExecOptions(),
70+
})
71+
t.AddStep(&step.CopyFromContainer{
72+
ContainerSrcPath: layout.ToolsV2ConfSystemPath,
73+
ContainerId: containerId,
74+
HostDestPath: confPath,
75+
ExecOptions: curveadm.ExecOptions(),
76+
})
77+
78+
return t, nil
79+
}

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)