From 17ba1346b7d3cdc6914442465ed172518cb81d30 Mon Sep 17 00:00:00 2001 From: KeithMnemonic Date: Tue, 7 Apr 2020 15:14:45 -0400 Subject: [PATCH] Do not copy /sbin/ip to /usr/bin/monasa-agent-ip This patch removes the code that does the copy of /sbin/ip to /usr/bin/monasca-agent-ip. There is a limitation with /sbin/ip that limits copying it to a new name that is longer than 2 characters. The error is: ./monasca-agent-ip a Object "nasca-agent-ip" is unknown, try "ip help". As this is not working on RHEL,SLES, or Ubuntu this code should be removed. Change-Id: I439be00070eb1cf16416325f23a86fc7cd518acc Story: 2001593 Task: 6543 --- docs/Libvirt.md | 12 ++-- monasca_setup/detection/plugins/libvirt.py | 74 ++++++---------------- 2 files changed, 28 insertions(+), 58 deletions(-) diff --git a/docs/Libvirt.md b/docs/Libvirt.md index 36679d3b..ed3f8ebe 100644 --- a/docs/Libvirt.md +++ b/docs/Libvirt.md @@ -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. diff --git a/monasca_setup/detection/plugins/libvirt.py b/monasca_setup/detection/plugins/libvirt.py index 1d904fb5..c42e6cc6 100644 --- a/monasca_setup/detection/plugins/libvirt.py +++ b/monasca_setup/detection/plugins/libvirt.py @@ -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)