From a8b320bb0f683d1ad84f6da5b382ae4846636886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89douard=20Thuleau?= Date: Mon, 19 Jan 2015 18:11:39 +0100 Subject: [PATCH] Check vrouter release before schedule VM SI Check if the vrouter agent version supports to be scheduled for a virtual machine that compose a service instance. Closes-bug: #1412515 (cherry picked from commit fa7b70c30277c4e2d2286d0d5fd8a72ef71ac957) Conflicts: src/config/svc-monitor/svc_monitor/scheduler/vrouter_scheduler.py src/config/svc-monitor/svc_monitor/tests/scheduler/test_vrouter_schedulers.py Change-Id: Id25144e7b67fcbae0e4e56d488a6f4025813b644 --- src/config/common/svc_info.py | 3 ++ .../scheduler/vrouter_scheduler.py | 31 ++++++++++++++++ .../scheduler/test_vrouter_schedulers.py | 35 +++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/src/config/common/svc_info.py b/src/config/common/svc_info.py index 8750d6be05c..da79e7aec2d 100644 --- a/src/config/common/svc_info.py +++ b/src/config/common/svc_info.py @@ -27,6 +27,9 @@ _ACTIVE_LOCAL_PREFERENCE = 200 _STANDBY_LOCAL_PREFERENCE = 100 +# Version from the vrouter agent can manage service instances +_VROUTER_NETNS_SUPPORTED_VERSION = '1.10' + def get_management_if_str(): return _MGMT_STR diff --git a/src/config/svc-monitor/svc_monitor/scheduler/vrouter_scheduler.py b/src/config/svc-monitor/svc_monitor/scheduler/vrouter_scheduler.py index 2800d9cffe3..ced06530442 100644 --- a/src/config/svc-monitor/svc_monitor/scheduler/vrouter_scheduler.py +++ b/src/config/svc-monitor/svc_monitor/scheduler/vrouter_scheduler.py @@ -18,10 +18,13 @@ # @author: Edouard Thuleau, Cloudwatt. import abc +import ast +from distutils.version import StrictVersion as V import random import six from cfgm_common import analytics_client +from cfgm_common import svc_info from vnc_api.vnc_api import NoIdError @six.add_metaclass(abc.ABCMeta) @@ -59,6 +62,11 @@ def _get_candidates(self, si_uuid, vm_uuid): vrs_fq_name = [vr['fq_name'] for vr in self._vnc_lib.virtual_routers_list()['virtual-routers'] if self.vrouter_running(vr['fq_name'][-1])] + vrs_fq_name = [vr_fq_name for vr_fq_name in vrs_fq_name + if self.vrouter_check_version( + vr_fq_name[-1], + svc_info._VROUTER_NETNS_SUPPORTED_VERSION)] + for vr_fq_name in vrs_fq_name: try: vr_obj = self._vnc_lib.virtual_router_read(fq_name=vr_fq_name) @@ -101,6 +109,29 @@ def vrouter_running(self, vrouter_name): return False + def vrouter_check_version(self, vrouter_name, version): + """Check the vrouter version is upper or equal to a desired version.""" + path = "/analytics/uves/vrouter/" + fqdn_uuid = "%s?cfilt=VrouterAgent" % vrouter_name + + try: + vrouter_agent = self._analytics.request(path, fqdn_uuid) + except analytics_client.OpenContrailAPIFailed: + return False + + if not vrouter_agent: + return False + + try: + build_info = ast.literal_eval( + vrouter_agent['VrouterAgent']['build_info']) + vrouter_version = V(build_info['build-info'][0]['build-version']) + requested_version = V(version) + except KeyError, ValueError: + return False + + return vrouter_version >= requested_version + def _bind_vrouter(self, vm_uuid, vr_fq_name): """Bind the virtual machine to the vrouter which has been chosen.""" vm_obj = self._vnc_lib.virtual_machine_read(id=vm_uuid) diff --git a/src/config/svc-monitor/svc_monitor/tests/scheduler/test_vrouter_schedulers.py b/src/config/svc-monitor/svc_monitor/tests/scheduler/test_vrouter_schedulers.py index 1bd252a1ad6..4cf853efaa4 100644 --- a/src/config/svc-monitor/svc_monitor/tests/scheduler/test_vrouter_schedulers.py +++ b/src/config/svc-monitor/svc_monitor/tests/scheduler/test_vrouter_schedulers.py @@ -21,6 +21,7 @@ import unittest import cfgm_common.analytics_client as analytics +import cfgm_common.svc_info as svc_info import svc_monitor.scheduler.vrouter_scheduler as scheduler from vnc_api.vnc_api import VirtualRouter, VirtualMachine @@ -55,6 +56,9 @@ } ], "description": "null" + }, + "VrouterAgent": { + "build_info": "{\"build-info\":[{\"build-time\":\"2015-01-12 11:13:42.160435\",\"build-hostname\":\"vrouter1\",\"build-git-ver\":\"bdcb043\",\"build-user\":\"root\",\"build-version\":\"2.0\",\"build-id\":\"unknown\",\"build-number\":\"unknown\"}]}" } } @@ -88,6 +92,9 @@ } ], "description": "null" + }, + "VrouterAgent": { + "build_info": "{\"build-info\":[{\"build-time\":\"2015-01-12 11:13:42.160435\",\"build-hostname\":\"vrouter1\",\"build-git-ver\":\"bdcb043\",\"build-user\":\"root\",\"build-version\":\"1.06\",\"build-id\":\"unknown\",\"build-number\":\"unknown\"}]}" } } @@ -121,6 +128,9 @@ } ], "description": "null" + }, + "VrouterAgent": { + "build_info": "{\"build-info\":[{\"build-time\":\"2015-01-12 11:13:42.160435\",\"build-hostname\":\"vrouter1\",\"build-git-ver\":\"bdcb043\",\"build-user\":\"root\",\"build-version\":\"1.10\",\"build-id\":\"unknown\",\"build-number\":\"unknown\"}]}" } } @@ -154,6 +164,9 @@ } ], "description": "null" + }, + "VrouterAgent": { + "build_info": "{\"build-info\":[{\"build-time\":\"2015-01-12 11:13:42.160435\",\"build-hostname\":\"vrouter1\",\"build-git-ver\":\"bdcb043\",\"build-user\":\"root\",\"build-version\":\"2.0\",\"build-id\":\"unknown\",\"build-number\":\"unknown\"}]}" } } @@ -213,6 +226,8 @@ def test_get_candidates(self): self.analytics_mock.side_effect = [RUNNING_VROUTER_UVES_STATUS, NON_RUNNING_VROUTER_UVES_STATUS_3, + RUNNING_VROUTER_UVES_STATUS, + RUNNING_VROUTER_UVES_STATUS, RUNNING_VROUTER_UVES_STATUS] vr_obj = VirtualRouter() @@ -246,6 +261,26 @@ def test_vrouter_running(self): self.assertFalse(self.scheduler.vrouter_running('fake_vrouter_name')) self.assertTrue(self.scheduler.vrouter_running('fake_vrouter_name')) + def test_vrouter_check_version(self): + self.analytics_mock.side_effect = [analytics.OpenContrailAPIFailed, + NON_RUNNING_VROUTER_UVES_STATUS_1, + NON_RUNNING_VROUTER_UVES_STATUS_2, + NON_RUNNING_VROUTER_UVES_STATUS_3, + NON_RUNNING_VROUTER_UVES_STATUS_4, + RUNNING_VROUTER_UVES_STATUS] + self.assertFalse(self.scheduler.vrouter_check_version( + 'fake_vrouter_name', svc_info._VROUTER_NETNS_SUPPORTED_VERSION)) + self.assertFalse(self.scheduler.vrouter_check_version( + 'fake_vrouter_name', svc_info._VROUTER_NETNS_SUPPORTED_VERSION)) + self.assertTrue(self.scheduler.vrouter_check_version( + 'fake_vrouter_name', svc_info._VROUTER_NETNS_SUPPORTED_VERSION)) + self.assertTrue(self.scheduler.vrouter_check_version( + 'fake_vrouter_name', svc_info._VROUTER_NETNS_SUPPORTED_VERSION)) + self.assertFalse(self.scheduler.vrouter_check_version( + 'fake_vrouter_name', svc_info._VROUTER_NETNS_SUPPORTED_VERSION)) + self.assertTrue(self.scheduler.vrouter_check_version( + 'fake_vrouter_name', svc_info._VROUTER_NETNS_SUPPORTED_VERSION)) + def test_random_scheduling(self): random_patch = mock.patch('random.choice') random_mock = random_patch.start()