From a10dab96ff14f800a0f731eef86b1ab55152ede7 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Fri, 1 Nov 2024 08:03:20 -0500 Subject: [PATCH] import almost works Signed-off-by: Jeff Carr --- importDomain.go | 99 ++++++++++++++++++++++++++++++++----------------- post.go | 3 -- 2 files changed, 65 insertions(+), 37 deletions(-) diff --git a/importDomain.go b/importDomain.go index 7ecaa89..3e07eb5 100644 --- a/importDomain.go +++ b/importDomain.go @@ -4,48 +4,56 @@ import ( "errors" "fmt" "net/http" + "os" "time" pb "go.wit.com/lib/protobuf/virtbuf" "go.wit.com/lib/virtigolib" "go.wit.com/log" + + // "libvirt.org/go/libvirt" "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) { - name := r.URL.Query().Get("domainName") - if name == "" { + domainName := r.URL.Query().Get("domainName") + if domainName == "" { result := "importDomain() failed. name is blank " + r.URL.Path log.Warn(result) fmt.Fprintln(w, 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 { - 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) fmt.Fprintln(w, result) return result, errors.New(result) } - start := d.SprintHeader() + + // if it's not local only, don't attempt this for now 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) fmt.Fprintln(w, 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) if h == nil { 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) } - // attempt to get the domain record from virtigo - xml, err := postImportDomain(h.pb.Hostname, name) + // exports and builds a libvirt.Domain from the hypervisor + domcfg, err := ExportLibvirtDomain(h.pb, domainName) if err != nil { - log.Log(WARN, err) - fmt.Fprintln(w, err) + reason := fmt.Sprintf("ExportLibvirtDomain() failed", err) + log.Warn(reason) + fmt.Fprintln(w, reason) return "", err } - domcfg := &libvirtxml.Domain{} - err = domcfg.Unmarshal(string(xml)) + // merges and updates the droplet protobuf based on the libvirt XML + events, err := virtigolib.MergelibvirtDomain(d, domcfg) if err != nil { - log.Info("Marshal failed", name, err) - log.Warn(string(xml)) - fmt.Fprintln(w, string(xml)) - return "", err + reason := fmt.Sprintf("MerglibvirtDomain() failed for", d.Hostname, err) + log.Warn(reason) + fmt.Fprintln(w, reason) + 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 { - 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 } - if d == nil { - fmt.Fprintln(w, "ImportXML d == nil for", name, err) - return "", err - } - for _, e := range alle { + log.Warn("bad XML:", s) + os.Exit(0) + + // everything worked. add the events + for _, e := range events { me.cluster.AddEvent(e) } - result := fmt.Sprintln("marshal worked", domcfg.Name, domcfg.UUID) + result := fmt.Sprintln("importDomain() worked") log.Log(WARN, result) fmt.Fprintln(w, result) return result, nil @@ -122,6 +134,25 @@ func (h *HyperT) importDomain(d *pb.Droplet) (bool, string) { 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) { url := "http://" + hypervisor + ":2520/import?domain=" + domain var msg string diff --git a/post.go b/post.go index 9537bc8..8e56b75 100644 --- a/post.go +++ b/post.go @@ -15,9 +15,6 @@ func httpPost(url string, data []byte) ([]byte, error) { var err error var req *http.Request - // data := []byte("some junk") - // url := "https://go.wit.com/register/" - req, err = http.NewRequest(http.MethodPost, url, bytes.NewBuffer(data)) usr, _ := user.Current()