2 #############################################################################
3 #Copyright 2017 Parker Berberian and others #
5 #Licensed under the Apache License, Version 2.0 (the "License"); #
6 #you may not use this file except in compliance with the License. #
7 #You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 #Unless required by applicable law or agreed to in writing, software #
12 #distributed under the License is distributed on an "AS IS" BASIS, #
13 #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 #See the License for the specific language governing permissions and #
15 #limitations under the License. #
16 #############################################################################
20 import xml.dom.minidom
26 This class defines a libvirt vm abstraction that can parse our simple
27 config file and add all necessary boiler plate and info to write a full xml
28 definition of itself for libvirt.
31 def __init__(self, propertiesDict):
34 properiesDict should be one of the dictionaries returned by the static
35 method parseConfigFile
37 self.name = propertiesDict['name']
38 self.memory = propertiesDict['memory']
39 self.vcpus = propertiesDict['vcpus']
40 self.disk = propertiesDict['disk']
41 self.iso = propertiesDict['iso']
42 # the vm will either boot from an iso or pxe
43 self.netBoot = not self.iso['used']
44 self.interfaces = propertiesDict['interfaces']
48 combines the given configuration with a lot of
49 boiler plate to create a valid libvirt xml
50 definition of a domain.
53 definition = xml.dom.minidom.parseString("<domain>\n</domain>")
54 definition.documentElement.setAttribute('type', 'kvm')
56 nameElem = definition.createElement('name')
57 nameElem.appendChild(definition.createTextNode(self.name))
58 definition.documentElement.appendChild(nameElem)
60 memElem = definition.createElement('memory')
61 memElem.appendChild(definition.createTextNode(str(self.memory)))
62 definition.documentElement.appendChild(memElem)
64 curMemElem = definition.createElement('currentMemory')
65 curMemElem.appendChild(definition.createTextNode(str(self.memory)))
66 definition.documentElement.appendChild(curMemElem)
68 vcpuElem = definition.createElement('vcpu')
69 vcpuElem.appendChild(definition.createTextNode(str(self.vcpus)))
70 definition.documentElement.appendChild(vcpuElem)
72 osElem = definition.createElement('os')
74 typeElem = definition.createElement('type')
75 typeElem.setAttribute('arch', 'x86_64')
76 typeElem.appendChild(definition.createTextNode('hvm'))
77 osElem.appendChild(typeElem)
80 bootElem = definition.createElement('boot')
81 bootElem.setAttribute('dev', 'network')
82 osElem.appendChild(bootElem)
84 bootElem = definition.createElement('boot')
85 bootElem.setAttribute('dev', 'hd')
86 osElem.appendChild(bootElem)
89 bootElem = definition.createElement('boot')
90 bootElem.setAttribute('dev', 'cdrom')
91 osElem.appendChild(bootElem)
93 definition.documentElement.appendChild(osElem)
95 featureElem = definition.createElement('feature')
96 featureElem.appendChild(definition.createElement('acpi'))
97 featureElem.appendChild(definition.createElement('apic'))
99 definition.documentElement.appendChild(featureElem)
101 cpuElem = definition.createElement('cpu')
102 cpuElem.setAttribute('mode', 'custom')
103 cpuElem.setAttribute('match', 'exact')
104 modelElem = definition.createElement('model')
105 modelElem.appendChild(definition.createTextNode('Broadwell'))
106 cpuElem.appendChild(modelElem)
108 definition.documentElement.appendChild(cpuElem)
110 clockElem = definition.createElement('clock')
111 clockElem.setAttribute('offset', 'utc')
113 timeElem = definition.createElement('timer')
114 timeElem.setAttribute('name', 'rtc')
115 timeElem.setAttribute('tickpolicy', 'catchup')
116 clockElem.appendChild(timeElem)
118 timeElem = definition.createElement('timer')
119 timeElem.setAttribute('name', 'pit')
120 timeElem.setAttribute('tickpolicy', 'delay')
121 clockElem.appendChild(timeElem)
123 timeElem = definition.createElement('timer')
124 timeElem.setAttribute('name', 'hpet')
125 timeElem.setAttribute('present', 'no')
126 clockElem.appendChild(timeElem)
128 definition.documentElement.appendChild(clockElem)
130 poweroffElem = definition.createElement('on_poweroff')
131 poweroffElem.appendChild(definition.createTextNode('destroy'))
133 definition.documentElement.appendChild(poweroffElem)
135 rebootElem = definition.createElement('on_reboot')
136 rebootElem.appendChild(definition.createTextNode('restart'))
138 definition.documentElement.appendChild(rebootElem)
140 crashElem = definition.createElement('on_reboot')
141 crashElem.appendChild(definition.createTextNode('restart'))
143 definition.documentElement.appendChild(crashElem)
145 pmElem = definition.createElement('pm')
146 memElem = definition.createElement('suspend-to-mem')
147 memElem.setAttribute('enabled', 'no')
148 pmElem.appendChild(memElem)
149 diskElem = definition.createElement('suspend-to-disk')
150 diskElem.setAttribute('enabled', 'no')
151 pmElem.appendChild(diskElem)
153 definition.documentElement.appendChild(pmElem)
155 deviceElem = definition.createElement('devices')
157 emuElem = definition.createElement('emulator')
158 emuElem.appendChild(definition.createTextNode('/usr/libexec/qemu-kvm'))
159 deviceElem.appendChild(emuElem)
161 diskElem = definition.createElement('disk')
162 diskElem.setAttribute('type', 'file')
163 diskElem.setAttribute('device', 'disk')
165 driverElem = definition.createElement('driver')
166 driverElem.setAttribute('name', 'qemu')
167 driverElem.setAttribute('type', 'qcow2')
168 diskElem.appendChild(driverElem)
170 sourceElem = definition.createElement('source')
171 sourceElem.setAttribute('file', self.disk)
172 diskElem.appendChild(sourceElem)
174 targetElem = definition.createElement('target')
175 targetElem.setAttribute('dev', 'hda')
176 targetElem.setAttribute('bus', 'ide')
177 diskElem.appendChild(targetElem)
179 deviceElem.appendChild(diskElem)
182 diskElem = definition.createElement('disk')
183 diskElem.setAttribute('type', 'file')
184 diskElem.setAttribute('device', 'cdrom')
186 driverElem = definition.createElement('driver')
187 driverElem.setAttribute('name', 'qemu')
188 driverElem.setAttribute('type', 'raw')
189 diskElem.appendChild(driverElem)
191 sourceElem = definition.createElement('source')
192 sourceElem.setAttribute('file', self.iso['location'])
193 diskElem.appendChild(sourceElem)
195 targetElem = definition.createElement('target')
196 targetElem.setAttribute('dev', 'hdb')
197 targetElem.setAttribute('bus', 'ide')
198 diskElem.appendChild(targetElem)
200 diskElem.appendChild(definition.createElement('readonly'))
201 deviceElem.appendChild(diskElem)
203 for iface in self.interfaces:
204 ifaceElem = definition.createElement('interface')
205 ifaceElem.setAttribute('type', iface['type'])
206 sourceElem = definition.createElement('source')
207 sourceElem.setAttribute(iface['type'], iface['name'])
208 modelElem = definition.createElement('model')
209 modelElem.setAttribute('type', 'e1000')
210 ifaceElem.appendChild(sourceElem)
211 ifaceElem.appendChild(modelElem)
212 deviceElem.appendChild(ifaceElem)
214 graphicElem = definition.createElement('graphics')
215 graphicElem.setAttribute('type', 'vnc')
216 graphicElem.setAttribute('port', '-1')
217 deviceElem.appendChild(graphicElem)
219 consoleElem = definition.createElement('console')
220 consoleElem.setAttribute('type', 'pty')
221 deviceElem.appendChild(consoleElem)
223 definition.documentElement.appendChild(deviceElem)
224 return definition.toprettyxml()
226 def writeXML(self, filePath):
228 writes this domain's xml definition to the given file.
230 f = open(filePath, 'w')
231 f.write(self.toXML())
235 def parseConfigFile(path):
237 parses the domains config file
239 configFile = open(path, 'r')
241 config = yaml.safe_load(configFile)
243 print "Invalid domain configuration. exiting"