[virt-tools-list] [PATCH 3/3] add a checkbox for cpu host-model mode, remove 'copy' button
Guannan Ren
gren at redhat.com
Tue Apr 16 11:02:16 UTC 2013
If the host-model is selected, disable the cpu model drop down
and features list. They still show what exact configuration the
host-model is using.
For the old libvirt which doesn't support <cpu mode='host-model'/>
virt-manager still copy cpu configs from caps XML to domain XML.
If a certain libvirt version supports host-model, but the UPDATE_CPU
flag doesn't exist, a WARN image will show up on UI to give a hint.
---
ui/vmm-details.ui | 246 ++++++++++++++++++++++++-------------------------
virtManager/details.py | 44 +++++----
virtManager/domain.py | 17 ++--
3 files changed, 156 insertions(+), 151 deletions(-)
diff --git a/ui/vmm-details.ui b/ui/vmm-details.ui
index ad0652d..45f3e82 100644
--- a/ui/vmm-details.ui
+++ b/ui/vmm-details.ui
@@ -2314,192 +2314,184 @@ I/O:</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
- <object class="GtkTable" id="table15">
+ <object class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">12</property>
- <property name="row_spacing">3</property>
<child>
- <object class="GtkLabel" id="label52">
+ <object class="GtkCheckButton" id="cpu-host-model-checkbutton">
+ <property name="label" translatable="yes">host model</property>
+ <property name="use_action_appearance">False</property>
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Model:</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_cpu_host_model_enable_toggled" swapped="no"/>
</object>
<packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox21">
+ <object class="GtkImage" id="host-model-info">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <child>
- <object class="GtkAlignment" id="alignment33">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkComboBox" id="cpu-model">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="has_entry">True</property>
- <signal name="changed" handler="on_cpu_model_changed" swapped="no"/>
- <child internal-child="entry">
- <object class="GtkEntry" id="combobox-entry">
- <property name="can_focus">True</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
+ <property name="xalign">0</property>
+ <property name="stock">gtk-info</property>
</object>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options">GTK_FILL</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
</packing>
</child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox14">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
<child>
- <object class="GtkAlignment" id="alignment37">
+ <object class="GtkLabel" id="label52">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <child>
- <placeholder/>
- </child>
+ <property name="label" translatable="yes">Model:</property>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox25">
+ <object class="GtkAlignment" id="alignment12">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
- <object class="GtkButton" id="cpu-copy-host">
- <property name="label" translatable="yes">Copy host CPU configuration</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <signal name="clicked" handler="on_cpu_copy_host_clicked" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment38">
+ <object class="GtkComboBox" id="cpu-model">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <child>
- <placeholder/>
+ <property name="has_entry">True</property>
+ <signal name="changed" handler="on_cpu_model_changed" swapped="no"/>
+ <child internal-child="entry">
+ <object class="GtkEntry" id="combobox-entry">
+ <property name="can_focus">True</property>
+ </object>
</child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">GTK_FILL</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
- <object class="GtkExpander" id="cpu-features-expander">
+ <object class="GtkHBox" id="hbox21">
<property name="visible">True</property>
- <property name="can_focus">True</property>
+ <property name="can_focus">False</property>
<child>
- <object class="GtkAlignment" id="alignment29">
+ <object class="GtkExpander" id="cpu-features-expander">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">21</property>
+ <property name="can_focus">True</property>
<child>
- <object class="GtkHBox" id="hbox19">
+ <object class="GtkAlignment" id="alignment29">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="spacing">6</property>
+ <property name="left_padding">21</property>
<child>
- <object class="GtkScrolledWindow" id="scrolledwindow4">
- <property name="height_request">150</property>
+ <object class="GtkHBox" id="hbox19">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">never</property>
- <property name="shadow_type">etched-in</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkTreeView" id="cpu-features">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">False</property>
- <child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection3"/>
+ <object class="GtkScrolledWindow" id="scrolledwindow4">
+ <property name="height_request">150</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="shadow_type">etched-in</property>
+ <child>
+ <object class="GtkTreeView" id="cpu-features">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection3"/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
</child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment32">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
<child>
- <placeholder/>
+ <object class="GtkAlignment" id="alignment32">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
</child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
</child>
+ <child type="label">
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes"><b>CPU Features</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
</object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label5">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes"><b>CPU Features</b></property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="cpu-feat-warn-image">
+ <property name="visible">False</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-dialog-warning</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
</packing>
</child>
</object>
diff --git a/virtManager/details.py b/virtManager/details.py
index 29b0627..89d7bdf 100644
--- a/virtManager/details.py
+++ b/virtManager/details.py
@@ -360,7 +360,6 @@ class vmmDetails(vmmGObjectUI):
self.ignorePause = False
self.ignoreDetails = False
- self._cpu_copy_host = False
self.console = vmmConsolePages(self.vm, self.builder, self.topwin)
@@ -431,7 +430,7 @@ class vmmDetails(vmmGObjectUI):
"on_cpu_cores_changed": lambda *x: self.enable_apply(x, EDIT_TOPOLOGY),
"on_cpu_sockets_changed": lambda *x: self.enable_apply(x, EDIT_TOPOLOGY),
"on_cpu_threads_changed": lambda *x: self.enable_apply(x, EDIT_TOPOLOGY),
- "on_cpu_copy_host_clicked": self.config_cpu_copy_host,
+ "on_cpu_host_model_enable_toggled": self.config_cpu_host_model_enable,
"on_cpu_topology_enable_toggled": self.config_cpu_topology_enable,
"on_config_memory_changed": self.config_memory_changed,
@@ -916,6 +915,8 @@ class vmmDetails(vmmGObjectUI):
feat_model.append([name, "default"])
# CPU model combo
+ self.widget("host-model-info").set_tooltip_text(
+ _("Use CPU model which most closely matches the host, this gives close to maximum functionality and performance."))
cpu_model = self.widget("cpu-model")
model = Gtk.ListStore(str, object)
@@ -1813,17 +1814,11 @@ class vmmDetails(vmmGObjectUI):
def config_maxvcpus_changed(self, ignore):
self.enable_apply(EDIT_VCPUS)
- def config_cpu_copy_host(self, src_ignore):
- # Update UI with output copied from host
- try:
- CPU = virtinst.CPU(self.vm.conn.vmm)
- CPU.copy_host_cpu()
-
- self._refresh_cpu_config(CPU)
- self._cpu_copy_host = True
- except Exception, e:
- self.err.show_err(_("Error copying host CPU: %s") % str(e))
- return
+ def config_cpu_host_model_enable(self, src):
+ do_enable = src.get_active()
+ self.widget("cpu-model").set_sensitive(not bool(do_enable))
+ self.widget("cpu-features").set_sensitive(not bool(do_enable))
+ self.enable_apply(EDIT_CPU)
def config_cpu_topology_enable(self, src):
do_enable = src.get_active()
@@ -2116,10 +2111,14 @@ class vmmDetails(vmmGObjectUI):
add_hotplug(self.config_vcpu_pin_cpuset, cpuset)
if self.editted(EDIT_CPU):
+ from_host = False
+ if self.widget("cpu-host-model-checkbutton").get_active():
+ from_host = True
+
model, vendor = self.get_config_cpu_model()
features = self.get_config_cpu_features()
add_define(self.vm.define_cpu,
- model, vendor, self._cpu_copy_host, features)
+ model, vendor, from_host, features)
if self.editted(EDIT_TOPOLOGY):
do_top = self.widget("cpu-topology-enable").get_active()
@@ -2134,8 +2133,6 @@ class vmmDetails(vmmGObjectUI):
add_define(self.vm.define_cpu_topology, sockets, cores, threads)
ret = self._change_config_helper(df, da, hf, ha)
- if ret:
- self._cpu_copy_host = False
return ret
def config_vcpu_pin(self, src_ignore, path, new_text):
@@ -2815,6 +2812,7 @@ class vmmDetails(vmmGObjectUI):
def _refresh_cpu_config(self, cpu):
feature_ui = self.widget("cpu-features")
model = cpu.model or ""
+ mode = cpu.mode
caps = self.vm.conn.get_capabilities()
capscpu = None
@@ -2834,12 +2832,25 @@ class vmmDetails(vmmGObjectUI):
cores = cpu.cores or 1
threads = cpu.threads or 1
+ if mode == "host-model":
+ host_model = self.widget("cpu-host-model-checkbutton")
+ if not host_model.get_active():
+ host_model.set_active(True)
+
self.widget("cpu-topology-enable").set_active(show_top)
self.widget("cpu-model").get_child().set_text(model)
self.widget("cpu-sockets").set_value(sockets)
self.widget("cpu-cores").set_value(cores)
self.widget("cpu-threads").set_value(threads)
+ # Only happened when VIR_DOMAIN_XML_UPDATE_CPU flag doesn't exist
+ # for host-model mode
+ if mode == "host-model" and not cpu.features:
+ cpu_feat_warn = self.widget("cpu-feat-warn-image")
+ cpu_feat_warn.show()
+ cpu_feat_warn.set_tooltip_text(_("CPU features failed to show."))
+ return
+
def get_feature_policy(name):
for f in cpu.features:
if f.name == name:
@@ -2855,7 +2866,6 @@ class vmmDetails(vmmGObjectUI):
row[1] = get_feature_policy(row[0])
def refresh_config_cpu(self):
- self._cpu_copy_host = False
cpu = self.vm.get_cpu_config()
self._refresh_cpu_count()
diff --git a/virtManager/domain.py b/virtManager/domain.py
index 82a7ac8..14f8983 100644
--- a/virtManager/domain.py
+++ b/virtManager/domain.py
@@ -468,16 +468,19 @@ class vmmDomain(vmmLibvirtObject):
def define_cpu(self, model, vendor, from_host, featurelist):
def change(guest):
if from_host:
- guest.cpu.copy_host_cpu()
- elif guest.cpu.model != model:
- # Since we don't expose this in the UI, have host value trump
- # caps value
- guest.cpu.vendor = vendor
+ if virtinst.support.check_domain_support(self._backend,
+ virtinst.support.SUPPORT_DOMAIN_CPU_HOST_MODEL):
+ guest.cpu.reset()
+ guest.cpu.mode = "host-model"
+ else:
+ guest.cpu.copy_host_cpu()
+ return
guest.cpu.model = model or None
+ guest.cpu.vendor = vendor or None
+
if guest.cpu.model is None:
- for f in guest.cpu.features:
- guest.cpu.remove_feature(f)
+ guest.cpu.reset()
return
origfeatures = guest.cpu.features
--
1.7.11.2
More information about the virt-tools-list
mailing list