apple / apple/container

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

Open
#1,502 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Swift
Stars
49.9k
Forks
1.8k
Avg merge
1d 20h
Merged PRs (30d)
22

Description

> _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

```swift
// Sources/ContainerResource/Container/HealthStatus.swift (new)
public enum HealthStatus: String, CaseIterable, Sendable, Codable {
case none, starting, healthy, unhealthy
}
```

```swift
// 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](https://github.com/full-chaos/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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.