package main import ( "errors" "fmt" "net/http" "time" pb "go.wit.com/lib/protobuf/virtbuf" "go.wit.com/lib/virtigolib" "go.wit.com/log" "libvirt.org/go/libvirtxml" ) // attempts to create a new virtual machine func importDomain(w http.ResponseWriter, r *http.Request) (string, error) { name := r.URL.Query().Get("domainName") if name == "" { 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) if d == nil { result := "libvirt domain " + name + " could not be found on any hypervisor" log.Info(result) fmt.Fprintln(w, result) return result, errors.New(result) } start := d.SprintHeader() if d.LocalOnly == "" { result := start + " LocalOnly is blank. THIS SHOULD NEVER HAPPEN." 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) } h := findHypervisorByName(d.Current.Hypervisor) if h == nil { result := "unknown hypervisor = " + d.Current.Hypervisor log.Log(WARN, result) fmt.Fprintln(w, result) return result, errors.New(result) } // attempt to get the domain record from virtigo xml, err := postImportDomain(h.pb.Hostname, name) if err != nil { log.Log(WARN, err) fmt.Fprintln(w, err) return "", err } domcfg := &libvirtxml.Domain{} err = domcfg.Unmarshal(string(xml)) if err != nil { log.Info("Marshal failed", name, err) log.Warn(string(xml)) fmt.Fprintln(w, string(xml)) return "", err } // func ImportXML(domcfg *libvirtxml.Domain) (*pb.Droplet, []*pb.Event, error) { d, alle, err := virtigolib.ImportXML(domcfg) if err != nil { fmt.Fprintln(w, "ImportXML failed with", name, err) return "", err } if d == nil { fmt.Fprintln(w, "ImportXML d == nil for", name, err) return "", err } for _, e := range alle { me.cluster.AddEvent(e) } result := fmt.Sprintln("marshal worked", domcfg.Name, domcfg.UUID) log.Log(WARN, result) fmt.Fprintln(w, result) return result, nil } // this must be bool in string because accumulated output is sometimes // written to STDOUT, sometimes to http func (h *HyperT) importDomain(d *pb.Droplet) (bool, string) { ready, result := me.cluster.DropletReady(d) if !ready { return false, result } url := "http://" + h.pb.Hostname + ":2520/import?domain=" + d.Hostname var msg string var data []byte msg = d.FormatJSON() data = []byte(msg) // Convert the string to []byte req, err := httpPost(url, data) if err != nil { return false, fmt.Sprintln("error:", err) } log.Info("http post url:", url) log.Info("http post data:", msg) result = "EVENT import droplet url: " + url + "\n" result += "EVENT import droplet response: " + string(req) // increment the counter for a start attempt working d.Current.StartAttempts += 1 // mark the cluster as unstable so droplet starts can be throttled me.unstable = time.Now() return true, result } func postImportDomain(hypervisor string, domain string) ([]byte, error) { url := "http://" + hypervisor + ":2520/import?domain=" + domain var msg string var data []byte msg = "import " + domain data = []byte(msg) // Convert the string to []byte req, err := httpPost(url, data) if err != nil { return nil, err } return req, nil }