Skip to content

Scripting

cv4pve-cli is a plain command-line program: it never asks a question, prints its results on standard output and runs the same from a terminal, a cron job or a CI pipeline.

A script uses the current context, like a terminal. On a machine of its own (a CI runner, a management VM), create the context at the start, with the token taken from the secrets of the job:

cv4pve-cli config add ci --host=pve01.example.com,pve02.example.com --api-token="$PVE_TOKEN"
cv4pve-cli config use ci

The current context is stored in a file and shared by every shell of that user. Two scripts that run at the same time as the same user against different clusters switch the context under each other’s feet: run them as different users, or one after the other. The token is saved in clear text in the configuration file: see Where the credentials are stored.

-o json prints the rows of the answer as a JSON array on one line, for jq or any JSON parser:

# names of the running VMs and containers
cv4pve-cli api get /cluster/resources --type vm -o json \
| jq -r '.[] | select(.status == "running") | .name'

A list comes out as one object per item; an object as key / value pairs; a single value (a UPID, the next free VM ID) as it is, with no JSON around it. Values are those of the API: sizes in bytes, times in seconds or Unix time. -v prints the raw answer of Proxmox VE, {"data": …}. See Output.

Once a day cv4pve-cli checks GitHub for a newer release and, if there is one, prints a notice at the end of the output, only when the output goes to a terminal, never into a pipe or a file.

Code Meaning
0 Success
1 Any other error
2 Authentication or configuration: wrong token or password, no current context, a privilege missing (HTTP 401, 403)
3 Not found: a path, a guest, a context or an alias that does not exist (HTTP 404, 501)
4 Node unreachable or server error (HTTP 5xx); also config verify for any failed connection, wrong credentials included
5 A task ended with an error, or task wait timed out
6 Wrong input: a parameter Proxmox VE rejects (HTTP 400), an alias argument missing or in excess, an alias that needs --yes, task stop without --yes

Errors start with Error: and go to standard error, so standard output holds only results. When Proxmox VE refuses a call, the message also shows the call that was sent: see Troubleshooting.

if ! out=$(cv4pve-cli api get /nodes/pve01/status -o json); then
echo "failed with code $?" >&2
fi

A call that starts a task returns at once with its UPID. Add --wait to wait for the task: the exit code is 5 when it fails or --wait-timeout expires.

cv4pve-cli api create /nodes/pve01/qemu/100/snapshot --snapname "nightly-$(date +%F)" --wait --wait-timeout 900 \
|| echo "snapshot failed" >&2

To start now and check later, capture the UPID and use task wait or task log --follow.