Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (3.1 kB)

1
import datetime
2
from django.utils import simplejson as json
3
from django.db import transaction
4
from snf_django.lib.api import faults
5
from snf_django.lib.api.utils import isoformat
6
from synnefo.plankton.utils import image_backend
7
from synnefo.logic import backend
8
from synnefo.volume import util
9

    
10
SNAPSHOTS_CONTAINER = "snapshots"
11
SNAPSHOTS_DOMAIN = "plankton"
12
SNAPSHOTS_PREFIX = "plankton:"
13
SNAPSHOTS_TYPE = "application/octet-stream"
14
SNAPSHOTS_MAPFILE_PREFIX = "archip:"
15

    
16

    
17
@transaction.commit_on_success
18
def create(user_id, volume, name, description, metadata, force=False):
19

    
20
    if volume.machine is None:
21
        raise faults.BadRequest("Can not snapshot detached volume!")
22

    
23
    volume.snapshot_counter += 1
24
    volume.save()
25
    transaction.commit()
26

    
27
    snapshot_metadata = {}
28
    snapshot_metadata[SNAPSHOTS_PREFIX + "name"] = name
29
    snapshot_metadata[SNAPSHOTS_PREFIX + "description"] = description
30
    snapshot_metadata[SNAPSHOTS_PREFIX + "metadata"] = json.dumps(metadata)
31
    snapshot_metadata[SNAPSHOTS_PREFIX + "volume_id"] = volume.id
32
    snapshot_metadata[SNAPSHOTS_PREFIX + "status"] = "CREATING"
33
    #XXX: just to work
34
    snapshot_metadata[SNAPSHOTS_PREFIX + "is_snapshot"] = True
35
    #XXX: for images
36
    snapshot_metadata[SNAPSHOTS_PREFIX + "store"] = "pithos"
37
    snapshot_metadata[SNAPSHOTS_PREFIX + "disk_format"] = "diskdump"
38
    snapshot_metadata[SNAPSHOTS_PREFIX + "default_container_format"] = "bare"
39
    # XXX: Hack-ish way to clone the metadata
40
    image_properties = {"EXCLUDE_ALL_TASKS": "yes",
41
                        "description": description}
42
    vm_metadata = dict(volume.machine.metadata.values_list("meta_key", "meta_value"))
43
    for key in ["OS", "users"]:
44
        val = vm_metadata.get(key)
45
        if val is not None:
46
            image_properties[key] = val
47
    snapshot_metadata[SNAPSHOTS_PREFIX + "properties"] = json.dumps(image_properties)
48

    
49
    snapshot_name = generate_snapshot_name(volume)
50
    mapfile = SNAPSHOTS_MAPFILE_PREFIX + snapshot_name
51

    
52
    size = volume.size << 30
53
    with image_backend(user_id) as pithos_backend:
54
        # move this to plankton backend
55
        snapshot_uuid = pithos_backend.backend.register_object_map(
56
            user=user_id,
57
            account=user_id,
58
            container=SNAPSHOTS_CONTAINER,
59
            name=snapshot_name,
60
            size=size,
61
            domain=SNAPSHOTS_DOMAIN,
62
            type=SNAPSHOTS_TYPE,
63
            mapfile=mapfile,
64
            meta=snapshot_metadata,
65
            replace_meta=True,
66
            permissions=None)
67
            #checksum=None,
68

    
69
    backend.snapshot_instance(volume.machine, snapshot_name=snapshot_name)
70

    
71
    snapshot = util.get_snapshot(user_id, snapshot_uuid)
72

    
73
    return snapshot
74

    
75

    
76
def generate_snapshot_name(volume):
77
    time = isoformat(datetime.datetime.now())
78
    return "snf-snapshot-of-volume-%s-%s" % (volume.id,
79
                                                volume.snapshot_counter)
80

    
81

    
82
@transaction.commit_on_success
83
def delete(snapshot):
84
    user_id = snapshot["owner"]
85
    with image_backend(user_id) as pithos_backend:
86
        pithos_backend.delete_snapshot(snapshot["uuid"])
87
    return snapshot