Merge "Replace cluster size with new property desired_capacity"

This commit is contained in:
Jenkins 2015-04-29 08:49:20 +00:00 committed by Gerrit Code Review
commit 9086166e93
16 changed files with 89 additions and 79 deletions

View File

@ -42,10 +42,11 @@ class ClusterData(object):
raise exc.HTTPBadRequest(_("No cluster name specified."))
return self.data[consts.CLUSTER_NAME]
def size(self):
if consts.CLUSTER_SIZE not in self.data:
raise exc.HTTPBadRequest(_("No cluster size provided."))
return self.data.get(consts.CLUSTER_SIZE, None)
def desired_capacity(self):
if consts.CLUSTER_DESIRED_CAPACITY not in self.data:
raise exc.HTTPBadRequest(_("No cluster desired "
"capacity provided."))
return self.data.get(consts.CLUSTER_DESIRED_CAPACITY, None)
def profile(self):
if consts.CLUSTER_PROFILE not in self.data:
@ -133,7 +134,8 @@ class ClusterController(object):
data = ClusterData(cluster_data)
cluster = self.rpc_client.cluster_create(req.context, data.name(),
data.size(), data.profile(),
data.desired_capacity(),
data.profile(),
data.parent(), data.tags(),
data.timeout())
@ -155,10 +157,10 @@ class ClusterController(object):
raise exc.HTTPBadRequest(_("Malformed request data, missing "
"'cluster' key in request body."))
size = cluster_data.get(consts.CLUSTER_SIZE)
if size is not None:
msg = _("Updating cluster size is not supported, please use "
"cluster scaling operations instead.")
desired_capacity = cluster_data.get(consts.CLUSTER_DESIRED_CAPACITY)
if desired_capacity is not None:
msg = _("Updating cluster desired capacity is not supported, "
"please use cluster scaling operations instead.")
raise exc.HTTPBadRequest(msg)
name = cluster_data.get(consts.CLUSTER_NAME)

View File

@ -54,14 +54,14 @@ ACTION_NAMES = (
CLUSTER_ATTRS = (
CLUSTER_NAME, CLUSTER_PROFILE, CLUSTER_SIZE,
CLUSTER_NAME, CLUSTER_PROFILE, CLUSTER_DESIRED_CAPACITY,
CLUSTER_ID, CLUSTER_PARENT,
CLUSTER_DOMAIN, CLUSTER_PROJECT, CLUSTER_USER,
CLUSTER_CREATED_TIME, CLUSTER_UPDATED_TIME, CLUSTER_DELETED_TIME,
CLUSTER_STATUS, CLUSTER_STATUS_REASON, CLUSTER_TIMEOUT,
CLUSTER_TAGS,
) = (
'name', 'profile_id', 'size',
'name', 'profile_id', 'desired_capacity',
'id', 'parent',
'domain', 'project', 'user',
'created_time', 'updated_time', 'deleted_time',

View File

@ -296,7 +296,6 @@ def node_create(context, values):
cluster_id = values.get('cluster_id', None)
if cluster_id is not None:
cluster = session.query(models.Cluster).get(cluster_id)
cluster.size += 1
cluster.next_index += 1
cluster.save(session)
@ -425,12 +424,9 @@ def node_migrate(context, node_id, to_cluster, timestamp):
node = session.query(models.Node).get(node_id)
from_cluster = node.cluster_id
if from_cluster is not None:
cluster1 = session.query(models.Cluster).get(from_cluster)
cluster1.size -= 1
node.index = -1
if to_cluster is not None:
cluster2 = session.query(models.Cluster).get(to_cluster)
cluster2.size += 1
index = cluster2.next_index
cluster2.next_index += 1
node.index = index
@ -449,7 +445,6 @@ def node_delete(context, node_id, force=False):
if node.cluster_id is not None:
cluster = session.query(models.Cluster).get(node.cluster_id)
cluster.size -= 1
cluster.save(session)
node.update_and_save({'deleted_time': timeutils.utcnow(),

View File

@ -53,7 +53,7 @@ def upgrade(migrate_engine):
sqlalchemy.Column('created_time', sqlalchemy.DateTime),
sqlalchemy.Column('updated_time', sqlalchemy.DateTime),
sqlalchemy.Column('deleted_time', sqlalchemy.DateTime),
sqlalchemy.Column('size', sqlalchemy.Integer),
sqlalchemy.Column('desired_capacity', sqlalchemy.Integer),
sqlalchemy.Column('next_index', sqlalchemy.Integer),
sqlalchemy.Column('timeout', sqlalchemy.Integer),
sqlalchemy.Column('status', sqlalchemy.String(255)),

View File

@ -103,7 +103,7 @@ class Cluster(BASE, SenlinBase, SoftDelete):
updated_time = sqlalchemy.Column(sqlalchemy.DateTime)
deleted_time = sqlalchemy.Column(sqlalchemy.DateTime)
size = sqlalchemy.Column(sqlalchemy.Integer)
desired_capacity = sqlalchemy.Column(sqlalchemy.Integer)
next_index = sqlalchemy.Column(sqlalchemy.Integer)
timeout = sqlalchemy.Column(sqlalchemy.Integer)

View File

@ -136,7 +136,8 @@ class ClusterAction(base.Action):
cluster.set_status(cluster.ERROR, reason)
return self.RES_ERROR, reason
result, reason = self._create_nodes(cluster, cluster.size, policy_data)
result, reason = self._create_nodes(cluster, cluster.desired_capacity,
policy_data)
if result == self.RES_OK:
reason = 'Cluster creation succeeded'
@ -180,7 +181,7 @@ class ClusterAction(base.Action):
# Wait for cluster updating complete
result = self.RES_OK
if cluster.size > 0:
if cluster.desired_capacity > 0:
result, reason = self._wait_for_dependents()
if result == self.RES_OK:

View File

@ -46,7 +46,8 @@ class Cluster(periodic_task.PeriodicTasks):
'DELETED', 'WARNING', 'UPDATING', 'UPDATE_CANCELLED',
)
def __init__(self, name, profile_id, size=0, context=None, **kwargs):
def __init__(self, name, profile_id, desired_capacity=0,
context=None, **kwargs):
'''Intialize a cluster object.
The cluster defaults to have 0 nodes with no profile assigned.
@ -67,9 +68,7 @@ class Cluster(periodic_task.PeriodicTasks):
self.updated_time = kwargs.get('updated_time', None)
self.deleted_time = kwargs.get('deleted_time', None)
# size is only the 'desired capacity', which many not be the real
# size of the cluster at a moment.
self.size = size
self.desired_capacity = desired_capacity
self.next_index = kwargs.get('next_index', 1)
self.timeout = kwargs.get('timeout', cfg.CONF.default_action_timeout)
@ -120,7 +119,7 @@ class Cluster(periodic_task.PeriodicTasks):
'created_time': self.created_time,
'updated_time': self.updated_time,
'deleted_time': self.deleted_time,
'size': self.size,
'desired_capacity': self.desired_capacity,
'next_index': self.next_index,
'timeout': self.timeout,
'status': self.status,
@ -166,7 +165,7 @@ class Cluster(periodic_task.PeriodicTasks):
'tags': record.tags,
}
return cls(record.name, record.profile_id, record.size,
return cls(record.name, record.profile_id, record.desired_capacity,
context=context, **kwargs)
@classmethod
@ -214,7 +213,7 @@ class Cluster(periodic_task.PeriodicTasks):
'created_time': _fmt_time(self.created_time),
'updated_time': _fmt_time(self.updated_time),
'deleted_time': _fmt_time(self.deleted_time),
'size': self.size,
'desired_capacity': self.desired_capacity,
'timeout': self.timeout,
'status': self.status,
'status_reason': self.status_reason,

View File

@ -414,11 +414,13 @@ class EngineService(service.Service):
return cluster.to_dict()
@request_context
def cluster_create(self, context, name, size, profile_id, parent=None,
tags=None, timeout=None):
def cluster_create(self, context, name, desired_capacity, profile_id,
parent=None, tags=None, timeout=None):
db_profile = self.profile_find(context, profile_id)
size = utils.parse_int_param(consts.CLUSTER_SIZE, size)
desired_capacity =\
utils.parse_int_param(consts.CLUSTER_DESIRED_CAPACITY,
desired_capacity)
if timeout is not None:
timeout = utils.parse_int_param(consts.CLUSTER_TIMEOUT, timeout)
@ -432,7 +434,8 @@ class EngineService(service.Service):
'tags': tags
}
cluster = cluster_mod.Cluster(name, db_profile.id, size, **kwargs)
cluster = cluster_mod.Cluster(name, db_profile.id,
desired_capacity, **kwargs)
cluster.store(context)
# Build an Action for cluster creation

View File

@ -35,7 +35,7 @@ msgid "No cluster name specified."
msgstr ""
#: senlin/api/openstack/v1/clusters.py:47
msgid "No cluster size provided."
msgid "No cluster desired capacity provided."
msgstr ""
#: senlin/api/openstack/v1/clusters.py:52
@ -50,8 +50,8 @@ msgstr ""
#: senlin/api/openstack/v1/clusters.py:160
#: senlin/tests/apiv1/test_clusters.py:597
msgid ""
"Updating cluster size is not supported, please use cluster scaling "
"operations instead."
"Updating cluster desired capacity is not supported, please use cluster "
"scaling operations instead."
msgstr ""
#: senlin/api/openstack/v1/clusters.py:185 senlin/api/openstack/v1/nodes.py:181

View File

@ -164,10 +164,11 @@ class EngineClient(object):
return self.call(ctxt,
self.make_msg('cluster_get', identity=identity))
def cluster_create(self, ctxt, name, size, profile_id, parent=None,
tags=None, timeout=0):
def cluster_create(self, ctxt, name, desired_capacity, profile_id,
parent=None, tags=None, timeout=0):
return self.call(ctxt, self.make_msg('cluster_create',
name=name, size=size,
name=name,
desired_capacity=desired_capacity,
profile_id=profile_id,
parent=parent,
tags=tags,

View File

@ -38,13 +38,13 @@ class ClusterDataTest(base.SenlinTestCase):
body = {'not the cluster name': 'wibble'}
data = clusters.ClusterData(body)
self.assertRaises(exc.HTTPBadRequest, data.name)
self.assertRaises(exc.HTTPBadRequest, data.size)
self.assertRaises(exc.HTTPBadRequest, data.desired_capacity)
self.assertRaises(exc.HTTPBadRequest, data.profile)
def test_cluster_size(self):
body = {'size': 0}
def test_cluster_desired_capacity(self):
body = {'desired_capacity': 0}
data = clusters.ClusterData(body)
self.assertEqual(0, data.size())
self.assertEqual(0, data.desired_capacity())
def test_cluster_timeout(self):
body = {'timeout': 33}
@ -86,7 +86,7 @@ class ClusterControllerTest(shared.ControllerTest, base.SenlinTestCase):
u'created_time': u'2015-01-09T09:16:45Z',
u'updated_time': None,
u'deleted_time': None,
u'size': 0,
u'desired_capacity': 0,
u'timeout': 60,
u'status': u'ACTIVE',
u'status_reason': u'Cluster successfully created.',
@ -263,7 +263,7 @@ class ClusterControllerTest(shared.ControllerTest, base.SenlinTestCase):
'cluster': {
'name': 'test_cluster',
'profile_id': 'xxxx-yyyy',
'size': 0,
'desired_capacity': 0,
'parent': None,
'tags': {},
'timeout': None,
@ -275,7 +275,7 @@ class ClusterControllerTest(shared.ControllerTest, base.SenlinTestCase):
engine_response = {
'name': 'test_cluster',
'profile_id': 'xxxx-yyyy',
'size': 0,
'desired_capacity': 0,
'parent': None,
'tags': {},
'timeout': 60,
@ -291,7 +291,7 @@ class ClusterControllerTest(shared.ControllerTest, base.SenlinTestCase):
('cluster_create', {
'name': 'test_cluster',
'profile_id': 'xxxx-yyyy',
'size': 0,
'desired_capacity': 0,
'parent': None,
'tags': {},
'timeout': None
@ -306,7 +306,7 @@ class ClusterControllerTest(shared.ControllerTest, base.SenlinTestCase):
body = {
'name': 'test_cluster',
'profile_id': 'xxxx-yyyy',
'size': 0,
'desired_capacity': 0,
'parent': None,
'tags': {},
'timeout': None,
@ -330,7 +330,7 @@ class ClusterControllerTest(shared.ControllerTest, base.SenlinTestCase):
'cluster': {
'name': 'test_cluster',
'profile_id': 'xxxx-yyyy',
'size': 0,
'desired_capacity': 0,
'parent': None,
'tags': {},
'timeout': None,
@ -352,7 +352,7 @@ class ClusterControllerTest(shared.ControllerTest, base.SenlinTestCase):
'cluster': {
'name': 'test_cluster',
'profile_id': 'xxxx-yyyy',
'size': -1,
'desired_capacity': -1,
'parent': None,
'tags': {},
'timeout': None,
@ -360,7 +360,7 @@ class ClusterControllerTest(shared.ControllerTest, base.SenlinTestCase):
}
req = self._post('/clusters', json.dumps(body))
error = senlin_exc.InvalidParameter(name='size', value=-1)
error = senlin_exc.InvalidParameter(name='desired_capacity', value=-1)
mock_call = self.patchobject(rpc_client.EngineClient, 'call',
side_effect=error)
@ -379,7 +379,7 @@ class ClusterControllerTest(shared.ControllerTest, base.SenlinTestCase):
'cluster': {
'name': 'test_cluster',
'profile_id': 'xxxx-yyyy',
'size': 0,
'desired_capacity': 0,
'parent': None,
'tags': {},
'timeout': None,
@ -415,7 +415,7 @@ class ClusterControllerTest(shared.ControllerTest, base.SenlinTestCase):
u'created_time': u'2015-01-09T09:16:45Z',
u'updated_time': None,
u'deleted_time': None,
u'size': 0,
u'desired_capacity': 0,
u'timeout': 60,
u'status': u'ACTIVE',
u'status_reason': u'Cluster successfully created.',
@ -578,11 +578,11 @@ class ClusterControllerTest(shared.ControllerTest, base.SenlinTestCase):
self.assertFalse(mock_call.called)
def test_cluster_update_reject_size(self, mock_enforce):
def test_cluster_update_reject_desired_capacity(self, mock_enforce):
self._mock_enforce_setup(mock_enforce, 'update', True)
cid = 'aaaa-bbbb-cccc'
body = {'cluster': {'size': 10}}
body = {'cluster': {'desired_capacity': 10}}
req = self._put('/clusters/%(cluster_id)s' % {'cluster_id': cid},
json.dumps(body))
@ -594,8 +594,9 @@ class ClusterControllerTest(shared.ControllerTest, base.SenlinTestCase):
cluster_id=cid,
body=body)
self.assertEqual(_("Updating cluster size is not supported, please "
"use cluster scaling operations instead."),
self.assertEqual(_("Updating cluster desired capacity is not "
"supported, please use cluster scaling "
"operations instead."),
six.text_type(ex))
self.assertFalse(mock_call.called)

View File

@ -67,7 +67,7 @@ def create_cluster(ctx, profile, **kwargs):
'parent': None,
'next_index': 1,
'timeout': 60,
'size': 0,
'desired_capacity': 0,
'init_time': datetime.datetime.utcnow(),
'status': 'INIT',
'status_reason': 'Just Initialized',

View File

@ -41,7 +41,7 @@ class DBAPIClusterTest(base.SenlinTestCase):
self.assertIsNone(cluster.parent)
self.assertEqual(1, cluster.next_index)
self.assertEqual(60, cluster.timeout)
self.assertEqual(0, cluster.size)
self.assertEqual(0, cluster.desired_capacity)
self.assertEqual('INIT', cluster.status)
self.assertEqual('Just Initialized', cluster.status_reason)
self.assertIsNone(cluster.created_time)

View File

@ -33,8 +33,8 @@ class DBAPINodeTest(base.SenlinTestCase):
self.cluster = shared.create_cluster(self.ctx, self.profile)
def test_node_create(self):
cluster = db_api.cluster_get(self.ctx, self.cluster.id)
self.assertEqual(0, cluster.size)
nodes = db_api.node_get_all_by_cluster(self.ctx, self.cluster.id)
self.assertEqual(0, len(nodes))
res = shared.create_node(self.ctx, self.cluster, self.profile)
node = db_api.node_get(self.ctx, res.id)
self.assertIsNotNone(node)
@ -52,8 +52,8 @@ class DBAPINodeTest(base.SenlinTestCase):
self.assertEqual(self.cluster.id, node.cluster_id)
self.assertEqual(self.profile.id, node.profile_id)
cluster = db_api.cluster_get(self.ctx, self.cluster.id)
self.assertEqual(1, cluster.size)
nodes = db_api.node_get_all_by_cluster(self.ctx, self.cluster.id)
self.assertEqual(1, len(nodes))
def test_node_status_reason_truncate(self):
node = shared.create_node(self.ctx, self.cluster, self.profile,
@ -68,6 +68,8 @@ class DBAPINodeTest(base.SenlinTestCase):
node = db_api.node_get(self.ctx, UUID2)
self.assertIsNone(node)
nodes = db_api.node_get_all_by_cluster(self.ctx, self.cluster.id)
self.assertEqual(1, len(nodes))
def test_node_get_show_deleted(self):
res = shared.create_node(self.ctx, self.cluster, self.profile)
@ -451,26 +453,28 @@ class DBAPINodeTest(base.SenlinTestCase):
self.assertEqual(timestamp, node.updated_time)
self.assertEqual(self.cluster.id, node.cluster_id)
self.assertEqual(2, cluster.next_index)
self.assertEqual(1, cluster.size)
nodes = db_api.node_get_all_by_cluster(self.ctx, self.cluster.id)
self.assertEqual(1, len(nodes))
def test_node_migrate_to_none(self):
node = shared.create_node(self.ctx, self.cluster, self.profile)
timestamp = datetime.datetime.utcnow()
node_new = db_api.node_migrate(self.ctx, node.id, None, timestamp)
cluster = db_api.cluster_get(self.ctx, self.cluster.id)
self.assertEqual(timestamp, node_new.updated_time)
self.assertIsNone(node_new.cluster_id)
self.assertEqual(0, cluster.size)
nodes = db_api.node_get_all_by_cluster(self.ctx, self.cluster.id)
self.assertEqual(0, len(nodes))
def test_node_migrate_between_clusters(self):
cluster1 = shared.create_cluster(self.ctx, self.profile)
cluster2 = shared.create_cluster(self.ctx, self.profile)
node = shared.create_node(self.ctx, cluster1, self.profile)
self.assertEqual(1, cluster1.size)
self.assertEqual(0, cluster2.size)
nodes = db_api.node_get_all_by_cluster(self.ctx, cluster1.id)
self.assertEqual(1, len(nodes))
nodes = db_api.node_get_all_by_cluster(self.ctx, cluster2.id)
self.assertEqual(0, len(nodes))
self.assertEqual(2, cluster1.next_index)
self.assertEqual(1, cluster2.next_index)
@ -482,8 +486,10 @@ class DBAPINodeTest(base.SenlinTestCase):
cluster2 = db_api.cluster_get(self.ctx, cluster2.id)
self.assertEqual(timestamp, node_new.updated_time)
self.assertEqual(cluster2.id, node_new.cluster_id)
self.assertEqual(0, cluster1.size)
self.assertEqual(1, cluster2.size)
nodes = db_api.node_get_all_by_cluster(self.ctx, cluster1.id)
self.assertEqual(0, len(nodes))
nodes = db_api.node_get_all_by_cluster(self.ctx, cluster2.id)
self.assertEqual(1, len(nodes))
self.assertEqual(2, cluster1.next_index)
self.assertEqual(2, cluster2.next_index)
@ -496,8 +502,10 @@ class DBAPINodeTest(base.SenlinTestCase):
cluster2 = db_api.cluster_get(self.ctx, cluster2.id)
self.assertEqual(timestamp, node_new.updated_time)
self.assertEqual(cluster1.id, node_new.cluster_id)
self.assertEqual(1, cluster1.size)
self.assertEqual(0, cluster2.size)
nodes = db_api.node_get_all_by_cluster(self.ctx, cluster1.id)
self.assertEqual(1, len(nodes))
nodes = db_api.node_get_all_by_cluster(self.ctx, cluster2.id)
self.assertEqual(0, len(nodes))
self.assertEqual(3, cluster1.next_index)
self.assertEqual(2, cluster2.next_index)
@ -505,15 +513,15 @@ class DBAPINodeTest(base.SenlinTestCase):
node = shared.create_node(self.ctx, self.cluster, self.profile)
node_id = node.id
cluster = db_api.cluster_get(self.ctx, self.cluster.id)
self.assertEqual(1, cluster.size)
nodes = db_api.node_get_all_by_cluster(self.ctx, self.cluster.id)
self.assertEqual(1, len(nodes))
db_api.node_delete(self.ctx, node_id)
res = db_api.node_get(self.ctx, node_id)
self.assertIsNone(res)
cluster = db_api.cluster_get(self.ctx, self.cluster.id)
self.assertEqual(0, cluster.size)
nodes = db_api.node_get_all_by_cluster(self.ctx, self.cluster.id)
self.assertEqual(0, len(nodes))
def test_node_delete_not_found(self):
node_id = 'BogusNodeID'

View File

@ -64,7 +64,7 @@ class ClusterTest(base.SenlinTestCase):
self.profile['id'])
self.assertIsNotNone(result)
self.assertEqual('c-1', result['name'])
self.assertEqual(0, result['size'])
self.assertEqual(0, result['desired_capacity'])
self.assertEqual(self.profile['id'], result['profile_id'])
self.assertEqual(self.ctx.user, result['user'])
self.assertEqual('cluster_test_project', result['project'])
@ -102,13 +102,13 @@ class ClusterTest(base.SenlinTestCase):
self.assertEqual(exception.InvalidParameter, ex.exc_info[0])
@mock.patch.object(dispatcher, 'notify')
def test_cluster_create_with_size(self, notify):
def test_cluster_create_with_desired_capacity(self, notify):
result = self.eng.cluster_create(self.ctx, 'c-1', 2,
self.profile['id'])
self.assertIsNotNone(result)
self.assertEqual('c-1', result['name'])
self.assertEqual(2, result['size'])
self.assertEqual(2, result['desired_capacity'])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_create,

View File

@ -206,7 +206,7 @@ class EngineRpcAPITestCase(base.SenlinTestCase):
def test_cluster_create(self):
kwargs = {
'name': 'mycluster',
'size': 0,
'desired_capacity': 0,
'profile_id': 'aaaa-bbbb-cccc',
'parent': None,
'tags': None,