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.
This commit is contained in:
43
decnet/lifecycle/events.py
Normal file
43
decnet/lifecycle/events.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""Bus emit helper for DeckyLifecycle transitions.
|
||||
|
||||
DB is the source of truth (wizard polls ``GET /deckies/lifecycle?ids=``).
|
||||
The bus is best-effort live notification — publish failures are logged
|
||||
and swallowed via ``publish_safely``, never propagated.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from decnet.bus import topics as _topics
|
||||
from decnet.bus.base import BaseBus
|
||||
from decnet.bus.publish import publish_safely
|
||||
|
||||
|
||||
async def emit_lifecycle(
|
||||
bus: BaseBus | None,
|
||||
*,
|
||||
lifecycle_id: str,
|
||||
decky_name: str,
|
||||
operation: str,
|
||||
status: str,
|
||||
error: Optional[str] = None,
|
||||
) -> None:
|
||||
"""Publish ``decky.<name>.lifecycle`` with the current transition.
|
||||
|
||||
Payload keys: ``lifecycle_id``, ``operation``, ``status`` and
|
||||
optionally ``error``. Documented in
|
||||
``wiki-checkout/Service-Bus.md``.
|
||||
"""
|
||||
payload: dict = {
|
||||
"lifecycle_id": lifecycle_id,
|
||||
"operation": operation,
|
||||
"status": status,
|
||||
}
|
||||
if error is not None:
|
||||
payload["error"] = error
|
||||
await publish_safely(
|
||||
bus,
|
||||
_topics.decky_lifecycle(decky_name),
|
||||
payload,
|
||||
event_type=_topics.DECKY_LIFECYCLE,
|
||||
)
|
||||
Reference in New Issue
Block a user