Skip to content

Commit 397fc08

Browse files
authored
Merge pull request #201 from legionxiong/auto-mount-disk
Feature: support direct disk mounting for service container
2 parents af342de + 2c50545 commit 397fc08

File tree

18 files changed

+476
-135
lines changed

18 files changed

+476
-135
lines changed

cli/command/disks/commit.go

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727

2828
"github.com/fatih/color"
2929
"github.com/opencurve/curveadm/cli/cli"
30-
"github.com/opencurve/curveadm/internal/common"
3130
comm "github.com/opencurve/curveadm/internal/common"
3231
"github.com/opencurve/curveadm/internal/configure/disks"
3332
"github.com/opencurve/curveadm/internal/configure/topology"
@@ -40,7 +39,8 @@ import (
4039
)
4140

4241
const (
43-
COMMIT_EXAMPLE = `Examples:
42+
HOST_DEVICE_SEP = ":"
43+
COMMIT_EXAMPLE = `Examples:
4444
$ curveadm disks commit /path/to/disks.yaml # Commit disks`
4545
)
4646

@@ -89,35 +89,55 @@ func readAndCheckDisks(curveadm *cli.CurveAdm, options commitOptions) (string, [
8989
}
9090

9191
// 3) check disks data
92-
dcs, err = disks.ParseDisks(data, curveadm)
92+
dcs, err = disks.ParseDisks(data)
9393
return data, dcs, err
9494
}
9595

9696
func assambleNewDiskRecords(dcs []*disks.DiskConfig,
9797
oldDiskRecords []storage.Disk) ([]storage.Disk, []storage.Disk) {
98-
keySep := ":"
9998
newDiskMap := make(map[string]bool)
10099

100+
// "ServiceMountDevice=0" means write disk UUID into /etc/fstab for host mounting.
101+
// "ServiceMountDevice=1" means not to update /etc/fstab, the disk UUID will be wrote
102+
// into the config of service(chunkserver) container for disk automatic mounting.
103+
serviceMountDevice := 0 // 0: false, 1: true
101104
var newDiskRecords, diskRecordDeleteList []storage.Disk
102105
for _, dc := range dcs {
103106
for _, host := range dc.GetHost() {
104-
key := strings.Join([]string{host, dc.GetDevice()}, keySep)
107+
device := dc.GetDevice()
108+
key := strings.Join([]string{host, device}, HOST_DEVICE_SEP)
105109
newDiskMap[key] = true
110+
if dc.GetServiceMount() {
111+
serviceMountDevice = 1
112+
}
113+
diskSize := comm.DISK_DEFAULT_NULL_SIZE
114+
diskUri := comm.DISK_DEFAULT_NULL_URI
115+
diskChunkserverId := comm.DISK_DEFAULT_NULL_CHUNKSERVER_ID
116+
for _, dr := range oldDiskRecords {
117+
if dr.Host == host && device == dr.Device {
118+
diskSize = dr.Size
119+
diskUri = dr.URI
120+
diskChunkserverId = dr.ChunkServerID
121+
break
122+
}
123+
}
106124
newDiskRecords = append(
107125
newDiskRecords, storage.Disk{
108-
Host: host,
109-
Device: dc.GetDevice(),
110-
Size: comm.DISK_DEFAULT_NULL_SIZE,
111-
URI: comm.DISK_DEFAULT_NULL_URI,
112-
MountPoint: dc.GetMountPoint(),
113-
FormatPercent: dc.GetFormatPercent(),
114-
ChunkServerID: comm.DISK_DEFAULT_NULL_CHUNKSERVER_ID,
126+
Host: host,
127+
Device: device,
128+
Size: diskSize,
129+
URI: diskUri,
130+
MountPoint: dc.GetMountPoint(),
131+
ContainerImage: dc.GetContainerImage(),
132+
FormatPercent: dc.GetFormatPercent(),
133+
ChunkServerID: diskChunkserverId,
134+
ServiceMountDevice: serviceMountDevice,
115135
})
116136
}
117137
}
118138

119139
for _, dr := range oldDiskRecords {
120-
key := strings.Join([]string{dr.Host, dr.Device}, keySep)
140+
key := strings.Join([]string{dr.Host, dr.Device}, HOST_DEVICE_SEP)
121141
if _, ok := newDiskMap[key]; !ok {
122142
diskRecordDeleteList = append(diskRecordDeleteList, dr)
123143
}
@@ -127,19 +147,16 @@ func assambleNewDiskRecords(dcs []*disks.DiskConfig,
127147
}
128148

129149
func writeDiskRecord(dr storage.Disk, curveadm *cli.CurveAdm) error {
130-
if diskRecords, err := curveadm.Storage().GetDisk(
131-
common.DISK_FILTER_DEVICE, dr.Host, dr.Device); err != nil {
150+
if err := curveadm.Storage().SetDisk(
151+
dr.Host,
152+
dr.Device,
153+
dr.MountPoint,
154+
dr.ContainerImage,
155+
dr.FormatPercent,
156+
dr.ServiceMountDevice); err != nil {
132157
return err
133-
} else if len(diskRecords) == 0 {
134-
if err := curveadm.Storage().SetDisk(
135-
dr.Host,
136-
dr.Device,
137-
dr.MountPoint,
138-
dr.ContainerImage,
139-
dr.FormatPercent); err != nil {
140-
return err
141-
}
142158
}
159+
143160
return nil
144161
}
145162

@@ -153,15 +170,17 @@ func syncDiskRecords(data string, dcs []*disks.DiskConfig,
153170
oldDiskRecordsString := tui.FormatDisks(oldDiskRecords)
154171
newDiskRecordsString := tui.FormatDisks(newDiskRecords)
155172

156-
if !options.slient {
157-
diff := utils.Diff(oldDiskRecordsString, newDiskRecordsString)
158-
curveadm.WriteOutln(diff)
159-
}
173+
if len(newDiskRecords) != len(oldDiskRecords) {
174+
if !options.slient {
175+
diff := utils.Diff(oldDiskRecordsString, newDiskRecordsString)
176+
curveadm.WriteOutln(diff)
177+
}
160178

161-
pass := tuicomm.ConfirmYes("Disk changes are showing above. Do you want to continue?")
162-
if !pass {
163-
curveadm.WriteOut(tuicomm.PromptCancelOpetation("commit disk table"))
164-
return errno.ERR_CANCEL_OPERATION
179+
pass := tuicomm.ConfirmYes("Disk changes are showing above. Do you want to continue?")
180+
if !pass {
181+
curveadm.WriteOut(tuicomm.PromptCancelOpetation("commit disk table"))
182+
return errno.ERR_CANCEL_OPERATION
183+
}
165184
}
166185

167186
// write new disk records

cli/command/format.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,17 @@ func runFormat(curveadm *cli.CurveAdm, options formatOptions) error {
155155
if err != nil {
156156
return err
157157
}
158-
fc.UseDiskUri = true
159-
chunkserverId := dr.ChunkServerID
160-
if len(chunkserverId) > 1 {
158+
159+
fc.FromDiskRecord = true
160+
161+
// "ServiceMountDevice=0" means write disk UUID into /etc/fstab for host mounting.
162+
// "ServiceMountDevice=1" means not to update /etc/fstab, the disk UUID will be wrote
163+
// into the config of service(chunkserver) container for disk automatic mounting.
164+
if dr.ServiceMountDevice != 0 {
165+
fc.ServiceMountDevice = true
166+
}
167+
168+
if dr.ChunkServerID != comm.DISK_DEFAULT_NULL_CHUNKSERVER_ID {
161169
// skip formatting the disk with nonempty chunkserver id
162170
continue
163171
}

configs/bs/cluster/disks.yaml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
global:
22
format_percent: 95
33
container_image: opencurvedocker/curvebs:v1.2
4+
service_mount_device: false # disk device will be mounted by service(chunkserver) directly if set "true", default "false"
45
host:
56
- curve-1
67
- curve-2
78
- curve-3
89

910
disk:
10-
- device: /dev/sdb1
11-
mount: /data/chunkserver0
11+
- device: /dev/sdb1 # disk device path
12+
mount: /data/chunkserver0 # mount point for disk formatting, consistent with the "data_dir" field of chunkserver service in topology
1213
- device: /dev/sdc1
1314
mount: /data/chunkserver1
14-
format_percent: 90
15+
format_percent: 90 # use a different value for disk format percent
1516
- device: /dev/sdd1
1617
mount: /data/chunkserver2
17-
exclude: # for the use case that some hosts have not certain disk device
18+
exclude: # for the use case that disk device does not exist in some hosts
1819
- curve-3
1920
- device: /dev/sde1
2021
mount: /data/chunkserver3
21-
host:
22+
host: # override global host config, for the use case that disk device only exists in some hosts
2223
- curve-1
2324
- curve-2

internal/common/common.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ const (
5757
DISK_FILTER_MOUNT = "mount"
5858
DISK_FILTER_SERVICE = "service"
5959
DISK_EXCLUDE_HOST = "exclude"
60-
61-
DISK_FORMAT_PERCENT = "format_percent"
60+
DISK_SERVICE_MOUNT_DEVICE = "service_mount_device"
61+
DISK_FORMAT_PERCENT = "format_percent"
6262

6363
DISK_FORMAT_MOUNT_POINT = "mount"
6464
DISK_FORMAT_CONTAINER_IMAGE = "container_image"

internal/configure/common/item_set.go

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const (
3535
REQUIRE_BOOL
3636
REQUIRE_INT
3737
REQUIRE_POSITIVE_INTEGER
38-
REQUIRE_SLICE
38+
REQUIRE_STRING_SLICE
3939
)
4040

4141
type (
@@ -82,6 +82,25 @@ func (itemset *ItemSet) GetAll() []*Item {
8282
return itemset.items
8383
}
8484

85+
func convertSlice[T int | string | any](key, value any) ([]T, error) {
86+
var slice []T
87+
if !utils.IsAnySlice(value) || len(value.([]any)) == 0 {
88+
return slice, errno.ERR_CONFIGURE_VALUE_REQUIRES_NONEMPTY_SLICE
89+
}
90+
anySlice := value.([]any)
91+
switch anySlice[0].(type) {
92+
case T:
93+
for _, str := range anySlice {
94+
slice = append(slice, str.(T))
95+
}
96+
default:
97+
return slice, errno.ERR_UNSUPPORT_CONFIGURE_VALUE_TYPE.
98+
F("%s: %v", key, value)
99+
}
100+
101+
return slice, nil
102+
}
103+
85104
func (itemset *ItemSet) Build(key string, value interface{}) (interface{}, error) {
86105
item := itemset.Get(key)
87106
if item == nil {
@@ -135,34 +154,12 @@ func (itemset *ItemSet) Build(key string, value interface{}) (interface{}, error
135154
return v, nil
136155
}
137156

138-
case REQUIRE_SLICE:
139-
anySlice := value.([]any)
140-
if len(anySlice) > 0 {
141-
switch anySlice[0].(type) {
142-
case string:
143-
return convertSlice[string](value), nil
144-
case int:
145-
return convertSlice[int](value), nil
146-
case bool:
147-
return convertSlice[bool](value), nil
148-
default:
149-
return []any{}, errno.ERR_UNSUPPORT_CONFIGURE_VALUE_TYPE.
150-
F("%s: %v", key, value)
151-
}
152-
}
153-
return []any{}, nil
157+
case REQUIRE_STRING_SLICE:
158+
return convertSlice[string](key, value)
154159

155160
default:
156161
// do nothing
157162
}
158163

159164
return value, nil
160165
}
161-
162-
func convertSlice[T int | string | any](value any) []T {
163-
var slice []T
164-
for _, str := range value.([]any) {
165-
slice = append(slice, str.(T))
166-
}
167-
return slice
168-
}

internal/configure/disks/dc_get.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ func (dc *DiskConfig) getInt(i *comm.Item) int {
5555
return v.(int)
5656
}
5757

58+
func (hc *DiskConfig) getBool(i *comm.Item) bool {
59+
v := hc.get(i)
60+
if v == nil {
61+
return false
62+
}
63+
return v.(bool)
64+
}
65+
5866
func (dc *DiskConfig) getStrSlice(i *comm.Item) []string {
5967
v := dc.get(i)
6068
if v == nil {
@@ -65,6 +73,7 @@ func (dc *DiskConfig) getStrSlice(i *comm.Item) []string {
6573

6674
func (dc *DiskConfig) GetContainerImage() string { return dc.getString(CONFIG_GLOBAL_CONTAINER_IMAGE) }
6775
func (dc *DiskConfig) GetFormatPercent() int { return dc.getInt(CONFIG_GLOBAL_FORMAT_PERCENT) }
76+
func (dc *DiskConfig) GetServiceMount() bool { return dc.getBool(CONFIG_GLOBAL_SERVICE_MOUNT_DEVICE) }
6877
func (dc *DiskConfig) GetHost() []string { return dc.getStrSlice(CONFIG_GLOBAL_HOST) }
6978
func (dc *DiskConfig) GetDevice() string { return dc.getString(CONFIG_DISK_DEVICE) }
7079
func (dc *DiskConfig) GetMountPoint() string { return dc.getString(CONFIG_DISK_MOUNT_POINT) }

internal/configure/disks/dc_item.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,20 @@ var (
4848
DEFAULT_FORMAT_PERCENT,
4949
)
5050

51+
CONFIG_GLOBAL_SERVICE_MOUNT_DEVICE = itemset.Insert(
52+
common.DISK_SERVICE_MOUNT_DEVICE,
53+
comm.REQUIRE_BOOL,
54+
false,
55+
false,
56+
)
57+
5158
CONFIG_GLOBAL_HOST = itemset.Insert(
5259
common.DISK_FILTER_HOST,
53-
comm.REQUIRE_SLICE,
60+
comm.REQUIRE_STRING_SLICE,
5461
false,
5562
nil,
5663
)
64+
5765
CONFIG_DISK_DEVICE = itemset.Insert(
5866
common.DISK_FILTER_DEVICE,
5967
comm.REQUIRE_STRING,
@@ -70,7 +78,7 @@ var (
7078

7179
CONFIG_DISK_HOST_EXCLUDE = itemset.Insert(
7280
common.DISK_EXCLUDE_HOST,
73-
comm.REQUIRE_SLICE,
81+
comm.REQUIRE_STRING_SLICE,
7482
false,
7583
nil,
7684
)

0 commit comments

Comments
 (0)