@@ -17,6 +17,8 @@ import (
17
17
"github.com/NVIDIA/aistore/cmn"
18
18
"github.com/NVIDIA/aistore/cmn/archive"
19
19
"github.com/NVIDIA/aistore/cmn/cos"
20
+ "github.com/NVIDIA/aistore/cmn/debug"
21
+ jsoniter "github.com/json-iterator/go"
20
22
"github.com/urfave/cli"
21
23
)
22
24
@@ -300,10 +302,10 @@ var (
300
302
}
301
303
)
302
304
303
- func createBucketHandler (c * cli.Context ) ( err error ) {
305
+ func createBucketHandler (c * cli.Context ) error {
304
306
var props * cmn.BpropsToSet
305
307
if flagIsSet (c , bucketPropsFlag ) {
306
- propSingleBck , err := parseBpropsFromContext (c )
308
+ propSingleBck , _ , err := _parseBprops (c )
307
309
if err != nil {
308
310
return err
309
311
}
@@ -400,24 +402,38 @@ func toggleLRU(c *cli.Context, bck cmn.Bck, p *cmn.Bprops, toggle bool) (err err
400
402
return updateBckProps (c , bck , p , toggledProps )
401
403
}
402
404
403
- func setPropsHandler (c * cli.Context ) (err error ) {
404
- var currProps * cmn.Bprops
405
- bck , err := parseBckURI (c , c .Args ().Get (0 ), false )
405
+ func setPropsHandler (c * cli.Context ) error {
406
+ var (
407
+ currBprops * cmn.Bprops
408
+ nvs cos.StrKVs // user specified
409
+ newBprops * cmn.BpropsToSet // API structure to set
410
+ bck , err = parseBckURI (c , c .Args ().Get (0 ), false )
411
+ )
406
412
if err != nil {
407
413
return err
408
414
}
415
+
409
416
dontHeadRemote := flagIsSet (c , dontHeadRemoteFlag )
410
417
if ! dontHeadRemote {
411
- if currProps , err = headBucket (bck , false /* don't add */ ); err != nil {
418
+ if currBprops , err = headBucket (bck , false /* don't add */ ); err != nil {
412
419
return err
413
420
}
414
421
}
415
- newProps , err := parseBpropsFromContext (c )
416
-
422
+ newBprops , nvs , err = _parseBprops (c )
417
423
if err == nil {
418
- newProps .Force = flagIsSet (c , forceFlag )
419
- return updateBckProps (c , bck , currProps , newProps )
424
+ newBprops .Force = flagIsSet (c , forceFlag )
425
+ err = updateBckProps (c , bck , currBprops , newBprops )
426
+ if err != nil {
427
+ return err
428
+ }
429
+ // feature flags: show all w/ descriptions
430
+ if _ , ok := nvs [featureFlagsJname ]; ok && newBprops .Features != nil {
431
+ err = printFeatVerbose (c , * newBprops .Features , true /*bucket scope*/ )
432
+ }
433
+ return err
420
434
}
435
+
436
+ // [usability] try to help
421
437
var (
422
438
section = c .Args ().Get (1 )
423
439
isValid bool
@@ -435,35 +451,100 @@ func setPropsHandler(c *cli.Context) (err error) {
435
451
return nil
436
452
}
437
453
}
454
+
438
455
return fmt .Errorf ("%v%s" , err , examplesBckSetProps )
439
456
}
440
457
441
- // TODO: more validation; e.g. `validate_warm_get = true` is only supported for buckets with Cloud and remais backends
442
- func updateBckProps (c * cli.Context , bck cmn.Bck , currProps * cmn.Bprops , updateProps * cmn.BpropsToSet ) (err error ) {
458
+ func updateBckProps (c * cli.Context , bck cmn.Bck , currBprops * cmn.Bprops , updateProps * cmn.BpropsToSet ) error {
443
459
// apply updated props
444
- allNewProps := currProps .Clone ()
445
- allNewProps .Apply (updateProps )
460
+ allNewBprops := currBprops .Clone ()
461
+ allNewBprops .Apply (updateProps )
446
462
447
463
// check for changes
448
- if allNewProps .Equal (currProps ) {
464
+ if allNewBprops .Equal (currBprops ) {
449
465
displayPropsEqMsg (c , bck )
450
466
return nil
451
467
}
452
468
453
469
// do
454
- if _ , err = api .SetBucketProps (apiBP , bck , updateProps ); err != nil {
470
+ if _ , err : = api .SetBucketProps (apiBP , bck , updateProps ); err != nil {
455
471
if herr , ok := err .(* cmn.ErrHTTP ); ok && herr .Status == http .StatusNotFound {
456
472
return herr
457
473
}
458
474
helpMsg := fmt .Sprintf ("To show bucket properties, run '%s %s %s %s'" ,
459
475
cliName , commandShow , cmdBucket , bck .Cname ("" ))
460
476
return newAdditionalInfoError (err , helpMsg )
461
477
}
462
- showDiff (c , currProps , allNewProps )
478
+
479
+ _showDiff (c , currBprops , allNewBprops )
480
+
463
481
actionDone (c , "\n Bucket props successfully updated." )
464
482
return nil
465
483
}
466
484
485
+ func _showDiff (c * cli.Context , currBprops , newBprops * cmn.Bprops ) {
486
+ var (
487
+ newPropList = bckPropList (newBprops , true )
488
+ origPropList = bckPropList (currBprops , true )
489
+ )
490
+ for _ , np := range newPropList {
491
+ var found bool
492
+ for _ , op := range origPropList {
493
+ if np .Name != op .Name {
494
+ continue
495
+ }
496
+ found = true
497
+ if np .Value != op .Value {
498
+ fmt .Fprintf (c .App .Writer , "%q set to: %q (was: %q)\n " , np .Name , _clearFmt (np .Value ), _clearFmt (op .Value ))
499
+ }
500
+ }
501
+ if ! found && np .Value != "" {
502
+ fmt .Fprintf (c .App .Writer , "%q set to: %q (was: n/a)\n " , np .Name , _clearFmt (np .Value ))
503
+ }
504
+ }
505
+
506
+ // feature flags: show all w/ descriptions
507
+ if len (newPropList ) == 1 && newPropList [0 ].Name == featureFlagsJname {
508
+ err := printFeatVerbose (c , newBprops .Features , true /*bucket scope*/ )
509
+ debug .AssertNoErr (err )
510
+ }
511
+ }
512
+
513
+ func _parseBprops (c * cli.Context ) (props * cmn.BpropsToSet , nvs cos.StrKVs , err error ) {
514
+ propArgs := c .Args ().Tail ()
515
+
516
+ if c .Command .Name == commandCreate {
517
+ inputProps := parseStrFlag (c , bucketPropsFlag )
518
+ if isJSON (inputProps ) {
519
+ err = jsoniter .Unmarshal ([]byte (inputProps ), & props )
520
+ return
521
+ }
522
+ propArgs = strings .Split (inputProps , " " )
523
+ }
524
+
525
+ if len (propArgs ) == 1 && isJSON (propArgs [0 ]) {
526
+ err = jsoniter .Unmarshal ([]byte (propArgs [0 ]), & props )
527
+ return
528
+ }
529
+
530
+ if len (propArgs ) == 0 {
531
+ return nil , nil , missingArgumentsError (c , "property key-value pairs" )
532
+ }
533
+
534
+ // command line => key/val pairs
535
+ nvs , err = makeBckPropPairs (propArgs )
536
+ if err != nil {
537
+ return nil , nil , err
538
+ }
539
+ if err = reformatBackendProps (c , nvs ); err != nil {
540
+ return nil , nvs , err
541
+ }
542
+
543
+ // key/val pairs => cmn.BpropsToSet
544
+ props , err = cmn .NewBpropsToSet (nvs )
545
+ return props , nvs , err
546
+ }
547
+
467
548
func displayPropsEqMsg (c * cli.Context , bck cmn.Bck ) {
468
549
args := c .Args ().Tail ()
469
550
if len (args ) == 1 && ! isJSON (args [0 ]) {
@@ -485,28 +566,6 @@ func _clearFmt(v string) string {
485
566
return strings .ReplaceAll (nv , "\t " , "" )
486
567
}
487
568
488
- func showDiff (c * cli.Context , currProps , newProps * cmn.Bprops ) {
489
- var (
490
- origKV = bckPropList (currProps , true )
491
- newKV = bckPropList (newProps , true )
492
- )
493
- for _ , np := range newKV {
494
- var found bool
495
- for _ , op := range origKV {
496
- if np .Name != op .Name {
497
- continue
498
- }
499
- found = true
500
- if np .Value != op .Value {
501
- fmt .Fprintf (c .App .Writer , "%q set to: %q (was: %q)\n " , np .Name , _clearFmt (np .Value ), _clearFmt (op .Value ))
502
- }
503
- }
504
- if ! found && np .Value != "" {
505
- fmt .Fprintf (c .App .Writer , "%q set to: %q (was: n/a)\n " , np .Name , _clearFmt (np .Value ))
506
- }
507
- }
508
- }
509
-
510
569
func listAnyHandler (c * cli.Context ) error {
511
570
var (
512
571
opts = cmn.ParseURIOpts {IsQuery : true }
0 commit comments