Create a storage pool from disk(s) (operator-only).
curl --request POST \ --url https://stratum.example.com/v1/storage-pools \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "name": "example", "nodeId": "example", "driver": "lvm-thin", "disks": [ "example" ], "createStorageClass": false, "storageClassName": "example", "forceWipe": false }'. Builds a new LVM-thin pool — a
dedicated volume group + thin pool — from one or more whole disks
on the local node (pvcreate + vgcreate + lvcreate), executed
in-container. The disks must be empty unless
forceWipe. When createStorageClass is true a storage class
pointing at the new pool is registered, so VMs can target the new
tier immediately (this is how tiering works).
Cedar action storage:CreateStoragePool. When nodeId is the local
node the pool is built synchronously (201). When it targets a
different node the leader records a node-storage intent and returns
202 + a Location to poll — the owning node’s reconciler runs the
op against its local disks. On done the
intent’s result.poolId is the created pool.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
Pool name (becomes the LVM volume group + thin pool name). Not one the install owns: data, stratum, stratum-block and stratum-compute are refused with 400 RESERVED_NAME.
Owning node. 2.0 supports only the local node; omit to default to it.
Only lvm-thin is supported at 2.0.
Device paths to build the pool from — whole disks (e.g. /dev/sdb) and/or partitions used as PVs (e.g. /dev/sdb1, GPT type 8e00). Each must be empty unless forceWipe..
Also register a storage class pointing at the new pool (enables tiering).
Name for the auto-created storage class; defaults to the pool name. Not stratum-compute, the OS disk’s class (400 RESERVED_NAME).
Wipe a disk that holds data (partitions, signatures, an old volume group) instead of refusing it. A mounted disk is refused either way. Destroys everything on the disk.
Responses
Section titled “Responses”The created pool (synchronous, local node).
A storage pool. For lvm-thin this is the install’s VG + thin pool on one node; capacity is refreshed by the 60s poller.
object
Stable surrogate id (pool-…)..
missing: the backend no longer has the pool; see
stateReason. Volumes cannot be placed in it. The next successful poll
restores the real state.
Why the pool is missing. Absent otherwise.
Physical devices (PVs) backing the pool’s VG.
The LVM volume group the pool lives in (lvm-thin only). The install’s
default pool is named after its thin LV but lives in the configured
VG, so read the VG from here, never from name. Absent for Ceph and
until the pool’s node has polled it..
Example
{ "driver": "lvm-thin", "state": "healthy"}Cross-node op accepted and recorded as an intent. Poll
the intent at the Location header until state is done or
error.
A cross-node disk/pool operation recorded by the CP leader for the
owning node’s reconciler to execute against its local /dev. Poll until state is done or error.
object
Intent id (nsi-…).
The node that executes the op (owns the physical disks).
Op-specific arguments (name, disks, poolId,…).
object
Op output on done. For create/extend/shrink: poolId, name,
totalBytes, devicePaths. For delete: poolId.
object
Failure detail when state is error.
Example
{ "op": "create-pool", "state": "pending"}Headers
Section titled “Headers”The intent poll URL.
RESERVED_NAME — the pool’s name is one the install already owns
(data, stratum, stratum-block, stratum-compute), or
createStorageClass would register the class stratum-compute, the
OS disk’s class. The installer refuses the same names.
Nothing is created and no disk is touched.
INVALID_INPUT — a missing name or disks, or a pool or class
name that breaks the name rule. Both names are checked before any
disk is touched.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Each refusal has its own code, and the storage.pool.created
audit event records the same one.
POOL_ALREADY_EXISTS — the target node already has a pool with
this name, or the name is the install’s default pool. Nothing is
created and no disk is touched.
DISK_NOT_EMPTY — a disk is mounted, or carries a filesystem, an
LVM signature or a partition table, and forceWipe is not set.
Nothing is created.
NAME_TAKEN — the pool was created, but the storage class that
createStorageClass asked for has a name already in use. Register
the class under another name, or use the pool directly.
UNSUPPORTED — a driver other than lvm-thin, or no live driver
that can create pools.
CONFLICT — any other refusal by the volume manager, such as a
disk that is already a physical volume.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}