Skip to content

Commit af342de

Browse files
authored
Merge pull request #188 from legionxiong/new-disk-format
Feature: support managing disk information in database
2 parents 10994d9 + de36749 commit af342de

File tree

28 files changed

+1420
-51
lines changed

28 files changed

+1420
-51
lines changed

cli/cli/cli.go

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,14 @@ type CurveAdm struct {
6464
memStorage *utils.SafeMap
6565

6666
// properties (hosts/cluster)
67-
hosts string // hosts
68-
clusterId int // current cluster id
69-
clusterUUId string // current cluster uuid
70-
clusterName string // current cluster name
71-
clusterTopologyData string // cluster topology
72-
clusterPoolData string // cluster pool
67+
hosts string // hosts
68+
disks string // disks
69+
diskRecords []storage.Disk // disk list
70+
clusterId int // current cluster id
71+
clusterUUId string // current cluster uuid
72+
clusterName string // current cluster name
73+
clusterTopologyData string // cluster topology
74+
clusterPoolData string // cluster pool
7375
}
7476

7577
/*
@@ -174,6 +176,23 @@ func (curveadm *CurveAdm) init() error {
174176
log.Field("ClusterName", cluster.Name))
175177
}
176178

179+
// (8) Get Disks
180+
var disks storage.Disks
181+
diskses, err := s.GetDisks()
182+
if err != nil {
183+
log.Error("Get disks failed", log.Field("Error", err))
184+
return errno.ERR_GET_DISKS_FAILED.E(err)
185+
} else if len(diskses) > 0 {
186+
disks = diskses[0]
187+
}
188+
189+
// (9) Get Disk Records
190+
diskRecords, err := s.GetDisk(comm.DISK_FILTER_ALL)
191+
if err != nil {
192+
log.Error("Get disk records failed", log.Field("Error", err))
193+
return errno.ERR_GET_DISK_RECORDS_FAILED.E(err)
194+
}
195+
177196
curveadm.dbpath = dbpath
178197
curveadm.logpath = logpath
179198
curveadm.config = config
@@ -183,6 +202,8 @@ func (curveadm *CurveAdm) init() error {
183202
curveadm.storage = s
184203
curveadm.memStorage = utils.NewSafeMap()
185204
curveadm.hosts = hosts.Data
205+
curveadm.disks = disks.Data
206+
curveadm.diskRecords = diskRecords
186207
curveadm.clusterId = cluster.Id
187208
curveadm.clusterUUId = cluster.UUId
188209
curveadm.clusterName = cluster.Name
@@ -264,6 +285,8 @@ func (curveadm *CurveAdm) Err() io.Writer { return curveadm.e
264285
func (curveadm *CurveAdm) Storage() *storage.Storage { return curveadm.storage }
265286
func (curveadm *CurveAdm) MemStorage() *utils.SafeMap { return curveadm.memStorage }
266287
func (curveadm *CurveAdm) Hosts() string { return curveadm.hosts }
288+
func (curveadm *CurveAdm) Disks() string { return curveadm.disks }
289+
func (curveadm *CurveAdm) DiskRecords() []storage.Disk { return curveadm.diskRecords }
267290
func (curveadm *CurveAdm) ClusterId() int { return curveadm.clusterId }
268291
func (curveadm *CurveAdm) ClusterUUId() string { return curveadm.clusterUUId }
269292
func (curveadm *CurveAdm) ClusterName() string { return curveadm.clusterName }

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+
"github.com/opencurve/curveadm/cli/command/disks"
3435
"github.com/opencurve/curveadm/cli/command/hosts"
3536
"github.com/opencurve/curveadm/cli/command/pfs"
3637
"github.com/opencurve/curveadm/cli/command/playground"
@@ -61,6 +62,7 @@ func addSubCommands(cmd *cobra.Command, curveadm *cli.CurveAdm) {
6162
cluster.NewClusterCommand(curveadm), // curveadm cluster ...
6263
config.NewConfigCommand(curveadm), // curveadm config ...
6364
hosts.NewHostsCommand(curveadm), // curveadm hosts ...
65+
disks.NewDisksCommand(curveadm), // curveadm disks ...
6466
playground.NewPlaygroundCommand(curveadm), // curveadm playground ...
6567
target.NewTargetCommand(curveadm), // curveadm target ...
6668
pfs.NewPFSCommand(curveadm), // curveadm pfs ...

cli/command/disks/cmd.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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-02-24
20+
* Author: Lijin Xiong ([email protected])
21+
*/
22+
23+
package disks
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 NewDisksCommand(curveadm *cli.CurveAdm) *cobra.Command {
32+
cmd := &cobra.Command{
33+
Use: "disks",
34+
Short: "Manage disks",
35+
Args: cliutil.NoArgs,
36+
RunE: cliutil.ShowHelp(curveadm.Err()),
37+
}
38+
39+
cmd.AddCommand(
40+
NewCommitCommand(curveadm),
41+
NewShowCommand(curveadm),
42+
NewListCommand(curveadm),
43+
)
44+
return cmd
45+
}

cli/command/disks/commit.go

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
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-02-24
20+
* Author: Lijin Xiong ([email protected])
21+
*/
22+
23+
package disks
24+
25+
import (
26+
"strings"
27+
28+
"github.com/fatih/color"
29+
"github.com/opencurve/curveadm/cli/cli"
30+
"github.com/opencurve/curveadm/internal/common"
31+
comm "github.com/opencurve/curveadm/internal/common"
32+
"github.com/opencurve/curveadm/internal/configure/disks"
33+
"github.com/opencurve/curveadm/internal/configure/topology"
34+
"github.com/opencurve/curveadm/internal/errno"
35+
"github.com/opencurve/curveadm/internal/storage"
36+
"github.com/opencurve/curveadm/internal/tui"
37+
tuicomm "github.com/opencurve/curveadm/internal/tui/common"
38+
"github.com/opencurve/curveadm/internal/utils"
39+
"github.com/spf13/cobra"
40+
)
41+
42+
const (
43+
COMMIT_EXAMPLE = `Examples:
44+
$ curveadm disks commit /path/to/disks.yaml # Commit disks`
45+
)
46+
47+
type commitOptions struct {
48+
filename string
49+
slient bool
50+
}
51+
52+
func NewCommitCommand(curveadm *cli.CurveAdm) *cobra.Command {
53+
var options commitOptions
54+
cmd := &cobra.Command{
55+
Use: "commit DISKS [OPTIONS]",
56+
Short: "Commit disks",
57+
Args: utils.ExactArgs(1),
58+
Example: COMMIT_EXAMPLE,
59+
RunE: func(cmd *cobra.Command, args []string) error {
60+
options.filename = args[0]
61+
return runCommit(curveadm, options)
62+
},
63+
DisableFlagsInUseLine: true,
64+
}
65+
66+
flags := cmd.Flags()
67+
flags.BoolVarP(&options.slient, "slient", "s", false, "Slient output for disks commit")
68+
69+
return cmd
70+
}
71+
72+
func readAndCheckDisks(curveadm *cli.CurveAdm, options commitOptions) (string, []*disks.DiskConfig, error) {
73+
var dcs []*disks.DiskConfig
74+
// 1) read disks from file
75+
if !utils.PathExist(options.filename) {
76+
return "", dcs, errno.ERR_DISKS_FILE_NOT_FOUND.
77+
F("%s: no such file", utils.AbsPath(options.filename))
78+
}
79+
data, err := utils.ReadFile(options.filename)
80+
if err != nil {
81+
return data, dcs, errno.ERR_READ_DISKS_FILE_FAILED.E(err)
82+
}
83+
84+
// 2) display disks difference
85+
oldData := curveadm.Disks()
86+
if !options.slient {
87+
diff := utils.Diff(oldData, data)
88+
curveadm.WriteOutln(diff)
89+
}
90+
91+
// 3) check disks data
92+
dcs, err = disks.ParseDisks(data, curveadm)
93+
return data, dcs, err
94+
}
95+
96+
func assambleNewDiskRecords(dcs []*disks.DiskConfig,
97+
oldDiskRecords []storage.Disk) ([]storage.Disk, []storage.Disk) {
98+
keySep := ":"
99+
newDiskMap := make(map[string]bool)
100+
101+
var newDiskRecords, diskRecordDeleteList []storage.Disk
102+
for _, dc := range dcs {
103+
for _, host := range dc.GetHost() {
104+
key := strings.Join([]string{host, dc.GetDevice()}, keySep)
105+
newDiskMap[key] = true
106+
newDiskRecords = append(
107+
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,
115+
})
116+
}
117+
}
118+
119+
for _, dr := range oldDiskRecords {
120+
key := strings.Join([]string{dr.Host, dr.Device}, keySep)
121+
if _, ok := newDiskMap[key]; !ok {
122+
diskRecordDeleteList = append(diskRecordDeleteList, dr)
123+
}
124+
}
125+
126+
return newDiskRecords, diskRecordDeleteList
127+
}
128+
129+
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 {
132+
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+
}
142+
}
143+
return nil
144+
}
145+
146+
func syncDiskRecords(data string, dcs []*disks.DiskConfig,
147+
curveadm *cli.CurveAdm, options commitOptions) error {
148+
oldDiskRecords := curveadm.DiskRecords()
149+
tui.SortDiskRecords(oldDiskRecords)
150+
151+
newDiskRecords, diskRecordDeleteList := assambleNewDiskRecords(dcs, oldDiskRecords)
152+
tui.SortDiskRecords(newDiskRecords)
153+
oldDiskRecordsString := tui.FormatDisks(oldDiskRecords)
154+
newDiskRecordsString := tui.FormatDisks(newDiskRecords)
155+
156+
if !options.slient {
157+
diff := utils.Diff(oldDiskRecordsString, newDiskRecordsString)
158+
curveadm.WriteOutln(diff)
159+
}
160+
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
165+
}
166+
167+
// write new disk records
168+
for _, dr := range newDiskRecords {
169+
if err := writeDiskRecord(dr, curveadm); err != nil {
170+
return err
171+
}
172+
}
173+
174+
// delete obsolete disk records
175+
for _, dr := range diskRecordDeleteList {
176+
if dr.ChunkServerID != comm.DISK_DEFAULT_NULL_CHUNKSERVER_ID {
177+
return errno.ERR_DELETE_SERVICE_BINDING_DISK.
178+
F("The disk[%s:%s] is used by service[%s:%s]",
179+
dr.Host, dr.Device, topology.ROLE_CHUNKSERVER, dr.ChunkServerID)
180+
}
181+
182+
if err := curveadm.Storage().DeleteDisk(dr.Host, dr.Device); err != nil {
183+
return errno.ERR_UPDATE_DISK_FAILED.E(err)
184+
}
185+
}
186+
187+
return nil
188+
}
189+
190+
func runCommit(curveadm *cli.CurveAdm, options commitOptions) error {
191+
// 1) read and check disks
192+
data, dcs, err := readAndCheckDisks(curveadm, options)
193+
if err != nil {
194+
return err
195+
}
196+
197+
// 2) confirm by user
198+
pass := tuicomm.ConfirmYes("Do you want to continue?")
199+
if !pass {
200+
curveadm.WriteOut(tuicomm.PromptCancelOpetation("commit disks"))
201+
return errno.ERR_CANCEL_OPERATION
202+
}
203+
204+
// 3) add disk records
205+
err = syncDiskRecords(data, dcs, curveadm, options)
206+
if err != nil {
207+
return err
208+
}
209+
210+
// 4) add disks data
211+
err = curveadm.Storage().SetDisks(data)
212+
if err != nil {
213+
return errno.ERR_UPDATE_DISKS_FAILED.
214+
F("commit disks failed")
215+
}
216+
217+
// 5) print success prompt
218+
curveadm.WriteOutln(color.GreenString("Disks updated"))
219+
return nil
220+
}

0 commit comments

Comments
 (0)