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