Skip to content

[CONS-8441] docker: tolerate port ranges in container ExposedPorts#54108

Draft
zhuminyi wants to merge 11 commits into
mainfrom
minyi/cons-8441-docker-port-range
Draft

[CONS-8441] docker: tolerate port ranges in container ExposedPorts#54108
zhuminyi wants to merge 11 commits into
mainfrom
minyi/cons-8441-docker-port-range

Conversation

@zhuminyi

@zhuminyi zhuminyi commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Stops the Docker collector from dropping a container whose image declares a port range in Config.ExposedPorts (e.g. 1061-1070).

DockerUtil.InspectNoCache gains a fallback: when an inspect fails on a port key the moby decoder rejects, it refetches the inspect payload as raw JSON, expands range keys into individual ports, and re-decodes. The success path is unchanged.

The fallback is deliberately conservative — it gives up and returns the original error unless all of these hold:

  • the error text looks like a rejected port key (cheap pre-filter only; correctness does not depend on it)
  • the refetched payload really did contain a fixable key (changed)
  • the sanitized payload re-decodes
  • the result is the container that was requested (callers may pass a name or short ID, and a container can be replaced between the two calls)

Ranges wider than 1024 ports are dropped rather than expanded, so a pathological EXPOSE 1-65535 can't push 65k ports into workloadmeta.

Motivation

Customer escalation CONS-8441. A third-party image (BMC Helix swp-mediator) has a port range baked into its image metadata. Docker daemons ≤ v25 return it verbatim; v29 normalizes it into individual ports. moby v29's network.Port is a struct with a strict UnmarshalText, so the range key fails — and because it's a JSON map key, the entire ContainerInspect decode aborts:

could not inspect container "85dfebd7…": invalid port '1061-1070': invalid syntax

The collector therefore skips the container completely: no metrics, no metadata, no autodiscovery. The customer can't change the vendor image, so their only workaround is upgrading Docker.

Scope note: only Config.ExposedPorts is sanitized. HostConfig.PortBindings and NetworkSettings.Ports use the same strict key type, but daemons rebuild those from numeric values, so a literal range isn't expected there. A range in those fields would behave exactly as it does today (original error, container skipped) — no regression.

Describe how you validated your changes

Automated. 10 tests in pkg/util/docker/inspect_ports_test.go, covering: the raw payload is rejected by moby (the bug), the range expands, individual ports are a no-op, malformed and over-wide keys are dropped, a genuine daemon failure surfaces the original error, a mismatched container is rejected, and a healthy payload never enters the fallback. Two drive a real moby client against an httptest daemon, so the actual decode path is exercised.

The docker build tag is in DARWIN_EXCLUDED_TAGS, so dda inv test silently runs 0 tests on macOS. Run them on Linux:

dda inv test --targets=./pkg/util/docker          # on Linux

Or, from macOS, in a container (GOWORK=off is required — the repo uses Go workspace mode):

docker run --rm -v "$PWD":/src -v "$(go env GOMODCACHE)":/go/pkg/mod -w /src \
  -e GOWORK=off -e GOTOOLCHAIN=local -e CGO_ENABLED=0 golang:1.26 \
  go test -tags docker -count=1 ./pkg/util/docker/

Manual, against a real old daemon. Reproduced and confirmed fixed on Docker v25.0.5. Note a fresh EXPOSE 1061-1070 will not reproduce it — v25 expands that at build time; the range has to be baked into the image metadata, so use an image that already carries one:

docker run -d --privileged --name dind25 -e DOCKER_TLS_CERTDIR="" \
  docker:25-dind --host=tcp://0.0.0.0:2375
docker exec dind25 docker pull container-registry.oracle.com/mysql/community-cluster:8.4
docker exec dind25 docker create --name mc container-registry.oracle.com/mysql/community-cluster:8.4
docker exec dind25 docker inspect mc --format '{{json .Config.ExposedPorts}}'
# {"1186/tcp":{},"2202/tcp":{},"3306/tcp":{},"33060-33061/tcp":{}}   <-- the range survives

Pointing an agent build at that daemon (DOCKER_HOST=tcp://dind25:2375): before, ContainerInspect fails with invalid port '33060-33061': invalid syntax; after, the container is inspected normally with 33060/tcp and 33061/tcp expanded.

Also: go vet -tags docker, gofmt, and a -race run are clean, and the workloadmeta docker collector builds.

Additional Notes

  • Image inspection is unaffected: ImageInspect decodes into dockerspec.DockerOCIImageConfig, whose ExposedPorts is a plain-string map. ContainerList is unaffected too (PortSummary uses numeric fields).
  • Upstream considers ranges in ExposedPorts unsupported and expects clients to expand them (moby/moby#51537), so this won't be fixed by an SDK bump. The raw refetch is needed because moby discards the raw bytes when its decode fails.
  • Follow-up (not in this PR): pkg/compliance/resolver.go calls ContainerInspect directly and returns on the first error, so one such container aborts the whole compliance container resolution.

Some container images declare a port range in their exposed ports (e.g.
`EXPOSE 1061-1070`). The range is baked into the image metadata by the
builder; Docker daemons <= v25 return it verbatim in the container inspect
payload, whereas v29 normalizes it into individual ports. moby's strict
network.Port map-key decoder rejects the range key ("invalid port
'1061-1070': invalid syntax"), which aborts the entire ContainerInspect
decode and causes the workloadmeta docker collector to skip the container
completely.

DockerUtil.InspectNoCache now detects that decode failure, refetches the
inspect payload as raw JSON via the moby client's own dialer, expands any
port-range keys into individual ports (dropping truly-malformed keys with a
warning), and decodes the sanitized payload. The happy path is untouched, so
modern daemons are unaffected.

Adds unit tests, a hermetic integration test through the real moby client
against an httptest fake daemon, and an opt-in real-daemon e2e reproduction
(Docker v25 + a ranged image).
@zhuminyi
zhuminyi requested a review from a team as a code owner July 24, 2026 17:05
@github-actions github-actions Bot added the medium review PR review might take time label Jul 24, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0803909448

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkg/util/docker/inspect_ports.go Outdated
@zhuminyi
zhuminyi marked this pull request as draft July 24, 2026 17:16
@datadog-prod-us1-5

datadog-prod-us1-5 Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

🎯 Code Coverage (details)
Patch Coverage: 72.45%
Overall Coverage: 52.08% (-4.36%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 8b40597 | Docs | Datadog PR Page | Give us feedback!

zhuminyi added 3 commits July 24, 2026 13:26
…tighten error match

- sanitizePortObject: store first-pass (moby-accepted) keys under their
  normalized form so an explicit, non-normalized entry (e.g. "80" or "80/TCP"
  with a real binding) is not clobbered by an overlapping expanded range entry.
  Adds a regression test.
- isPortRangeDecodeError: require the single-quote form ("invalid port '") so it
  no longer matches unrelated net/url dial errors on a misconfigured DOCKER_HOST.
- Document that ranged PortBindings values are replicated (best-effort) rather
  than reconstructing Docker's sequential host-port assignment.
Trim the fix to its essentials:
- Replace the recursive variadic-path walker with a flat [outer,inner] loop
  over the three fixed port-map locations.
- Merge the raw-refetch + sanitize + decode into one recoverInspectWithPortRanges
  method; sanitizeInspectPortRanges drops its unused error return.
- Drop the opt-in real-daemon test (never runs in CI; the httptest integration
  test already covers the real moby decode + fallback path end to end).

No behavior change; all unit + integration tests still pass.
Fold the nested-descent helper into the map loop and collapse the two-pass
key rewrite into a single loop (the valid-key branch overwrites, the range
branch fills only missing ports, so explicit entries still win regardless of
map order). No behavior change; inspect_ports.go drops from 237 to 159 lines.
@dd-octo-sts

dd-octo-sts Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Files inventory check summary

File checks results against ancestor c48026b1:

Results for datadog-agent_7.83.0~devel.git.363.8b40597.pipeline.126943571-1_amd64.deb:

No change detected

@dd-octo-sts

dd-octo-sts Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Static quality checks

✅ Please find below the results from static quality gates
Comparison made with ancestor c48026b
📊 Static Quality Gates Dashboard
🔗 SQG Job

Successful checks

Info

Quality gate Change Size (prev → curr → max)
agent_deb_amd64 +22.02 KiB (0.00% increase, -0.31% of buffer) 751.290 → 751.311 → 758.200
agent_deb_amd64_fips +22.02 KiB (0.00% increase, -0.48% of buffer) 706.062 → 706.084 → 710.520
agent_msi +25.5 KiB (0.00% increase, -0.15% of buffer) 639.499 → 639.524 → 656.640
agent_rpm_amd64 +22.02 KiB (0.00% increase, -0.31% of buffer) 751.273 → 751.295 → 758.170
agent_rpm_amd64_fips +22.02 KiB (0.00% increase, -0.48% of buffer) 706.046 → 706.067 → 710.520
agent_rpm_arm64 +20.63 KiB (0.00% increase, -1.16% of buffer) 727.928 → 727.948 → 729.660
agent_rpm_arm64_fips +24.63 KiB (0.00% increase, -0.79% of buffer) 685.851 → 685.875 → 688.910
agent_suse_amd64 +22.02 KiB (0.00% increase, -0.31% of buffer) 751.273 → 751.295 → 758.170
agent_suse_amd64_fips +22.02 KiB (0.00% increase, -0.48% of buffer) 706.046 → 706.067 → 710.520
agent_suse_arm64 +20.63 KiB (0.00% increase, -1.16% of buffer) 727.928 → 727.948 → 729.660
agent_suse_arm64_fips +24.63 KiB (0.00% increase, -0.79% of buffer) 685.851 → 685.875 → 688.910
docker_agent_amd64 +28.62 KiB (0.00% increase, -0.73% of buffer) 809.955 → 809.982 → 813.790
docker_agent_arm64 +27.23 KiB (0.00% increase, -0.79% of buffer) 811.656 → 811.683 → 815.030
docker_agent_jmx_amd64 +28.62 KiB (0.00% increase, -0.76% of buffer) 1000.852 → 1000.880 → 1004.550
docker_agent_jmx_arm64 +27.23 KiB (0.00% increase, -0.76% of buffer) 991.206 → 991.233 → 994.710
docker_dogstatsd_amd64 +12.03 KiB (0.03% increase, -1.76% of buffer) 39.243 → 39.255 → 39.910
docker_host_profiler_amd64 +16.16 KiB (0.01% increase, -0.11% of buffer) 303.876 → 303.892 → 317.640
docker_host_profiler_arm64 +14.28 KiB (0.00% increase, -0.10% of buffer) 315.371 → 315.384 → 328.900
dogstatsd_deb_amd64 +12.03 KiB (0.04% increase, -1.01% of buffer) 29.984 → 29.996 → 31.150
dogstatsd_deb_arm64 +12.03 KiB (0.04% increase, -0.78% of buffer) 28.024 → 28.035 → 29.530
dogstatsd_rpm_amd64 +12.03 KiB (0.04% increase, -1.01% of buffer) 29.984 → 29.996 → 31.150
dogstatsd_suse_amd64 +12.03 KiB (0.04% increase, -1.01% of buffer) 29.984 → 29.996 → 31.150
11 successful checks with minimal change (< 2 KiB)
Quality gate Current Size
agent_heroku_amd64 307.539 MiB
docker_cluster_agent_amd64 209.866 MiB
docker_cluster_agent_arm64 222.953 MiB
docker_cws_instrumentation_amd64 7.439 MiB
docker_cws_instrumentation_arm64 6.877 MiB
docker_dogstatsd_arm64 37.368 MiB
iot_agent_deb_amd64 46.153 MiB
iot_agent_deb_arm64 42.845 MiB
iot_agent_deb_armhf 43.613 MiB
iot_agent_rpm_amd64 46.154 MiB
iot_agent_suse_amd64 46.153 MiB

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Jul 24, 2026

Copy link
Copy Markdown

Regression Detector

Regression Detector Results

Metrics dashboard
Target profiles
Run ID: 834253e6-ebea-425c-9d25-f606acc451f2

Baseline: c48026b
Comparison: 8b40597
Diff

Optimization Goals: ✅ No significant changes detected

Fine details of change detection per experiment

perf experiment goal Δ mean % Δ mean % CI trials links
quality_gate_logs % cpu utilization +4.69 [+3.62, +5.77] 1 Logs bounds checks dashboard
quality_gate_metrics_logs memory utilization +0.44 [+0.19, +0.68] 1 Logs bounds checks dashboard
quality_gate_private_action_runner memory utilization -0.01 [-0.13, +0.11] 1 Logs bounds checks dashboard
quality_gate_idle_all_features memory utilization -0.09 [-0.13, -0.04] 1 Logs bounds checks dashboard
quality_gate_security_idle memory utilization -0.15 [-0.20, -0.09] 1 Logs bounds checks dashboard
quality_gate_security_mean_fs_load memory utilization -0.18 [-0.22, -0.15] 1 Logs bounds checks dashboard
quality_gate_idle memory utilization -0.38 [-0.42, -0.33] 1 Logs bounds checks dashboard
quality_gate_security_no_fs_load memory utilization -0.66 [-0.76, -0.56] 1 Logs bounds checks dashboard

Bounds Checks: ✅ Passed

perf experiment bounds_check_name replicates_passed observed_value links
quality_gate_idle intake_connections 10/10 3 ≤ 4 bounds checks dashboard
quality_gate_idle memory_usage 10/10 149.85MiB ≤ 154MiB bounds checks dashboard
quality_gate_idle total_bytes_received 10/10 735.92KiB ≤ 819.20KiB bounds checks dashboard
quality_gate_idle_all_features intake_connections 10/10 3 ≤ 4 bounds checks dashboard
quality_gate_idle_all_features memory_usage 10/10 501.12MiB ≤ 512MiB bounds checks dashboard
quality_gate_idle_all_features total_bytes_received 10/10 1.12MiB ≤ 1.25MiB bounds checks dashboard
quality_gate_logs intake_connections 10/10 4 ≤ 6 bounds checks dashboard
quality_gate_logs memory_usage 10/10 186.34MiB ≤ 195MiB bounds checks dashboard
quality_gate_logs missed_bytes 10/10 0B = 0B bounds checks dashboard
quality_gate_logs total_bytes_received 10/10 264.27MiB ≤ 292MiB bounds checks dashboard
quality_gate_metrics_logs cpu_usage 10/10 394.57 ≤ 2000 bounds checks dashboard
quality_gate_metrics_logs intake_connections 10/10 3 ≤ 6 bounds checks dashboard
quality_gate_metrics_logs memory_usage 10/10 401.73MiB ≤ 430MiB bounds checks dashboard
quality_gate_metrics_logs missed_bytes 10/10 0B = 0B bounds checks dashboard
quality_gate_metrics_logs total_bytes_received 10/10 0.94GiB ≤ 1.04GiB bounds checks dashboard
quality_gate_private_action_runner memory_usage 10/10 71.22MiB ≤ 75MiB bounds checks dashboard
quality_gate_security_idle cpu_usage 10/10 27.07 ≤ 100 bounds checks dashboard
quality_gate_security_idle memory_usage 10/10 297.30MiB ≤ 330MiB bounds checks dashboard
quality_gate_security_mean_fs_load cpu_usage 10/10 61.96 ≤ 200 bounds checks dashboard
quality_gate_security_mean_fs_load memory_usage 10/10 277.62MiB ≤ 310MiB bounds checks dashboard
quality_gate_security_no_fs_load cpu_usage 10/10 35.01 ≤ 100 bounds checks dashboard
quality_gate_security_no_fs_load memory_usage 10/10 288.48MiB ≤ 320MiB bounds checks dashboard

Explanation

Confidence level: 90.00%
Effect size tolerance: |Δ mean %| ≥ 5.00%

Performance changes are noted in the perf column of each table:

  • ✅ = significantly better comparison variant performance
  • ❌ = significantly worse comparison variant performance
  • ➖ = no significant change in performance

A regression test is an A/B test of target performance in a repeatable rig, where "performance" is measured as "comparison variant minus baseline variant" for an optimization goal (e.g., ingress throughput). Due to intrinsic variability in measuring that goal, we can only estimate its mean value for each experiment; we report uncertainty in that value as a 90.00% confidence interval denoted "Δ mean % CI".

For each experiment, we decide whether a change in performance is a "regression" -- a change worth investigating further -- if all of the following criteria are true:

  1. Its estimated |Δ mean %| ≥ 5.00%, indicating the change is big enough to merit a closer look.

  2. Its 90.00% confidence interval "Δ mean % CI" does not contain zero, indicating that if our statistical model is accurate, there is at least a 90.00% chance there is a difference in performance between baseline and comparison variants.

  3. Its configuration does not mark it "erratic".

Replicate Execution Details

We run multiple replicates for each experiment/variant. However, we allow replicates to be automatically retried if there are any failures, up to 8 times, at which point the replicate is marked dead and we are unable to run analysis for the entire experiment. We call each of these attempts at running replicates a replicate execution. This section lists all replicate executions that failed due to the target crashing or being oom killed.

Note: In the below tables we bucket failures by experiment, variant, and failure type. For each of these buckets we list out the replicate indexes that failed with an annotation signifying how many times said replicate failed with the given failure mode. In the below example the baseline variant of the experiment named experiment_with_failures had two replicates that failed by oom kills. Replicate 0, which failed 8 executions, and replicate 1 which failed 6 executions, all with the same failure mode.

Experiment Variant Replicates Failure Logs Debug Dashboard
experiment_with_failures baseline 0 (x8) 1 (x6) Oom killed Debug Dashboard

The debug dashboard links will take you to a debugging dashboard specifically designed to investigate replicate execution failures.

❌ Retried Profiling Replicate Execution Failures (ddprof)

Note: Profiling replicas may still be executing. See the debug dashboard for up to date status.

Experiment Variant Replicates Failure Debug Dashboard
quality_gate_idle_all_features baseline 10 Oom killed Debug Dashboard
quality_gate_idle_all_features comparison 10 Oom killed Debug Dashboard
quality_gate_metrics_logs baseline 10 Oom killed Debug Dashboard
quality_gate_metrics_logs comparison 10 Oom killed Debug Dashboard
quality_gate_security_idle baseline 10 Crashed (exit code: 134) Debug Dashboard
quality_gate_security_idle comparison 10 Crashed (exit code: 134) Debug Dashboard
quality_gate_security_mean_fs_load baseline 10 Oom killed Debug Dashboard
quality_gate_security_no_fs_load baseline 10 Oom killed Debug Dashboard
quality_gate_security_no_fs_load comparison 10 Oom killed Debug Dashboard

CI Pass/Fail Decision

Passed. All Quality Gates passed.

  • quality_gate_security_mean_fs_load, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_security_mean_fs_load, bounds check cpu_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_security_no_fs_load, bounds check cpu_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_security_no_fs_load, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_idle_all_features, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_idle_all_features, bounds check intake_connections: 10/10 replicas passed. Gate passed.
  • quality_gate_idle_all_features, bounds check total_bytes_received: 10/10 replicas passed. Gate passed.
  • quality_gate_metrics_logs, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_metrics_logs, bounds check cpu_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_metrics_logs, bounds check missed_bytes: 10/10 replicas passed. Gate passed.
  • quality_gate_metrics_logs, bounds check intake_connections: 10/10 replicas passed. Gate passed.
  • quality_gate_metrics_logs, bounds check total_bytes_received: 10/10 replicas passed. Gate passed.
  • quality_gate_security_idle, bounds check cpu_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_security_idle, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_private_action_runner, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_idle, bounds check total_bytes_received: 10/10 replicas passed. Gate passed.
  • quality_gate_idle, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_idle, bounds check intake_connections: 10/10 replicas passed. Gate passed.
  • quality_gate_logs, bounds check missed_bytes: 10/10 replicas passed. Gate passed.
  • quality_gate_logs, bounds check intake_connections: 10/10 replicas passed. Gate passed.
  • quality_gate_logs, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_logs, bounds check total_bytes_received: 10/10 replicas passed. Gate passed.

@zhuminyi
zhuminyi force-pushed the minyi/cons-8441-docker-port-range branch 6 times, most recently from 55f90cc to c024b52 Compare July 25, 2026 02:15
Some images bake a port RANGE into their metadata (e.g. "1061-1070" in
Config.ExposedPorts). Docker daemons <= v25 return it verbatim in the inspect
payload, and moby v29's strict network.Port map-key decoder rejects it
("invalid port '1061-1070': invalid syntax"), which aborts the whole
ContainerInspect decode and makes the workloadmeta docker collector skip the
container entirely. (v29 daemons normalize ranges, so they are unaffected.)

On that specific decode failure, DockerUtil.InspectNoCache now refetches the
inspect payload as raw JSON (moby discards the raw bytes on decode error),
expands any port-range keys into individual ports, and decodes the sanitized
payload. The happy path is untouched.

The raw refetch (rawContainerInspect) is self-contained in inspect_ports.go; it
mirrors the analogous /info strict-decode workaround in safe_info.go but is kept
separate to avoid coupling. Adds unit tests plus an integration test that drives
the real moby client against an httptest fake daemon.
@zhuminyi
zhuminyi force-pushed the minyi/cons-8441-docker-port-range branch from c024b52 to 0b74b0b Compare July 25, 2026 02:34
zhuminyi added 4 commits July 24, 2026 22:51
- recoverInspect now verifies the refetched payload identifies the container
  that was requested (callers may pass a name or short ID, and the container
  can be replaced between the failed inspect and the refetch). Previously any
  container the daemon returned was accepted and cached for 10s.
- Skip the refetch when the context is already done: it cannot succeed and only
  adds daemon load; the original timeout/cancel error is surfaced instead.
- TrimSpace the id, matching moby's client, so the fallback targets the same
  path as the SDK.
- Cap range expansion at 1024 ports: "1-65535" would otherwise inflate the
  payload and push 65k ports into workloadmeta for one container. Dropping the
  key still recovers the rest of the container.
- Demote the per-key "unparseable port" log to Debug (InspectNoCache runs per
  container event, so a malformed key could spam warnings) and keep a single
  Warn for a dropped wide range.
- Drop a stale comment describing PortMap binding values; the sanitizer only
  handles Config.ExposedPorts.

Tests: add coverage that a genuine daemon failure surfaces the original error
(the recovery path cannot mask it), that a mismatched container is rejected,
and that a pathological range is dropped.
Restore isPortRangeDecodeError as a pre-filter so an inspect failure that has
nothing to do with port ranges (connection refused, daemon 5xx, auth) returns
immediately instead of paying a second round trip to the daemon.

The gate is an optimization, not the safety net: recoverInspect still verifies
independently that the refetched payload actually contained a range, that it
re-decodes, and that it describes the requested container. So if moby ever
rewords the message, recovery simply stops being attempted (the pre-fix
behaviour) rather than returning anything wrong.
- Rename isPortRangeDecodeError to isInvalidPortKeyError: it matches any
  unparseable port key, not only ranges, which is intentional (the sanitizer
  drops those too and still recovers the container) but the old name implied
  otherwise.
- Demote the dropped-wide-range log to Debug. It shares the per-container-event
  uncached path with the sibling log, so a single offending container could
  otherwise spam warnings.
- Guard the test assertions that dereference c.Config with require.NotNil.
  Config is a *container.Config, so a regression that left it nil crashed the
  whole test binary with a SIGSEGV instead of failing one test, masking the
  other results.
@zhuminyi zhuminyi added the qa/done QA done before merge and regressions are covered by tests label Jul 25, 2026
@zhuminyi zhuminyi added this to the 7.83.0 milestone Jul 25, 2026
Generated by `bazel run //:gazelle -- ./pkg/util/docker`: adds inspect_ports.go
to the library srcs, inspect_ports_test.go to the test srcs, and the direct
moby/moby/api types/network dep to both.

Without this, a docker-tagged Bazel build compiled docker_util.go without the
new file and failed with `undefined: isInvalidPortKeyError` and
`d.recoverInspect undefined`. Verified both directions with
`bazel build //pkg/util/docker:docker --@rules_go//go/config:tags=docker`.
golangci-lint's perfsprint rule rejects fmt.Errorf without format arguments.
Fixes the three lint failures on lint_cross_windows-x64, lint_linux-arm64 and
lint_flavor_dogstatsd_linux-x64.

Verified with golangci-lint v2.12.2 (the pinned version) and the repo config:
`golangci-lint run --build-tags docker ./pkg/util/docker/...` -> 0 issues.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Identify a non-fork PR medium review PR review might take time qa/done QA done before merge and regressions are covered by tests team/agent-build team/container-integrations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant