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
|
package libvirt
import (
"encoding/xml"
"log"
libvirt "github.com/libvirt/libvirt-go"
libvirtxml "github.com/libvirt/libvirt-go-xml"
)
func getHostXMLDesc(ip, mac, name string) string {
dd := libvirtxml.NetworkDHCPHost{
IP: ip,
MAC: mac,
Name: name,
}
tmp := struct {
XMLName xml.Name `xml:"host"`
libvirtxml.NetworkDHCPHost
}{xml.Name{}, dd}
xml, err := xmlMarshallIndented(tmp)
if err != nil {
panic("could not marshall host")
}
return xml
}
// Adds a new static host to the network
func addHost(n *libvirt.Network, ip, mac, name string) error {
xmlDesc := getHostXMLDesc(ip, mac, name)
log.Printf("Adding host with XML:\n%s", xmlDesc)
return n.Update(libvirt.NETWORK_UPDATE_COMMAND_ADD_LAST, libvirt.NETWORK_SECTION_IP_DHCP_HOST, -1, xmlDesc, libvirt.NETWORK_UPDATE_AFFECT_CURRENT)
}
// Update a static host from the network
func updateHost(n *libvirt.Network, ip, mac, name string) error {
xmlDesc := getHostXMLDesc(ip, mac, name)
log.Printf("Updating host with XML:\n%s", xmlDesc)
return n.Update(libvirt.NETWORK_UPDATE_COMMAND_MODIFY, libvirt.NETWORK_SECTION_IP_DHCP_HOST, -1, xmlDesc, libvirt.NETWORK_UPDATE_AFFECT_CURRENT)
}
// Tries to update first, if that fails, it will add it
func updateOrAddHost(n *libvirt.Network, ip, mac, name string) error {
err := updateHost(n, ip, mac, name)
if virErr, ok := err.(libvirt.Error); ok && virErr.Code == libvirt.ERR_OPERATION_INVALID && virErr.Domain == libvirt.FROM_NETWORK {
return addHost(n, ip, mac, name)
}
return err
}
func getHostArchitecture(virConn *libvirt.Connect) (string, error) {
type HostCapabilities struct {
XMLName xml.Name `xml:"capabilities"`
Host struct {
XMLName xml.Name `xml:"host"`
CPU struct {
XMLName xml.Name `xml:"cpu"`
Arch string `xml:"arch"`
}
}
}
info, err := virConn.GetCapabilities()
if err != nil {
return "", err
}
capabilities := HostCapabilities{}
xml.Unmarshal([]byte(info), &capabilities)
return capabilities.Host.CPU.Arch, nil
}
func getHostCapabilities(virConn *libvirt.Connect) (libvirtxml.Caps, error) {
// We should perhaps think of storing this on the connect object
// on first call to avoid the back and forth
caps := libvirtxml.Caps{}
capsXML, err := virConn.GetCapabilities()
if err != nil {
return caps, err
}
xml.Unmarshal([]byte(capsXML), &caps)
log.Printf("[TRACE] Capabilities of host \n %+v", caps)
return caps, nil
}
|