Skip to content

[Request]: Reserve HealthStatus enum + health field on ContainerSnapshot #1502

@chrisgeo

Description

@chrisgeo

Suggested triage: type=Feature, label=enhancement. (External contributor — cannot self-apply.)

Feature or enhancement request details

Summary

Reserve a public HealthStatus enum and an optional health: HealthStatus? field on ContainerSnapshot. Data-shape only in this proposal — the field is always nil at runtime; this PR does not add a healthcheck observer to the daemon.

A draft PR with the implementation is open at #1504.

Motivation

External orchestrators that drive the API server (the canonical use case is a Compose-spec orchestrator implementing depends_on: condition: service_healthy) need to know whether a container is up AND healthy, not just up. Today ContainerSnapshot exposes .running for any started container, so consumers fall back to treating liveness as health. Real workloads (databases that take seconds to accept connections, queue brokers that warm up in-memory state, services that depend on a slow upstream during boot) hit this regularly and end up either waiting too long or proceeding too early.

Proposed change

// Sources/ContainerResource/Container/HealthStatus.swift (new)
public enum HealthStatus: String, CaseIterable, Sendable, Codable {
    case none, starting, healthy, unhealthy
}
// Sources/ContainerResource/Container/ContainerSnapshot.swift
public var health: HealthStatus?   // always nil today; see Scope below

Scope of the proposed PR (deliberately minimal)

This proposal is data-shape only. It adds the enum and the field to the SDK. It does NOT wire a healthcheck observer into the daemon: at runtime the field is always nil, so the on-the-wire behavior is unchanged modulo one new Codable key on ContainerSnapshot.

Why ship a nil-only field?

A container-level healthcheck observer is a non-trivial design discussion:

  • Where does the healthcheck spec live? ContainerCreateOptions? A separate HealthcheckSpec? A field on ContainerConfiguration?
  • Does the API server exec into the container, or does the runtime drive it from the sandbox side?
  • Does it leak into the sandbox boundary (the runtime VM has to run user-supplied probes)?
  • Cadence, retry, start_period, exit codes — all open per-design decisions.

We would rather have that discussion separately, against a concrete companion design issue, than couple it to the SDK shape PR. Reserving the SDK shape now lets downstream tools start coding against the field with the documented "always nil today" guarantee inline; flipping the implementation on later does not require another SDK-shape PR.

If the maintainers prefer the opposite path (block the SDK shape until an observer design lands), we will park this PR and open a design discussion issue instead.

Wire compatibility

ContainerSnapshot is marshaled as Codable JSON over XPC. Adding an optional field is forward-compatible:

  • Older clients reading from a newer server: ignore the new key.
  • Newer clients reading from an older server: decode health as nil.

Use case context

This is part of a downstream effort to power Compose-style orchestration on top of apple/container (container-compose). The Compose-spec depends_on: condition: service_healthy gate is the immediate motivator. We carry this shape on a fork today and would much prefer to consume it directly from upstream, both to drop the fork dependency and to give other ecosystem consumers a stable shape to coordinate on.

Code of Conduct

I agree to follow this project's Code of Conduct.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions