summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/data/xmlparse/change-minimal-guest-out.xml2
-rw-r--r--tests/test_capabilities.py6
-rw-r--r--tests/test_xmlconfig.py20
-rw-r--r--tests/test_xmlparse.py10
-rw-r--r--virtManager/details/details.py10
-rw-r--r--virtManager/object/domain.py9
-rw-r--r--virtinst/cli.py12
-rw-r--r--virtinst/domain/cpu.py62
8 files changed, 72 insertions, 59 deletions
diff --git a/tests/data/xmlparse/change-minimal-guest-out.xml b/tests/data/xmlparse/change-minimal-guest-out.xml
index d347eec0..e07c8e69 100644
--- a/tests/data/xmlparse/change-minimal-guest-out.xml
+++ b/tests/data/xmlparse/change-minimal-guest-out.xml
@@ -20,8 +20,8 @@
</features>
<clock offset="utc"/>
<cpu mode="custom" match="exact">
+ <topology cores="4" sockets="1" threads="1"/>
<model fallback="allow">foobar</model>
- <topology sockets="1" cores="4" threads="1"/>
<feature policy="forbid" name="x2apic"/>
</cpu>
<seclabel type="static" model="testSecurity">
diff --git a/tests/test_capabilities.py b/tests/test_capabilities.py
index 566c4516..46476182 100644
--- a/tests/test_capabilities.py
+++ b/tests/test_capabilities.py
@@ -33,9 +33,9 @@ class TestCapabilities(unittest.TestCase):
self.assertEqual(caps.host.cpu.model, "core2duo")
self.assertEqual(caps.host.cpu.vendor, "Intel")
- self.assertEqual(caps.host.cpu.threads, 3)
- self.assertEqual(caps.host.cpu.cores, 5)
- self.assertEqual(caps.host.cpu.sockets, 7)
+ self.assertEqual(caps.host.cpu.topology.threads, 3)
+ self.assertEqual(caps.host.cpu.topology.cores, 5)
+ self.assertEqual(caps.host.cpu.topology.sockets, 7)
def testCapsUtilFuncs(self):
caps_with_kvm = self._buildCaps("test-qemu-with-kvm.xml")
diff --git a/tests/test_xmlconfig.py b/tests/test_xmlconfig.py
index a066a151..2312da20 100644
--- a/tests/test_xmlconfig.py
+++ b/tests/test_xmlconfig.py
@@ -145,25 +145,27 @@ class TestXMLMisc(unittest.TestCase):
# Test CPU topology determining
cpu = virtinst.DomainCpu(self.conn)
cpu.set_topology_defaults(6)
- assert cpu.sockets is None
+ assert cpu.topology.sockets is None
- cpu.sockets = "2"
+ cpu.topology.sockets = "2"
cpu.set_topology_defaults(6)
- self.assertEqual([cpu.sockets, cpu.cores, cpu.threads], [2, 3, 1])
+ def get_top(_c):
+ return [_c.topology.sockets, _c.topology.cores, _c.topology.threads]
+ self.assertEqual(get_top(cpu), [2, 3, 1])
cpu = virtinst.DomainCpu(self.conn)
- cpu.cores = "4"
+ cpu.topology.cores = "4"
cpu.set_topology_defaults(9)
- self.assertEqual([cpu.sockets, cpu.cores, cpu.threads], [2, 4, 1])
+ self.assertEqual(get_top(cpu), [2, 4, 1])
cpu = virtinst.DomainCpu(self.conn)
- cpu.threads = "3"
+ cpu.topology.threads = "3"
cpu.set_topology_defaults(14)
- self.assertEqual([cpu.sockets, cpu.cores, cpu.threads], [4, 1, 3])
+ self.assertEqual(get_top(cpu), [4, 1, 3])
cpu = virtinst.DomainCpu(self.conn)
- cpu.sockets = 5
- cpu.cores = 2
+ cpu.topology.sockets = 5
+ cpu.topology.cores = 2
self.assertEqual(cpu.vcpus_from_topology(), 10)
cpu = virtinst.DomainCpu(self.conn)
diff --git a/tests/test_xmlparse.py b/tests/test_xmlparse.py
index b6f14e64..2eb1142b 100644
--- a/tests/test_xmlparse.py
+++ b/tests/test_xmlparse.py
@@ -195,10 +195,10 @@ class XMLParseTest(unittest.TestCase):
guest.cpu.set_model(guest, "qemu64")
check("model", "qemu64")
check("vendor", "Intel", "qemuvendor")
- check("threads", 2, 1)
- check("cores", 5, 3)
- guest.cpu.sockets = 4.0
- check("sockets", 4)
+ check("topology.threads", 2, 1)
+ check("topology.cores", 5, 3)
+ guest.cpu.topology.sockets = 4.0
+ check("topology.sockets", 4)
check = self._make_checker(guest.cpu.features[0])
check("name", "x2apic")
@@ -292,7 +292,7 @@ class XMLParseTest(unittest.TestCase):
guest.cpu.set_model(guest, "foobar")
check("model", "foobar")
check("model_fallback", None, "allow")
- check("cores", None, 4)
+ check("topology.cores", None, 4)
guest.cpu.add_feature("x2apic", "forbid")
guest.cpu.set_topology_defaults(guest.vcpus)
self.assertTrue(guest.cpu.get_xml().startswith("<cpu"))
diff --git a/virtManager/details/details.py b/virtManager/details/details.py
index 831fc57b..351dd227 100644
--- a/virtManager/details/details.py
+++ b/virtManager/details/details.py
@@ -1939,13 +1939,13 @@ class vmmDetails(vmmGObjectUI):
def _refresh_config_cpu(self):
# Set topology first, because it impacts vcpus values
- cpu = self.vm.get_cpu_config()
- show_top = bool(cpu.sockets or cpu.cores or cpu.threads)
+ cpu = self.vm.xmlobj.cpu
+ show_top = cpu.has_topology()
self.widget("cpu-topology-enable").set_active(show_top)
- sockets = cpu.sockets or 1
- cores = cpu.cores or 1
- threads = cpu.threads or 1
+ sockets = cpu.topology.sockets or 1
+ cores = cpu.topology.cores or 1
+ threads = cpu.topology.threads or 1
self.widget("cpu-sockets").set_value(sockets)
self.widget("cpu-cores").set_value(cores)
diff --git a/virtManager/object/domain.py b/virtManager/object/domain.py
index f47185be..62410bfc 100644
--- a/virtManager/object/domain.py
+++ b/virtManager/object/domain.py
@@ -559,9 +559,9 @@ class vmmDomain(vmmLibvirtObject):
guest.vcpu_current = int(vcpus)
if sockets != _SENTINEL:
- guest.cpu.sockets = sockets
- guest.cpu.cores = cores
- guest.cpu.threads = threads
+ guest.cpu.topology.sockets = sockets
+ guest.cpu.topology.cores = cores
+ guest.cpu.topology.threads = threads
if secure != _SENTINEL or model != _SENTINEL:
guest.cpu.secure = secure
@@ -1205,9 +1205,6 @@ class vmmDomain(vmmLibvirtObject):
def get_description(self):
return self.get_xmlobj().description
- def get_cpu_config(self):
- return self.get_xmlobj().cpu
-
def get_boot_order(self):
legacy = not self.can_use_device_boot_order()
return self.xmlobj.get_boot_order(legacy=legacy)
diff --git a/virtinst/cli.py b/virtinst/cli.py
index 4f0c8256..eac73ab9 100644
--- a/virtinst/cli.py
+++ b/virtinst/cli.py
@@ -2222,9 +2222,9 @@ class ParserCPU(VirtCLIParser):
cls.add_arg("disable", None, lookup_cb=None, cb=cls.set_feature_cb)
cls.add_arg("forbid", None, lookup_cb=None, cb=cls.set_feature_cb)
- cls.add_arg("topology.sockets", "sockets")
- cls.add_arg("topology.cores", "cores")
- cls.add_arg("topology.threads", "threads")
+ cls.add_arg("topology.sockets", "topology.sockets")
+ cls.add_arg("topology.cores", "topology.cores")
+ cls.add_arg("topology.threads", "topology.threads")
# Options for CPU.cells config
cls.add_arg("numa.cell[0-9]*.id", "id",
@@ -2407,9 +2407,9 @@ class ParserVCPU(VirtCLIParser):
cls.add_arg("vcpus", "vcpus", cb=cls.noset_cb)
# Further CPU options should be added to --cpu
- cls.add_arg("sockets", "cpu.sockets")
- cls.add_arg("cores", "cpu.cores")
- cls.add_arg("threads", "cpu.threads")
+ cls.add_arg("sockets", "cpu.topology.sockets")
+ cls.add_arg("cores", "cpu.topology.cores")
+ cls.add_arg("threads", "cpu.topology.threads")
# <domain><vcpu> options
cls.add_arg("vcpu", "vcpus")
diff --git a/virtinst/domain/cpu.py b/virtinst/domain/cpu.py
index 0e6f4f1e..670a9dd3 100644
--- a/virtinst/domain/cpu.py
+++ b/virtinst/domain/cpu.py
@@ -57,13 +57,43 @@ class _CPUFeature(XMLBuilder):
policy = XMLProperty("./@policy")
+class _CPUTopology(XMLBuilder):
+ """
+ Class for generating <cpu> <topology> XML
+ """
+ XML_NAME = "topology"
+ _XML_PROP_ORDER = ["sockets", "cores", "threads"]
+
+ sockets = XMLProperty("./@sockets", is_int=True)
+ cores = XMLProperty("./@cores", is_int=True)
+ threads = XMLProperty("./@threads", is_int=True)
+
+ def set_defaults_from_vcpus(self, vcpus):
+ if not self.sockets:
+ if not self.cores:
+ self.sockets = vcpus // self.threads
+ else:
+ self.sockets = vcpus // self.cores
+
+ if not self.cores:
+ if not self.threads:
+ self.cores = vcpus // self.sockets
+ else:
+ self.cores = vcpus // (self.sockets * self.threads)
+
+ if not self.threads:
+ self.threads = vcpus // (self.sockets * self.cores)
+
+ return
+
+
class DomainCpu(XMLBuilder):
"""
Class for generating <cpu> XML
"""
XML_NAME = "cpu"
_XML_PROP_ORDER = ["mode", "match", "model", "vendor",
- "sockets", "cores", "threads", "features"]
+ "topology", "features"]
secure = True
@@ -207,13 +237,15 @@ class DomainCpu(XMLBuilder):
Determine the CPU count represented by topology, or 1 if
no topology is set
"""
- return (self.sockets or 1) * (self.cores or 1) * (self.threads or 1)
+ return ((self.topology.sockets or 1) *
+ (self.topology.cores or 1) *
+ (self.topology.threads or 1))
def has_topology(self):
"""
Return True if any topology info is set
"""
- return bool(self.sockets or self.cores or self.threads)
+ return bool(self.topology.get_xml())
def set_topology_defaults(self, vcpus):
"""
@@ -223,29 +255,15 @@ class DomainCpu(XMLBuilder):
"""
if not self.has_topology():
return
-
- if not self.sockets:
- if not self.cores:
- self.sockets = vcpus // self.threads
- else:
- self.sockets = vcpus // self.cores
-
- if not self.cores:
- if not self.threads:
- self.cores = vcpus // self.sockets
- else:
- self.cores = vcpus // (self.sockets * self.threads)
-
- if not self.threads:
- self.threads = vcpus // (self.sockets * self.cores)
-
- return
+ self.topology.set_defaults_from_vcpus(vcpus)
##################
# XML properties #
##################
+ topology = XMLChildProperty(_CPUTopology, is_single=True)
+
model = XMLProperty("./model")
model_fallback = XMLProperty("./model/@fallback")
@@ -253,10 +271,6 @@ class DomainCpu(XMLBuilder):
vendor = XMLProperty("./vendor")
mode = XMLProperty("./@mode")
- sockets = XMLProperty("./topology/@sockets", is_int=True)
- cores = XMLProperty("./topology/@cores", is_int=True)
- threads = XMLProperty("./topology/@threads", is_int=True)
-
##################
# Default config #