Add registry import command line tool #160
55
cmd/xk6-registry/importer/import.go
Normal 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
|
||||
}
|
||||
|
||||
// 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
fyrchik
commented
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. 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?
elebedeva
commented
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
|
||||
}
|
27
cmd/xk6-registry/importer/root.go
Normal file
|
@ -0,0 +1,27 @@
|
|||||
package importer
|
||||||
acid-ant marked this conversation as resolved
Outdated
acid-ant
commented
Why have you put it in 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/*`?
elebedeva
commented
`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
fyrchik
commented
Line 21 in TrueCloudLab/frostfs-node@68029d7
https://git.frostfs.info/TrueCloudLab/frostfs-node/src/commit/68029d756e59d036b11b95153d70e64588ee720e/cmd/frostfs-cli/modules/acl/basic/print.go#L21
fyrchik
commented
Please, see the validation above, it can be done simpler. Please, see the validation above, it can be done simpler.
elebedeva
commented
Fixed! Fixed!
|
||||||
return err
|
||||||
}
|
||||||
}
|
||||||
return nil
|
||||||
}
|
18
cmd/xk6-registry/main.go
Normal 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
|
@ -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
fyrchik
commented
Will it look Will it look `xk6-registry runtimeVersion` in CLI?
elebedeva
commented
It's used in the template of
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()
|
||||
}
|
Please, check if
AddObject
usesDB.Batch()
. In this case we are effectively limited byMaxBatchDelay
(10ms or 20ms).Not important for preset (100 containers * 10 objects each = 1 second to process), but worth a comment somewhere.
It does.
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.