package host import ( "fmt" "log" "git.staur.ca/stobbsm/clustvirt/lib/guest" "libvirt.org/go/libvirt" ) // Host holds information and acts as a connection handle for a Host // If a connection is closed prematurely, will re-open the connection and // try the attempted method again type Host struct { HostName string conn *libvirt.Connect close chan struct{} closeErr chan error } // ConnectHost creates a host connection wrapper that can be used regularly func ConnectHost(host string) (*Host, error) { h := &Host{ HostName: host, } if err := h.connect(); err != nil { return nil, err } h.close = make(chan struct{}) h.closeErr = make(chan error) go func() { defer close(h.closeErr) <-h.close _, err := h.conn.Close() h.closeErr <- err }() return h, nil } // connect creates a host connection func (h *Host) connect() error { var err error h.conn, err = libvirt.NewConnect( fmt.Sprintf("qemu+ssh://%s/system", h.HostName), ) return err } // GetGuestByName returns a GuestVM instance that exists on the given host func (h *Host) GetGuestByName(name string) (*guest.VM, error) { g, err := guest.GetGuest(name, h.conn) if err == nil { return g, nil } lverr, ok := err.(libvirt.Error) if ok && lverr.Code == libvirt.ERR_INVALID_CONN { // try again after creating a new connection return guest.GetGuest(name, h.conn) } return nil, err } // Close triggers closing the host connection func (h *Host) Close() error { log.Println("Closing Host", h.HostName) close(h.close) return <-h.closeErr }