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
from django.db.models import (Model, BooleanField, CharField, DateTimeField,
ForeignKey)
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 sizefield.models import FileSizeField
from .tasks import local_tasks, storage_tasks
from celery.exceptions import TimeoutError
from common.models import WorkerNotFound
from common.models import WorkerNotFound, HumanReadableException
logger = logging.getLogger(__name__)
......@@ -104,43 +104,73 @@ class Disk(TimeStampedModel):
('create_empty_disk', _('Can create an empty disk.')),
('download_disk', _('Can download a disk.')))
class WrongDiskTypeError(Exception):
def __init__(self, type, message=None):
if message is None:
message = ("Operation can't be invoked on a disk of type '%s'."
% type)
Exception.__init__(self, message)
self.type = type
class DiskInUseError(Exception):
def __init__(self, disk, message=None):
if message is None:
message = ("The requested operation can't be performed on "
"disk '%s (%s)' because it is in use." %
(disk.name, disk.filename))
Exception.__init__(self, message)
self.disk = disk
class DiskIsNotReady(Exception):
""" Exception for operations that need a deployed disk.
"""
def __init__(self, disk, message=None):
if message is None:
message = ("The requested operation can't be performed on "
"disk '%s (%s)' because it has never been"
"deployed." % (disk.name, disk.filename))
Exception.__init__(self, message)
self.disk = disk
class DiskError(HumanReadableException):
admin_message = None
def __init__(self, disk, params=None, level=None, **kwargs):
kwargs.update(params or {})
self.disc = kwargs["disk"] = disk
super(Disk.DiskError, self).__init__(
level, self.message, self.admin_message or self.message,
kwargs)
class WrongDiskTypeError(DiskError):
message = ugettext_noop("Operation can't be invoked on disk "
"'%(name)s' of type '%(type)s'.")
admin_message = ugettext_noop(
"Operation can't be invoked on disk "
"'%(name)s' (%(pk)s) of type '%(type)s'.")
def __init__(self, disk, params=None, **kwargs):
super(Disk.WrongDiskTypeError, self).__init__(
disk, params, type=disk.type, name=disk.name, pk=disk.pk)
class DiskInUseError(DiskError):
message = ugettext_noop(
"The requested operation can't be performed on "
"disk '%(name)s' because it is in use.")
admin_message = ugettext_noop(
"The requested operation can't be performed on "
"disk '%(name)s' (%(pk)s) because it is in use.")
def __init__(self, disk, params=None, **kwargs):
super(Disk.DiskInUseError, self).__init__(
disk, params, name=disk.name, pk=disk.pk)
class DiskIsNotReady(DiskError):
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
def path(self):
......@@ -240,7 +270,7 @@ class Disk(TimeStampedModel):
}
if self.type not in type_mapping.keys():
raise self.WrongDiskTypeError(self.type)
raise self.WrongDiskTypeError(self)
new_type = type_mapping[self.type]
......@@ -313,6 +343,8 @@ class Disk(TimeStampedModel):
if self.is_ready:
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")
disk_desc = self.get_disk_desc()
if self.base is not None:
......@@ -417,7 +449,7 @@ class Disk(TimeStampedModel):
'iso': ("iso", self),
}
if self.type not in mapping.keys():
raise self.WrongDiskTypeError(self.type)
raise self.WrongDiskTypeError(self)
if self.is_in_use:
raise self.DiskInUseError(self)
......@@ -433,7 +465,7 @@ class Disk(TimeStampedModel):
disk = Disk.create(datastore=self.datastore,
base=new_base,
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")
remote = storage_tasks.merge.apply_async(kwargs={
......@@ -450,4 +482,6 @@ class Disk(TimeStampedModel):
AbortableAsyncResult(remote.id).abort()
disk.destroy()
raise Exception("Save as aborted by use.")
disk.is_ready = True
disk.save()
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