clustvirt/lib/host/host.go

72 lines
1.5 KiB
Go
Raw Normal View History

package host
import (
"fmt"
"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 {
close(h.close)
return <-h.closeErr
}