diff --git a/cli/command/format.go b/cli/command/format.go index 51e788cfa..7eb965713 100644 --- a/cli/command/format.go +++ b/cli/command/format.go @@ -24,6 +24,7 @@ package command import ( "fmt" + "github.com/opencurve/curveadm/internal/configure/topology" "github.com/opencurve/curveadm/cli/cli" comm "github.com/opencurve/curveadm/internal/common" @@ -39,11 +40,12 @@ import ( const ( FORMAT_EXAMPLE = `Examples: - $ curveadm format -f /path/to/format.yaml # Format chunkfile pool with specified configure file - $ curveadm format --status -f /path/to/format.yaml # Display formatting status - $ curveadm format --stop -f /path/to/format.yaml # Stop formatting progress - $ curveadm format --debug -f /path/to/format.yaml # Format chunkfile with debug mode - $ curveadm format --clean -f /path/to/format.yaml # clean the container left by debug mode` + $ curveadm format -f /path/to/format.yaml # Format chunkfile pool with specified configure file + $ curveadm format -f /path/to/format.yaml --increment # Incremental Format chunkfile pool with specified configure file + $ curveadm format --status -f /path/to/format.yaml # Display formatting status + $ curveadm format --stop -f /path/to/format.yaml # Stop formatting progress + $ curveadm format --debug -f /path/to/format.yaml # Format chunkfile with debug mode + $ curveadm format --clean -f /path/to/format.yaml # clean the container left by debug mode` ) var ( @@ -62,6 +64,11 @@ var ( FORMAT_CLEAN_PLAYBOOK_STEPS = []int{ playbook.CLEAN_FORMAT, } + + FORMAT_INCREMENT_PLAYBOOK_STEPS = []int{ + playbook.STOP_SERVICE, + playbook.FORMAT_CHUNKFILE_POOL, + } ) type formatOptions struct { @@ -70,6 +77,7 @@ type formatOptions struct { stopFormat bool debug bool clean bool + increment bool } func checkFormatOptions(options formatOptions) error { @@ -116,6 +124,7 @@ func NewFormatCommand(curveadm *cli.CurveAdm) *cobra.Command { flags.BoolVar(&options.stopFormat, "stop", false, "Stop formatting progress") flags.BoolVar(&options.debug, "debug", false, "Debug formatting progress") flags.BoolVar(&options.clean, "clean", false, "Clean the Container") + flags.BoolVar(&options.increment, "increment", false, "Incremental formatting") return cmd } @@ -131,6 +140,7 @@ func genFormatPlaybook(curveadm *cli.CurveAdm, stopFormat := options.stopFormat debug := options.debug clean := options.clean + increment := options.increment steps := FORMAT_PLAYBOOK_STEPS if showStatus { @@ -142,6 +152,9 @@ func genFormatPlaybook(curveadm *cli.CurveAdm, if clean { steps = FORMAT_CLEAN_PLAYBOOK_STEPS } + if increment { + steps = FORMAT_INCREMENT_PLAYBOOK_STEPS + } pb := playbook.NewPlaybook(curveadm) for _, step := range steps { @@ -150,14 +163,32 @@ func genFormatPlaybook(curveadm *cli.CurveAdm, if step == playbook.FORMAT_CHUNKFILE_POOL { options[comm.DEBUG_MODE] = debug } - pb.AddStep(&playbook.PlaybookStep{ - Type: step, - Configs: fcs, - ExecOptions: playbook.ExecOptions{ - SilentSubBar: showStatus, - }, - Options: options, - }) + options[comm.FORMAT_INCREMENTAL] = increment + if step == playbook.STOP_SERVICE { + dcs, err := curveadm.ParseTopology() + if err != nil { + return nil, err + } + stopChunkServercs := curveadm.FilterDeployConfig(dcs, topology.FilterOption{ + Role: "chunkserver", + }) + if len(stopChunkServercs) == 0 { + continue + } + pb.AddStep(&playbook.PlaybookStep{ + Type: step, + Configs: stopChunkServercs, + }) + } else { + pb.AddStep(&playbook.PlaybookStep{ + Type: step, + Configs: fcs, + ExecOptions: playbook.ExecOptions{ + SilentSubBar: showStatus, + }, + Options: options, + }) + } } return pb, nil } @@ -179,6 +210,7 @@ func runFormat(curveadm *cli.CurveAdm, options formatOptions) error { var fcs []*configure.FormatConfig diskRecords := curveadm.DiskRecords() debug := options.debug + increment := options.increment if debug { curveadm.SetDebugLevel() } @@ -224,13 +256,21 @@ func runFormat(curveadm *cli.CurveAdm, options formatOptions) error { return err } - // 3) run playbook + // 3) confirm by user + if increment { + if pass := tuicomm.ConfirmYes(tuicomm.PromptIncrementFormat()); !pass { + curveadm.WriteOut(tuicomm.PromptCancelOpetation("increment format")) + return errno.ERR_CANCEL_OPERATION + } + } + + // 4) run playbook err = pb.Run() if err != nil { return err } - // 4) print status or prompt + // 5) print status or prompt if options.showStatus { output := displayFormatStatus(curveadm) curveadm.WriteOutln("") diff --git a/internal/common/common.go b/internal/common/common.go index d5e3ff147..df2b68c5b 100644 --- a/internal/common/common.go +++ b/internal/common/common.go @@ -68,6 +68,7 @@ const ( // format KEY_ALL_FORMAT_STATUS = "ALL_FORMAT_STATUS" + FORMAT_INCREMENTAL = "FORMAT_INCREMENTAL" // check KEY_CHECK_WITH_WEAK = "CHECK_WITH_WEAK" diff --git a/internal/task/scripts/format.go b/internal/task/scripts/format.go index 826fcf137..6031d273d 100644 --- a/internal/task/scripts/format.go +++ b/internal/task/scripts/format.go @@ -28,12 +28,33 @@ percent=$2 chunkfile_size=$3 chunkfile_pool_dir=$4 chunkfile_pool_meta_path=$5 +increment_format=$6 mkdir -p $chunkfile_pool_dir -$binary \ - -allocatePercent=$percent \ - -fileSize=$chunkfile_size \ - -filePoolDir=$chunkfile_pool_dir \ - -filePoolMetaPath=$chunkfile_pool_meta_path \ - -fileSystemPath=$chunkfile_pool_dir + +if [ $increment_format == "true" ] +then + rootdir=$(dirname $chunkfile_pool_dir) + used_percent=$(df $rootdir --output=pcent|tail -n 1|sed 's/%//'|xargs) + let minus=$percent-$used_percent + + if [ $minus -gt 0 ] + then + $binary \ + -allocatePercent=$minus \ + -fileSize=$chunkfile_size \ + -filePoolDir=$chunkfile_pool_dir \ + -filePoolMetaPath=$chunkfile_pool_meta_path \ + -fileSystemPath=$chunkfile_pool_dir + fi +else + $binary \ + -allocatePercent=$percent \ + -fileSize=$chunkfile_size \ + -filePoolDir=$chunkfile_pool_dir \ + -filePoolMetaPath=$chunkfile_pool_meta_path \ + -fileSystemPath=$chunkfile_pool_dir +fi + + ` diff --git a/internal/task/task/bs/format.go b/internal/task/task/bs/format.go index 5d963a431..0049477e8 100644 --- a/internal/task/task/bs/format.go +++ b/internal/task/task/bs/format.go @@ -24,12 +24,12 @@ package bs import ( "fmt" + comm "github.com/opencurve/curveadm/internal/common" "regexp" "strings" "time" "github.com/opencurve/curveadm/cli/cli" - comm "github.com/opencurve/curveadm/internal/common" "github.com/opencurve/curveadm/internal/configure" "github.com/opencurve/curveadm/internal/configure/disks" os "github.com/opencurve/curveadm/internal/configure/os" @@ -246,8 +246,9 @@ func NewFormatChunkfilePoolTask(curveadm *cli.CurveAdm, fc *configure.FormatConf chunkfilePoolRootDir := layout.ChunkfilePoolRootDir formatScript := scripts.SCRIPT_FORMAT formatScriptPath := fmt.Sprintf("%s/format.sh", layout.ToolsBinDir) - formatCommand := fmt.Sprintf("%s %s %d %d %s %s", formatScriptPath, layout.FormatBinaryPath, - usagePercent, DEFAULT_CHUNKFILE_SIZE, layout.ChunkfilePoolDir, layout.ChunkfilePoolMetaPath) + increment := curveadm.MemStorage().Get(comm.FORMAT_INCREMENTAL).(bool) + formatCommand := fmt.Sprintf("%s %s %d %d %s %s %t", formatScriptPath, layout.FormatBinaryPath, + usagePercent, DEFAULT_CHUNKFILE_SIZE, layout.ChunkfilePoolDir, layout.ChunkfilePoolMetaPath, increment) debug := curveadm.MemStorage().Get(comm.DEBUG_MODE).(bool) // 1: skip if formating container exist @@ -279,10 +280,12 @@ func NewFormatChunkfilePoolTask(curveadm *cli.CurveAdm, fc *configure.FormatConf Paths: []string{mountPoint}, ExecOptions: curveadm.ExecOptions(), }) - t.AddStep(&step.CreateFilesystem{ // mkfs.ext4 MOUNT_POINT - Device: device, - ExecOptions: curveadm.ExecOptions(), - }) + if !increment { + t.AddStep(&step.CreateFilesystem{ // mkfs.ext4 MOUNT_POINT + Device: device, + ExecOptions: curveadm.ExecOptions(), + }) + } t.AddStep(&step.MountFilesystem{ Source: device, Directory: mountPoint, diff --git a/internal/tui/common/prompt.go b/internal/tui/common/prompt.go index ddeadefcd..52e8b1588 100644 --- a/internal/tui/common/prompt.go +++ b/internal/tui/common/prompt.go @@ -190,6 +190,12 @@ func PromptCollectService() string { return prompt.Build() } +func PromptIncrementFormat() string { + prompt := NewPrompt(color.YellowString(PROMPT_WARNING) + DEFAULT_CONFIRM_PROMPT) + prompt.data["warning"] = "WARNING: increment format will stop chunkserver service" + return prompt.Build() +} + func prettyClue(clue string) string { items := strings.Split(clue, "\n") for {