Skip to content

Commit 1d8f705

Browse files
committed
TODO
1 parent 1957fda commit 1d8f705

File tree

6 files changed

+105
-85
lines changed

6 files changed

+105
-85
lines changed

config/types.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -420,12 +420,20 @@ type swarmLimits struct{}
420420
var _ json.Unmarshaler = swarmLimits{}
421421

422422
func (swarmLimits) UnmarshalJSON(b []byte) error {
423-
switch _, err := json.NewDecoder(bytes.NewReader(b)).Token(); err {
424-
case io.EOF:
425-
return nil
426-
case nil:
427-
return fmt.Errorf("field Swarm.ResourceMgr.Limits has been removed in 0.19 and must be empty or not present")
428-
default:
429-
return err
423+
d := json.NewDecoder(bytes.NewReader(b))
424+
for {
425+
switch tok, err := d.Token(); err {
426+
case io.EOF:
427+
return nil
428+
case nil:
429+
switch tok {
430+
case json.Delim('{'), json.Delim('}'):
431+
// accept empty objects
432+
continue
433+
}
434+
return fmt.Errorf("field Swarm.ResourceMgr.Limits has been removed in 0.19 and must be empty or not present")
435+
default:
436+
return err
437+
}
430438
}
431439
}

core/commands/swarm.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,11 +348,10 @@ The output of this command is JSON.
348348
}
349349

350350
stats := rapi.Stat()
351-
result := libp2p.StatToLimitConfig(stats).ToPartialLimitConfig()
352351

353352
b := new(bytes.Buffer)
354353
enc := json.NewEncoder(b)
355-
err = enc.Encode(result)
354+
err = enc.Encode(stats)
356355
if err != nil {
357356
return err
358357
}

core/node/libp2p/rcmgr.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func ResourceManager(cfg config.SwarmConfig, userOverrides rcmgr.PartialLimitCon
5858
// We want to see this message on startup, that's why we are using fmt instead of log.
5959
fmt.Print(msg)
6060

61-
if err := ensureConnMgrMakeSenseVsResourceMgr(limitConfig, cfg.ConnMgr); err != nil {
61+
if err := ensureConnMgrMakeSenseVsResourceMgr(limitConfig, cfg); err != nil {
6262
return nil, opts, err
6363
}
6464

@@ -138,8 +138,6 @@ func LimitConfig(cfg config.SwarmConfig, userOverrides rcmgr.PartialLimitConfig)
138138
return limitConfig, msg, nil
139139
}
140140

141-
// StatToLimitConfig converts a stats object into a LimitConfig one. This is useful when you want to generate
142-
// JSONs with the same structure for current stats and limits.
143141
func StatToLimitConfig(stats rcmgr.ResourceManagerStat) rcmgr.ConcreteLimitConfig {
144142
result := rcmgr.PartialLimitConfig{}
145143

@@ -323,14 +321,14 @@ func scopeStatToBaseLimit(ss network.ScopeStat) rcmgr.BaseLimit {
323321
}
324322
}
325323

326-
func ensureConnMgrMakeSenseVsResourceMgr(concreteLimits rcmgr.ConcreteLimitConfig, cmgr config.ConnMgr) error {
327-
if cmgr.Type.WithDefault(config.DefaultConnMgrType) == "none" {
328-
return nil // none connmgr, no checks to do
324+
func ensureConnMgrMakeSenseVsResourceMgr(concreteLimits rcmgr.ConcreteLimitConfig, cfg config.SwarmConfig) error {
325+
if cfg.ConnMgr.Type.WithDefault(config.DefaultConnMgrType) == "none" || len(cfg.ResourceMgr.Allowlist) != 0 {
326+
return nil // none connmgr, or setup with an allow list, no checks to do
329327
}
330328

331329
rcm := concreteLimits.ToPartialLimitConfig()
332330

333-
highWater := cmgr.HighWater.WithDefault(config.DefaultConnMgrHighWater)
331+
highWater := cfg.ConnMgr.HighWater.WithDefault(config.DefaultConnMgrHighWater)
334332
if rcm.System.Conns != rcmgr.Unlimited && int64(rcm.System.Conns) <= highWater {
335333
// nolint
336334
return fmt.Errorf(`

repo/fsrepo/fsrepo.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package fsrepo
22

33
import (
44
"context"
5-
"encoding/json"
65
"errors"
76
"fmt"
87
"io"
@@ -447,18 +446,11 @@ func (r *FSRepo) openConfig() error {
447446
// openUserRessourceOverrides will remove all overrides if the file is not present.
448447
// It will error if the decoding fails.
449448
func (r *FSRepo) openUserRessourceOverrides() error {
450-
f, err := os.Open(filepath.Join(r.path, "limits.json"))
451-
switch {
452-
case err == nil:
453-
case os.IsNotExist(err):
454-
r.userRessourceOverrides = rcmgr.PartialLimitConfig{}
455-
return nil
456-
default:
457-
return err
449+
err := serialize.ReadConfigFile(filepath.Join(r.path, "limits.json"), &r.userRessourceOverrides)
450+
if err == serialize.ErrNotInitialized {
451+
err = nil
458452
}
459-
defer f.Close()
460-
461-
return json.NewDecoder(f).Decode(&r.userRessourceOverrides)
453+
return err
462454
}
463455

464456
func (r *FSRepo) openKeystore() error {

test/cli/harness/node.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/ipfs/kubo/config"
2121
serial "github.com/ipfs/kubo/config/serialize"
2222
"github.com/libp2p/go-libp2p/core/peer"
23+
rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
2324
"github.com/multiformats/go-multiaddr"
2425
manet "github.com/multiformats/go-multiaddr/net"
2526
)
@@ -96,6 +97,38 @@ func (n *Node) UpdateConfig(f func(cfg *config.Config)) {
9697
n.WriteConfig(cfg)
9798
}
9899

100+
func (n *Node) ReadUserSuppliedRessourceOverrides() *rcmgr.PartialLimitConfig {
101+
var r rcmgr.PartialLimitConfig
102+
err := serial.ReadConfigFile(filepath.Join(n.Dir, "limits.json"), &r)
103+
switch err {
104+
case nil, serial.ErrNotInitialized:
105+
return &r
106+
default:
107+
panic(err)
108+
}
109+
}
110+
111+
func (n *Node) WriteUserSuppliedRessourceOverrides(c *rcmgr.PartialLimitConfig) {
112+
err := serial.WriteConfigFile(filepath.Join(n.Dir, "limits.json"), c)
113+
if err != nil {
114+
panic(err)
115+
}
116+
}
117+
118+
func (n *Node) UpdateUserSuppliedRessourceManagerOverrides(f func(overrides *rcmgr.PartialLimitConfig)) {
119+
overrides := n.ReadUserSuppliedRessourceOverrides()
120+
f(overrides)
121+
n.WriteUserSuppliedRessourceOverrides(overrides)
122+
}
123+
124+
func (n *Node) UpdateConfigAndUserSuppliedRessourceManagerOverrides(f func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig)) {
125+
overrides := n.ReadUserSuppliedRessourceOverrides()
126+
cfg := n.ReadConfig()
127+
f(cfg, overrides)
128+
n.WriteConfig(cfg)
129+
n.WriteUserSuppliedRessourceOverrides(overrides)
130+
}
131+
99132
func (n *Node) IPFS(args ...string) RunResult {
100133
res := n.RunIPFS(args...)
101134
n.Runner.AssertNoError(res)

test/cli/rcmgr_test.go

Lines changed: 47 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/ipfs/kubo/config"
88
"github.com/ipfs/kubo/test/cli/harness"
99
"github.com/libp2p/go-libp2p/core/peer"
10+
"github.com/libp2p/go-libp2p/core/protocol"
1011
rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
1112
"github.com/stretchr/testify/assert"
1213
"github.com/stretchr/testify/require"
@@ -47,12 +48,12 @@ func TestRcmgr(t *testing.T) {
4748
t.Run("swarm limit should fail", func(t *testing.T) {
4849
res := node.RunIPFS("swarm", "limit")
4950
assert.Equal(t, 1, res.ExitCode())
50-
assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr")
51+
assert.Contains(t, res.Stderr.String(), "missing ResourceMgr")
5152
})
5253
t.Run("swarm stats should fail", func(t *testing.T) {
5354
res := node.RunIPFS("swarm", "stats")
5455
assert.Equal(t, 1, res.ExitCode())
55-
assert.Contains(t, res.Stderr.Lines()[0], "missing ResourceMgr")
56+
assert.Contains(t, res.Stderr.String(), "missing ResourceMgr")
5657
})
5758
})
5859

@@ -131,14 +132,8 @@ func TestRcmgr(t *testing.T) {
131132
assert.Equal(t, resetRes.Stdout.Bytes(), limitRes.Stdout.Bytes())
132133
})
133134

134-
t.Run("scope is required using reset flags", func(t *testing.T) {
135-
res := node.RunIPFS("swarm", "limit", "--reset")
136-
assert.Equal(t, 1, res.ExitCode())
137-
assert.Contains(t, res.Stderr.Lines()[0], `Error: argument "scope" is required`)
138-
})
139-
140135
t.Run("swarm stats works", func(t *testing.T) {
141-
res := node.RunIPFS("swarm", "stats", "all", "--enc=json")
136+
res := node.RunIPFS("swarm", "stats")
142137
require.Equal(t, 0, res.ExitCode())
143138

144139
stats := rcmgr.PartialLimitConfig{}
@@ -178,46 +173,36 @@ func TestRcmgr(t *testing.T) {
178173
})
179174
})
180175

181-
t.Run("set the system memory limit while the daemon is running", func(t *testing.T) {
182-
node := harness.NewT(t).NewNode().Init().StartDaemon()
183-
updateLimitsWithFile(t, node, "system", func(limits *rcmgr.ResourceLimits) {
184-
limits.Memory = 99998
185-
})
186-
187-
assert.Equal(t, rcmgr.LimitVal64(99998), node.ReadConfig().Swarm.ResourceMgr.Limits.System.Memory)
188-
189-
res := node.RunIPFS("swarm", "limit")
190-
limits := unmarshalLimits(t, res.Stdout.Bytes())
191-
assert.Equal(t, rcmgr.LimitVal64(99998), limits.System.Memory)
192-
})
193-
194176
t.Run("smoke test transient scope", func(t *testing.T) {
195-
node := harness.NewT(t).NewNode().Init().StartDaemon()
196-
updateLimitsWithFile(t, node, "transient", func(limits *rcmgr.ResourceLimits) {
197-
limits.Memory = 88888
177+
node := harness.NewT(t).NewNode().Init()
178+
node.UpdateUserSuppliedRessourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) {
179+
overrides.Transient.Memory = 88888
198180
})
181+
node.StartDaemon()
199182

200183
res := node.RunIPFS("swarm", "limit")
201184
limits := unmarshalLimits(t, res.Stdout.Bytes())
202185
assert.Equal(t, rcmgr.LimitVal64(88888), limits.Transient.Memory)
203186
})
204187

205188
t.Run("smoke test service scope", func(t *testing.T) {
206-
node := harness.NewT(t).NewNode().Init().StartDaemon()
207-
updateLimitsWithFile(t, node, "svc:foo", func(limits *rcmgr.ResourceLimits) {
208-
limits.Memory = 77777
189+
node := harness.NewT(t).NewNode().Init()
190+
node.UpdateUserSuppliedRessourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) {
191+
overrides.Service = map[string]rcmgr.ResourceLimits{"foo": {Memory: 77777}}
209192
})
193+
node.StartDaemon()
210194

211195
res := node.RunIPFS("swarm", "limit")
212196
limits := unmarshalLimits(t, res.Stdout.Bytes())
213197
assert.Equal(t, rcmgr.LimitVal64(77777), limits.Service["foo"].Memory)
214198
})
215199

216200
t.Run("smoke test protocol scope", func(t *testing.T) {
217-
node := harness.NewT(t).NewNode().Init().StartDaemon()
218-
updateLimitsWithFile(t, node, "proto:foo", func(limits *rcmgr.ResourceLimits) {
219-
limits.Memory = 66666
201+
node := harness.NewT(t).NewNode().Init()
202+
node.UpdateUserSuppliedRessourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) {
203+
overrides.Protocol = map[protocol.ID]rcmgr.ResourceLimits{"foo": {Memory: 66666}}
220204
})
205+
node.StartDaemon()
221206

222207
res := node.RunIPFS("swarm", "limit")
223208
limits := unmarshalLimits(t, res.Stdout.Bytes())
@@ -227,19 +212,20 @@ func TestRcmgr(t *testing.T) {
227212
t.Run("smoke test peer scope", func(t *testing.T) {
228213
validPeerID, err := peer.Decode("QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN")
229214
assert.NoError(t, err)
230-
node := harness.NewT(t).NewNode().Init().StartDaemon()
231-
updateLimitsWithFile(t, node, "peer:"+validPeerID.Pretty(), func(limits *rcmgr.ResourceLimits) {
232-
limits.Memory = 66666
215+
node := harness.NewT(t).NewNode().Init()
216+
node.UpdateUserSuppliedRessourceManagerOverrides(func(overrides *rcmgr.PartialLimitConfig) {
217+
overrides.Peer = map[peer.ID]rcmgr.ResourceLimits{validPeerID: {Memory: 55555}}
233218
})
219+
node.StartDaemon()
234220

235-
res := node.RunIPFS("swarm", "limit", "peer:"+validPeerID.Pretty(), "--enc=json")
221+
res := node.RunIPFS("swarm", "limit")
236222
limits := unmarshalLimits(t, res.Stdout.Bytes())
237-
assert.Equal(t, rcmgr.LimitVal64(66666), limits.Peer[validPeerID].Memory)
223+
assert.Equal(t, rcmgr.LimitVal64(55555), limits.Peer[validPeerID].Memory)
238224

239225
t.Parallel()
240226

241227
t.Run("getting limit for invalid peer ID fails", func(t *testing.T) {
242-
res := node.RunIPFS("swarm", "limit", "peer:foo")
228+
res := node.RunIPFS("swarm", "limit")
243229
assert.Equal(t, 1, res.ExitCode())
244230
assert.Contains(t, res.Stderr.String(), "invalid peer ID")
245231
})
@@ -259,20 +245,20 @@ func TestRcmgr(t *testing.T) {
259245
// peerID0, peerID1, peerID2 := node0.PeerID(), node1.PeerID(), node2.PeerID()
260246
peerID1, peerID2 := node1.PeerID().String(), node2.PeerID().String()
261247

262-
node0.UpdateConfig(func(cfg *config.Config) {
248+
node0.UpdateConfigAndUserSuppliedRessourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) {
249+
*overrides = rcmgr.PartialLimitConfig{
250+
System: rcmgr.ResourceLimits{
251+
Conns: rcmgr.BlockAllLimit,
252+
ConnsInbound: rcmgr.BlockAllLimit,
253+
ConnsOutbound: rcmgr.BlockAllLimit,
254+
},
255+
}
263256
cfg.Swarm.ResourceMgr.Enabled = config.True
264257
cfg.Swarm.ResourceMgr.Allowlist = []string{"/ip4/0.0.0.0/ipcidr/0/p2p/" + peerID2}
265258
})
266259

267260
nodes.StartDaemons()
268261

269-
// change system limits on node 0
270-
updateLimitsWithFile(t, node0, "system", func(limits *rcmgr.ResourceLimits) {
271-
limits.Conns = rcmgr.BlockAllLimit
272-
limits.ConnsInbound = rcmgr.BlockAllLimit
273-
limits.ConnsOutbound = rcmgr.BlockAllLimit
274-
})
275-
276262
t.Parallel()
277263
t.Run("node 0 should fail to connect to node 1", func(t *testing.T) {
278264
res := node0.Runner.Run(harness.RunRequest{
@@ -307,9 +293,10 @@ func TestRcmgr(t *testing.T) {
307293
t.Parallel()
308294
t.Run("system conns", func(t *testing.T) {
309295
node := harness.NewT(t).NewNode().Init()
310-
node.UpdateConfig(func(cfg *config.Config) {
311-
cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{}
312-
cfg.Swarm.ResourceMgr.Limits.System.Conns = 128
296+
node.UpdateConfigAndUserSuppliedRessourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) {
297+
*overrides = rcmgr.PartialLimitConfig{
298+
System: rcmgr.ResourceLimits{Conns: 128},
299+
}
313300
cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128)
314301
cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64)
315302
})
@@ -319,9 +306,10 @@ func TestRcmgr(t *testing.T) {
319306
})
320307
t.Run("system conns inbound", func(t *testing.T) {
321308
node := harness.NewT(t).NewNode().Init()
322-
node.UpdateConfig(func(cfg *config.Config) {
323-
cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{}
324-
cfg.Swarm.ResourceMgr.Limits.System.ConnsInbound = 128
309+
node.UpdateConfigAndUserSuppliedRessourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) {
310+
*overrides = rcmgr.PartialLimitConfig{
311+
System: rcmgr.ResourceLimits{ConnsInbound: 128},
312+
}
325313
cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128)
326314
cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64)
327315
})
@@ -331,9 +319,10 @@ func TestRcmgr(t *testing.T) {
331319
})
332320
t.Run("system streams", func(t *testing.T) {
333321
node := harness.NewT(t).NewNode().Init()
334-
node.UpdateConfig(func(cfg *config.Config) {
335-
cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{}
336-
cfg.Swarm.ResourceMgr.Limits.System.Streams = 128
322+
node.UpdateConfigAndUserSuppliedRessourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) {
323+
*overrides = rcmgr.PartialLimitConfig{
324+
System: rcmgr.ResourceLimits{Streams: 128},
325+
}
337326
cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128)
338327
cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64)
339328
})
@@ -343,9 +332,10 @@ func TestRcmgr(t *testing.T) {
343332
})
344333
t.Run("system streams inbound", func(t *testing.T) {
345334
node := harness.NewT(t).NewNode().Init()
346-
node.UpdateConfig(func(cfg *config.Config) {
347-
cfg.Swarm.ResourceMgr.Limits = &rcmgr.PartialLimitConfig{}
348-
cfg.Swarm.ResourceMgr.Limits.System.StreamsInbound = 128
335+
node.UpdateConfigAndUserSuppliedRessourceManagerOverrides(func(cfg *config.Config, overrides *rcmgr.PartialLimitConfig) {
336+
*overrides = rcmgr.PartialLimitConfig{
337+
System: rcmgr.ResourceLimits{StreamsInbound: 128},
338+
}
349339
cfg.Swarm.ConnMgr.HighWater = config.NewOptionalInteger(128)
350340
cfg.Swarm.ConnMgr.LowWater = config.NewOptionalInteger(64)
351341
})

0 commit comments

Comments
 (0)