@cryptotaxi247 / kubo / commits / bf8274f6e

feat: --reset flag on swarm limit command (#9310)

* feat: --reset flag on swarm limit command This flag allows to the user to reset limits to default values. Signed-off-by: Antonio Navarro Perez <antnavper@gmail.com> * Use adjusted default limits and remove already fixed FIXME Signed-off-by: Antonio Navarro Perez <antnavper@gmail.com> * Apply suggestions from code review Co-authored-by: Gus Eggert <gus@gus.dev> * Return correct defaults * Remove resetting all values from a map. Signed-off-by: Antonio Navarro Perez <antnavper@gmail.com> Signed-off-by: Antonio Navarro Perez <antnavper@gmail.com> Co-authored-by: Gus Eggert <gus@gus.dev>

Antonio Navarro Perez committed Oct 12, 2022 at 17:02 UTC bf8274f6e2afb28a624b75859991cb164cb367ff
4 files changed +135 -9
core/commands/swarm.go
+21 -8
@@ -63,10 +63,11 @@ ipfs peers in the internet.
63 }
64
65 const (
66 - swarmVerboseOptionName = "verbose"
67 - swarmStreamsOptionName = "streams"
68 - swarmLatencyOptionName = "latency"
69 - swarmDirectionOptionName = "direction"
66 + swarmVerboseOptionName = "verbose"
67 + swarmStreamsOptionName = "streams"
68 + swarmLatencyOptionName = "latency"
69 + swarmDirectionOptionName = "direction"
70 + swarmResetLimitsOptionName = "reset"
71 )
72
73 type peeringResult struct {
@@ -387,6 +388,9 @@ Changes made via command line are persisted in the Swarm.ResourceMgr.Limits fiel
388 cmds.StringArg("scope", true, false, "scope of the limit"),
389 cmds.FileArg("limit.json", false, false, "limits to be set").EnableStdin(),
390 },
391 + Options: []cmds.Option{
392 + cmds.BoolOption(swarmResetLimitsOptionName, "reset limit to default"),
393 + },
394 Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
395 node, err := cmdenv.GetNode(env)
396 if err != nil {
@@ -418,10 +422,19 @@ Changes made via command line are persisted in the Swarm.ResourceMgr.Limits fiel
422 }
423 }
424
421 - // get scope limit
422 - result, err := libp2p.NetLimit(node.ResourceManager, scope)
423 - if err != nil {
424 - return err
425 + var result rcmgr.BaseLimit
426 + _, reset := req.Options[swarmResetLimitsOptionName]
427 + if reset {
428 + result, err = libp2p.NetResetLimit(node.ResourceManager, node.Repo, scope)
429 + if err != nil {
430 + return err
431 + }
432 + } else {
433 + // get scope limit
434 + result, err = libp2p.NetLimit(node.ResourceManager, scope)
435 + if err != nil {
436 + return err
437 + }
438 }
439
440 b := new(bytes.Buffer)
core/node/libp2p/rcmgr.go
+98
@@ -347,3 +347,101 @@ func NetSetLimit(mgr network.ResourceManager, repo repo.Repo, scope string, limi
347
348 return nil
349 }
350 +
351 +// NetResetLimit resets ResourceManager limits to defaults. The limits take effect immediately, and are also persisted to the repo config.
352 +func NetResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) (rcmgr.BaseLimit, error) {
353 + var result rcmgr.BaseLimit
354 +
355 + setLimit := func(s network.ResourceScope, l rcmgr.Limit) error {
356 + limiter, ok := s.(rcmgr.ResourceScopeLimiter)
357 + if !ok {
358 + return ErrNoResourceMgr
359 + }
360 +
361 + limiter.SetLimit(l)
362 + return nil
363 + }
364 +
365 + cfg, err := repo.Config()
366 + if err != nil {
367 + return result, fmt.Errorf("reading config to reset limit: %w", err)
368 + }
369 +
370 + defaults := adjustedDefaultLimits(cfg.Swarm)
371 +
372 + if cfg.Swarm.ResourceMgr.Limits == nil {
373 + cfg.Swarm.ResourceMgr.Limits = &rcmgr.LimitConfig{}
374 + }
375 + configLimits := cfg.Swarm.ResourceMgr.Limits
376 +
377 + var setConfigFunc func() rcmgr.BaseLimit
378 + switch {
379 + case scope == config.ResourceMgrSystemScope:
380 + err = mgr.ViewSystem(func(s network.ResourceScope) error { return setLimit(s, &defaults.System) })
381 + setConfigFunc = func() rcmgr.BaseLimit {
382 + configLimits.System = defaults.System
383 + return defaults.System
384 + }
385 + case scope == config.ResourceMgrTransientScope:
386 + err = mgr.ViewTransient(func(s network.ResourceScope) error { return setLimit(s, &defaults.Transient) })
387 + setConfigFunc = func() rcmgr.BaseLimit {
388 + configLimits.Transient = defaults.Transient
389 + return defaults.Transient
390 + }
391 + case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix):
392 + svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix)
393 +
394 + err = mgr.ViewService(svc, func(s network.ServiceScope) error { return setLimit(s, &defaults.ServiceDefault) })
395 + setConfigFunc = func() rcmgr.BaseLimit {
396 + if configLimits.Service == nil {
397 + configLimits.Service = map[string]rcmgr.BaseLimit{}
398 + }
399 + configLimits.Service[svc] = defaults.ServiceDefault
400 + return defaults.ServiceDefault
401 + }
402 + case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix):
403 + proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix)
404 +
405 + err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { return setLimit(s, &defaults.ProtocolDefault) })
406 + setConfigFunc = func() rcmgr.BaseLimit {
407 + if configLimits.Protocol == nil {
408 + configLimits.Protocol = map[protocol.ID]rcmgr.BaseLimit{}
409 + }
410 + configLimits.Protocol[protocol.ID(proto)] = defaults.ProtocolDefault
411 +
412 + return defaults.ProtocolDefault
413 + }
414 + case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix):
415 + p := strings.TrimPrefix(scope, config.ResourceMgrPeerScopePrefix)
416 +
417 + var pid peer.ID
418 + pid, err = peer.Decode(p)
419 + if err != nil {
420 + return result, fmt.Errorf("invalid peer ID: %q: %w", p, err)
421 + }
422 +
423 + err = mgr.ViewPeer(pid, func(s network.PeerScope) error { return setLimit(s, &defaults.PeerDefault) })
424 + setConfigFunc = func() rcmgr.BaseLimit {
425 + if configLimits.Peer == nil {
426 + configLimits.Peer = map[peer.ID]rcmgr.BaseLimit{}
427 + }
428 + configLimits.Peer[pid] = defaults.PeerDefault
429 +
430 + return defaults.PeerDefault
431 + }
432 + default:
433 + return result, fmt.Errorf("invalid scope %q", scope)
434 + }
435 +
436 + if err != nil {
437 + return result, fmt.Errorf("resetting new limits on resource manager: %w", err)
438 + }
439 +
440 + result = setConfigFunc()
441 +
442 + if err := repo.SetConfig(cfg); err != nil {
443 + return result, fmt.Errorf("writing new limits to repo config: %w", err)
444 + }
445 +
446 + return result, nil
447 +}
core/node/libp2p/rcmgr_defaults.go
-1
@@ -21,7 +21,6 @@ import (
21 func adjustedDefaultLimits(cfg config.SwarmConfig) rcmgr.LimitConfig {
22 // Run checks to avoid introducing regressions
23 if os.Getenv("IPFS_CHECK_RCMGR_DEFAULTS") != "" {
24 - // FIXME: Broken. Being tracked in https://github.com/ipfs/go-ipfs/issues/8949.
24 checkImplicitDefaults()
25 }
26 defaultLimits := rcmgr.DefaultLimits
test/sharness/t0139-swarm-rcmgr.sh
+16
@@ -54,6 +54,22 @@ test_expect_success 'ResourceMgr enabled: swarm limit' '
54 jq -e .StreamsInbound < json &&
55 jq -e .StreamsOutbound < json
56 '
57 +test_expect_success 'ResourceMgr enabled: swarm limit reset' '
58 + ipfs swarm limit system --reset --enc=json 2> reset &&
59 + ipfs swarm limit system --enc=json 2> actual &&
60 + test_cmp reset actual
61 +'
62 +
63 +test_expect_success 'ResourceMgr enabled: swarm limit reset on map values' '
64 + ipfs swarm limit peer:12D3KooWL7i1T9VSPeF8AgQApbyM51GNKZsYPvNvL347aMDmvNzG --reset --enc=json 2> reset &&
65 + ipfs swarm limit peer:12D3KooWL7i1T9VSPeF8AgQApbyM51GNKZsYPvNvL347aMDmvNzG --enc=json 2> actual &&
66 + test_cmp reset actual
67 +'
68 +
69 +test_expect_success 'ResourceMgr enabled: scope is required using reset flag' '
70 + test_expect_code 1 ipfs swarm limit --reset 2> actual &&
71 + test_should_contain "Error: argument \"scope\" is required" actual
72 +'
73
74 test_expect_success 'connected: swarm stats all working properly' '
75 test_expect_code 0 ipfs swarm stats all