Expose auto_activate on POST /deployments/{id}/revisions
- Dominant language
- Python
- Stars
- 670
- Forks
- 183
- Avg merge
- 17h 7m
- Merged PRs (30d)
- 358
Description
## Context
`POST /deployments/{id}/revisions` (`AddRevisionRequest`) does not expose `auto_activate`, so clients must make two sequential calls (create revision → activate revision) to publish a new revision. This is not atomic — if the activate call fails, an orphan CREATED revision is left behind and operators must recover it manually.
WebUI ran into this while implementing **Update Service** ([FR-2528](https://lablup.atlassian.net/browse/FR-2528), PR [lablup/backend.ai-webui#6607](https://github.com/lablup/backend.ai-webui/pull/6607)). The WebUI currently has a `TODO(needs-backend): FR-2528` comment and a dedicated error key `UpdateServiceActivateFailedWithId` to surface the orphan revision id. Both should be removable once this lands.
## Current state
The service layer already supports `auto_activate` end-to-end. `services/deployment/service.py:990`:
```python
if action.adder.auto_activate:
await self.activate_revision(
ActivateRevisionAction(
deployment_id=deployment_id,
revision_id=revision_data.id,
)
)
```
`ModelRevisionCreator.auto_activate: bool = False` already exists at `data/deployment/creator.py:47`. The only thing missing is DTO → adapter plumbing for the `POST /deployments/{id}/revisions` route.
The legacy `POST /services` wrapper forces `auto_activate=True` at `services/deployment/service.py:496` via `dataclasses.replace(revision, auto_activate=True)`, so the initial-revision path is unaffected.
## Required changes
**1. RevisionInput DTO (v1)** — `src/ai/backend/common/dto/manager/deployment/request.py:263`
```python
auto_activate: bool = Field(
default=False,
description="If true, activate the new revision immediately after creation in the same request.",
)
```
**2. RevisionInput DTO (v2)** — `src/ai/backend/common/dto/manager/v2/deployment/request.py:320` — same field, same default.
**3. Adapter** — `src/ai/backend/manager/api/rest/deployment/adapter.py:428` — `build_revision_creator` passes the field through:
```python
return ModelRevisionCreator(
image_id=revision_input.image.id,
resource_spec=resource_spec,
mounts=mounts,
execution=execution,
model_definition=revision_input.model_definition,
auto_activate=revision_input.auto_activate, # NEW
)
```
## Out of scope
- GraphQL `add_model_revision` resolver (`api/gql/deployment/resolver/revision.py:145`) — REST-only is enough for the WebUI use case.
- Additional transaction work — `activate_revision` is already called in the same request context; failure propagates as a normal HTTP error response.
## Compatibility
Default is `False`, existing clients unaffected. No schema or DB changes.
## Acceptance
- [ ] `POST /deployments/{id}/revisions` accepts `auto_activate: true` and activates the new revision in the same request.
- [ ] Existing callers without the field still work unchanged.
- [ ] WebUI [PR #6607](https://github.com/lablup/backend.ai-webui/pull/6607) can drop the 2-step call and the `UpdateServiceActivateFailedWithId` error path in a follow-up.
## References
- [FR-2528](https://lablup.atlassian.net/browse/FR-2528) — WebUI Update Service feature
- [lablup/backend.ai-webui#6607](https://github.com/lablup/backend.ai-webui/pull/6607)
JIRA Issue: BA-5675
[FR-2528]: https://lablup.atlassian.net/browse/FR-2528?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[FR-2528]: https://lablup.atlassian.net/browse/FR-2528?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
Contributor guide
Assessment
This issue has not been assessed yet.