Skip to content

wslc: align docker_schema with bundled dockerd v25.0.3 (API v1.44)#40552

Open
benhillis wants to merge 2 commits into
microsoft:masterfrom
benhillis:fix/wslc-docker-schema-v25-audit
Open

wslc: align docker_schema with bundled dockerd v25.0.3 (API v1.44)#40552
benhillis wants to merge 2 commits into
microsoft:masterfrom
benhillis:fix/wslc-docker-schema-v25-audit

Conversation

@benhillis
Copy link
Copy Markdown
Member

Follow-up to #40550. Audits the rest of docker_schema.h against the moby version we actually ship — dockerd v25.0.3, Docker API v1.44 (verified via the version banner in the dockerd ETL trace from the linked test failure). Authoritative source: https://github.com/moby/moby/tree/v25.0.3/api.

None of these are observable user-facing bugs on a stock Docker daemon today, but each is a latent crash or wrong-behavior path waiting on the right wire payload from a third-party driver, future daemon, or TTY exec.

Schema fixes

# Field Before After Why
1 ContainerState enum Created was the first enum entry, so NLOHMANN_JSON_SERIALIZE_ENUM mapped any unrecognized state string to Created Unknown is first, mapped to nullptr Daemon can introduce new states (e.g. configured for swarm). Old code silently labels them Created.
2 HostConfig.ShmSize std::optional<ULONGLONG> std::int64_t Wire type is signed int64; 0 already means "use daemon default". The optional added nothing.
3 Volume.Status optional<map<string, string>> optional<map<string, nlohmann::json>> Docker's wire schema is map[string]any. Third-party volume drivers may publish numbers, bools, or nested objects — currently throws type_error.
4 Image.Size, InspectImage.Size uint64_t int64_t Daemon serializes int64.
5 CreateExec / StartExec ConsoleSize Macro-generated to_json that always wrote "ConsoleSize": [] Custom to_json that omits the field when empty Docker treats an empty array as an explicit 0×0 console for TTY execs. We never set ConsoleSize, so every exec was sending [].
6 CreatedContainer.Name Field present Removed Docker's POST /containers/create response is only {Id, Warnings}; Name is a query parameter, not echoed in the response body. Switched to WITH_DEFAULT for parity.
7 API doc URLs v1.52 (aspirational) v1.44 + comment about bundled dockerd version Match the actual shipped daemon.

Consumer cascade

Image.Size going uint64_t -> int64_t requires explicit casts where the value flows back to ULONGLONG ABI fields:

  • WslcSDK\wslcsdk.cpp:1480
  • wslc\services\ImageService.cpp:207
  • wslcsession\WSLCSession.cpp:112, 1314, 1340

HostConfig.ShmSize becoming int64_t simplifies the consumer at WSLCContainer.cpp:1419 (drops the > 0 guard, just direct assignment with cast).

Not in scope

  • InspectExec polling-loop tightening: deferred until Fix WSLC exec hang on fast runc failure (e.g. invalid user/group) #40550 lands. The change only becomes safe once state.Pid is no longer always has_value() == true, otherwise we'd race-bug on the transient Running=false, ExitCode=null state.
  • moby v28+ schema changes (e.g., ExitCode becoming non-nullable): not exercised today; left for a future PR after the daemon bumps.

Verification

  • clang-format --dry-run --Werror passes on all modified files.
  • Each consumer of every changed field was inspected by hand. No code reads Volume.Status, CreatedContainer.Name, or any ConsoleSize field; the rest are listed above.
  • Cross-checked against https://raw.githubusercontent.com/moby/moby/v25.0.3/api/types/... to confirm wire types.

WSLC talks to a bundled dockerd v25.0.3 (Docker API v1.44). Several entries
in docker_schema.h drifted toward documented-but-not-shipped types or were
defensive in the wrong way. None of these are observable user-facing bugs
on a stock daemon today, but each is a latent crash or misbehavior waiting
on the right wire payload from a third-party driver, future daemon, or
TTY exec.

Authoritative source: https://github.com/moby/moby/tree/v25.0.3/api

Schema fixes:

* ContainerState enum: prepend {Unknown, nullptr} so an unrecognized state
  string from the daemon falls back to Unknown rather than silently
  decoding as the first map entry (Created).

* HostConfig.ShmSize: change std::optional<ULONGLONG> -> std::int64_t.
  Docker's wire type is signed int64 and 0 already means "use daemon
  default", so the optional indirection added nothing.

* Volume.Status: change optional<map<string,string>> ->
  optional<map<string, nlohmann::json>>. Docker's wire schema is
  map[string]any; third-party volume drivers may publish numbers, bools,
  or nested objects which would currently throw type_error during deserialize.

* Image.Size, InspectImage.Size: change uint64_t -> int64_t to match the
  daemon's int64 wire type. Cast at consumer sites that feed ULONGLONG
  ABI fields.

* CreateExec / StartExec ConsoleSize: replace
  NLOHMANN_DEFINE_TYPE_INTRUSIVE_* with explicit to_json that omits the
  field when empty. Docker treats an empty array as an explicit 0x0
  console for TTY execs; we were unconditionally serializing [].

* CreatedContainer.Name: removed (Docker's POST /containers/create
  response only contains Id and Warnings; Name is supplied as a query
  parameter, not echoed back). Switched to WITH_DEFAULT for parity with
  surrounding types.

Doc:

* Updated two API doc URL references from v1.52 to v1.44 with a note
  about the bundled dockerd version.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@benhillis benhillis requested a review from a team as a code owner May 15, 2026 02:46
Comment thread src/windows/wslc/services/ImageService.cpp
Comment thread src/windows/WslcSDK/wslcsdk.cpp Outdated
Comment thread src/windows/wslcsession/WSLCContainer.cpp Outdated
Per PR review: replace boundary static_casts with consistent signed
64-bit types across IDL, SDK, service models, and CLI schema. Mirrors
the existing MemoryBytes/NanoCpus precedent.

- IDL: WSLCImageInformation.Size, WSLCContainerOptions.ShmSize -> LONGLONG
- SDK: WslcImageInfo.sizeBytes -> int64_t
- Models: ImageInformation::Size, ContainerOptions::ShmSize -> int64_t
- Schema: InspectImage::Size -> int64_t
- Launcher: m_shmSize/SetShmSize -> int64_t
- Validation: GetMemorySizeFromString returns int64_t

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/windows/inc/docker_schema.h
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants