2020-03-09 06:13:22 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/mitchellh/go-homedir"
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
"gopkg.in/urfave/cli.v2"
|
|
|
|
|
|
|
|
lcli "github.com/filecoin-project/lotus/cli"
|
|
|
|
"github.com/filecoin-project/lotus/node/config"
|
|
|
|
)
|
|
|
|
|
|
|
|
const metaFile = "sectorstore.json"
|
|
|
|
|
|
|
|
var storageCmd = &cli.Command{
|
|
|
|
Name: "storage",
|
|
|
|
Usage: "manage sector storage",
|
|
|
|
Subcommands: []*cli.Command{
|
|
|
|
storageAttachCmd,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var storageAttachCmd = &cli.Command{
|
|
|
|
Name: "attach",
|
|
|
|
Usage: "attach local storage path",
|
|
|
|
Flags: []cli.Flag{
|
|
|
|
&cli.BoolFlag{
|
2020-03-09 06:13:45 +00:00
|
|
|
Name: "init",
|
2020-03-09 06:13:22 +00:00
|
|
|
Usage: "initialize the path first",
|
|
|
|
},
|
|
|
|
&cli.Uint64Flag{
|
2020-03-09 06:13:45 +00:00
|
|
|
Name: "weight",
|
2020-03-09 06:13:22 +00:00
|
|
|
Usage: "(for init) path weight",
|
|
|
|
Value: 10,
|
|
|
|
},
|
|
|
|
&cli.BoolFlag{
|
2020-03-09 06:13:45 +00:00
|
|
|
Name: "seal",
|
2020-03-09 06:13:22 +00:00
|
|
|
Usage: "(for init) use path for sealing",
|
|
|
|
},
|
|
|
|
&cli.BoolFlag{
|
2020-03-09 06:13:45 +00:00
|
|
|
Name: "store",
|
2020-03-09 06:13:22 +00:00
|
|
|
Usage: "(for init) use path for long-term storage",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Action: func(cctx *cli.Context) error {
|
|
|
|
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer closer()
|
|
|
|
ctx := lcli.ReqContext(cctx)
|
|
|
|
|
|
|
|
if !cctx.Args().Present() {
|
|
|
|
return xerrors.Errorf("must specify storage path to attach")
|
|
|
|
}
|
|
|
|
|
|
|
|
p, err := homedir.Expand(cctx.Args().First())
|
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("expanding path: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if cctx.Bool("init") {
|
2020-03-09 22:00:29 +00:00
|
|
|
if err := os.MkdirAll(p, 0755); err != nil {
|
|
|
|
if !os.IsExist(err) {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-09 06:13:22 +00:00
|
|
|
_, err := os.Stat(filepath.Join(p, metaFile))
|
|
|
|
if !os.IsNotExist(err) {
|
|
|
|
if err == nil {
|
|
|
|
return xerrors.Errorf("path is already initialized")
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
cfg := &config.StorageMeta{
|
|
|
|
ID: uuid.New().String(),
|
|
|
|
Weight: cctx.Uint64("weight"),
|
|
|
|
CanSeal: cctx.Bool("seal"),
|
|
|
|
CanStore: cctx.Bool("store"),
|
|
|
|
}
|
|
|
|
|
|
|
|
if !(cfg.CanStore || cfg.CanSeal) {
|
|
|
|
return xerrors.Errorf("must specify at least one of --store of --seal")
|
|
|
|
}
|
|
|
|
|
|
|
|
b, err := json.MarshalIndent(cfg, "", " ")
|
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("marshaling storage config: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := ioutil.WriteFile(filepath.Join(p, metaFile), b, 0644); err != nil {
|
|
|
|
return xerrors.Errorf("persisting storage metadata (%s): %w", filepath.Join(p, metaFile), err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nodeApi.StorageAddLocal(ctx, p)
|
|
|
|
},
|
|
|
|
}
|