Commit a9e4ec53 by Dudás Ádám

storage: refactoring model and tasks' interfaces

parent 6bb44292
# coding=utf-8
import logging
import jsonpickle
import json
from django.db import models, transaction
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.db.models.signals import post_save, post_delete
from django.db.models.signals import post_delete
from model_utils.models import TimeStampedModel
from .tasks import StorageDriver
......@@ -14,9 +12,8 @@ logger = logging.getLogger(__name__)
class DataStore(models.Model):
'''
'''
"""Collection of virtual disks.
"""
name = models.CharField(max_length=100, unique=True,
verbose_name=_('name'))
path = models.CharField(max_length=200, unique=True,
......@@ -32,25 +29,41 @@ class DataStore(models.Model):
class Disk(TimeStampedModel):
"""Virtual disks."""
FORMATS = [('qcow2', 'qcow2'), ('raw', 'raw'), ('iso', 'iso')]
TYPES = [('snapshot', 'snapshot'), ('normal', 'normal')]
name = models.CharField(max_length=100, unique=True,
verbose_name=_('name'))
datastore = models.ForeignKey('DataStore')
format = models.CharField(max_length=10, choices=FORMATS)
size = models.IntegerField()
"""A virtual disk.
"""
TYPES = [('qcow2-norm', 'qcow2 normal'), ('qcow2-snap', 'qcow2 snapshot'),
('iso', 'iso'), ('raw-ro', 'raw read-only'), ('raw-rw', 'raw')]
name = models.CharField(max_length=100, verbose_name=_('name'))
filename = models.CharField(max_length=256, unique=True,
verbose_name=_('filename'))
datastore = models.ForeignKey(DataStore)
type = models.CharField(max_length=10, choices=TYPES)
size = models.IntegerField()
base = models.ForeignKey('self', blank=True, null=True,
related_name='derivatives')
ready = models.BooleanField(default=False)
dev_num = models.CharField(max_length=1, verbose_name="device number")
dev_num = models.CharField(default='a', max_length=1,
verbose_name="device number")
class Meta:
ordering = ['name']
verbose_name = _('disk')
verbose_name_plural = _('disks')
@property
def path(self):
return self.datastore.path + '/' + self.filename
@property
def format(self):
return {
'qcow2-norm': 'qcow2',
'qcow2-snap': 'qcow2',
'iso': 'iso',
'raw-ro': 'raw',
'raw-rw': 'raw',
}[self.type]
def get_exclusive(self):
"""Get an instance of the disk for exclusive usage.
......@@ -70,75 +83,35 @@ class Disk(TimeStampedModel):
def get_vmdisk_desc(self):
return {
'source': self.datastore.path + '/' + self.name,
'source': self.path,
'driver_type': self.format,
'driver_cache': 'default',
'target_device': self.device_type + self.dev_num
}
def to_json(self):
self.base_name = self.base.name if self.base else None
self.dir = self.datastore.path
return jsonpickle.encode(self, unpicklable=True)
def __unicode__(self):
return u"%s (#%d)" % (self.name, self.id)
@classmethod
def create_signal(cls, sender, instance, created, **kwargs):
if not instance.created:
StorageDriver.create_disk.delay(instance.to_json()).get()
instance.created = True
instance.save()
def deploy(self):
if self.ready:
return
@classmethod
def delete_signal(cls, sender, instance, using, **kwargs):
StorageDriver.delete_disk.delay(instance.to_json()).get()
disk_desc = {
'name': self.name,
'dir': self.datastore.path,
'format': self.format,
'size': self.size,
'base_name': self.base.name if self.base else None,
'type': self.type
}
StorageDriver.create_disk.delay(disk_desc).get()
self.ready = True
self.save()
@classmethod
def update_disk(cls, disk):
name = disk['name']
modified = False
try:
base = cls.objects.get(name=disk['base_name'])
except cls.DoesNotExist:
base = None
try:
d = cls.objects.get(name=name)
except Disk.DoesNotExist:
d = Disk(name=name,
created=True,
datastore=DataStore.objects.get(path=disk['dir']),
format=disk['format'],
type=disk['type'])
modified = True
if d.size != disk['size'] or d.base != base:
d.size = disk['size']
d.base = base
modified = True
if modified:
d.full_clean()
d.save()
def delete_signal(cls, sender, instance, using, **kwargs):
# TODO
# StorageDriver.delete_disk.delay(instance.to_json()).get()
pass
@classmethod
def update_disks(cls, delete=True):
"""Get and register virtual disks from storage driver."""
try:
json_data = StorageDriver.list_disks.delay().get(timeout=10)
disks = json.loads(json_data)
except:
return
with transaction.commit_on_success():
l = []
for disk in disks:
print disk
cls.update_disk(disk)
l.append(disk['name'])
if delete:
cls.objects.exclude(name__in=l).delete()
post_save.connect(Disk.create_signal, sender=Disk)
post_delete.connect(Disk.delete_signal, sender=Disk)
......@@ -8,17 +8,19 @@ logger = logging.getLogger(__name__)
class StorageDriver:
@celery.task(filter=task_method, name='storagedriver.list_disks')
def list_disks():
def list_disks(dir):
pass
@celery.task(filter=task_method, name='storagedriver.create_disk')
def create_disk(json_data):
def create_disk(disk_desc):
pass
@celery.task(filter=task_method, name='storagedriver.delete_disk')
def delete_disk(json_data):
# TODO review
pass
@celery.task(filter=task_method, name='storagedriver.get_disk')
def get_disk(json_data):
# TODO review
pass
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