Files
DECNET/decnet/lifecycle/__init__.py
anti c0ad380020 feat(lifecycle): runner + strategies + bus topic
Add decnet.lifecycle package: pure orchestration layer that the
master API will invoke via asyncio.create_task to drive DeckyLifecycle
rows through pending -> running -> succeeded | failed without
holding an HTTP request open.

Strategy classes per (operation, transport):
- LocalDeployStrategy: master-resident, runs engine.deployer.deploy
  in a thread.
- SwarmDeployStrategy: shards by host_uuid, dispatches via
  AgentClient.deploy; worker drives terminal via heartbeat.
- LocalMutateStrategy: write_compose + compose up.
- SwarmMutateStrategy: AgentClient.mutate; worker drives terminal.

decnet.bus.topics gains decky_lifecycle(name) -> decky.<name>.lifecycle
plus DECKY_LIFECYCLE constant. Payload documented in the wiki
(separate commit). publish_safely keeps bus best-effort.

Nothing is wired to call this yet -- next commits convert worker
/deploy /mutate to 202, then heartbeat delta wiring, then master API.
2026-05-22 16:25:33 -04:00

16 lines
672 B
Python

"""Async deploy/mutate lifecycle runner.
The runner is invoked by the master API handlers (deploy + mutate) after
they write ``DeckyLifecycle`` rows and return 202 Accepted to the
caller. It executes the actual docker work off the request thread,
flips lifecycle row status through ``running -> succeeded|failed``, and
emits ``decky.<name>.lifecycle`` bus signals on every transition.
Strategy classes encapsulate transport (local docker on master vs
remote agent over mTLS). ``runner.run_deploy`` / ``run_mutate`` pick
the right strategy from the request context.
"""
from decnet.lifecycle.runner import run_deploy, run_mutate
__all__ = ["run_deploy", "run_mutate"]