Skip to content

Storage API

List Storage

Responses

StatusDescriptionSchema
200Successful Responseany

Attach Storage

Attach a storage definition (doc 05 §Storage, doc 01 §5 “Add/edit storage”).

Synchronous: Proxmox returns no UPID for /storage, so there is no job and therefore no jobs.params row holding body.config. The audit row is the only durable trace, and write_audit runs it through redact(); nested config.password included.

The response deliberately echoes NO config: a credential the caller just sent must not come back out of a GET the browser might cache or a screenshot someone pastes into a ticket.

capability="lifecycle": attaching/editing/detaching a storage POOL DEFINITION needs Datastore.Allocate, a node-infrastructure privilege none of the four capabilities carried until the per-capability token sweep found the gap (host-token-privileges-step-one-report.md), the same class of bug Sys.PowerMgmt was.

Request body (required), application/json, StorageAttachIn

FieldTypeRequiredDescription
configobjectno
host_idintegeryes
storagestringyes
typestringyes

Responses

StatusDescriptionSchema
201Successful Responseany
422Validation ErrorHTTPValidationError

Detach Storage

Owner, not admin (doc 05): detaching drops the definition while guest disks keep pointing at it, which is the one action here that can strand running guests. Upstream data is left in place; this is not a wipe.

Parameters

NameInTypeRequiredDescription
host_idpathintegeryes
namepathstringyes

Responses

StatusDescriptionSchema
200Successful Responseany
422Validation ErrorHTTPValidationError

Storage Detail

Parameters

NameInTypeRequiredDescription
host_idpathintegeryes
namepathstringyes
nodequerystring | nullno

Responses

StatusDescriptionSchema
200Successful Responseany
422Validation ErrorHTTPValidationError

Edit Storage

Audits the NAMES of the keys changed, never their values; the same rule settings.py::patch_settings follows, and the reason a rotated PBS password leaves a legible audit trail without leaving the password in it.

Parameters

NameInTypeRequiredDescription
host_idpathintegeryes
namepathstringyes

Request body (required), application/json, StorageEditIn

FieldTypeRequiredDescription
configobjectyes

Responses

StatusDescriptionSchema
200Successful Responseany
422Validation ErrorHTTPValidationError

GET /api/v1/storage/{host_id}/{name}/content

Section titled “GET /api/v1/storage/{host_id}/{name}/content”

Storage Content

Parameters

NameInTypeRequiredDescription
host_idpathintegeryes
namepathstringyes
nodequerystring | nullno
contentquerystring | nullno

Responses

StatusDescriptionSchema
200Successful Responseany
422Validation ErrorHTTPValidationError

POST /api/v1/storage/{host_id}/{name}/content

Section titled “POST /api/v1/storage/{host_id}/{name}/content”

Upload Content

Spool the body to disk, then hand the PATH to a job (doc 05 §Storage).

Never slurp the whole upload in one call: FastAPI’s UploadFile already spools to a SpooledTemporaryFile, and reading it all at once would materialise a multi-GB ISO in this process’s RAM. The 1 MiB loop below keeps peak memory flat regardless of file size. The cost, stated in services/storagejobs.py’s docstring too: the ISO crosses the wire twice (browser -> here -> PVE) and the Proxploy host needs transient free disk equal to the file size.

Parameters

NameInTypeRequiredDescription
host_idpathintegeryes
namepathstringyes

Request body (required), multipart/form-data, Body_upload_content_api_v1_storage__host_id___name__content_post

FieldTypeRequiredDescription
contentstringno
filestringyes
nodestring | nullno
overwritebooleanno

Responses

StatusDescriptionSchema
202Successful Responseany
422Validation ErrorHTTPValidationError

DELETE /api/v1/storage/{host_id}/{name}/content/{volid}

Section titled “DELETE /api/v1/storage/{host_id}/{name}/content/{volid}”

Delete Content

:path because a volid is local:iso/ubuntu.iso; it carries a slash, which a plain {volid} converter would refuse to match.

Parameters

NameInTypeRequiredDescription
host_idpathintegeryes
namepathstringyes
volidpathstringyes
nodequerystring | nullno

Responses

StatusDescriptionSchema
202Successful Responseany
422Validation ErrorHTTPValidationError