luthermonson / go-proxmox Goto Github PK
View Code? Open in Web Editor NEWGo client with types and tests for the Proxmox-VE REST API
License: Apache License 2.0
Go client with types and tests for the Proxmox-VE REST API
License: Apache License 2.0
Hi,
thanks a lot for this great interface to proxmox!
I think that line 576 of Types.go shoud not read
type Tasks []*Tasks
but
type Tasks []*Task
best regards
Andy
Hi, I was trying to loop through proxmox.VirtualMachines
and when I use VirtualMachineConfig.Memory
field, it throws a panic error:
panic: runtime error: invalid memory address or nil pointer dereference
Here's the program snippet:
func showVMs(vm proxmox.VirtualMachines) {
for i := range vm {
fmt.Println(vm[i].VMID, vm[i].Name, vm[i].VirtualMachineConfig.Memory)
}
}
Any help would be appreciated! Thanks for this awesome API.
As part of capi provider for proxmox.
We need a way of unmounting the Cloud init ISO.
Hi there,
I was wondering if there is planning on implementing the rrddata Endpoint /api2/json/nodes/pve/qemu/<vmid>/rrddata
With that I also have another question, why is the VirtualMachine struct and several other structs that outdated? There are several elements missing. The Library still seems to be actively maintained and updated except for the described issue. Is this on purpose?
Thank you in advance! :)
we should do a similar create/start/stop/remove integration test like we do for containers but on a qemu virtual machine. perhaps when we get to the iso upload/management apis we figure out how to upload a small linux iso and boot a vm and see if it comes up.
Trying to do a disk import, as would be done using qm disk import
, but remotely using the API:
# qm disk import 100 /path/to/some/disk.qcow2 local-zfs
Not really seeing anything obviously correct for this, and nothing suitable is showing up in the official API viewer either as I look through it.
Anyone have suggestions? 😄
Hi!
Function Delete for VM fails with
runtime error: invalid memory address or nil pointer dereference
My code
ctx := context.Background()
// Use vm.Status != "stopped" because vm.IsStopped()/vm.IsRunning() always returns 'false'
if vm.Status != "stopped" {
task, err := vm.Stop(ctx)
if err != nil {
log.Error(err)
return err
}
status, completed, err := task.WaitForCompleteStatus(ctx, 10, 3, 5, 10)
if err != nil {
return err
}
if !status && !completed {
return fmt.Errorf("cannot stop vm %v", vmid)
}
}
task, err := vm.Delete(ctx)
if err != nil {
log.Error(err)
return err
}
status, completed, err := task.WaitForCompleteStatus(ctx, 10, 3, 5, 10)
if err != nil {
return err
}
if !status && !completed {
return fmt.Errorf("cannot delete vm %v", vmid)
}
vm.Stop works but vm.Delete fails
runtime error: invalid memory address or nil pointer dereference
/usr/lib/go/src/runtime/panic.go:261 (0x450ef7)
panicmem: panic(memoryError)
/usr/lib/go/src/runtime/signal_unix.go:861 (0x450ec5)
sigpanic: panicmem()
/home/snels/go/pkg/mod/github.com/luthermonson/[email protected]/virtual_machine.go:54 (0x940e5b)
(*VirtualMachine).HasTag: if v.VirtualMachineConfig.Tags == "" {
/home/snels/go/pkg/mod/github.com/luthermonson/[email protected]/virtual_machine.go:337 (0x943616)
(*VirtualMachine).deleteCloudInitISO: if v.HasTag(MakeTag(TagCloudInit)) {
/home/snels/go/pkg/mod/github.com/luthermonson/[email protected]/virtual_machine.go:324 (0x943436)
(*VirtualMachine).Delete: if ok, err := v.deleteCloudInitISO(ctx); err != nil || !ok {
/home/snels/git/pve-api-gateway/pkg/pve/vm.go:542 (0x952464)
deleteVM: task, err := vm.Delete(ctx)
Am I doing something wrong or is the problem in the module?
Hello,
The api endpoint for /cluster/backup seems to be missing, the one in node/vzdump doesn't take schedule argument, am i missing something ?
Thank you.
Starting this issue with the full disclosure that I know enough Go and enough Proxmox to be dangerous, but not much more than that.
It seems that the VirtualMachine
type is written in such a way that it is not necessarily expected to always get a value for QMPStatus:
QMPStatus string `json:"qmpstatus,omitempty"`
But the VirtualMachine.IsRunning()
and VirtualMachine.IsStopped()
functions (and likely others) essentially require QMPStatus to be set to work.
func (v *VirtualMachine) IsRunning() bool {
return v.Status == StatusVirtualMachineRunning && v.QMPStatus == StatusVirtualMachineRunning
}
As such (for reasons not clear to me), I have VMs on my Proxmox server that are not returning anything for QMPStatus, so IsRunning()
always returns false
despite the fact that the VMs are running.
Should this be checking for empty values before comparing QMPStatus? If so, I am willing to try to make a PR for that. I Just wanted to make sure I'm not misunderstanding what is happening before I attempt that.
Thanks!
Add endpoints to create and delete containers and add tests to create, start/stop and remove a container. maybe for this we use nginx base container and check for 200OK + welcome to nginx text. check out docker run -d --name nginx -p 8081:80 --restart=always nginx
and what it boots on localhost:8081 and just test for that
The first Container funcs were created before UPID/Tasks were done so it used a ContainerStatus struct, this was changed to a string now but should ultimately be the UPID/Task system with a func profile looking similar to this...
func (c *Container) Start(ctx context.Context) (task *Task, err error)
func (c *Container) Stop(ctx context.Context) (task *Task, err error)
func (c *Container) Suspend(ctx context.Context) (task *Task, err error)
func (c *Container) Reboot(ctx context.Context) (task *Task, err error)
func (c *Container) Resume(ctx context.Context) (task *Task, err error)
func (c *Container) Shutdown(ctx context.Context, force bool, timeout int) (task *Task, err error)
Hello, thanks for making great proxmox-sdk. I see that, containter interfaces function is commented out.
For me running proxmox version 8.1.4
, the api path /nodes/%s/lxc/%d/interfaces
, works correctly:
curl --location 'https://192.168.1.254:8006/api2/json/nodes/pve1/lxc/700/interfaces' \
--header "Authorization: $API_TOKEN" --insecure
{"data":[{"inet":"127.0.0.1/8","hwaddr":"00:00:00:00:00:00","name":"lo","inet6":"::1/128"},{"inet6":"fe80::be24:11ff:fe89:6707/64","name":"eth0","hwaddr":"bc:24:11:89:67:07","inet":"192.168.3.95/22"}]}
Is there any way of uncommenting this function?
Hi!
How to define storage for CloudInit function?
I'm trying to use context.WithValue something like
isoStorage, _ := node.StorageISO(context.Background())
ctxISO := context.WithValue(ctx, &isoStorage.Name, "templates")
target.CloudInit(ctxISO, "ide0", vm.CloudInit.UserData, "", "", vm.CloudInit.NetworkData)
but without success.
What am I doing wrong?
Hey, Ive been trying this for at least 6hs now and cant really wrap my head around it. Ive created two very basic cloudinit files as strings (just metadata and the cloudinit file, the rest should be optional after checking the code).
It keeps returning unexpected end of JSON input despite being valid yaml. Ive also tried just passing JSON directly, but this also fails with the same issue.
Also, there is no real documentation of what device should be.
I have tried numerous values but that does not affect the end result.
// Define the cloud-init configuration strings
userdata := `
#cloud-config
users:
- name: default
`
metadata := `
instance-id: iid-123456
`
device := "ide2"
// Call the CloudInit method
err = createdVM.CloudInit(ctx, device, userdata, metadata, "", "")
Hi,
I'm having issues using this client implementation of qemu Clone
and MoveDisk
.
MoveDisk
seems focused on moving disks between storage backends and forces the use of the optional storage
parameter, whereas I would like to use it to move disks from one VM to another while keeping the same storage backend, for which I need the optional parameters format
, target-disk
and target-vmid
.
Clone
has similar issues and forces the usage of the target
optional parameter even though it only works with shared storage backends. I'm using local ZFS pools with templates in the local filesystem, and thus needs the full
, storage
and format
optional parameters instead.
I could do a PR implementing all this while keeping the current optional parameters, but as those methods are using hardcoded args, this either means duplicating methods or breaking API compatibility, and I would like to ask for opinions on this subject first.
I forgot to specify that it would came from string.
https://$PROXMOX_NODE_IP:8006/api2/json/nodes/$PROXMOX_NODE_NAME/qemu/$VMID/config
{
"data": {
"cores": 2,
"name": "minha-nova-vps",
"bootdisk": "scsi0",
"net0": "virtio=5A:95:56:B3:18:1C,bridge=vmbr0",
"vga": "serial0",
"ipconfig0": "gw=192.168.0.1,ip=192.168.0.154/24",
"memory": 2048,
"smbios1": "uuid=5059a66c-23d5-461b-a3cb-004eb3124718",
"boot": "c",
"scsihw": "virtio-scsi-pci",
"serial0": "socket",
"ide2": "local-lvm:vm-505-cloudinit,media=cdrom,size=4M",
"meta": "creation-qemu=7.2.0,ctime=1691463271",
"cipassword": "**********",
"agent": "enabled=1,fstrim_cloned_disks=1",
"vmgenid": "d4443aa6-b66f-45b2-97ff-6dee78eade44",
"ciuser": "root",
"cpulimit": "0.4",
"digest": "aa9ce37c4df320889d4ab5382a2947efa4c1d815",
"scsi0": "local-lvm:vm-505-disk-0,size=60G"
}
}
I actually didn't know about that, I learned if from here https://stackoverflow.com/a/9573928
I should have mapped something like this
CPULimit float32 `json:"cpulimit,omitempty,string"`
This time I actually tested, sorry for the trouble!
Hello! I've been experimenting with VNCProxy and encountered a crash at this specific line in the code: proxmox.go#L328. It appears that this functionality might not have been thoroughly tested, leading me to wonder if it was intended to work at all.
Is it possible that VNCProxy wasn't supposed to work in this context?
Hello,
I'm trying to pull RRDDatas for a vm with go-proxmox, however the data are not complete :
metrics, err := vm.RRDData(context.Background(), proxmox.TimeframeHour)
returns :
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706343600}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706343660}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706343720}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706343780}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706343840}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706343900}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706343960}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344020}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344080}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344140}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344200}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344260}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344320}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344380}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344440}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344500}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344560}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344620}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344680}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344740}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344800}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344860}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344920}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706344980}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706345040}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706345100}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706345160}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706345220}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706345280}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706345340}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706345400}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706345460}
[00] &{MaxCPU:1 MaxMem:1073741824 Disk:0 MaxDisk:16106127360 Time:1706345520}
The datas are always the same as it only returns the "max" and there is a lot of stuff missing. If i compare it to :
pvesh get /nodes/mtl1/qemu/138/rrddata --timeframe=hour --output-format=json
which returns :
{"cpu":0.124238321859991,"disk":0,"diskread":0,"diskwrite":4724.05333333333,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432397243.733333,"netin":9832.04666666667,"netout":14.38,"time":1706344620},{"cpu":0.125377080353475,"disk":0,"diskread":0,"diskwrite":4614.82666666667,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432381952,"netin":10647.8133333333,"netout":22.1066666666667,"time":1706344680},{"cpu":0.12763936071886,"disk":0,"diskread":0,"diskwrite":2962.77333333333,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432391782.4,"netin":11070.2933333333,"netout":29.5333333333333,"time":1706344740},{"cpu":0.127307933001489,"disk":0,"diskread":0,"diskwrite":8246.61333333333,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432372121.6,"netin":10695.0533333333,"netout":21,"time":1706344800},{"cpu":0.124545909511637,"disk":0,"diskread":0,"diskwrite":3126.61333333333,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432392874.666667,"netin":10415.1266666667,"netout":13.0266666666667,"time":1706344860},{"cpu":0.127210656369903,"disk":0,"diskread":0,"diskwrite":4246.18666666667,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432387413.333333,"netin":10518.0533333333,"netout":22,"time":1706344920},{"cpu":0.125842717200846,"disk":0,"diskread":0,"diskwrite":3481.6,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432383044.266667,"netin":10762.5466666667,"netout":12.16,"time":1706344980},{"cpu":0.128401595234267,"disk":0,"diskread":0,"diskwrite":5939.2,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432385228.8,"netin":11247.9966666667,"netout":18.68,"time":1706345040},{"cpu":0.125352078722909,"disk":0,"diskread":0,"diskwrite":4191.57333333333,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432388505.6,"netin":11359.26,"netout":22.3133333333333,"time":1706345100},{"cpu":0.12693991896238,"disk":0,"diskread":0,"diskwrite":4355.41333333333,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432388505.6,"netin":11301.52,"netout":25.18,"time":1706345160},{"cpu":0.126816451857934,"disk":0,"diskread":0,"diskwrite":5256.53333333333,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432386321.066667,"netin":11869.2633333333,"netout":18.84,"time":1706345220},{"cpu":0.126811605527418,"disk":0,"diskread":0,"diskwrite":2594.13333333333,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432388505.6,"netin":11374.6933333333,"netout":15.42,"time":1706345280},{"cpu":0.124099103732564,"disk":0,"diskread":0,"diskwrite":0,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432398336,"netin":10737.1366666667,"netout":22.3233333333333,"time":1706345340},{"cpu":0.124497920960517,"disk":0,"diskread":0,"diskwrite":286.72,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432398336,"netin":10998.5666666667,"netout":20.82,"time":1706345400},{"cpu":0.125006141203898,"disk":0,"diskread":0,"diskwrite":54.6133333333333,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432397243.733333,"netin":11047.36,"netout":16.38,"time":1706345460},{"cpu":0.124747998571836,"disk":0,"diskread":0,"diskwrite":0,"maxcpu":1,"maxdisk":16106127360,"maxmem":1073741824,"mem":432392874.666667,"netin":11656.4733333333,"netout":20.14,"time":1706345520}]
Here we have a lot more informations :
cpu, diskread, diskwrite, mem, netin, netout
Would it be possible to add the rest of the data instead of only MaxCPU, MaxMem, Disk and MaxDisk ?
Let me know if i'm missing something.
After checking it seems it have been added in this PR: #87
but it haven't made it's way to main ? I can't seem to have access to the branch "vm-updates".
and do the marshalling in the Post/Put methods instead of repeating code in the different call wrappers
After getting the termproxy and vncwebsocket end points working I've run into something with virtual machines which I will document here for others to see. The basics are you need a serial terminal for the websocket to work properly. You will need to add a serial0: socket
config to the VM like this
task, err = vm.Config(
VirtualMachineOption{Name: "serial0", Value: "socket"},
)
if you do not have the interface setup your proxy will return unable to find a serial interface
. When you have the socket seriali interface configured you will see the following starting serial terminal on interface serial0
.
Just adding the interface is not everything, you will need to follow the guide to configure the guest Virtual Machine actually use it, ideally this can be documented on how to setup cloud-init or ignition to bootstrap the serial0 socket device properly and move to a wiki how-to guide.
Hi,
VirtualMachines returns an error when there is a halted vm in node.
it's pid is null, thus does not pass isFloat pattern check in types.go
I temporarily modified it to return nil, but would be nice to handle this situation.
kudos for your work and providing this api impl
Hi Luther,
I had been moving forward using the library :) thanks a lot for it
I have a question regarding the VNC ticket. I can see here
https://github.com/luthermonson/go-proxmox/blob/main/proxmox.go#L196
the function VNCWebSocket receive a vnc argument, which seems to be a struct containing the vnc.Ticket and vnc.User.
Where are the VNC calls in the code? I had been searching but it seems am little bit blind.
I want to use it in order to access noVNC console from a reactjs app.
thanks in advance,
Shouldn't cpulimit be float32? I have set mine to 0.4 to give my VM a fraction of my CPU Core? It works on proxmox but the go-proxmox API cannot unmarshal it.
[Edit]
In the documentation https://pve.proxmox.com/wiki/Qemu/KVM_Virtual_Machines it says
...
...Resource Limits...
With the cpulimit (“Host CPU Time”) option you can limit how much CPU time the whole VM can use on the host. It is a floating point value representing CPU time in percent, so 1.0 is equal to 100%, 2.5 to 250% and so on.
...
This looks like a really promising library, thank you for sharing it.
Looking over the PVE API and the functionality implemented in the library. I was thinking the following enhancements would be helpful:
node.NewContainer()
POST
to /nodes/{node}/lxc
node.Container()
to include container.Config
This shouldn't break the existing API and bring it in line with existing VirtualMachine behavior. It would also complete CRUD functionality for PVE containers.
Would like to try and offer support for taking a cloud-config and metadata file as string and then auto-generate an iso, upload it and then mount it before booting to get caught in the no-cloud boot options for cloud-init. See code I wrote for the (vsphere machine driver)[https://github.com/rancher/machine/blob/master/drivers/vmwarevsphere/cloudinit.go#L128-L202] and see if we can get full support for cloud-init using this as it would greatly improve the machine driver as well as a terraform module if we decide.
Just note... as per some things we came across with while doing the vsphere driver...
Hi,
I'm not sure if there's something I'm overlooking — maybe the IntOrBool type in the same file is relevant here? But I think this should accept a bool
proxmox offers a tunnel into everything via a termproxy end point and a websocket. the UI seems to make a call to termproxy, grab a ticket and then issue a websocket call to tunnel in. we should figure out how to get the socket started and tunnel into the node, vms and containers so we can tunnel in and run shell commands against them.
figure out how to get qcow2 images down onto a node and booted and usable through single point of entry function. this is a good test too for cloud-init as the openstack jeos image supports cloud-init. so wrap up a single test in grabbing qcow2 + booting and testing cloud init.
I think It's time to plan for the first release v0.1.0
The title of this Issue is probably a little unclear what I mean. But as an example, take the function to request a node's version details:
Line 24 in 0a31b09
This API method requires me to make a request to Node(ctx, nodeName)
and then make the request to get the VE node's version from the Node struct that it returned. So, I'm making 2 API requests to get that version data, when I could do this in 1 API request if the method took a node name string instead.
I see the design decision, but I don't think it's a good assumption that I'm always going to care about all the output from Node(...)
when I want the data from Version(...)
. For example, maybe I just made a request to Nodes(ctx)
, got my list of nodes (and their names) and now just want to hit the Version method, or maybe I know my node names some other way (I did name them in the first place.)
The Node/Version API method issue is just one example, that design decision with that assumption is seen across many other API methods in this library.
I actually wrote my own library for a PVE prometheus metrics exporter product I work on partially because of this constraint, but it's maybe something to think about here, since your library has more users it services.
Hi friends,
I had been trying this module and it is great.
I just have a question regarding the Ping() method. As far as I can see it returns an error if occurred.
But I had in mind that i could be useful(for me) to get the actual current information from the VM. Is there another method similar to ping that can bring the current state with its full body?
I had a look at the endpoint we are sending the request and it has different kind of information I would like to use
https://pve.proxmox.com/pve-docs/api-viewer/#/nodes/{node}/qemu/{vmid}/status/current
or is there a way to get the body of that request?
hope my question is understandable and if you need more info I can provide it
thanks in advance!
Wouldn't it be easier to always convert to the Uint64 type ?
Node:json: cannot unmarshal number 42268934144 into Go struct field Ksm.Ksm.Shared of type int
happens on: node, err := client.Node("xxxx")
It seems that the KSM shared value is too big..
While deleting a container, there is a force option that allows a deletion even if the container is running. Please expose this to the Delete()
function
https://github.com/luthermonson/go-proxmox/blob/main/containers.go#L32
Reference:
https://pve.proxmox.com/pve-docs/api-viewer/index.html#/nodes/{node}/lxc/{vmid}
After adding the iso the first time, the second run fails:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x8 pc=0x104837bb0]
goroutine 1 [running]:
github.com/luthermonson/go-proxmox.(*Task).Ping(0x0)
/Users/mbenjemaa/workspace/go/pkg/mod/github.com/luthermonson/[email protected]/tasks.go:39 +0x20
github.com/luthermonson/go-proxmox.(*Task).Wait(0x0, 0x3b9aca00, 0x77359400)
/Users/mbenjemaa/workspace/go/pkg/mod/github.com/luthermonson/[email protected]/tasks.go:145 +0x2c
github.com/luthermonson/go-proxmox.(*Task).WaitFor(...)
/Users/mbenjemaa/workspace/go/pkg/mod/github.com/luthermonson/[email protected]/tasks.go:140
github.com/luthermonson/go-proxmox.(*VirtualMachine).CloudInit(0x140001980e0, {0x104844d81, 0x4}, {0x10485df67, 0x1ed}, {0x10485df67, 0x1ed})
/Users/mbenjemaa/workspace/go/pkg/mod/github.com/luthermonson/[email protected]/virtual_machine.go:149 +0x1a8
Useful for knowing if a VM supports Spice.
https://pve.proxmox.com/pve-docs/api-viewer/index.html#/nodes/{node}/qemu/{vmid}/status/current
Not a big deal since custom structs work in client.Get(). More of a convenience.
I'm trying to create a VM with a cloud-init ssh key, but the server keeps on returning 500 SSH public key validation error
. 😕
It seems pretty weird, as the exact same key works fine when using qm
on the server itself to create the VM.
The code in question for creating the VM:
vmProps := []proxmox.VirtualMachineOption{
{Name: "name", Value: "test1"},
{Name: "memory", Value: 1024 * 8},
{Name: "cores", Value: 6},
{Name: "cpu", Value: "host"},
{Name: "net0", Value: "model=virtio,bridge=" + publicBridge + ",firewall=1"},
{Name: "scsihw", Value: "virtio-scsi-single"},
{Name: "virtio1", Value: "local-zfs:16,cache=" + cacheMode + ",discard=on,iothread=1"},
{Name: "agent", Value: 1},
{Name: "ostype", Value: "l26"},
{Name: "localtime", Value: "0"},
{Name: "ide0", Value: "local-zfs:cloudinit"},
{Name: "ipconfig0", Value: "gw=10.1.1.1,ip=10.1.248." + strconv.Itoa(vmID) + "/16"},
{Name: "sshkeys", Value: url.QueryEscape("/root/.ssh/id_rsa.pub")},
}
vmTask, err := node.NewVirtualMachine(ctx, vmID, vmProps...)
if err != nil {
log.Fatal(err)
}
If I remove that last vmProps line (the sshkeys
one), then the vm creation works. With that in place though, I'm getting:
2024/04/30 04:12:44 500 SSH public key validation error
The working qm
version of it:
# Create a new VM
qm create ${VMID} --name "test1" \
--cpu host \
--cores 6 \
--memory 8192 \
--net0 virtio,bridge=${PUBLIC_BRIDGE},firewall=1 \
--scsihw virtio-scsi-single \
--virtio1 local-zfs:16,cache=${CACHE_MODE},discard=on,iothread=1 \
--agent 1 \
--ostype l26 \
--localtime 0 \
--ide0 local-zfs:cloudinit \
--ipconfig0 gw=10.1.1.1,ip=10.1.248.${VMID}/16 \
--sshkeys "~/.ssh/id_rsa.pub"
Anyone have ideas what could be going wrong?
Hi there! I'm currently developing a middleware in Go that interfaces between Proxmox and a web console. In the frontend, I'm utilizing xtermjs. However, I've encountered an issue where a line break is added after every key sent to Proxmox, disrupting the seamless usage of xtermjs.
Here's the relevant code snippet where the issue occurs: proxmox.go#L436
It seems that the current implementation is designed to send complete commands, but I'd prefer a solution where every character, including line breaks, can be sent individually. This would enable smoother interaction with xtermjs, allowing even backspace functionality to work seamlessly.
Text enhanced by ChatGPT.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.