From bf547112deb67e09606d1b5e50999a3bc21af1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 12 Nov 2020 19:11:46 +0100 Subject: [PATCH] miner: Storage list sectors command --- cmd/lotus-storage-miner/storage.go | 166 +++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/cmd/lotus-storage-miner/storage.go b/cmd/lotus-storage-miner/storage.go index 8b960a4bf..00af03d8f 100644 --- a/cmd/lotus-storage-miner/storage.go +++ b/cmd/lotus-storage-miner/storage.go @@ -20,11 +20,14 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" "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/storiface" + sealing "github.com/filecoin-project/lotus/extern/storage-sealing" + "github.com/filecoin-project/lotus/lib/tablewriter" ) const metaFile = "sectorstore.json" @@ -147,6 +150,9 @@ var storageListCmd = &cli.Command{ Flags: []cli.Flag{ &cli.BoolFlag{Name: "color"}, }, + Subcommands: []*cli.Command{ + storageListSectorsCmd, + }, Action: func(cctx *cli.Context) error { color.NoColor = !cctx.Bool("color") @@ -408,3 +414,163 @@ var storageFindCmd = &cli.Command{ 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) +}