From 2d160ecfcb8a2fbdae999b73df62ab22979c63ad Mon Sep 17 00:00:00 2001 From: yatin Date: Thu, 3 Nov 2016 12:00:54 +0530 Subject: [PATCH] Support scheduler strategy for swarm cluster Swarm cluster can be created by specifying any of the scheduler strategy supported by swarm. The strategy can be specified while creating cluster template using labels parameter, Ex:- --labels swarm_strategy=spread Supported values for swarm_strategy=spread, binpack, random Change-Id: If471f10a3b1f955638a77d5afe462aebdeb4277c Implements: blueprint add-support-different-strategy-in-swarmbay --- magnum/api/attr_validator.py | 19 ++++++++++++++++++- .../common/swarm_fedora_template_def.py | 3 ++- .../fragments/write-swarm-master-service.sh | 1 + .../templates/cluster.yaml | 7 +++++++ .../templates/swarmmaster.yaml | 8 ++++++++ magnum/tests/unit/api/test_attr_validator.py | 14 ++++++++++++++ .../handlers/test_swarm_cluster_conductor.py | 8 +++++++- .../unit/drivers/test_template_definition.py | 4 +++- 8 files changed, 60 insertions(+), 4 deletions(-) diff --git a/magnum/api/attr_validator.py b/magnum/api/attr_validator.py index 537bf76c5d..68b96d266a 100644 --- a/magnum/api/attr_validator.py +++ b/magnum/api/attr_validator.py @@ -28,6 +28,7 @@ SUPPORTED_ISOLATION = ['filesystem/posix', 'filesystem/linux', 'cgroups/mem', 'docker/runtime', 'namespaces/pid'] SUPPORTED_IMAGE_PROVIDERS = ['docker', 'appc'] +SUPPORTED_SWARM_STRATEGY = ['spread', 'binpack', 'random'] def validate_image(cli, image): @@ -166,6 +167,21 @@ def validate_labels_executor_env_variables(labels): raise exception.InvalidParameterValue(err) +def validate_labels_strategy(labels): + """Validate swarm_strategy""" + swarm_strategy = list(labels.get('swarm_strategy', "").split()) + unsupported_strategy = set(swarm_strategy) - set( + SUPPORTED_SWARM_STRATEGY) + if (len(unsupported_strategy) > 0): + raise exception.InvalidParameterValue(_( + 'property "labels/swarm_strategy" with value ' + '"%(strategy)s" is not supported, supported values are: ' + '%(supported_strategies)s') % { + 'strategy': ' '.join(list(unsupported_strategy)), + 'supported_strategies': ', '.join( + SUPPORTED_SWARM_STRATEGY + ['unspecified'])}) + + def validate_os_resources(context, cluster_template, cluster=None): """Validate ClusterTemplate's OpenStack Resources""" @@ -201,4 +217,5 @@ labels_validators = {'mesos_slave_isolation': validate_labels_isolation, 'mesos_slave_image_providers': validate_labels_image_providers, 'mesos_slave_executor_env_variables': - validate_labels_executor_env_variables} + validate_labels_executor_env_variables, + 'swarm_strategy': validate_labels_strategy} diff --git a/magnum/drivers/common/swarm_fedora_template_def.py b/magnum/drivers/common/swarm_fedora_template_def.py index 00373b7b04..c5c596ab0e 100644 --- a/magnum/drivers/common/swarm_fedora_template_def.py +++ b/magnum/drivers/common/swarm_fedora_template_def.py @@ -94,7 +94,8 @@ class SwarmFedoraTemplateDefinition(template_def.BaseTemplateDefinition): extra_params['magnum_url'] = osc.magnum_url() label_list = ['flannel_network_cidr', 'flannel_backend', - 'flannel_network_subnetlen', 'rexray_preempt'] + 'flannel_network_subnetlen', 'rexray_preempt', + 'swarm_strategy'] extra_params['auth_url'] = context.auth_url diff --git a/magnum/drivers/common/templates/swarm/fragments/write-swarm-master-service.sh b/magnum/drivers/common/templates/swarm/fragments/write-swarm-master-service.sh index 4f006b4f50..47626bac5b 100644 --- a/magnum/drivers/common/templates/swarm/fragments/write-swarm-master-service.sh +++ b/magnum/drivers/common/templates/swarm/fragments/write-swarm-master-service.sh @@ -20,6 +20,7 @@ ExecStart=/usr/bin/docker run --name swarm-manager \\ -e no_proxy=$NO_PROXY \\ swarm:$SWARM_VERSION \\ manage -H tcp://0.0.0.0:2375 \\ + --strategy $SWARM_STRATEGY \\ --replication \\ --advertise $NODE_IP:2376 \\ END_SERVICE_TOP diff --git a/magnum/drivers/swarm_fedora_atomic_v1/templates/cluster.yaml b/magnum/drivers/swarm_fedora_atomic_v1/templates/cluster.yaml index 0de667db3f..63885dffec 100644 --- a/magnum/drivers/swarm_fedora_atomic_v1/templates/cluster.yaml +++ b/magnum/drivers/swarm_fedora_atomic_v1/templates/cluster.yaml @@ -147,6 +147,12 @@ parameters: description: version of swarm used for swarm cluster default: 1.0.0 + swarm_strategy: + type: string + description: > + schedule strategy to be used by swarm manager + default: "spread" + trustee_domain_id: type: string description: domain id of the trustee @@ -414,6 +420,7 @@ resources: etcd_server_ip: {get_attr: [etcd_loadbalancer, vip_address]} api_ip_address: {get_attr: [api_pool_floating, floating_ip_address]} swarm_version: {get_param: swarm_version} + swarm_strategy: {get_param: swarm_strategy} trustee_user_id: {get_param: trustee_user_id} trustee_password: {get_param: trustee_password} trust_id: {get_param: trust_id} diff --git a/magnum/drivers/swarm_fedora_atomic_v1/templates/swarmmaster.yaml b/magnum/drivers/swarm_fedora_atomic_v1/templates/swarmmaster.yaml index dacaa65d05..72d2900a6a 100644 --- a/magnum/drivers/swarm_fedora_atomic_v1/templates/swarmmaster.yaml +++ b/magnum/drivers/swarm_fedora_atomic_v1/templates/swarmmaster.yaml @@ -103,6 +103,13 @@ parameters: type: string description: version of swarm used for swarm cluster + swarm_strategy: + type: string + description: > + schedule strategy to be used by swarm manager + constraints: + - allowed_values: ["spread", "binpack", "random"] + secgroup_swarm_master_id: type: string description: ID of the security group for swarm master. @@ -315,6 +322,7 @@ resources: "$NO_PROXY": {get_param: no_proxy} "$TLS_DISABLED": {get_param: tls_disabled} "$SWARM_VERSION": {get_param: swarm_version} + "$SWARM_STRATEGY": {get_param: swarm_strategy} enable_services: type: "OS::Heat::SoftwareConfig" diff --git a/magnum/tests/unit/api/test_attr_validator.py b/magnum/tests/unit/api/test_attr_validator.py index 04d7778f33..01294113ce 100644 --- a/magnum/tests/unit/api/test_attr_validator.py +++ b/magnum/tests/unit/api/test_attr_validator.py @@ -186,6 +186,20 @@ class TestAttrValidator(base.BaseTestCase): attr_validator.validate_labels_isolation, fake_labels) + def test_validate_labels_strategy_valid(self): + fake_labels = {'swarm_strategy': 'spread'} + attr_validator.validate_labels_strategy(fake_labels) + + def test_validate_labels_strategy_missing(self): + fake_labels = {'strategy': 'spread'} + attr_validator.validate_labels_strategy(fake_labels) + + def test_validate_labels_strategy_invalid(self): + fake_labels = {'swarm_strategy': 'invalid'} + self.assertRaises(exception.InvalidParameterValue, + attr_validator.validate_labels_strategy, + fake_labels) + @mock.patch('magnum.api.utils.get_openstack_resource') def test_validate_image_with_valid_image_by_name(self, mock_os_res): mock_image = {'name': 'fedora-21-atomic-5', diff --git a/magnum/tests/unit/conductor/handlers/test_swarm_cluster_conductor.py b/magnum/tests/unit/conductor/handlers/test_swarm_cluster_conductor.py index 42c955d079..c20868d379 100644 --- a/magnum/tests/unit/conductor/handlers/test_swarm_cluster_conductor.py +++ b/magnum/tests/unit/conductor/handlers/test_swarm_cluster_conductor.py @@ -51,7 +51,8 @@ class TestClusterConductorWithSwarm(base.TestCase): 'labels': {'flannel_network_cidr': '10.101.0.0/16', 'flannel_network_subnetlen': '26', 'flannel_backend': 'vxlan', - 'rexray_preempt': 'False'}, + 'rexray_preempt': 'False', + 'swarm_strategy': 'spread'}, 'master_lb_enabled': False, 'volume_driver': 'rexray' } @@ -139,6 +140,7 @@ class TestClusterConductorWithSwarm(base.TestCase): 'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de', 'auth_url': 'http://192.168.10.10:5000/v3', 'swarm_version': 'fake-version', + 'swarm_strategy': u'spread', 'volume_driver': 'rexray', 'rexray_preempt': 'False' } @@ -209,6 +211,7 @@ class TestClusterConductorWithSwarm(base.TestCase): 'auth_url': 'http://192.168.10.10:5000/v3', 'docker_storage_driver': 'devicemapper', 'swarm_version': 'fake-version', + 'swarm_strategy': u'spread', 'volume_driver': 'rexray', 'rexray_preempt': 'False' } @@ -272,6 +275,7 @@ class TestClusterConductorWithSwarm(base.TestCase): 'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de', 'auth_url': 'http://192.168.10.10:5000/v3', 'swarm_version': 'fake-version', + 'swarm_strategy': u'spread', 'rexray_preempt': 'False' } self.assertEqual(expected, definition) @@ -335,6 +339,7 @@ class TestClusterConductorWithSwarm(base.TestCase): 'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de', 'auth_url': 'http://192.168.10.10:5000/v3', 'swarm_version': 'fake-version', + 'swarm_strategy': u'spread', 'volume_driver': 'rexray', 'rexray_preempt': 'False' } @@ -400,6 +405,7 @@ class TestClusterConductorWithSwarm(base.TestCase): 'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de', 'auth_url': 'http://192.168.10.10:5000/v3', 'swarm_version': 'fake-version', + 'swarm_strategy': u'spread', 'volume_driver': 'rexray', 'rexray_preempt': 'False' } diff --git a/magnum/tests/unit/drivers/test_template_definition.py b/magnum/tests/unit/drivers/test_template_definition.py index 598d7b6ebd..d800f171f0 100644 --- a/magnum/tests/unit/drivers/test_template_definition.py +++ b/magnum/tests/unit/drivers/test_template_definition.py @@ -718,6 +718,7 @@ class AtomicSwarmTemplateDefinitionTestCase(base.TestCase): 'flannel_network_subnetlen') flannel_backend = mock_cluster_template.labels.get('flannel_backend') rexray_preempt = mock_cluster_template.labels.get('rexray_preempt') + swarm_strategy = mock_cluster_template.labels.get('swarm_strategy') swarm_def = swarm_tdef.AtomicSwarmTemplateDefinition() @@ -730,7 +731,8 @@ class AtomicSwarmTemplateDefinitionTestCase(base.TestCase): 'flannel_backend': flannel_backend, 'flannel_network_subnetlen': flannel_subnet, 'auth_url': 'http://192.168.10.10:5000/v3', - 'rexray_preempt': rexray_preempt}} + 'rexray_preempt': rexray_preempt, + 'swarm_strategy': swarm_strategy}} mock_get_params.assert_called_once_with(mock_context, mock_cluster_template, mock_cluster,