英文:
Golang libvirt guest-agent not available
问题
我已经尝试通过libvirt golang API与qemu实例上的客户代理进行通信。然而,它总是拒绝我的连接:
2022-12-02T00:10:43.799+0100 DPANIC test/main.go:335 Failed to connect to guest {"error": "virError(Code=86, Domain=10, Message='Guest agent is not responding: QEMU guest agent is not connected')"}
即使qemu实例已经完全启动,并且通过命令行可以访问客户代理:
sudo virsh qemu-agent-command test-vm '{"execute":"guest-info"}'}
这是实现中的一个错误吗?还是我需要在go代码中注册代理?我在文档中没有找到相关的参考。
<channel type='unix'>
<source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-6-test-vm/org.qemu.guest_agent.0'/>
<target type='virtio' name='org.qemu.guest_agent.0' state='connected'/>
<alias name='channel0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
谢谢!
英文:
I've tried to communicate with the guest agent on a qemu instance through the libvirt golang API. However, it always reject my connections with
2022-12-02T00:10:43.799+0100 DPANIC test/main.go:335 Failed to connect to guest {"error": "virError(Code=86, Domain=10, Message='Guest agent is not responding: QEMU guest agent is not connected')"}
Even if the qemu instance is fully booted and the guest agent is available through the commandline
sudo virsh qemu-agent-command test-vm '{"execute":"guest-info"}'
Is this a bug in the implementation or do I have to register the agent somewhere in the go code? I wasn't able to find references in the documentation.
<channel type='unix'>
<source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-6-test-vm/org.qemu.guest_agent.0'/>
<target type='virtio' name='org.qemu.guest_agent.0' state='connected'/>
<alias name='channel0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
Thanks!
答案1
得分: 0
最终原因不确定。我有一个循环,并且正在访问(或更具体地说,尝试访问)代理。我将其更改为使用500毫秒的超时,现在它可以工作了。
type qemuStatusResponse struct {
Return struct {
Exitcode int `json:"exitcode,omitempty"`
OutData string `json:"out-data,omitempty"`
Exited bool `json:"exited,omitempty"`
ErrData string `json:"err-data,omitempty"`
} `json:"return,omitempty"`
}
func (l *LibvirtInstance) waitForCompletion(ctx context.Context, pid int, domain *libvirt.Domain) (response *qemuStatusResponse, err error) {
response = &qemuStatusResponse{}
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
for {
select {
case <-ticker.C:
result, err := domain.QemuAgentCommand(
fmt.Sprintf(`
{
"execute": "guest-exec-status",
"arguments": {
"pid": %d
}
}`, pid),
libvirt.DOMAIN_QEMU_AGENT_COMMAND_BLOCK, 0)
if err != nil {
return nil, err
}
if err := json.Unmarshal([]byte(result), response); err != nil {
return nil, err
}
if response.Return.Exited {
return response, nil
}
case <-ctx.Done():
return nil, ctx.Err()
}
}
}
此外,我遇到了一些稳定性问题(即,在对连接执行多个并发请求时,有时会中断连接)。我在网上找到了一篇文章,建议将用户添加到"kvm"组中。这对我起作用了。
英文:
Not sure what was the cause in the end. I had a loop and was accessing, or to be more specific try to access, the agent. I changed it to use a timeout of 500ms and not it works.
<!-- language: lang-go -->
type qemuStatusResponse struct {
Return struct {
Exitcode int `json:"exitcode,omitempty"`
OutData string `json:"out-data,omitempty"`
Exited bool `json:"exited,omitempty"`
ErrData string `json:"err-data,omitempty"`
} `json:"return,omitempty"`
}
func (l *LibvirtInstance) waitForCompletion(ctx context.Context, pid int, domain *libvirt.Domain) (response *qemuStatusResponse, err error) {
response = &qemuStatusResponse{}
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
for {
select {
case <-ticker.C:
result, err := domain.QemuAgentCommand(
fmt.Sprintf(`
{
"execute": "guest-exec-status",
"arguments": {
"pid": %d
}
}`, pid),
libvirt.DOMAIN_QEMU_AGENT_COMMAND_BLOCK, 0)
if err != nil {
return nil, err
}
if err := json.Unmarshal([]byte(result), response); err != nil {
return nil, err
}
if response.Return.Exited {
return response, nil
}
case <-ctx.Done():
return nil, ctx.Err()
}
}
}
Furhtermore I had some stability issues (i.e., when executing multiple concurrent requests to the connection it was sometimes broken). I found some article in the web suggesting adding the user to the kvm
group. This worked for me.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论