Add volume type field to launch instance dialog
With the addition of Cinder volume type support in the CLI the corresponding change is needed in Horizon. In the launch instance dialog added the volume type field pulldown. It will be populated by a call to cinder volume_type_list. The default value will be prepended to the list as "no_type". This default is used in the cinder panels. Updated api and tests to account for new cinder calls and add the default value to the post commands in the tests. Change-Id: I7fb2404ccf9d42c293bde1a708518e108f9a1625 Closes-Bug: #1551340
This commit is contained in:
parent
731e005b6b
commit
4a85ec5c2a
@ -121,11 +121,13 @@ def instance_delete(request, instance_id):
|
||||
def instance_create(request, name, volume, flavor, databases=None,
|
||||
users=None, restore_point=None, nics=None,
|
||||
datastore=None, datastore_version=None,
|
||||
replica_of=None):
|
||||
replica_of=None, volume_type=None):
|
||||
# TODO(dklyle): adding conditional to support trove without volume
|
||||
# support for now until API supports checking for volume support
|
||||
if volume > 0:
|
||||
volume_params = {'size': volume}
|
||||
if volume_type:
|
||||
volume_params['type'] = volume_type
|
||||
else:
|
||||
volume_params = None
|
||||
return troveclient(request).instances.create(
|
||||
|
@ -129,6 +129,7 @@ class DatabaseTests(test.TestCase):
|
||||
api.trove: ('flavor_list', 'backup_list',
|
||||
'datastore_list', 'datastore_version_list',
|
||||
'instance_list'),
|
||||
dash_api.cinder: ('volume_type_list',),
|
||||
dash_api.neutron: ('network_list',)})
|
||||
def test_launch_instance(self):
|
||||
api.trove.flavor_list(IsA(http.HttpRequest)).AndReturn(
|
||||
@ -144,6 +145,8 @@ class DatabaseTests(test.TestCase):
|
||||
api.trove.datastore_version_list(IsA(http.HttpRequest), IsA(str)).\
|
||||
MultipleTimes().AndReturn(self.datastore_versions.list())
|
||||
|
||||
dash_api.cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn([])
|
||||
|
||||
dash_api.neutron.network_list(IsA(http.HttpRequest),
|
||||
tenant_id=self.tenant.id,
|
||||
shared=False).AndReturn(
|
||||
@ -192,6 +195,7 @@ class DatabaseTests(test.TestCase):
|
||||
api.trove: ('flavor_list', 'backup_list', 'instance_create',
|
||||
'datastore_list', 'datastore_version_list',
|
||||
'instance_list'),
|
||||
dash_api.cinder: ('volume_type_list',),
|
||||
dash_api.neutron: ('network_list',)})
|
||||
def test_create_simple_instance(self):
|
||||
api.trove.flavor_list(IsA(http.HttpRequest)).AndReturn(
|
||||
@ -211,6 +215,8 @@ class DatabaseTests(test.TestCase):
|
||||
api.trove.datastore_version_list(IsA(http.HttpRequest), IsA(str))\
|
||||
.MultipleTimes().AndReturn(self.datastore_versions.list())
|
||||
|
||||
dash_api.cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn([])
|
||||
|
||||
dash_api.neutron.network_list(IsA(http.HttpRequest),
|
||||
tenant_id=self.tenant.id,
|
||||
shared=False).AndReturn(
|
||||
@ -234,7 +240,8 @@ class DatabaseTests(test.TestCase):
|
||||
restore_point=None,
|
||||
replica_of=None,
|
||||
users=None,
|
||||
nics=nics).AndReturn(self.databases.first())
|
||||
nics=nics,
|
||||
volume_type=None).AndReturn(self.databases.first())
|
||||
|
||||
self.mox.ReplayAll()
|
||||
post = {
|
||||
@ -243,6 +250,7 @@ class DatabaseTests(test.TestCase):
|
||||
'flavor': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
||||
'network': self.networks.first().id,
|
||||
'datastore': 'mysql,5.5',
|
||||
'volume_type': 'no_type'
|
||||
}
|
||||
|
||||
res = self.client.post(LAUNCH_URL, post)
|
||||
@ -252,6 +260,7 @@ class DatabaseTests(test.TestCase):
|
||||
api.trove: ('flavor_list', 'backup_list', 'instance_create',
|
||||
'datastore_list', 'datastore_version_list',
|
||||
'instance_list'),
|
||||
dash_api.cinder: ('volume_type_list',),
|
||||
dash_api.neutron: ('network_list',)})
|
||||
def test_create_simple_instance_exception(self):
|
||||
trove_exception = self.exceptions.nova
|
||||
@ -272,6 +281,8 @@ class DatabaseTests(test.TestCase):
|
||||
api.trove.datastore_version_list(IsA(http.HttpRequest), IsA(str))\
|
||||
.MultipleTimes().AndReturn(self.datastore_versions.list())
|
||||
|
||||
dash_api.cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn([])
|
||||
|
||||
dash_api.neutron.network_list(IsA(http.HttpRequest),
|
||||
tenant_id=self.tenant.id,
|
||||
shared=False).AndReturn(
|
||||
@ -295,7 +306,8 @@ class DatabaseTests(test.TestCase):
|
||||
restore_point=None,
|
||||
replica_of=None,
|
||||
users=None,
|
||||
nics=nics).AndRaise(trove_exception)
|
||||
nics=nics,
|
||||
volume_type=None).AndRaise(trove_exception)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
post = {
|
||||
@ -304,6 +316,7 @@ class DatabaseTests(test.TestCase):
|
||||
'flavor': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
||||
'network': self.networks.first().id,
|
||||
'datastore': 'mysql,5.5',
|
||||
'volume_type': 'no_type'
|
||||
}
|
||||
|
||||
res = self.client.post(LAUNCH_URL, post)
|
||||
@ -939,6 +952,7 @@ class DatabaseTests(test.TestCase):
|
||||
api.trove: ('flavor_list', 'backup_list', 'instance_create',
|
||||
'datastore_list', 'datastore_version_list',
|
||||
'instance_list', 'instance_get'),
|
||||
dash_api.cinder: ('volume_type_list',),
|
||||
dash_api.neutron: ('network_list',)})
|
||||
def test_create_replica_instance(self):
|
||||
api.trove.flavor_list(IsA(http.HttpRequest)).AndReturn(
|
||||
@ -957,6 +971,8 @@ class DatabaseTests(test.TestCase):
|
||||
IsA(str))\
|
||||
.MultipleTimes().AndReturn(self.datastore_versions.list())
|
||||
|
||||
dash_api.cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn([])
|
||||
|
||||
dash_api.neutron.network_list(IsA(http.HttpRequest),
|
||||
tenant_id=self.tenant.id,
|
||||
shared=False).\
|
||||
@ -983,7 +999,8 @@ class DatabaseTests(test.TestCase):
|
||||
restore_point=None,
|
||||
replica_of=self.databases.first().id,
|
||||
users=None,
|
||||
nics=nics).AndReturn(self.databases.first())
|
||||
nics=nics,
|
||||
volume_type=None).AndReturn(self.databases.first())
|
||||
|
||||
self.mox.ReplayAll()
|
||||
post = {
|
||||
@ -993,7 +1010,8 @@ class DatabaseTests(test.TestCase):
|
||||
'network': self.networks.first().id,
|
||||
'datastore': 'mysql,5.5',
|
||||
'initial_state': 'master',
|
||||
'master': self.databases.first().id
|
||||
'master': self.databases.first().id,
|
||||
'volume_type': 'no_type'
|
||||
}
|
||||
|
||||
res = self.client.post(LAUNCH_URL, post)
|
||||
|
@ -39,6 +39,10 @@ class SetInstanceDetailsAction(workflows.Action):
|
||||
min_value=0,
|
||||
initial=1,
|
||||
help_text=_("Size of the volume in GB."))
|
||||
volume_type = forms.ChoiceField(
|
||||
label=_("Volume Type"),
|
||||
required=False,
|
||||
help_text=_("Applicable only if the volume size is specified."))
|
||||
datastore = forms.ChoiceField(label=_("Datastore"),
|
||||
help_text=_(
|
||||
"Type and version of datastore."))
|
||||
@ -70,6 +74,17 @@ class SetInstanceDetailsAction(workflows.Action):
|
||||
return instance_utils.sort_flavor_list(request, flavors)
|
||||
return []
|
||||
|
||||
@memoized.memoized_method
|
||||
def populate_volume_type_choices(self, request, context):
|
||||
try:
|
||||
volume_types = dash_api.cinder.volume_type_list(request)
|
||||
return ([("no_type", _("No volume type"))] +
|
||||
[(type.name, type.name)
|
||||
for type in volume_types])
|
||||
except Exception:
|
||||
LOG.exception("Exception while obtaining volume types list")
|
||||
self._volume_types = []
|
||||
|
||||
@memoized.memoized_method
|
||||
def datastores(self, request):
|
||||
try:
|
||||
@ -124,7 +139,7 @@ TROVE_ADD_PERMS = TROVE_ADD_USER_PERMS + TROVE_ADD_DATABASE_PERMS
|
||||
|
||||
class SetInstanceDetails(workflows.Step):
|
||||
action_class = SetInstanceDetailsAction
|
||||
contributes = ("name", "volume", "flavor", "datastore")
|
||||
contributes = ("name", "volume", "volume_type", "flavor", "datastore")
|
||||
|
||||
|
||||
class SetNetworkAction(workflows.Action):
|
||||
@ -388,16 +403,23 @@ class LaunchInstance(workflows.Workflow):
|
||||
else:
|
||||
return None
|
||||
|
||||
def _get_volume_type(self, context):
|
||||
volume_type = None
|
||||
if context.get('volume_type') != 'no_type':
|
||||
volume_type = context['volume_type']
|
||||
return volume_type
|
||||
|
||||
def handle(self, request, context):
|
||||
try:
|
||||
datastore = self.context['datastore'].split(',')[0]
|
||||
datastore_version = self.context['datastore'].split(',')[1]
|
||||
LOG.info("Launching database instance with parameters "
|
||||
"{name=%s, volume=%s, flavor=%s, "
|
||||
"{name=%s, volume=%s, volume_type=%s, flavor=%s, "
|
||||
"datastore=%s, datastore_version=%s, "
|
||||
"dbs=%s, users=%s, "
|
||||
"backups=%s, nics=%s, replica_of=%s}",
|
||||
context['name'], context['volume'], context['flavor'],
|
||||
context['name'], context['volume'],
|
||||
self._get_volume_type(context), context['flavor'],
|
||||
datastore, datastore_version,
|
||||
self._get_databases(context), self._get_users(context),
|
||||
self._get_backup(context), self._get_nics(context),
|
||||
@ -412,7 +434,9 @@ class LaunchInstance(workflows.Workflow):
|
||||
users=self._get_users(context),
|
||||
restore_point=self._get_backup(context),
|
||||
nics=self._get_nics(context),
|
||||
replica_of=context.get('master'))
|
||||
replica_of=context.get('master'),
|
||||
volume_type=self._get_volume_type(
|
||||
context))
|
||||
return True
|
||||
except Exception:
|
||||
exceptions.handle(request)
|
||||
|
Loading…
x
Reference in New Issue
Block a user