summaryrefslogtreecommitdiffstats
path: root/laas-fog/source/domain.py
diff options
context:
space:
mode:
Diffstat (limited to 'laas-fog/source/domain.py')
-rw-r--r--laas-fog/source/domain.py244
1 files changed, 244 insertions, 0 deletions
diff --git a/laas-fog/source/domain.py b/laas-fog/source/domain.py
new file mode 100644
index 0000000..6f00239
--- /dev/null
+++ b/laas-fog/source/domain.py
@@ -0,0 +1,244 @@
+"""
+#############################################################################
+#Copyright 2017 Parker Berberian and others #
+# #
+#Licensed under the Apache License, Version 2.0 (the "License"); #
+#you may not use this file except in compliance with the License. #
+#You may obtain a copy of the License at #
+# #
+# http://www.apache.org/licenses/LICENSE-2.0 #
+# #
+#Unless required by applicable law or agreed to in writing, software #
+#distributed under the License is distributed on an "AS IS" BASIS, #
+#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
+#See the License for the specific language governing permissions and #
+#limitations under the License. #
+#############################################################################
+"""
+
+import xml.dom
+import xml.dom.minidom
+import yaml
+
+
+class Domain:
+ """
+ This class defines a libvirt vm abstraction that can parse our simple
+ config file and add all necessary boiler plate and info to write a full xml
+ definition of itself for libvirt.
+ """
+
+ def __init__(self, propertiesDict):
+ """
+ init function.
+ properiesDict should be one of the dictionaries returned by the static
+ method parseConfigFile
+ """
+ self.name = propertiesDict['name']
+ self.memory = propertiesDict['memory']
+ self.vcpus = propertiesDict['vcpus']
+ self.disk = propertiesDict['disk']
+ self.iso = propertiesDict['iso']
+ # the vm will either boot from an iso or pxe
+ self.netBoot = not self.iso['used']
+ self.interfaces = propertiesDict['interfaces']
+
+ def toXML(self):
+ """
+ combines the given configuration with a lot of
+ boiler plate to create a valid libvirt xml
+ definition of a domain.
+ returns a string
+ """
+ definition = xml.dom.minidom.parseString("<domain>\n</domain>")
+ definition.documentElement.setAttribute('type', 'kvm')
+
+ nameElem = definition.createElement('name')
+ nameElem.appendChild(definition.createTextNode(self.name))
+ definition.documentElement.appendChild(nameElem)
+
+ memElem = definition.createElement('memory')
+ memElem.appendChild(definition.createTextNode(str(self.memory)))
+ definition.documentElement.appendChild(memElem)
+
+ curMemElem = definition.createElement('currentMemory')
+ curMemElem.appendChild(definition.createTextNode(str(self.memory)))
+ definition.documentElement.appendChild(curMemElem)
+
+ vcpuElem = definition.createElement('vcpu')
+ vcpuElem.appendChild(definition.createTextNode(str(self.vcpus)))
+ definition.documentElement.appendChild(vcpuElem)
+
+ osElem = definition.createElement('os')
+
+ typeElem = definition.createElement('type')
+ typeElem.setAttribute('arch', 'x86_64')
+ typeElem.appendChild(definition.createTextNode('hvm'))
+ osElem.appendChild(typeElem)
+
+ if self.netBoot:
+ bootElem = definition.createElement('boot')
+ bootElem.setAttribute('dev', 'network')
+ osElem.appendChild(bootElem)
+
+ bootElem = definition.createElement('boot')
+ bootElem.setAttribute('dev', 'hd')
+ osElem.appendChild(bootElem)
+
+ if self.iso['used']:
+ bootElem = definition.createElement('boot')
+ bootElem.setAttribute('dev', 'cdrom')
+ osElem.appendChild(bootElem)
+
+ definition.documentElement.appendChild(osElem)
+
+ featureElem = definition.createElement('feature')
+ featureElem.appendChild(definition.createElement('acpi'))
+ featureElem.appendChild(definition.createElement('apic'))
+
+ definition.documentElement.appendChild(featureElem)
+
+ cpuElem = definition.createElement('cpu')
+ cpuElem.setAttribute('mode', 'custom')
+ cpuElem.setAttribute('match', 'exact')
+ modelElem = definition.createElement('model')
+ modelElem.appendChild(definition.createTextNode('Broadwell'))
+ cpuElem.appendChild(modelElem)
+
+ definition.documentElement.appendChild(cpuElem)
+
+ clockElem = definition.createElement('clock')
+ clockElem.setAttribute('offset', 'utc')
+
+ timeElem = definition.createElement('timer')
+ timeElem.setAttribute('name', 'rtc')
+ timeElem.setAttribute('tickpolicy', 'catchup')
+ clockElem.appendChild(timeElem)
+
+ timeElem = definition.createElement('timer')
+ timeElem.setAttribute('name', 'pit')
+ timeElem.setAttribute('tickpolicy', 'delay')
+ clockElem.appendChild(timeElem)
+
+ timeElem = definition.createElement('timer')
+ timeElem.setAttribute('name', 'hpet')
+ timeElem.setAttribute('present', 'no')
+ clockElem.appendChild(timeElem)
+
+ definition.documentElement.appendChild(clockElem)
+
+ poweroffElem = definition.createElement('on_poweroff')
+ poweroffElem.appendChild(definition.createTextNode('destroy'))
+
+ definition.documentElement.appendChild(poweroffElem)
+
+ rebootElem = definition.createElement('on_reboot')
+ rebootElem.appendChild(definition.createTextNode('restart'))
+
+ definition.documentElement.appendChild(rebootElem)
+
+ crashElem = definition.createElement('on_reboot')
+ crashElem.appendChild(definition.createTextNode('restart'))
+
+ definition.documentElement.appendChild(crashElem)
+
+ pmElem = definition.createElement('pm')
+ memElem = definition.createElement('suspend-to-mem')
+ memElem.setAttribute('enabled', 'no')
+ pmElem.appendChild(memElem)
+ diskElem = definition.createElement('suspend-to-disk')
+ diskElem.setAttribute('enabled', 'no')
+ pmElem.appendChild(diskElem)
+
+ definition.documentElement.appendChild(pmElem)
+
+ deviceElem = definition.createElement('devices')
+
+ emuElem = definition.createElement('emulator')
+ emuElem.appendChild(definition.createTextNode('/usr/libexec/qemu-kvm'))
+ deviceElem.appendChild(emuElem)
+
+ diskElem = definition.createElement('disk')
+ diskElem.setAttribute('type', 'file')
+ diskElem.setAttribute('device', 'disk')
+
+ driverElem = definition.createElement('driver')
+ driverElem.setAttribute('name', 'qemu')
+ driverElem.setAttribute('type', 'qcow2')
+ diskElem.appendChild(driverElem)
+
+ sourceElem = definition.createElement('source')
+ sourceElem.setAttribute('file', self.disk)
+ diskElem.appendChild(sourceElem)
+
+ targetElem = definition.createElement('target')
+ targetElem.setAttribute('dev', 'hda')
+ targetElem.setAttribute('bus', 'ide')
+ diskElem.appendChild(targetElem)
+
+ deviceElem.appendChild(diskElem)
+
+ if self.iso['used']:
+ diskElem = definition.createElement('disk')
+ diskElem.setAttribute('type', 'file')
+ diskElem.setAttribute('device', 'cdrom')
+
+ driverElem = definition.createElement('driver')
+ driverElem.setAttribute('name', 'qemu')
+ driverElem.setAttribute('type', 'raw')
+ diskElem.appendChild(driverElem)
+
+ sourceElem = definition.createElement('source')
+ sourceElem.setAttribute('file', self.iso['location'])
+ diskElem.appendChild(sourceElem)
+
+ targetElem = definition.createElement('target')
+ targetElem.setAttribute('dev', 'hdb')
+ targetElem.setAttribute('bus', 'ide')
+ diskElem.appendChild(targetElem)
+
+ diskElem.appendChild(definition.createElement('readonly'))
+ deviceElem.appendChild(diskElem)
+
+ for iface in self.interfaces:
+ ifaceElem = definition.createElement('interface')
+ ifaceElem.setAttribute('type', iface['type'])
+ sourceElem = definition.createElement('source')
+ sourceElem.setAttribute(iface['type'], iface['name'])
+ modelElem = definition.createElement('model')
+ modelElem.setAttribute('type', 'e1000')
+ ifaceElem.appendChild(sourceElem)
+ ifaceElem.appendChild(modelElem)
+ deviceElem.appendChild(ifaceElem)
+
+ graphicElem = definition.createElement('graphics')
+ graphicElem.setAttribute('type', 'vnc')
+ graphicElem.setAttribute('port', '-1')
+ deviceElem.appendChild(graphicElem)
+
+ consoleElem = definition.createElement('console')
+ consoleElem.setAttribute('type', 'pty')
+ deviceElem.appendChild(consoleElem)
+
+ definition.documentElement.appendChild(deviceElem)
+ return definition.toprettyxml()
+
+ def writeXML(self, filePath):
+ """
+ writes this domain's xml definition to the given file.
+ """
+ f = open(filePath, 'w')
+ f.write(self.toXML())
+ f.close()
+
+ @staticmethod
+ def parseConfigFile(path):
+ """
+ parses the domains config file
+ """
+ configFile = open(path, 'r')
+ try:
+ config = yaml.safe_load(configFile)
+ except Exception:
+ print "Invalid domain configuration. exiting"
+ return config