summaryrefslogtreecommitdiff
path: root/importDomain.go
blob: 7ecaa89574b83a9c547f6d5907f13688fa962d22 (plain)
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
}