Merge pull request #4831 from filecoin-project/feat/miner-storagelistsectors
miner: Storage list sectors command
This commit is contained in:
commit
36b78b1891
@ -20,11 +20,14 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
lcli "github.com/filecoin-project/lotus/cli"
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
||||||
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
||||||
|
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
||||||
|
"github.com/filecoin-project/lotus/lib/tablewriter"
|
||||||
)
|
)
|
||||||
|
|
||||||
const metaFile = "sectorstore.json"
|
const metaFile = "sectorstore.json"
|
||||||
@ -147,6 +150,9 @@ var storageListCmd = &cli.Command{
|
|||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.BoolFlag{Name: "color"},
|
&cli.BoolFlag{Name: "color"},
|
||||||
},
|
},
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
storageListSectorsCmd,
|
||||||
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
color.NoColor = !cctx.Bool("color")
|
color.NoColor = !cctx.Bool("color")
|
||||||
|
|
||||||
@ -408,3 +414,163 @@ var storageFindCmd = &cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var storageListSectorsCmd = &cli.Command{
|
||||||
|
Name: "sectors",
|
||||||
|
Usage: "get list of all sector files",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "color",
|
||||||
|
Value: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
color.NoColor = !cctx.Bool("color")
|
||||||
|
|
||||||
|
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
napi, closer2, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer2()
|
||||||
|
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
|
sectors, err := nodeApi.SectorsList(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("listing sectors: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
maddr, err := nodeApi.ActorAddress(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
aid, err := address.IDFromAddress(maddr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
mi, err := napi.StateMinerInfo(ctx, maddr, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sid := func(sn abi.SectorNumber) abi.SectorID {
|
||||||
|
return abi.SectorID{
|
||||||
|
Miner: abi.ActorID(aid),
|
||||||
|
Number: sn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type entry struct {
|
||||||
|
id abi.SectorNumber
|
||||||
|
storage stores.ID
|
||||||
|
ft storiface.SectorFileType
|
||||||
|
urls string
|
||||||
|
|
||||||
|
primary, seal, store bool
|
||||||
|
|
||||||
|
state api.SectorState
|
||||||
|
}
|
||||||
|
|
||||||
|
var list []entry
|
||||||
|
|
||||||
|
for _, sector := range sectors {
|
||||||
|
st, err := nodeApi.SectorsStatus(ctx, sector, false)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting sector status for sector %d: %w", sector, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ft := range storiface.PathTypes {
|
||||||
|
si, err := nodeApi.StorageFindSector(ctx, sid(sector), ft, mi.SectorSize, false)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("find sector %d: %w", sector, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, info := range si {
|
||||||
|
|
||||||
|
list = append(list, entry{
|
||||||
|
id: sector,
|
||||||
|
storage: info.ID,
|
||||||
|
ft: ft,
|
||||||
|
urls: strings.Join(info.URLs, ";"),
|
||||||
|
|
||||||
|
primary: info.Primary,
|
||||||
|
seal: info.CanSeal,
|
||||||
|
store: info.CanStore,
|
||||||
|
|
||||||
|
state: st.State,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(list, func(i, j int) bool {
|
||||||
|
if list[i].store != list[j].store {
|
||||||
|
return list[i].store
|
||||||
|
}
|
||||||
|
|
||||||
|
if list[i].storage != list[j].storage {
|
||||||
|
return list[i].storage < list[j].storage
|
||||||
|
}
|
||||||
|
|
||||||
|
if list[i].id != list[j].id {
|
||||||
|
return list[i].id < list[j].id
|
||||||
|
}
|
||||||
|
|
||||||
|
return list[i].ft < list[j].ft
|
||||||
|
})
|
||||||
|
|
||||||
|
tw := tablewriter.New(
|
||||||
|
tablewriter.Col("Storage"),
|
||||||
|
tablewriter.Col("Sector"),
|
||||||
|
tablewriter.Col("Type"),
|
||||||
|
tablewriter.Col("State"),
|
||||||
|
tablewriter.Col("Primary"),
|
||||||
|
tablewriter.Col("Path use"),
|
||||||
|
tablewriter.Col("URLs"),
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(list) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
lastS := list[0].storage
|
||||||
|
sc1, sc2 := color.FgBlue, color.FgCyan
|
||||||
|
|
||||||
|
for _, e := range list {
|
||||||
|
if e.storage != lastS {
|
||||||
|
lastS = e.storage
|
||||||
|
sc1, sc2 = sc2, sc1
|
||||||
|
}
|
||||||
|
|
||||||
|
m := map[string]interface{}{
|
||||||
|
"Storage": color.New(sc1).Sprint(e.storage),
|
||||||
|
"Sector": e.id,
|
||||||
|
"Type": e.ft.String(),
|
||||||
|
"State": color.New(stateOrder[sealing.SectorState(e.state)].col).Sprint(e.state),
|
||||||
|
"Primary": maybeStr(e.seal, color.FgGreen, "primary"),
|
||||||
|
"Path use": maybeStr(e.seal, color.FgMagenta, "seal ") + maybeStr(e.store, color.FgCyan, "store"),
|
||||||
|
"URLs": e.urls,
|
||||||
|
}
|
||||||
|
tw.Write(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tw.Flush(os.Stdout)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func maybeStr(c bool, col color.Attribute, s string) string {
|
||||||
|
if !c {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return color.New(col).Sprint(s)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user