Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / volume / snapshots.py @ 19b2c29d

History | View | Annotate | Download (3.3 kB)

1 79a1e9bd Christos Stavrakakis
import datetime
2 79a1e9bd Christos Stavrakakis
from django.utils import simplejson as json
3 79a1e9bd Christos Stavrakakis
from django.db import transaction
4 79a1e9bd Christos Stavrakakis
from snf_django.lib.api import faults
5 79a1e9bd Christos Stavrakakis
from snf_django.lib.api.utils import isoformat
6 79a1e9bd Christos Stavrakakis
from synnefo.plankton.utils import image_backend
7 79a1e9bd Christos Stavrakakis
from synnefo.logic import backend
8 79a1e9bd Christos Stavrakakis
from synnefo.volume import util
9 79a1e9bd Christos Stavrakakis
10 79a1e9bd Christos Stavrakakis
SNAPSHOTS_CONTAINER = "snapshots"
11 79a1e9bd Christos Stavrakakis
SNAPSHOTS_DOMAIN = "plankton"
12 79a1e9bd Christos Stavrakakis
SNAPSHOTS_PREFIX = "plankton:"
13 79a1e9bd Christos Stavrakakis
SNAPSHOTS_TYPE = "application/octet-stream"
14 79a1e9bd Christos Stavrakakis
SNAPSHOTS_MAPFILE_PREFIX = "archip:"
15 79a1e9bd Christos Stavrakakis
16 79a1e9bd Christos Stavrakakis
17 79a1e9bd Christos Stavrakakis
@transaction.commit_on_success
18 79a1e9bd Christos Stavrakakis
def create(user_id, volume, name, description, metadata, force=False):
19 79a1e9bd Christos Stavrakakis
20 79a1e9bd Christos Stavrakakis
    if volume.machine is None:
21 79a1e9bd Christos Stavrakakis
        raise faults.BadRequest("Can not snapshot detached volume!")
22 79a1e9bd Christos Stavrakakis
23 8e057ed0 Christos Stavrakakis
    flavor = volume.machine.flavor
24 8e057ed0 Christos Stavrakakis
    if not flavor.disk_template.startswith("ext_"):
25 8e057ed0 Christos Stavrakakis
        msg = ("Snapshots are supported only for volumes of ext_*"
26 8e057ed0 Christos Stavrakakis
               " disk template")
27 8e057ed0 Christos Stavrakakis
        raise faults.BadRequest(msg)
28 8e057ed0 Christos Stavrakakis
29 79a1e9bd Christos Stavrakakis
    volume.snapshot_counter += 1
30 79a1e9bd Christos Stavrakakis
    volume.save()
31 4944a1f8 Christos Stavrakakis
    transaction.commit()
32 79a1e9bd Christos Stavrakakis
33 79a1e9bd Christos Stavrakakis
    snapshot_metadata = {}
34 4944a1f8 Christos Stavrakakis
    snapshot_metadata[SNAPSHOTS_PREFIX + "name"] = name
35 79a1e9bd Christos Stavrakakis
    snapshot_metadata[SNAPSHOTS_PREFIX + "description"] = description
36 79a1e9bd Christos Stavrakakis
    snapshot_metadata[SNAPSHOTS_PREFIX + "metadata"] = json.dumps(metadata)
37 79a1e9bd Christos Stavrakakis
    snapshot_metadata[SNAPSHOTS_PREFIX + "volume_id"] = volume.id
38 79a1e9bd Christos Stavrakakis
    snapshot_metadata[SNAPSHOTS_PREFIX + "status"] = "CREATING"
39 79a1e9bd Christos Stavrakakis
    #XXX: just to work
40 79a1e9bd Christos Stavrakakis
    snapshot_metadata[SNAPSHOTS_PREFIX + "is_snapshot"] = True
41 4944a1f8 Christos Stavrakakis
    #XXX: for images
42 4944a1f8 Christos Stavrakakis
    snapshot_metadata[SNAPSHOTS_PREFIX + "store"] = "pithos"
43 4944a1f8 Christos Stavrakakis
    snapshot_metadata[SNAPSHOTS_PREFIX + "disk_format"] = "diskdump"
44 4944a1f8 Christos Stavrakakis
    snapshot_metadata[SNAPSHOTS_PREFIX + "default_container_format"] = "bare"
45 4944a1f8 Christos Stavrakakis
    # XXX: Hack-ish way to clone the metadata
46 4944a1f8 Christos Stavrakakis
    image_properties = {"EXCLUDE_ALL_TASKS": "yes",
47 4944a1f8 Christos Stavrakakis
                        "description": description}
48 4944a1f8 Christos Stavrakakis
    vm_metadata = dict(volume.machine.metadata.values_list("meta_key", "meta_value"))
49 4944a1f8 Christos Stavrakakis
    for key in ["OS", "users"]:
50 4944a1f8 Christos Stavrakakis
        val = vm_metadata.get(key)
51 4944a1f8 Christos Stavrakakis
        if val is not None:
52 4944a1f8 Christos Stavrakakis
            image_properties[key] = val
53 4944a1f8 Christos Stavrakakis
    snapshot_metadata[SNAPSHOTS_PREFIX + "properties"] = json.dumps(image_properties)
54 79a1e9bd Christos Stavrakakis
55 79a1e9bd Christos Stavrakakis
    snapshot_name = generate_snapshot_name(volume)
56 79a1e9bd Christos Stavrakakis
    mapfile = SNAPSHOTS_MAPFILE_PREFIX + snapshot_name
57 79a1e9bd Christos Stavrakakis
58 4944a1f8 Christos Stavrakakis
    size = volume.size << 30
59 79a1e9bd Christos Stavrakakis
    with image_backend(user_id) as pithos_backend:
60 79a1e9bd Christos Stavrakakis
        # move this to plankton backend
61 79a1e9bd Christos Stavrakakis
        snapshot_uuid = pithos_backend.backend.register_object_map(
62 79a1e9bd Christos Stavrakakis
            user=user_id,
63 79a1e9bd Christos Stavrakakis
            account=user_id,
64 79a1e9bd Christos Stavrakakis
            container=SNAPSHOTS_CONTAINER,
65 4944a1f8 Christos Stavrakakis
            name=snapshot_name,
66 4944a1f8 Christos Stavrakakis
            size=size,
67 4944a1f8 Christos Stavrakakis
            domain=SNAPSHOTS_DOMAIN,
68 79a1e9bd Christos Stavrakakis
            type=SNAPSHOTS_TYPE,
69 79a1e9bd Christos Stavrakakis
            mapfile=mapfile,
70 79a1e9bd Christos Stavrakakis
            meta=snapshot_metadata,
71 4944a1f8 Christos Stavrakakis
            replace_meta=True,
72 79a1e9bd Christos Stavrakakis
            permissions=None)
73 79a1e9bd Christos Stavrakakis
            #checksum=None,
74 79a1e9bd Christos Stavrakakis
75 4944a1f8 Christos Stavrakakis
    backend.snapshot_instance(volume.machine, snapshot_name=snapshot_name)
76 79a1e9bd Christos Stavrakakis
77 79a1e9bd Christos Stavrakakis
    snapshot = util.get_snapshot(user_id, snapshot_uuid)
78 79a1e9bd Christos Stavrakakis
79 79a1e9bd Christos Stavrakakis
    return snapshot
80 79a1e9bd Christos Stavrakakis
81 79a1e9bd Christos Stavrakakis
82 79a1e9bd Christos Stavrakakis
def generate_snapshot_name(volume):
83 79a1e9bd Christos Stavrakakis
    time = isoformat(datetime.datetime.now())
84 4944a1f8 Christos Stavrakakis
    return "snf-snapshot-of-volume-%s-%s" % (volume.id,
85 4944a1f8 Christos Stavrakakis
                                                volume.snapshot_counter)
86 79a1e9bd Christos Stavrakakis
87 79a1e9bd Christos Stavrakakis
88 79a1e9bd Christos Stavrakakis
@transaction.commit_on_success
89 79a1e9bd Christos Stavrakakis
def delete(snapshot):
90 79a1e9bd Christos Stavrakakis
    user_id = snapshot["owner"]
91 79a1e9bd Christos Stavrakakis
    with image_backend(user_id) as pithos_backend:
92 79a1e9bd Christos Stavrakakis
        pithos_backend.delete_snapshot(snapshot["uuid"])
93 79a1e9bd Christos Stavrakakis
    return snapshot