diff --git a/cli/flags.go b/cli/flags.go index bcf562d..b30b6a0 100644 --- a/cli/flags.go +++ b/cli/flags.go @@ -273,6 +273,16 @@ var ioFlags = []cli.Flag{ Name: "lookup", Usage: "Force requests to be 'host' for host-style or 'path' for path-style lookup. Default will attempt autodetect based on remote host name.", }, + cli.StringSliceFlag{ + Name: "metadata", + Usage: "Add user metada to all objects using the format =. Random value can be set with 'rand:%length'. Can be used multiple times. Example: --metadata foo=bar --metadata randomValue=rand:1024.", + Hidden: true, + }, + cli.StringSliceFlag{ + Name: "tag", + Usage: "Add user tag to all objects using the format =. Random value can be set with 'rand:%length'. Can be used multiple times. Example: --tag foo=bar --tag randomValue=rand:1024.", + Hidden: true, + }, } func getCommon(ctx *cli.Context, src func() generator.Source) bench.Common { diff --git a/cli/put.go b/cli/put.go index 5c6d791..c55c8f5 100644 --- a/cli/put.go +++ b/cli/put.go @@ -18,6 +18,10 @@ package cli import ( + "fmt" + "math/rand" + "strings" + "github.com/minio/cli" "github.com/minio/minio-go/v7" "github.com/minio/pkg/v2/console" @@ -71,10 +75,12 @@ func mainPut(ctx *cli.Context) error { return runBench(ctx, &b) } +const metadataChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_." + // putOpts retrieves put options from the context. func putOpts(ctx *cli.Context) minio.PutObjectOptions { pSize, _ := toSize(ctx.String("part.size")) - return minio.PutObjectOptions{ + options := minio.PutObjectOptions{ ServerSideEncryption: newSSE(ctx), DisableMultipart: ctx.Bool("disable-multipart"), DisableContentSha256: ctx.Bool("disable-sha256-payload"), @@ -82,6 +88,40 @@ func putOpts(ctx *cli.Context) minio.PutObjectOptions { StorageClass: ctx.String("storage-class"), PartSize: pSize, } + + for _, flag := range []string{"metadata", "tag"} { + values := make(map[string]string) + + for _, v := range ctx.StringSlice(flag) { + idx := strings.Index(v, "=") + if idx <= 0 { + console.Fatalf("--%s takes `key=value` argument", flag) + } + key := v[:idx] + value := v[idx+1:] + if len(value) == 0 { + console.Fatal("--%s value can't be empty", flag) + } + var rand_n int + if _, err := fmt.Sscanf(value, "rand:%d", &rand_n); err == nil { + rng := rand.New(rand.NewSource(int64(rand.Uint64()))) + value = "" + for i := 0; i < rand_n; i++ { + value = value + string(metadataChars[rng.Int()%len(metadataChars)]) + } + } + values[key] = value + } + + switch flag { + case "metadata": + options.UserMetadata = values + case "tag": + options.UserTags = values + } + } + + return options } func checkPutSyntax(ctx *cli.Context) {