[node-patches] Change in ovirt-node[master]: ui: Add and use TransactionProgressDialog

fabiand at fedoraproject.org fabiand at fedoraproject.org
Tue Dec 11 20:09:44 UTC 2012


Fabian Deutsch has uploaded a new change for review.

Change subject: ui: Add and use TransactionProgressDialog
......................................................................

ui: Add and use TransactionProgressDialog

To easily track the progress of a transaction relies on proper
Transaction.Elements.

Change-Id: I7c70f83e8c7705e38eb0cc6f81e46bbba1a42f44
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
---
M scripts/tui/src/ovirt/node/config/defaults.py
M scripts/tui/src/ovirt/node/setup/engine_page.py
M scripts/tui/src/ovirt/node/setup/kdump_page.py
M scripts/tui/src/ovirt/node/setup/keyboard_page.py
M scripts/tui/src/ovirt/node/setup/logging_page.py
M scripts/tui/src/ovirt/node/setup/monitoring_page.py
M scripts/tui/src/ovirt/node/setup/network_page.py
M scripts/tui/src/ovirt/node/setup/remote_storage_page.py
M scripts/tui/src/ovirt/node/setup/security_page.py
M scripts/tui/src/ovirt/node/setup/snmp_page.py
M scripts/tui/src/ovirt/node/ui/__init__.py
M scripts/tui/src/ovirt/node/ui/builder.py
M scripts/tui/src/ovirt/node/ui/tui.py
M scripts/tui/src/ovirt/node/ui/widgets.py
M scripts/tui/src/ovirt/node/utils/system.py
15 files changed, 131 insertions(+), 65 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/76/9976/1

diff --git a/scripts/tui/src/ovirt/node/config/defaults.py b/scripts/tui/src/ovirt/node/config/defaults.py
index b6084eb..d22bb65 100644
--- a/scripts/tui/src/ovirt/node/config/defaults.py
+++ b/scripts/tui/src/ovirt/node/config/defaults.py
@@ -323,7 +323,6 @@
             def commit(self):
                 utils.AugeasWrapper.force_reload()
 
-
         tx = utils.Transaction("Applying new network configuration")
         tx.append(ConfigureNIC())
         tx.append(ReloadNetworkConfiguration())
@@ -369,6 +368,8 @@
 
     def __legacy_transaction(self):
         class ConfigureNameservers(utils.Transaction.Element):
+            title = "Setting namservers"
+
             def commit(self):
                 import ovirtnode.network as onet
                 net = onet.Network()
@@ -405,7 +406,7 @@
         servers = servers.split(",")
 
         class UpdateResolvConf(utils.Transaction.Element):
-            title = "Updateing resolv.conf"
+            title = "Updating resolv.conf"
 
             def commit(self):
                 # Write resolv.conf any way, sometimes without servers
@@ -474,6 +475,8 @@
 
     def __legacy_transaction(self):
         class ConfigureTimeservers(utils.Transaction.Element):
+            title = "Setting timeservers"
+
             def commit(self):
                 import ovirtnode.network as onet
                 net = onet.Network()
@@ -512,6 +515,8 @@
         server, port = (cfg["server"], cfg["port"])
 
         class CreateRsyslogConfig(utils.Transaction.Element):
+            title = "Setting syslog server and port"
+
             def commit(self):
                 import ovirtnode.log as olog
                 olog.ovirt_rsyslog(server, port, "udp")
@@ -549,6 +554,8 @@
         server, port = (cfg["server"], cfg["port"])
 
         class ConfigureCollectd(utils.Transaction.Element):
+            title = "Setting collect server and port"
+
             def commit(self):
                 import ovirt_config_setup.collectd as ocollectd
                 if ocollectd.write_collectd_config(server, port):
@@ -621,6 +628,8 @@
         nfs, ssh, restore = (cfg["nfs"], cfg["ssh"], cfg["local"])
 
         class BackupKdumpConfig(utils.Transaction.Element):
+            title = "Backing up config files"
+
             def __init__(self):
                 self.backups = utils.fs.BackupedFiles(["/etc/kdump.conf"])
 
@@ -628,16 +637,22 @@
                 self.backups.create()
 
         class RestoreKdumpConfig(utils.Transaction.Element):
+            title = "Restoring default kdump config"
+
             def commit(self):
                 import ovirtnode.kdump as okdump
                 okdump.restore_kdump_config()
 
         class CreateNfsKdumpConfig(utils.Transaction.Element):
+            title = "Creating kdump NFS config"
+
             def commit(self):
                 import ovirtnode.kdump as okdump
                 okdump.write_kdump_config(nfs)
 
         class CreateSshKdumpConfig(utils.Transaction.Element):
+            title = "Creating kdump SSH config"
+
             def commit(self):
                 import ovirtnode.kdump as okdump
                 from ovirtnode.ovirtfunctions import ovirt_store_config
@@ -662,6 +677,8 @@
                                         "SSH: %s" % stdout)
 
         class RemoveKdumpConfig(utils.Transaction.Element):
+            title = "Removing kdump backup"
+
             def __init__(self, backups):
                 self.backups = backups
 
@@ -675,6 +692,8 @@
                 self.backups.remove()
 
         class RestartKdumpService(utils.Transaction.Element):
+            title = "Restarting kdump service"
+
             def __init__(self, backups):
                 self.backups = backups
 
@@ -705,7 +724,7 @@
             tx.append(CreateNfsKdumpConfig())
         elif ssh:
             tx.append(CreateSshKdumpConfig())
-        elif restore:
+        elif restore in [True, False]:
             tx.append(RestoreKdumpConfig())
         else:
             final_txe = RemoveKdumpConfig(backup_txe.backups)
@@ -747,6 +766,8 @@
         initiator_name = cfg["name"]
 
         class ConfigureIscsiInitiator(utils.Transaction.Element):
+            title = "Setting the iSCSI initiator name"
+
             def commit(self):
                 iscsi = utils.storage.iSCSI()
                 iscsi.initiator_name(initiator_name)
@@ -778,6 +799,8 @@
         password = cfg["password"]
 
         class ConfigureSNMP(utils.Transaction.Element):
+            title = "Enabling/Disabling SNMP and setting the password"
+
             def commit(self):
                 # FIXME snmp plugin needs to be placed somewhere else (in src)
                 import ovirt_config_setup.snmp as osnmp
@@ -816,6 +839,8 @@
         server, port = (cfg["server"], cfg["port"])
 
         class CreateNetconsoleConfig(utils.Transaction.Element):
+            title = "Setting netconsole server and port"
+
             def commit(self):
                 import ovirtnode.log as olog
                 olog.ovirt_netconsole(server, port, "udp")
@@ -848,6 +873,8 @@
         max_size = cfg["max_size"]
 
         class CreateLogrotateConfig(utils.Transaction.Element):
+            title = "Setting logrotate maximum logfile size"
+
             def commit(self):
                 import ovirtnode.log as olog
                 olog.set_logrotate_size(max_size)
@@ -899,7 +926,7 @@
 
         # FIXME setting password is missing
 
-        tx = utils.Transaction("Configuring SNMP")
+        tx = utils.Transaction("Configuring CIM")
         tx.append(ConfigureCIM())
         return tx
 
@@ -928,6 +955,8 @@
         layout = cfg["layout"]
 
         class CreateKeyboardConfig(utils.Transaction.Element):
+            title = "Setting keyboard layout"
+
             def commit(self):
                 from ovirtnode.ovirtfunctions import ovirt_store_config
                 kbd = utils.Keyboard()
@@ -964,6 +993,8 @@
         domain = cfg["domain"]
 
         class ConfigureNfsv4(utils.Transaction.Element):
+            title = "Setting NFSv4 domain"
+
             def commit(self):
                 from ovirtnode.network import set_nfsv4_domain
                 set_nfsv4_domain(domain)
@@ -1019,16 +1050,19 @@
 
         class ConfigurePasswordAuthentication(utils.Transaction.Element):
             title = "Configuring SSH password authentication"
+
             def commit(self):
                 ssh.password_authentication(pwauth)
 
         class ConfigureStrongRNG(utils.Transaction.Element):
-            title = "Configuring strong RNG"
+            title = "Configuring SSH strong RNG"
+
             def commit(self):
                 ssh.strong_rng(num_bytes)
 
         class ConfigureAESNI(utils.Transaction.Element):
-            title = "Configuring AES NI"
+            title = "Configuring SSH AES NI"
+
             def commit(self):
                 ssh.disable_aesni(disable_aesni)
 
diff --git a/scripts/tui/src/ovirt/node/setup/engine_page.py b/scripts/tui/src/ovirt/node/setup/engine_page.py
index a522d86..2f461b9 100644
--- a/scripts/tui/src/ovirt/node/setup/engine_page.py
+++ b/scripts/tui/src/ovirt/node/setup/engine_page.py
@@ -91,3 +91,8 @@
 
     def on_merge(self, effective_changes):
         pass
+
+        txs = utils.Transaction("Configuring oVirt Engine")
+
+        progress_dialog = ui.TransactionProgressDialog(txs, self)
+        progress_dialog.run()
diff --git a/scripts/tui/src/ovirt/node/setup/kdump_page.py b/scripts/tui/src/ovirt/node/setup/kdump_page.py
index 846e05b..0cd93de 100644
--- a/scripts/tui/src/ovirt/node/setup/kdump_page.py
+++ b/scripts/tui/src/ovirt/node/setup/kdump_page.py
@@ -139,5 +139,5 @@
                 model.update(None, None, None)
             txs += model.transaction()
 
-        txs.prepare()  # Just to display something in dry mode
-        self.dry_or(lambda: txs())
+        progress_dialog = ui.TransactionProgressDialog(txs, self)
+        progress_dialog.run()
diff --git a/scripts/tui/src/ovirt/node/setup/keyboard_page.py b/scripts/tui/src/ovirt/node/setup/keyboard_page.py
index 89e8cfc..5ae835c 100644
--- a/scripts/tui/src/ovirt/node/setup/keyboard_page.py
+++ b/scripts/tui/src/ovirt/node/setup/keyboard_page.py
@@ -86,5 +86,5 @@
             model.update(*effective_model.get_key_values(layout_keys))
             txs += model.transaction()
 
-        txs.prepare()  # Just to display something in dry mode
-        self.dry_or(lambda: txs())
+        progress_dialog = ui.TransactionProgressDialog(txs, self)
+        progress_dialog.run()
diff --git a/scripts/tui/src/ovirt/node/setup/logging_page.py b/scripts/tui/src/ovirt/node/setup/logging_page.py
index ee25e88..7147e19 100644
--- a/scripts/tui/src/ovirt/node/setup/logging_page.py
+++ b/scripts/tui/src/ovirt/node/setup/logging_page.py
@@ -133,5 +133,5 @@
             model.update(*effective_model.get_key_values(netconsole_keys))
             txs += model.transaction()
 
-        txs.prepare()  # Just to display something in dry mode
-        self.dry_or(lambda: txs())
+        progress_dialog = ui.TransactionProgressDialog(txs, self)
+        progress_dialog.run()
diff --git a/scripts/tui/src/ovirt/node/setup/monitoring_page.py b/scripts/tui/src/ovirt/node/setup/monitoring_page.py
index 14f35e8..4967517 100644
--- a/scripts/tui/src/ovirt/node/setup/monitoring_page.py
+++ b/scripts/tui/src/ovirt/node/setup/monitoring_page.py
@@ -91,5 +91,5 @@
             model.update(*effective_model.get_key_values(collectd_keys))
             txs += model.transaction()
 
-        txs.prepare()
-        self.dry_or(lambda: txs())
+        progress_dialog = ui.TransactionProgressDialog(txs, self)
+        progress_dialog.run()
diff --git a/scripts/tui/src/ovirt/node/setup/network_page.py b/scripts/tui/src/ovirt/node/setup/network_page.py
index 4cd9d91..5f502e2 100644
--- a/scripts/tui/src/ovirt/node/setup/network_page.py
+++ b/scripts/tui/src/ovirt/node/setup/network_page.py
@@ -25,7 +25,6 @@
 from ovirt.node import plugins, ui, valid, utils
 from ovirt.node.config import defaults
 import ovirt.node.utils.network
-import time
 
 
 class Plugin(ovirt.node.plugins.NodePlugin):
@@ -274,19 +273,6 @@
             self.logger.debug("Save and close NIC")
             self._nic_dialog.close()
 
-        def set_progress(txt):
-            set_progress.txt += txt + "\n"
-            progress.set_text(set_progress.txt)
-        set_progress.txt = "Applying changes ...\n"
-
-        progress = ui.Label(set_progress.txt)
-        _d = self._build_dialog("dialog.dia",
-                                                               "fooo", [
-            ("dialog.dia.text[0]", progress),
-            ])
-        _d.buttons = []
-        d = self.application.ui.show_dialog(_d)
-
         # This object will contain all transaction elements to be executed
         txs = utils.Transaction("DNS and NTP configuration")
 
@@ -321,16 +307,8 @@
             args = helper.get_key_values(self._nic_details_group)
             txs += self._configure_nic(*args)
 
-        # Commit all outstanding transactions
-        txs.prepare()  # Just to display something in dry mode
-        for idx, e in enumerate(txs):
-            n = "(%s/%s) " % (idx + 1, len(txs))
-            set_progress(n + e.title)
-            self.dry_or(lambda: e.commit())
-
-        set_progress("All changes were applied.")
-        time.sleep(3)
-        d.close()
+        progress_dialog = ui.TransactionProgressDialog(txs, self)
+        progress_dialog.run()
 
         # Behaves like a page reload
         return self.ui_content()
diff --git a/scripts/tui/src/ovirt/node/setup/remote_storage_page.py b/scripts/tui/src/ovirt/node/setup/remote_storage_page.py
index 55801c0..57c4823 100644
--- a/scripts/tui/src/ovirt/node/setup/remote_storage_page.py
+++ b/scripts/tui/src/ovirt/node/setup/remote_storage_page.py
@@ -96,5 +96,5 @@
             model.update(*args)
             txs += model.transaction()
 
-        txs.prepare()  # Just to display something in dry mode
-        self.dry_or(lambda: txs())
+        progress_dialog = ui.TransactionProgressDialog(txs, self)
+        progress_dialog.run()
diff --git a/scripts/tui/src/ovirt/node/setup/security_page.py b/scripts/tui/src/ovirt/node/setup/security_page.py
index 47d88fd..b58ddee 100644
--- a/scripts/tui/src/ovirt/node/setup/security_page.py
+++ b/scripts/tui/src/ovirt/node/setup/security_page.py
@@ -124,5 +124,5 @@
                     passwd.set_password("admin", pw)
             txs += [SetAdminPasswd()]
 
-        txs.prepare()  # Just to display something in dry mode
-        self.dry_or(lambda: txs())
+        progress_dialog = ui.TransactionProgressDialog(txs, self)
+        progress_dialog.run()
diff --git a/scripts/tui/src/ovirt/node/setup/snmp_page.py b/scripts/tui/src/ovirt/node/setup/snmp_page.py
index d2fc9ab..0e8cb5d 100644
--- a/scripts/tui/src/ovirt/node/setup/snmp_page.py
+++ b/scripts/tui/src/ovirt/node/setup/snmp_page.py
@@ -105,5 +105,5 @@
             model.update(*args)
             txs += model.transaction()
 
-        txs.prepare()
-        self.dry_or(lambda: txs())
+        progress_dialog = ui.TransactionProgressDialog(txs, self)
+        progress_dialog.run()
diff --git a/scripts/tui/src/ovirt/node/ui/__init__.py b/scripts/tui/src/ovirt/node/ui/__init__.py
index dddc8e4..359b059 100644
--- a/scripts/tui/src/ovirt/node/ui/__init__.py
+++ b/scripts/tui/src/ovirt/node/ui/__init__.py
@@ -18,12 +18,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA  02110-1301, USA.  A copy of the GNU General Public License is
 # also available at http://www.gnu.org/copyleft/gpl.html.
+from ovirt.node import base
 
 """
 This contains abstract UI Elements
 """
-
-from ovirt.node import base
 
 
 # http://stackoverflow.com/questions/739654/understanding-python-decorators
@@ -76,10 +75,12 @@
     """An abstract container Element containing other Elements
     """
     children = []
+    title = None
 
-    def __init__(self, children):
+    def __init__(self, children, title=None):
         super(ContainerElement, self).__init__()
         self.children = children
+        self.title = title
 
     def children(self, v=None):
         if v:
@@ -92,8 +93,8 @@
     """
     buttons = []
 
-    def __init__(self, children):
-        super(Page, self).__init__(children)
+    def __init__(self, children, title=None):
+        super(Page, self).__init__(children, title)
         self.buttons = self.buttons or [
                         (None, SaveButton()),
                         (None, ResetButton())
@@ -107,8 +108,7 @@
     escape_key = "esc"
 
     def __init__(self, title, children):
-        super(Dialog, self).__init__(children)
-        self.title = title
+        super(Dialog, self).__init__(children, title)
         self.close(False)
 
     @Element.signal_change
@@ -354,3 +354,39 @@
 
     def run(self):
         raise NotImplementedError
+
+
+class TransactionProgressDialog(Dialog):
+    def __init__(self, transaction, plugin, initial_text=""):
+        self.transaction = transaction
+        self.texts = [initial_text, ""]
+        self.plugin = plugin
+
+        self._close_button = CloseButton()
+        self.buttons = [(None, self._close_button)]
+        self._progress_label = Label(initial_text)
+        widgets = [("dialog.progress", self._progress_label)]
+        super(TransactionProgressDialog, self).__init__(self.transaction.title,
+                                                        widgets)
+
+    def add_update(self, txt):
+        self.texts.append(txt)
+        self._progress_label.set_text("\n".join(self.texts))
+
+    def run(self):
+        self.plugin.application.ui.show_dialog(self)
+        self._close_button.enabled(False)
+        try:
+            self.transaction.prepare()  # Just to display something in dry mode
+            for idx, e in enumerate(self.transaction):
+                txt = "(%s/%s) %s" % (idx + 1, len(self.transaction), e.title)
+                self.add_update(txt)
+                self.plugin.dry_or(lambda: e.commit())
+            self.add_update("\nAll changes were applied successfully.")
+        except Exception as e:
+            self.add_update("\nAn error occurred when applying the changes:")
+            self.add_update(e.message)
+            self.logger.warning("Exception '%s' on transaction " +
+                                "'%s': %s - %s" % (self.transaction, type(e),
+                                                      e, e.message))
+        self._close_button.enabled(True)
diff --git a/scripts/tui/src/ovirt/node/ui/builder.py b/scripts/tui/src/ovirt/node/ui/builder.py
index 1b502a1..2ebc855 100644
--- a/scripts/tui/src/ovirt/node/ui/builder.py
+++ b/scripts/tui/src/ovirt/node/ui/builder.py
@@ -72,7 +72,7 @@
     except:
         tui.notify("error", "Initial model validation failed.")
 
-    page = ui.widgets.PageWidget(widgets)
+    page = ui.widgets.PageWidget(widgets, container.title)
     page.plugin = plugin
 
     return page
@@ -217,6 +217,10 @@
 #            plugin._on_ui_change({path: True})
     urwid.connect_signal(widget, "click", on_widget_click_cb)
 
+    def on_item_enabled_change_cb(w, v):
+        widget.enable(v)
+    item.connect_signal("enabled", on_item_enabled_change_cb)
+
     return widget
 
 
diff --git a/scripts/tui/src/ovirt/node/ui/tui.py b/scripts/tui/src/ovirt/node/ui/tui.py
index 8592f5e..b86a1d0 100644
--- a/scripts/tui/src/ovirt/node/ui/tui.py
+++ b/scripts/tui/src/ovirt/node/ui/tui.py
@@ -32,6 +32,10 @@
 import ovirt.node.ui.widgets
 
 
+def inherits(obj, t):
+    return t in type(obj).mro()
+
+
 class UrwidTUI(ovirt.node.ui.Window):
     app = None
 
@@ -94,6 +98,7 @@
                ('plugin.widget.options.label', element_styles["label"]),
                ('plugin.widget.dialog', None),
                ('plugin.widget.page', None),
+               ('plugin.widget.page.header', element_styles["label"]),
                ('plugin.widget.page.frame', None),
                ('plugin.widget.checkbox.label', element_styles["label"]),
                ('plugin.widget.checkbox', element_styles["label"]),
@@ -107,7 +112,7 @@
     def show_body(self, body):
         """
         """
-        assert type(body) is ui.Page
+        assert inherits(body, ui.Page)
         widget = ui.builder.build_page(self, self._current_plugin, body)
         self.__display_as_body(widget)
 
@@ -116,7 +121,7 @@
         This transforms the abstract ui.Page to a urwid specififc version
         and displays it.
         """
-        assert type(page) is ui.Page
+        assert inherits(page, ui.Page)
         widget = ui.builder.build_page(self, self._current_plugin, page)
         self.__display_as_page(widget)
 
@@ -125,14 +130,15 @@
         This transforms the abstract ui.Dialog to a urwid specififc version
         and displays it.
         """
-        assert type(dialog) is ui.Dialog
+        if not inherits(dialog, ui.Dialog):
+            raise Exception("'%s' does not inherit from ui.Dialog" % dialog)
         widget = ui.builder.build_page(self, self._current_plugin, dialog)
         return self.__display_as_dialog(widget, dialog.title,
                                         dialog.escape_key)
 
     def topmost_dialog(self):
         dialog = [w for w in self.__widget_stack
-                  if type(w) is ovirt.node.ui.widgets.ModalDialog][-1:]
+                  if inherits(w, ovirt.node.ui.widgets.ModalDialog)][-1:]
         if dialog:
             dialog = dialog[0]
         else:
@@ -262,7 +268,7 @@
     def __filter_hotkeys(self, keys, raw):
         key = str(keys)
 
-        if type(self.__loop.widget) is ovirt.node.ui.widgets.ModalDialog:
+        if inherits(self.__loop.widget, ovirt.node.ui.widgets.ModalDialog):
             self.logger.debug("Modal dialog escape: %s" % key)
             if self.__loop.widget.escape_key is None:
                 self.logger.debug("Dialog can not be closed with magic key")
diff --git a/scripts/tui/src/ovirt/node/ui/widgets.py b/scripts/tui/src/ovirt/node/ui/widgets.py
index 1273ac4..cc56648 100644
--- a/scripts/tui/src/ovirt/node/ui/widgets.py
+++ b/scripts/tui/src/ovirt/node/ui/widgets.py
@@ -371,11 +371,10 @@
     def enable(self, is_enabled):
         self.selectable = lambda: is_enabled
         if is_enabled:
-            self._button_attrmap.set_attr_map({None: self._button_attr})
+            amap = {None: self._button_attr}
         else:
-            self._button_attrmap.set_attr_map({
-                None: self._button_disabled_attr
-                })
+            amap = {None: self._button_disabled_attr}
+        self._button_attrmap.set_attr_map(amap)
 
 
 class Divider(urwid.WidgetWrap):
@@ -430,7 +429,6 @@
     def set_text(self, txt):
         self.select(txt)
 
-    # FIXME and disabling
 
 class Checkbox(urwid.WidgetWrap):
     signals = ['change']
@@ -463,13 +461,16 @@
 class PageWidget(urwid.WidgetWrap):
     save_button = None
 
-    def __init__(self, widgets):
+    def __init__(self, widgets, title=None):
 #        self._listwalker = urwid.SimpleListWalker(widgets)
 #        self._container = urwid.ListBox(self._listwalker)
         self._container = urwid.Pile(widgets)
         self._container_attrmap = urwid.AttrMap(self._container,
                                                 "plugin.widget.page")
         self._header = None
+        if title:
+            self._header = urwid.AttrMap(urwid.Text(title),
+                                         "plugin.widget.page.header")
         self._frame = urwid.Frame(self._container_attrmap, self._header)
         self._box = urwid.Padding(self._frame, width=("relative", 97))
         super(PageWidget, self).__init__(self._box)
diff --git a/scripts/tui/src/ovirt/node/utils/system.py b/scripts/tui/src/ovirt/node/utils/system.py
index 6702896..d10c7f4 100644
--- a/scripts/tui/src/ovirt/node/utils/system.py
+++ b/scripts/tui/src/ovirt/node/utils/system.py
@@ -20,14 +20,16 @@
 # also available at http://www.gnu.org/copyleft/gpl.html.
 
 """
-A module to access system wide stuff 
+A module to access system wide stuff
 e.g. services, reboot ...
 """
 
 from ovirt.node.utils import process
 
+
 def reboot():
     process.system("reboot")
 
+
 def poweroff():
-    process.system("poweroff")
\ No newline at end of file
+    process.system("poweroff")


--
To view, visit http://gerrit.ovirt.org/9976
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I7c70f83e8c7705e38eb0cc6f81e46bbba1a42f44
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Fabian Deutsch <fabiand at fedoraproject.org>



More information about the node-patches mailing list