Skip to content

Commit 283c78a

Browse files
erthalionMolter73
andauthored
Replace container-stats with golang client (#2188)
Use CRI/Docker API clients to get container stats information, instead of spinnig up a new container (which can fail to mount docker socket and thus provide no information). Co-authored-by: Mauro Ezequiel Moltrasio <[email protected]>
1 parent 97ca5f6 commit 283c78a

19 files changed

+132
-83
lines changed

integration-tests/go.mod

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,19 @@ toolchain go1.23.6
77
require (
88
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
99
github.com/docker/cli v26.1.3+incompatible
10-
github.com/docker/docker v26.1.3+incompatible
10+
github.com/docker/docker v28.2.2+incompatible
1111
github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b
1212
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
1313
github.com/hashicorp/go-multierror v1.1.1
1414
github.com/pkg/errors v0.9.1
15+
github.com/prometheus/common v0.55.0
1516
github.com/stackrox/rox v0.0.0-20210914215712-9ac265932e28
1617
github.com/stretchr/testify v1.9.0
1718
github.com/thoas/go-funk v0.9.3
1819
go.opentelemetry.io/otel/trace v1.28.0
1920
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
2021
golang.org/x/sys v0.26.0
21-
google.golang.org/grpc v1.65.0
22+
google.golang.org/grpc v1.67.0
2223
gopkg.in/yaml.v3 v3.0.1
2324
k8s.io/api v0.32.2
2425
k8s.io/apimachinery v0.32.2
@@ -34,6 +35,8 @@ require (
3435
github.com/blang/semver/v4 v4.0.0 // indirect
3536
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
3637
github.com/cespare/xxhash/v2 v2.3.0 // indirect
38+
github.com/containerd/errdefs v1.0.0 // indirect
39+
github.com/containerd/errdefs/pkg v0.3.0 // indirect
3740
github.com/distribution/reference v0.6.0 // indirect
3841
github.com/docker/docker-credential-helpers v0.8.1 // indirect
3942
github.com/docker/go-connections v0.5.0 // indirect
@@ -71,18 +74,18 @@ require (
7174
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
7275
github.com/moby/docker-image-spec v1.3.1 // indirect
7376
github.com/moby/spdystream v0.5.0 // indirect
77+
github.com/moby/sys/atomicwriter v0.1.0 // indirect
7478
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
7579
github.com/modern-go/reflect2 v1.0.2 // indirect
7680
github.com/morikuni/aec v1.0.0 // indirect
7781
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
7882
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
7983
github.com/opencontainers/go-digest v1.0.0 // indirect
8084
github.com/opencontainers/image-spec v1.1.0 // indirect
81-
github.com/planetscale/vtprotobuf v0.6.0 // indirect
85+
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
8286
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
8387
github.com/prometheus/client_golang v1.19.1 // indirect
8488
github.com/prometheus/client_model v0.6.1 // indirect
85-
github.com/prometheus/common v0.55.0 // indirect
8689
github.com/prometheus/procfs v0.15.1 // indirect
8790
github.com/sirupsen/logrus v1.9.3 // indirect
8891
github.com/spf13/cobra v1.8.1 // indirect
@@ -107,7 +110,7 @@ require (
107110
golang.org/x/text v0.19.0 // indirect
108111
golang.org/x/time v0.7.0 // indirect
109112
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 // indirect
110-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect
113+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
111114
google.golang.org/protobuf v1.35.1 // indirect
112115
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
113116
gopkg.in/inf.v0 v0.9.1 // indirect

integration-tests/go.sum

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3
1515
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
1616
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
1717
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
18+
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
19+
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
20+
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
21+
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
1822
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
1923
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
2024
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@@ -26,8 +30,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
2630
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
2731
github.com/docker/cli v26.1.3+incompatible h1:bUpXT/N0kDE3VUHI2r5VMsYQgi38kYuoC0oL9yt3lqc=
2832
github.com/docker/cli v26.1.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
29-
github.com/docker/docker v26.1.3+incompatible h1:lLCzRbrVZrljpVNobJu1J2FHk8V0s4BawoZippkc+xo=
30-
github.com/docker/docker v26.1.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
33+
github.com/docker/docker v28.2.2+incompatible h1:CjwRSksz8Yo4+RmQ339Dp/D2tGO5JxwYeqtMOEe0LDw=
34+
github.com/docker/docker v28.2.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
3135
github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo=
3236
github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
3337
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
@@ -126,6 +130,10 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N
126130
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
127131
github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
128132
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
133+
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
134+
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
135+
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
136+
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
129137
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
130138
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
131139
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -151,8 +159,8 @@ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYr
151159
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
152160
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
153161
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
154-
github.com/planetscale/vtprotobuf v0.6.0 h1:nBeETjudeJ5ZgBHUz1fVHvbqUKnYOXNhsIEabROxmNA=
155-
github.com/planetscale/vtprotobuf v0.6.0/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
162+
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
163+
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
156164
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
157165
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
158166
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -286,10 +294,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
286294
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
287295
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw=
288296
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
289-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs=
290-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
291-
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
292-
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
297+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
298+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
299+
google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
300+
google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
293301
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
294302
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
295303
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

integration-tests/pkg/executor/executor.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package executor
22

33
import (
4+
"context"
45
"os/exec"
6+
"time"
57

68
"github.com/stackrox/collector/integration-tests/pkg/config"
79
)
@@ -16,6 +18,14 @@ type ContainerLogs struct {
1618
Stderr string
1719
}
1820

21+
type ContainerStat struct {
22+
Timestamp time.Time
23+
Id string
24+
Name string
25+
Mem uint64
26+
Cpu uint64
27+
}
28+
1929
func (c *ContainerLogs) Empty() bool {
2030
return *c == (ContainerLogs{})
2131
}
@@ -47,6 +57,7 @@ type Executor interface {
4757
StopContainer(name string) (string, error)
4858
StartContainer(config config.ContainerStartConfig) (string, error)
4959
GetContainerHealthCheck(containerID string) (string, error)
60+
GetContainerStats(ctx context.Context, containerID string) (*ContainerStat, error)
5061
GetContainerIP(containerID string) (string, error)
5162
GetContainerLogs(containerID string) (ContainerLogs, error)
5263
CaptureLogs(testName, containerName string) (string, error)

integration-tests/pkg/executor/executor_cri.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,23 @@ func (c *criExecutor) GetContainerHealthCheck(containerID string) (string, error
289289
return "", fmt.Errorf("Unsupported")
290290
}
291291

292+
func (c *criExecutor) GetContainerStats(ctx context.Context, containerID string) (
293+
*ContainerStat, error) {
294+
295+
stats, err := c.runtimeService.ContainerStats(ctx, containerID)
296+
if err != nil {
297+
return nil, err
298+
}
299+
300+
return &ContainerStat{
301+
Timestamp: time.Unix(stats.Memory.Timestamp, 0),
302+
Id: stats.Attributes.Id,
303+
Name: stats.Attributes.Metadata.Name,
304+
Mem: stats.Memory.UsageBytes.GetValue(),
305+
Cpu: stats.Cpu.UsageCoreNanoSeconds.GetValue(),
306+
}, nil
307+
}
308+
292309
func (c *criExecutor) GetContainerIP(name string) (string, error) {
293310
container, err := c.getContainer(name)
294311
if err != nil {

integration-tests/pkg/executor/executor_docker_api.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package executor
33
import (
44
"bytes"
55
"context"
6+
"encoding/json"
67
"fmt"
78
"io"
89
"strings"
@@ -91,6 +92,34 @@ func (d *dockerAPIExecutor) GetContainerHealthCheck(containerID string) (string,
9192
return strings.Join(inspectResp.Config.Healthcheck.Test, " "), nil
9293
}
9394

95+
func (d *dockerAPIExecutor) GetContainerStats(ctx context.Context, containerID string) (
96+
*ContainerStat, error) {
97+
98+
// ContainerStatsOneShot add "one-shot" parameter to the API query, which
99+
// instructs the server to get a single stat, rather than waiting for more.
100+
statsResp, err := d.client.ContainerStatsOneShot(ctx, containerID)
101+
if err != nil {
102+
return nil, err
103+
}
104+
105+
var stats container.StatsResponse
106+
decoder := json.NewDecoder(statsResp.Body)
107+
108+
if err := decoder.Decode(&stats); err == io.EOF {
109+
return nil, nil
110+
} else if err != nil {
111+
return nil, err
112+
}
113+
114+
return &ContainerStat{
115+
Timestamp: stats.Read,
116+
Id: stats.ID,
117+
Name: stats.Name,
118+
Mem: stats.MemoryStats.Usage,
119+
Cpu: stats.CPUStats.CPUUsage.TotalUsage,
120+
}, nil
121+
}
122+
94123
func (d *dockerAPIExecutor) StartContainer(startConfig config.ContainerStartConfig) (string, error) {
95124
ctx := context.Background()
96125
var binds []string
@@ -159,7 +188,7 @@ func (d *dockerAPIExecutor) StartContainer(startConfig config.ContainerStartConf
159188

160189
func (d *dockerAPIExecutor) ExecContainer(opts *ExecOptions) (string, error) {
161190
ctx := context.Background()
162-
execConfig := types.ExecConfig{
191+
execConfig := container.ExecOptions{
163192
AttachStdout: true,
164193
AttachStderr: true,
165194
Cmd: opts.Command,
@@ -170,7 +199,7 @@ func (d *dockerAPIExecutor) ExecContainer(opts *ExecOptions) (string, error) {
170199
return "", fmt.Errorf("error creating Exec: %w", err)
171200
}
172201

173-
execStartCheck := types.ExecStartCheck{Detach: false, Tty: false}
202+
execStartCheck := container.ExecAttachOptions{Detach: false, Tty: false}
174203
attachResp, err := d.client.ContainerExecAttach(ctx, resp.ID, execStartCheck)
175204
if err != nil {
176205
return "", fmt.Errorf("error attaching to Exec: %w", err)

integration-tests/suites/async_connections.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ type AsyncConnectionTestSuite struct {
3333
*/
3434
func (s *AsyncConnectionTestSuite) SetupSuite() {
3535
s.RegisterCleanup("server", "client")
36-
s.StartContainerStats()
3736

3837
collectorOptions := collector.StartupOptions{
3938
Env: map[string]string{

0 commit comments

Comments
 (0)