Change in vdsm[master]: netinfo, tool: Add a vdsm-tool to determine bonding defaults...
osvoboda at redhat.com
osvoboda at redhat.com
Fri Sep 26 13:19:48 UTC 2014
Ondřej Svoboda has uploaded a new change for review.
Change subject: netinfo, tool: Add a vdsm-tool to determine bonding defaults offline
......................................................................
netinfo, tool: Add a vdsm-tool to determine bonding defaults offline
Change-Id: I89b907ba80f23f417d5e481db9350247445ab772
Signed-off-by: Ondřej Svoboda <osvoboda at redhat.com>
---
M init/vdsmd_init_common.sh.in
M lib/vdsm/netinfo.py
A lib/vdsm/tool/dump_bonding_defaults.py
M tests/netinfoTests.py
M vdsm/sudoers.vdsm.in
5 files changed, 163 insertions(+), 113 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/03/33403/1
diff --git a/init/vdsmd_init_common.sh.in b/init/vdsmd_init_common.sh.in
index 298b658..0b72b69 100644
--- a/init/vdsmd_init_common.sh.in
+++ b/init/vdsmd_init_common.sh.in
@@ -100,6 +100,11 @@
}
+task_dump_bonding_defaults(){
+ "${VDSM_TOOL}" dump_bonding_defaults > "@VDSMLIBDIR@/bonding-defaults.json"
+}
+
+
task_tune_system(){
"@SYSCTL_PATH@" -q -p "/etc/sysctl.d/vdsm.conf"
}
@@ -240,6 +245,7 @@
nwfilter \
dummybr \
load_needed_modules \
+ dump_bonding_defaults \
tune_system \
test_space \
test_lo \
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index fcca5a7..cd47062 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -19,7 +19,6 @@
#
from collections import defaultdict
-from contextlib import contextmanager
import errno
from glob import iglob
from datetime import datetime
@@ -27,10 +26,8 @@
from itertools import chain
import logging
import os
-import random
import shlex
import socket
-import string
import struct
from xml.dom import minidom
@@ -45,10 +42,11 @@
from .ipwrapper import routeShowGateways
from . import libvirtconnection
from .netconfpersistence import RunningConfig
-from .utils import execCmd, memoized, pgrep, CommandPath
+from .utils import memoized
from .netlink import link as nl_link
from .netlink import addr as nl_addr
from .netlink import route as nl_route
+from .tool.dump_bonding_defaults import BONDING_DEFAULTS
NET_CONF_DIR = '/etc/sysconfig/network-scripts/'
@@ -77,8 +75,6 @@
))
_IFCFG_ZERO_SUFFIXED = frozenset(
('IPADDR0', 'GATEWAY0', 'PREFIX0', 'NETMASK0'))
-_TEE_BINARY = CommandPath('tee', constants.EXT_TEE)
-_NM_CLI_BINARY = CommandPath('nmcli', constants.EXT_NMCLI)
LIBVIRT_NET_PREFIX = 'vdsm-'
DEFAULT_MTU = '1500'
@@ -148,7 +144,7 @@
return opts
-def _realBondOpts(bond):
+def realBondOpts(bond):
"""
Return a dictionary in the same format as bondOpts(). Exclude entries that
are not bonding options, e.g. 'ad_num_ports' or 'slaves'.
@@ -405,82 +401,13 @@
return paddr
-def _randomIfaceName():
- MAX_LENGTH = 15
- CHARS = string.ascii_lowercase + string.ascii_uppercase + string.digits
-
- return ''.join(random.choice(CHARS) for _ in range(MAX_LENGTH))
-
-
- at contextmanager
-def _avoidNetworkManager(interface):
- """Make a network interface unmanaged by NetworkManager.
-
- Until NM supports placing its 'unmanaged-devices' directive in
- /etc/NetworkManager/conf.d/00-server.conf we are left with a hack.
- The directive should also support globbing so we do not have to use
- a predictable name for e.g. the reference bond (but we could accept that,
- too).
-
- Please see https://bugzilla.redhat.com/show_bug.cgi?id=1136843"""
- has_nm = pgrep('NetworkManager')
-
- if has_nm:
- nmcli = _NM_CLI_BINARY.cmd
- ifcfgPath = NET_CONF_PREF + interface
- execCmd([_TEE_BINARY.cmd, ifcfgPath], sudo=True,
- data='DEVICE=%s\nNM_CONTROLLED=no\n' % interface)
-
- rc, _, _ = execCmd([nmcli, 'conn', 'load', ifcfgPath], sudo=True)
- if rc:
- raise RuntimeError('Failed to unmanage %s.' % interface)
- try:
- yield
- finally:
- if has_nm:
- execCmd([nmcli, 'conn', 'delete', interface], sudo=True)
- execCmd([constants.EXT_RM, ifcfgPath], sudo=True)
-
-
@memoized
def _getAllDefaultBondingOptions():
"""
Return default options per mode, in a dictionary of dictionaries. All keys
- are strings.
+ are numeric modes stored as strings for coherence with 'mode' option value.
"""
- teeCmd = _TEE_BINARY.cmd
- MAX_MODE = 6
-
- bondName = _randomIfaceName()
- with _avoidNetworkManager(bondName):
- rc, _, err = execCmd([teeCmd, BONDING_MASTERS], data='+' + bondName,
- sudo=True)
- if rc:
- raise RuntimeError('Creating a reference bond failed',
- '\n'.join(err))
- opts = {}
- try:
- defaultMode = bondOpts(bondName, keys=['mode'])['mode']
-
- # read default values for all modes
- for mode in range(0, MAX_MODE + 1):
- mode = str(mode)
- sysfsMode = BONDING_OPT % (bondName, 'mode')
- rc, _, err = execCmd([teeCmd, sysfsMode], data=mode, sudo=True)
- if rc:
- raise RuntimeError('Changing the mode of the reference '
- 'bond failed. Is NetworkManager '
- 'running?', '\n'.join(err))
-
- # only read non-empty options
- opts[mode] = dict(((opt, val) for (opt, val) in
- _realBondOpts(bondName).iteritems() if val))
- opts[mode]['mode'] = defaultMode
-
- finally:
- execCmd([teeCmd, BONDING_MASTERS], data='-' + bondName, sudo=True)
-
- return opts
+ return json.load(open(constants.P_VDSM_BONDING_DEFAULTS).read())
@memoized
diff --git a/lib/vdsm/tool/dump_bonding_defaults.py b/lib/vdsm/tool/dump_bonding_defaults.py
new file mode 100644
index 0000000..27311c3
--- /dev/null
+++ b/lib/vdsm/tool/dump_bonding_defaults.py
@@ -0,0 +1,121 @@
+#! /usr/bin/python
+# Copyright 2014 Red Hat, Inc.
+#
+# 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 json
+import os
+import random
+import string
+
+from ..constants import EXT_NMCLI, EXT_RM, P_VDSM_LIB
+from ..netinfo import (BONDING_MASTERS, BONDING_OPT, NET_CONF_PREF, bondOpts,
+ realBondOpts)
+from ..utils import execCmd, pgrep
+from . import expose, ExtraArgsError
+
+
+BONDING_DEFAULTS = os.path.join(P_VDSM_LIB, 'bonding-defaults.json')
+
+
+def _randomIfaceName():
+ MAX_LENGTH = 15
+ CHARS = string.ascii_lowercase + string.ascii_uppercase + string.digits
+
+ return ''.join(random.choice(CHARS) for _ in range(MAX_LENGTH))
+
+
+ at contextmanager
+def _avoidNetworkManager(interface):
+ """Make a network interface unmanaged by NetworkManager.
+
+ Until NM supports placing its 'unmanaged-devices' directive in
+ /etc/NetworkManager/conf.d/00-server.conf we are left with a hack.
+ The directive should also support globbing so we do not have to use
+ a predictable name for e.g. the reference bond (but we could accept that,
+ too).
+
+ Please see https://bugzilla.redhat.com/show_bug.cgi?id=1136843"""
+ has_nm = pgrep('NetworkManager')
+
+ if has_nm:
+ ifcfgPath = NET_CONF_PREF + interface
+ with open(ifcfgPath, 'w') as ifcfgFile:
+ ifcfgFile.write('DEVICE=%s\nNM_CONTROLLED=no\n' % interface)
+
+ execCmd([EXT_NMCLI, 'conn', 'load', ifcfgPath])
+ try:
+ yield
+ finally:
+ if has_nm:
+ execCmd([EXT_NMCLI, 'conn', 'delete', interface])
+ execCmd([EXT_RM, ifcfgPath])
+
+
+def _getAllDefaultBondingOptions():
+ """
+ Return default options per mode, in a dictionary of dictionaries. All keys
+ are strings.
+ """
+ MAX_MODE = 6
+ # TODO: We can just use something like REFERENCE_BOND = ';vdsmrefbond;'
+ bondName = _randomIfaceName()
+ opts = {}
+
+ with _avoidNetworkManager(bondName):
+ with open(BONDING_MASTERS, 'w') as bonds:
+ bonds.write('+' + bondName)
+
+ try:
+ defaultMode = bondOpts(bondName, keys=['mode'])['mode']
+
+ # read default values for all modes
+ for mode in range(0, MAX_MODE + 1):
+ mode = str(mode)
+ with open(BONDING_OPT % (bondName, 'mode'), 'w') as opt:
+ opt.write(mode)
+
+ # only read non-empty options
+ opts[mode] = dict(((opt, val) for (opt, val) in
+ realBondOpts(bondName).iteritems() if val))
+ opts[mode]['mode'] = defaultMode
+
+ finally:
+ with open(BONDING_MASTERS, 'w') as bonds:
+ bonds.write('-' + bondName)
+
+ return opts
+
+
+ at expose('dump_bonding_defaults')
+def main(*args):
+ """dump_bonding_defaults
+
+ Read bonding option defaults and print them out as a dictionary (per mode)
+ in JSON format.
+ """
+
+ if len(args) > 1:
+ raise ExtraArgsError()
+
+ with open(BONDING_DEFAULTS, 'w') as defaults:
+ defaults.write(json.dumps(_getAllDefaultBondingOptions()))
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/netinfoTests.py b/tests/netinfoTests.py
index 5828399..63c11ae 100644
--- a/tests/netinfoTests.py
+++ b/tests/netinfoTests.py
@@ -26,16 +26,17 @@
from vdsm import ipwrapper
from vdsm import netconfpersistence
from vdsm import netinfo
-from vdsm.netinfo import (getBootProtocol, getDhclientIfaces, BONDING_MASTERS,
- BONDING_OPT, _randomIfaceName, _getBondingOptions,
- _avoidNetworkManager)
+from vdsm.netinfo import getBootProtocol, getDhclientIfaces
+# BONDING_MASTERS, BONDING_OPT, _randomIfaceName, _getBondingOptions
+# _avoidNetworkManager
from vdsm.netlink import addr as nl_addr
from functional import dummy, veth
from ipwrapperTests import _fakeTypeDetection
from monkeypatch import MonkeyPatch, MonkeyPatchScope
from testlib import VdsmTestCase as TestCaseBase, namedTemporaryDir
-from testValidation import ValidateRunningAsRoot, RequireBondingMod
+from testValidation import ValidateRunningAsRoot
+# RequireBondingMod
# speeds defined in ethtool
ETHTOOL_SPEEDS = set([10, 100, 1000, 2500, 10000])
@@ -301,27 +302,28 @@
self.assertNotIn('expired', dhcp4)
self.assertNotIn('expired2', dhcp4)
- @ValidateRunningAsRoot
- @RequireBondingMod
- def testGetBondingOptions(self):
- INTERVAL = '12345'
- bondName = _randomIfaceName()
-
- with _avoidNetworkManager(bondName):
- with open(BONDING_MASTERS, 'w') as bonds:
- bonds.write('+' + bondName)
- bonds.flush()
-
- try:
- with self.assertNotRaises():
- self.assertEqual(_getBondingOptions(bondName), {})
-
- with open(BONDING_OPT % (bondName, 'miimon'),
- 'w') as opt:
- opt.write(INTERVAL)
-
- self.assertEqual(_getBondingOptions(bondName),
- {'miimon': INTERVAL})
-
- finally:
- bonds.write('-' + bondName)
+# TODO: move to toolTests.py?
+# @ValidateRunningAsRoot
+# @RequireBondingMod
+# def testGetBondingOptions(self):
+# INTERVAL = '12345'
+# bondName = _randomIfaceName()
+#
+# with _avoidNetworkManager(bondName):
+# with open(BONDING_MASTERS, 'w') as bonds:
+# bonds.write('+' + bondName)
+# bonds.flush()
+#
+# try:
+# with self.assertNotRaises():
+# self.assertEqual(_getBondingOptions(bondName), {})
+#
+# with open(BONDING_OPT % (bondName, 'miimon'),
+# 'w') as opt:
+# opt.write(INTERVAL)
+#
+# self.assertEqual(_getBondingOptions(bondName),
+# {'miimon': INTERVAL})
+#
+# finally:
+# bonds.write('-' + bondName)
diff --git a/vdsm/sudoers.vdsm.in b/vdsm/sudoers.vdsm.in
index 465b530..2b745d3 100644
--- a/vdsm/sudoers.vdsm.in
+++ b/vdsm/sudoers.vdsm.in
@@ -30,13 +30,7 @@
@SETSID_PATH@ @IONICE_PATH@ -c ? -n ? @SU_PATH@ vdsm -s /bin/sh -c /usr/libexec/vdsm/spmprotect.sh*, \
@SERVICE_PATH@ vdsmd *, \
@REBOOT_PATH@ -f
-Cmnd_Alias VDSM_NETWORK = \
- @NMCLI_PATH@, \
- @TEE_PATH@ /etc/sysconfig/network-scripts/ifcfg-*, \
- @RM_PATH@ /etc/sysconfig/network-scripts/ifcfg-*, \
- @TEE_PATH@ /sys/class/net/bonding_masters, \
- @TEE_PATH@ /sys/class/net/*/bonding/mode
-vdsm ALL=(ALL) NOPASSWD: VDSM_LIFECYCLE, VDSM_STORAGE, VDSM_NETWORK
+vdsm ALL=(ALL) NOPASSWD: VDSM_LIFECYCLE, VDSM_STORAGE
Defaults:vdsm !requiretty
Defaults:vdsm !syslog
--
To view, visit http://gerrit.ovirt.org/33403
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I89b907ba80f23f417d5e481db9350247445ab772
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Ondřej Svoboda <osvoboda at redhat.com>
More information about the vdsm-patches
mailing list