Hello!
Today I would like to talk a little bit about using the API of the notorious virtualization system - Proxmox.
Background ...
I encountered proksmox several years ago, when I got a good car in my hands, located in one of the data centers of the notorious Hetzner. At that time, we had a question about raising virtualization to our needs. We considered several options, namely: VMWare, OpenStack and of course Proxmox. I will not say that he is better than 2 other candidates, just at that moment he fully satisfied our needs. After some time, it became necessary to create a kind of control panel for third-party users who could simply monitor the status of their virtual machine, start / stop VMs, make reboot, and also manage several settings. Of course, Proxmocks allows you to add users, as well as groups of users and assign them your rights. But this option did not suit us. I don’t know how it is now, but at that time there was no normal Proxmox API documentation in Russian. This, of course, did not stop me, and I completely managed to do it in the
English version , in which, by the way, everything is very well and clearly described. However, there are always people who do not get along well with English. So, this article is for you.
At once I will make a reservation that all VMs (virtual machines) we had were based on KVM. Consequently, the API that we will consider in this article will be for KVM-based machines using PhP.
')
So, let's begin…
To work with their API, we need a PhP class that can be taken from
the github repository.The types of requests to the API server are divided into only 3 types: GET, POST and PUT. And we will receive answers in JSON format.
Create an index.php file in which we include the api class we downloaded and create an object.
require_once "proxmox.api.php"; $px = new PVE2_API("192.168.2.1", "root", "pam", "my_password");
where as parameters we specify the IP of our server, login and password.
By default, proxmox is set to port 8006. However, if you changed it, then you also have to change the port in the proxmox API class. To do this, we need to find lines like this: (There are 3 in total)
curl_setopt($prox_ch, CURLOPT_URL, "https://".$this->pve_hostname.":8006/api2/json/access/ticket");
I have 93 line. (At the time of downloading the class. Maybe now there are some changes. I did not check) and replace 8006 with the required value.
In order to check whether the authorization passed successfully on our server, use the following method:
if($px->constructor_success()){ if($px->login()){
Now we will try to fulfill our first request, which will give us information about the VM we are interested in. Each virtual machine has its own unique identification number, according to which we will receive information. Also, each VM can be located in its “node” (node), which also participates in the request.
if($px->constructor_success()){ if($px->login()){ $status = $px->get("/nodes/node2/qemu/100/status/current"); var_dump($status); } }
where: node2 is the name of the node I use, and 100 is the id of the VM.
As a result, we get about the following:
array(19) { ["disk"]=> int(0) ["status"]=> string(7) "running" ["ha"]=> int(0) ["freemem"]=> int(518893568) ["qmpstatus"]=> string(7) "running" ["netout"]=> int(214648283) ["maxdisk"]=> int(21474836480) ["maxmem"]=> int(3221225472) ["pid"]=> string(6) "526695" ["uptime"]=> int(2585643) ["balloon"]=> int(3221225472) ["cpu"]=> float(0.089612785396815) ["netin"]=> int(3038528849) ["diskread"]=> int(5224400988) ["template"]=> string(0) "" ["name"]=> string(15) "vds-192.168.1.9" ["diskwrite"]=> int(100378349568) ["mem"]=> int(2638614528) ["cpus"]=> int(1) }
To a greater degree, everything is clear here, so I will not comment, and we will go further.
In the previous example, where we received the status of our VM, we used a GET request. As a rule, GET is used to receive information, POST and PUT to perform some actions or change settings.
Now we will try to stop our virtual machine. To do this, send a POST request with vmid (virtual machine ID and node):
if($px->constructor_success()){ if($px->login()){ $px->post("/nodes/node2/qemu/192/status/shutdown", array("forceStop" => true)); } }
As you can see, everything is quite simple. The first parameter of the POST request is infa about our VM, and the second is some not always optional parameters. In this case, for clarity, I used the forceStop parameter, which speaks for itself. Sometimes there are times when a VM for some reason cannot complete its work "voluntarily." This can happen for various reasons, a system error, a hanging process, etc. So the forceStop parameter tells proxmox'u that the machine should complete its work anyway. A complete list of parameters can be found in the documentation provided.
Now we will start back our VM.
if($px->constructor_success()){ if($px->login()){ $start = $px->post("/nodes/node2/qemu/192/status/start"); } }
All available commands for VM statuses:
- reset - a kind of reboot
- resume - resumes VM
- shutdown - turns off the VM
- start - starts the VM
- stop - stops the VM
- suspend - suspends the work of the VM
Go to the settings ...
We get the settings of a specific VM, as usual:
if($px->constructor_success()){ if($px->login()){ $start = $px->get("/nodes/node2/qemu/166/config"); var_dump($start); } }
If everything is ok, we get the following result:
array(10) { ["net0"]=> string(36) "e1000=9A:7B:96:C7:C4:7D,bridge=vmbr0" ["ide2"]=> string(59) "local:iso/debian-6.0.7-amd64-CD-1.iso,media=cdrom,size=645M" ["name"]=> string(15) "san-192.168.1.9" ["bootdisk"]=> string(4) "ide0" ["cores"]=> int(1) ["ide0"]=> string(50) "local:166/vm-166-disk-1.qcow2,format=qcow2,size=1G" ["ostype"]=> string(3) "l26" ["memory"]=> int(512) ["sockets"]=> int(1) ["digest"]=> string(40) "2aa7fcf6cbaff2f11d2f50f1b7b18fc97d2b04d6" }
In order to install the VM configuration, you must use a PUT request:
if($px->constructor_success()){ if($px->login()){ $px->put("/nodes/node2/qemu/166/config", array( )); } }
where in the array you need to specify the necessary parameters and their value. I will not give all the parameters, as there are many of them and they are described in the official documentation. Please note that for some add-ins to take effect, a VM reboot is required.
Now a little more interesting. Sometimes there is a need to automate the process of creating virtual machines. I would like to talk about this in more detail in the next article, but for the most impatient, a small example now:
if($px->constructor_success()){ if($px->login()){ $d = array( 'vmid' => '777', 'memory' => '300', 'cores' => '2', 'autostart' => true, 'ostype' => 'l26', 'ide0' => 'local:32,format=qcow2', 'ide2' => 'local:iso/ubuntu-12.04.2-server-amd64.iso,media=cdrom', 'net0' => 'e1000,bridge=vmbr0' ); $px->post("/nodes/node2/qemu", $d); $px->post("/nodes/node2/qemu/777/status/start"); } }
Where:
- vmid - unique VM identifier
- memory - the type number (integer) indicates the size of RAM in megabytes.
- cores - number of vm cores
- autostart - (bool) initiate autostart VM
- ostype - OS type
- ide0 - HDD size and format. local: 32 - means 32GB
- ide2 - the path to the OS image and type of boot
- net0 - Network Adapter
That's all for now. In the next part, I would like to delve into the methods that I described above, as well as talk about some of the intricacies that I did not find in the API at that time.
PS Instead of just minus the article, take a bit of your time and describe what is wrong in it, what you didn’t like and what you would like to see more. This will allow me to understand my mistakes and not to commit them further.
Thanks for attention.