From e8e11b57a95fe6f7bfdf7588bf731c96f76b8e87 Mon Sep 17 00:00:00 2001 From: Aleksey Savchuk Date: Mon, 19 Aug 2024 18:02:11 +0300 Subject: [PATCH] [#1223] lens/tui: Add TUI app for write cache Signed-off-by: Aleksey Savchuk --- cmd/frostfs-lens/internal/writecache/root.go | 2 +- cmd/frostfs-lens/internal/writecache/tui.go | 78 ++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 cmd/frostfs-lens/internal/writecache/tui.go diff --git a/cmd/frostfs-lens/internal/writecache/root.go b/cmd/frostfs-lens/internal/writecache/root.go index eb3b325b6..d7d6db240 100644 --- a/cmd/frostfs-lens/internal/writecache/root.go +++ b/cmd/frostfs-lens/internal/writecache/root.go @@ -17,5 +17,5 @@ var Root = &cobra.Command{ } func init() { - Root.AddCommand(listCMD, inspectCMD) + Root.AddCommand(listCMD, inspectCMD, tuiCMD) } diff --git a/cmd/frostfs-lens/internal/writecache/tui.go b/cmd/frostfs-lens/internal/writecache/tui.go new file mode 100644 index 000000000..46a3791ac --- /dev/null +++ b/cmd/frostfs-lens/internal/writecache/tui.go @@ -0,0 +1,78 @@ +package writecache + +import ( + "context" + "fmt" + + common "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal" + schema "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal/schema/writecache" + "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal/tui" + "github.com/rivo/tview" + "github.com/spf13/cobra" + "go.etcd.io/bbolt" +) + +var tuiCMD = &cobra.Command{ + Use: "tui", + Short: "Write cache TUI", + Long: `Launch a TUI to browse write cache and search for data. + +Available search filters: +- cid CID +- oid OID +- addr CID/OID +`, + Run: tuiFunc, +} + +var initialPrompt string + +func init() { + common.AddComponentPathFlag(tuiCMD, &vPath) + + tuiCMD.Flags().StringVar( + &initialPrompt, + "filter", + "", + "Filter prompt to start with, format 'tag:value [+ tag:value]...'", + ) +} + +func tuiFunc(cmd *cobra.Command, _ []string) { + common.ExitOnErr(cmd, runTUI(cmd)) +} + +func runTUI(cmd *cobra.Command) error { + db, err := openDB(false) + common.ExitOnErr(cmd, err) + defer db.Close() + + ctx, cancel := context.WithCancel(cmd.Context()) + defer cancel() + + app := tview.NewApplication() + ui := tui.NewUI(ctx, app, db, schema.WritecacheParser, nil) + + _ = ui.AddFilter("cid", tui.CIDParser, "CID") + _ = ui.AddFilter("oid", tui.OIDParser, "OID") + _ = ui.AddCompositeFilter("addr", tui.AddressParser, "CID/OID") + + err = ui.WithPrompt(initialPrompt) + if err != nil { + return fmt.Errorf("invalid filter prompt: %w", err) + } + + app.SetRoot(ui, true).SetFocus(ui) + + return app.Run() +} + +func openDB(writable bool) (*bbolt.DB, error) { + db, err := bbolt.Open(vPath, 0o600, &bbolt.Options{ + ReadOnly: !writable, + }) + if err != nil { + return nil, fmt.Errorf("couldn't open database: %w", err) + } + return db, nil +}