1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
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
}
|