Merge "Do not copy /sbin/ip to /usr/bin/monasa-agent-ip"

This commit is contained in:
Zuul 2020-04-27 16:43:40 +00:00 committed by Gerrit Code Review
commit 5148493fb7
2 changed files with 28 additions and 58 deletions

View File

@ -336,17 +336,19 @@ It is helpful for determining, for example, if a VM is in a panicked or halted s
2. Neutron L2 plugin with a tenant network type of `vlan` or `vxlan` (other types may be supported, but have not been tested).
3. The `python-neutronclient` library and its dependencies installed and available to the Monasca Agent
4. Each VM needs an appropriate security group configuration to allow ICMP
5. A sudoers entry for the monasca-agent user needs to be created which allows access to /bin/ip. For example:
Defaults:monasca-agent !requiretty
Defaults:monasca-agent secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
monasca-agent ALL = (root) NOPASSWD:/bin/ip
#### Detection
The monasca-setup detection plugin for libvirt performs the following tests and tasks before configuring ping checks:
1. Ability to determine the name of the user under which monasca-agent processes run (eg, `mon-agent`)
2. Availability of the `python-neutronclient` library (by attempting to import `client` from `neutronclient.v2_0`)
3. A separate enhanced-capabilities `ip` command exists:
a. The detection plugin copies `/sbin/ip` to `sys.path[0]/monasca-agent-ip` (see the [configuration](#configuration) section above for an example)
b. Permissions on the copy are changed to the `mon-agent` user (or whichever Agent user is configured), mode 0700.
c. The `/sbin/setcap` command is called, applying `cap_sys_admin+ep` to the copy, as `cap_sys_admin` is the only capability which provides `setns`, necessary to execute commands in a separate namespace.
d. The detection plugin confirms that the enhanced capabilities were successfully applied
3. Existance of /bin/ip. A separate enhanced-capabilities `ip` command exists:
4. Existence of a ping command; detection will try `/usr/bin/fping`, `/sbin/fping`, and `/bin/ping` in that order. `fping` is preferred because it allows for sub-second timeouts, but is not installed by default in some Linux distributions.
If any of the above requirements fail, a WARN-level message is output, describing the problem. The libvirt plugin will continue to function without these requirements, but ping checks will be disabled.

View File

@ -16,9 +16,6 @@
import logging
import os
import pwd
from shutil import copy
import subprocess
import sys
from oslo_config import cfg
from oslo_utils import importutils
@ -49,7 +46,7 @@ ping_options = [["/usr/bin/fping", "-n", "-c1", "-t250", "-q"],
["/bin/ping", "-n", "-c1", "-w1", "-q"],
["/usr/bin/ping", "-n", "-c1", "-w1", "-q"]]
# Path to 'ip' command (needed to execute ping within network namespaces)
ip_cmd = "/sbin/ip"
ip_cmd = "sudo /bin/ip"
# How many ping commands to run concurrently
default_max_ping_concurrency = 8
# Disk metrics can be collected at a larger interval than other vm metrics
@ -147,56 +144,27 @@ class Libvirt(plugin.Plugin):
log.warn("\tUnable to determine agent user. Skipping ping checks.")
return
try:
client = importutils.try_import('neutronclient.v2_0.client',
False)
if not client:
log.warning(
'\tpython-neutronclient module missing, '
'required for ping checks.')
return
client = importutils.try_import('neutronclient.v2_0.client',
False)
if not client:
log.warning(
'\tpython-neutronclient module missing, '
'required for ping checks.')
return
# TODO(dmllr) Find a better rundir or avoid copying the binary
# alltogether. see https://storyboard.openstack.org/#!/story/2001593
monasca_rundir = sys.path[0]
monasca_ip = "{0}/monasca-agent-ip".format(monasca_rundir)
# Copy system 'ip' command to monasca_rundir
copy(ip_cmd, monasca_ip)
# Restrict permissions on the local 'ip' command
os.chown(monasca_ip, *self._get_user_uid_gid(self._agent_user))
os.chmod(monasca_ip, 0o700)
# Set capabilities on 'ip' which will allow
# self.agent_user to exec commands in namespaces
setcap_cmd = ['/sbin/setcap', 'cap_sys_admin+ep',
monasca_ip]
subprocess.Popen(setcap_cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# Verify that the capabilities were set
setcap_cmd.extend(['-v', '-q'])
subprocess.check_call(setcap_cmd)
# Look for the best ping command
for ping_cmd in ping_options:
if os.path.isfile(ping_cmd[0]):
init_config[
'ping_check'] = "{0} netns exec NAMESPACE {1}".format(
monasca_ip,
' '.join(ping_cmd))
log.info(
"\tEnabling ping checks using {0}".format(ping_cmd[0]))
break
if init_config['ping_check'] is False:
log.warn('\tUnable to find suitable ping command, '
'disabling ping checks.')
except IOError:
log.warn('\tUnable to copy {0}, '
'ping checks disabled.'.format(ip_cmd))
pass
except (subprocess.CalledProcessError, OSError):
log.warn('\tUnable to set up ping checks, '
'setcap failed ({0})'.format(' '.join(setcap_cmd)))
pass
# Look for the best ping command
for ping_cmd in ping_options:
if os.path.isfile(ping_cmd[0]):
init_config[
'ping_check'] = "{0} netns exec NAMESPACE {1}".format(
ip_cmd,
' '.join(ping_cmd))
log.info(
"\tEnabling ping checks using {0}".format(ping_cmd[0]))
break
if init_config['ping_check'] is False:
log.warn('\tUnable to find suitable ping command, '
'disabling ping checks.')
def dependencies_installed(self):
return importutils.try_import('novaclient.client', False)