Attach to a server
POST/api/v1/volumes/{disk_uuid}/attach
Attaches the volume to a running server without a restart. The server sees a new disk, usually /dev/vdb; format and mount it the first time. A volume is on one server at a time.
Parameters
| Name | In | Description |
|---|---|---|
| disk_uuid | path, stringrequired | Volume id, from Create a volume or List volumes |
Request body
| Field | Type | Description |
|---|---|---|
| vm_uuid | stringrequired | Server id, from List VMs of the cloud VM API |
Example request
curl -X POST "https://platform.serverscamp.com/api/v1/volumes/$DISK_UUID/attach" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"vm_uuid": "6f1c2a9e-4b3d-4e8a-9c71-2d5e8f0a1b34"
}'import os, requests
token = os.environ["API_TOKEN"]
disk_uuid = "c7a1e3f9-52b8-4d06-9e41-8b3f2a6d0c75"
r = requests.post(
f"https://platform.serverscamp.com/api/v1/volumes/{disk_uuid}/attach",
headers={"Authorization": f"Bearer {token}"},
json={
"vm_uuid": "6f1c2a9e-4b3d-4e8a-9c71-2d5e8f0a1b34"
},
)
r.raise_for_status()
print(r.json())const diskUuid = 'c7a1e3f9-52b8-4d06-9e41-8b3f2a6d0c75';
const r = await fetch(`https://platform.serverscamp.com/api/v1/volumes/${diskUuid}/attach`, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.API_TOKEN}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
"vm_uuid": "6f1c2a9e-4b3d-4e8a-9c71-2d5e8f0a1b34"
}),
});
console.log(r.status, await r.json());Answer
Status 200 with this body.
| Field | Type | Description |
|---|---|---|
| disk_uuid | stringrequired | |
| vm_uuid | stringrequired | The server it goes to |
| status | stringrequired | attach_queued: poll Get a volume until vm_uuid is set and the state settles |
{
"disk_uuid": "c7a1e3f9-52b8-4d06-9e41-8b3f2a6d0c75",
"vm_uuid": "6f1c2a9e-4b3d-4e8a-9c71-2d5e8f0a1b34",
"status": "attach_queued"
}Wait until it is ready
The answer comes at once and the work runs in the background, usually for a few seconds. Get a volume shows how far it got in its state field.
Check the state
Ask Get a volume with the volume's id; the field to watch is state:
curl "https://platform.serverscamp.com/api/v1/volumes/$DISK_UUID" \
-H "Authorization: Bearer $API_TOKEN"| state | What it means |
|---|---|
creating | The volume is being made; one from a backup also shows provision_phase and provision_pct |
created | Ready. With vm_uuid set it is attached to that server, without it the volume is free |
attaching, detaching, resizing | The change runs |
failed | Something went wrong. Write to support with the volume id |
Wait in a loop
Ask every few seconds until the state is no longer one of the busy ones, and stop on failed.
# DISK_UUID: disk_uuid of the volume, from the answer above
BUSY=" pending queued creating provisioning attaching attach_queued detaching detach_queued resizing deleting deprovisioning delete_queued "
while true; do
VOL=$(curl -s "https://platform.serverscamp.com/api/v1/volumes/$DISK_UUID" -H "Authorization: Bearer $API_TOKEN")
STATE=$(echo "$VOL" | jq -r .state)
echo "$STATE"
case "$STATE" in failed|error) echo "volume $STATE"; exit 1;; esac
case "$BUSY" in *" $STATE "*) ;; *) [ "$(echo "$VOL" | jq -r '.provision_phase // "ready"')" = ready ] && break;; esac
sleep 5
done# disk_uuid: disk_uuid of the volume, from the answer above
import os, time, requests
headers = {"Authorization": f"Bearer {os.environ['API_TOKEN']}"}
busy = {"pending", "queued", "creating", "provisioning", "attaching", "attach_queued", "detaching", "detach_queued", "resizing", "deleting", "deprovisioning", "delete_queued"}
while True:
vol = requests.get(f"https://platform.serverscamp.com/api/v1/volumes/{disk_uuid}", headers=headers).json()
print(vol["state"])
if vol["state"] in ("failed", "error"):
raise SystemExit("volume " + vol["state"])
if vol["state"] not in busy and (vol.get("provision_phase") or "ready") == "ready":
break
time.sleep(5)// diskUuid: disk_uuid of the volume, from the answer above
const headers = { Authorization: `Bearer ${process.env.API_TOKEN}` };
const busy = new Set(['pending', 'queued', 'creating', 'provisioning', 'attaching', 'attach_queued', 'detaching', 'detach_queued', 'resizing', 'deleting', 'deprovisioning', 'delete_queued']);
for (;;) {
const vol = await (await fetch(`https://platform.serverscamp.com/api/v1/volumes/${diskUuid}`, { headers })).json();
console.log(vol.state);
if (vol.state === 'failed' || vol.state === 'error') throw new Error('volume ' + vol.state);
if (!busy.has(vol.state) && (vol.provision_phase ?? 'ready') === 'ready') break;
await new Promise((ok) => setTimeout(ok, 5000));
}The bash version needs jq.
Errors
| Status | When |
|---|---|
401 | No token, or a token that is not valid |
404 | No such volume or server in your account |
409 | The volume is attached already, or busy |
422 | The body or a parameter is not what the operation takes |
Every operation can also answer 401 without a valid token. All errors