Skip to content

Asynchronous client configuration

Control Odoo dispatches managed client work through restricted start/status runners. Configuration, production, resize, credential and custom operations have separate profiles. Each request binds an exact client-<UUID>, canonical request UUID, profile and, for release-aware clients, the selected immutable client SHA. The profile-to-role table and receipt formats live in the durable execution protocol.

Dispatch and status

The controller first checks oduflow.ping(minion_id) and complete authenticated pillar. For configuration it calls oduflow.apply_start(minion_id, request_id, client_revision); production uses oduflow.production_start with the same identities. Subsequent status calls use the original minion/request pair and matching profile endpoint.

The master commits a private claim before launching its worker and records the Salt JID and dispatch intent before publication. The client receives the reviewed oduflow_job.run wrapper, which applies the fixed profile from the selected release and commits a reduced result before returning it. It does not accept an arbitrary RPC function, target pattern, role or pillar override. Validated custom high data uses its own bounded, digest-bound path.

control_master installs /usr/local/libexec/oduflow-apply-worker. Master claims live in /var/cache/salt/oduflow-apply, owned by the Salt account with directory mode 0700 and file mode 0600. Global job/pillar caches stay disabled. Raw state returns and secret pillar are not the operation history.

The public summary includes minion/request/JID, status and state counts, plus the revision or source digest when required by the protocol:

Status Interpretation
not_started No matching claim/result at that boundary; not permission to republish an already recorded dispatch
running The request is launching or still has matching live execution evidence
succeeded A valid, nonempty state mapping has every result exactly True
failed A valid state mapping includes False, or a confirmed preflight failure prevented dispatch
unknown Transport/execution evidence is missing, invalid or interrupted; possible effects must be reconciled

Empty mappings, compiler-error lists and non-boolean results are not successful or trustworthy failed-state receipts. Optional diagnostics explain classifications but do not override the durable result.

Concurrency and time limits

Profiles share a per-client execution lease. A worker can wait up to 60 seconds for it; a busy or quarantined target fails preflight without publishing Salt work. Execution waits up to 7,200 seconds, with a 7,250-second hard deadline and bounded status polling. The dispatch timestamp separates lease waiting from execution.

A worker/master restart can lose the response while the minion continues applying. Keep the original request and JID and retrieve its exact terminal receipt. A trustworthy late result may resolve an unknown status. Exiting the master worker does not establish that the client stopped executing.

Recovery and rollout

Update the master executor and allowlist before a controller uses a new protocol; capability checks reject clients that cannot produce the required receipt. Old receipts retain their original format and interpretation. Client software updates follow client releases.

For a failed or unknown configuration, use deployment recovery. A repeated status read does not run configuration again. The explicit recovery workflow can link a new configuration generation after ownership and inactive execution checks, preserving the old result. General job retry or receipt deletion cannot substitute for that workflow.

Configuration checks local application health. Production separately guards creation, hardens the administrator account and verifies public access. Neither profile proves that a real AI coding task completed.