Proxmox VE is an open source, KVM-based virtualization system
Through the official API documentation, we can learn how to use the API to operate the virtual machine. Official document address:
https://pve.proxmox.com/pve-docs/api-viewer/
1. Certification
To operate on PVE, we must have permission. PVE implements authentication through "CSRFPreventionToken" and "PVEAuthCookie"
CSRFPreventionToken is submitted as a parameter
PVEAuthCookie is submitted as a cookie
Before using these two parameters, we need to obtain the information of these two parameters (testpve in the following is the node name)
curl -k -d "username=root@pam&password=xxxxx" https://10.x.x.x:8006/api2/json/access/ticket
The returned information is as follows:
{"data":{"ticket":"PVE:root@pam:61B2EC05::Y1uRp+iFUpcSTEQsE0M8FB3aQi7lpNO3gIxr/g7rJX6GOLSOshKv9WHsGTUD3huFS3C3kIt/S3tFpg34xqHWFpF5cRjyqyG66ca3h+9ag/wSGuKPt+SkagVJOFZ2nlroSy5pY8sCZu+q5XhwLhElGSJOG43dMUod4Fhc5U2jdRn52FV15dY9aC9ym3FNpxRuNPRorSQASDFASDFZXCZduhEpDMKsTiSYxE0Owwme5g+sNZ1LKbkX5mpM2QdlN183jLU/AVgXPAw5hLdEeZorojC7HcO8f7A4SvmBxRzMl4GbXJYvwc+IyqTM+mZ9oPJPBTgQb+MAEafisW5Vbg==","cap":{"sdn":{"Permissions.Modify":1,"SDN.Allocate":1,"SDN.Audit":1},"vms":{"VM.Config.Network":1,"VM.Config.Disk":1,"VM.Console":1,"VM.Snapshot":1,"VM.Allocate":1,"VM.Config.Memory":1,"VM.Monitor":1,"VM.Backup":1,"VM.Migrate":1,"VM.Clone":1,"VM.Config.Cloudinit":1,"VM.Snapshot.Rollback":1,"VM.Config.CDROM":1,"VM.Config.HWType":1,"VM.PowerMgmt":1,"VM.Audit":1,"Permissions.Modify":1,"VM.Config.CPU":1,"VM.Config.Options":1},"dc":{"SDN.Allocate":1,"SDN.Audit":1,"Sys.Audit":1},"access":{"Group.Allocate":1,"Permissions.Modify":1,"User.Modify":1},"storage":{"Datastore.AllocateTemplate":1,"Permissions.Modify":1,"Datastore.AllocateSpace":1,"Datastore.Audit":1,"Datastore.Allocate":1},"nodes":{"Sys.Console":1,"Sys.Modify":1,"Sys.Audit":1,"Sys.Syslog":1,"Permissions.Modify":1,"Sys.PowerMgmt":1}},"username":"root@pam","CSRFPreventionToken":"61B2EC05:FvQWERQWEQHDO3JTDNgaDFGDFxkl46YjDI"}}
We need to extract two parts from the returned information. The first part is PVEAuthCookie:
PVE:root@pam:61B2EC05::Y1uRp+iFUpcSTEQsE0M8FB3aQi7lpNO3gIxr/g7rJX6GOLSOshKv9WHsGTUD3huFS3C3kIt/S3tFpg34xqHWFpF5cRjyqyG66ca3h+9ag/wSGuKPt+SkagVJOFZ2nlroSy5pY8sCZu+q5XhwLhElGSJOG43dMUod4Fhc5U2jdRn52FV15dY9aC9ym3FNpxRuNPRorSQASDFASDFZXCZduhEpDMKsTiSYxE0Owwme5g+sNZ1LKbkX5mpM2QdlN183jLU/AVgXPAw5hLdEeZorojC7HcO8f7A4SvmBxRzMl4GbXJYvwc+IyqTM+mZ9oPJPBTgQb+MAEafisW5Vbg==
The second part is: CSRFPreventionToken
61B2EC05:FvQWERQWEQHDO3JTDNgaDFGDFxkl46YjDI
2. Submit GET/POST for operation. Let's take the query (GET) virtual machine status with ID 103 as an example:
Note: The query is generally GET, and the operation is POST
Pay attention to the writing method, the PVEAuthCookie in the submitted content should be in the form of "cookie:PVEAuthCookie=".
curl https://10.x.x.x:8006/api2/json/nodes/testpve/qemu/102/status/current -H "CSRFPreventionToken:61B2EC05:FvQWERQWEQHDO3JTDNgaDFGDFxkl46YjDI" -H "Cookie: PVE:root@pam:61B2EC05::Y1uRp+iFUpcSTEQsE0M8FB3aQi7lpNO3gIxr/g7rJX6GOLSOshKv9WHsGTUD3huFS3C3kIt/S3tFpg34xqHWFpF5cRjyqyG66ca3h+9ag/wSGuKPt+SkagVJOFZ2nlroSy5pY8sCZu+q5XhwLhElGSJOG43dMUod4Fhc5U2jdRn52FV15dY9aC9ym3FNpxRuNPRorSQASDFASDFZXCZduhEpDMKsTiSYxE0Owwme5g+sNZ1LKbkX5mpM2QdlN183jLU/AVgXPAw5hLdEeZorojC7HcO8f7A4SvmBxRzMl4GbXJYvwc+IyqTM+mZ9oPJPBTgQb+MAEafisW5Vbg==" -H "Content-Type: application/x-www-form-urlencoded" -k
The returned information is as follows:
{"data":{"netin":1992409179,"maxdisk":107374182400,"running-machine":"pc-i440fx-6.0+pve0","agent":1,"cpu":0.00208252476257264,"cpus":8,"pid":4629,"freemem":7214153728,"proxmox-support":{"pbs-masterkey":true,"pbs-dirty-bitmap-savevm":true,"pbs-dirty-bitmap":true,"pbs-dirty-bitmap-migration":true,"pbs-library-version":"1.2.0 (6e555bc73a7dcfb4d0b47355b958afd101ad27b5)","query-bitmap-info":true},"maxmem":8589934592,"ballooninfo":{"minor_page_faults":378853818,"max_mem":8589934592,"free_mem":7214153728,"major_page_faults":2311,"mem_swapped_in":0,"total_mem":8369123328,"mem_swapped_out":0,"actual":8589934592,"last_update":1639116905},"nics":{"tap103i0":{"netin":1992409179,"netout":3610439}},"name":"pve-vdi-manage","blockstat":{"ide2":{"rd_operations":26,"rd_merged":0,"rd_bytes":1056972,"failed_unmap_operations":0,"unmap_operations":0,"failed_rd_operations":0,"account_invalid":true,"flush_total_time_ns":0,"account_failed":true,"unmap_bytes":0,"idle_time_ns":5443695922019176,"rd_total_time_ns":4491153,"unmap_merged":0,"invalid_rd_operations":0,"flush_operations":0,"invalid_unmap_operations":0,"timed_stats":[],"failed_flush_operations":0,"wr_total_time_ns":0,"wr_highest_offset":0,"wr_merged":0,"wr_operations":0,"wr_bytes":0,"invalid_wr_operations":0,"unmap_total_time_ns":0,"invalid_flush_operations":0,"failed_wr_operations":0},"ide0":{"invalid_flush_operations":0,"unmap_total_time_ns":0,"failed_wr_operations":0,"wr_merged":0,"wr_operations":321858,"wr_bytes":2502272000,"invalid_wr_operations":0,"timed_stats":[],"wr_total_time_ns":40406772668,"failed_flush_operations":0,"wr_highest_offset":95623819264,"unmap_merged":0,"invalid_rd_operations":0,"flush_operations":150925,"invalid_unmap_operations":0,"account_failed":true,"idle_time_ns":17073158113,"unmap_bytes":0,"rd_total_time_ns":5821276744,"failed_rd_operations":0,"account_invalid":true,"flush_total_time_ns":24817618480,"failed_unmap_operations":0,"unmap_operations":0,"rd_operations":93758,"rd_merged":0,"rd_bytes":444012032}},"uptime":5443711,"ha":{"managed":0},"balloon":8589934592,"disk":0,"status":"running","running-qemu":"6.0.0","vmid":103,"netout":3610439,"diskwrite":2502272000,"qmpstatus":"running","spice":1,"diskread":445069004,"mem":1154969600}}
Since the command is too long, we will replace CSRFPreventionToken with $csrftoken and PVEAuthCookie with $token later
3. Clone the virtual machine
Before cloning a virtual machine, we need to prepare a virtual machine and convert it into a template. If the template is not converted, clone it in Full mode. If it is converted into a template, it can be cloned in Link and Full modes. Link and Full difference, please find it yourself. We operate in the way of Link here.
The image numbered 101 is cloned, and the virtual machine of 107 is cloned. and named testclone
curl -s -k -H "Content-Type: application/x-www-form-urlencoded" -H "Cookie:$cookie" -H "CSRFPreventionToken:$csrftoken" -d "newid=107&name=testclone&target=testpve" https://10.x.x.x:8006/api2/extjs/nodes/testpve/qemu/101/clone
The following information is returned to represent success:
{"data":"UPID:testpve:003D2A62:207404D3:61B2F443:qmclone:101:root@pam:","success":1}
Then query the specific status information through the query operation of (2), or view the specific information through the web page
As for starting the virtual machine, please find the API documentation by yourself, and you can start it by POST.
Five: Generate spice files.
curl -s -k -X POST -H "Content-Type: application/x-www-form-urlencoded" -H "Cookie:$cookie" -H "CSRFPreventionToken:$csrftoken" https://10.x.x.x:8006/api2/extjs/nodes/testpve/qemu/107/spiceproxy
If the virtual machine is not powered on, it cannot be generated. The tips are as follows:
{"data":null,"message":"VM 107 not running\n","success":0,"status":500}
If the virtual machine status is normal, the returned information is as follows:
{"data":{"release-cursor":"Ctrl+Alt+R","password":"43c43f09a18c9feafd0614ca6827764bc1a412a3","host-subject":"OU=PVE Cluster Node,O=Proxmox Virtual Environment,CN=testpve.xxx.xx","ca":"-----BEGIN CERTIFICATE-----\\nMIIFzTCCA7WgAwIBAgIUM+Jkh8wVnOvxPMOEVVqTFPTRWocwDQYJKoZIhvcNAQEL\\nBQAwdjEkMCIGA1UEAwwbUHJveG1veCBWaXJ0dWFsIEVudmlyb25tZW50MS0wKwYD\\nVQQLDCQwNjY1NTYwNS04NWFlLTQ0MTctOWYwNi1mMmFmNGVkNjU1NGIxHzAdBgNV\\nBAoMFlBWRSBDbHVzdGVyIE1hbmFnZXIgQ0EwHhcNMjEwOTE2MDg0MjI2WhcNMzEw\\nOTE0MDg0MjI2WjB2MSQwIgYDVQQDDBtQcm94bW94IFZpcnR1YWwgRW52aXJvbm1l\\nbnQxLTArBgNVBAsMJDA2NjU1NjA1LTg1YWUtNDQxNy05ZjA2LWYyYWY0ZWQ2NTU0\\nYjEfMB0GA1UECgwWUFZFIENsdXN0ZXIgTWFuYWdlciBDQTCCAiIwDQYJKoZIhvcN\\nAQEBBQADggIPADCCAgoCggIBAMozDSwtKDZ+2dGvca+Erz0/o4nNGbfzhLsAczI4\\nf4LR3bTJzdoJXRM66pNIWBaIMCPCotvzgajTBPq3of7nid2mpi/fRz2OOdLMeu7n\\nIyB1gfe9B5l13gCEwIL6g6LWNZPosHtFsqfo+xgTDUl+2L1MY1oFQX5H2xKJumbj\\nlsU1dUS3dTE2B6sOS7itxqPKxYw1MGNUmQq9tYcmMWiw+aqFRHrk3xquK4eIeHG3\\noXnLOztfgPy7KA5CbBigF775udhYFDjszIeybJN1mqROgJXacLSZxXoPWyb0+oXk\\n0k2bcNfNh2RSmxDmHB934lYIgZvFjR7SupnpmPFX1v9KD0xsSNWJc0S9eErrJYMe\\nLFb9AM5zWHEgtjt9UcXkIhARwJbteZb9P8uoQcCggVu8JSP2uFwggXrVzZhg9orG\\novOOgXYRarweCThZEaRhWZYvNOItyapvSgPuaaB0QD1s76VNblbwCOy1Z5SGQzgr\\ne3e3Anj/OXU7dufYfwkjfYIHEva2eiX9xpoPuAw7OXosQg0EV5Zl6pPbSXJD+2E7\\n8e8t5YS82QIlz1wXCdpkRPtn+48MvgI65E13dvW0R+DeEj6KghWSalxjJP6Gpq51\\nVlpFKsL3nMdIicU1qJmMifM8owE0/4QyenbDARnKjUm3Kvs4qHZDDQGZK7Uvgs7o\\nMjQNAgMBAAGjUzBRMB0GA1UdDgQWBBSyLqj9zDyYbiFgxgEFX6PoT984DDAfBgNV\\nHSMEGDAWgBSyLqj9zDyYbiFgxgEFX6PoT984DDAPBgNVHRMBAf8EBTADAQH/MA0G\\nCSqGSIb3DQEBCwUAA4ICAQCCgmq5YqqPk15T+mX4+HoDEFamwj9B1fSp6++C7nJj\\nKRU/UhitkcRMxDUhqvXkWfDelxhUrJyzy4Qlz3kgsfYaDLkgG0QGEfxXTGP+NFIs\\nLgruipe81iL+m31ta5E9C6qktMix4zIKI/IV643dB4CNs6+DySJWlXCr2a1a4tN1\\nUQdrulj2H8NXnKzqeUvSUuvZh5octe2ossBs8hwyAzhuyVkoJUXYxL+w69QfbU5L\\nOPf3JgMXKsWGXHN1UjfglUgJl5ye6ItEGUSqf8LKubfeUt2vH3QJfW9Wva8BW8hj\\nNbexsAC7At9Y9wpqJt6Gnr1Az7PcVL1EDev6kCXQniRA1sDA0toVTJUkKQfQqiA2\\nMN1zZZ1m245ykckGJaVQ2y2zpWuRVS9Ulu/8wVx8EyggObnS+KC/4shslbtK941B\\nyJJUhVfXHscnhipAwYqdtSNLG/xt9PId6CU/FVxSoCddAkH6c0KrExSjo0SN9V7F\\numj1+59+ra+OSEcYkMVhUUTfZnIawMJyK9SenMcIasN8JofxHA/sPpmuv0A0aOwF\\n9tf9PYroUtphb3q4EWrmyEDdHwsz+LqQPKGrsw0p3qe/YtoPBewc1uLUBHeoTwj0\\no7jSSXf7qFmBQLX0zscRPXNFfjSXyWtoaVjTCo/BLNxKv9TqHnXpsefvJbd9zlh9\\nzg==\\n-----END CERTIFICATE-----\\n","type":"spice","secure-attention":"Ctrl+Alt+Ins","delete-this-file":1,"title":"VM 107 - testclone","host":"pvespiceproxy:61b2f57f:107:testpve::b849a33661f4bbcb2222c5b614e0e2d735c74bab","tls-port":61002,"toggle-fullscreen":"Shift+F11","proxy":"http://10.x.x.x:3128"},"success":1}
Parse the return value and generate a text file suffixed with vv in the following format
Open this file in the form of spice client and virtviewer to connect to the virtual machine.
As someone may ask, what is the use of this? Then I give you a scenario: PVE-based Virtual Desktop Infrastructure. The point is free, free, free! ! !