summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2012-05-01 17:09:32 +0100
committerDaniel P. Berrange <berrange@redhat.com>2012-06-12 11:32:13 +0100
commit573ada525b8a7384398a8d7d5f094f343555df56 (patch)
tree32f7dff67ebf7650e9594029bc541e99ea45ef21
parent6555c5a8728c5eed9fc104894fdb988a5c9d3e0b (diff)
downloadnova-573ada525b8a7384398a8d7d5f094f343555df56.tar.gz
nova-573ada525b8a7384398a8d7d5f094f343555df56.tar.xz
nova-573ada525b8a7384398a8d7d5f094f343555df56.zip
Add support for configuring libvirt VM clock and timers
There are a number of time sources made available to guests, each of which have a number of configurable policies. This introduces config APIs for the libvirt domain XML to configure the clock time sources Change-Id: Ic5047b02b4753f20bb9a63e85130d84258df7a28 Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-rw-r--r--nova/tests/test_libvirt_config.py92
-rw-r--r--nova/virt/libvirt/config.py65
2 files changed, 157 insertions, 0 deletions
diff --git a/nova/tests/test_libvirt_config.py b/nova/tests/test_libvirt_config.py
index df435690f..1e0818bd7 100644
--- a/nova/tests/test_libvirt_config.py
+++ b/nova/tests/test_libvirt_config.py
@@ -54,6 +54,98 @@ class LibvirtConfigTest(LibvirtConfigBaseTest):
self.assertXmlEqual(xml, "<demo><foo>bar</foo></demo>")
+class LibvirtConfigGuestTimerTest(LibvirtConfigBaseTest):
+ def test_config_platform(self):
+ obj = config.LibvirtConfigGuestTimer()
+ obj.track = "host"
+
+ xml = obj.to_xml()
+ self.assertXmlEqual(xml, """
+ <timer name="platform" track="host"/>
+ """)
+
+ def test_config_pit(self):
+ obj = config.LibvirtConfigGuestTimer()
+ obj.name = "pit"
+ obj.tickpolicy = "discard"
+
+ xml = obj.to_xml()
+ self.assertXmlEqual(xml, """
+ <timer name="pit" tickpolicy="discard"/>
+ """)
+
+ def test_config_hpet(self):
+ obj = config.LibvirtConfigGuestTimer()
+ obj.name = "hpet"
+ obj.present = False
+
+ xml = obj.to_xml()
+ self.assertXmlEqual(xml, """
+ <timer name="hpet" present="no"/>
+ """)
+
+
+class LibvirtConfigGuestClockTest(LibvirtConfigBaseTest):
+ def test_config_utc(self):
+ obj = config.LibvirtConfigGuestClock()
+
+ xml = obj.to_xml()
+ self.assertXmlEqual(xml, """
+ <clock offset="utc"/>
+ """)
+
+ def test_config_localtime(self):
+ obj = config.LibvirtConfigGuestClock()
+ obj.offset = "localtime"
+
+ xml = obj.to_xml()
+ self.assertXmlEqual(xml, """
+ <clock offset="localtime"/>
+ """)
+
+ def test_config_timezone(self):
+ obj = config.LibvirtConfigGuestClock()
+ obj.offset = "timezone"
+ obj.timezone = "EDT"
+
+ xml = obj.to_xml()
+ self.assertXmlEqual(xml, """
+ <clock offset="timezone" timezone="EDT"/>
+ """)
+
+ def test_config_variable(self):
+ obj = config.LibvirtConfigGuestClock()
+ obj.offset = "variable"
+ obj.adjustment = "123456"
+
+ xml = obj.to_xml()
+ self.assertXmlEqual(xml, """
+ <clock offset="variable" adjustment="123456"/>
+ """)
+
+ def test_config_timers(self):
+ obj = config.LibvirtConfigGuestClock()
+
+ tmpit = config.LibvirtConfigGuestTimer()
+ tmpit.name = "pit"
+ tmpit.tickpolicy = "discard"
+
+ tmrtc = config.LibvirtConfigGuestTimer()
+ tmrtc.name = "rtc"
+ tmrtc.tickpolicy = "merge"
+
+ obj.add_timer(tmpit)
+ obj.add_timer(tmrtc)
+
+ xml = obj.to_xml()
+ self.assertXmlEqual(xml, """
+ <clock offset="utc">
+ <timer name="pit" tickpolicy="discard"/>
+ <timer name="rtc" tickpolicy="merge"/>
+ </clock>
+ """)
+
+
class LibvirtConfigGuestDiskTest(LibvirtConfigBaseTest):
def test_config_file(self):
diff --git a/nova/virt/libvirt/config.py b/nova/virt/libvirt/config.py
index 3f068fa05..3ebdf21f0 100644
--- a/nova/virt/libvirt/config.py
+++ b/nova/virt/libvirt/config.py
@@ -63,6 +63,63 @@ class LibvirtConfigObject(object):
return xml_str
+class LibvirtConfigGuestTimer(LibvirtConfigObject):
+
+ def __init__(self, **kwargs):
+ super(LibvirtConfigGuestTimer, self).__init__(root_name="timer",
+ **kwargs)
+
+ self.name = "platform"
+ self.track = None
+ self.tickpolicy = None
+ self.present = None
+
+ def format_dom(self):
+ tm = super(LibvirtConfigGuestTimer, self).format_dom()
+
+ tm.set("name", self.name)
+ if self.track is not None:
+ tm.set("track", self.track)
+ if self.tickpolicy is not None:
+ tm.set("tickpolicy", self.tickpolicy)
+ if self.present is not None:
+ if self.present:
+ tm.set("present", "yes")
+ else:
+ tm.set("present", "no")
+
+ return tm
+
+
+class LibvirtConfigGuestClock(LibvirtConfigObject):
+
+ def __init__(self, **kwargs):
+ super(LibvirtConfigGuestClock, self).__init__(root_name="clock",
+ **kwargs)
+
+ self.offset = "utc"
+ self.adjustment = None
+ self.timezone = None
+ self.timers = []
+
+ def format_dom(self):
+ clk = super(LibvirtConfigGuestClock, self).format_dom()
+
+ clk.set("offset", self.offset)
+ if self.adjustment:
+ clk.set("adjustment", self.adjustment)
+ elif self.timezone:
+ clk.set("timezone", self.timezone)
+
+ for tm in self.timers:
+ clk.append(tm.format_dom())
+
+ return clk
+
+ def add_timer(self, tm):
+ self.timers.append(tm)
+
+
class LibvirtConfigGuestDevice(LibvirtConfigObject):
def __init__(self, **kwargs):
@@ -306,6 +363,7 @@ class LibvirtConfigGuest(LibvirtConfigObject):
self.memory = 1024 * 1024 * 500
self.vcpus = 1
self.acpi = False
+ self.clock = None
self.os_type = None
self.os_kernel = None
self.os_initrd = None
@@ -360,6 +418,10 @@ class LibvirtConfigGuest(LibvirtConfigObject):
self._format_basic_props(root)
self._format_os(root)
self._format_features(root)
+
+ if self.clock is not None:
+ root.append(self.clock.format_dom())
+
self._format_devices(root)
return root
@@ -367,6 +429,9 @@ class LibvirtConfigGuest(LibvirtConfigObject):
def add_device(self, dev):
self.devices.append(dev)
+ def set_clock(self, clk):
+ self.clock = clk
+
class LibvirtConfigCPU(LibvirtConfigObject):