Add registry import command line tool #160

Merged
fyrchik merged 1 commit from elebedeva/xk6-frostfs:feat/registry-importer into master 2024-08-23 10:47:04 +00:00
4 changed files with 133 additions and 0 deletions

View file

@ -0,0 +1,55 @@
package importer
import (
"encoding/json"
"os"
"git.frostfs.info/TrueCloudLab/xk6-frostfs/internal/registry"
)
type PreGenObj struct {
Bucket string `json:"bucket"`
Object string `json:"object"`
Container string `json:"container"`
}
type PreGenerateInfo struct {
Buckets []string `json:"buckets"`
Containers []string `json:"containers"`
Objects []PreGenObj `json:"objects"`
ObjSize string `json:"obj_size"`
}
// ImportJSONPreGen writes objects from pregenerated JSON file
// to the registry.
// Note that ImportJSONPreGen does not check if object already
// exists in the registry so in case of re-entry the registry
// will have two entities representing the same object.
func ImportJSONPreGen(o *registry.ObjRegistry, filename string) error {
f, err := os.ReadFile(filename)
if err != nil {
return err
}
var pregenInfo PreGenerateInfo
err = json.Unmarshal(f, &pregenInfo)
if err != nil {
return err
fyrchik marked this conversation as resolved Outdated

Please, check if AddObject uses DB.Batch(). In this case we are effectively limited by MaxBatchDelay (10ms or 20ms).
Not important for preset (100 containers * 10 objects each = 1 second to process), but worth a comment somewhere.

Please, check if `AddObject` uses `DB.Batch()`. In this case we are effectively limited by `MaxBatchDelay` (10ms or 20ms). Not important for preset (100 containers * 10 objects each = 1 second to process), but worth a comment somewhere.

AddObject uses DB.Batch()

It does.

worth a comment somewhere

Do you mean the comment in the code?

> `AddObject` uses `DB.Batch()` It does. > worth a comment somewhere Do you mean the comment in the code?

Yes, near the loop -- it is the first thing we will try if we need to speed up things.

Yes, near the loop -- it is the first thing we will try if we need to speed up things.
}
// AddObject uses DB.Batch to combine concurrent Batch calls
// into a single Bolt transaction. DB.Batch is limited by
fyrchik marked this conversation as resolved Outdated

Is this command idempotent. I.e. if we fail (no space on disk) on the object A, it would be both in preset and registry.
What will happen if we run this command again?

Is this command idempotent. I.e. if we fail (no space on disk) on the object A, it would be both in preset and registry. What will happen if we run this command again?

The command is not idempotent. If we run it again after the object was put in registry, the registry will have two entities representing this object.

The command is not idempotent. If we run it again after the object was put in registry, the registry will have two entities representing this object.
// DB.MaxBatchDelay which may affect perfomance.
for _, obj := range pregenInfo.Objects {
if obj.Bucket != "" {
err = o.AddObject("", "", obj.Bucket, obj.Object, "")
} else {
err = o.AddObject(obj.Container, obj.Object, "", "", "")
}
if err != nil {
return err
}
}
return nil
}

View file

@ -0,0 +1,27 @@
package importer
acid-ant marked this conversation as resolved Outdated

Why have you put it in cmd/xk6-registry/importer/ but not in cmd/xk6-registry-importer/ as it is done for xk6-registry-exporter?
How to build it with make bin/*?

Why have you put it in `cmd/xk6-registry/importer/` but not in `cmd/xk6-registry-importer/` as it is done for `xk6-registry-exporter`? How to build it with `make bin/*`?

import is a subcommand of xk6-registry commandline tool. Later we can move xk6-registry-exporter functionality to the subcommand export of xk6-registry so that we have one tool to work with registry instead of many.

`import` is a subcommand of `xk6-registry` commandline tool. Later we can move `xk6-registry-exporter` functionality to the subcommand `export` of `xk6-registry` so that we have one tool to work with registry instead of many.
import (
"git.frostfs.info/TrueCloudLab/xk6-frostfs/internal/registry"
"github.com/spf13/cobra"
)
// Cmd represents the import command.
var Cmd = &cobra.Command{
Use: "import",
Short: "Import objects into registry",
Long: "Import objects into registry from pregenerated files",
Example: `xk6-registry import registry.bolt preset.json
xk6-registry import --status created registry.bolt preset.json another_preset.json`,
RunE: runCmd,
Args: cobra.MinimumNArgs(2),
}
func runCmd(cmd *cobra.Command, args []string) error {
objRegistry := registry.NewObjRegistry(cmd.Context(), args[0])
for i := 1; i < len(args); i++ {
if err := ImportJSONPreGen(objRegistry, args[i]); err != nil {
fyrchik marked this conversation as resolved Outdated
https://git.frostfs.info/TrueCloudLab/frostfs-node/src/commit/68029d756e59d036b11b95153d70e64588ee720e/cmd/frostfs-cli/modules/acl/basic/print.go#L21

Please, see the validation above, it can be done simpler.

Please, see the validation above, it can be done simpler.

Fixed!

Fixed!
return err
}
}
return nil
}

18
cmd/xk6-registry/main.go Normal file
View file

@ -0,0 +1,18 @@
package main
import (
"context"
"os"
"os/signal"
"syscall"
)
func main() {
ctx, _ := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
if cmd, err := rootCmd.ExecuteContextC(ctx); err != nil {
cmd.PrintErrln("Error:", err.Error())
cmd.PrintErrf("Run '%v --help' for usage.\n", cmd.CommandPath())
os.Exit(1)
}
}

33
cmd/xk6-registry/root.go Normal file
View file

@ -0,0 +1,33 @@
package main
import (
"runtime"
"git.frostfs.info/TrueCloudLab/xk6-frostfs/cmd/xk6-registry/importer"
"git.frostfs.info/TrueCloudLab/xk6-frostfs/internal/version"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
Use: "xk6-registry",
Version: version.Version,
Short: "Command Line Tool to work with Registry",
Long: `Registry provides tools to work with object registry for xk6.
It contains command for importing objects in registry from preset`,
SilenceErrors: true,
SilenceUsage: true,
Run: rootCmdRun,
}
func init() {
cobra.AddTemplateFunc("runtimeVersion", runtime.Version)
fyrchik marked this conversation as resolved Outdated

Will it look xk6-registry runtimeVersion in CLI?

Will it look `xk6-registry runtimeVersion` in CLI?

It's used in the template of --version.
Looks like this:

❯ ./bin/frostfs-xk6-registry -v
FrostFS xk6-registry
Version: fa240302
GoVersion: go1.22.5
It's used in the template of `--version`. Looks like this: ``` ❯ ./bin/frostfs-xk6-registry -v FrostFS xk6-registry Version: fa240302 GoVersion: go1.22.5 ```
rootCmd.SetVersionTemplate(`FrostFS xk6-registry
{{printf "Version: %s" .Version }}
GoVersion: {{ runtimeVersion }}
`)
rootCmd.AddCommand(importer.Cmd)
}
func rootCmdRun(cmd *cobra.Command, _ []string) {
_ = cmd.Usage()
}