import almost works

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2024-11-01 08:03:20 -05:00
parent 7fa6c2e2de
commit a10dab96ff
2 changed files with 65 additions and 37 deletions

View File

@ -4,48 +4,56 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"os"
"time" "time"
pb "go.wit.com/lib/protobuf/virtbuf" pb "go.wit.com/lib/protobuf/virtbuf"
"go.wit.com/lib/virtigolib" "go.wit.com/lib/virtigolib"
"go.wit.com/log" "go.wit.com/log"
// "libvirt.org/go/libvirt"
"libvirt.org/go/libvirtxml" "libvirt.org/go/libvirtxml"
) )
// attempts to create a new virtual machine // attempts to import the *libvirt.Domain directly from the hypervisor
func importDomain(w http.ResponseWriter, r *http.Request) (string, error) { func importDomain(w http.ResponseWriter, r *http.Request) (string, error) {
name := r.URL.Query().Get("domainName") domainName := r.URL.Query().Get("domainName")
if name == "" { if domainName == "" {
result := "importDomain() failed. name is blank " + r.URL.Path result := "importDomain() failed. name is blank " + r.URL.Path
log.Warn(result) log.Warn(result)
fmt.Fprintln(w, result) fmt.Fprintln(w, result)
return "", errors.New(result) return "", errors.New(result)
} }
log.Warn("importDomain() START name is", name)
fmt.Fprintln(w, "importDomain() START name is", name)
d := me.cluster.FindDropletByName(name) // a LocalOnly record should already have been created by hypervisor.Poll()
d := me.cluster.FindDropletByName(domainName)
if d == nil { if d == nil {
result := "libvirt domain " + name + " could not be found on any hypervisor" result := "libvirt domain " + domainName + " could not be found on any hypervisor"
log.Info(result) log.Info(result)
fmt.Fprintln(w, result) fmt.Fprintln(w, result)
return result, errors.New(result) return result, errors.New(result)
} }
start := d.SprintHeader()
// if it's not local only, don't attempt this for now
if d.LocalOnly == "" { if d.LocalOnly == "" {
result := start + " LocalOnly is blank. THIS SHOULD NEVER HAPPEN." result := "LocalOnly is blank. SKIP. merge not supported yet."
log.Log(WARN, result) log.Log(WARN, result)
fmt.Fprintln(w, result) fmt.Fprintln(w, result)
return result, errors.New(result) return result, errors.New(result)
} }
if d.Current.State != pb.DropletState_OFF {
result := "error: libvirt domain " + name + " is not off"
log.Info(result)
fmt.Fprintln(w, result)
return result, errors.New(result)
}
/*
// it probably doesn't really matter what the state it
if d.Current.State != pb.DropletState_OFF {
result := "error: libvirt domain " + name + " is not off"
log.Info(result)
fmt.Fprintln(w, result)
return result, errors.New(result)
}
*/
// get the hypervisor record for what it's worth
h := findHypervisorByName(d.Current.Hypervisor) h := findHypervisorByName(d.Current.Hypervisor)
if h == nil { if h == nil {
result := "unknown hypervisor = " + d.Current.Hypervisor result := "unknown hypervisor = " + d.Current.Hypervisor
@ -54,37 +62,41 @@ func importDomain(w http.ResponseWriter, r *http.Request) (string, error) {
return result, errors.New(result) return result, errors.New(result)
} }
// attempt to get the domain record from virtigo // exports and builds a libvirt.Domain from the hypervisor
xml, err := postImportDomain(h.pb.Hostname, name) domcfg, err := ExportLibvirtDomain(h.pb, domainName)
if err != nil { if err != nil {
log.Log(WARN, err) reason := fmt.Sprintf("ExportLibvirtDomain() failed", err)
fmt.Fprintln(w, err) log.Warn(reason)
fmt.Fprintln(w, reason)
return "", err return "", err
} }
domcfg := &libvirtxml.Domain{} // merges and updates the droplet protobuf based on the libvirt XML
err = domcfg.Unmarshal(string(xml)) events, err := virtigolib.MergelibvirtDomain(d, domcfg)
if err != nil { if err != nil {
log.Info("Marshal failed", name, err) reason := fmt.Sprintf("MerglibvirtDomain() failed for", d.Hostname, err)
log.Warn(string(xml)) log.Warn(reason)
fmt.Fprintln(w, string(xml)) fmt.Fprintln(w, reason)
return "", err return "", errors.New(reason)
} }
// func ImportXML(domcfg *libvirtxml.Domain) (*pb.Droplet, []*pb.Event, error) {
d, alle, err := virtigolib.ImportXML(domcfg) // check what was non-standard and make a note of it. Save it in the protobuf
s, err := virtigolib.DumpNonStandardXML(domcfg)
if err != nil { if err != nil {
fmt.Fprintln(w, "ImportXML failed with", name, err) reason := s + "\n"
reason = fmt.Sprintln("DumpNonStandardXML() on", domcfg.Name, "failed for", err)
log.Info(reason)
return "", err return "", err
} }
if d == nil { log.Warn("bad XML:", s)
fmt.Fprintln(w, "ImportXML d == nil for", name, err) os.Exit(0)
return "", err
} // everything worked. add the events
for _, e := range alle { for _, e := range events {
me.cluster.AddEvent(e) me.cluster.AddEvent(e)
} }
result := fmt.Sprintln("marshal worked", domcfg.Name, domcfg.UUID) result := fmt.Sprintln("importDomain() worked")
log.Log(WARN, result) log.Log(WARN, result)
fmt.Fprintln(w, result) fmt.Fprintln(w, result)
return result, nil return result, nil
@ -122,6 +134,25 @@ func (h *HyperT) importDomain(d *pb.Droplet) (bool, string) {
return true, result return true, result
} }
func ExportLibvirtDomain(h *pb.Hypervisor, domainName string) (*libvirtxml.Domain, error) {
// attempt to get the domain record from virtigo
xml, err := postImportDomain(h.Hostname, domainName)
if err != nil {
log.Warn(err)
return nil, err
}
// convert the xml into a libvirt object
domcfg := &libvirtxml.Domain{}
err = domcfg.Unmarshal(string(xml))
if err != nil {
log.Warn("Unmarshal failed", domainName, err)
return nil, err
}
return domcfg, nil
}
func postImportDomain(hypervisor string, domain string) ([]byte, error) { func postImportDomain(hypervisor string, domain string) ([]byte, error) {
url := "http://" + hypervisor + ":2520/import?domain=" + domain url := "http://" + hypervisor + ":2520/import?domain=" + domain
var msg string var msg string

View File

@ -15,9 +15,6 @@ func httpPost(url string, data []byte) ([]byte, error) {
var err error var err error
var req *http.Request var req *http.Request
// data := []byte("some junk")
// url := "https://go.wit.com/register/"
req, err = http.NewRequest(http.MethodPost, url, bytes.NewBuffer(data)) req, err = http.NewRequest(http.MethodPost, url, bytes.NewBuffer(data))
usr, _ := user.Current() usr, _ := user.Current()