2024-10-31 15:43:25 -05:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
2024-11-01 05:50:42 -05:00
|
|
|
"time"
|
2024-10-31 15:43:25 -05:00
|
|
|
|
2024-10-31 22:14:11 -05:00
|
|
|
pb "go.wit.com/lib/protobuf/virtbuf"
|
2024-11-01 06:41:20 -05:00
|
|
|
"go.wit.com/lib/virtigolib"
|
2024-10-31 15:43:25 -05:00
|
|
|
"go.wit.com/log"
|
2024-11-01 05:50:42 -05:00
|
|
|
"libvirt.org/go/libvirtxml"
|
2024-10-31 15:43:25 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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 == "" {
|
2024-11-01 05:50:42 -05:00
|
|
|
result := "importDomain() failed. name is blank " + r.URL.Path
|
2024-10-31 15:43:25 -05:00
|
|
|
log.Warn(result)
|
|
|
|
fmt.Fprintln(w, result)
|
|
|
|
return "", errors.New(result)
|
|
|
|
}
|
2024-11-01 02:00:46 -05:00
|
|
|
log.Warn("importDomain() START name is", name)
|
|
|
|
fmt.Fprintln(w, "importDomain() START name is", name)
|
2024-10-31 15:43:25 -05:00
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
2024-11-01 02:00:46 -05:00
|
|
|
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)
|
|
|
|
}
|
2024-10-31 22:14:11 -05:00
|
|
|
if d.Current.State != pb.DropletState_OFF {
|
2024-11-01 02:00:46 -05:00
|
|
|
result := "error: libvirt domain " + name + " is not off"
|
2024-10-31 22:14:11 -05:00
|
|
|
log.Info(result)
|
|
|
|
fmt.Fprintln(w, result)
|
2024-11-01 02:00:46 -05:00
|
|
|
return result, errors.New(result)
|
2024-10-31 22:14:11 -05:00
|
|
|
}
|
2024-11-01 02:00:46 -05:00
|
|
|
|
|
|
|
h := findHypervisorByName(d.Current.Hypervisor)
|
|
|
|
if h == nil {
|
2024-11-01 05:50:42 -05:00
|
|
|
result := "unknown hypervisor = " + d.Current.Hypervisor
|
2024-10-31 22:14:11 -05:00
|
|
|
log.Log(WARN, result)
|
|
|
|
fmt.Fprintln(w, result)
|
2024-11-01 02:00:46 -05:00
|
|
|
return result, errors.New(result)
|
2024-10-31 22:14:11 -05:00
|
|
|
}
|
2024-11-01 05:50:42 -05:00
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|
2024-11-01 06:41:20 -05:00
|
|
|
// 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)
|
|
|
|
}
|
2024-11-01 05:50:42 -05:00
|
|
|
|
|
|
|
result := fmt.Sprintln("marshal worked", domcfg.Name, domcfg.UUID)
|
2024-10-31 22:14:11 -05:00
|
|
|
log.Log(WARN, result)
|
2024-10-31 15:43:25 -05:00
|
|
|
fmt.Fprintln(w, result)
|
2024-11-01 05:50:42 -05:00
|
|
|
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
|
2024-11-01 02:00:46 -05:00
|
|
|
}
|
2024-11-01 05:50:42 -05:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-11-01 06:12:12 -05:00
|
|
|
func postImportDomain(hypervisor string, domain string) ([]byte, error) {
|
|
|
|
url := "http://" + hypervisor + ":2520/import?domain=" + domain
|
2024-11-01 05:50:42 -05:00
|
|
|
var msg string
|
|
|
|
var data []byte
|
2024-11-01 06:12:12 -05:00
|
|
|
msg = "import " + domain
|
2024-11-01 05:50:42 -05:00
|
|
|
data = []byte(msg) // Convert the string to []byte
|
|
|
|
req, err := httpPost(url, data)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return req, nil
|
2024-10-31 15:43:25 -05:00
|
|
|
}
|