Repository navigation
api: remove ExternalVolume.Status enum and status field #2414
Copy link
Copy link
Labels
area/apiUser-facing API changesUser-facing API changeskind/cleanupSmall fixes that are not bugs, for example a typo in a code commentSmall fixes that are not bugs, for example a typo in a code comment
Description
Problem
In pkg/proto/ateapipb/ateapi.proto (lines 352–366), ExternalVolume defines a nested Status enum and status field:
message ExternalVolume {
...
enum Status {
STATUS_UNSPECIFIED = 0;
STATUS_PENDING = 1;
STATUS_CREATED = 2;
STATUS_DELETING = 3;
}
Status status = 4;
}This has two issues:
- Inconsistent use of
status: Acrossateapi.proto,statusis a distinct API concept reserved for server-managed container messages on resources (ActorStatus status,WorkerStatus status,TagStatus status,ActorTemplateStatus status), never for a lifecycle
enum field. - Redundant "phase"-style enum: Like Kubernetes
phasefields (which Kubernetes API conventions deprecate), every value ofExternalVolume.Statusduplicates state already recorded onExternalVolumeandActorStatus:STATUS_PENDINGvsSTATUS_CREATEDis 1-to-1 withstorage_volume_id == ""vsstorage_volume_id != "":CreateActor(volumes.go:49-53) initializes eachExternalVolumeentry inactor.status.actor_volumeswithvolume_name,volume_type,storage_volume_id: "", andstatus: STATUS_PENDING.ResumeActor(volumes.go:130-136) callsplugin.CreateVolumeand setsstorage_volume_id: resp.VolumeIDandstatus: STATUS_CREATEDin the same struct literal (detachActorVolumesinvolumes.go:224-228already checksvol.GetStorageVolumeId() == ""to skip
unprovisioned volumes).
STATUS_DELETINGis 1-to-1 withactor.status.state == ACTOR_STATE_DELETING:STATUS_DELETINGis only ever written inworkflow_delete.go:335-338inside the exact same store transaction that setsactor.status.state = ACTOR_STATE_DELETING.deleteActorVolumes(volumes.go:142-160) never inspectsvol.GetStatus();ensureVolumesDeletedonly checksactor.GetStatus().GetState() == ACTOR_STATE_DELETING.
Idempotency & Failure Recovery
Removing ExternalVolume.status preserves the exact same idempotency and crash-recovery guarantees as the current implementation:
- Normal
ResumeActorafter provisioning: OnceUpdateActorpersistsstorage_volume_id, subsequentResumeActorcalls seevol.GetStorageVolumeId() != ""and skipplugin.CreateVolume(just as they currently checkSTATUS_CREATED). - Crash between
plugin.CreateVolumeandUpdateActor: Both today (STATUS_PENDING) and withoutstatus(storage_volume_id == ""), a retry ofResumeActorcallsplugin.CreateVolumewith the deterministic volume nameactorVolumeID(actorUID, volName)
("substrate-<actorUID>-<volName>"), which CSIControllerCreateVolumerequires to be idempotent by name. DeleteActorbeforestorage_volume_idis persisted: BecauseCreateActorstill pre-populates theExternalVolumeentry (withvolume_name,volume_type, and emptystorage_volume_id),deleteActorVolumes(volumes.go:148-154) continues to fall back to
actorVolumeID(actorUID, vol.GetVolumeName())whenstorage_volume_id == "".
Proposal
- Remove
enum StatusandStatus status = 4fromExternalVolumeinpkg/proto/ateapipb/ateapi.proto. - In
cmd/ateapi/internal/controlapi/volumes.goandworkflow_resume.go, usevol.GetStorageVolumeId() == ""to determine whether a volume still needs to be provisioned. - In
cmd/ateapi/internal/controlapi/workflow_delete.go, stop settingvol.Status = ExternalVolume_STATUS_DELETINGwhen transitioning the Actor toACTOR_STATE_DELETING. - Regenerate protobufs and validation code (
hack/update/codegen.sh) and update tests and docs (cmd/ateapi,internal/e2e,docs/api-guide.md).
Michelle Au (@msau42) thoughts?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area/apiUser-facing API changesUser-facing API changeskind/cleanupSmall fixes that are not bugs, for example a typo in a code commentSmall fixes that are not bugs, for example a typo in a code comment
Activity
[-]api: remove ExternalVolume.Status enum and status field[/-][+]api: remove `ExternalVolume.Status` enum and `status` field[/+]msau42 commentedon Oct 9, 2026
That makes sense to me. My biggest concern is to make sure we can keep track of create operations that we started but have not completed, so we can make sure they are properly cleaned up if the Actor gets deleted while the volume creation is in progress.
With the proposed change we could still keep track of that with volume_name.
ericcurtin commentedon Oct 10, 2026
I'll send a PR for this.
ExternalVolume no longer has a status field (agent-substrate#2456)