2024-08-28 15:32:30 +00:00
|
|
|
package metabase
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2024-09-06 08:16:12 +00:00
|
|
|
"sync"
|
2024-08-28 15:32:30 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
|
|
|
|
engineconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/engine"
|
|
|
|
shardconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/engine/shard"
|
|
|
|
meta "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase"
|
|
|
|
"github.com/spf13/cobra"
|
2024-09-06 08:16:12 +00:00
|
|
|
"golang.org/x/sync/errgroup"
|
2024-08-28 15:32:30 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
pathFlag = "path"
|
|
|
|
noCompactFlag = "no-compact"
|
|
|
|
)
|
|
|
|
|
|
|
|
var errNoPathsFound = errors.New("no metabase paths found")
|
|
|
|
|
|
|
|
var path string
|
|
|
|
|
|
|
|
var UpgradeCmd = &cobra.Command{
|
|
|
|
Use: "upgrade",
|
|
|
|
Short: "Upgrade metabase to latest version",
|
|
|
|
RunE: upgrade,
|
|
|
|
}
|
|
|
|
|
|
|
|
func upgrade(cmd *cobra.Command, _ []string) error {
|
|
|
|
configFile, err := cmd.Flags().GetString(commonflags.ConfigFlag)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
configDir, err := cmd.Flags().GetString(commonflags.ConfigDirFlag)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
noCompact, _ := cmd.Flags().GetBool(noCompactFlag)
|
|
|
|
var paths []string
|
|
|
|
if path != "" {
|
|
|
|
paths = append(paths, path)
|
|
|
|
}
|
|
|
|
appCfg := config.New(configFile, configDir, config.EnvPrefix)
|
|
|
|
if err := engineconfig.IterateShards(appCfg, false, func(sc *shardconfig.Config) error {
|
|
|
|
paths = append(paths, sc.Metabase().Path())
|
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("failed to get metabase paths: %w", err)
|
|
|
|
}
|
|
|
|
if len(paths) == 0 {
|
|
|
|
return errNoPathsFound
|
|
|
|
}
|
|
|
|
cmd.Println("found", len(paths), "metabases:")
|
|
|
|
for i, path := range paths {
|
|
|
|
cmd.Println(i+1, ":", path)
|
|
|
|
}
|
|
|
|
result := make(map[string]bool)
|
2024-09-06 08:16:12 +00:00
|
|
|
var resultGuard sync.Mutex
|
|
|
|
eg, ctx := errgroup.WithContext(cmd.Context())
|
2024-08-28 15:32:30 +00:00
|
|
|
for _, path := range paths {
|
2024-09-06 08:16:12 +00:00
|
|
|
eg.Go(func() error {
|
|
|
|
var success bool
|
|
|
|
cmd.Println("upgrading metabase", path, "...")
|
|
|
|
if err := meta.Upgrade(ctx, path, !noCompact, func(a ...any) {
|
|
|
|
cmd.Println(append([]any{time.Now().Format(time.RFC3339), ":", path, ":"}, a...)...)
|
|
|
|
}); err != nil {
|
|
|
|
cmd.Println("error: failed to upgrade metabase", path, ":", err)
|
|
|
|
} else {
|
|
|
|
success = true
|
|
|
|
cmd.Println("metabase", path, "upgraded successfully")
|
|
|
|
}
|
|
|
|
resultGuard.Lock()
|
|
|
|
result[path] = success
|
|
|
|
resultGuard.Unlock()
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
if err := eg.Wait(); err != nil {
|
|
|
|
return err
|
2024-08-28 15:32:30 +00:00
|
|
|
}
|
|
|
|
for mb, ok := range result {
|
|
|
|
if ok {
|
|
|
|
cmd.Println(mb, ": success")
|
|
|
|
} else {
|
|
|
|
cmd.Println(mb, ": failed")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func initUpgradeCommand() {
|
|
|
|
flags := UpgradeCmd.Flags()
|
|
|
|
flags.StringVar(&path, pathFlag, "", "Path to metabase file")
|
|
|
|
flags.Bool(noCompactFlag, false, "Do not compact upgraded metabase file")
|
|
|
|
}
|