Deployment status
Deploying from your own code is two APIs and one field. You write a
Distribution to say what should run where, the platform creates a Pod
per matching device, and you read status.phase on those pods to find out what
happened.
This page is about the reading half. Creating resources follows the same patterns as everything else in this section; knowing when a rollout has actually succeeded is the part that catches people out.
Which resource to watch
Both live in the Applications service.
| Resource | What it is | What you do with it |
|---|---|---|
Distribution |
An application plus a rule for which devices should run it | Create and update it to drive a rollout |
Pod |
One running instance on one device | Read it to find out what actually happened |
A distribution records your intent. It does not tell you whether ninety devices took the update and ten failed. Status lives on the pods, so a rollout is judged by listing or watching the pods the distribution produced, not by re-reading the distribution.
The cuttle applications command family maps onto the same API, which makes it
the fastest way to see the shape of a response before you write code against
it.
Reading status.phase
Pod.Status.Phase is the single field that answers “did this work?”.
| Phase | Meaning |
|---|---|
PENDING |
Accepted, not yet launched |
RUNNING |
Every container that should be up is up |
SUCCEEDED |
Terminated, with non-error exit codes |
FAILED |
Ran, then some or all containers stopped running |
UNKNOWN |
The device stopped responding |
IMAGE_DOWNLOAD_FAILED |
The image pull failed |
INIT_FAILED |
Validation or initialization failed — often compose syntax, or a full disk |
POD_CREATE_FAILED |
The compose file is valid, but bringing the pod up failed |
PHASE_UNSPECIFIED |
Unknown state; not normally used |
Two things about this enum are worth internalizing before you write a polling loop against it.
There is no TERMINATED phase. A pod that has stopped is SUCCEEDED or
FAILED, depending on exit codes. TERMINATED exists, but it is a container
state, in status.containerStatuses[].state. Code that waits for a terminated
pod by matching on the phase will wait forever.
Failure is not one value. Treating FAILED as “the deployment broke”
misses three of the four ways it can break. IMAGE_DOWNLOAD_FAILED,
INIT_FAILED, and POD_CREATE_FAILED all mean the deployment did not work,
and none of them is FAILED — that phase is reserved for a pod that started
successfully and then stopped. Match the whole failure set, or you will report
success for a pod that never pulled its image.
When a pod is in any failure phase, status.error carries the message, and
status.failureCount counts retries for the errors that are retried.
Health is a separate question
status.healthStatus is not a finer-grained status.phase. Phase answers
whether the containers are running; health answers whether the containers
that are running consider themselves well, aggregated across the pod. A pod
is UNHEALTHY as soon as any one container is, and HEALTHY while at least
one reports healthy.
So a pod can be RUNNING and UNHEALTHY at the same time, and for most
alerting that combination is the interesting one — the platform believes it did
its job, and your application disagrees.
Watch, do not poll
A rollout is exactly the case watch exists for: you want to know the moment a pod changes phase, across a fleet, without asking repeatedly.
Watch the pods your distribution produced and apply changes when isCurrent
arrives, as described in Watching for changes. For a controller
tracking a whole collection across reconnects, use a STATELESS watch so you
can resume from a token rather than restarting with a fresh snapshot.
If you do poll — in a CI job that deploys and exits, say — request only the fields you need with a field mask. Pod status is much smaller than a full pod, and the difference is multiplied by every device in the fleet. See Reading resources.
Related
- Monitor and control applications — the same statuses as the dashboard presents them, which is useful for agreeing on vocabulary with whoever is watching the UI.
- Applications API — the full resource and method reference.
- Errors and limits — including what a deployment refused for quota reasons looks like.