Add template definition of Mesos bay

After this commit, users should be able to create a Mesos bay.
To do that, they need to create a baymodel first. The baymodel
should have a coe attribute with value 'mesos'. Then they can
create a Mesos bay by using the baymodel.

Change-Id: I19eaa7abf028ab81070bea18991940462ad509ad
Partial-Implements: blueprint mesos-bay-type
This commit is contained in:
Hongbin Lu 2015-06-12 23:47:31 -04:00
parent e2935280ef
commit 4fc17a1f66
7 changed files with 195 additions and 5 deletions

View File

@ -438,6 +438,75 @@ Now that we're done with the container we can delete it::
magnum container-delete test-container magnum container-delete test-container
Building and Using a Mesos Bay
==============================
Provisioning a mesos bay requires a Ubuntu-based image with some packages
pre-installed. To build and upload such image, please refer to
`<http://git.openstack.org/cgit/openstack/magnum/tree/magnum/templates/heat-mesos/elements/README.md>`_
Then, create a baymodel by using 'mesos' as the coe, with the rest of arguments
similar to the Kubernetes baymodel::
NIC_ID=$(neutron net-show public | awk '/ id /{print $4}')
magnum baymodel-create --name mesosbaymodel --image-id ubuntu-mesos \
--keypair-id testkey \
--external-network-id $NIC_ID \
--dns-nameserver 8.8.8.8 --flavor-id m1.small \
--coe mesos
Finally, create the bay. Use the baymodel 'mesosbaymodel' as a template for
bay creation. This bay will result in one mesos master node and two mesos
slave nodes::
magnum bay-create --name mesosbay --baymodel mesosbaymodel --node-count 2
Now that we have a mesos bay we can start interacting with it. First we need
to make sure the bay's status is 'CREATE_COMPLETE'::
$ magnum bay-show mesosbay
+----------------+--------------------------------------+
| Property | Value |
+----------------+--------------------------------------+
| status | CREATE_COMPLETE |
| uuid | ff727f0d-72ca-4e2b-9fef-5ec853d74fdf |
| created_at | 2015-06-09T20:21:43+00:00 |
| updated_at | 2015-06-09T20:28:18+00:00 |
| api_address | 172.24.4.115 |
| baymodel_id | 92dbda62-32d4-4435-88fc-8f42d514b347 |
| node_count | 2 |
| node_addresses | [u'172.24.4.116', u'172.24.4.117'] |
| status_reason | Stack CREATE completed successfully |
| discovery_url | None |
| name | mesosbay |
+----------------+--------------------------------------+
Next we will create a container in this bay by using the REST API of Marathon.
This container will ping the address 8.8.8.8::
$ cat > mesos.json << END
{
"container": {
"type": "DOCKER",
"docker": {
"image": "cirros"
}
},
"id": "ubuntu",
"instances": 1,
"cpus": 0.5,
"mem": 512,
"uris": [],
"cmd": "ping 8.8.8.8"
}
END
$ MASTER_IP=$(magnum bay-show mesosbay | awk '/ api_address /{print $4}')
$ curl -X POST -H "Content-Type: application/json" \
http://${MASTER_IP}:8080/v2/apps -d@mesos.json
Using the Marathon web console (at http://<master>:8080/), you will see the
application you created.
Building Developer Documentation Building Developer Documentation
================================ ================================

View File

@ -259,8 +259,12 @@
# Url for swarm public discovery endpoint. (string value) # Url for swarm public discovery endpoint. (string value)
#public_swarm_discovery_url = https://discovery-stage.hub.docker.com/v1/clusters #public_swarm_discovery_url = https://discovery-stage.hub.docker.com/v1/clusters
# Location of template to build a mesos cluster on ubuntu. (string
# value)
#mesos_ubuntu_template_path = $pybasedir/templates/heat-mesos/mesoscluster.yaml
# Enabled bay definition entry points. (list value) # Enabled bay definition entry points. (list value)
#enabled_definitions = magnum_vm_atomic_k8s,magnum_vm_coreos_k8s,magnum_vm_atomic_swarm #enabled_definitions = magnum_vm_atomic_k8s,magnum_vm_coreos_k8s,magnum_vm_atomic_swarm,magnum_vm_ubuntu_mesos
[bay_heat] [bay_heat]

View File

@ -64,9 +64,14 @@ template_def_opts = [
cfg.StrOpt('public_swarm_discovery_url', cfg.StrOpt('public_swarm_discovery_url',
default='https://discovery-stage.hub.docker.com/v1/clusters', default='https://discovery-stage.hub.docker.com/v1/clusters',
help=_('Url for swarm public discovery endpoint.')), help=_('Url for swarm public discovery endpoint.')),
cfg.StrOpt('mesos_ubuntu_template_path',
default=paths.basedir_def('templates/heat-mesos/'
'mesoscluster.yaml'),
help=_('Location of template to build a mesos cluster '
'on ubuntu. ')),
cfg.ListOpt('enabled_definitions', cfg.ListOpt('enabled_definitions',
default=['magnum_vm_atomic_k8s', 'magnum_vm_coreos_k8s', default=['magnum_vm_atomic_k8s', 'magnum_vm_coreos_k8s',
'magnum_vm_atomic_swarm'], 'magnum_vm_atomic_swarm', 'magnum_vm_ubuntu_mesos'],
help=_('Enabled bay definition entry points. ')), help=_('Enabled bay definition entry points. ')),
] ]
@ -304,7 +309,6 @@ class BaseTemplateDefinition(TemplateDefinition):
self.add_parameter('ssh_key_name', self.add_parameter('ssh_key_name',
baymodel_attr='keypair_id', baymodel_attr='keypair_id',
required=True) required=True)
self.add_parameter('server_image', self.add_parameter('server_image',
baymodel_attr='image_id') baymodel_attr='image_id')
self.add_parameter('dns_nameserver', self.add_parameter('dns_nameserver',
@ -452,3 +456,31 @@ class AtomicSwarmTemplateDefinition(BaseTemplateDefinition):
@property @property
def template_path(self): def template_path(self):
return cfg.CONF.bay.swarm_atomic_template_path return cfg.CONF.bay.swarm_atomic_template_path
class UbuntuMesosTemplateDefinition(BaseTemplateDefinition):
provides = [
{'platform': 'vm', 'os': 'ubuntu', 'coe': 'mesos'},
]
def __init__(self):
super(UbuntuMesosTemplateDefinition, self).__init__()
self.add_parameter('external_network',
baymodel_attr='external_network_id',
required=True)
self.add_parameter('number_of_slaves',
bay_attr='node_count',
param_type=str)
self.add_parameter('master_flavor',
baymodel_attr='master_flavor_id')
self.add_parameter('slave_flavor',
baymodel_attr='flavor_id')
self.add_output('mesos_master',
bay_attr='api_address')
self.add_output('mesos_slaves',
bay_attr='node_addresses')
@property
def template_path(self):
return cfg.CONF.bay.mesos_ubuntu_template_path

View File

@ -18,7 +18,7 @@ from magnum.tests import base
class TestTemplates(base.TestCase): class TestTemplates(base.TestCase):
def test_templates_list(self): def test_templates_list(self):
entry_points = list(tdef.TemplateDefinition.load_entry_points()) entry_points = list(tdef.TemplateDefinition.load_entry_points())
self.assertEqual(3, len(entry_points)) self.assertEqual(4, len(entry_points))
templates = [] templates = []
for entry_point, def_class in entry_points: for entry_point, def_class in entry_points:
@ -26,5 +26,6 @@ class TestTemplates(base.TestCase):
self.assertEqual(['AtomicK8sTemplateDefinition', self.assertEqual(['AtomicK8sTemplateDefinition',
'AtomicSwarmTemplateDefinition', 'AtomicSwarmTemplateDefinition',
'CoreOSK8sTemplateDefinition'], 'CoreOSK8sTemplateDefinition',
'UbuntuMesosTemplateDefinition'],
sorted(templates)) sorted(templates))

View File

@ -745,3 +745,77 @@ class TestBayConductorWithSwarm(base.TestCase):
'discovery_url': 'test_discovery' 'discovery_url': 'test_discovery'
} }
self.assertEqual(expected, definition) self.assertEqual(expected, definition)
class TestBayConductorWithMesos(base.TestCase):
def setUp(self):
super(TestBayConductorWithMesos, self).setUp()
self.baymodel_dict = {
'image_id': 'image_id',
'flavor_id': 'flavor_id',
'master_flavor_id': 'master_flavor_id',
'keypair_id': 'keypair_id',
'dns_nameserver': 'dns_nameserver',
'external_network_id': 'external_network_id',
'fixed_network': '10.2.0.0/22',
'cluster_distro': 'ubuntu',
'coe': 'mesos'
}
self.bay_dict = {
'id': 1,
'uuid': 'some_uuid',
'baymodel_id': 'xx-xx-xx-xx',
'name': 'bay1',
'stack_id': 'xx-xx-xx-xx',
'api_address': '172.17.2.3',
'node_addresses': ['172.17.2.4'],
'node_count': 1,
}
@patch('magnum.objects.BayModel.get_by_uuid')
def test_extract_template_definition_all_values(
self,
mock_objects_baymodel_get_by_uuid):
baymodel = objects.BayModel(self.context, **self.baymodel_dict)
mock_objects_baymodel_get_by_uuid.return_value = baymodel
bay = objects.Bay(self.context, **self.bay_dict)
(template_path,
definition) = bay_conductor._extract_template_definition(self.context,
bay)
expected = {
'ssh_key_name': 'keypair_id',
'external_network': 'external_network_id',
'dns_nameserver': 'dns_nameserver',
'server_image': 'image_id',
'master_flavor': 'master_flavor_id',
'slave_flavor': 'flavor_id',
'number_of_slaves': '1',
'fixed_network_cidr': '10.2.0.0/22'
}
self.assertEqual(expected, definition)
@patch('magnum.objects.BayModel.get_by_uuid')
def test_extract_template_definition_only_required(
self,
mock_objects_baymodel_get_by_uuid):
not_required = ['image_id', 'master_flavor_id', 'flavor_id',
'dns_nameserver', 'fixed_network']
for key in not_required:
self.baymodel_dict[key] = None
baymodel = objects.BayModel(self.context, **self.baymodel_dict)
mock_objects_baymodel_get_by_uuid.return_value = baymodel
bay = objects.Bay(self.context, **self.bay_dict)
(template_path,
definition) = bay_conductor._extract_template_definition(self.context,
bay)
expected = {
'ssh_key_name': 'keypair_id',
'external_network': 'external_network_id',
'number_of_slaves': '1',
}
self.assertEqual(expected, definition)

View File

@ -76,6 +76,15 @@ class TemplateDefinitionTestCase(base.TestCase):
self.assertIsInstance(definition, self.assertIsInstance(definition,
tdef.AtomicSwarmTemplateDefinition) tdef.AtomicSwarmTemplateDefinition)
def test_get_vm_ubuntu_mesos_definition(self):
definition = tdef.TemplateDefinition.get_template_definition(
'vm',
'ubuntu',
'mesos')
self.assertIsInstance(definition,
tdef.UbuntuMesosTemplateDefinition)
def test_get_definition_not_supported(self): def test_get_definition_not_supported(self):
self.assertRaises(exception.BayTypeNotSupported, self.assertRaises(exception.BayTypeNotSupported,
tdef.TemplateDefinition.get_template_definition, tdef.TemplateDefinition.get_template_definition,

View File

@ -57,6 +57,7 @@ magnum.template_definitions =
magnum_vm_atomic_k8s = magnum.conductor.template_definition:AtomicK8sTemplateDefinition magnum_vm_atomic_k8s = magnum.conductor.template_definition:AtomicK8sTemplateDefinition
magnum_vm_coreos_k8s = magnum.conductor.template_definition:CoreOSK8sTemplateDefinition magnum_vm_coreos_k8s = magnum.conductor.template_definition:CoreOSK8sTemplateDefinition
magnum_vm_atomic_swarm = magnum.conductor.template_definition:AtomicSwarmTemplateDefinition magnum_vm_atomic_swarm = magnum.conductor.template_definition:AtomicSwarmTemplateDefinition
magnum_vm_ubuntu_mesos = magnum.conductor.template_definition:UbuntuMesosTemplateDefinition
[wheel] [wheel]
universal = 1 universal = 1