Skip to content

Commit 27747ca

Browse files
L3n41cclaude
andcommitted
[CONTINT-5217][CONTINT-5218][CONTINT-5219][CONTINT-5220] Upgrade Docker SDK from docker/docker v28 to moby/moby v29
Migrate from github.com/docker/docker v28.5.2+incompatible to github.com/moby/moby/api v1.54.1 and github.com/moby/moby/client v0.4.0 to fix CVE-2026-34040 (High, CVSS 7.8) and CVE-2026-33997 (Medium, CVSS 8.1). This is a major SDK migration: Docker Engine v29 restructured its Go modules into separate sub-modules (moby/moby/api for types, moby/moby/client for the client) with a new Options/Result pattern for all API methods. Key changes: - Update all 55 files importing from github.com/docker/docker - Adapt to v29 Options/Result method signatures in DockerUtil wrapper - Migrate filters from api/types/filters to client.Filters - Handle removed types: ContainerJSONBase (flattened into InspectResponse), image.Summary.VirtualSize, image.InspectResponse.DockerVersion/ContainerConfig - Handle type changes: IPAddress (string -> netip.Addr), Port (nat.Port -> network.Port), ContainerState (string -> typed) - Replace libnetwork/resolvconf with inline implementation (removed in v29) - Update ContainerExec* -> Exec* method names in e2e framework Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 61fdef4 commit 27747ca

57 files changed

Lines changed: 353 additions & 370 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

comp/core/workloadfilter/util/docker/create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
package docker
1010

1111
import (
12-
"github.com/docker/docker/api/types/container"
12+
"github.com/moby/moby/api/types/container"
1313

1414
workloadfilter "github.com/DataDog/datadog-agent/comp/core/workloadfilter/def"
1515
"github.com/DataDog/datadog-agent/pkg/proto/pbgo/core"

comp/core/workloadmeta/collectors/internal/docker/docker.go

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ import (
1818
"sync"
1919
"time"
2020

21-
"github.com/docker/docker/api/types/container"
22-
"github.com/docker/docker/api/types/events"
23-
"github.com/docker/docker/api/types/image"
24-
"github.com/docker/docker/api/types/network"
25-
"github.com/docker/go-connections/nat"
21+
"github.com/moby/moby/api/types/container"
22+
"github.com/moby/moby/api/types/events"
23+
"github.com/moby/moby/api/types/image"
24+
"github.com/moby/moby/api/types/network"
25+
dockerclient "github.com/moby/moby/client"
2626
v1 "github.com/opencontainers/image-spec/specs-go/v1"
2727
"go.uber.org/fx"
2828

@@ -199,7 +199,7 @@ func (c *collector) generateEventsFromContainerList(ctx context.Context, filter
199199
return errors.New("Start was not called")
200200
}
201201

202-
containers, err := c.dockerUtil.RawContainerListWithFilter(ctx, container.ListOptions{}, filter, c.store)
202+
containers, err := c.dockerUtil.RawContainerListWithFilter(ctx, dockerclient.ContainerListOptions{}, filter, c.store)
203203
if err != nil {
204204
return err
205205
}
@@ -459,35 +459,32 @@ func extractPorts(container container.InspectResponse) []workloadmeta.ContainerP
459459
return ports
460460
}
461461

462-
func extractPort(port nat.Port) []workloadmeta.ContainerPort {
462+
func extractPort(port network.Port) []workloadmeta.ContainerPort {
463463
var output []workloadmeta.ContainerPort
464464

465-
// Try to parse a port range, eg. 22-25
466-
first, last, err := port.Range()
467-
if err != nil {
468-
log.Debugf("cannot get port range from nat.Port: %s", err)
469-
return output
470-
}
465+
pr := port.Range()
466+
first := int(pr.Start())
467+
last := int(pr.End())
471468

472469
if last > first {
473470
output = make([]workloadmeta.ContainerPort, 0, last-first+1)
474471
for p := first; p <= last; p++ {
475472
output = append(output, workloadmeta.ContainerPort{
476473
Port: p,
477-
Protocol: port.Proto(),
474+
Protocol: string(port.Proto()),
478475
})
479476
}
480477

481478
return output
482479
}
483480

484-
// Try to parse a single port (most common case)
485-
p := port.Int()
481+
// Single port (most common case)
482+
p := int(port.Num())
486483
if p > 0 {
487484
output = []workloadmeta.ContainerPort{
488485
{
489486
Port: p,
490-
Protocol: port.Proto(),
487+
Protocol: string(port.Proto()),
491488
},
492489
}
493490
}
@@ -499,8 +496,8 @@ func extractNetworkIPs(networks map[string]*network.EndpointSettings) map[string
499496
networkIPs := make(map[string]string)
500497

501498
for net, settings := range networks {
502-
if len(settings.IPAddress) > 0 {
503-
networkIPs[net] = settings.IPAddress
499+
if settings.IPAddress.IsValid() {
500+
networkIPs[net] = settings.IPAddress.String()
504501
}
505502
}
506503

comp/core/workloadmeta/collectors/internal/docker/docker_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"testing"
1212
"time"
1313

14-
"github.com/docker/docker/api/types/image"
14+
"github.com/moby/moby/api/types/image"
1515
v1 "github.com/opencontainers/image-spec/specs-go/v1"
1616
"github.com/stretchr/testify/assert"
1717

go.mod

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ require (
216216
github.com/cyphar/filepath-securejoin v0.6.0
217217
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
218218
github.com/distribution/reference v0.6.0
219-
github.com/docker/docker v28.5.2+incompatible
220-
github.com/docker/go-connections v0.6.0
219+
github.com/docker/docker v28.5.2+incompatible // indirect
220+
github.com/docker/go-connections v0.6.0 // indirect
221221
github.com/dustin/go-humanize v1.0.1
222222
github.com/elastic/go-libaudit/v2 v2.6.2
223223
github.com/elastic/go-seccomp-bpf v1.6.0
@@ -685,7 +685,6 @@ require (
685685
github.com/moby/docker-image-spec v1.3.1
686686
github.com/moby/locker v1.0.1 // indirect
687687
github.com/moby/spdystream v0.5.0 // indirect
688-
github.com/moby/sys/atomicwriter v0.1.0 // indirect
689688
github.com/moby/sys/sequential v0.6.0 // indirect
690689
github.com/moby/sys/signal v0.7.1 // indirect
691690
github.com/moby/sys/user v0.4.0 // indirect
@@ -993,6 +992,8 @@ require (
993992
github.com/hashicorp/vault/api/auth/userpass v0.11.0
994993
github.com/jarcoal/httpmock v1.4.1
995994
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c
995+
github.com/moby/moby/api v1.54.1
996+
github.com/moby/moby/client v0.4.0
996997
github.com/modelcontextprotocol/go-sdk v1.4.1
997998
github.com/qri-io/jsonpointer v0.1.1
998999
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
@@ -1161,8 +1162,6 @@ require (
11611162
github.com/lestrrat-go/option v1.0.1 // indirect
11621163
github.com/mattn/go-zglob v0.0.2-0.20191112051448-a8912a37f9e7 // indirect
11631164
github.com/mitchellh/pointerstructure v1.2.1 // indirect
1164-
github.com/moby/moby/api v1.52.0 // indirect
1165-
github.com/moby/moby/client v0.2.1 // indirect
11661165
github.com/montanaflynn/stats v0.7.1 // indirect
11671166
github.com/nexus-rpc/sdk-go v0.5.1 // indirect
11681167
github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 // indirect

go.sum

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/collector/corechecks/containers/docker/check.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import (
1616
"strings"
1717
"time"
1818

19-
"github.com/docker/docker/api/types/container"
19+
"github.com/moby/moby/api/types/container"
20+
dockerclient "github.com/moby/moby/client"
2021

2122
"github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration"
2223
tagger "github.com/DataDog/datadog-agent/comp/core/tagger/def"
@@ -171,7 +172,7 @@ func (d *DockerCheck) Run() error {
171172
d.collectContainerSizeCounter = (d.collectContainerSizeCounter + 1) % d.instance.CollectContainerSizeFreq
172173
}
173174

174-
rawContainerList, err := du.RawContainerList(context.TODO(), container.ListOptions{All: true, Size: collectContainerSize})
175+
rawContainerList, err := du.RawContainerList(context.TODO(), dockerclient.ContainerListOptions{All: true, Size: collectContainerSize})
175176
if err != nil {
176177
sender.ServiceCheck(DockerServiceUp, servicecheck.ServiceCheckCritical, "", nil, err.Error())
177178
_ = d.Warnf("Error collecting containers: %s", err)
@@ -207,7 +208,7 @@ func (d *DockerCheck) runDockerCustom(sender sender.Sender, du docker.Client, ra
207208
}
208209

209210
for _, rawContainer := range rawContainerList {
210-
if rawContainer.State == string(workloadmeta.ContainerStatusRunning) {
211+
if string(rawContainer.State) == string(workloadmeta.ContainerStatusRunning) {
211212
containersRunning++
212213
} else {
213214
containersStopped++
@@ -238,7 +239,7 @@ func (d *DockerCheck) runDockerCustom(sender sender.Sender, du docker.Client, ra
238239
}
239240

240241
isContainerExcluded := d.containerFilter.IsExcluded(filterableContainer)
241-
isContainerRunning := rawContainer.State == string(workloadmeta.ContainerStatusRunning)
242+
isContainerRunning := string(rawContainer.State) == string(workloadmeta.ContainerStatusRunning)
242243
taggerEntityID := types.NewEntityID(types.ContainerID, rawContainer.ID)
243244
tags, err := d.getImageTagsFromContainer(taggerEntityID, resolvedImageName, isContainerExcluded || !isContainerRunning)
244245
if err != nil {
@@ -337,8 +338,7 @@ func (d *DockerCheck) collectImageMetrics(sender sender.Sender, du docker.Client
337338
continue
338339
}
339340

340-
//nolint:staticcheck // TODO(CINT) Fix staticcheck linter
341-
sender.Gauge("docker.image.virtual_size", float64(image.VirtualSize), "", imageTags)
341+
sender.Gauge("docker.image.virtual_size", float64(image.Size), "", imageTags)
342342
sender.Gauge("docker.image.size", float64(image.Size), "", imageTags)
343343
}
344344
}

pkg/collector/corechecks/containers/docker/check_linux_test.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
package docker
99

1010
import (
11+
"net/netip"
1112
"testing"
1213

13-
"github.com/docker/docker/api/types/container"
14-
dockerNetworkTypes "github.com/docker/docker/api/types/network"
14+
"github.com/moby/moby/api/types/container"
15+
dockerNetworkTypes "github.com/moby/moby/api/types/network"
1516

1617
nooptagger "github.com/DataDog/datadog-agent/comp/core/tagger/impl-noop"
1718
workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def"
@@ -138,7 +139,7 @@ func TestDockerNetworkExtension(t *testing.T) {
138139
})
139140
container1RawDocker := container.Summary{
140141
ID: "kube-host-network",
141-
State: string(workloadmeta.ContainerStatusRunning),
142+
State: container.ContainerState(workloadmeta.ContainerStatusRunning),
142143
HostConfig: struct {
143144
NetworkMode string `json:",omitempty"`
144145
Annotations map[string]string `json:",omitempty"`
@@ -169,7 +170,7 @@ func TestDockerNetworkExtension(t *testing.T) {
169170
})
170171
container2RawDocker := container.Summary{
171172
ID: "kube-app",
172-
State: string(workloadmeta.ContainerStatusRunning),
173+
State: container.ContainerState(workloadmeta.ContainerStatusRunning),
173174
HostConfig: struct {
174175
NetworkMode string `json:",omitempty"`
175176
Annotations map[string]string `json:",omitempty"`
@@ -182,7 +183,7 @@ func TestDockerNetworkExtension(t *testing.T) {
182183
// Container3 is only raw as it's excluded (pause container)
183184
container3RawDocker := container.Summary{
184185
ID: "kube-app-pause",
185-
State: string(workloadmeta.ContainerStatusRunning),
186+
State: container.ContainerState(workloadmeta.ContainerStatusRunning),
186187
HostConfig: struct {
187188
NetworkMode string `json:",omitempty"`
188189
Annotations map[string]string `json:",omitempty"`
@@ -219,18 +220,18 @@ func TestDockerNetworkExtension(t *testing.T) {
219220
})
220221
container4RawDocker := container.Summary{
221222
ID: "docker-app",
222-
State: string(workloadmeta.ContainerStatusRunning),
223+
State: container.ContainerState(workloadmeta.ContainerStatusRunning),
223224
HostConfig: struct {
224225
NetworkMode string `json:",omitempty"`
225226
Annotations map[string]string `json:",omitempty"`
226227
}{NetworkMode: "ubuntu_default"},
227228
NetworkSettings: &container.NetworkSettingsSummary{
228229
Networks: map[string]*dockerNetworkTypes.EndpointSettings{
229230
"ubuntu_default": {
230-
IPAddress: "172.18.0.2",
231+
IPAddress: netip.MustParseAddr("172.18.0.2"),
231232
},
232233
"bridge": {
233-
IPAddress: "172.17.0.2",
234+
IPAddress: netip.MustParseAddr("172.17.0.2"),
234235
},
235236
},
236237
},
@@ -293,7 +294,7 @@ func TestNetworkCustomOnFailure(t *testing.T) {
293294
Labels: map[string]string{
294295
"io.kubernetes.pod.namespace": "kubens",
295296
},
296-
State: string(workloadmeta.ContainerStatusRunning),
297+
State: container.ContainerState(workloadmeta.ContainerStatusRunning),
297298
SizeRw: 100,
298299
SizeRootFs: 200,
299300
})

pkg/collector/corechecks/containers/docker/check_network.go

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
"strings"
1515
"time"
1616

17-
"github.com/docker/docker/api/types/container"
17+
"github.com/moby/moby/api/types/container"
1818

1919
tagger "github.com/DataDog/datadog-agent/comp/core/tagger/def"
2020
taggerUtils "github.com/DataDog/datadog-agent/comp/core/tagger/utils"
@@ -126,7 +126,7 @@ func (dn *dockerNetworkExtension) processContainer(rawContainer container.Summar
126126
// We keep excluded containers because pause containers are required as they usually hold
127127
// the network configuration for other containers.
128128
// However stopped containers are not useful there.
129-
if rawContainer.State != string(workloadmeta.ContainerStatusRunning) {
129+
if string(rawContainer.State) != string(workloadmeta.ContainerStatusRunning) {
130130
return
131131
}
132132

@@ -227,22 +227,12 @@ func findDockerNetworks(procPath string, entry *containerNetworkEntry, container
227227
return
228228
}
229229

230-
ipString := netConf.IPAddress
231-
// Check if this is a CIDR or just an IP
232-
var ip net.IP
233-
if strings.Contains(ipString, "/") {
234-
ip, _, err = net.ParseCIDR(ipString)
235-
if err != nil {
236-
log.Warnf("Malformed IP %s for container id %s: %s, skipping", ipString, entry.containerID, err)
237-
continue
238-
}
239-
} else {
240-
ip = net.ParseIP(ipString)
241-
if ip == nil {
242-
log.Warnf("Malformed IP %s for container id %s: %s, skipping", ipString, entry.containerID, err)
243-
continue
244-
}
230+
addr := netConf.IPAddress
231+
if !addr.IsValid() {
232+
log.Warnf("Invalid IP for container id %s in network %s, skipping", entry.containerID, netName)
233+
continue
245234
}
235+
ip := net.IP(addr.AsSlice())
246236

247237
// Convert IP to little endian uint64 for comparison to network routes.
248238
interfaces[netName] = uint64(binary.LittleEndian.Uint32(ip.To4()))

0 commit comments

Comments
 (0)