Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (4 kB)

1
import logging
2

    
3
from django.db import transaction
4
from synnefo.db.models import Volume
5
from snf_django.lib.api import faults
6
from synnefo.volume import util
7
from synnefo.logic import backend, servers
8

    
9
log = logging.getLogger(__name__)
10

    
11

    
12
@transaction.commit_on_success
13
def create(user_id, size, server_id, name=None, description=None,
14
           source_volume_id=None, source_snapshot_id=None,
15
           source_image_id=None, metadata=None):
16

    
17
    if server_id is None:
18
        raise faults.BadRequest("Volume must be attached to server")
19
    server = util.get_server(user_id, server_id, for_update=True,
20
                             exception=faults.BadRequest)
21

    
22
    # Assert that not more than one source are used
23
    sources = filter(lambda x: x is not None,
24
                     [source_volume_id, source_snapshot_id, source_image_id])
25
    if len(sources) > 1:
26
        raise faults.BadRequest("Volume can not have more than one source!")
27

    
28
    # Only ext_ disk template supports cloning from another source
29
    disk_template = server.flavor.disk_template
30
    if not disk_template.startswith("ext_") and sources:
31
        msg = ("Volumes of '%s' disk template cannot have a source" %
32
               disk_template)
33
        raise faults.BadRequest(msg)
34

    
35
    origin = None
36
    source = None
37
    if source_volume_id is not None:
38
        source_volume = util.get_volume(user_id, source_volume_id,
39
                                        for_update=True,
40
                                        exception=faults.BadRequest)
41
        # Check that volume is ready to be snapshotted
42
        if source_volume.status != "AVAILABLE":
43
            msg = ("Cannot take a snapshot while snapshot is in '%s' state"
44
                   % source_volume.status)
45
            raise faults.BadRequest(msg)
46
        source = Volume.prefix_source(source_volume_id, source_type="volume")
47
        origin = source_volume.backend_volume_uuid
48
    elif source_snapshot_id is not None:
49
        source_snapshot = util.get_snapshot(user_id, source_snapshot_id,
50
                                            exception=faults.BadRequest)
51
        # TODO: Check the state of the snapshot!!
52
        source = Volume.prefix_source(source_snapshot_id,
53
                                      source_type="snapshot")
54
        origin = source_snapshot["checksum"]
55
    elif source_image_id is not None:
56
        source_image = util.get_image(user_id, source_image_id,
57
                                      exception=faults.BadRequest)
58
        source = Volume.prefix_source(source_image_id, source_type="image")
59
        origin = source_image["checksum"]
60

    
61
    volume = Volume.objects.create(userid=user_id,
62
                                   size=size,
63
                                   name=name,
64
                                   machine=server,
65
                                   description=description,
66
                                   source=source,
67
                                   origin=origin,
68
                                   #volume_type=volume_type,
69
                                   status="CREATING")
70

    
71
    if metadata is not None:
72
        for meta_key, meta_val in metadata.items():
73
            volume.metadata.create(key=meta_key, value=meta_val)
74

    
75
    servers.attach_volume(server, volume)
76

    
77
    return volume
78

    
79

    
80
@transaction.commit_on_success
81
def delete(volume):
82
    """Delete a Volume"""
83
    # A volume is deleted by detaching it from the server that is attached.
84
    # Deleting a detached volume is not implemented.
85
    if volume.machine_id is not None:
86
        servers.detach_volume(volume.machine, volume)
87
        log.info("Detach volume '%s' from server '%s', job: %s",
88
                 volume.id, volume.machine_id, volume.backendjobid)
89
    else:
90
        raise faults.BadRequest("Cannot delete a detached volume")
91

    
92
    return volume
93

    
94

    
95
@transaction.commit_on_success
96
def rename(volume, new_name):
97
    volume.name = new_name
98
    volume.save()
99
    return volume
100

    
101

    
102
@transaction.commit_on_success
103
def update_description(volume, new_description):
104
    volume.description = new_description
105
    volume.save()
106
    return volume