Change in vdsm[master]: netinfo, tool: Add a vdsm-tool to determine bonding defaults...

osvoboda at redhat.com osvoboda at redhat.com
Mon Sep 29 14:27:54 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

dump-bonding-defaults reads bonding option defaults (per mode) and saves them
to /var/lib/vdsm/bonding-defaults.json. VDSM loads the file once at runtime
and refers to this static information of defaults when reporting bonding
options of bonds in the system.

As the bonding defaults are bound to the used kernel it is the responsibility
of the packager (or the sysadmin in customized setups) to regenerate the file
by running (during the build, or installation, respectively):

vdsm-tool dump-bonding-defaults

It is currently not advised to run the tool on startup because NetworkManager
may ifup the reference bond, making the tool unable to determine all options.

Change-Id: I92bcf62a4ae1756b0d2857cc0c7387c128f9b8a0
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1142701
Signed-off-by: Ondřej Svoboda <osvoboda at redhat.com>
---
M debian/vdsm-python.install
M debian/vdsm.install
M init/vdsmd_init_common.sh.in
M lib/vdsm/netinfo.py
M lib/vdsm/tool/Makefile.am
A lib/vdsm/tool/dump_bonding_defaults.py
M tests/netinfoTests.py
M vdsm.spec.in
M vdsm/Makefile.am
A vdsm/bonding-defaults.json
M vdsm/sudoers.vdsm.in
11 files changed, 545 insertions(+), 48 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/89/33489/1

diff --git a/debian/vdsm-python.install b/debian/vdsm-python.install
index 0294be8..42f08c2 100644
--- a/debian/vdsm-python.install
+++ b/debian/vdsm-python.install
@@ -17,6 +17,7 @@
 ./usr/lib/python2.7/dist-packages/vdsm/sslutils.py
 ./usr/lib/python2.7/dist-packages/vdsm/tool/__init__.py
 ./usr/lib/python2.7/dist-packages/vdsm/tool/dummybr.py
+./usr/lib/python2.7/dist-packages/vdsm/tool/dump_bonding_defaults.py
 ./usr/lib/python2.7/dist-packages/vdsm/tool/configurator.py
 ./usr/lib/python2.7/dist-packages/vdsm/tool/load_needed_modules.py
 ./usr/lib/python2.7/dist-packages/vdsm/tool/nwfilter.py
diff --git a/debian/vdsm.install b/debian/vdsm.install
index c97b8dd..4a0b976 100644
--- a/debian/vdsm.install
+++ b/debian/vdsm.install
@@ -23,6 +23,7 @@
 ./lib/udev/rules.d/61-vdsm-lvm.rules
 ./usr/lib/python2.7/dist-packages/sos/plugins/vdsm.py
 ./usr/lib/python2.7/dist-packages/vdsmapi.py
+./var/lib/vdsm/bonding-defaults.json
 ./usr/libexec/vdsm/curl-img-wrap
 ./usr/libexec/vdsm/ovirt_functions.sh
 ./usr/libexec/vdsm/persist-vdsm-hooks
diff --git a/init/vdsmd_init_common.sh.in b/init/vdsmd_init_common.sh.in
index 298b658..49e9f19 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
+}
+
+
 task_tune_system(){
     "@SYSCTL_PATH@" -q -p "/etc/sysctl.d/vdsm.conf"
 }
@@ -228,6 +233,10 @@
 
 case "$1" in
     --pre-start)
+        # If dump_bonding_defaults is desired (for the uneliminable possibility
+        # of added bonding options or tweaked kernel defaults) it has to be run
+        # after load_needed_modules (modprobe bonding).
+        # NetworkManager must not crash on nmcli conn delete.
         run_tasks " \
             mkdirs \
             configure_coredump \
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index 5dc2cd6..f98dcea 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -24,12 +24,11 @@
 from datetime import datetime
 from functools import partial
 from itertools import chain
+import json
 import logging
 import os
-import random
 import shlex
 import socket
-import string
 import struct
 from xml.dom import minidom
 
@@ -47,7 +46,7 @@
 from . import libvirtconnection
 from .netconfpersistence import RunningConfig
 from .netlink import iter_addrs, iter_links
-from .utils import execCmd, memoized, CommandPath
+from .utils import memoized
 
 
 NET_CONF_DIR = '/etc/sysconfig/network-scripts/'
@@ -69,6 +68,7 @@
 BONDING_MASTERS = '/sys/class/net/bonding_masters'
 BONDING_SLAVES = '/sys/class/net/%s/bonding/slaves'
 BONDING_OPT = '/sys/class/net/%s/bonding/%s'
+BONDING_DEFAULTS = constants.P_VDSM_LIB + 'bonding-defaults.json'
 BRIDGING_OPT = '/sys/class/net/%s/bridge/%s'
 _BONDING_FAILOVER_MODES = frozenset(('1', '3'))
 _BONDING_LOADBALANCE_MODES = frozenset(('0', '2', '4', '5', '6'))
@@ -78,7 +78,6 @@
 ))
 _IFCFG_ZERO_SUFFIXED = frozenset(
     ('IPADDR0', 'GATEWAY0', 'PREFIX0', 'NETMASK0'))
-_TEE_BINARY = CommandPath('tee', constants.EXT_TEE)
 
 LIBVIRT_NET_PREFIX = 'vdsm-'
 DEFAULT_MTU = '1500'
@@ -187,7 +186,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'.
@@ -522,47 +521,14 @@
     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))
-
-
 @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()
-    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)
-            rc, _, err = execCmd([teeCmd, BONDING_OPT % (bondName, 'mode')],
-                                 data=mode, sudo=True)
-
-            # 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
+    with open(BONDING_DEFAULTS) as defaults:
+        return json.loads(defaults.read())
 
 
 @memoized
@@ -584,7 +550,7 @@
     Return non-empty options differing from defaults, excluding not actual or
     not applicable options, e.g. 'ad_num_ports' or 'slaves'.
     """
-    opts = _realBondOpts(bond)
+    opts = realBondOpts(bond)
     mode = opts['mode'][-1] if 'mode' in opts else None
     defaults = _getDefaultBondingOptions(mode)
 
diff --git a/lib/vdsm/tool/Makefile.am b/lib/vdsm/tool/Makefile.am
index 7be78fc..a181617 100644
--- a/lib/vdsm/tool/Makefile.am
+++ b/lib/vdsm/tool/Makefile.am
@@ -40,6 +40,7 @@
 dist_vdsmtool_PYTHON = \
 	__init__.py \
 	dummybr.py \
+	dump_bonding_defaults.py \
 	nwfilter.py \
 	configurator.py \
 	passwd.py \
diff --git a/lib/vdsm/tool/dump_bonding_defaults.py b/lib/vdsm/tool/dump_bonding_defaults.py
new file mode 100644
index 0000000..09bb82d
--- /dev/null
+++ b/lib/vdsm/tool/dump_bonding_defaults.py
@@ -0,0 +1,83 @@
+# 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 random
+import string
+
+from ..netinfo import (BONDING_MASTERS, BONDING_OPT, BONDING_DEFAULTS,
+                       bondOpts, realBondOpts)
+from . import expose, ExtraArgsError
+
+
+def _random_iface_name():
+    MAX_LENGTH = 15
+    CHARS = string.ascii_lowercase + string.ascii_uppercase + string.digits
+
+    return ''.join(random.choice(CHARS) for _ in range(MAX_LENGTH))
+
+
+def _get_default_bonding_options():
+    """
+    Return default options per mode, in a dictionary of dictionaries. All keys
+    are strings.
+    """
+    MAX_MODE = 6
+    bond_name = _random_iface_name()
+    opts = {}
+
+    with open(BONDING_MASTERS, 'w') as bonds:
+        bonds.write('+' + bond_name)
+
+    try:
+        default_mode = bondOpts(bond_name, keys=['mode'])['mode']
+
+        # read default values for all modes
+        for mode in range(0, MAX_MODE + 1):
+            mode = str(mode)
+            with open(BONDING_OPT % (bond_name, 'mode'), 'w') as opt:
+                opt.write(mode)
+
+            # only read non-empty options
+            opts[mode] = dict(((opt, val) for (opt, val) in
+                               realBondOpts(bond_name).iteritems() if val))
+            opts[mode]['mode'] = default_mode
+
+    finally:
+        with open(BONDING_MASTERS, 'w') as bonds:
+            bonds.write('-' + bond_name)
+
+    return opts
+
+
+ at expose('dump-bonding-defaults')
+def main(*args):
+    """dump-bonding-defaults
+
+    Read bonding option defaults (per mode) and dump them to BONDING_DEFAULTS
+    in JSON format.
+    """
+
+    if len(args) > 1:
+        raise ExtraArgsError()
+
+    with open(BONDING_DEFAULTS, 'w') as defaults:
+        json.dump(_get_default_bonding_options(), defaults, sort_keys=True,
+                  indent=4, separators=(',', ': '))
diff --git a/tests/netinfoTests.py b/tests/netinfoTests.py
index a3a1e64..e277ea5 100644
--- a/tests/netinfoTests.py
+++ b/tests/netinfoTests.py
@@ -30,7 +30,8 @@
 from vdsm import netconfpersistence
 from vdsm import netinfo
 from vdsm.netinfo import (getBootProtocol, getDhclientIfaces, BONDING_MASTERS,
-                          BONDING_OPT, _randomIfaceName, _getBondingOptions)
+                          BONDING_OPT, _getBondingOptions)
+from vdsm.tool.dump_bonding_defaults import _random_iface_name
 
 from functional import dummy, veth
 from ipwrapperTests import _fakeTypeDetection
@@ -352,9 +353,11 @@
         self.assertNotIn('expired2', dhcp4)
 
     @ValidateRunningAsRoot
+    # TODO: backport 'netinfo_tests: load bonding module for Centos7' first
+    # @RequireBondingMod
     def testGetBondingOptions(self):
         INTERVAL = '12345'
-        bondName = _randomIfaceName()
+        bondName = _random_iface_name()
 
         with open(BONDING_MASTERS, 'w') as bonds:
             bonds.write('+' + bondName)
diff --git a/vdsm.spec.in b/vdsm.spec.in
index ca2e86f..21ac926 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1159,6 +1159,7 @@
 %dir %{_sysconfdir}/pki/%{vdsm_name}/certs
 %dir %{_sysconfdir}/pki/%{vdsm_name}/libvirt-spice
 %config(noreplace) %{_sysconfdir}/pki/%{vdsm_name}/keys/libvirt_password
+%{_localstatedir}/lib/%{vdsm_name}/bonding-defaults.json
 %dir %{_localstatedir}/lib/%{vdsm_name}
 %dir %{_localstatedir}/lib/%{vdsm_name}/netconfback
 %dir %{_localstatedir}/lib/%{vdsm_name}/persistence
@@ -1200,6 +1201,7 @@
 %{python_sitearch}/%{vdsm_name}/tool/load_needed_modules.py*
 %endif
 %{python_sitearch}/%{vdsm_name}/tool/dummybr.py*
+%{python_sitearch}/%{vdsm_name}/tool/dump_bonding_defaults.py*
 %{python_sitearch}/%{vdsm_name}/tool/nwfilter.py*
 %{python_sitearch}/%{vdsm_name}/tool/configurator.py*
 %{python_sitearch}/%{vdsm_name}/tool/configurators/__init__*
diff --git a/vdsm/Makefile.am b/vdsm/Makefile.am
index 96deef2..55edbf5 100644
--- a/vdsm/Makefile.am
+++ b/vdsm/Makefile.am
@@ -94,6 +94,7 @@
 	$(nodist_man8_MANS)
 
 EXTRA_DIST = \
+	bonding-defaults.json \
 	dsaversion.py.in \
 	dumpStorageTable.py.in \
 	libvirt_password \
@@ -133,6 +134,7 @@
 	chmod 775 $(DESTDIR)$(localstatedir)/lib/libvirt/qemu/channels
 
 install-data-local: \
+		install-data-bonding-defaults \
 		install-data-dhclient-hooks \
 		install-data-libvirtpass \
 		install-data-logger \
@@ -159,6 +161,7 @@
 	$(MKDIR_P) $(DESTDIR)$(localstatedir)/lib/libvirt/qemu/channels
 
 uninstall-local: \
+		uninstall-data-bonding-defaults \
 		uninstall-data-dhclient-hooks \
 		uninstall-data-libvirtpass \
 		uninstall-data-logger \
@@ -186,6 +189,15 @@
 uninstall-data-libvirtpass:
 	$(RM) $(DESTDIR)$(vdsmtsdir)/keys/libvirt_password
 
+# lib/vdsm does not exist yet
+install-data-bonding-defaults:
+	$(MKDIR_P) $(DESTDIR)$(vdsmlibdir)
+	$(INSTALL_DATA) -m 600 $(srcdir)/bonding-defaults.json \
+		$(DESTDIR)$(vdsmlibdir)/bonding-defaults.json
+
+uninstall-data-bonding-defaults:
+	$(RM) $(DESTDIR)$(vdsmlibdir)/bonding-defaults.json
+
 install-data-rwtab:
 	$(MKDIR_P) $(DESTDIR)$(sysconfdir)/rwtab.d
 	$(INSTALL_DATA) vdsm.rwtab \
diff --git a/vdsm/bonding-defaults.json b/vdsm/bonding-defaults.json
new file mode 100644
index 0000000..52f2d6c
--- /dev/null
+++ b/vdsm/bonding-defaults.json
@@ -0,0 +1,422 @@
+{
+    "0": {
+        "ad_select": [
+            "stable",
+            "0"
+        ],
+        "all_slaves_active": [
+            "0"
+        ],
+        "arp_interval": [
+            "0"
+        ],
+        "arp_validate": [
+            "none",
+            "0"
+        ],
+        "downdelay": [
+            "0"
+        ],
+        "fail_over_mac": [
+            "none",
+            "0"
+        ],
+        "lacp_rate": [
+            "slow",
+            "0"
+        ],
+        "miimon": [
+            "0"
+        ],
+        "min_links": [
+            "0"
+        ],
+        "mode": [
+            "balance-rr",
+            "0"
+        ],
+        "num_grat_arp": [
+            "1"
+        ],
+        "num_unsol_na": [
+            "1"
+        ],
+        "primary_reselect": [
+            "always",
+            "0"
+        ],
+        "resend_igmp": [
+            "1"
+        ],
+        "updelay": [
+            "0"
+        ],
+        "use_carrier": [
+            "1"
+        ],
+        "xmit_hash_policy": [
+            "layer2",
+            "0"
+        ]
+    },
+    "1": {
+        "ad_select": [
+            "stable",
+            "0"
+        ],
+        "all_slaves_active": [
+            "0"
+        ],
+        "arp_interval": [
+            "0"
+        ],
+        "arp_validate": [
+            "none",
+            "0"
+        ],
+        "downdelay": [
+            "0"
+        ],
+        "fail_over_mac": [
+            "none",
+            "0"
+        ],
+        "lacp_rate": [
+            "slow",
+            "0"
+        ],
+        "miimon": [
+            "0"
+        ],
+        "min_links": [
+            "0"
+        ],
+        "mode": [
+            "balance-rr",
+            "0"
+        ],
+        "num_grat_arp": [
+            "1"
+        ],
+        "num_unsol_na": [
+            "1"
+        ],
+        "primary_reselect": [
+            "always",
+            "0"
+        ],
+        "resend_igmp": [
+            "1"
+        ],
+        "updelay": [
+            "0"
+        ],
+        "use_carrier": [
+            "1"
+        ],
+        "xmit_hash_policy": [
+            "layer2",
+            "0"
+        ]
+    },
+    "2": {
+        "ad_select": [
+            "stable",
+            "0"
+        ],
+        "all_slaves_active": [
+            "0"
+        ],
+        "arp_interval": [
+            "0"
+        ],
+        "arp_validate": [
+            "none",
+            "0"
+        ],
+        "downdelay": [
+            "0"
+        ],
+        "fail_over_mac": [
+            "none",
+            "0"
+        ],
+        "lacp_rate": [
+            "slow",
+            "0"
+        ],
+        "miimon": [
+            "0"
+        ],
+        "min_links": [
+            "0"
+        ],
+        "mode": [
+            "balance-rr",
+            "0"
+        ],
+        "num_grat_arp": [
+            "1"
+        ],
+        "num_unsol_na": [
+            "1"
+        ],
+        "primary_reselect": [
+            "always",
+            "0"
+        ],
+        "resend_igmp": [
+            "1"
+        ],
+        "updelay": [
+            "0"
+        ],
+        "use_carrier": [
+            "1"
+        ],
+        "xmit_hash_policy": [
+            "layer2",
+            "0"
+        ]
+    },
+    "3": {
+        "ad_select": [
+            "stable",
+            "0"
+        ],
+        "all_slaves_active": [
+            "0"
+        ],
+        "arp_interval": [
+            "0"
+        ],
+        "arp_validate": [
+            "none",
+            "0"
+        ],
+        "downdelay": [
+            "0"
+        ],
+        "fail_over_mac": [
+            "none",
+            "0"
+        ],
+        "lacp_rate": [
+            "slow",
+            "0"
+        ],
+        "miimon": [
+            "0"
+        ],
+        "min_links": [
+            "0"
+        ],
+        "mode": [
+            "balance-rr",
+            "0"
+        ],
+        "num_grat_arp": [
+            "1"
+        ],
+        "num_unsol_na": [
+            "1"
+        ],
+        "primary_reselect": [
+            "always",
+            "0"
+        ],
+        "resend_igmp": [
+            "1"
+        ],
+        "updelay": [
+            "0"
+        ],
+        "use_carrier": [
+            "1"
+        ],
+        "xmit_hash_policy": [
+            "layer2",
+            "0"
+        ]
+    },
+    "4": {
+        "ad_select": [
+            "stable",
+            "0"
+        ],
+        "all_slaves_active": [
+            "0"
+        ],
+        "arp_interval": [
+            "0"
+        ],
+        "arp_validate": [
+            "none",
+            "0"
+        ],
+        "downdelay": [
+            "0"
+        ],
+        "fail_over_mac": [
+            "none",
+            "0"
+        ],
+        "lacp_rate": [
+            "slow",
+            "0"
+        ],
+        "miimon": [
+            "0"
+        ],
+        "min_links": [
+            "0"
+        ],
+        "mode": [
+            "balance-rr",
+            "0"
+        ],
+        "num_grat_arp": [
+            "1"
+        ],
+        "num_unsol_na": [
+            "1"
+        ],
+        "primary_reselect": [
+            "always",
+            "0"
+        ],
+        "resend_igmp": [
+            "1"
+        ],
+        "updelay": [
+            "0"
+        ],
+        "use_carrier": [
+            "1"
+        ],
+        "xmit_hash_policy": [
+            "layer2",
+            "0"
+        ]
+    },
+    "5": {
+        "ad_select": [
+            "stable",
+            "0"
+        ],
+        "all_slaves_active": [
+            "0"
+        ],
+        "arp_interval": [
+            "0"
+        ],
+        "arp_validate": [
+            "none",
+            "0"
+        ],
+        "downdelay": [
+            "0"
+        ],
+        "fail_over_mac": [
+            "none",
+            "0"
+        ],
+        "lacp_rate": [
+            "slow",
+            "0"
+        ],
+        "miimon": [
+            "0"
+        ],
+        "min_links": [
+            "0"
+        ],
+        "mode": [
+            "balance-rr",
+            "0"
+        ],
+        "num_grat_arp": [
+            "1"
+        ],
+        "num_unsol_na": [
+            "1"
+        ],
+        "primary_reselect": [
+            "always",
+            "0"
+        ],
+        "resend_igmp": [
+            "1"
+        ],
+        "updelay": [
+            "0"
+        ],
+        "use_carrier": [
+            "1"
+        ],
+        "xmit_hash_policy": [
+            "layer2",
+            "0"
+        ]
+    },
+    "6": {
+        "ad_select": [
+            "stable",
+            "0"
+        ],
+        "all_slaves_active": [
+            "0"
+        ],
+        "arp_interval": [
+            "0"
+        ],
+        "arp_validate": [
+            "none",
+            "0"
+        ],
+        "downdelay": [
+            "0"
+        ],
+        "fail_over_mac": [
+            "none",
+            "0"
+        ],
+        "lacp_rate": [
+            "slow",
+            "0"
+        ],
+        "miimon": [
+            "0"
+        ],
+        "min_links": [
+            "0"
+        ],
+        "mode": [
+            "balance-rr",
+            "0"
+        ],
+        "num_grat_arp": [
+            "1"
+        ],
+        "num_unsol_na": [
+            "1"
+        ],
+        "primary_reselect": [
+            "always",
+            "0"
+        ],
+        "resend_igmp": [
+            "1"
+        ],
+        "updelay": [
+            "0"
+        ],
+        "use_carrier": [
+            "1"
+        ],
+        "xmit_hash_policy": [
+            "layer2",
+            "0"
+        ]
+    }
+}
\ No newline at end of file
diff --git a/vdsm/sudoers.vdsm.in b/vdsm/sudoers.vdsm.in
index dbc035c..584807d 100644
--- a/vdsm/sudoers.vdsm.in
+++ b/vdsm/sudoers.vdsm.in
@@ -32,10 +32,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 = \
-    @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/33489
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I92bcf62a4ae1756b0d2857cc0c7387c128f9b8a0
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