Skip to content

Commit d7db7c6

Browse files
committed
[feat]curvefs/curvebs: auto restart&mount
Signed-off-by: Cyber-SiKu <[email protected]> Set the restart policy of the client container to unless-stopped, so that it will automatically remount when the machine restarts Signed-off-by: Cyber-SiKu <[email protected]>
1 parent 78c415a commit d7db7c6

File tree

21 files changed

+627
-35
lines changed

21 files changed

+627
-35
lines changed

cli/command/target/list.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/opencurve/curveadm/cli/cli"
2727
comm "github.com/opencurve/curveadm/internal/common"
2828
"github.com/opencurve/curveadm/internal/playbook"
29+
"github.com/opencurve/curveadm/internal/task/step"
2930
"github.com/opencurve/curveadm/internal/task/task/bs"
3031
"github.com/opencurve/curveadm/internal/tui"
3132
cliutil "github.com/opencurve/curveadm/internal/utils"
@@ -80,10 +81,10 @@ func genListPlaybook(curveadm *cli.CurveAdm, options listOptions) (*playbook.Pla
8081
}
8182

8283
func displayTargets(curveadm *cli.CurveAdm) {
83-
targets := []bs.Target{}
84+
targets := []step.Target{}
8485
value := curveadm.MemStorage().Get(comm.KEY_ALL_TARGETS)
8586
if value != nil {
86-
m := value.(map[string]*bs.Target)
87+
m := value.(map[string]*step.Target)
8788
for _, target := range m {
8889
targets = append(targets, *target)
8990
}

internal/common/common.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,10 @@ const (
130130
AUDIT_STATUS_FAIL
131131
AUDIT_STATUS_CANCEL
132132
)
133+
134+
// container restart policy
135+
const (
136+
POLICY_ALWAYS_RESTART = "always"
137+
POLICY_NEVER_RESTART = "no"
138+
POLICY_UNLESS_STOPPED = "unless-stopped"
139+
)

internal/errno/errno.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,7 @@ var (
539539
ERR_COPY_INTO_CONTAINER_FAILED = EC(630011, "copy file into container failed (docker cp SRC_PATH CONTAINER:DEST_PATH)")
540540
ERR_INSPECT_CONTAINER_FAILED = EC(630012, "get container low-level information failed (docker inspect ID)")
541541
ERR_GET_CONTAINER_LOGS_FAILED = EC(630013, "get container logs failed (docker logs ID)")
542+
ERR_UPDATE_CONTAINER_FAILED = EC(630014, "update container failed (docker update ID)")
542543

543544
// 690: execuetr task (others)
544545
ERR_START_CRONTAB_IN_CONTAINER_FAILED = EC(690000, "start crontab in container failed")

internal/task/step/container.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,14 @@ type (
152152
Success *bool
153153
module.ExecOptions
154154
}
155+
156+
UpdateContainer struct {
157+
ContainerId *string
158+
Restart string
159+
Out *string
160+
Success *bool
161+
module.ExecOptions
162+
}
155163
)
156164

157165
func (s *DockerInfo) Execute(ctx *context.Context) error {
@@ -312,3 +320,12 @@ func (s *ContainerLogs) Execute(ctx *context.Context) error {
312320
out, err := cli.Execute(s.ExecOptions)
313321
return PostHandle(s.Success, s.Out, out, err, errno.ERR_GET_CONTAINER_LOGS_FAILED)
314322
}
323+
324+
func (s *UpdateContainer) Execute(ctx *context.Context) error {
325+
cli := ctx.Module().DockerCli().UpdateContainer(*s.ContainerId)
326+
if len(s.Restart) > 0 {
327+
cli.AddOption("--restart %s", s.Restart)
328+
}
329+
out, err := cli.Execute(s.ExecOptions)
330+
return PostHandle(s.Success, s.Out, out, err, errno.ERR_UPDATE_CONTAINER_FAILED)
331+
}

internal/task/step/daemon.go

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
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-03-16
20+
* Author: Cyber-SiKu
21+
*/
22+
23+
package step
24+
25+
import (
26+
"encoding/json"
27+
"fmt"
28+
"strconv"
29+
"strings"
30+
31+
comm "github.com/opencurve/curveadm/internal/common"
32+
"github.com/opencurve/curveadm/internal/task/context"
33+
"github.com/opencurve/curveadm/internal/utils"
34+
"github.com/opencurve/curveadm/pkg/module"
35+
)
36+
37+
const (
38+
AFTER_TASK_DIR = "/curve/init.d/"
39+
)
40+
41+
var ALLOC_ID int = 0
42+
43+
type afterRunTask struct {
44+
ID int `json:"ID"`
45+
Path string `json:"Path"`
46+
Args []string `json:"Args"`
47+
Env []string `json:"Env"`
48+
Dir string `json:"Dir"`
49+
OutputPath string `json:"OutputPath"`
50+
InputPath string `json:"InputPath"`
51+
}
52+
53+
func (task afterRunTask) ToString() string {
54+
b, err := json.Marshal(task)
55+
if err != nil {
56+
return ""
57+
}
58+
return string(b)
59+
}
60+
61+
func newDaemonTask(path string, args ...string) *afterRunTask {
62+
task := afterRunTask{
63+
ID: ALLOC_ID,
64+
Path: path,
65+
Args: args,
66+
}
67+
return &task
68+
}
69+
70+
type AddDaemonTask struct {
71+
ContainerId *string
72+
Cmd string
73+
Args []string
74+
TaskName string
75+
module.ExecOptions
76+
}
77+
78+
type DelDaemonTask struct {
79+
ContainerId *string
80+
Tid string
81+
MemStorage *utils.SafeMap
82+
module.ExecOptions
83+
}
84+
85+
func (s *AddDaemonTask) getAllocId(ctx *context.Context) {
86+
if ALLOC_ID != 0 {
87+
ALLOC_ID++
88+
return
89+
} else {
90+
// first add daemon task
91+
// create dir AFTER_TASK_DIR
92+
step := ContainerExec{
93+
ContainerId: s.ContainerId,
94+
Command: fmt.Sprintf("mkdir -p %s", AFTER_TASK_DIR),
95+
ExecOptions: s.ExecOptions,
96+
}
97+
err := step.Execute(ctx)
98+
if err != nil {
99+
return
100+
}
101+
}
102+
var count string
103+
// get max id
104+
// The contents of the file are as follows:
105+
// {"ID":1,"Path":"tgtd","Args":null,"Env":null,"Dir":"","OutputPath":"","InputPath":""}
106+
step := ContainerExec{
107+
ContainerId: s.ContainerId,
108+
Command: fmt.Sprintf("grep -r '\"ID\":[0-9]*,' %s | awk -F \":\" '{print $3}' | awk -F \",\" '{print $1}' | sort -n | tail -1", AFTER_TASK_DIR),
109+
Out: &count,
110+
ExecOptions: s.ExecOptions,
111+
}
112+
err := step.Execute(ctx)
113+
if err != nil {
114+
ALLOC_ID = 1
115+
}
116+
id, err := strconv.Atoi(count)
117+
if err != nil {
118+
ALLOC_ID = 1
119+
}
120+
ALLOC_ID = id + 1
121+
}
122+
123+
func (s *AddDaemonTask) Execute(ctx *context.Context) error {
124+
s.getAllocId(ctx)
125+
content := newDaemonTask(s.Cmd, s.Args...).ToString()
126+
step := InstallFile{
127+
Content: &content,
128+
ContainerId: s.ContainerId,
129+
ContainerDestPath: AFTER_TASK_DIR + s.TaskName + ".task",
130+
ExecOptions: s.ExecOptions,
131+
}
132+
return step.Execute(ctx)
133+
}
134+
135+
type Target struct {
136+
Host string
137+
Tid string
138+
Name string
139+
Store string
140+
Portal string
141+
}
142+
143+
func (s *DelDaemonTask) Execute(ctx *context.Context) error {
144+
v := s.MemStorage.Get(comm.KEY_ALL_TARGETS)
145+
target := v.(map[string]*Target)[s.Tid]
146+
if target == nil {
147+
return nil
148+
}
149+
stores := strings.Split(target.Store, "//")
150+
if len(stores) < 2 {
151+
// unable to recognize cbd:pool
152+
return nil
153+
}
154+
path := AFTER_TASK_DIR + "addTarget_" + stores[1] + ".task"
155+
step := ContainerExec{
156+
ContainerId: s.ContainerId,
157+
Command: "rm -f " + path,
158+
ExecOptions: s.ExecOptions,
159+
}
160+
return step.Execute(ctx)
161+
}

internal/task/task/bs/add_target.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ package bs
2424

2525
import (
2626
"fmt"
27+
"regexp"
28+
"strconv"
2729

2830
"github.com/opencurve/curveadm/cli/cli"
2931
comm "github.com/opencurve/curveadm/internal/common"
@@ -34,12 +36,12 @@ import (
3436
)
3537

3638
type TargetOption struct {
37-
Host string
38-
User string
39-
Volume string
40-
Create bool
41-
Size int
42-
Tid string
39+
Host string
40+
User string
41+
Volume string
42+
Create bool
43+
Size int
44+
Tid string
4345
Blocksize uint64
4446
}
4547

@@ -91,5 +93,18 @@ func NewAddTargetTask(curveadm *cli.CurveAdm, cc *configure.ClientConfig) (*task
9193
ExecOptions: curveadm.ExecOptions(),
9294
})
9395

96+
t.AddStep(&step.AddDaemonTask{ // install addTarget.task
97+
ContainerId: &containerId,
98+
Cmd: "/bin/bash",
99+
Args: []string{targetScriptPath, user, volume, strconv.FormatBool(options.Create), strconv.Itoa(options.Size), strconv.FormatUint(options.Blocksize, 10)},
100+
TaskName: "addTarget"+TranslateVolumeName(volume, user),
101+
ExecOptions: curveadm.ExecOptions(),
102+
})
103+
94104
return t, nil
95105
}
106+
107+
func TranslateVolumeName(volume, user string) string {
108+
reg, _ := regexp.Compile("[^a-zA-Z0-9]+")
109+
return reg.ReplaceAllString(volume, "_") + "_" + user + "_"
110+
}

internal/task/task/bs/create_volume.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ func NewCreateVolumeTask(curveadm *cli.CurveAdm, cc *configure.ClientConfig) (*t
8484
script := scripts.CREATE_VOLUME
8585
scriptPath := "/curvebs/nebd/sbin/create.sh"
8686
command := fmt.Sprintf("/bin/bash %s %s %s %d", scriptPath, options.User, options.Volume, options.Size)
87+
8788
t.AddStep(&step.ListContainers{
8889
ShowAll: true,
8990
Format: "'{{.Status}}'",

internal/task/task/bs/delete_target.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,24 @@ func NewDeleteTargetTask(curveadm *cli.CurveAdm, cc *client.ClientConfig) (*task
7575
t.AddStep(&step2CheckTgtdStatus{
7676
output: &output,
7777
})
78+
t.AddStep(&step.ContainerExec{
79+
ContainerId: &containerId,
80+
Command: fmt.Sprintf("tgtadm --lld iscsi --mode target --op show"),
81+
Out: &output,
82+
ExecOptions: curveadm.ExecOptions(),
83+
})
84+
t.AddStep(&step2FormatTarget{
85+
host: options.Host,
86+
hostname: hc.GetHostname(),
87+
output: &output,
88+
memStorage: curveadm.MemStorage(),
89+
})
90+
t.AddStep(&step.DelDaemonTask{
91+
ContainerId: &containerId,
92+
Tid: tid,
93+
MemStorage: curveadm.MemStorage(),
94+
ExecOptions: curveadm.ExecOptions(),
95+
})
7896
t.AddStep(&step.ContainerExec{
7997
ContainerId: &containerId,
8098
Command: fmt.Sprintf("tgtadm --lld iscsi --mode target --op delete --tid %s", tid),

internal/task/task/bs/list_targets.go

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,14 @@ type (
4646
output *string
4747
memStorage *utils.SafeMap
4848
}
49-
50-
Target struct {
51-
Host string
52-
Tid string
53-
Name string
54-
Store string
55-
Portal string
56-
}
5749
)
5850

59-
func addTarget(memStorage *utils.SafeMap, id string, target *Target) {
51+
func addTarget(memStorage *utils.SafeMap, id string, target *step.Target) {
6052
memStorage.TX(func(kv *utils.SafeMap) error {
61-
m := map[string]*Target{}
53+
m := map[string]*step.Target{}
6254
v := kv.Get(comm.KEY_ALL_TARGETS)
6355
if v != nil {
64-
m = v.(map[string]*Target)
56+
m = v.(map[string]*step.Target)
6557
}
6658
m[id] = target
6759
kv.Set(comm.KEY_ALL_TARGETS, m)
@@ -84,13 +76,13 @@ func (s *step2FormatTarget) Execute(ctx *context.Context) error {
8476
output := *s.output
8577
lines := strings.Split(output, "\n")
8678

87-
var target *Target
79+
var target *step.Target
8880
titlePattern := regexp.MustCompile("^Target ([0-9]+): (.+)$")
8981
storePattern := regexp.MustCompile("Backing store path: (cbd:pool//.+)$")
9082
for _, line := range lines {
9183
mu := titlePattern.FindStringSubmatch(line)
9284
if len(mu) > 0 {
93-
target = &Target{
85+
target = &step.Target{
9486
Host: s.host,
9587
Tid: mu[1],
9688
Name: mu[2],

internal/task/task/bs/map.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ func NewMapTask(curveadm *cli.CurveAdm, cc *configure.ClientConfig) (*task.Task,
106106
Args: []string{"nbds_max=64"},
107107
ExecOptions: curveadm.ExecOptions(),
108108
})
109+
t.AddStep(&step.AddDaemonTask{ // install modprobe.task
110+
ContainerId: &containerId,
111+
Cmd: "modprobe",
112+
Args: []string{comm.KERNERL_MODULE_NBD, "nbds_max=64"},
113+
TaskName: "modProbe",
114+
ExecOptions: curveadm.ExecOptions(),
115+
})
109116
t.AddStep(&step.SyncFile{ // sync nebd-client config
110117
ContainerSrcId: &containerId,
111118
ContainerSrcPath: "/curvebs/conf/nebd-client.conf",
@@ -130,6 +137,13 @@ func NewMapTask(curveadm *cli.CurveAdm, cc *configure.ClientConfig) (*task.Task,
130137
Mutate: newToolsV2Mutate(cc, TOOLSV2_CONFIG_DELIMITER),
131138
ExecOptions: curveadm.ExecOptions(),
132139
})
140+
t.AddStep(&step.AddDaemonTask{ // install map.task
141+
ContainerId: &containerId,
142+
Cmd: "/bin/bash",
143+
Args: []string{scriptPath, options.User, options.Volume, mapOptions},
144+
TaskName: "map",
145+
ExecOptions: curveadm.ExecOptions(),
146+
})
133147
t.AddStep(&step.ContainerExec{
134148
ContainerId: &containerId,
135149
Command: command,

0 commit comments

Comments
 (0)