Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / volume / volumes.py @ 18ca395d

History | View | Annotate | Download (4.1 kB)

1 dec501fa Christos Stavrakakis
import logging
2 dec501fa Christos Stavrakakis
3 dec501fa Christos Stavrakakis
from django.db import transaction
4 dec501fa Christos Stavrakakis
from synnefo.db.models import Volume
5 dec501fa Christos Stavrakakis
from snf_django.lib.api import faults
6 dec501fa Christos Stavrakakis
from synnefo.volume import util
7 dec501fa Christos Stavrakakis
from synnefo.logic import backend
8 dec501fa Christos Stavrakakis
9 dec501fa Christos Stavrakakis
log = logging.getLogger(__name__)
10 dec501fa Christos Stavrakakis
11 dec501fa Christos Stavrakakis
12 dec501fa Christos Stavrakakis
@transaction.commit_on_success
13 dec501fa Christos Stavrakakis
def create(user_id, size, server_id, name=None, description=None,
14 dec501fa Christos Stavrakakis
           source_volume_id=None, source_snapshot_id=None,
15 dec501fa Christos Stavrakakis
           source_image_id=None, metadata=None):
16 dec501fa Christos Stavrakakis
17 dec501fa Christos Stavrakakis
    if server_id is None:
18 dec501fa Christos Stavrakakis
        raise faults.BadRequest("Volume must be attached to server")
19 dec501fa Christos Stavrakakis
    server = util.get_server(user_id, server_id, for_update=True,
20 dec501fa Christos Stavrakakis
                             exception=faults.BadRequest)
21 dec501fa Christos Stavrakakis
22 dec501fa Christos Stavrakakis
    # Assert that not more than one source are used
23 dec501fa Christos Stavrakakis
    sources = filter(lambda x: x is not None,
24 dec501fa Christos Stavrakakis
                     [source_volume_id, source_snapshot_id, source_image_id])
25 dec501fa Christos Stavrakakis
    if len(sources) > 1:
26 dec501fa Christos Stavrakakis
        raise faults.BadRequest("Volume can not have more than one source!")
27 dec501fa Christos Stavrakakis
28 5f90e24c Christos Stavrakakis
    # Only ext_ disk template supports cloning from another source
29 5f90e24c Christos Stavrakakis
    disk_template = server.flavor.disk_template
30 5f90e24c Christos Stavrakakis
    if not disk_template.startswith("ext_") and sources:
31 5f90e24c Christos Stavrakakis
        msg = ("Volumes of '%s' disk template cannot have a source" %
32 5f90e24c Christos Stavrakakis
               disk_template)
33 5f90e24c Christos Stavrakakis
        raise faults.BadRequest(msg)
34 5f90e24c Christos Stavrakakis
35 5f90e24c Christos Stavrakakis
    origin = None
36 5f90e24c Christos Stavrakakis
    source = None
37 dec501fa Christos Stavrakakis
    if source_volume_id is not None:
38 dec501fa Christos Stavrakakis
        source_volume = util.get_volume(user_id, source_volume_id,
39 dec501fa Christos Stavrakakis
                                        for_update=True,
40 dec501fa Christos Stavrakakis
                                        exception=faults.BadRequest)
41 5f90e24c Christos Stavrakakis
        # Check that volume is ready to be snapshotted
42 5f90e24c Christos Stavrakakis
        if source_volume.status != "AVAILABLE":
43 5f90e24c Christos Stavrakakis
            msg = ("Cannot take a snapshot while snapshot is in '%s' state"
44 5f90e24c Christos Stavrakakis
                   % source_volume.status)
45 5f90e24c Christos Stavrakakis
            raise faults.BadRequest(msg)
46 5f90e24c Christos Stavrakakis
        source = Volume.SOURCE_VOLUME_PREFIX + str(source_volume_id)
47 5f90e24c Christos Stavrakakis
        origin = source_volume.backend_volume_uuid
48 5f90e24c Christos Stavrakakis
    elif source_snapshot_id is not None:
49 dec501fa Christos Stavrakakis
        source_snapshot = util.get_snapshot(user_id, source_snapshot_id,
50 dec501fa Christos Stavrakakis
                                            exception=faults.BadRequest)
51 5f90e24c Christos Stavrakakis
        # TODO: Check the state of the snapshot!!
52 5f90e24c Christos Stavrakakis
        origin = source_snapshot["checksum"]
53 5f90e24c Christos Stavrakakis
        source = Volume.SOURCE_SNAPSHOT_PREFIX + str(source_snapshot_id)
54 5f90e24c Christos Stavrakakis
    elif source_image_id is not None:
55 dec501fa Christos Stavrakakis
        source_image = util.get_image(user_id, source_image_id,
56 dec501fa Christos Stavrakakis
                                      exception=faults.BadRequest)
57 5f90e24c Christos Stavrakakis
        origin = source_image["checksum"]
58 5f90e24c Christos Stavrakakis
        source = Volume.SOURCE_IMAGE_PREFIX + str(source_image_id)
59 dec501fa Christos Stavrakakis
60 dec501fa Christos Stavrakakis
    volume = Volume.objects.create(userid=user_id,
61 dec501fa Christos Stavrakakis
                                   size=size,
62 dec501fa Christos Stavrakakis
                                   name=name,
63 dec501fa Christos Stavrakakis
                                   machine=server,
64 dec501fa Christos Stavrakakis
                                   description=description,
65 5f90e24c Christos Stavrakakis
                                   source=source,
66 5f90e24c Christos Stavrakakis
                                   origin=origin,
67 dec501fa Christos Stavrakakis
                                   #volume_type=volume_type,
68 dec501fa Christos Stavrakakis
                                   status="CREATING")
69 dec501fa Christos Stavrakakis
70 dec501fa Christos Stavrakakis
    if metadata is not None:
71 dec501fa Christos Stavrakakis
        for meta_key, meta_val in metadata.items():
72 dec501fa Christos Stavrakakis
            volume.metadata.create(key=meta_key, value=meta_val)
73 dec501fa Christos Stavrakakis
74 dec501fa Christos Stavrakakis
    # Create the disk in the backend
75 dec501fa Christos Stavrakakis
    volume.backendjobid = backend.attach_volume(server, volume)
76 dec501fa Christos Stavrakakis
    volume.save()
77 dec501fa Christos Stavrakakis
78 dec501fa Christos Stavrakakis
    return volume
79 dec501fa Christos Stavrakakis
80 dec501fa Christos Stavrakakis
81 dec501fa Christos Stavrakakis
@transaction.commit_on_success
82 dec501fa Christos Stavrakakis
def delete(volume):
83 5f90e24c Christos Stavrakakis
    """Delete a Volume"""
84 5f90e24c Christos Stavrakakis
    # A volume is deleted by detaching it from the server that is attached.
85 5f90e24c Christos Stavrakakis
    # Deleting a detached volume is not implemented.
86 5f90e24c Christos Stavrakakis
    if volume.index == 0:
87 5f90e24c Christos Stavrakakis
        raise faults.BadRequest("Cannot detach the root volume of a server")
88 dec501fa Christos Stavrakakis
89 5f90e24c Christos Stavrakakis
    if volume.machine_id is not None:
90 5f90e24c Christos Stavrakakis
        volume.backendjobid = backend.detach_volume(volume.machine, volume)
91 5f90e24c Christos Stavrakakis
        log.info("Detach volume '%s' from server '%s', job: %s",
92 5f90e24c Christos Stavrakakis
                 volume.id, volume.machine_id, volume.backendjobid)
93 5f90e24c Christos Stavrakakis
    else:
94 5f90e24c Christos Stavrakakis
        raise faults.BadRequest("Cannot delete a detached volume")
95 dec501fa Christos Stavrakakis
96 dec501fa Christos Stavrakakis
    return volume
97 dec501fa Christos Stavrakakis
98 dec501fa Christos Stavrakakis
99 dec501fa Christos Stavrakakis
@transaction.commit_on_success
100 dec501fa Christos Stavrakakis
def rename(volume, new_name):
101 dec501fa Christos Stavrakakis
    volume.name = new_name
102 dec501fa Christos Stavrakakis
    volume.save()
103 dec501fa Christos Stavrakakis
    return volume
104 dec501fa Christos Stavrakakis
105 dec501fa Christos Stavrakakis
106 dec501fa Christos Stavrakakis
@transaction.commit_on_success
107 dec501fa Christos Stavrakakis
def update_description(volume, new_description):
108 dec501fa Christos Stavrakakis
    volume.description = new_description
109 dec501fa Christos Stavrakakis
    volume.save()
110 dec501fa Christos Stavrakakis
    return volume