[virt-tools-list] [virt-manager PATCH 3/3] virt-manager: Add UI support to add/configure vhostuser interface

Lin Ma lma at suse.com
Fri Oct 20 09:08:29 UTC 2017


Signed-off-by: Lin Ma <lma at suse.com>
---
 ui/netlist.ui          | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++
 virtManager/details.py |  9 ++++-
 virtManager/domain.py  |  8 ++++-
 virtManager/netlist.py | 67 +++++++++++++++++++++++++++++++++-
 4 files changed, 178 insertions(+), 3 deletions(-)

diff --git a/ui/netlist.ui b/ui/netlist.ui
index 909f167..92ced9d 100644
--- a/ui/netlist.ui
+++ b/ui/netlist.ui
@@ -183,6 +183,103 @@
         <property name="top_attach">3</property>
       </packing>
     </child>
+    <child>
+      <object class="GtkGrid" id="vhostuser-options-box">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="label11">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="hexpand">False</property>
+            <property name="label" translatable="yes">_Type:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">vhostuser-type</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label12">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="hexpand">False</property>
+            <property name="label" translatable="yes">_Path:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">vhostuser-path</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label13">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="hexpand">False</property>
+            <property name="label" translatable="yes">_Mode:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">vhostuser-mode</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">3</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="vhostuser-type">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="hexpand">True</property>
+            <property name="has_entry">True</property>
+            <signal name="changed" handler="on_net_vhostuser_type_changed" swapped="no"/>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="vhostuser-path">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="halign">start</property>
+            <property name="hexpand">True</property>
+            <signal name="changed" handler="on_net_vhostuser_path_changed" swapped="no"/>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="vhostuser-mode">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="hexpand">True</property>
+            <property name="has_entry">True</property>
+            <signal name="changed" handler="on_net_vhostuser_mode_changed" swapped="no"/>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">3</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">5</property>
+      </packing>
+    </child>
   </object>
   <object class="GtkLabel" id="net-source-label">
     <property name="visible">True</property>
diff --git a/virtManager/details.py b/virtManager/details.py
index e74ea5f..78c89b5 100644
--- a/virtManager/details.py
+++ b/virtManager/details.py
@@ -83,6 +83,7 @@ from .graphwidgets import Sparkline
  EDIT_NET_VPORT,
  EDIT_NET_SOURCE,
  EDIT_NET_MAC,
+ EDIT_NET_VHOSTUSER,
 
  EDIT_GFX_PASSWD,
  EDIT_GFX_TYPE,
@@ -106,7 +107,7 @@ from .graphwidgets import Sparkline
 
  EDIT_FS,
 
- EDIT_HOSTDEV_ROMBAR) = range(1, 49)
+ EDIT_HOSTDEV_ROMBAR) = range(1, 50)
 
 
 # Columns in hw list model
@@ -427,6 +428,8 @@ class vmmDetails(vmmGObjectUI):
             lambda x: self.enable_apply(x, EDIT_NET_SOURCE))
         self.netlist.connect("changed-vport",
             lambda x: self.enable_apply(x, EDIT_NET_VPORT))
+        self.netlist.connect("changed-vhostuser",
+            lambda x: self.enable_apply(x, EDIT_NET_VHOSTUSER))
 
         # Set default window size
         w, h = self.vm.get_details_window_size()
@@ -2170,6 +2173,10 @@ class vmmDetails(vmmGObjectUI):
              kwargs["typeid"], kwargs["typeidversion"],
              kwargs["instanceid"]) = self.netlist.get_vport()
 
+        if self.edited(EDIT_NET_VHOSTUSER):
+            (kwargs["source_type"], kwargs["source_path"],
+             kwargs["mode"]) = self.netlist.get_vhostuser()
+
         if self.edited(EDIT_NET_MAC):
             kwargs["macaddr"] = self.widget("network-mac-entry").get_text()
 
diff --git a/virtManager/domain.py b/virtManager/domain.py
index 724f83f..1a97d46 100644
--- a/virtManager/domain.py
+++ b/virtManager/domain.py
@@ -848,7 +848,8 @@ class vmmDomain(vmmLibvirtObject):
         mode=_SENTINEL, model=_SENTINEL, addrstr=_SENTINEL,
         vtype=_SENTINEL, managerid=_SENTINEL, typeid=_SENTINEL,
         typeidversion=_SENTINEL, instanceid=_SENTINEL,
-        portgroup=_SENTINEL, macaddr=_SENTINEL):
+        portgroup=_SENTINEL, macaddr=_SENTINEL,
+        source_type=_SENTINEL, source_path=_SENTINEL):
         xmlobj = self._make_xmlobj_to_define()
         editdev = self._lookup_device_to_define(xmlobj, devobj, do_hotplug)
         if not editdev:
@@ -878,6 +879,11 @@ class vmmDomain(vmmLibvirtObject):
         if macaddr != _SENTINEL:
             editdev.macaddr = macaddr
 
+        if source_type != _SENTINEL:
+            editdev.source_type = source_type
+            editdev.source_path = source_path
+            editdev.source_mode = mode
+
         if do_hotplug:
             self.hotplug(device=editdev)
         else:
diff --git a/virtManager/netlist.py b/virtManager/netlist.py
index 4f1e991..1ebca44 100644
--- a/virtManager/netlist.py
+++ b/virtManager/netlist.py
@@ -30,7 +30,8 @@ from .baseclass import vmmGObjectUI
 class vmmNetworkList(vmmGObjectUI):
     __gsignals__ = {
         "changed": (GObject.SignalFlags.RUN_FIRST, None, []),
-        "changed-vport": (GObject.SignalFlags.RUN_FIRST, None, [])
+        "changed-vport": (GObject.SignalFlags.RUN_FIRST, None, []),
+        "changed-vhostuser": (GObject.SignalFlags.RUN_FIRST, None, [])
     }
 
     def __init__(self, conn, builder, topwin):
@@ -49,6 +50,10 @@ class vmmNetworkList(vmmGObjectUI):
             "on_vport_typeid_changed": self._emit_vport_changed,
             "on_vport_typeidversion_changed": self._emit_vport_changed,
             "on_vport_instanceid_changed": self._emit_vport_changed,
+
+            "on_net_vhostuser_type_changed": self._emit_vhostuser_changed,
+            "on_net_vhostuser_path_changed": self._emit_vhostuser_changed,
+            "on_net_vhostuser_mode_changed": self._emit_vhostuser_changed,
         })
 
         self._init_ui()
@@ -102,6 +107,25 @@ class vmmNetworkList(vmmGObjectUI):
         combo.set_model(model)
         uiutil.init_combo_text_column(combo, 1)
 
+        combo = self.widget("vhostuser-type")
+        # [xml value, label]
+        model = Gtk.ListStore(str, str)
+        combo.set_model(model)
+        uiutil.init_combo_text_column(combo, 1)
+
+        model.append(["unix", "unix"])
+        combo.set_active(0)
+
+        combo = self.widget("vhostuser-mode")
+        # [xml value, label]
+        model = Gtk.ListStore(str, str)
+        combo.set_model(model)
+        uiutil.init_combo_text_column(combo, 1)
+
+        model.append(["server", "server"])
+        model.append(["client", "client"])
+        combo.set_active(0)
+
         self.conn.connect("net-added", self._repopulate_network_list)
         self.conn.connect("net-removed", self._repopulate_network_list)
         self.conn.connect("interface-added", self._repopulate_network_list)
@@ -247,6 +271,12 @@ class vmmNetworkList(vmmGObjectUI):
                 True, False, manual_bridge=True)
             model.append(manual_row)
 
+        def _add_vhostuser_row():
+            vhostuser_row = self._build_source_row(
+                _("vhostuser"), None, _("vhostuser"),
+                True, False, manual_bridge=False)
+            model.append(vhostuser_row)
+
         if self.conn.is_qemu_session():
             nettype = virtinst.VirtualNetworkInterface.TYPE_USER
             r = self._build_source_row(
@@ -291,6 +321,7 @@ class vmmNetworkList(vmmGObjectUI):
             default = [idx for idx in range(len(model)) if
                        model[idx][2] == label][0]
 
+        _add_vhostuser_row()
         _add_manual_bridge_row()
         return default
 
@@ -336,6 +367,13 @@ class vmmNetworkList(vmmGObjectUI):
         return (vport_type, vport_managerid, vport_typeid,
          vport_idver, vport_instid)
 
+    def get_vhostuser(self):
+        vhostuser_type = uiutil.get_list_selection(self.widget("vhostuser-type"))
+        vhostuser_path = self.widget("vhostuser-path").get_text() or None
+        vhostuser_mode = uiutil.get_list_selection(self.widget("vhostuser-mode"))
+
+        return (vhostuser_type, vhostuser_path, vhostuser_mode)
+
     def validate_network(self, macaddr, model=None):
         nettype, devname, mode, portgroup = self.get_network_selection()
         if nettype is None:
@@ -388,6 +426,13 @@ class vmmNetworkList(vmmGObjectUI):
                 net.virtualport.typeid = vport_typeid or None
                 net.virtualport.typeidversion = vport_idver or None
                 net.virtualport.instanceid = vport_instid or None
+
+            if net.type == virtinst.VirtualNetworkInterface.TYPE_VHOSTUSER:
+                (net.source_type, net.source_path,
+                 net.source_mode) = self.get_vhostuser()
+                # Vhostuser requires the virtio-net* frontend
+                net.model = "virtio"
+
         except Exception as e:
             return self.err.val_err(_("Error with network parameters."), e)
 
@@ -426,6 +471,10 @@ class vmmNetworkList(vmmGObjectUI):
         self.widget("vport-typeidversion").set_text("")
         self.widget("vport-instanceid").set_text("")
 
+        self.widget("vhostuser-type").set_active(0)
+        self.widget("vhostuser-mode").set_active(0)
+        self.widget("vhostuser-path").set_text("")
+
     def set_dev(self, net):
         self.reset_state()
 
@@ -470,6 +519,13 @@ class vmmNetworkList(vmmGObjectUI):
         if net.portgroup:
             uiutil.set_list_selection(self.widget("net-portgroup"), net.portgroup)
 
+        if net.type == "vhostuser":
+            uiutil.set_list_selection(self.widget("vhostuser-type"),
+                                      net.source_type)
+            uiutil.set_list_selection(self.widget("vhostuser-mode"),
+                                      net.source_mode)
+            self.widget("vhostuser-path").set_text(net.source_path)
+
 
     #############
     # Listeners #
@@ -485,6 +541,11 @@ class vmmNetworkList(vmmGObjectUI):
         ignore2 = kwargs
         self.emit("changed-vport")
 
+    def _emit_vhostuser_changed(self, *args, **kwargs):
+        ignore1 = args
+        ignore2 = kwargs
+        self.emit("changed-vhostuser")
+
     def _repopulate_network_list(self, *args, **kwargs):
         ignore1 = args
         ignore2 = kwargs
@@ -529,6 +590,8 @@ class vmmNetworkList(vmmGObjectUI):
         if not row:
             return
 
+        is_vhostuser = (
+            row[0] == virtinst.VirtualNetworkInterface.TYPE_VHOSTUSER)
         is_openvswitch = row[2].endswith("(OpenVSwitch)")
         is_direct = (row[0] == virtinst.VirtualNetworkInterface.TYPE_DIRECT)
         self.widget("vport-expander").set_visible(is_direct or is_openvswitch)
@@ -537,6 +600,8 @@ class vmmNetworkList(vmmGObjectUI):
             self.widget("net-macvtap-warn-box"), is_direct)
         if is_direct and self.widget("net-source-mode").get_active() == -1:
             self.widget("net-source-mode").set_active(0)
+        uiutil.set_grid_row_visible(
+            self.widget("vhostuser-options-box"), is_vhostuser)
 
         show_bridge = row[5]
         uiutil.set_grid_row_visible(
-- 
2.9.2




More information about the virt-tools-list mailing list