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 |