[virt-tools-list] [PATCH virt-manager 3/5] virtManager, createnet: support QoS

Giuseppe Scrivano gscrivan at redhat.com
Wed Jun 25 11:05:48 UTC 2014


Add UI elements to specify QoS when creating a new network

Signed-off-by: Giuseppe Scrivano <gscrivan at redhat.com>
---
 ui/createnet.ui          | 292 +++++++++++++++++++++++++++++++++++++++++++++++
 virtManager/createnet.py | 107 ++++++++++++++++-
 2 files changed, 397 insertions(+), 2 deletions(-)

diff --git a/ui/createnet.ui b/ui/createnet.ui
index 1596241..ccd0876 100644
--- a/ui/createnet.ui
+++ b/ui/createnet.ui
@@ -1440,6 +1440,298 @@
                     <property name="tab_fill">False</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkVBox" id="vbox1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="label8">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes"><b>Quality of Service</b></property>
+                        <property name="use_markup">True</property>
+                        <property name="wrap">True</property>
+                        <property name="max_width_chars">50</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkAlignment" id="alignment5">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="left_padding">15</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="grid3">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <object class="GtkEntry" id="qos-inbound-peak">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                  </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>
+                                  </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-inbound-floor">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                  </object>
+                                  <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="top_attach">3</property>
+                                    <property name="width">1</property>
+                                    <property name="height">1</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="label9">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Average (kilobytes/second):</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="label10">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Burst (kilobytes):</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>
+                                  </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="label15">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Peak (kilobytes/second):</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="label16">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Floor (kilobytes/second):</property>
+                                  </object>
+                                  <packing>
+                                    <property name="left_attach">0</property>
+                                    <property name="top_attach">3</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="grid4">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <object class="GtkEntry" id="qos-outbound-peak">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                  </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>
+                                  </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>
+                                  </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="label18">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Burst (kilobytes):</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="label21">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Peak (kilobytes/second):</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="label17">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">Average (kilobytes/second):</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>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">4</property>
+                  </packing>
+                </child>
+                <child type="tab">
+                  <object class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">QoS</property>
+                  </object>
+                  <packing>
+                    <property name="position">4</property>
+                    <property name="tab_fill">False</property>
+                  </packing>
+                </child>
               </object>
               <packing>
                 <property name="expand">True</property>
diff --git a/virtManager/createnet.py b/virtManager/createnet.py
index 0bc2fd6..d4bc063 100644
--- a/virtManager/createnet.py
+++ b/virtManager/createnet.py
@@ -35,7 +35,10 @@ from virtManager.baseclass import vmmGObjectUI
 (PAGE_NAME,
 PAGE_IPV4,
 PAGE_IPV6,
-PAGE_MISC) = range(4)
+PAGE_MISC,
+PAGE_QOS) = range(5)
+
+PAGE_MAX = PAGE_QOS
 
 _green = Gdk.Color.parse("#c0ffc0")[1]
 _red = Gdk.Color.parse("#ffc0c0")[1]
@@ -87,6 +90,9 @@ class vmmCreateNetwork(vmmGObjectUI):
             "on_net-routev6-enable_toggled":  self.change_routev6_enable,
             "on_net-routev6-network_changed": self.change_routev6_network,
             "on_net-routev6-gateway_changed": self.change_routev6_gateway,
+
+            "on_net-qos-inbound-enable_toggled": self.change_qos_in_enable,
+            "on_net-qos-outbound-enable_toggled": self.change_qos_out_enable,
         })
         self.bind_escape_key_close()
 
@@ -185,6 +191,18 @@ class vmmCreateNetwork(vmmGObjectUI):
         self.widget("net-forward-none").set_active(True)
 
 
+        self.widget("net-qos-inbound-enable").set_active(False)
+        self.widget("qos-inbound-average").set_sensitive(False)
+        self.widget("qos-inbound-peak").set_sensitive(False)
+        self.widget("qos-inbound-burst").set_sensitive(False)
+        self.widget("qos-inbound-floor").set_sensitive(False)
+
+        self.widget("net-qos-outbound-enable").set_active(False)
+        self.widget("qos-outbound-average").set_sensitive(False)
+        self.widget("qos-outbound-peak").set_sensitive(False)
+        self.widget("qos-outbound-burst").set_sensitive(False)
+
+
     ##################
     # UI get helpers #
     ##################
@@ -201,6 +219,25 @@ class vmmCreateNetwork(vmmGObjectUI):
         return self.widget("net-routev4-enable").get_active()
     def get_config_routev6_enable(self):
         return self.widget("net-routev6-enable").get_active()
+    def get_config_inbound_qos_enable(self):
+        return self.widget("net-qos-inbound-enable").get_active()
+    def get_config_outbound_qos_enable(self):
+        return self.widget("net-qos-outbound-enable").get_active()
+
+    def get_config_inbound_average(self):
+        return self.widget("qos-inbound-average").get_text()
+    def get_config_inbound_peak(self):
+        return self.widget("qos-inbound-peak").get_text()
+    def get_config_inbound_burst(self):
+        return self.widget("qos-inbound-burst").get_text()
+    def get_config_inbound_floor(self):
+        return self.widget("qos-inbound-floor").get_text()
+    def get_config_outbound_average(self):
+        return self.widget("qos-outbound-average").get_text()
+    def get_config_outbound_peak(self):
+        return self.widget("qos-outbound-peak").get_text()
+    def get_config_outbound_burst(self):
+        return self.widget("qos-outbound-burst").get_text()
 
     def _get_network_helper(self, widgetname):
         widget = self.widget(widgetname)
@@ -435,6 +472,41 @@ class vmmCreateNetwork(vmmGObjectUI):
 
         return True
 
+    def validate_qos(self):
+        def check(val, err):
+            if len(val) and not val.isdigit():
+                return self.err.val_err(err)
+            return True
+
+        inbound_qos_enable = self.get_config_inbound_qos_enable()
+        if inbound_qos_enable:
+            if not check(self.get_config_inbound_average(),
+                         _("Invalid value for inbound average")):
+                return False
+            if not check(self.get_config_inbound_peak(),
+                         _("Invalid value for inbound peak")):
+                return False
+            if not check(self.get_config_inbound_burst(),
+                         _("Invalid value for inbound burst")):
+                return False
+            if not check(self.get_config_inbound_floor(),
+                         _("Invalid value for inbound floor")):
+                return False
+
+        outbound_qos_enable = self.get_config_outbound_qos_enable()
+        if outbound_qos_enable:
+            if not check(self.get_config_outbound_average(),
+                         _("Invalid value for outbound average")):
+                return False
+            if not check(self.get_config_outbound_peak(),
+                         _("Invalid value for outbound peak")):
+                return False
+            if not check(self.get_config_outbound_burst(),
+                         _("Invalid value for outbound burst")):
+                return False
+
+        return True
+
     def validate(self, page_num):
         if page_num == PAGE_NAME:
             return self.validate_name()
@@ -444,6 +516,8 @@ class vmmCreateNetwork(vmmGObjectUI):
             return self.validate_ipv6()
         elif page_num == PAGE_MISC:
             return self.validate_miscellaneous()
+        elif page_num == PAGE_QOS:
+            return self.validate_qos()
         return True
 
 
@@ -467,7 +541,7 @@ class vmmCreateNetwork(vmmGObjectUI):
         page_lbl = ("<span color='#59B0E2'>%s</span>" %
                     _("Step %(current_page)d of %(max_page)d") %
                     {'current_page': page_number + 1,
-                     'max_page': PAGE_MISC + 1})
+                     'max_page': PAGE_MAX})
         self.widget("header-pagenum").set_markup(page_lbl)
 
         if page_number == PAGE_NAME:
@@ -527,6 +601,20 @@ class vmmCreateNetwork(vmmGObjectUI):
         uiutil.set_grid_row_visible(start, enabled)
         uiutil.set_grid_row_visible(end, enabled)
 
+    def change_qos_in_enable(self, ignore):
+        enabled = self.get_config_inbound_qos_enable()
+        self.widget("qos-inbound-average").set_sensitive(enabled)
+        self.widget("qos-inbound-peak").set_sensitive(enabled)
+        self.widget("qos-inbound-burst").set_sensitive(enabled)
+        self.widget("qos-inbound-floor").set_sensitive(enabled)
+
+    def change_qos_out_enable(self, ignore):
+        enabled = self.get_config_outbound_qos_enable()
+        self.widget("qos-outbound-average").set_sensitive(enabled)
+        self.widget("qos-outbound-peak").set_sensitive(enabled)
+        self.widget("qos-outbound-burst").set_sensitive(enabled)
+
+
     def change_dhcpv4_start(self, src):
         start = self.get_config_dhcpv4_start()
         self.change_dhcpv4(src, start)
@@ -735,6 +823,21 @@ class vmmCreateNetwork(vmmGObjectUI):
             route.prefix = netaddr.prefixlen
             route.gateway = gwaddr.network
 
+        inbound_qos_enable = self.get_config_inbound_qos_enable()
+        outbound_qos_enable = self.get_config_outbound_qos_enable()
+        if inbound_qos_enable or outbound_qos_enable:
+            b = net.bandwidth
+            if inbound_qos_enable:
+                b.inbound_average = self.get_config_inbound_average() or None
+                b.inbound_peak = self.get_config_inbound_peak() or None
+                b.inbound_burst = self.get_config_inbound_burst() or None
+                b.inbound_floor = self.get_config_inbound_floor() or None
+
+            if outbound_qos_enable:
+                b.outbound_average = self.get_config_outbound_average() or None
+                b.outbound_peak = self.get_config_outbound_peak() or None
+                b.outbound_burst = self.get_config_outbound_burst() or None
+
         return net
 
     def _finish_cb(self, error, details):
-- 
1.9.3




More information about the virt-tools-list mailing list