Hello Miguel Angel Ajo Pelayo,

I'd like you to do a code review.  Please visit

    http://gerrit.ovirt.org/23659

to review the following change.

Change subject: vdsm hooks: this patch provides after/before_network_setup 
hooks.
......................................................................

vdsm hooks: this patch provides after/before_network_setup hooks.

This enables the capability to interact with physical network
management interfaces, setting up extra parameters, or
interacting with switches, etc.

It also introduces a standard testing decorator for hook
testcases.

Change-Id: Iac5c6f57b300b3b1a2a9bfad4a7919f4d8a74707
Signed-off-by: Miguel Angel Ajo <[email protected]>
Reviewed-on: http://gerrit.ovirt.org/20076
Reviewed-by: Dan Kenigsberg <[email protected]>
---
M AUTHORS
M tests/Makefile.am
M tests/functional/networkTests.py
A tests/hookValidation.py
M vdsm.spec.in
M vdsm/configNetwork.py
M vdsm/hooks.py
M vdsm/vdsmd.8.in
M vdsm_hooks/Makefile.am
9 files changed, 154 insertions(+), 5 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/59/23659/1

diff --git a/AUTHORS b/AUTHORS
index e2f52fe..41ffec2 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -10,6 +10,7 @@
 
 Patches have also been contributed by (ordered by lastname):
 
+   Miguel Angel Ajo <[email protected]>
    Timothy Asir <[email protected]>
    Haim Ateya <[email protected]>
    Daniel P. Berrange <[email protected]>
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f87eddd..9756c05 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -102,9 +102,11 @@
 dist_vdsmtests_PYTHON = \
        $(test_modules) \
        apiData.py \
+       hookValidation.py \
        monkeypatch.py \
        testrunner.py \
-       testValidation.py
+       testValidation.py \
+       $(NULL)
 
 dist_vdsmtests_SCRIPTS = \
        run_tests.sh \
diff --git a/tests/functional/networkTests.py b/tests/functional/networkTests.py
index f4d29eb..02e9144 100644
--- a/tests/functional/networkTests.py
+++ b/tests/functional/networkTests.py
@@ -18,10 +18,12 @@
 #
 from contextlib import contextmanager
 from threading import Thread
+import os.path
 import time
 
 import neterrors
 
+from hookValidation import ValidatesHook
 from testrunner import (VdsmTestCase as TestCaseBase,
                         expandPermutations, permutations)
 from testValidation import RequireDummyMod, ValidateRunningAsRoot
@@ -1429,3 +1431,39 @@
                                                       {'connectivityCheck': 0})
             self.assertEqual(status, SUCCESS, msg)
             self.assertFalse(self.vdsm_net.networkExists(NETWORK_NAME))
+
+    @cleanupNet
+    @RequireDummyMod
+    @ValidateRunningAsRoot
+    @ValidatesHook('before_network_setup', 'testBeforeNetworkSetup.sh')
+    def testBeforeNetworkSetupHook(self, hook_cookiefile):
+        with dummyIf(1) as nics:
+            nic, = nics
+            networks = {NETWORK_NAME: {'nic': nic, 'bridged': False,
+                                       'bootproto': 'none'}}
+            with self.vdsm_net.pinger():
+                self.vdsm_net.setupNetworks(networks, {}, {})
+
+                self.assertTrue(os.path.isfile(hook_cookiefile))
+
+                delete_networks = {NETWORK_NAME: {'remove': True}}
+                self.vdsm_net.setupNetworks(delete_networks,
+                                            {}, {})
+
+    @cleanupNet
+    @RequireDummyMod
+    @ValidateRunningAsRoot
+    @ValidatesHook('after_network_setup', 'testAfterNetworkSetup.sh')
+    def testAfterNetworkSetupHook(self, hook_cookiefile):
+        with dummyIf(1) as nics:
+            nic, = nics
+            networks = {NETWORK_NAME: {'nic': nic, 'bridged': False,
+                                       'bootproto': 'none'}}
+            with self.vdsm_net.pinger():
+                self.vdsm_net.setupNetworks(networks, {}, {})
+
+                self.assertTrue(os.path.isfile(hook_cookiefile))
+
+                delete_networks = {NETWORK_NAME: {'remove': True}}
+                self.vdsm_net.setupNetworks(delete_networks,
+                                            {}, {})
diff --git a/tests/hookValidation.py b/tests/hookValidation.py
new file mode 100644
index 0000000..80e7239
--- /dev/null
+++ b/tests/hookValidation.py
@@ -0,0 +1,88 @@
+
+# Copyright 2013 Miguel Angel Ajo
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import os
+import shutil
+import tempfile
+
+from functools import wraps
+from vdsm import constants
+
+
+def _createHookScript(hook_path, hook_filename, script=None):
+
+    """ Puts a script in place to be executed by a hook, the script
+        parameter must have a %(cookiefile)s placeholder for the output
+        file that test will check later """
+
+    hook_script_path = hook_path + '/' + hook_filename
+    hook_script_cookiefile = tempfile.mktemp()
+
+    with open(hook_script_path, 'w') as f:
+        if script is None:
+            script = "#!/bin/sh\ndate --rfc-3339=ns > %(cookiefile)s\n"
+
+        f.write(script % {'cookiefile': hook_script_cookiefile})
+
+    os.chmod(hook_script_path, 0o777)
+
+    return hook_script_cookiefile
+
+
+def ValidatesHook(hook_dir, hook_name, functional=True, hook_script=None):
+    """ Decorator for test cases that need to validate hook point execution """
+    def decorator(test_function):
+        @wraps(test_function)
+        def wrapper(*args, **kwargs):
+
+            directory_existed = False
+
+            if not functional:
+                old_vdsm_hooks = constants.P_VDSM_HOOKS
+                constants.P_VDSM_HOOKS = tempfile.mkdtemp()
+
+            hook_path = constants.P_VDSM_HOOKS + '/' + hook_dir
+
+            try:
+                os.mkdir(hook_path)
+            except OSError:
+                directory_existed = True
+
+            cookie_file = _createHookScript(hook_path, hook_name, hook_script)
+
+            output = None
+
+            try:
+                kwargs['hook_cookiefile'] = cookie_file
+                output = test_function(*args, **kwargs)
+            finally:
+                if directory_existed:
+                    os.unlink(cookie_file)
+                else:
+                    shutil.rmtree(hook_path)
+
+                if not functional:
+                    constants.P_VDSM_HOOKS = old_vdsm_hooks
+
+            return output
+
+        return wrapper
+
+    return decorator
diff --git a/vdsm.spec.in b/vdsm.spec.in
index c8bbf8d..a1fa38c 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -987,6 +987,8 @@
 %dir %{_libexecdir}/%{vdsm_name}/hooks/after_disk_hotunplug
 %dir %{_libexecdir}/%{vdsm_name}/hooks/before_vdsm_start
 %dir %{_libexecdir}/%{vdsm_name}/hooks/after_vdsm_stop
+%dir %{_libexecdir}/%{vdsm_name}/hooks/before_network_setup
+%dir %{_libexecdir}/%{vdsm_name}/hooks/after_network_setup
 %{_datadir}/%{vdsm_name}/addNetwork
 %{_datadir}/%{vdsm_name}/configNetwork.py*
 %{_datadir}/%{vdsm_name}/delNetwork
diff --git a/vdsm/configNetwork.py b/vdsm/configNetwork.py
index 97d3f09..8175742 100755
--- a/vdsm/configNetwork.py
+++ b/vdsm/configNetwork.py
@@ -38,6 +38,7 @@
 from netmodels import IpConfig
 from netmodels import Nic
 from netmodels import Vlan
+import hooks
 
 CONNECTIVITY_TIMEOUT_DEFAULT = 4
 
@@ -500,6 +501,8 @@
         logging.debug("Validating configuration")
         _validateNetworkSetup(dict(networks), dict(bondings))
 
+    hooks.before_network_setup()
+
     logger.debug("Applying...")
     with Ifcfg() as configurator:
         libvirt_nets = netinfo.networks()
@@ -560,6 +563,8 @@
                 raise ConfigNetworkError(ne.ERR_LOST_CONNECTION,
                                          'connectivity check failed')
 
+    hooks.after_network_setup()
+
 
 def _vlanToInternalRepresentation(vlan):
     if vlan is None or vlan == '':
diff --git a/vdsm/hooks.py b/vdsm/hooks.py
index 8b74907..ccc21a2 100644
--- a/vdsm/hooks.py
+++ b/vdsm/hooks.py
@@ -304,6 +304,14 @@
     return _runHooksDir(None, 'after_vdsm_stop', raiseError=False)
 
 
+def before_network_setup():
+    return _runHooksDir(None, 'before_network_setup')
+
+
+def after_network_setup():
+    return _runHooksDir(None, 'after_network_setup', raiseError=False)
+
+
 def _getScriptInfo(path):
     try:
         with file(path) as f:
diff --git a/vdsm/vdsmd.8.in b/vdsm/vdsmd.8.in
index 14be547..f872bb0 100644
--- a/vdsm/vdsmd.8.in
+++ b/vdsm/vdsmd.8.in
@@ -56,15 +56,17 @@
     before_update_device, after_update_device, after_update_device_fail,
     before_disk_hotplug, after_disk_hotplug,
     before_disk_hotunplug, after_disk_hotunplug,
-    before_vdsm_start, after_vdsm_stop.
+    before_vdsm_start, after_vdsm_stop,
+    before_network_setup, after_network_setup.
 
 Each hook executes the scripts under
 .FN /usr/libexec/vdsm/hooks/<hook-name>/
 in lexicographic order.
 
 .SS Hook environment
-Each hook script (except before_vdsm_start and after_vdsm_stop) inherit the
-environment of the VDSM process, with an additional variable
+Each hook script (except before_vdsm_start, after_vdsm_stop, 
+before_network_setup and after_network_setup)) inherit the environment of
+the VDSM process, with an additional variable
 .B _hook_domxml
 which holds the path of libvirt's
 .B domain xml
diff --git a/vdsm_hooks/Makefile.am b/vdsm_hooks/Makefile.am
index 8a8d594..8d446bb 100644
--- a/vdsm_hooks/Makefile.am
+++ b/vdsm_hooks/Makefile.am
@@ -99,7 +99,10 @@
        before_disk_hotunplug \
        after_disk_hotunplug \
        before_vdsm_start \
-       after_vdsm_stop
+       after_vdsm_stop \
+       before_network_setup \
+       after_network_setup \
+       $(NULL)
 
 all-local: \
        $(nodist_vdsmexec_SCRIPTS)


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iac5c6f57b300b3b1a2a9bfad4a7919f4d8a74707
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.3
Gerrit-Owner: Dan Kenigsberg <[email protected]>
Gerrit-Reviewer: Miguel Angel Ajo Pelayo <[email protected]>
_______________________________________________
vdsm-patches mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to