Commit f068881e by Czémán Arnold

dashboard, vm, storage: add datastore attribute for VirtualMachineDescModel, add…

dashboard, vm, storage: add datastore attribute for VirtualMachineDescModel, add datastore selector for vm and template views, modify sleep, wake up, and delete mem dump operation
parent f601f261
...@@ -1450,6 +1450,25 @@ class RawDataForm(forms.ModelForm): ...@@ -1450,6 +1450,25 @@ class RawDataForm(forms.ModelForm):
return helper return helper
class VmDataStoreForm(forms.ModelForm):
datastore = forms.ModelChoiceField(queryset=DataStore.objects.all(),
empty_label=None)
class Meta:
model = Instance
fields = ('datastore', )
@property
def helper(self):
helper = FormHelper()
helper.form_show_labels = False
helper.form_action = reverse_lazy("dashboard.views.vm-data-store",
kwargs={'pk': self.instance.pk})
helper.add_input(Submit("submit", _("Save"),
css_class="btn btn-success", ))
return helper
class GroupPermissionForm(forms.ModelForm): class GroupPermissionForm(forms.ModelForm):
permissions = forms.ModelMultipleChoiceField( permissions = forms.ModelMultipleChoiceField(
queryset=None, queryset=None,
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
<fieldset> <fieldset>
<legend>{% trans "External resources" %}</legend> <legend>{% trans "External resources" %}</legend>
{{ form.networks|as_crispy_field }} {{ form.networks|as_crispy_field }}
{{ form.datastore|as_crispy_field }}
{{ form.lease|as_crispy_field }} {{ form.lease|as_crispy_field }}
{% if show_lease_create %} {% if show_lease_create %}
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
<legend>{% trans "External resources" %}</legend> <legend>{% trans "External resources" %}</legend>
{{ form.networks|as_crispy_field }} {{ form.networks|as_crispy_field }}
{{ form.lease|as_crispy_field }} {{ form.lease|as_crispy_field }}
{{ form.datastore|as_crispy_field }}
{{ form.tags|as_crispy_field }} {{ form.tags|as_crispy_field }}
</fieldset> </fieldset>
......
...@@ -91,6 +91,17 @@ ...@@ -91,6 +91,17 @@
</div> </div>
</div> </div>
<hr/>
<div class="row">
<div class="col-sm-12">
<h3>
{% trans "Data store" %}
</h3>
{% crispy data_store_form %}
</div>
</div>
{% endif %} {% endif %}
{% block extra_js %} {% block extra_js %}
......
...@@ -42,7 +42,7 @@ from .views import ( ...@@ -42,7 +42,7 @@ from .views import (
ConnectCommandDelete, ConnectCommandDetail, ConnectCommandCreate, ConnectCommandDelete, ConnectCommandDetail, ConnectCommandCreate,
StoreList, store_download, store_upload, store_get_upload_url, StoreRemove, StoreList, store_download, store_upload, store_get_upload_url, StoreRemove,
store_new_directory, store_refresh_toplist, store_new_directory, store_refresh_toplist,
VmTraitsUpdate, VmRawDataUpdate, VmTraitsUpdate, VmRawDataUpdate, VmDataStoreUpdate,
GroupPermissionsView, GroupPermissionsView,
LeaseAclUpdateView, LeaseAclUpdateView,
toggle_template_tutorial, toggle_template_tutorial,
...@@ -114,6 +114,8 @@ urlpatterns = patterns( ...@@ -114,6 +114,8 @@ urlpatterns = patterns(
name='dashboard.views.vm-traits'), name='dashboard.views.vm-traits'),
url(r'^vm/(?P<pk>\d+)/raw_data/$', VmRawDataUpdate.as_view(), url(r'^vm/(?P<pk>\d+)/raw_data/$', VmRawDataUpdate.as_view(),
name='dashboard.views.vm-raw-data'), name='dashboard.views.vm-raw-data'),
url(r'^vm/(?P<pk>\d+)/data_store/$', VmDataStoreUpdate.as_view(),
name='dashboard.views.vm-data-store'),
url(r'^vm/(?P<pk>\d+)/toggle_tutorial/$', toggle_template_tutorial, url(r'^vm/(?P<pk>\d+)/toggle_tutorial/$', toggle_template_tutorial,
name='dashboard.views.vm-toggle-tutorial'), name='dashboard.views.vm-toggle-tutorial'),
......
...@@ -64,7 +64,7 @@ from ..forms import ( ...@@ -64,7 +64,7 @@ from ..forms import (
VmDiskResizeForm, RedeployForm, VmDiskRemoveForm, VmDiskResizeForm, RedeployForm, VmDiskRemoveForm,
VmMigrateForm, VmDeployForm, VmMigrateForm, VmDeployForm,
VmPortRemoveForm, VmPortAddForm, VmPortRemoveForm, VmPortAddForm,
VmRemoveInterfaceForm, VmRemoveInterfaceForm, VmDataStoreForm,
) )
from request.models import TemplateAccessType, LeaseType from request.models import TemplateAccessType, LeaseType
from request.forms import LeaseRequestForm, TemplateRequestForm from request.forms import LeaseRequestForm, TemplateRequestForm
...@@ -158,6 +158,7 @@ class VmDetailView(GraphMixin, CheckedDetailView): ...@@ -158,6 +158,7 @@ class VmDetailView(GraphMixin, CheckedDetailView):
if self.request.user.is_superuser: if self.request.user.is_superuser:
context['traits_form'] = TraitsForm(instance=instance) context['traits_form'] = TraitsForm(instance=instance)
context['raw_data_form'] = RawDataForm(instance=instance) context['raw_data_form'] = RawDataForm(instance=instance)
context['data_store_form'] = VmDataStoreForm(instance=instance)
# resources change perm # resources change perm
context['can_change_resources'] = self.request.user.has_perm( context['can_change_resources'] = self.request.user.has_perm(
...@@ -311,6 +312,14 @@ class VmRawDataUpdate(SuperuserRequiredMixin, UpdateView): ...@@ -311,6 +312,14 @@ class VmRawDataUpdate(SuperuserRequiredMixin, UpdateView):
return self.get_object().get_absolute_url() + "#resources" return self.get_object().get_absolute_url() + "#resources"
class VmDataStoreUpdate(SuperuserRequiredMixin, UpdateView):
form_class = VmDataStoreForm
model = Instance
def get_success_url(self):
return self.get_object().get_absolute_url() + "#resources"
class VmOperationView(AjaxOperationMixin, OperationView): class VmOperationView(AjaxOperationMixin, OperationView):
model = Instance model = Instance
......
...@@ -44,7 +44,7 @@ def delete(disk_desc): ...@@ -44,7 +44,7 @@ def delete(disk_desc):
@celery.task(name='storagedriver.delete_dump') @celery.task(name='storagedriver.delete_dump')
def delete_dump(data_store_type, path): def delete_dump(data_store_type, dir, filename):
pass pass
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('storage', '0005_auto_20160331_1823'),
('vm', '0002_interface_model'),
]
operations = [
migrations.AddField(
model_name='instance',
name='datastore',
field=models.ForeignKey(default=1, verbose_name='Data store', to='storage.DataStore', help_text="The target of VM's dump."),
preserve_default=False,
),
migrations.AddField(
model_name='instancetemplate',
name='datastore',
field=models.ForeignKey(default=1, verbose_name='Data store', to='storage.DataStore', help_text="The target of VM's dump."),
preserve_default=False,
),
]
...@@ -50,6 +50,7 @@ from .activity import (ActivityInProgressError, InstanceActivity) ...@@ -50,6 +50,7 @@ from .activity import (ActivityInProgressError, InstanceActivity)
from .common import BaseResourceConfigModel, Lease from .common import BaseResourceConfigModel, Lease
from .network import Interface from .network import Interface
from .node import Node, Trait from .node import Node, Trait
from storage.models import DataStore
logger = getLogger(__name__) logger = getLogger(__name__)
pre_state_changed = Signal(providing_args=["new_state"]) pre_state_changed = Signal(providing_args=["new_state"])
...@@ -93,6 +94,7 @@ class VirtualMachineDescModel(BaseResourceConfigModel): ...@@ -93,6 +94,7 @@ class VirtualMachineDescModel(BaseResourceConfigModel):
"""Abstract base for virtual machine describing models. """Abstract base for virtual machine describing models.
""" """
access_method = CharField(max_length=10, choices=ACCESS_METHODS, access_method = CharField(max_length=10, choices=ACCESS_METHODS,
verbose_name=_('access method'), verbose_name=_('access method'),
help_text=_('Primary remote access method.')) help_text=_('Primary remote access method.'))
...@@ -116,6 +118,8 @@ class VirtualMachineDescModel(BaseResourceConfigModel): ...@@ -116,6 +118,8 @@ class VirtualMachineDescModel(BaseResourceConfigModel):
help_text=_( help_text=_(
'If the machine has agent installed, and ' 'If the machine has agent installed, and '
'the manager should wait for its start.')) 'the manager should wait for its start.'))
datastore = ForeignKey(DataStore, verbose_name=_("Data store"),
help_text=_("The target of VM's dump."))
class Meta: class Meta:
abstract = True abstract = True
...@@ -482,16 +486,10 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin, ...@@ -482,16 +486,10 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
def mem_dump(self): def mem_dump(self):
"""Return the path and datastore for the memory dump. """Return the path and datastore for the memory dump.
It is always on the first hard drive storage named cloud-<id>.dump It named cloud-<id>.dump
""" """
try: filename = self.vm_name + '.dump'
datastore = self.disks.all()[0].datastore return {'datastore': self.datastore, 'filename': filename}
except IndexError:
from storage.models import DataStore
datastore = DataStore.get_default_datastore()
path = datastore.path + '/' + self.vm_name + '.dump'
return {'datastore': datastore, 'path': path}
@property @property
def primary_host(self): def primary_host(self):
......
...@@ -530,7 +530,9 @@ class DestroyOperation(InstanceOperation): ...@@ -530,7 +530,9 @@ class DestroyOperation(InstanceOperation):
"storage", "fast") "storage", "fast")
def _get_remote_args(self, **kwargs): def _get_remote_args(self, **kwargs):
return [self.instance.mem_dump['path']] return [self.instance.mem_dump['datastore'].type,
self.instance.mem_dump['datastore'].path,
self.instance.mem_dump['filename']]
@register_operation @register_operation
...@@ -772,6 +774,7 @@ class SaveAsTemplateOperation(InstanceOperation): ...@@ -772,6 +774,7 @@ class SaveAsTemplateOperation(InstanceOperation):
'ram_size': self.instance.ram_size, 'ram_size': self.instance.ram_size,
'raw_data': self.instance.raw_data, 'raw_data': self.instance.raw_data,
'system': self.instance.system, 'system': self.instance.system,
'datastore': self.instance.datastore,
} }
params.update(kwargs) params.update(kwargs)
params.pop("parent_activity", None) params.pop("parent_activity", None)
...@@ -923,7 +926,9 @@ class SleepOperation(InstanceOperation): ...@@ -923,7 +926,9 @@ class SleepOperation(InstanceOperation):
def _get_remote_args(self, **kwargs): def _get_remote_args(self, **kwargs):
return (super(SleepOperation.SuspendVmOperation, self) return (super(SleepOperation.SuspendVmOperation, self)
._get_remote_args(**kwargs) + ._get_remote_args(**kwargs) +
[self.instance.mem_dump['path']]) [self.instance.mem_dump['datastore'].type,
self.instance.mem_dump['datastore'].path,
self.instance.mem_dump['filename']])
@register_operation @register_operation
...@@ -977,7 +982,9 @@ class WakeUpOperation(InstanceOperation): ...@@ -977,7 +982,9 @@ class WakeUpOperation(InstanceOperation):
def _get_remote_args(self, **kwargs): def _get_remote_args(self, **kwargs):
return (super(WakeUpOperation.WakeUpVmOperation, self) return (super(WakeUpOperation.WakeUpVmOperation, self)
._get_remote_args(**kwargs) + ._get_remote_args(**kwargs) +
[self.instance.mem_dump['path']]) [self.instance.mem_dump['datastore'].type,
self.instance.mem_dump['datastore'].path,
self.instance.mem_dump['filename']])
@register_operation @register_operation
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment