Merge "Add support for instance datastore-flavors"
This commit is contained in:
commit
77fcb993ae
@ -13,6 +13,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import binascii
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import django
|
import django
|
||||||
@ -128,7 +129,7 @@ class DatabaseTests(test.TestCase):
|
|||||||
self.assertMessageCount(res, error=1)
|
self.assertMessageCount(res, error=1)
|
||||||
|
|
||||||
@test.create_stubs({
|
@test.create_stubs({
|
||||||
api.trove: ('flavor_list', 'backup_list',
|
api.trove: ('datastore_flavors', 'backup_list',
|
||||||
'datastore_list', 'datastore_version_list',
|
'datastore_list', 'datastore_version_list',
|
||||||
'instance_list'),
|
'instance_list'),
|
||||||
dash_api.cinder: ('volume_type_list',),
|
dash_api.cinder: ('volume_type_list',),
|
||||||
@ -137,8 +138,10 @@ class DatabaseTests(test.TestCase):
|
|||||||
})
|
})
|
||||||
def test_launch_instance(self):
|
def test_launch_instance(self):
|
||||||
policy.check((), IsA(http.HttpRequest)).MultipleTimes().AndReturn(True)
|
policy.check((), IsA(http.HttpRequest)).MultipleTimes().AndReturn(True)
|
||||||
api.trove.flavor_list(IsA(http.HttpRequest)).AndReturn(
|
api.trove.datastore_flavors(IsA(http.HttpRequest),
|
||||||
self.flavors.list())
|
IsA(six.string_types),
|
||||||
|
IsA(six.string_types)).\
|
||||||
|
MultipleTimes().AndReturn(self.flavors.list())
|
||||||
api.trove.backup_list(IsA(http.HttpRequest)).AndReturn(
|
api.trove.backup_list(IsA(http.HttpRequest)).AndReturn(
|
||||||
self.database_backups.list())
|
self.database_backups.list())
|
||||||
api.trove.instance_list(IsA(http.HttpRequest)).AndReturn(
|
api.trove.instance_list(IsA(http.HttpRequest)).AndReturn(
|
||||||
@ -197,7 +200,7 @@ class DatabaseTests(test.TestCase):
|
|||||||
log.setLevel(level)
|
log.setLevel(level)
|
||||||
|
|
||||||
@test.create_stubs({
|
@test.create_stubs({
|
||||||
api.trove: ('flavor_list', 'backup_list', 'instance_create',
|
api.trove: ('datastore_flavors', 'backup_list', 'instance_create',
|
||||||
'datastore_list', 'datastore_version_list',
|
'datastore_list', 'datastore_version_list',
|
||||||
'instance_list'),
|
'instance_list'),
|
||||||
dash_api.cinder: ('volume_type_list',),
|
dash_api.cinder: ('volume_type_list',),
|
||||||
@ -206,8 +209,10 @@ class DatabaseTests(test.TestCase):
|
|||||||
})
|
})
|
||||||
def test_create_simple_instance(self):
|
def test_create_simple_instance(self):
|
||||||
policy.check((), IsA(http.HttpRequest)).MultipleTimes().AndReturn(True)
|
policy.check((), IsA(http.HttpRequest)).MultipleTimes().AndReturn(True)
|
||||||
api.trove.flavor_list(IsA(http.HttpRequest)).AndReturn(
|
api.trove.datastore_flavors(IsA(http.HttpRequest),
|
||||||
self.flavors.list())
|
IsA(six.string_types),
|
||||||
|
IsA(six.string_types)).\
|
||||||
|
MultipleTimes().AndReturn(self.flavors.list())
|
||||||
|
|
||||||
api.trove.backup_list(IsA(http.HttpRequest)).AndReturn(
|
api.trove.backup_list(IsA(http.HttpRequest)).AndReturn(
|
||||||
self.database_backups.list())
|
self.database_backups.list())
|
||||||
@ -236,6 +241,10 @@ class DatabaseTests(test.TestCase):
|
|||||||
|
|
||||||
nics = [{"net-id": self.networks.first().id, "v4-fixed-ip": ''}]
|
nics = [{"net-id": self.networks.first().id, "v4-fixed-ip": ''}]
|
||||||
|
|
||||||
|
datastore = 'mysql'
|
||||||
|
datastore_version = '5.5'
|
||||||
|
field_name = self._build_flavor_widget_name(datastore,
|
||||||
|
datastore_version)
|
||||||
# Actual create database call
|
# Actual create database call
|
||||||
api.trove.instance_create(
|
api.trove.instance_create(
|
||||||
IsA(http.HttpRequest),
|
IsA(http.HttpRequest),
|
||||||
@ -243,8 +252,8 @@ class DatabaseTests(test.TestCase):
|
|||||||
IsA(int),
|
IsA(int),
|
||||||
IsA(six.text_type),
|
IsA(six.text_type),
|
||||||
databases=None,
|
databases=None,
|
||||||
datastore=IsA(six.text_type),
|
datastore=datastore,
|
||||||
datastore_version=IsA(six.text_type),
|
datastore_version=datastore_version,
|
||||||
restore_point=None,
|
restore_point=None,
|
||||||
replica_of=None,
|
replica_of=None,
|
||||||
users=None,
|
users=None,
|
||||||
@ -257,8 +266,9 @@ class DatabaseTests(test.TestCase):
|
|||||||
'name': "MyDB",
|
'name': "MyDB",
|
||||||
'volume': '1',
|
'volume': '1',
|
||||||
'flavor': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
'flavor': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
||||||
|
'datastore': field_name,
|
||||||
|
field_name: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
||||||
'network': self.networks.first().id,
|
'network': self.networks.first().id,
|
||||||
'datastore': 'mysql,5.5',
|
|
||||||
'volume_type': 'no_type'
|
'volume_type': 'no_type'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +276,7 @@ class DatabaseTests(test.TestCase):
|
|||||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||||
|
|
||||||
@test.create_stubs({
|
@test.create_stubs({
|
||||||
api.trove: ('flavor_list', 'backup_list', 'instance_create',
|
api.trove: ('datastore_flavors', 'backup_list', 'instance_create',
|
||||||
'datastore_list', 'datastore_version_list',
|
'datastore_list', 'datastore_version_list',
|
||||||
'instance_list'),
|
'instance_list'),
|
||||||
dash_api.cinder: ('volume_type_list',),
|
dash_api.cinder: ('volume_type_list',),
|
||||||
@ -276,8 +286,10 @@ class DatabaseTests(test.TestCase):
|
|||||||
def test_create_simple_instance_exception(self):
|
def test_create_simple_instance_exception(self):
|
||||||
policy.check((), IsA(http.HttpRequest)).MultipleTimes().AndReturn(True)
|
policy.check((), IsA(http.HttpRequest)).MultipleTimes().AndReturn(True)
|
||||||
trove_exception = self.exceptions.nova
|
trove_exception = self.exceptions.nova
|
||||||
api.trove.flavor_list(IsA(http.HttpRequest)).AndReturn(
|
api.trove.datastore_flavors(IsA(http.HttpRequest),
|
||||||
self.flavors.list())
|
IsA(six.string_types),
|
||||||
|
IsA(six.string_types)).\
|
||||||
|
MultipleTimes().AndReturn(self.flavors.list())
|
||||||
|
|
||||||
api.trove.backup_list(IsA(http.HttpRequest)).AndReturn(
|
api.trove.backup_list(IsA(http.HttpRequest)).AndReturn(
|
||||||
self.database_backups.list())
|
self.database_backups.list())
|
||||||
@ -306,6 +318,10 @@ class DatabaseTests(test.TestCase):
|
|||||||
|
|
||||||
nics = [{"net-id": self.networks.first().id, "v4-fixed-ip": ''}]
|
nics = [{"net-id": self.networks.first().id, "v4-fixed-ip": ''}]
|
||||||
|
|
||||||
|
datastore = 'mysql'
|
||||||
|
datastore_version = '5.5'
|
||||||
|
field_name = self._build_flavor_widget_name(datastore,
|
||||||
|
datastore_version)
|
||||||
# Actual create database call
|
# Actual create database call
|
||||||
api.trove.instance_create(
|
api.trove.instance_create(
|
||||||
IsA(http.HttpRequest),
|
IsA(http.HttpRequest),
|
||||||
@ -313,8 +329,8 @@ class DatabaseTests(test.TestCase):
|
|||||||
IsA(int),
|
IsA(int),
|
||||||
IsA(six.text_type),
|
IsA(six.text_type),
|
||||||
databases=None,
|
databases=None,
|
||||||
datastore=IsA(six.text_type),
|
datastore=datastore,
|
||||||
datastore_version=IsA(six.text_type),
|
datastore_version=datastore_version,
|
||||||
restore_point=None,
|
restore_point=None,
|
||||||
replica_of=None,
|
replica_of=None,
|
||||||
users=None,
|
users=None,
|
||||||
@ -327,8 +343,9 @@ class DatabaseTests(test.TestCase):
|
|||||||
'name': "MyDB",
|
'name': "MyDB",
|
||||||
'volume': '1',
|
'volume': '1',
|
||||||
'flavor': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
'flavor': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
||||||
|
'datastore': field_name,
|
||||||
|
field_name: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
||||||
'network': self.networks.first().id,
|
'network': self.networks.first().id,
|
||||||
'datastore': 'mysql,5.5',
|
|
||||||
'volume_type': 'no_type'
|
'volume_type': 'no_type'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -964,7 +981,7 @@ class DatabaseTests(test.TestCase):
|
|||||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||||
|
|
||||||
@test.create_stubs({
|
@test.create_stubs({
|
||||||
api.trove: ('flavor_list', 'backup_list', 'instance_create',
|
api.trove: ('datastore_flavors', 'backup_list', 'instance_create',
|
||||||
'datastore_list', 'datastore_version_list',
|
'datastore_list', 'datastore_version_list',
|
||||||
'instance_list_all', 'instance_get'),
|
'instance_list_all', 'instance_get'),
|
||||||
dash_api.cinder: ('volume_type_list',),
|
dash_api.cinder: ('volume_type_list',),
|
||||||
@ -973,8 +990,10 @@ class DatabaseTests(test.TestCase):
|
|||||||
})
|
})
|
||||||
def test_create_replica_instance(self):
|
def test_create_replica_instance(self):
|
||||||
policy.check((), IsA(http.HttpRequest)).MultipleTimes().AndReturn(True)
|
policy.check((), IsA(http.HttpRequest)).MultipleTimes().AndReturn(True)
|
||||||
api.trove.flavor_list(IsA(http.HttpRequest)).AndReturn(
|
api.trove.datastore_flavors(IsA(http.HttpRequest),
|
||||||
self.flavors.list())
|
IsA(six.string_types),
|
||||||
|
IsA(six.string_types)).\
|
||||||
|
MultipleTimes().AndReturn(self.flavors.list())
|
||||||
|
|
||||||
api.trove.backup_list(IsA(http.HttpRequest)).AndReturn(
|
api.trove.backup_list(IsA(http.HttpRequest)).AndReturn(
|
||||||
self.database_backups.list())
|
self.database_backups.list())
|
||||||
@ -1005,6 +1024,10 @@ class DatabaseTests(test.TestCase):
|
|||||||
api.trove.instance_get(IsA(http.HttpRequest), IsA(six.text_type))\
|
api.trove.instance_get(IsA(http.HttpRequest), IsA(six.text_type))\
|
||||||
.AndReturn(self.databases.first())
|
.AndReturn(self.databases.first())
|
||||||
|
|
||||||
|
datastore = 'mysql'
|
||||||
|
datastore_version = '5.5'
|
||||||
|
field_name = self._build_flavor_widget_name(datastore,
|
||||||
|
datastore_version)
|
||||||
# Actual create database call
|
# Actual create database call
|
||||||
api.trove.instance_create(
|
api.trove.instance_create(
|
||||||
IsA(http.HttpRequest),
|
IsA(http.HttpRequest),
|
||||||
@ -1012,8 +1035,8 @@ class DatabaseTests(test.TestCase):
|
|||||||
IsA(int),
|
IsA(int),
|
||||||
IsA(six.text_type),
|
IsA(six.text_type),
|
||||||
databases=None,
|
databases=None,
|
||||||
datastore=IsA(six.text_type),
|
datastore=datastore,
|
||||||
datastore_version=IsA(six.text_type),
|
datastore_version=datastore_version,
|
||||||
restore_point=None,
|
restore_point=None,
|
||||||
replica_of=self.databases.first().id,
|
replica_of=self.databases.first().id,
|
||||||
users=None,
|
users=None,
|
||||||
@ -1026,8 +1049,9 @@ class DatabaseTests(test.TestCase):
|
|||||||
'name': "MyDB",
|
'name': "MyDB",
|
||||||
'volume': '1',
|
'volume': '1',
|
||||||
'flavor': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
'flavor': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
||||||
|
'datastore': field_name,
|
||||||
|
field_name: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
||||||
'network': self.networks.first().id,
|
'network': self.networks.first().id,
|
||||||
'datastore': 'mysql,5.5',
|
|
||||||
'initial_state': 'master',
|
'initial_state': 'master',
|
||||||
'master': self.databases.first().id,
|
'master': self.databases.first().id,
|
||||||
'replica_count': 2,
|
'replica_count': 2,
|
||||||
@ -1159,3 +1183,10 @@ class DatabaseTests(test.TestCase):
|
|||||||
advanced_page = create_instance.AdvancedAction(request, None)
|
advanced_page = create_instance.AdvancedAction(request, None)
|
||||||
choices = advanced_page.populate_master_choices(request, None)
|
choices = advanced_page.populate_master_choices(request, None)
|
||||||
self.assertTrue(len(choices) == len(self.databases.list()) + 1)
|
self.assertTrue(len(choices) == len(self.databases.list()) + 1)
|
||||||
|
|
||||||
|
def _build_datastore_display_text(self, datastore, datastore_version):
|
||||||
|
return datastore + ' - ' + datastore_version
|
||||||
|
|
||||||
|
def _build_flavor_widget_name(self, datastore, datastore_version):
|
||||||
|
return binascii.hexlify(self._build_datastore_display_text(
|
||||||
|
datastore, datastore_version))
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import binascii
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -34,10 +35,15 @@ from trove_dashboard import api
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_datastore_and_version_text(datastore_and_version):
|
||||||
|
if datastore_and_version:
|
||||||
|
datastore, datastore_version = datastore_and_version.split('-', 1)
|
||||||
|
return datastore.strip(), datastore_version.strip()
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
class SetInstanceDetailsAction(workflows.Action):
|
class SetInstanceDetailsAction(workflows.Action):
|
||||||
name = forms.CharField(max_length=80, label=_("Instance Name"))
|
name = forms.CharField(max_length=80, label=_("Instance Name"))
|
||||||
flavor = forms.ChoiceField(label=_("Flavor"),
|
|
||||||
help_text=_("Size of image to launch."))
|
|
||||||
volume = forms.IntegerField(label=_("Volume Size"),
|
volume = forms.IntegerField(label=_("Volume Size"),
|
||||||
min_value=0,
|
min_value=0,
|
||||||
initial=1,
|
initial=1,
|
||||||
@ -46,24 +52,53 @@ class SetInstanceDetailsAction(workflows.Action):
|
|||||||
label=_("Volume Type"),
|
label=_("Volume Type"),
|
||||||
required=False,
|
required=False,
|
||||||
help_text=_("Applicable only if the volume size is specified."))
|
help_text=_("Applicable only if the volume size is specified."))
|
||||||
datastore = forms.ChoiceField(label=_("Datastore"),
|
datastore = forms.ChoiceField(
|
||||||
help_text=_(
|
label=_("Datastore"),
|
||||||
"Type and version of datastore."))
|
help_text=_("Type and version of datastore."),
|
||||||
|
widget=forms.Select(attrs={
|
||||||
|
'class': 'switchable',
|
||||||
|
'data-slug': 'datastore'
|
||||||
|
}))
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
name = _("Details")
|
name = _("Details")
|
||||||
help_text_template = "project/databases/_launch_details_help.html"
|
help_text_template = "project/databases/_launch_details_help.html"
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
if self.data.get("datastore", None) == "select_datastore_type_version":
|
datastore_and_version = self.data.get("datastore", None)
|
||||||
|
if not datastore_and_version:
|
||||||
msg = _("You must select a datastore type and version.")
|
msg = _("You must select a datastore type and version.")
|
||||||
self._errors["datastore"] = self.error_class([msg])
|
self._errors["datastore"] = self.error_class([msg])
|
||||||
|
else:
|
||||||
|
datastore, datastore_version = parse_datastore_and_version_text(
|
||||||
|
binascii.unhexlify(datastore_and_version))
|
||||||
|
field_name = self._build_flavor_field_name(datastore,
|
||||||
|
datastore_version)
|
||||||
|
flavor = self.data.get(field_name, None)
|
||||||
|
if not flavor:
|
||||||
|
msg = _("You must select a flavor.")
|
||||||
|
self._errors[field_name] = self.error_class([msg])
|
||||||
|
|
||||||
return self.cleaned_data
|
return self.cleaned_data
|
||||||
|
|
||||||
|
def handle(self, request, context):
|
||||||
|
datastore_and_version = context["datastore"]
|
||||||
|
if datastore_and_version:
|
||||||
|
datastore, datastore_version = parse_datastore_and_version_text(
|
||||||
|
binascii.unhexlify(context["datastore"]))
|
||||||
|
field_name = self._build_flavor_field_name(datastore,
|
||||||
|
datastore_version)
|
||||||
|
flavor = self.data[field_name]
|
||||||
|
if flavor:
|
||||||
|
context["flavor"] = flavor
|
||||||
|
return context
|
||||||
|
return None
|
||||||
|
|
||||||
@memoized.memoized_method
|
@memoized.memoized_method
|
||||||
def flavors(self, request):
|
def datastore_flavors(self, request, datastore_name, datastore_version):
|
||||||
try:
|
try:
|
||||||
return api.trove.flavor_list(request)
|
return api.trove.datastore_flavors(
|
||||||
|
request, datastore_name, datastore_version)
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.exception("Exception while obtaining flavors list")
|
LOG.exception("Exception while obtaining flavors list")
|
||||||
redirect = reverse("horizon:project:databases:index")
|
redirect = reverse("horizon:project:databases:index")
|
||||||
@ -71,12 +106,6 @@ class SetInstanceDetailsAction(workflows.Action):
|
|||||||
_('Unable to obtain flavors.'),
|
_('Unable to obtain flavors.'),
|
||||||
redirect=redirect)
|
redirect=redirect)
|
||||||
|
|
||||||
def populate_flavor_choices(self, request, context):
|
|
||||||
flavors = self.flavors(request)
|
|
||||||
if flavors:
|
|
||||||
return instance_utils.sort_flavor_list(request, flavors)
|
|
||||||
return []
|
|
||||||
|
|
||||||
@memoized.memoized_method
|
@memoized.memoized_method
|
||||||
def populate_volume_type_choices(self, request, context):
|
def populate_volume_type_choices(self, request, context):
|
||||||
try:
|
try:
|
||||||
@ -106,36 +135,66 @@ class SetInstanceDetailsAction(workflows.Action):
|
|||||||
|
|
||||||
def populate_datastore_choices(self, request, context):
|
def populate_datastore_choices(self, request, context):
|
||||||
choices = ()
|
choices = ()
|
||||||
set_initial = False
|
|
||||||
datastores = self.datastores(request)
|
datastores = self.datastores(request)
|
||||||
if datastores is not None:
|
if datastores is not None:
|
||||||
num_datastores_with_one_version = 0
|
|
||||||
for ds in datastores:
|
for ds in datastores:
|
||||||
versions = self.datastore_versions(request, ds.name)
|
versions = self.datastore_versions(request, ds.name)
|
||||||
if not set_initial:
|
|
||||||
if len(versions) >= 2:
|
|
||||||
set_initial = True
|
|
||||||
elif len(versions) == 1:
|
|
||||||
num_datastores_with_one_version += 1
|
|
||||||
if num_datastores_with_one_version > 1:
|
|
||||||
set_initial = True
|
|
||||||
if versions:
|
if versions:
|
||||||
# only add to choices if datastore has at least one version
|
# only add to choices if datastore has at least one version
|
||||||
version_choices = ()
|
version_choices = ()
|
||||||
for v in versions:
|
for v in versions:
|
||||||
if hasattr(v, 'active') and not v.active:
|
if hasattr(v, 'active') and not v.active:
|
||||||
continue
|
continue
|
||||||
|
selection_text = self._build_datastore_display_text(
|
||||||
|
ds.name, v.name)
|
||||||
|
widget_text = self._build_widget_field_name(
|
||||||
|
ds.name, v.name)
|
||||||
version_choices = (version_choices +
|
version_choices = (version_choices +
|
||||||
((ds.name + ',' + v.name, v.name),))
|
((widget_text, selection_text),))
|
||||||
datastore_choices = (ds.name, version_choices)
|
self._add_datastore_flavor_field(request,
|
||||||
choices = choices + (datastore_choices,)
|
ds.name,
|
||||||
if set_initial:
|
v.name)
|
||||||
# prepend choice to force user to choose
|
choices = choices + version_choices
|
||||||
initial = (('select_datastore_type_version',
|
|
||||||
_('Select datastore type and version')))
|
|
||||||
choices = (initial,) + choices
|
|
||||||
return choices
|
return choices
|
||||||
|
|
||||||
|
def _add_datastore_flavor_field(self,
|
||||||
|
request,
|
||||||
|
datastore,
|
||||||
|
datastore_version):
|
||||||
|
name = self._build_widget_field_name(datastore, datastore_version)
|
||||||
|
attr_key = 'data-datastore-' + name
|
||||||
|
field_name = self._build_flavor_field_name(datastore,
|
||||||
|
datastore_version)
|
||||||
|
self.fields[field_name] = forms.ChoiceField(
|
||||||
|
label=_("Flavor"),
|
||||||
|
help_text=_("Size of image to launch."),
|
||||||
|
required=False,
|
||||||
|
widget=forms.Select(attrs={
|
||||||
|
'class': 'switched',
|
||||||
|
'data-switch-on': 'datastore',
|
||||||
|
attr_key: _("Flavor")
|
||||||
|
}))
|
||||||
|
valid_flavors = self.datastore_flavors(request,
|
||||||
|
datastore,
|
||||||
|
datastore_version)
|
||||||
|
if valid_flavors:
|
||||||
|
self.fields[field_name].choices = instance_utils.sort_flavor_list(
|
||||||
|
request, valid_flavors)
|
||||||
|
|
||||||
|
def _build_datastore_display_text(self, datastore, datastore_version):
|
||||||
|
return datastore + ' - ' + datastore_version
|
||||||
|
|
||||||
|
def _build_widget_field_name(self, datastore, datastore_version):
|
||||||
|
# Since the fieldnames cannot contain an uppercase character
|
||||||
|
# we generate a hex encoded string representation of the
|
||||||
|
# datastore and version as the fieldname
|
||||||
|
return binascii.hexlify(
|
||||||
|
self._build_datastore_display_text(datastore, datastore_version))
|
||||||
|
|
||||||
|
def _build_flavor_field_name(self, datastore, datastore_version):
|
||||||
|
return self._build_widget_field_name(datastore,
|
||||||
|
datastore_version)
|
||||||
|
|
||||||
|
|
||||||
TROVE_ADD_USER_PERMS = getattr(settings, 'TROVE_ADD_USER_PERMS', [])
|
TROVE_ADD_USER_PERMS = getattr(settings, 'TROVE_ADD_USER_PERMS', [])
|
||||||
TROVE_ADD_DATABASE_PERMS = getattr(settings, 'TROVE_ADD_DATABASE_PERMS', [])
|
TROVE_ADD_DATABASE_PERMS = getattr(settings, 'TROVE_ADD_DATABASE_PERMS', [])
|
||||||
@ -387,8 +446,8 @@ class LaunchInstance(workflows.Workflow):
|
|||||||
|
|
||||||
def handle(self, request, context):
|
def handle(self, request, context):
|
||||||
try:
|
try:
|
||||||
datastore = self.context['datastore'].split(',')[0]
|
datastore, datastore_version = parse_datastore_and_version_text(
|
||||||
datastore_version = self.context['datastore'].split(',')[1]
|
binascii.unhexlify(self.context['datastore']))
|
||||||
LOG.info("Launching database instance with parameters "
|
LOG.info("Launching database instance with parameters "
|
||||||
"{name=%s, volume=%s, volume_type=%s, flavor=%s, "
|
"{name=%s, volume=%s, volume_type=%s, flavor=%s, "
|
||||||
"datastore=%s, datastore_version=%s, "
|
"datastore=%s, datastore_version=%s, "
|
||||||
|
Loading…
Reference in New Issue
Block a user