Skip to content

Job manifest

apiVersion: odysseus/v1
kind: Job
metadata:
name: api-migrate
spec:
image: registry.delta-telematics.ca/acme/api:1.4.2
command: ["/app/migrate", "up"]
networks: [acme-network]
restartPolicy: "no" # quoted — bare no is YAML false
backoffLimit: 2
activeDeadlineSeconds: 600
ttlAfterFinished: 1h
secrets:
- name: DB
vaultPath: deployments/api/db
Validated against JobManifest · testdata/docs-examples/migration-job.yaml

Generated from JobSpec. Hand edits to this table are overwritten on the next build — change the Go doc comment, or the generator.

Field Type Required Default Mutability Since
activeDeadlineSeconds integer no — in-place 0.7.6
backoffLimit integer no — in-place 0.7.6
command string[] no — recreate 0.7.6
entrypoint string[] no — recreate 0.7.6
environment object no — recreate 0.7.6
healthCheck HealthCheckSpec no — recreate 0.7.6
image string no — recreate 0.7.6
init boolean no — recreate 0.21.1
networks string[] no — recreate 0.7.6
placement PlacementSpec no — recreate 0.7.6
resources ResourceSpec no — recreate 0.7.6
restartPolicy string no — recreate 0.7.6
secrets SecretSpec[] no — recreate 0.7.6
ttlAfterFinished string no — in-place 0.7.6
ulimits Ulimit[] no — recreate 0.21.1
volumes VolumeSpec[] no — recreate 0.7.6
workingDir string no — recreate 0.7.6

activeDeadlineSeconds: 0 = no deadline

backoffLimit: nil → 3 (JD6)

command: Command overrides the image’s CMD, as argv. Empty leaves the image default.

entrypoint: Entrypoint overrides the image’s ENTRYPOINT, as argv.

environment: Environment are plain environment variables set on every container. Never put a credential here — use secrets:, which resolves from Vault at dispatch and never stores the value.

healthCheck: HealthCheck is the container probe. Only type: exec produces a real healthcheck; an http or tcp declaration is refused rather than left inert.

image: Image is the fully-qualified container image reference, including an explicit tag. Never “:latest” in production: an unpinned tag makes a rollback impossible to describe.

init: Init runs Docker’s tiny init as PID 1 so orphaned processes are reaped. Omit it to take the platform default, which is on; set false only for an image that already runs its own init.

networks: Networks are the Docker networks the container joins. Names are tenant-prefixed for you; a backend should stay off traefik-public.

placement: SP-4; shared: Jobs place too

resources: Resources are the CPU and memory limits and requests, written as limits/requests rather than as four flat keys.

restartPolicy: RestartPolicy is what Docker does when the container exits. The accepted values differ by kind and are enforced by each kind’s own validator.

secrets: Secrets are references to material in Vault, injected as environment variables at dispatch. The value never appears in this document.

ttlAfterFinished: duration; “” = keep

ulimits: Ulimits are the container’s POSIX resource limits. A per-container ulimit overrides the daemon’s defaults, which is the supported way to raise a file-descriptor ceiling — never a hand-edited daemon.json.

volumes: Volumes are the named volumes and bind mounts attached to each container.

workingDir: WorkingDir is the directory the process starts in, overriding the image’s WORKDIR.

Generated from ResourceSpec. Hand edits to this table are overwritten on the next build — change the Go doc comment, or the generator.

Field Type Required Default Mutability Since
limits ResourceValues no — recreate 0.1.0
requests ResourceValues no — recreate 0.1.0

Generated from Ulimit. Hand edits to this table are overwritten on the next build — change the Go doc comment, or the generator.

Field Type Required Default Mutability Since
hard integer no — recreate 0.21.1
name string no — recreate 0.21.1
soft integer no — recreate 0.21.1

Generated from HealthCheckSpec. Hand edits to this table are overwritten on the next build — change the Go doc comment, or the generator.

Field Type Required Default Mutability Since
command any no — recreate 0.1.0
interval string no — recreate 0.1.0
path string no — recreate 0.1.0
port integer no — recreate 0.1.0
retries integer no — recreate 0.1.0
startPeriod string no — recreate 0.1.0
timeout string no — recreate 0.1.0
type string no — recreate 0.1.0

command: Command is the probe command, in either the shell-string or the argv-list form (see ShellOrArgv). Both land on the same stored []string.

interval — There is no floor. Clamping an interval upward would delay failure detection, so unlike the timeout it is not safety-monotonic — a longer timeout can only reduce spurious kills, a longer interval can only slow detection. odysseus spec-audit reports the value; nothing rejects or changes it.

timeout — There is a 10s floor for exec probes: a timed-out exec is SIGKILLed and reparented to a PID 1 that never reaps it, so a shorter value is refused outright on create (code healthcheck_timeout_below_floor). On a DEPLOYMENT update that omits healthCheck entirely, the stored value is restored first and THEN clamped up to the floor if it predates this rule — silently, unless you are reading the response, where it is disclosed as healthcheck_timeout_clamped. Omit timeout to take Docker’s 30s default, which already clears the floor; state it explicitly only to set a tighter bound than the default.

type: http, tcp, exec

Generated from VolumeSpec. Hand edits to this table are overwritten on the next build — change the Go doc comment, or the generator.

Field Type Required Default Mutability Since
distributedVolumeId string no — recreate 0.63.0
readOnly boolean no — recreate 0.1.0
source string no — recreate 0.1.0
target string no — recreate 0.1.0

distributedVolumeId: DistributedVolumeID mounts a DVM volume by its typed ID (#414). Its PRESENCE is the discriminator — the manifest surface deliberately has no type key (every plain manifest volume is a bind mount, see convertVolumeSpecs), so exactly one of source/distributedVolumeId is set, and the shape validator downstream rejects both-or-neither.

Generated from SecretSpec. Hand edits to this table are overwritten on the next build — change the Go doc comment, or the generator.

Field Type Required Default Mutability Since
anchor string no — recreate 0.37.0
mountPath string no — recreate 0.1.0
name string no — recreate 0.1.0
rotation string no — recreate 0.1.0
vaultPath string no — recreate 0.1.0

anchor: Anchor: volume(<id>) | process | external — WP18 S10.

Generated from PlacementSpec. Hand edits to this table are overwritten on the next build — change the Go doc comment, or the generator.

Field Type Required Default Mutability Since
affinity PlacementSelector no — recreate 0.7.6
antiAffinity PlacementSelector no — recreate 0.7.6
node string no — recreate 0.7.6
preferredZone string no — recreate 0.7.6
residency ResidencySpec no — recreate 0.74.0

affinity: Affinity steers placement TOWARD nodes carrying a label. It is a preference the scorer weighs, not a filter that refuses — a workload with an unsatisfiable affinity is still placed, just not where it asked.

antiAffinity: AntiAffinity steers placement AWAY from nodes carrying a label, with the same weigh-do-not-refuse semantics as Affinity.

node: Node pins the workload to one node by name, landing on Deployment.NodeID. Leave it unset to let the scheduler choose; an empty value never clears an assignment the scheduler already made.

preferredZone: PreferredZone names an edge zone the scorer prefers.

NOTE, so nobody debugs this twice: no zone is declared in any shipped control-plane config today, so this currently scores against nothing. That is a real finding with its own issue, not a defect in this block.

residency: Residency is where the workload is legally allowed to run (S19, #557).