From 495ff1b00bb1f609c93b2a0ae41c14e05f6777b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 2 Feb 2024 12:09:12 +0100 Subject: [PATCH] lotus-provider: new-cluster command --- cmd/lotus-provider/config.go | 1 + .../{migrate.go => config_migrate.go} | 0 cmd/lotus-provider/config_new.go | 149 ++++++++++++++++++ 3 files changed, 150 insertions(+) rename cmd/lotus-provider/{migrate.go => config_migrate.go} (100%) create mode 100644 cmd/lotus-provider/config_new.go diff --git a/cmd/lotus-provider/config.go b/cmd/lotus-provider/config.go index 13156833c..5e0a0598a 100644 --- a/cmd/lotus-provider/config.go +++ b/cmd/lotus-provider/config.go @@ -28,6 +28,7 @@ var configCmd = &cli.Command{ configViewCmd, configRmCmd, configMigrateCmd, + configNewCmd, }, } diff --git a/cmd/lotus-provider/migrate.go b/cmd/lotus-provider/config_migrate.go similarity index 100% rename from cmd/lotus-provider/migrate.go rename to cmd/lotus-provider/config_migrate.go diff --git a/cmd/lotus-provider/config_new.go b/cmd/lotus-provider/config_new.go new file mode 100644 index 000000000..9e2a4a87d --- /dev/null +++ b/cmd/lotus-provider/config_new.go @@ -0,0 +1,149 @@ +package main + +import ( + "bytes" + "crypto/rand" + "encoding/base64" + "fmt" + "github.com/BurntSushi/toml" + "github.com/fatih/color" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types" + cliutil "github.com/filecoin-project/lotus/cli/util" + "github.com/filecoin-project/lotus/cmd/lotus-provider/deps" + "github.com/filecoin-project/lotus/node/config" + "github.com/filecoin-project/lotus/node/repo" + "github.com/samber/lo" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" + "io" +) + +var configNewCmd = &cli.Command{ + Name: "new-cluster", + Usage: "Create new coniguration for a new cluster", + ArgsUsage: "[SP actor address...]", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + EnvVars: []string{"LOTUS_PATH"}, + Hidden: true, + Value: "~/.lotus", + }, + }, + Action: func(cctx *cli.Context) error { + configColor := color.New(color.FgHiGreen).SprintFunc() + + if cctx.Args().Len() < 1 { + return xerrors.New("must specify at least one SP actor address. Use 'lotus-shed miner create'") + } + + ctx := cctx.Context + + db, err := deps.MakeDB(cctx) + if err != nil { + return err + } + + full, closer, err := cliutil.GetFullNodeAPIV1(cctx) + if err != nil { + return xerrors.Errorf("connecting to full node: %w", err) + } + defer closer() + + var titles []string + err = db.Select(ctx, &titles, `SELECT title FROM harmony_config WHERE LENGTH(config) > 0`) + if err != nil { + return fmt.Errorf("miner cannot reach the db. Ensure the config toml's HarmonyDB entry"+ + " is setup to reach Yugabyte correctly: %s", err.Error()) + } + + name := cctx.String("to-layer") + if name == "" { + name = fmt.Sprintf("cluster%d", len(titles)) + } else { + if lo.Contains(titles, name) && !cctx.Bool("overwrite") { + return xerrors.New("the overwrite flag is needed to replace existing layer: " + name) + } + } + msg := "Layer " + configColor(name) + ` created. ` + + // setup config + lpCfg := config.DefaultLotusProvider() + + for _, addr := range cctx.Args().Slice() { + maddr, err := address.NewFromString(addr) + if err != nil { + return xerrors.Errorf("Invalid address: %s", addr) + } + + _, err = full.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("Failed to get miner info: %w", err) + } + + lpCfg.Addresses.MinerAddresses = append(lpCfg.Addresses.MinerAddresses, addr) + } + + { + sk, err := io.ReadAll(io.LimitReader(rand.Reader, 32)) + if err != nil { + return err + } + + lpCfg.Apis.StorageRPCSecret = base64.StdEncoding.EncodeToString(sk) + } + + { + ainfo, err := cliutil.GetAPIInfo(cctx, repo.FullNode) + if err != nil { + return xerrors.Errorf("could not get API info for FullNode: %w", err) + } + + token, err := full.AuthNew(ctx, api.AllPermissions) + if err != nil { + return err + } + + lpCfg.Apis.ChainApiInfo = append(lpCfg.Apis.ChainApiInfo, fmt.Sprintf("%s:%s", string(token), ainfo.Addr)) + } + + // write config + + configTOML := &bytes.Buffer{} + if err = toml.NewEncoder(configTOML).Encode(lpCfg); err != nil { + return err + } + + if !lo.Contains(titles, "base") { + cfg, err := getDefaultConfig(true) + if err != nil { + return xerrors.Errorf("Cannot get default config: %w", err) + } + _, err = db.Exec(ctx, "INSERT INTO harmony_config (title, config) VALUES ('base', $1)", cfg) + + if err != nil { + return err + } + } + + if cctx.Bool("overwrite") { + i, err := db.Exec(ctx, "DELETE FROM harmony_config WHERE title=$1", name) + if i != 0 { + fmt.Println("Overwriting existing layer") + } + if err != nil { + fmt.Println("Got error while deleting existing layer: " + err.Error()) + } + } + + _, err = db.Exec(ctx, "INSERT INTO harmony_config (title, config) VALUES ($1, $2)", name, configTOML.String()) + if err != nil { + return err + } + + fmt.Println(msg) + return nil + }, +}