[virt-tools-list] [PATCH v2 virt-manager 1/2] virtManager: add QoS information for a network

Giuseppe Scrivano gscrivan at redhat.com
Mon Jul 7 10:03:22 UTC 2014


Add UI elements to display and modify QoS settings in the network
details.

Closes: https://bugzilla.redhat.com/show_bug.cgi?id=1089117

Signed-off-by: Giuseppe Scrivano <gscrivan at redhat.com>
---
 ui/host.ui             | 246 +++++++++++++++++++++++++++++++++++++++++++++++++
 virtManager/host.py    |  78 +++++++++++++++-
 virtManager/network.py |  15 ++-
 3 files changed, 337 insertions(+), 2 deletions(-)

diff --git a/ui/host.ui b/ui/host.ui
index e1e2088..07b06a1 100644
--- a/ui/host.ui
+++ b/ui/host.ui
@@ -1091,6 +1091,252 @@
                                     <property name="position">2</property>
                                   </packing>
                                 </child>
+                                <child>
+                                  <object class="GtkExpander" id="net-qos-expander">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <child>
+                                      <object class="GtkBox" id="box14">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="orientation">vertical</property>
+                                        <child>
+                                          <object class="GtkCheckButton" id="net-qos-inbound-enable">
+                                            <property name="label" translatable="yes">Enable inbound QoS</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">False</property>
+                                            <property name="xalign">0</property>
+                                            <property name="draw_indicator">True</property>
+                                            <signal name="toggled" handler="on_net_qos_inbound_enable_toggled" swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">True</property>
+                                            <property name="position">0</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkGrid" id="net-qos-inbound-grid">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">False</property>
+                                            <property name="row_spacing">5</property>
+                                            <property name="column_spacing">6</property>
+                                            <child>
+                                              <object class="GtkEntry" id="qos-inbound-peak">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">True</property>
+                                                <signal name="changed" handler="on_qos_inbound_peak_changed" swapped="no"/>
+                                              </object>
+                                              <packing>
+                                                <property name="left_attach">1</property>
+                                                <property name="top_attach">1</property>
+                                                <property name="width">1</property>
+                                                <property name="height">1</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <object class="GtkEntry" id="qos-inbound-burst">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">True</property>
+                                                <signal name="changed" handler="on_qos_inbound_burst_changed" swapped="no"/>
+                                              </object>
+                                              <packing>
+                                                <property name="left_attach">1</property>
+                                                <property name="top_attach">2</property>
+                                                <property name="width">1</property>
+                                                <property name="height">1</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <object class="GtkLabel" id="label35">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">False</property>
+                                                <property name="xalign">0</property>
+                                                <property name="label" translatable="yes">Average (KiB/sec):</property>
+                                              </object>
+                                              <packing>
+                                                <property name="left_attach">0</property>
+                                                <property name="top_attach">0</property>
+                                                <property name="width">1</property>
+                                                <property name="height">1</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <object class="GtkLabel" id="label36">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">False</property>
+                                                <property name="xalign">0</property>
+                                                <property name="label" translatable="yes">Burst (KiB):</property>
+                                              </object>
+                                              <packing>
+                                                <property name="left_attach">0</property>
+                                                <property name="top_attach">2</property>
+                                                <property name="width">1</property>
+                                                <property name="height">1</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <object class="GtkEntry" id="qos-inbound-average">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">True</property>
+                                                <signal name="changed" handler="on_qos_inbound_average_changed" swapped="no"/>
+                                              </object>
+                                              <packing>
+                                                <property name="left_attach">1</property>
+                                                <property name="top_attach">0</property>
+                                                <property name="width">1</property>
+                                                <property name="height">1</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <object class="GtkLabel" id="label37">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">False</property>
+                                                <property name="xalign">0</property>
+                                                <property name="label" translatable="yes">Peak (KiB/sec):</property>
+                                              </object>
+                                              <packing>
+                                                <property name="left_attach">0</property>
+                                                <property name="top_attach">1</property>
+                                                <property name="width">1</property>
+                                                <property name="height">1</property>
+                                              </packing>
+                                            </child>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">True</property>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkCheckButton" id="net-qos-outbound-enable">
+                                            <property name="label" translatable="yes">Enable outbound QoS</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">False</property>
+                                            <property name="xalign">0</property>
+                                            <property name="draw_indicator">True</property>
+                                            <signal name="toggled" handler="on_net_qos_outbound_enable_toggled" swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">True</property>
+                                            <property name="position">2</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkGrid" id="net-qos-outbound-grid">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">False</property>
+                                            <property name="row_spacing">5</property>
+                                            <property name="column_spacing">6</property>
+                                            <child>
+                                              <object class="GtkEntry" id="qos-outbound-peak">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">True</property>
+                                                <signal name="changed" handler="on_qos_outbound_peak_changed" swapped="no"/>
+                                              </object>
+                                              <packing>
+                                                <property name="left_attach">1</property>
+                                                <property name="top_attach">1</property>
+                                                <property name="width">1</property>
+                                                <property name="height">1</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <object class="GtkEntry" id="qos-outbound-burst">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">True</property>
+                                                <signal name="changed" handler="on_qos_outbound_burst_changed" swapped="no"/>
+                                              </object>
+                                              <packing>
+                                                <property name="left_attach">1</property>
+                                                <property name="top_attach">2</property>
+                                                <property name="width">1</property>
+                                                <property name="height">1</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <object class="GtkEntry" id="qos-outbound-average">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">True</property>
+                                                <signal name="changed" handler="on_qos_outbound_average_changed" swapped="no"/>
+                                              </object>
+                                              <packing>
+                                                <property name="left_attach">1</property>
+                                                <property name="top_attach">0</property>
+                                                <property name="width">1</property>
+                                                <property name="height">1</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <object class="GtkLabel" id="label42">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">False</property>
+                                                <property name="xalign">0</property>
+                                                <property name="label" translatable="yes">Burst (KiB/sec):</property>
+                                              </object>
+                                              <packing>
+                                                <property name="left_attach">0</property>
+                                                <property name="top_attach">2</property>
+                                                <property name="width">1</property>
+                                                <property name="height">1</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <object class="GtkLabel" id="label44">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">False</property>
+                                                <property name="xalign">0</property>
+                                                <property name="label" translatable="yes">Peak (KiB/sec):</property>
+                                              </object>
+                                              <packing>
+                                                <property name="left_attach">0</property>
+                                                <property name="top_attach">1</property>
+                                                <property name="width">1</property>
+                                                <property name="height">1</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <object class="GtkLabel" id="label45">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">False</property>
+                                                <property name="xalign">0</property>
+                                                <property name="label" translatable="yes">Average (KiB/sec):</property>
+                                              </object>
+                                              <packing>
+                                                <property name="left_attach">0</property>
+                                                <property name="top_attach">0</property>
+                                                <property name="width">1</property>
+                                                <property name="height">1</property>
+                                              </packing>
+                                            </child>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">True</property>
+                                            <property name="position">3</property>
+                                          </packing>
+                                        </child>
+                                      </object>
+                                    </child>
+                                    <child type="label">
+                                      <object class="GtkLabel" id="label38">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="label" translatable="yes"><b>QoS configuration</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">3</property>
+                                  </packing>
+                                </child>
                               </object>
                             </child>
                           </object>
diff --git a/virtManager/host.py b/virtManager/host.py
index 4166929..3c53a20 100644
--- a/virtManager/host.py
+++ b/virtManager/host.py
@@ -43,10 +43,11 @@ INTERFACE_PAGE_ERROR = 1
 
 (EDIT_NET_NAME,
 EDIT_NET_AUTOSTART,
+EDIT_NET_QOS,
 
 EDIT_POOL_NAME,
 EDIT_POOL_AUTOSTART,
-) = range(4)
+) = range(5)
 
 
 class vmmHost(vmmGObjectUI):
@@ -127,6 +128,22 @@ class vmmHost(vmmGObjectUI):
             "on_interface_list_changed": self.interface_selected,
 
             "on_config_autoconnect_toggled": self.toggle_autoconnect,
+
+            "on_qos_inbound_average_changed":  (lambda *x:
+                self.enable_net_apply(x, EDIT_NET_QOS)),
+            "on_qos_inbound_peak_changed":  (lambda *x:
+                self.enable_net_apply(x, EDIT_NET_QOS)),
+            "on_qos_inbound_burst_changed":  (lambda *x:
+                self.enable_net_apply(x, EDIT_NET_QOS)),
+            "on_qos_outbound_average_changed":  (lambda *x:
+                self.enable_net_apply(x, EDIT_NET_QOS)),
+            "on_qos_outbound_peak_changed":  (lambda *x:
+                self.enable_net_apply(x, EDIT_NET_QOS)),
+            "on_qos_outbound_burst_changed":  (lambda *x:
+                self.enable_net_apply(x, EDIT_NET_QOS)),
+
+            "on_net_qos_inbound_enable_toggled": self.change_qos_in_enable,
+            "on_net_qos_outbound_enable_toggled": self.change_qos_out_enable,
         })
 
         self.repopulate_networks()
@@ -481,6 +498,33 @@ class vmmHost(vmmGObjectUI):
             if EDIT_NET_NAME in self.active_edits:
                 net.define_name(self.widget("net-name").get_text())
                 self.repopulate_networks()
+            if EDIT_NET_QOS in self.active_edits:
+                in_qos = self.widget("net-qos-inbound-enable").get_active()
+                out_qos = self.widget("net-qos-outbound-enable").get_active()
+
+                def get_value(name, enabled):
+                    if not enabled:
+                        return None
+                    return self.widget(name).get_text() or None
+
+                args = {}
+                args['inbound_average'] = get_value("qos-inbound-average", in_qos)
+                args['inbound_peak'] = get_value("qos-inbound-peak", in_qos)
+                args['inbound_burst'] = get_value("qos-inbound-burst", in_qos)
+
+                args['outbound_average'] = get_value("qos-outbound-average", out_qos)
+                args['outbound_peak'] = get_value("qos-outbound-peak", out_qos)
+                args['outbound_burst'] = get_value("qos-outbound-burst", out_qos)
+
+                if net.set_qos(**args):
+                    self.err.show_err(
+                        _("Network could not be updated"),
+                        text2=_("This change will take effect when the "
+                                "network is restarted"),
+                        buttons=Gtk.ButtonsType.OK,
+                        dialog_type=Gtk.MessageType.INFO)
+
+
         except Exception, e:
             self.err.show_err(_("Error changing network settings: %s") % str(e))
             return
@@ -615,6 +659,37 @@ class vmmHost(vmmGObjectUI):
             routevia = routeaddr + ", gateway=" + routevia
             self.widget("net-ipv6-route").set_text(routevia or "")
 
+    def update_qos_widgets(self):
+        enabled = self.widget("net-qos-inbound-enable").get_active()
+        self.widget("net-qos-inbound-grid").set_visible(enabled)
+
+        enabled = self.widget("net-qos-outbound-enable").get_active()
+        self.widget("net-qos-outbound-grid").set_visible(enabled)
+
+    def change_qos_in_enable(self, ignore):
+        self.enable_net_apply(EDIT_NET_QOS)
+        self.update_qos_widgets()
+
+    def change_qos_out_enable(self, ignore):
+        self.enable_net_apply(EDIT_NET_QOS)
+        self.update_qos_widgets()
+
+    def _populate_qos_state(self, net):
+        qos = net.get_qos()
+
+        self.widget("net-qos-inbound-enable").set_active(qos.is_inbound())
+        self.widget("net-qos-outbound-enable").set_active(qos.is_outbound())
+
+        self.update_qos_widgets()
+
+        self.widget("qos-inbound-average").set_text(qos.inbound_average or "")
+        self.widget("qos-inbound-peak").set_text(qos.inbound_peak or "")
+        self.widget("qos-inbound-burst").set_text(qos.inbound_burst or "")
+
+        self.widget("qos-outbound-average").set_text(qos.outbound_average or "")
+        self.widget("qos-outbound-peak").set_text(qos.outbound_peak or "")
+        self.widget("qos-outbound-burst").set_text(qos.outbound_burst or "")
+
     def populate_net_state(self, net):
         active = net.is_active()
 
@@ -644,6 +719,7 @@ class vmmHost(vmmGObjectUI):
 
         self._populate_net_ipv4_state(net)
         self._populate_net_ipv6_state(net)
+        self._populate_qos_state(net)
 
 
     def reset_net_state(self):
diff --git a/virtManager/network.py b/virtManager/network.py
index 163a0c0..4ad4c94 100644
--- a/virtManager/network.py
+++ b/virtManager/network.py
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2006, 2013 Red Hat, Inc.
+# Copyright (C) 2006, 2013-2014 Red Hat, Inc.
 # Copyright (C) 2006 Daniel P. Berrange <berrange at redhat.com>
 #
 # This program is free software; you can redistribute it and/or modify
@@ -121,6 +121,17 @@ class vmmNetwork(vmmLibvirtObject):
     def tick(self):
         self.force_update_status()
 
+    def set_qos(self, **kwargs):
+        q = self.get_qos()
+        for key, val in kwargs.items():
+            setattr(q, key, val)
+
+        xml = self.get_xml()
+
+        self._redefine_xml(xml)
+        return self.is_active()
+
+
     def define_name(self, newname):
         return self._define_name_helper("network",
                                         self.conn.rename_network,
@@ -143,6 +154,8 @@ class vmmNetwork(vmmLibvirtObject):
         return self.get_xmlobj().forward.mode
     def pretty_forward_mode(self):
         return self.get_xmlobj().forward.pretty_desc()
+    def get_qos(self):
+        return self.get_xmlobj().bandwidth
 
     def can_pxe(self):
         return self.get_xmlobj().can_pxe()
-- 
1.9.3




More information about the virt-tools-list mailing list