🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

Commit fed41c8

Browse files
committed
[BMD change] add extra.custom: per-bucket user-defined metadata; cli help
* opaque string (up to 128 chars) in ExtraProps, settable via api.SetBucketProps * validate: max length, no control characters (all providers) --- * cli: add usage example --- * set-bucket-props error message: include unmarshal error Signed-off-by: Alex Aizman <alex.aizman@gmail.com>
1 parent ddbca5e commit fed41c8

5 files changed

Lines changed: 27 additions & 8 deletions

File tree

‎ais/proxy.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2162,7 +2162,7 @@ func (p *proxy) httpbckpatch(w http.ResponseWriter, r *http.Request, apireq *api
21622162
return
21632163
}
21642164
if err := cos.MorphMarshal(msg.Value, &propsToUpdate); err != nil {
2165-
p.writeErrMsg(w, r, "invalid props-to-update value in apireq: "+msg.String())
2165+
p.writeErrf(w, r, "invalid set-bucket-props request (msg=%s): %v", msg, err)
21662166
return
21672167
}
21682168
bck := apireq.bck

‎cmd/cli/cli/bucket_hdlr.go‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,11 @@ const setBpropsUsage = "Update bucket properties; the command accepts both JSON-
160160
indent1 + "\t* ais bucket props set gs://vvv versioning.validate_warm_get=false versioning.synchronize=true\n" +
161161
indent1 + "\t* ais bucket props set gs://vvv mirror.enabled=true mirror.copies=4 checksum.type=md5\n" +
162162
indent1 + "\t* ais bucket props set s3://mmm ec.enabled true ec.data_slices 6 ec.parity_slices 4 --force\n" +
163-
indent1 + "\tReferences:\n" +
163+
indent1 + "\t* ais bucket props set ais://nnn extra.custom=\"owner:team-a; project:research\"\n" +
164+
indent1 + "\tNotes:\n" +
164165
indent1 + "\t* for details and many more examples, see docs/cli/bucket.md\n" +
165-
indent1 + "\t* to show bucket properties (names and current values), use 'ais bucket show'"
166+
indent1 + "\t* to show bucket properties (names and current values), use 'ais bucket show'\n" +
167+
indent1 + "\t* 'extra.custom' is an opaque string (up to 128 characters) for per-bucket user-defined metadata"
166168

167169
// ais evict
168170
const evictUsage = "Evict one remote bucket, multiple remote buckets, or\n" +

‎cmd/cli/go.mod‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/NVIDIA/aistore/cmd/cli
33
go 1.26
44

55
require (
6-
github.com/NVIDIA/aistore v1.4.4-0.20260402210240-1fc284676618
6+
github.com/NVIDIA/aistore v1.4.4-0.20260403192745-bd0b7649cf79
77
github.com/fatih/color v1.18.0
88
github.com/json-iterator/go v1.1.12
99
github.com/onsi/ginkgo/v2 v2.27.5

‎cmd/cli/go.sum‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
22
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
33
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
4-
github.com/NVIDIA/aistore v1.4.4-0.20260402184834-2f6c6e7cf56e h1:zglEcqaBKgEnHYhwABEr8bJBPelD2+JVy4/ukvjNxg4=
5-
github.com/NVIDIA/aistore v1.4.4-0.20260402184834-2f6c6e7cf56e/go.mod h1:QHijEYljk1kmQR0jZcEf7Yjk3nI3mFnect6IVlxKP+c=
6-
github.com/NVIDIA/aistore v1.4.4-0.20260402210240-1fc284676618 h1:IT5hxxAxD0ecZH0Ycc9F5P5T5ojb0fKh1b0IKzTydjs=
7-
github.com/NVIDIA/aistore v1.4.4-0.20260402210240-1fc284676618/go.mod h1:QHijEYljk1kmQR0jZcEf7Yjk3nI3mFnect6IVlxKP+c=
4+
github.com/NVIDIA/aistore v1.4.4-0.20260403192745-bd0b7649cf79 h1:wgee2CD+9XAo4hJ0MHYzT40J6j1KOHcDiCwlpJvt7Is=
5+
github.com/NVIDIA/aistore v1.4.4-0.20260403192745-bd0b7649cf79/go.mod h1:cIncReWKV26gfKKSeKRWfcudlvdZagHvFE7huFRCEkk=
86
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
97
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
108
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=

‎cmn/api.go‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"reflect"
1515
"sort"
1616
"strings"
17+
"unicode"
1718

1819
"github.com/NVIDIA/aistore/api/apc"
1920
"github.com/NVIDIA/aistore/cmn/cos"
@@ -74,11 +75,15 @@ type (
7475
HTTP ExtraPropsHTTP `json:"http,omitempty" list:"omitempty"`
7576
AWS ExtraPropsAWS `json:"aws,omitempty" list:"omitempty"`
7677
GCP ExtraPropsGCP `json:"gcp,omitempty" list:"omitempty"`
78+
// e.g. "team=alpha;project=beta;id=123"
79+
Custom string `json:"custom,omitempty"`
7780
}
7881
ExtraToSet struct { // ref. bpropsFilterExtra
7982
AWS *ExtraPropsAWSToSet `json:"aws,omitempty"`
8083
HTTP *ExtraPropsHTTPToSet `json:"http,omitempty"`
8184
GCP *ExtraPropsGCPToSet `json:"gcp,omitempty"`
85+
// beware: any change to this field is still a version-bump + metasync
86+
Custom *string `json:"custom,omitempty"`
8287
}
8388

8489
ExtraPropsAWS struct {
@@ -315,6 +320,8 @@ const (
315320

316321
maxAWSProfileLen = 256
317322
maxAWSRegionLen = 64
323+
324+
maxCustomLen = 128
318325
)
319326

320327
func (c *ExtraProps) UnmarshalJSON(data []byte) error {
@@ -343,6 +350,18 @@ func (c *ExtraProps) ValidateAsProps(arg ...any) error {
343350
provider, ok := arg[0].(string)
344351
debug.Assert(ok)
345352

353+
// custom
354+
if s := c.Custom; s != "" {
355+
if len(s) > maxCustomLen {
356+
return fmt.Errorf("invalid extra.custom: too long (%d > %d)", len(s), maxCustomLen)
357+
}
358+
for i, r := range s {
359+
if unicode.IsControl(r) {
360+
return fmt.Errorf("invalid extra.custom: control character at byte position %d", i)
361+
}
362+
}
363+
}
364+
346365
switch provider {
347366
case apc.HT:
348367
if c.HTTP.OrigURLBck == "" {

0 commit comments

Comments
 (0)