Commit 1ff259f9 by Czémán Arnold

dashboard, storage, vm: add data store selection feature for create disk form

parent 6a9f1d2c
...@@ -816,10 +816,19 @@ class VmCreateDiskForm(OperationForm): ...@@ -816,10 +816,19 @@ class VmCreateDiskForm(OperationForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
default = kwargs.pop('default', None) default = kwargs.pop('default', None)
datastore_choices = kwargs.pop('datastore_choices')
super(VmCreateDiskForm, self).__init__(*args, **kwargs) super(VmCreateDiskForm, self).__init__(*args, **kwargs)
if default: if default:
self.fields['name'].initial = default self.fields['name'].initial = default
datastore_field = forms.ModelChoiceField(
queryset=datastore_choices, required=False, initial=None,
label=_('Data store'))
if not datastore_choices:
datastore_field.widget.attrs['disabled'] = 'disabled'
datastore_field.empty_label = _('No more data stores.')
self.fields['datastore'] = datastore_field
def clean_size(self): def clean_size(self):
size_in_bytes = self.cleaned_data.get("size") size_in_bytes = self.cleaned_data.get("size")
if not size_in_bytes.isdigit() and len(size_in_bytes) > 0: if not size_in_bytes.isdigit() and len(size_in_bytes) > 0:
......
...@@ -47,7 +47,7 @@ from common.models import ( ...@@ -47,7 +47,7 @@ from common.models import (
) )
from firewall.models import Vlan, Host, Rule from firewall.models import Vlan, Host, Rule
from manager.scheduler import SchedulerError from manager.scheduler import SchedulerError
from storage.models import Disk from storage.models import Disk, DataStore
from vm.models import ( from vm.models import (
Instance, InstanceActivity, Node, Lease, Instance, InstanceActivity, Node, Lease,
InstanceTemplate, InterfaceTemplate, Interface, InstanceTemplate, InterfaceTemplate, Interface,
...@@ -416,6 +416,7 @@ class VmCreateDiskView(FormOperationMixin, VmOperationView): ...@@ -416,6 +416,7 @@ class VmCreateDiskView(FormOperationMixin, VmOperationView):
val = super(VmCreateDiskView, self).get_form_kwargs() val = super(VmCreateDiskView, self).get_form_kwargs()
num = op.instance.disks.count() + 1 num = op.instance.disks.count() + 1
val['default'] = "%s %d" % (op.instance.name, num) val['default'] = "%s %d" % (op.instance.name, num)
val['datastore_choices'] = DataStore.get_all()
return val return val
......
...@@ -151,6 +151,11 @@ class DataStore(Model): ...@@ -151,6 +151,11 @@ class DataStore(Model):
pass pass
return cls.objects.all()[0] # TODO return cls.objects.all()[0] # TODO
@classmethod
def get_all(cls):
return cls.objects.all()
class Disk(TimeStampedModel): class Disk(TimeStampedModel):
...@@ -492,6 +497,14 @@ class Disk(TimeStampedModel): ...@@ -492,6 +497,14 @@ class Disk(TimeStampedModel):
self.save() self.save()
return True return True
@staticmethod
def get_type_for_datastore(datastore):
if datastore.type == "ceph_block":
return "ceph-norm"
return "qcow2-norm"
@classmethod @classmethod
def create(cls, user=None, **params): def create(cls, user=None, **params):
disk = cls.__create(user, params) disk = cls.__create(user, params)
......
...@@ -872,3 +872,18 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin, ...@@ -872,3 +872,18 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
user=user, concurrency_check=concurrency_check, user=user, concurrency_check=concurrency_check,
readable_name=readable_name, resultant_state=resultant_state) readable_name=readable_name, resultant_state=resultant_state)
return activitycontextimpl(act, on_abort=on_abort, on_commit=on_commit) return activitycontextimpl(act, on_abort=on_abort, on_commit=on_commit)
def get_most_used_datastore(self):
disks = self.disks.all()
if not disks:
return None
freqs = dict()
for disk in disks:
datastore = disk.datastore
freqs[datastore] = freqs.get(datastore, 0) + 1
datastore = max(freqs.items(), key=lambda x: x[1])
return datastore[0]
...@@ -255,12 +255,20 @@ class CreateDiskOperation(InstanceOperation): ...@@ -255,12 +255,20 @@ class CreateDiskOperation(InstanceOperation):
required_perms = ('storage.create_empty_disk', ) required_perms = ('storage.create_empty_disk', )
accept_states = ('STOPPED', 'PENDING', 'RUNNING') accept_states = ('STOPPED', 'PENDING', 'RUNNING')
def _operation(self, user, size, activity, name=None): def _operation(self, user, size, datastore, activity, name=None):
from storage.models import Disk from storage.models import Disk, DataStore
if not datastore:
datastore = self.instance.get_most_used_datastore()
if not datastore:
datastore = DataStore.get_default_datastore()
type = Disk.get_type_for_datastore(datastore)
if not name: if not name:
name = "new disk" name = "new disk"
disk = Disk.create(size=size, name=name, type="qcow2-norm") disk = Disk.create(size=size, name=name,
datastore=datastore, type=type)
disk.full_clean() disk.full_clean()
devnums = list(ascii_lowercase) devnums = list(ascii_lowercase)
for d in self.instance.disks.all(): for d in self.instance.disks.all():
......
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