[#1714] lens: Add meta subcommand

Includes:
1. `inspect`
2. `list-garbage`
3. `list-graveyard`

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
Pavel Karpy 2022-08-23 17:05:32 +03:00 committed by LeL
parent adff08ad02
commit 2132b78aba
5 changed files with 209 additions and 0 deletions

View file

@ -0,0 +1,84 @@
package meta
import (
"errors"
"fmt"
"time"
common "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
"github.com/spf13/cobra"
"go.etcd.io/bbolt"
)
var inspectCMD = &cobra.Command{
Use: "inspect",
Short: "Object inspection",
Long: `Inspect specific object in a metabase.`,
Run: inspectFunc,
}
func init() {
common.AddAddressFlag(inspectCMD, &vAddress)
common.AddComponentPathFlag(inspectCMD, &vPath)
}
func inspectFunc(cmd *cobra.Command, _ []string) {
var addr oid.Address
err := addr.DecodeString(vAddress)
common.ExitOnErr(cmd, common.Errf("invalid address argument: %w", err))
db := meta.New(
meta.WithPath(vPath),
meta.WithBoltDBOptions(&bbolt.Options{
ReadOnly: true,
Timeout: 100 * time.Millisecond,
}),
meta.WithEpochState(epochState{}),
)
common.ExitOnErr(cmd, common.Errf("could not open metabase: %w", db.Open(true)))
storageID := meta.StorageIDPrm{}
storageID.SetAddress(addr)
resStorageID, err := db.StorageID(storageID)
common.ExitOnErr(cmd, common.Errf("could not check if the obj is small: %w", err))
if id := resStorageID.StorageID(); id != nil {
cmd.Printf("Object storageID: %s\n\n", blobovnicza.NewIDFromBytes(id).String())
} else {
cmd.Printf("Object does not contain storageID\n\n")
}
prm := meta.GetPrm{}
prm.SetAddress(addr)
prm.SetRaw(true)
siErr := new(object.SplitInfoError)
res, err := db.Get(prm)
if errors.As(err, &siErr) {
link, linkSet := siErr.SplitInfo().Link()
last, lastSet := siErr.SplitInfo().LastPart()
fmt.Println("Object is split")
cmd.Println("\tSplitID:", siErr.SplitInfo().SplitID().String())
if linkSet {
cmd.Println("\tLink:", link)
}
if lastSet {
cmd.Println("\tLast:", last)
}
return
}
common.ExitOnErr(cmd, common.Errf("could not get object: %w", err))
common.PrintObjectHeader(cmd, *res.Header())
}

View file

@ -0,0 +1,44 @@
package meta
import (
"time"
common "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/spf13/cobra"
"go.etcd.io/bbolt"
)
var listGarbageCMD = &cobra.Command{
Use: "list-garbage",
Short: "Garbage listing",
Long: `List all the objects that have received GC Mark.`,
Run: listGarbageFunc,
}
func init() {
common.AddComponentPathFlag(listGarbageCMD, &vPath)
}
func listGarbageFunc(cmd *cobra.Command, _ []string) {
db := meta.New(
meta.WithPath(vPath),
meta.WithBoltDBOptions(&bbolt.Options{
ReadOnly: true,
Timeout: 100 * time.Millisecond,
}),
meta.WithEpochState(epochState{}),
)
common.ExitOnErr(cmd, common.Errf("could not open metabase: %w", db.Open(true)))
var garbPrm meta.GarbageIterationPrm
garbPrm.SetHandler(
func(garbageObject meta.GarbageObject) error {
cmd.Println(garbageObject.Address().EncodeToString())
return nil
})
err := db.IterateOverGarbage(garbPrm)
common.ExitOnErr(cmd, common.Errf("could not iterate over garbage bucket: %w", err))
}

View file

@ -0,0 +1,49 @@
package meta
import (
"time"
common "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/spf13/cobra"
"go.etcd.io/bbolt"
)
var listGraveyardCMD = &cobra.Command{
Use: "list-graveyard",
Short: "Graveyard listing",
Long: `List all the objects that have been covered with a Tomb Stone.`,
Run: listGraveyardFunc,
}
func init() {
common.AddComponentPathFlag(listGraveyardCMD, &vPath)
}
func listGraveyardFunc(cmd *cobra.Command, _ []string) {
db := meta.New(
meta.WithPath(vPath),
meta.WithBoltDBOptions(&bbolt.Options{
ReadOnly: true,
Timeout: 100 * time.Millisecond,
}),
meta.WithEpochState(epochState{}),
)
common.ExitOnErr(cmd, common.Errf("could not open metabase: %w", db.Open(true)))
var gravePrm meta.GraveyardIterationPrm
gravePrm.SetHandler(
func(tsObj meta.TombstonedObject) error {
cmd.Printf(
"Object: %s\nTS: %s\n",
tsObj.Address().EncodeToString(),
tsObj.Tombstone().EncodeToString(),
)
return nil
})
err := db.IterateOverGraveyard(gravePrm)
common.ExitOnErr(cmd, common.Errf("could not iterate over graveyard bucket: %w", err))
}

View file

@ -0,0 +1,30 @@
package meta
import (
"github.com/spf13/cobra"
)
var (
vAddress string
vPath string
)
type epochState struct{}
func (s epochState) CurrentEpoch() uint64 {
return 0
}
// Root contains `meta` command definition.
var Root = &cobra.Command{
Use: "meta",
Short: "Operations with a metabase",
}
func init() {
Root.AddCommand(
inspectCMD,
listGraveyardCMD,
listGarbageCMD,
)
}

View file

@ -4,6 +4,7 @@ import (
"os"
"github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal/blobovnicza"
"github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal/meta"
"github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal/writecache"
"github.com/nspcc-dev/neofs-node/misc"
"github.com/nspcc-dev/neofs-node/pkg/util/gendoc"
@ -35,6 +36,7 @@ func init() {
command.Flags().Bool("version", false, "application version")
command.AddCommand(
blobovnicza.Root,
meta.Root,
writecache.Root,
gendoc.Command(command),
)