doumei9832 2018-09-27 14:01
浏览 126
已采纳

libvirt-go:如何为系统重启定义回调函数

I am currently writing a small program in go, which I would like to use later to start virtual machines. The VM's are all based on centos7.0. A kickstartfile is used to install the VM's according to the same scheme.

To use the function with the kickstartfile I have to activate the direct kernel boot. I pass the path to the kernel (vmlinuz), initrd (initrd.img) and the argements (ks=http://172.25.35.165/kvm-centos.ks).

After the installation the VM starts again via the kickstartfile, which leads to a permanent installation routine.

I'm now looking for an EventHandler that notifies my go program that the VM is being restarted. Then I could disable the kernel boot settings with the kickstartfile argument.

I have already tried with DomainEventRegister, but the event is not triggered. The libvirt-go package is also very poorly documented when it comes to event handling.

Does anyone know how I can set a CallbackFunction for reboot actions to disable the kernel boot settings after successfully installing the VM?

Here my go function:

// CreateDomain
func CreateDomain(domainCfg *libvirtxml.Domain, conn *libvirt.Connect) error {

  domainXML, err := domainCfg.Marshal()
  if err != nil {
    return err
  }

  domain, err := conn.DomainDefineXML(domainXML)
  if err != nil {
    return err
  }

  conn.DomainEventRegister(nil, func(c *libvirt.Connect, d *libvirt.Domain, event *libvirt.Event) {
    log.Println("Reboot")
  })

  err = domain.CreateWithFlags(libvirt.DOMAIN_NONE)
  if err != nil {
    return err
  }

  domainState, _, err := domain.GetState()

  for domainState == libvirt.DOMAIN_RUNNING {
    state, _, err := domain.GetState()
    if err != nil {
      return err
    }

    time.Sleep(time.Second * 10)
    log.Println(state)

    if state != libvirt.DOMAIN_RUNNING {
      break
    }

  }

  return nil
}
  • 写回答

1条回答 默认 最新

  • dounan9070 2018-09-27 19:41
    关注

    This is not the way you install an OS on a new VM.

    Instead, you should define the domain twice: first, with the installation configuration, and second, with the permanent configuration.

    First, you call conn.DomainDefineXML() with the installation configuration XML, then after you start it and it is running, you call the same function again with the permanent configuration XML. Because the domain already exists, the new configuration will replace the old, but the new configuration won't take effect until the domain shuts down.

    To fully make this work, you need to set <on_reboot>destroy</on_reboot> in the installation XML. This causes the VM to shut down when the installer reboots. You can then start it again and it will come up with your permanent configuration.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?