Golang libvirt客户机代理不可用

huangapple go评论77阅读模式
英文:

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:&quot;exitcode,omitempty&quot;`
		OutData  string `json:&quot;out-data,omitempty&quot;`
		Exited   bool   `json:&quot;exited,omitempty&quot;`
		ErrData  string `json:&quot;err-data,omitempty&quot;`
	} `json:&quot;return,omitempty&quot;`
}

func (l *LibvirtInstance) waitForCompletion(ctx context.Context, pid int, domain *libvirt.Domain) (response *qemuStatusResponse, err error) {
	response = &amp;qemuStatusResponse{}

	ticker := time.NewTicker(500 * time.Millisecond)
	defer ticker.Stop()
	for {
		select {
		case &lt;-ticker.C:
			result, err := domain.QemuAgentCommand(
				fmt.Sprintf(`
				{
					&quot;execute&quot;: &quot;guest-exec-status&quot;,
					&quot;arguments&quot;: {
						&quot;pid&quot;: %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 &lt;-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.

huangapple
  • 本文由 发表于 2022年12月2日 07:18:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/74649202.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定