Commit f678f975 by Bach Dániel

Merge branch 'fix-disk_is_ready' into 'master'

Fix Disk Is Ready
parents 0a81d922 8237165c
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
import logging
logging.basicConfig(filename='/var/tmp/0015_disk_migration.log',level=logging.INFO)
logger = logging.getLogger()
class Migration(DataMigration):
def forwards(self, orm):
"Write your forwards methods here."
# Note: Don't use "from appname.models import ModelName".
# Use orm.ModelName to refer to models in this application,
# and orm['appname.ModelName'] for models in other applications.
disks = orm.Disk
for disk in disks.objects.all():
if disk.base is None and disk.destroyed is None:
logger.info("Set disk %s (%s) with filename: %s to ready.",
disk.name, disk.pk, disk.filename)
disk.is_ready = True
disk.save()
def backwards(self, orm):
"Write your backwards methods here."
models = {
u'storage.datastore': {
'Meta': {'ordering': "[u'name']", 'object_name': 'DataStore'},
'hostname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
u'storage.disk': {
'Meta': {'ordering': "[u'name']", 'object_name': 'Disk'},
'base': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'derivatives'", 'null': 'True', 'to': u"orm['storage.Disk']"}),
'created': ('model_utils.fields.AutoCreatedField', [], {'default': 'datetime.datetime.now'}),
'datastore': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['storage.DataStore']"}),
'destroyed': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'dev_num': ('django.db.models.fields.CharField', [], {'default': "u'a'", 'max_length': '1'}),
'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '256'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_ready': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'modified': ('model_utils.fields.AutoLastModifiedField', [], {'default': 'datetime.datetime.now'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'size': ('sizefield.models.FileSizeField', [], {'default': 'None', 'null': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '10'})
}
}
complete_apps = ['storage']
symmetrical = True
...@@ -27,13 +27,13 @@ from celery.contrib.abortable import AbortableAsyncResult ...@@ -27,13 +27,13 @@ from celery.contrib.abortable import AbortableAsyncResult
from django.db.models import (Model, BooleanField, CharField, DateTimeField, from django.db.models import (Model, BooleanField, CharField, DateTimeField,
ForeignKey) ForeignKey)
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _, ugettext_noop
from model_utils.models import TimeStampedModel from model_utils.models import TimeStampedModel
from sizefield.models import FileSizeField from sizefield.models import FileSizeField
from .tasks import local_tasks, storage_tasks from .tasks import local_tasks, storage_tasks
from celery.exceptions import TimeoutError from celery.exceptions import TimeoutError
from common.models import WorkerNotFound from common.models import WorkerNotFound, HumanReadableException
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -104,43 +104,73 @@ class Disk(TimeStampedModel): ...@@ -104,43 +104,73 @@ class Disk(TimeStampedModel):
('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.')))
class WrongDiskTypeError(Exception): class DiskError(HumanReadableException):
admin_message = None
def __init__(self, type, message=None):
if message is None: def __init__(self, disk, params=None, level=None, **kwargs):
message = ("Operation can't be invoked on a disk of type '%s'." kwargs.update(params or {})
% type) self.disc = kwargs["disk"] = disk
super(Disk.DiskError, self).__init__(
Exception.__init__(self, message) level, self.message, self.admin_message or self.message,
kwargs)
self.type = type
class WrongDiskTypeError(DiskError):
class DiskInUseError(Exception): message = ugettext_noop("Operation can't be invoked on disk "
"'%(name)s' of type '%(type)s'.")
def __init__(self, disk, message=None):
if message is None: admin_message = ugettext_noop(
message = ("The requested operation can't be performed on " "Operation can't be invoked on disk "
"disk '%s (%s)' because it is in use." % "'%(name)s' (%(pk)s) of type '%(type)s'.")
(disk.name, disk.filename))
def __init__(self, disk, params=None, **kwargs):
Exception.__init__(self, message) super(Disk.WrongDiskTypeError, self).__init__(
disk, params, type=disk.type, name=disk.name, pk=disk.pk)
self.disk = disk
class DiskInUseError(DiskError):
class DiskIsNotReady(Exception): message = ugettext_noop(
"The requested operation can't be performed on "
""" Exception for operations that need a deployed disk. "disk '%(name)s' because it is in use.")
"""
admin_message = ugettext_noop(
def __init__(self, disk, message=None): "The requested operation can't be performed on "
if message is None: "disk '%(name)s' (%(pk)s) because it is in use.")
message = ("The requested operation can't be performed on "
"disk '%s (%s)' because it has never been" def __init__(self, disk, params=None, **kwargs):
"deployed." % (disk.name, disk.filename)) super(Disk.DiskInUseError, self).__init__(
disk, params, name=disk.name, pk=disk.pk)
Exception.__init__(self, message)
class DiskIsNotReady(DiskError):
self.disk = disk message = ugettext_noop(
"The requested operation can't be performed on "
"disk '%(name)s' because it has never been deployed.")
admin_message = ugettext_noop(
"The requested operation can't be performed on "
"disk '%(name)s' (%(pk)s) [%(filename)s] because it has never been"
"deployed.")
def __init__(self, disk, params=None, **kwargs):
super(Disk.DiskIsNotReady, self).__init__(
disk, params, name=disk.name, pk=disk.pk,
filename=disk.filename)
class DiskBaseIsNotReady(DiskError):
message = ugettext_noop(
"The requested operation can't be performed on "
"disk '%(name)s' because its base has never been deployed.")
admin_message = ugettext_noop(
"The requested operation can't be performed on "
"disk '%(name)s' (%(pk)s) [%(filename)s] because its base "
"'%(b_name)s' (%(b_pk)s) [%(b_filename)s] has never been"
"deployed.")
def __init__(self, disk, params=None, **kwargs):
base = kwargs.get('base')
super(Disk.DiskBaseIsNotReady, self).__init__(
disk, params, name=disk.name, pk=disk.pk,
filename=disk.filename, b_name=base.name,
b_pk=base.pk, b_filename=base.filename)
@property @property
def path(self): def path(self):
...@@ -240,7 +270,7 @@ class Disk(TimeStampedModel): ...@@ -240,7 +270,7 @@ class Disk(TimeStampedModel):
} }
if self.type not in type_mapping.keys(): if self.type not in type_mapping.keys():
raise self.WrongDiskTypeError(self.type) raise self.WrongDiskTypeError(self)
new_type = type_mapping[self.type] new_type = type_mapping[self.type]
...@@ -313,6 +343,8 @@ class Disk(TimeStampedModel): ...@@ -313,6 +343,8 @@ class Disk(TimeStampedModel):
if self.is_ready: if self.is_ready:
return True return True
if self.base and not self.base.is_ready:
raise self.DiskBaseIsNotReady(self, base=self.base)
queue_name = self.get_remote_queue_name('storage', priority="fast") queue_name = self.get_remote_queue_name('storage', priority="fast")
disk_desc = self.get_disk_desc() disk_desc = self.get_disk_desc()
if self.base is not None: if self.base is not None:
...@@ -417,7 +449,7 @@ class Disk(TimeStampedModel): ...@@ -417,7 +449,7 @@ class Disk(TimeStampedModel):
'iso': ("iso", self), 'iso': ("iso", self),
} }
if self.type not in mapping.keys(): if self.type not in mapping.keys():
raise self.WrongDiskTypeError(self.type) raise self.WrongDiskTypeError(self)
if self.is_in_use: if self.is_in_use:
raise self.DiskInUseError(self) raise self.DiskInUseError(self)
...@@ -433,7 +465,7 @@ class Disk(TimeStampedModel): ...@@ -433,7 +465,7 @@ class Disk(TimeStampedModel):
disk = Disk.create(datastore=self.datastore, disk = Disk.create(datastore=self.datastore,
base=new_base, base=new_base,
name=self.name, size=self.size, name=self.name, size=self.size,
type=new_type) type=new_type, dev_num=self.dev_num)
queue_name = self.get_remote_queue_name("storage", priority="slow") queue_name = self.get_remote_queue_name("storage", priority="slow")
remote = storage_tasks.merge.apply_async(kwargs={ remote = storage_tasks.merge.apply_async(kwargs={
...@@ -450,4 +482,6 @@ class Disk(TimeStampedModel): ...@@ -450,4 +482,6 @@ class Disk(TimeStampedModel):
AbortableAsyncResult(remote.id).abort() AbortableAsyncResult(remote.id).abort()
disk.destroy() disk.destroy()
raise Exception("Save as aborted by use.") raise Exception("Save as aborted by use.")
disk.is_ready = True
disk.save()
return disk return disk
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