Replace "Terminate Instance" with "Delete Instance"
"Delete" is being used almost everywhere in OpenStack Dashboard except the instance panel. Using "Delete" looks more consistent. In addition, "Delete" tells non-native English speakers that deleted instances will be no longer usable again compared to "Terminate". DocImpact Closes-Bug: #1502773 Change-Id: Idccaf3c45566f20f11d02ada64c1d3934a6f3002
This commit is contained in:
parent
2432283fbc
commit
5fc26b0a11
@ -182,13 +182,13 @@ horizon.addInitFunction(horizon.instances.init = function () {
|
|||||||
elements_list = "#id_instance_snapshot_id";
|
elements_list = "#id_instance_snapshot_id";
|
||||||
break;
|
break;
|
||||||
case "volume_id":
|
case "volume_id":
|
||||||
elements_list = "#id_volume_id, #id_device_name, #id_delete_on_terminate";
|
elements_list = "#id_volume_id, #id_device_name, #id_vol_delete_on_instance_delete";
|
||||||
break;
|
break;
|
||||||
case "volume_image_id":
|
case "volume_image_id":
|
||||||
elements_list = "#id_image_id, #id_volume_size, #id_device_name, #id_delete_on_terminate";
|
elements_list = "#id_image_id, #id_volume_size, #id_device_name, #id_vol_delete_on_instance_delete";
|
||||||
break;
|
break;
|
||||||
case "volume_snapshot_id":
|
case "volume_snapshot_id":
|
||||||
elements_list = "#id_volume_snapshot_id, #id_device_name, #id_delete_on_terminate";
|
elements_list = "#id_volume_snapshot_id, #id_device_name, #id_vol_delete_on_instance_delete";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var elements_list_group = $(elements_list).closest(".form-group");
|
var elements_list_group = $(elements_list).closest(".form-group");
|
||||||
|
@ -986,7 +986,7 @@ horizon.network_topology = {
|
|||||||
table2:portTmpl
|
table2:portTmpl
|
||||||
});
|
});
|
||||||
} else if (d instanceof Server) {
|
} else if (d instanceof Server) {
|
||||||
htmlData.delete_label = gettext('Terminate Instance');
|
htmlData.delete_label = gettext('Delete Instance');
|
||||||
htmlData.view_details_label = gettext('View Instance Details');
|
htmlData.view_details_label = gettext('View Instance Details');
|
||||||
htmlData.console_id = d.id;
|
htmlData.console_id = d.id;
|
||||||
htmlData.ips = d.ip_addresses;
|
htmlData.ips = d.ip_addresses;
|
||||||
|
@ -29,25 +29,25 @@ from openstack_dashboard.contrib.trove.content.databases import db_capability
|
|||||||
ACTIVE_STATES = ("ACTIVE",)
|
ACTIVE_STATES = ("ACTIVE",)
|
||||||
|
|
||||||
|
|
||||||
class TerminateCluster(tables.BatchAction):
|
class DeleteCluster(tables.BatchAction):
|
||||||
name = "terminate"
|
name = "delete"
|
||||||
icon = "remove"
|
icon = "remove"
|
||||||
classes = ('btn-danger',)
|
classes = ('btn-danger',)
|
||||||
help_text = _("Terminated cluster is not recoverable.")
|
help_text = _("Deleted cluster is not recoverable.")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def action_present(count):
|
def action_present(count):
|
||||||
return ungettext_lazy(
|
return ungettext_lazy(
|
||||||
u"Terminate Cluster",
|
u"Delete Cluster",
|
||||||
u"Terminate Clusters",
|
u"Delete Clusters",
|
||||||
count
|
count
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def action_past(count):
|
def action_past(count):
|
||||||
return ungettext_lazy(
|
return ungettext_lazy(
|
||||||
u"Scheduled termination of Cluster",
|
u"Scheduled deletion of Cluster",
|
||||||
u"Scheduled termination of Clusters",
|
u"Scheduled deletion of Clusters",
|
||||||
count
|
count
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -159,8 +159,8 @@ class ClustersTable(tables.DataTable):
|
|||||||
verbose_name = _("Clusters")
|
verbose_name = _("Clusters")
|
||||||
status_columns = ["task"]
|
status_columns = ["task"]
|
||||||
row_class = UpdateRow
|
row_class = UpdateRow
|
||||||
table_actions = (LaunchLink, TerminateCluster)
|
table_actions = (LaunchLink, DeleteCluster)
|
||||||
row_actions = (AddShard, ResetPassword, TerminateCluster)
|
row_actions = (AddShard, ResetPassword, DeleteCluster)
|
||||||
|
|
||||||
|
|
||||||
def get_instance_size(instance):
|
def get_instance_size(instance):
|
||||||
|
@ -31,26 +31,26 @@ from openstack_dashboard.contrib.trove.content.database_backups \
|
|||||||
ACTIVE_STATES = ("ACTIVE",)
|
ACTIVE_STATES = ("ACTIVE",)
|
||||||
|
|
||||||
|
|
||||||
class TerminateInstance(tables.BatchAction):
|
class DeleteInstance(tables.BatchAction):
|
||||||
help_text = _("Terminated instances are not recoverable.")
|
help_text = _("Deleted instances are not recoverable.")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def action_present(count):
|
def action_present(count):
|
||||||
return ungettext_lazy(
|
return ungettext_lazy(
|
||||||
u"Terminate Instance",
|
u"Delete Instance",
|
||||||
u"Terminate Instances",
|
u"Delete Instances",
|
||||||
count
|
count
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def action_past(count):
|
def action_past(count):
|
||||||
return ungettext_lazy(
|
return ungettext_lazy(
|
||||||
u"Scheduled termination of Instance",
|
u"Scheduled deletion of Instance",
|
||||||
u"Scheduled termination of Instances",
|
u"Scheduled deletion of Instances",
|
||||||
count
|
count
|
||||||
)
|
)
|
||||||
|
|
||||||
name = "terminate"
|
name = "delete"
|
||||||
classes = ("btn-danger", )
|
classes = ("btn-danger", )
|
||||||
icon = "remove"
|
icon = "remove"
|
||||||
|
|
||||||
@ -340,13 +340,13 @@ class InstancesTable(tables.DataTable):
|
|||||||
verbose_name = _("Instances")
|
verbose_name = _("Instances")
|
||||||
status_columns = ["status"]
|
status_columns = ["status"]
|
||||||
row_class = UpdateRow
|
row_class = UpdateRow
|
||||||
table_actions = (LaunchLink, TerminateInstance)
|
table_actions = (LaunchLink, DeleteInstance)
|
||||||
row_actions = (CreateBackup,
|
row_actions = (CreateBackup,
|
||||||
ResizeVolume,
|
ResizeVolume,
|
||||||
ResizeInstance,
|
ResizeInstance,
|
||||||
RestartInstance,
|
RestartInstance,
|
||||||
DetachReplica,
|
DetachReplica,
|
||||||
TerminateInstance)
|
DeleteInstance)
|
||||||
|
|
||||||
|
|
||||||
class UsersTable(tables.DataTable):
|
class UsersTable(tables.DataTable):
|
||||||
|
@ -171,7 +171,7 @@ class AdminInstancesTable(tables.DataTable):
|
|||||||
name = "instances"
|
name = "instances"
|
||||||
verbose_name = _("Instances")
|
verbose_name = _("Instances")
|
||||||
status_columns = ["status", "task"]
|
status_columns = ["status", "task"]
|
||||||
table_actions = (project_tables.TerminateInstance,
|
table_actions = (project_tables.DeleteInstance,
|
||||||
AdminInstanceFilterAction)
|
AdminInstanceFilterAction)
|
||||||
row_class = AdminUpdateRow
|
row_class = AdminUpdateRow
|
||||||
row_actions = (project_tables.ConfirmResize,
|
row_actions = (project_tables.ConfirmResize,
|
||||||
@ -187,4 +187,4 @@ class AdminInstancesTable(tables.DataTable):
|
|||||||
LiveMigrateInstance,
|
LiveMigrateInstance,
|
||||||
project_tables.SoftRebootInstance,
|
project_tables.SoftRebootInstance,
|
||||||
project_tables.RebootInstance,
|
project_tables.RebootInstance,
|
||||||
project_tables.TerminateInstance)
|
project_tables.DeleteInstance)
|
||||||
|
@ -81,31 +81,31 @@ def is_deleting(instance):
|
|||||||
return task_state.lower() == "deleting"
|
return task_state.lower() == "deleting"
|
||||||
|
|
||||||
|
|
||||||
class TerminateInstance(policy.PolicyTargetMixin, tables.BatchAction):
|
class DeleteInstance(policy.PolicyTargetMixin, tables.BatchAction):
|
||||||
name = "terminate"
|
name = "delete"
|
||||||
classes = ("btn-danger",)
|
classes = ("btn-danger",)
|
||||||
icon = "remove"
|
icon = "remove"
|
||||||
policy_rules = (("compute", "compute:delete"),)
|
policy_rules = (("compute", "compute:delete"),)
|
||||||
help_text = _("Terminated instances are not recoverable.")
|
help_text = _("Deleted instances are not recoverable.")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def action_present(count):
|
def action_present(count):
|
||||||
return ungettext_lazy(
|
return ungettext_lazy(
|
||||||
u"Terminate Instance",
|
u"Delete Instance",
|
||||||
u"Terminate Instances",
|
u"Delete Instances",
|
||||||
count
|
count
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def action_past(count):
|
def action_past(count):
|
||||||
return ungettext_lazy(
|
return ungettext_lazy(
|
||||||
u"Scheduled termination of Instance",
|
u"Scheduled deletion of Instance",
|
||||||
u"Scheduled termination of Instances",
|
u"Scheduled deletion of Instances",
|
||||||
count
|
count
|
||||||
)
|
)
|
||||||
|
|
||||||
def allowed(self, request, instance=None):
|
def allowed(self, request, instance=None):
|
||||||
"""Allow terminate action if instance not currently being deleted."""
|
"""Allow delete action if instance not currently being deleted."""
|
||||||
return not is_deleting(instance)
|
return not is_deleting(instance)
|
||||||
|
|
||||||
def action(self, request, obj_id):
|
def action(self, request, obj_id):
|
||||||
@ -1174,7 +1174,7 @@ class InstancesTable(tables.DataTable):
|
|||||||
launch_actions = (LaunchLink,) + launch_actions
|
launch_actions = (LaunchLink,) + launch_actions
|
||||||
if getattr(settings, 'LAUNCH_INSTANCE_NG_ENABLED', False):
|
if getattr(settings, 'LAUNCH_INSTANCE_NG_ENABLED', False):
|
||||||
launch_actions = (LaunchLinkNG,) + launch_actions
|
launch_actions = (LaunchLinkNG,) + launch_actions
|
||||||
table_actions = launch_actions + (TerminateInstance,
|
table_actions = launch_actions + (DeleteInstance,
|
||||||
InstancesFilterAction)
|
InstancesFilterAction)
|
||||||
row_actions = (StartInstance, ConfirmResize, RevertResize,
|
row_actions = (StartInstance, ConfirmResize, RevertResize,
|
||||||
CreateSnapshot, SimpleAssociateIP, AssociateIP,
|
CreateSnapshot, SimpleAssociateIP, AssociateIP,
|
||||||
@ -1184,4 +1184,4 @@ class InstancesTable(tables.DataTable):
|
|||||||
ConsoleLink, LogLink, TogglePause, ToggleSuspend,
|
ConsoleLink, LogLink, TogglePause, ToggleSuspend,
|
||||||
ToggleShelve, ResizeLink, LockInstance, UnlockInstance,
|
ToggleShelve, ResizeLink, LockInstance, UnlockInstance,
|
||||||
SoftRebootInstance, RebootInstance,
|
SoftRebootInstance, RebootInstance,
|
||||||
StopInstance, RebuildInstance, TerminateInstance)
|
StopInstance, RebuildInstance, DeleteInstance)
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<script type="text/javascript" charset="utf-8">
|
<script type="text/javascript" charset="utf-8">
|
||||||
$(function () {
|
$(function () {
|
||||||
var $flavor = $("#flavor_details_{{ id }}");
|
var $flavor = $("#flavor_details_{{ id }}");
|
||||||
// NOTE(tsufiev): check this in case this template is used in network topology -> terminate instance
|
// NOTE(tsufiev): check this in case this template is used in network topology -> delete instance
|
||||||
if ( $flavor.popover ) {
|
if ( $flavor.popover ) {
|
||||||
$flavor.popover({html:true});
|
$flavor.popover({html:true});
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ class InstanceTests(helpers.TestCase):
|
|||||||
'server_delete',),
|
'server_delete',),
|
||||||
api.glance: ('image_list_detailed',),
|
api.glance: ('image_list_detailed',),
|
||||||
api.network: ('servers_update_addresses',)})
|
api.network: ('servers_update_addresses',)})
|
||||||
def test_terminate_instance(self):
|
def test_delete_instance(self):
|
||||||
servers = self.servers.list()
|
servers = self.servers.list()
|
||||||
server = servers[0]
|
server = servers[0]
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ class InstanceTests(helpers.TestCase):
|
|||||||
api.nova.server_delete(IsA(http.HttpRequest), server.id)
|
api.nova.server_delete(IsA(http.HttpRequest), server.id)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
formData = {'action': 'instances__terminate__%s' % server.id}
|
formData = {'action': 'instances__delete__%s' % server.id}
|
||||||
res = self.client.post(INDEX_URL, formData)
|
res = self.client.post(INDEX_URL, formData)
|
||||||
|
|
||||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||||
@ -266,7 +266,7 @@ class InstanceTests(helpers.TestCase):
|
|||||||
'server_delete',),
|
'server_delete',),
|
||||||
api.glance: ('image_list_detailed',),
|
api.glance: ('image_list_detailed',),
|
||||||
api.network: ('servers_update_addresses',)})
|
api.network: ('servers_update_addresses',)})
|
||||||
def test_terminate_instance_exception(self):
|
def test_delete_instance_exception(self):
|
||||||
servers = self.servers.list()
|
servers = self.servers.list()
|
||||||
server = servers[0]
|
server = servers[0]
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ class InstanceTests(helpers.TestCase):
|
|||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
formData = {'action': 'instances__terminate__%s' % server.id}
|
formData = {'action': 'instances__delete__%s' % server.id}
|
||||||
res = self.client.post(INDEX_URL, formData)
|
res = self.client.post(INDEX_URL, formData)
|
||||||
|
|
||||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||||
@ -4384,7 +4384,7 @@ class InstanceTests(helpers.TestCase):
|
|||||||
'server_delete',),
|
'server_delete',),
|
||||||
api.glance: ('image_list_detailed',),
|
api.glance: ('image_list_detailed',),
|
||||||
api.network: ('servers_update_addresses',)})
|
api.network: ('servers_update_addresses',)})
|
||||||
def test_terminate_instance_with_pagination(self):
|
def test_delete_instance_with_pagination(self):
|
||||||
"""Instance should be deleted from
|
"""Instance should be deleted from
|
||||||
the next page.
|
the next page.
|
||||||
"""
|
"""
|
||||||
@ -4408,7 +4408,7 @@ class InstanceTests(helpers.TestCase):
|
|||||||
servers[page_size - 1].id])
|
servers[page_size - 1].id])
|
||||||
next_page_url = "?".join([reverse('horizon:project:instances:index'),
|
next_page_url = "?".join([reverse('horizon:project:instances:index'),
|
||||||
params])
|
params])
|
||||||
formData = {'action': 'instances__terminate__%s' % server.id}
|
formData = {'action': 'instances__delete__%s' % server.id}
|
||||||
res = self.client.post(next_page_url, formData)
|
res = self.client.post(next_page_url, formData)
|
||||||
|
|
||||||
self.assertRedirectsNoFollow(res, next_page_url)
|
self.assertRedirectsNoFollow(res, next_page_url)
|
||||||
|
@ -128,11 +128,11 @@ class SetInstanceDetailsAction(workflows.Action):
|
|||||||
"system choose a device name "
|
"system choose a device name "
|
||||||
"for you."))
|
"for you."))
|
||||||
|
|
||||||
delete_on_terminate = forms.BooleanField(label=_("Delete on Terminate"),
|
vol_delete_on_instance_delete = forms.BooleanField(
|
||||||
initial=False,
|
label=_("Delete Volume on Instance Delete"),
|
||||||
required=False,
|
initial=False,
|
||||||
help_text=_("Delete volume on "
|
required=False,
|
||||||
"instance terminate"))
|
help_text=_("Delete volume when the instance is deleted"))
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
name = _("Details")
|
name = _("Details")
|
||||||
@ -507,7 +507,7 @@ class SetInstanceDetails(workflows.Step):
|
|||||||
contributes = ("source_type", "source_id",
|
contributes = ("source_type", "source_id",
|
||||||
"availability_zone", "name", "count", "flavor",
|
"availability_zone", "name", "count", "flavor",
|
||||||
"device_name", # Can be None for an image.
|
"device_name", # Can be None for an image.
|
||||||
"delete_on_terminate")
|
"vol_delete_on_instance_delete")
|
||||||
|
|
||||||
def prepare_action_context(self, request, context):
|
def prepare_action_context(self, request, context):
|
||||||
if 'source_type' in context and 'source_id' in context:
|
if 'source_type' in context and 'source_id' in context:
|
||||||
@ -884,17 +884,18 @@ class LaunchInstance(workflows.Workflow):
|
|||||||
'source_type': dev_source_type_mapping[source_type],
|
'source_type': dev_source_type_mapping[source_type],
|
||||||
'destination_type': 'volume',
|
'destination_type': 'volume',
|
||||||
'delete_on_termination':
|
'delete_on_termination':
|
||||||
bool(context['delete_on_terminate']),
|
bool(context['vol_delete_on_instance_delete']),
|
||||||
'uuid': volume_source_id,
|
'uuid': volume_source_id,
|
||||||
'boot_index': '0',
|
'boot_index': '0',
|
||||||
'volume_size': context['volume_size']
|
'volume_size': context['volume_size']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
dev_mapping_1 = {context['device_name']: '%s::%s' %
|
dev_mapping_1 = {
|
||||||
(context['source_id'],
|
context['device_name']: '%s::%s' %
|
||||||
bool(context['delete_on_terminate']))
|
(context['source_id'],
|
||||||
}
|
bool(context['vol_delete_on_instance_delete']))
|
||||||
|
}
|
||||||
except Exception:
|
except Exception:
|
||||||
msg = _('Unable to retrieve extensions information')
|
msg = _('Unable to retrieve extensions information')
|
||||||
exceptions.handle(request, msg)
|
exceptions.handle(request, msg)
|
||||||
@ -906,7 +907,7 @@ class LaunchInstance(workflows.Workflow):
|
|||||||
'source_type': 'image',
|
'source_type': 'image',
|
||||||
'destination_type': 'volume',
|
'destination_type': 'volume',
|
||||||
'delete_on_termination':
|
'delete_on_termination':
|
||||||
bool(context['delete_on_terminate']),
|
bool(context['vol_delete_on_instance_delete']),
|
||||||
'uuid': context['source_id'],
|
'uuid': context['source_id'],
|
||||||
'boot_index': '0',
|
'boot_index': '0',
|
||||||
'volume_size': context['volume_size']
|
'volume_size': context['volume_size']
|
||||||
|
@ -22,5 +22,5 @@ class InstancesTable(tables.InstancesTable):
|
|||||||
name = "instances"
|
name = "instances"
|
||||||
verbose_name = _("Instances")
|
verbose_name = _("Instances")
|
||||||
row_actions = (
|
row_actions = (
|
||||||
tables.TerminateInstance,
|
tables.DeleteInstance,
|
||||||
)
|
)
|
||||||
|
@ -160,7 +160,7 @@
|
|||||||
vol_create: false,
|
vol_create: false,
|
||||||
// May be null
|
// May be null
|
||||||
vol_device_name: 'vda',
|
vol_device_name: 'vda',
|
||||||
vol_delete_on_terminate: false,
|
vol_delete_on_instance_delete: false,
|
||||||
vol_size: 1
|
vol_size: 1
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -472,7 +472,7 @@
|
|||||||
delete finalSpec.source_type;
|
delete finalSpec.source_type;
|
||||||
delete finalSpec.vol_create;
|
delete finalSpec.vol_create;
|
||||||
delete finalSpec.vol_device_name;
|
delete finalSpec.vol_device_name;
|
||||||
delete finalSpec.vol_delete_on_terminate;
|
delete finalSpec.vol_delete_on_instance_delete;
|
||||||
delete finalSpec.vol_size;
|
delete finalSpec.vol_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,7 +486,7 @@
|
|||||||
'device_name': deviceName,
|
'device_name': deviceName,
|
||||||
'source_type': SOURCE_TYPE_IMAGE,
|
'source_type': SOURCE_TYPE_IMAGE,
|
||||||
'destination_type': SOURCE_TYPE_VOLUME,
|
'destination_type': SOURCE_TYPE_VOLUME,
|
||||||
'delete_on_termination': finalSpec.vol_delete_on_terminate,
|
'delete_on_termination': finalSpec.vol_delete_on_instance_delete,
|
||||||
'uuid': finalSpec.source_id,
|
'uuid': finalSpec.source_id,
|
||||||
'boot_index': '0',
|
'boot_index': '0',
|
||||||
'volume_size': finalSpec.vol_size
|
'volume_size': finalSpec.vol_size
|
||||||
@ -503,7 +503,7 @@
|
|||||||
':',
|
':',
|
||||||
sourceType,
|
sourceType,
|
||||||
'::',
|
'::',
|
||||||
finalSpec.vol_delete_on_terminate
|
finalSpec.vol_delete_on_instance_delete
|
||||||
].join('');
|
].join('');
|
||||||
|
|
||||||
// Source ID must be empty for API
|
// Source ID must be empty for API
|
||||||
|
@ -373,7 +373,7 @@
|
|||||||
it('sets volume options appropriately', function() {
|
it('sets volume options appropriately', function() {
|
||||||
expect(model.newInstanceSpec.vol_create).toBe(false);
|
expect(model.newInstanceSpec.vol_create).toBe(false);
|
||||||
expect(model.newInstanceSpec.vol_device_name).toBe('vda');
|
expect(model.newInstanceSpec.vol_device_name).toBe('vda');
|
||||||
expect(model.newInstanceSpec.vol_delete_on_terminate).toBe(false);
|
expect(model.newInstanceSpec.vol_delete_on_instance_delete).toBe(false);
|
||||||
expect(model.newInstanceSpec.vol_size).toBe(1);
|
expect(model.newInstanceSpec.vol_size).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -391,7 +391,7 @@
|
|||||||
model.newInstanceSpec.security_groups = [ { id: 'adminId', name: 'admin' },
|
model.newInstanceSpec.security_groups = [ { id: 'adminId', name: 'admin' },
|
||||||
{ id: 'demoId', name: 'demo' } ];
|
{ id: 'demoId', name: 'demo' } ];
|
||||||
model.newInstanceSpec.vol_create = true;
|
model.newInstanceSpec.vol_create = true;
|
||||||
model.newInstanceSpec.vol_delete_on_terminate = true;
|
model.newInstanceSpec.vol_delete_on_instance_delete = true;
|
||||||
model.newInstanceSpec.vol_device_name = "volTestName";
|
model.newInstanceSpec.vol_device_name = "volTestName";
|
||||||
model.newInstanceSpec.vol_size = 10;
|
model.newInstanceSpec.vol_size = 10;
|
||||||
});
|
});
|
||||||
@ -442,7 +442,7 @@
|
|||||||
it('should handle source type of "volume"', function() {
|
it('should handle source type of "volume"', function() {
|
||||||
model.newInstanceSpec.source_type.type = 'volume';
|
model.newInstanceSpec.source_type.type = 'volume';
|
||||||
model.newInstanceSpec.source[0].id = 'imAnID';
|
model.newInstanceSpec.source[0].id = 'imAnID';
|
||||||
model.newInstanceSpec.vol_delete_on_terminate = 'yep';
|
model.newInstanceSpec.vol_delete_on_instance_delete = 'yep';
|
||||||
|
|
||||||
var finalSpec = model.createInstance();
|
var finalSpec = model.createInstance();
|
||||||
expect(finalSpec.block_device_mapping.volTestName)
|
expect(finalSpec.block_device_mapping.volTestName)
|
||||||
@ -461,7 +461,7 @@
|
|||||||
it('should handle source type of "volume_snapshot"', function() {
|
it('should handle source type of "volume_snapshot"', function() {
|
||||||
model.newInstanceSpec.source_type.type = 'volume_snapshot';
|
model.newInstanceSpec.source_type.type = 'volume_snapshot';
|
||||||
model.newInstanceSpec.source[0].id = 'imAnID';
|
model.newInstanceSpec.source[0].id = 'imAnID';
|
||||||
model.newInstanceSpec.vol_delete_on_terminate = 'yep';
|
model.newInstanceSpec.vol_delete_on_instance_delete = 'yep';
|
||||||
|
|
||||||
var finalSpec = model.createInstance();
|
var finalSpec = model.createInstance();
|
||||||
expect(finalSpec.block_device_mapping.volTestName)
|
expect(finalSpec.block_device_mapping.volTestName)
|
||||||
|
@ -240,7 +240,7 @@
|
|||||||
function updateBootSourceSelection(selectedSource) {
|
function updateBootSourceSelection(selectedSource) {
|
||||||
ctrl.currentBootSource = selectedSource;
|
ctrl.currentBootSource = selectedSource;
|
||||||
$scope.model.newInstanceSpec.vol_create = false;
|
$scope.model.newInstanceSpec.vol_create = false;
|
||||||
$scope.model.newInstanceSpec.vol_delete_on_terminate = false;
|
$scope.model.newInstanceSpec.vol_delete_on_instance_delete = false;
|
||||||
changeBootSource(selectedSource);
|
changeBootSource(selectedSource);
|
||||||
validateBootSourceType();
|
validateBootSourceType();
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@
|
|||||||
|
|
||||||
expect(ctrl.currentBootSource).toEqual('image');
|
expect(ctrl.currentBootSource).toEqual('image');
|
||||||
expect(scope.model.newInstanceSpec.vol_create).toBe(false);
|
expect(scope.model.newInstanceSpec.vol_create).toBe(false);
|
||||||
expect(scope.model.newInstanceSpec.vol_delete_on_terminate).toBe(false);
|
expect(scope.model.newInstanceSpec.vol_delete_on_instance_delete).toBe(false);
|
||||||
|
|
||||||
// check table data
|
// check table data
|
||||||
expect(ctrl.tableData).toBeDefined();
|
expect(ctrl.tableData).toBeDefined();
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<p translate><li><b>Image</b>: This option uses an image to boot the instance.</li></p>
|
<p translate><li><b>Image</b>: This option uses an image to boot the instance.</li></p>
|
||||||
<p translate><li><b>Instance Snapshot</b>: This option uses an instance snapshot to boot the instance.</li></p>
|
<p translate><li><b>Instance Snapshot</b>: This option uses an instance snapshot to boot the instance.</li></p>
|
||||||
<p translate>If you want to create an instance that uses persistent storage, meaning the instance data is saved when the instance is deleted, then select one of the following boot options:</p>
|
<p translate>If you want to create an instance that uses persistent storage, meaning the instance data is saved when the instance is deleted, then select one of the following boot options:</p>
|
||||||
<p translate><li><b>Image (with Create New Volume checked)</b>: This options uses an image to boot the instance, and creates a new volume to persist instance data. You can specify volume size and whether to delete the volume on termination of the instance.</li></p>
|
<p translate><li><b>Image (with Create New Volume checked)</b>: This options uses an image to boot the instance, and creates a new volume to persist instance data. You can specify volume size and whether to delete the volume on deletion of the instance.</li></p>
|
||||||
<p translate><li><b>Volume</b>: This option uses a volume that already exists. It does not create a new volume. You can choose to delete the volume on termination of the instance. <em>Note: when selecting Volume, you can only launch one instance.</em></li></p>
|
<p translate><li><b>Volume</b>: This option uses a volume that already exists. It does not create a new volume. You can choose to delete the volume on deletion of the instance. <em>Note: when selecting Volume, you can only launch one instance.</em></li></p>
|
||||||
<p translate><li><b>Volume Snapshot</b>: This option uses a volume snapshot to boot the instance, and creates a new volume to persist instance data. You can choose to delete the volume on termination of the instance.</li></p>
|
<p translate><li><b>Volume Snapshot</b>: This option uses a volume snapshot to boot the instance, and creates a new volume to persist instance data. You can choose to delete the volume on deletion of the instance.</li></p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -77,12 +77,12 @@
|
|||||||
|
|
||||||
<div class="col-xs-12 col-sm-4" ng-if="model.newInstanceSpec.vol_create == true">
|
<div class="col-xs-12 col-sm-4" ng-if="model.newInstanceSpec.vol_create == true">
|
||||||
<div class="form-group delete-volume">
|
<div class="form-group delete-volume">
|
||||||
<label translate class="on-top">Delete Volume on Terminate</label>
|
<label translate class="on-top">Delete Volume on Instance Delete</label>
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<label class="btn btn-toggle"
|
<label class="btn btn-toggle"
|
||||||
ng-repeat="option in ctrl.toggleButtonOptions"
|
ng-repeat="option in ctrl.toggleButtonOptions"
|
||||||
ng-model="model.newInstanceSpec.vol_delete_on_terminate"
|
ng-model="model.newInstanceSpec.vol_delete_on_instance_delete"
|
||||||
btn-radio="option.value">{$ ::option.label $}</label>
|
btn-radio="option.value">{$ ::option.label $}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -96,12 +96,12 @@
|
|||||||
<div class="col-xs-12 col-sm-6">
|
<div class="col-xs-12 col-sm-6">
|
||||||
|
|
||||||
<div class="form-group delete-volume">
|
<div class="form-group delete-volume">
|
||||||
<label translate class="on-top">Delete Volume on Terminate</label>
|
<label translate class="on-top">Delete Volume on Instance Delete</label>
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<label class="btn btn-toggle"
|
<label class="btn btn-toggle"
|
||||||
ng-repeat="option in ctrl.toggleButtonOptions"
|
ng-repeat="option in ctrl.toggleButtonOptions"
|
||||||
ng-model="model.newInstanceSpec.vol_delete_on_terminate"
|
ng-model="model.newInstanceSpec.vol_delete_on_instance_delete"
|
||||||
btn-radio="option.value">{$ ::option.label $}</label>
|
btn-radio="option.value">{$ ::option.label $}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -545,7 +545,7 @@ div.input input[type="checkbox"] {
|
|||||||
width: 25px;
|
width: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.terminated {
|
tr.deleted {
|
||||||
color: #999999;
|
color: #999999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,13 +25,13 @@ class InstancesPage(basepage.BaseNavigationPage):
|
|||||||
DEFAULT_VOLUME_NAME = None
|
DEFAULT_VOLUME_NAME = None
|
||||||
DEFAULT_SNAPSHOT_NAME = None
|
DEFAULT_SNAPSHOT_NAME = None
|
||||||
DEFAULT_VOLUME_SNAPSHOT_NAME = None
|
DEFAULT_VOLUME_SNAPSHOT_NAME = None
|
||||||
DEFAULT_DELETE_ON_TERMINATE = False
|
DEFAULT_VOL_DELETE_ON_INSTANCE_DELETE = False
|
||||||
DEFAULT_SECURITY_GROUP = True
|
DEFAULT_SECURITY_GROUP = True
|
||||||
|
|
||||||
_instances_table_locator = (by.By.CSS_SELECTOR, 'table#instances')
|
_instances_table_locator = (by.By.CSS_SELECTOR, 'table#instances')
|
||||||
|
|
||||||
INSTANCES_TABLE_NAME = "instances"
|
INSTANCES_TABLE_NAME = "instances"
|
||||||
INSTANCES_TABLE_ACTIONS = ("launch_ng", "launch", "terminate",
|
INSTANCES_TABLE_ACTIONS = ("launch_ng", "launch", "delete",
|
||||||
('start', 'stop', "reboot"))
|
('start', 'stop', "reboot"))
|
||||||
INSTANCES_TABLE_NAME_COLUMN_INDEX = 0
|
INSTANCES_TABLE_NAME_COLUMN_INDEX = 0
|
||||||
INSTANCES_TABLE_STATUS_COLUMN_INDEX = 5
|
INSTANCES_TABLE_STATUS_COLUMN_INDEX = 5
|
||||||
@ -41,14 +41,14 @@ class InstancesPage(basepage.BaseNavigationPage):
|
|||||||
"associate_floating_ip", "disassociate_floating_ip",
|
"associate_floating_ip", "disassociate_floating_ip",
|
||||||
"edit_instance", "edit_security_groups", "console",
|
"edit_instance", "edit_security_groups", "console",
|
||||||
"view_log", "pause", "suspend", "resize", "lock", "unlock",
|
"view_log", "pause", "suspend", "resize", "lock", "unlock",
|
||||||
"soft_reboot", "hard_reboot", "shutoff", "rebuild", "terminate")
|
"soft_reboot", "hard_reboot", "shutoff", "rebuild", "delete")
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_INSTANCE_FORM_FIELDS = ((
|
CREATE_INSTANCE_FORM_FIELDS = ((
|
||||||
"availability_zone", "name", "flavor",
|
"availability_zone", "name", "flavor",
|
||||||
"count", "source_type", "instance_snapshot_id",
|
"count", "source_type", "instance_snapshot_id",
|
||||||
"volume_id", "volume_snapshot_id", "image_id", "volume_size",
|
"volume_id", "volume_snapshot_id", "image_id", "volume_size",
|
||||||
"delete_on_terminate"),
|
"vol_delete_on_instance_delete"),
|
||||||
("keypair", "groups"),
|
("keypair", "groups"),
|
||||||
("script_source", "script_upload", "script_data"),
|
("script_source", "script_upload", "script_data"),
|
||||||
("disk_config", "config_drive")
|
("disk_config", "config_drive")
|
||||||
@ -88,14 +88,16 @@ class InstancesPage(basepage.BaseNavigationPage):
|
|||||||
def is_instance_present(self, name):
|
def is_instance_present(self, name):
|
||||||
return bool(self._get_row_with_instance_name(name))
|
return bool(self._get_row_with_instance_name(name))
|
||||||
|
|
||||||
def create_instance(self, instance_name,
|
def create_instance(
|
||||||
available_zone=None,
|
self, instance_name,
|
||||||
instance_count=DEFAULT_COUNT,
|
available_zone=None,
|
||||||
flavor=DEFAULT_FLAVOR,
|
instance_count=DEFAULT_COUNT,
|
||||||
boot_source=DEFAULT_BOOT_SOURCE,
|
flavor=DEFAULT_FLAVOR,
|
||||||
source_name=None,
|
boot_source=DEFAULT_BOOT_SOURCE,
|
||||||
device_size=None,
|
source_name=None,
|
||||||
delete_on_terminate=DEFAULT_DELETE_ON_TERMINATE):
|
device_size=None,
|
||||||
|
vol_delete_on_instance_delete=DEFAULT_VOL_DELETE_ON_INSTANCE_DELETE
|
||||||
|
):
|
||||||
if not available_zone:
|
if not available_zone:
|
||||||
available_zone = self.conf.launch_instances.available_zone
|
available_zone = self.conf.launch_instances.available_zone
|
||||||
self.instances_table.launch.click()
|
self.instances_table.launch.click()
|
||||||
@ -112,19 +114,19 @@ class InstancesPage(basepage.BaseNavigationPage):
|
|||||||
boot_source[0].text = source_name
|
boot_source[0].text = source_name
|
||||||
if device_size:
|
if device_size:
|
||||||
instance.volume_size.value = device_size
|
instance.volume_size.value = device_size
|
||||||
if delete_on_terminate:
|
if vol_delete_on_instance_delete:
|
||||||
instance.delete_on_terminate.mark()
|
instance.vol_delete_on_instance_delete.mark()
|
||||||
instance.submit.click()
|
instance.submit.click()
|
||||||
self.wait_till_popups_disappear()
|
self.wait_till_popups_disappear()
|
||||||
|
|
||||||
def terminate_instance(self, name):
|
def delete_instance(self, name):
|
||||||
row = self._get_row_with_instance_name(name)
|
row = self._get_row_with_instance_name(name)
|
||||||
row.mark()
|
row.mark()
|
||||||
self.instances_table.terminate.click()
|
self.instances_table.delete.click()
|
||||||
self.confirm_delete_instances_form.submit.click()
|
self.confirm_delete_instances_form.submit.click()
|
||||||
self.wait_till_popups_disappear()
|
self.wait_till_popups_disappear()
|
||||||
|
|
||||||
def is_instance_terminated(self, name):
|
def is_instance_deleted(self, name):
|
||||||
try:
|
try:
|
||||||
row = self._get_row_with_instance_name(name)
|
row = self._get_row_with_instance_name(name)
|
||||||
self._wait_till_element_disappears(row)
|
self._wait_till_element_disappears(row)
|
||||||
|
@ -17,12 +17,12 @@ INSTANCES_NAME = helpers.gen_random_resource_name('instance',
|
|||||||
|
|
||||||
class TestInstances(helpers.AdminTestCase):
|
class TestInstances(helpers.AdminTestCase):
|
||||||
"""This is a basic scenario to test:
|
"""This is a basic scenario to test:
|
||||||
* Create Instance and Terminate Instance
|
* Create Instance and Delete Instance
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_create_terminate_instance(self):
|
def test_create_delete_instance(self):
|
||||||
instances_page = self.home_pg.go_to_compute_instancespage()
|
instances_page = self.home_pg.go_to_compute_instancespage()
|
||||||
instances_page.create_instance(INSTANCES_NAME)
|
instances_page.create_instance(INSTANCES_NAME)
|
||||||
self.assertTrue(instances_page.is_instance_active(INSTANCES_NAME))
|
self.assertTrue(instances_page.is_instance_active(INSTANCES_NAME))
|
||||||
instances_page.terminate_instance(INSTANCES_NAME)
|
instances_page.delete_instance(INSTANCES_NAME)
|
||||||
self.assertTrue(instances_page.is_instance_terminated(INSTANCES_NAME))
|
self.assertTrue(instances_page.is_instance_deleted(INSTANCES_NAME))
|
||||||
|
@ -26,7 +26,7 @@ from openstack_dashboard.usage import quotas
|
|||||||
|
|
||||||
|
|
||||||
class BaseUsage(object):
|
class BaseUsage(object):
|
||||||
show_terminated = False
|
show_deleted = False
|
||||||
|
|
||||||
def __init__(self, request, project_id=None):
|
def __init__(self, request, project_id=None):
|
||||||
self.project_id = project_id or request.user.tenant_id
|
self.project_id = project_id or request.user.tenant_id
|
||||||
@ -248,7 +248,7 @@ class BaseUsage(object):
|
|||||||
|
|
||||||
|
|
||||||
class GlobalUsage(BaseUsage):
|
class GlobalUsage(BaseUsage):
|
||||||
show_terminated = True
|
show_deleted = True
|
||||||
|
|
||||||
def get_usage_list(self, start, end):
|
def get_usage_list(self, start, end):
|
||||||
return api.nova.usage_list(self.request, start, end)
|
return api.nova.usage_list(self.request, start, end)
|
||||||
@ -259,10 +259,10 @@ class ProjectUsage(BaseUsage):
|
|||||||
'hours', 'local_gb')
|
'hours', 'local_gb')
|
||||||
|
|
||||||
def get_usage_list(self, start, end):
|
def get_usage_list(self, start, end):
|
||||||
show_terminated = self.request.GET.get('show_terminated',
|
show_deleted = self.request.GET.get('show_deleted',
|
||||||
self.show_terminated)
|
self.show_deleted)
|
||||||
instances = []
|
instances = []
|
||||||
terminated_instances = []
|
deleted_instances = []
|
||||||
usage = api.nova.usage_get(self.request, self.project_id, start, end)
|
usage = api.nova.usage_get(self.request, self.project_id, start, end)
|
||||||
# Attribute may not exist if there are no instances
|
# Attribute may not exist if there are no instances
|
||||||
if hasattr(usage, 'server_usages'):
|
if hasattr(usage, 'server_usages'):
|
||||||
@ -273,8 +273,8 @@ class ProjectUsage(BaseUsage):
|
|||||||
server_uptime = server_usage['uptime']
|
server_uptime = server_usage['uptime']
|
||||||
total_uptime = now - datetime.timedelta(seconds=server_uptime)
|
total_uptime = now - datetime.timedelta(seconds=server_uptime)
|
||||||
server_usage['uptime_at'] = total_uptime
|
server_usage['uptime_at'] = total_uptime
|
||||||
if server_usage['ended_at'] and not show_terminated:
|
if server_usage['ended_at'] and not show_deleted:
|
||||||
terminated_instances.append(server_usage)
|
deleted_instances.append(server_usage)
|
||||||
else:
|
else:
|
||||||
instances.append(server_usage)
|
instances.append(server_usage)
|
||||||
usage.server_usages = instances
|
usage.server_usages = instances
|
||||||
|
@ -20,7 +20,7 @@ from openstack_dashboard.usage import base
|
|||||||
|
|
||||||
class UsageView(tables.DataTableView):
|
class UsageView(tables.DataTableView):
|
||||||
usage_class = None
|
usage_class = None
|
||||||
show_terminated = True
|
show_deleted = True
|
||||||
csv_template_name = None
|
csv_template_name = None
|
||||||
page_title = _("Overview")
|
page_title = _("Overview")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user