lotus/cmd/lotus-provider/config.go

174 lines
4.0 KiB
Go
Raw Normal View History

2023-08-28 16:37:36 +00:00
package main
import (
2023-09-20 03:48:39 +00:00
"context"
"errors"
2023-08-28 16:37:36 +00:00
"fmt"
2023-09-20 03:48:39 +00:00
"os"
"regexp"
"strings"
2023-08-28 16:37:36 +00:00
2023-09-20 03:48:39 +00:00
"github.com/BurntSushi/toml"
"github.com/filecoin-project/lotus/lib/harmony/harmonydb"
"github.com/filecoin-project/lotus/node/config"
"github.com/kr/pretty"
2023-08-28 16:37:36 +00:00
"github.com/urfave/cli/v2"
)
var configCmd = &cli.Command{
Name: "config",
2023-09-20 03:48:39 +00:00
Usage: "Manage node config by layers. The layer 'base' will always be applied. ",
2023-08-28 16:37:36 +00:00
Subcommands: []*cli.Command{
configDefaultCmd,
configSetCmd,
configGetCmd,
2023-09-20 03:48:39 +00:00
configListCmd,
configViewCmd,
2023-08-28 16:37:36 +00:00
},
}
var configDefaultCmd = &cli.Command{
Name: "default",
2023-09-20 03:48:39 +00:00
Usage: "Print default node config",
2023-08-28 16:37:36 +00:00
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "no-comment",
Usage: "don't comment default values",
},
},
Action: func(cctx *cli.Context) error {
2023-09-20 03:48:39 +00:00
c := config.DefaultLotusProvider()
cb, err := config.ConfigUpdate(c, nil, config.Commented(!cctx.Bool("no-comment")), config.DefaultKeepUncommented())
if err != nil {
return err
}
fmt.Println(string(cb))
2023-08-28 16:37:36 +00:00
return nil
},
}
var configSetCmd = &cli.Command{
2023-09-20 03:48:39 +00:00
Name: "set",
Usage: "Set a config layer or the base",
ArgsUsage: "a layer's name",
2023-08-28 16:37:36 +00:00
Action: func(cctx *cli.Context) error {
2023-09-20 03:48:39 +00:00
args := cctx.Args()
if args.Len() != 1 {
return errors.New("Must have exactly 1 arg for the file name.")
}
db, err := makeDB(cctx)
if err != nil {
return err
}
fn := args.First()
bytes, err := os.ReadFile(fn)
if err != nil {
return fmt.Errorf("cannot read file %w", err)
}
lp := config.DefaultLotusProvider() // ensure it's toml
toml.Decode(string(bytes), lp)
_ = lp
name := strings.Split(fn, ".")[0]
_, err = db.Exec(context.Background(),
`INSERT INTO harmony_config (title, config) VALUES (?,?)
ON CONFLICT (title) DO UPDATE SET config = excluded.config`, name, string(bytes))
if err != nil {
return fmt.Errorf("unable to save config layer: %w", err)
}
fmt.Println("Layer " + name + " created/updated")
2023-08-28 16:37:36 +00:00
return nil
},
}
var configGetCmd = &cli.Command{
2023-09-20 03:48:39 +00:00
Name: "get",
Usage: "Get a config layer by name. You may want to pipe the output to a file, or use 'less'",
ArgsUsage: "layer name",
Action: func(cctx *cli.Context) error {
args := cctx.Args()
if args.Len() != 1 {
return errors.New("Must have exactly 1 arg for the layer name.")
}
db, err := makeDB(cctx)
if err != nil {
return err
}
var cfg string
err = db.QueryRow(context.Background(), `SELECT config FROM harmony_config WHERE title=?`, args.First()).Scan(&cfg)
if err != nil {
return err
}
fmt.Println(cfg)
return nil
2023-08-28 16:37:36 +00:00
},
2023-09-20 03:48:39 +00:00
}
var configListCmd = &cli.Command{
Name: "list",
Usage: "List config layers you can get.",
Flags: []cli.Flag{},
2023-08-28 16:37:36 +00:00
Action: func(cctx *cli.Context) error {
2023-09-20 03:48:39 +00:00
db, err := makeDB(cctx)
if err != nil {
return err
}
var res []string
db.Select(context.Background(), &res, `SELECT title FROM harmony_confg ORDER BY title`)
for _, r := range res {
fmt.Println(r)
}
2023-08-28 16:37:36 +00:00
return nil
},
}
2023-09-20 03:48:39 +00:00
var configViewCmd = &cli.Command{
Name: "view",
Usage: "View stacked config layers as it will be interpreted.",
ArgsUsage: "a list of layers to be interpreted as the final config",
Action: func(cctx *cli.Context) error {
db, err := makeDB(cctx)
if err != nil {
return err
}
lp, err := getConfig(cctx, db)
if err != nil {
return err
}
fmt.Println(pretty.Sprint(lp))
return nil
},
}
func getConfig(cctx *cli.Context, db *harmonydb.DB) (*config.LotusProviderConfig, error) {
lp := config.DefaultLotusProvider()
have := []string{}
for _, layer := range regexp.MustCompile("[ |,]").Split(cctx.String("layers"), -1) {
text := ""
err := db.QueryRow(cctx.Context, `SELECT config FROM harmony_config WHERE title=?`, layer).Scan(&text)
if err != nil {
return nil, fmt.Errorf("could not read layer %s: %w", layer, err)
}
meta, err := toml.Decode(text, &lp)
if err != nil {
return nil, fmt.Errorf("could not read layer, bad toml %s: %w", layer, err)
}
for _, k := range meta.Keys() {
have = append(have, strings.Join(k, " "))
}
}
_ = have // TODO: verify that required fields are here.
return lp, nil
}