Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit765e705

Browse files
chore: use container memory if containerised for oom notifications (#17062)
Currently we query only the underlying host's memory usage for ourmemory resource monitor. This PR changes that to check if the workspaceis in a container, and if so it queries the container's memory usage,falling back to the host's memory usage if not.
1 parent674f60f commit765e705

File tree

4 files changed

+156
-8
lines changed

4 files changed

+156
-8
lines changed

‎agent/agent.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,10 @@ func (a *agent) run() (retErr error) {
965965
iferr!=nil {
966966
returnxerrors.Errorf("failed to create resources fetcher: %w",err)
967967
}
968-
resourcesFetcher:=resourcesmonitor.NewFetcher(statfetcher)
968+
resourcesFetcher,err:=resourcesmonitor.NewFetcher(statfetcher)
969+
iferr!=nil {
970+
returnxerrors.Errorf("new resource fetcher: %w",err)
971+
}
969972

970973
resourcesmonitor:=resourcesmonitor.NewResourcesMonitor(logger,clk,config,resourcesFetcher,aAPI)
971974
returnresourcesmonitor.Start(ctx)

‎agent/proto/resourcesmonitor/fetcher.go

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,58 @@ import (
66
"github.com/coder/coder/v2/cli/clistat"
77
)
88

9+
typeStatterinterface {
10+
IsContainerized() (bool,error)
11+
ContainerMemory(p clistat.Prefix) (*clistat.Result,error)
12+
HostMemory(p clistat.Prefix) (*clistat.Result,error)
13+
Disk(p clistat.Prefix,pathstring) (*clistat.Result,error)
14+
}
15+
916
typeFetcherinterface {
1017
FetchMemory() (totalint64,usedint64,errerror)
1118
FetchVolume(volumestring) (totalint64,usedint64,errerror)
1219
}
1320

1421
typefetcherstruct {
15-
*clistat.Statter
22+
Statter
23+
isContainerizedbool
1624
}
1725

1826
//nolint:revive
19-
funcNewFetcher(f*clistat.Statter)*fetcher {
20-
return&fetcher{
21-
f,
27+
funcNewFetcher(fStatter) (*fetcher,error) {
28+
isContainerized,err:=f.IsContainerized()
29+
iferr!=nil {
30+
returnnil,xerrors.Errorf("check is containerized: %w",err)
2231
}
32+
33+
return&fetcher{f,isContainerized},nil
2334
}
2435

2536
func (f*fetcher)FetchMemory() (totalint64,usedint64,errerror) {
26-
mem,err:=f.HostMemory(clistat.PrefixDefault)
27-
iferr!=nil {
28-
return0,0,xerrors.Errorf("failed to fetch memory: %w",err)
37+
varmem*clistat.Result
38+
39+
iff.isContainerized {
40+
mem,err=f.ContainerMemory(clistat.PrefixDefault)
41+
iferr!=nil {
42+
return0,0,xerrors.Errorf("fetch container memory: %w",err)
43+
}
44+
45+
// A container might not have a memory limit set. If this
46+
// happens we want to fallback to querying the host's memory
47+
// to know what the total memory is on the host.
48+
ifmem.Total==nil {
49+
hostMem,err:=f.HostMemory(clistat.PrefixDefault)
50+
iferr!=nil {
51+
return0,0,xerrors.Errorf("fetch host memory: %w",err)
52+
}
53+
54+
mem.Total=hostMem.Total
55+
}
56+
}else {
57+
mem,err=f.HostMemory(clistat.PrefixDefault)
58+
iferr!=nil {
59+
return0,0,xerrors.Errorf("fetch host memory: %w",err)
60+
}
2961
}
3062

3163
ifmem.Total==nil {
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package resourcesmonitor_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
"golang.org/x/xerrors"
8+
9+
"github.com/coder/coder/v2/agent/proto/resourcesmonitor"
10+
"github.com/coder/coder/v2/cli/clistat"
11+
"github.com/coder/coder/v2/coderd/util/ptr"
12+
)
13+
14+
typemockStatterstruct {
15+
isContainerizedbool
16+
containerMemory clistat.Result
17+
hostMemory clistat.Result
18+
diskmap[string]clistat.Result
19+
}
20+
21+
func (s*mockStatter)IsContainerized() (bool,error) {
22+
returns.isContainerized,nil
23+
}
24+
25+
func (s*mockStatter)ContainerMemory(_ clistat.Prefix) (*clistat.Result,error) {
26+
return&s.containerMemory,nil
27+
}
28+
29+
func (s*mockStatter)HostMemory(_ clistat.Prefix) (*clistat.Result,error) {
30+
return&s.hostMemory,nil
31+
}
32+
33+
func (s*mockStatter)Disk(_ clistat.Prefix,pathstring) (*clistat.Result,error) {
34+
disk,ok:=s.disk[path]
35+
if!ok {
36+
returnnil,xerrors.New("path not found")
37+
}
38+
return&disk,nil
39+
}
40+
41+
funcTestFetchMemory(t*testing.T) {
42+
t.Parallel()
43+
44+
t.Run("IsContainerized",func(t*testing.T) {
45+
t.Parallel()
46+
47+
t.Run("WithMemoryLimit",func(t*testing.T) {
48+
t.Parallel()
49+
50+
fetcher,err:=resourcesmonitor.NewFetcher(&mockStatter{
51+
isContainerized:true,
52+
containerMemory: clistat.Result{
53+
Used:10.0,
54+
Total:ptr.Ref(20.0),
55+
},
56+
hostMemory: clistat.Result{
57+
Used:20.0,
58+
Total:ptr.Ref(30.0),
59+
},
60+
})
61+
require.NoError(t,err)
62+
63+
total,used,err:=fetcher.FetchMemory()
64+
require.NoError(t,err)
65+
require.Equal(t,int64(10),used)
66+
require.Equal(t,int64(20),total)
67+
})
68+
69+
t.Run("WithoutMemoryLimit",func(t*testing.T) {
70+
t.Parallel()
71+
72+
fetcher,err:=resourcesmonitor.NewFetcher(&mockStatter{
73+
isContainerized:true,
74+
containerMemory: clistat.Result{
75+
Used:10.0,
76+
Total:nil,
77+
},
78+
hostMemory: clistat.Result{
79+
Used:20.0,
80+
Total:ptr.Ref(30.0),
81+
},
82+
})
83+
require.NoError(t,err)
84+
85+
total,used,err:=fetcher.FetchMemory()
86+
require.NoError(t,err)
87+
require.Equal(t,int64(10),used)
88+
require.Equal(t,int64(30),total)
89+
})
90+
})
91+
92+
t.Run("IsHost",func(t*testing.T) {
93+
t.Parallel()
94+
95+
fetcher,err:=resourcesmonitor.NewFetcher(&mockStatter{
96+
isContainerized:false,
97+
hostMemory: clistat.Result{
98+
Used:20.0,
99+
Total:ptr.Ref(30.0),
100+
},
101+
})
102+
require.NoError(t,err)
103+
104+
total,used,err:=fetcher.FetchMemory()
105+
require.NoError(t,err)
106+
require.Equal(t,int64(20),used)
107+
require.Equal(t,int64(30),total)
108+
})
109+
}

‎cli/clistat/container.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ const (
1616
kubernetesDefaultServiceAccountToken="/var/run/secrets/kubernetes.io/serviceaccount/token"//nolint:gosec
1717
)
1818

19+
func (s*Statter)IsContainerized() (okbool,errerror) {
20+
returnIsContainerized(s.fs)
21+
}
22+
1923
// IsContainerized returns whether the host is containerized.
2024
// This is adapted from https://github.com/elastic/go-sysinfo/tree/main/providers/linux/container.go#L31
2125
// with modifications to support Sysbox containers.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp