From a17615a726601e4abc26831330c4204cb2b06655 Mon Sep 17 00:00:00 2001 From: Ilya Shakhat Date: Mon, 20 Apr 2015 16:59:25 +0300 Subject: [PATCH] Use MAC as default agent id Also do not allow to run 2 agents at the same host pointing to the same server-endpoint Change-Id: Id1ef2d5d78acdbb3bde12cf05c2fb9a474691ed1 --- doc/source/tools/shaker-agent.txt | 2 +- doc/source/tools/shaker-report.txt | 2 +- doc/source/tools/shaker.txt | 2 +- etc/shaker.conf | 6 ++-- requirements.txt | 1 + shaker/agent/agent.py | 49 ++++++++++++++++++++++++++++++ shaker/engine/config.py | 3 +- 7 files changed, 57 insertions(+), 8 deletions(-) diff --git a/doc/source/tools/shaker-agent.txt b/doc/source/tools/shaker-agent.txt index 3b3edf4..42cda69 100644 --- a/doc/source/tools/shaker-agent.txt +++ b/doc/source/tools/shaker-agent.txt @@ -10,7 +10,7 @@ usage: shaker-agent [-h] [--agent-id AGENT_ID] [--config-dir DIR] optional arguments: -h, --help show this help message and exit - --agent-id AGENT_ID Agent unique id, defaults to env[SHAKER_AGENT_ID]. + --agent-id AGENT_ID Agent unique id, defaults to MAC of primary interface. --config-dir DIR Path to a config directory to pull *.conf files from. This file set is sorted, so as to provide a predictable parse order if individual options are diff --git a/doc/source/tools/shaker-report.txt b/doc/source/tools/shaker-report.txt index 4e2dd36..decfcf0 100644 --- a/doc/source/tools/shaker-report.txt +++ b/doc/source/tools/shaker-report.txt @@ -65,4 +65,4 @@ optional arguments: instead of default WARNING level). --version show program's version number and exit --report-template REPORT_TEMPLATE - Report template in Jinja format + Report template file name diff --git a/doc/source/tools/shaker.txt b/doc/source/tools/shaker.txt index 69a1807..5304ab1 100644 --- a/doc/source/tools/shaker.txt +++ b/doc/source/tools/shaker.txt @@ -90,7 +90,7 @@ optional arguments: How frequently the agent polls server, in seconds --report REPORT Report file name, defaults to env[SHAKER_REPORT]. --report-template REPORT_TEMPLATE - Report template in Jinja format + Report template file name --scenario SCENARIO Scenario file name, defaults to env[SHAKER_SCENARIO]. --subunit SUBUNIT Subunit stream file name, defaults to env[SHAKER_SUBUNIT]. diff --git a/etc/shaker.conf b/etc/shaker.conf index 39d9392..7ca3e1d 100644 --- a/etc/shaker.conf +++ b/etc/shaker.conf @@ -139,8 +139,8 @@ # Do not generate report for failed scenarios (boolean value) #no_report_on_error = false -# Report template in Jinja format (string value) -#report_template = shaker/resources/report_template.jinja2 +# Report template file name (string value) +#report_template = shaker/resources/report_template.html # Report file name, defaults to env[SHAKER_REPORT]. (string value) #report = @@ -151,7 +151,7 @@ # File to read test results from, defaults to env[SHAKER_INPUT]. (string value) #input = -# Agent unique id, defaults to env[SHAKER_AGENT_ID]. (string value) +# Agent unique id, defaults to MAC of primary interface. (string value) #agent_id = # Heat template for the image builder. (string value) diff --git a/requirements.txt b/requirements.txt index 2030010..f827e4c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,7 @@ oslo.i18n>=1.3.0 # Apache-2.0 oslo.log>=0.4.0 # Apache-2.0 oslo.serialization>=1.2.0 # Apache-2.0 oslo.utils>=1.2.0 # Apache-2.0 +psutil>=1.1.1,<2.0.0 python-glanceclient>=0.15.0 python-keystoneclient>=1.1.0 python-neutronclient>=2.3.11,<3 diff --git a/shaker/agent/agent.py b/shaker/agent/agent.py index e79ce14..2120974 100644 --- a/shaker/agent/agent.py +++ b/shaker/agent/agent.py @@ -14,13 +14,16 @@ # limitations under the License. import os +import re import shlex import tempfile import time +import uuid from oslo_concurrency import processutils from oslo_config import cfg from oslo_log import log as logging +import psutil import sys import zmq @@ -116,6 +119,39 @@ def work(agent_id, endpoint, polling_interval): LOG.exception(e) +def get_mac(): + s = '%012x' % uuid.getnode() + return ':'.join([s[i:i + 2] for i in range(0, len(s), 2)]) + + +def check_if_already_running(my_endpoint): + def _pick_shaker_agents(): + PSUTIL2 = psutil.version_info >= (2, 0) # compatibility bw 1.x and 2.x + + my_pid = os.getpid() + for pid in psutil.get_pid_list(): + if pid != my_pid: + try: + p = psutil.Process(pid) + except Exception as e: + LOG.info('Exception while iterating process list: %s', e) + + name = p.name() if PSUTIL2 else p.name + if name == 'shaker-agent': + yield (p.cmdline() if PSUTIL2 else p.cmdline) + + for cmdline in _pick_shaker_agents(): + LOG.info('Found running shaker-agent: %s', ' '.join(cmdline)) + + args = iter(cmdline) + for arg in args: + if arg == '--server-endpoint': + other_endpoint = next(args) + return other_endpoint == my_endpoint + + return None + + def main(): utils.init_config_and_logging(config.COMMON_OPTS + config.AGENT_OPTS) @@ -123,6 +159,19 @@ def main(): polling_interval = cfg.CONF.polling_interval agent_id = cfg.CONF.agent_id + if not re.match('\S+:\d+', endpoint): + LOG.error('Wrong value of server_endpoint, expected :, ' + 'but got: %s', endpoint) + exit(1) + + if check_if_already_running(endpoint): + LOG.warning('Shaker-agent already running with the same endpoint') + exit(1) + + if not agent_id: + agent_id = get_mac() + LOG.info('Using MAC address as agent_id: %s', agent_id) + work(agent_id, endpoint, polling_interval) if __name__ == "__main__": diff --git a/shaker/engine/config.py b/shaker/engine/config.py index bbe3571..5094648 100644 --- a/shaker/engine/config.py +++ b/shaker/engine/config.py @@ -118,8 +118,7 @@ INPUT_OPTS = [ AGENT_OPTS = [ cfg.StrOpt('agent-id', default=utils.env('SHAKER_AGENT_ID'), - required=True, - help='Agent unique id, defaults to env[SHAKER_AGENT_ID].'), + help='Agent unique id, defaults to MAC of primary interface.'), ] IMAGE_BUILDER_OPTS = [