Commit 238c23ba by Bálint Máhonfai

Start implementing export and import

parent 3615d835
Pipeline #785 failed with stage
in 0 seconds
...@@ -830,6 +830,34 @@ class VmCreateDiskForm(OperationForm): ...@@ -830,6 +830,34 @@ class VmCreateDiskForm(OperationForm):
return size_in_bytes return size_in_bytes
class VmDiskExportForm(OperationForm):
def __init__(self, *args, **kwargs):
choices = kwargs.pop('choices')
self.disk = kwargs.pop('default')
super(VmDiskExportForm, self).__init__(*args, **kwargs)
self.fields['disk'] = forms.ModelChoiceField(
queryset=choices, initial=self.disk, required=True,
empty_label=None, label=_('Disk'))
if self.disk:
self.fields['disk'].widget = HiddenInput()
@property
def helper(self):
helper = super(VmDiskExportForm, self).helper
if self.disk:
helper.layout = Layout(
AnyTag(
"div",
HTML(_("<label>Disk:</label> %s") % escape(self.disk)),
css_class="form-group",
),
Field("disk"),
)
return helper
class VmDiskResizeForm(OperationForm): class VmDiskResizeForm(OperationForm):
size = forms.CharField( size = forms.CharField(
widget=FileSizeWidget, initial=(10 << 30), label=_('Size'), widget=FileSizeWidget, initial=(10 << 30), label=_('Size'),
...@@ -899,6 +927,11 @@ class VmDiskRemoveForm(OperationForm): ...@@ -899,6 +927,11 @@ class VmDiskRemoveForm(OperationForm):
return helper return helper
class VmImportDiskForm(OperationForm):
name = forms.CharField(max_length=50, label=_('Name'))
disk_file = forms.FileField(label=_('File'))
class VmDownloadDiskForm(OperationForm): class VmDownloadDiskForm(OperationForm):
name = forms.CharField(max_length=100, label=_("Name"), required=False) name = forms.CharField(max_length=100, label=_("Name"), required=False)
url = forms.CharField(label=_('URL'), validators=[URLValidator(), ]) url = forms.CharField(label=_('URL'), validators=[URLValidator(), ])
......
...@@ -61,9 +61,10 @@ from .util import ( ...@@ -61,9 +61,10 @@ from .util import (
) )
from ..forms import ( from ..forms import (
AclUserOrGroupAddForm, VmResourcesForm, TraitsForm, RawDataForm, AclUserOrGroupAddForm, VmResourcesForm, TraitsForm, RawDataForm,
VmAddInterfaceForm, VmCreateDiskForm, VmDownloadDiskForm, VmSaveForm, VmAddInterfaceForm, VmCreateDiskForm, VmDownloadDiskForm,
VmImportDiskForm, VmSaveForm,
VmRenewForm, VmStateChangeForm, VmListSearchForm, VmCustomizeForm, VmRenewForm, VmStateChangeForm, VmListSearchForm, VmCustomizeForm,
VmDiskResizeForm, RedeployForm, VmDiskRemoveForm, VmDiskExportForm, VmDiskResizeForm, RedeployForm, VmDiskRemoveForm,
VmMigrateForm, VmDeployForm, VmMigrateForm, VmDeployForm,
VmPortRemoveForm, VmPortAddForm, VmPortRemoveForm, VmPortAddForm,
VmRemoveInterfaceForm, VmRemoveInterfaceForm,
...@@ -408,6 +409,17 @@ class VmCreateDiskView(FormOperationMixin, VmOperationView): ...@@ -408,6 +409,17 @@ class VmCreateDiskView(FormOperationMixin, VmOperationView):
return val return val
class VmImportDiskView(FormOperationMixin, VmOperationView):
op = 'import_disk'
form_class = VmImportDiskForm
show_in_toolbar = False
icon = 'upload'
effect = "success"
is_disk_operation = True
with_reload = True
class VmDownloadDiskView(FormOperationMixin, VmOperationView): class VmDownloadDiskView(FormOperationMixin, VmOperationView):
op = 'download_disk' op = 'download_disk'
...@@ -769,7 +781,11 @@ vm_ops = OrderedDict([ ...@@ -769,7 +781,11 @@ vm_ops = OrderedDict([
extra_bases=[TokenOperationView], extra_bases=[TokenOperationView],
op='destroy', icon='times', effect='danger')), op='destroy', icon='times', effect='danger')),
('create_disk', VmCreateDiskView), ('create_disk', VmCreateDiskView),
('import_disk', VmImportDiskView),
('download_disk', VmDownloadDiskView), ('download_disk', VmDownloadDiskView),
('export_disk', VmDiskModifyView.factory(
op='export_disk', form_class=VmDiskExportForm,
icon='download', effect='info')),
('resize_disk', VmDiskModifyView.factory( ('resize_disk', VmDiskModifyView.factory(
op='resize_disk', form_class=VmDiskResizeForm, op='resize_disk', form_class=VmDiskResizeForm,
icon='arrows-alt', effect="warning")), icon='arrows-alt', effect="warning")),
......
...@@ -149,7 +149,9 @@ class Disk(TimeStampedModel): ...@@ -149,7 +149,9 @@ class Disk(TimeStampedModel):
permissions = ( permissions = (
('create_empty_disk', _('Can create an empty disk.')), ('create_empty_disk', _('Can create an empty disk.')),
('download_disk', _('Can download a disk.')), ('download_disk', _('Can download a disk.')),
('resize_disk', _('Can resize a disk.')) ('resize_disk', _('Can resize a disk.')),
('import_disk', _('Can import a disk.')),
('export_disk', _('Can export a disk.'))
) )
class DiskError(HumanReadableException): class DiskError(HumanReadableException):
...@@ -550,3 +552,7 @@ class Disk(TimeStampedModel): ...@@ -550,3 +552,7 @@ class Disk(TimeStampedModel):
@property @property
def is_resizable(self): def is_resizable(self):
return self.type in ('qcow2-norm', 'raw-rw', 'qcow2-snap', ) return self.type in ('qcow2-norm', 'raw-rw', 'qcow2-snap', )
@property
def is_exportable(self):
return self.type in ('qcow2-norm', 'qcow2-snap', 'raw-rw', 'raw-ro')
...@@ -352,6 +352,34 @@ class DownloadDiskOperation(InstanceOperation): ...@@ -352,6 +352,34 @@ class DownloadDiskOperation(InstanceOperation):
@register_operation @register_operation
class ImportDiskOperation(InstanceOperation):
id = 'import_disk'
name = _('import disk')
description = _('Import and attach a disk image to the virtual machine.')
abortable = True
has_percentage = True
required_perms = ('storage.import_disk',)
accept_states = ('STOPPED', 'PENDING', 'RUNNING')
async_queue = 'localhost.man.slow'
def _operation(self, **kwargs):
from storage.models import Disk
@register_operation
class ExportDiskOperation(InstanceOperation):
id = 'export_disk'
name = _('export disk')
description = _('Export disk to VMDK format.')
required_perms = ('storage.export_disk',)
accept_states = ('STOPPED', 'PENDING', 'RUNNING')
def _operation(self, **kwargs):
from storage.models import Disk
@register_operation
class DeployOperation(InstanceOperation): class DeployOperation(InstanceOperation):
id = 'deploy' id = 'deploy'
name = _("deploy") name = _("deploy")
......
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