[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