~blamar/nova/libvirt-cleanup-branch

« back to all changes in this revision

Viewing changes to nova/api/openstack/images.py

  • Committer: Brian Lamar
  • Date: 2011-07-01 16:07:15 UTC
  • mfrom: (1217.1.27 nova)
  • Revision ID: brian.lamar@rackspace.com-20110701160715-b5prxtlcfz2qotjx
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
import os.path
17
17
 
18
18
import webob.exc
 
19
from xml.dom import minidom
19
20
 
20
21
from nova import compute
21
22
from nova import exception
25
26
from nova import utils
26
27
from nova.api.openstack import common
27
28
from nova.api.openstack import faults
 
29
from nova.api.openstack import image_metadata
28
30
from nova.api.openstack.views import images as images_view
29
31
from nova.api.openstack import wsgi
30
32
 
90
92
        return webob.exc.HTTPNoContent()
91
93
 
92
94
    def create(self, req, body):
93
 
        """Snapshot a server instance and save the image.
 
95
        """Snapshot or backup a server instance and save the image.
 
96
 
 
97
        Images now have an `image_type` associated with them, which can be
 
98
        'snapshot' or the backup type, like 'daily' or 'weekly'.
 
99
 
 
100
        If the image_type is backup-like, then the rotation factor can be
 
101
        included and that will cause the oldest backups that exceed the
 
102
        rotation factor to be deleted.
94
103
 
95
104
        :param req: `wsgi.Request` object
96
105
        """
 
106
        def get_param(param):
 
107
            try:
 
108
                return body["image"][param]
 
109
            except KeyError:
 
110
                raise webob.exc.HTTPBadRequest(explanation="Missing required "
 
111
                        "param: %s" % param)
 
112
 
97
113
        context = req.environ['nova.context']
98
114
        content_type = req.get_content_type()
99
115
 
100
116
        if not body:
101
117
            raise webob.exc.HTTPBadRequest()
102
118
 
 
119
        image_type = body["image"].get("image_type", "snapshot")
 
120
 
103
121
        try:
104
122
            server_id = self._server_id_from_req(req, body)
105
 
            image_name = body["image"]["name"]
106
123
        except KeyError:
107
124
            raise webob.exc.HTTPBadRequest()
108
125
 
 
126
        image_name = get_param("name")
109
127
        props = self._get_extra_properties(req, body)
110
128
 
111
 
        image = self._compute_service.snapshot(context, server_id,
112
 
                                               image_name, props)
 
129
        if image_type == "snapshot":
 
130
            image = self._compute_service.snapshot(
 
131
                        context, server_id, image_name,
 
132
                        extra_properties=props)
 
133
        elif image_type == "backup":
 
134
            # NOTE(sirp): Unlike snapshot, backup is not a customer facing
 
135
            # API call; rather, it's used by the internal backup scheduler
 
136
            if not FLAGS.allow_admin_api:
 
137
                raise webob.exc.HTTPBadRequest(
 
138
                        explanation="Admin API Required")
 
139
 
 
140
            backup_type = get_param("backup_type")
 
141
            rotation = int(get_param("rotation"))
 
142
 
 
143
            image = self._compute_service.backup(
 
144
                        context, server_id, image_name,
 
145
                        backup_type, rotation, extra_properties=props)
 
146
        else:
 
147
            LOG.error(_("Invalid image_type '%s' passed") % image_type)
 
148
            raise webob.exc.HTTPBadRequest(explanation="Invalue image_type: "
 
149
                   "%s" % image_type)
 
150
 
113
151
        return dict(image=self.get_builder(req).build(image, detail=True))
114
152
 
115
153
    def get_builder(self, request):
116
154
        """Indicates that you must use a Controller subclass."""
117
 
        raise NotImplementedError
 
155
        raise NotImplementedError()
118
156
 
119
157
    def _server_id_from_req(self, req, data):
120
158
        raise NotImplementedError()
181
219
        """
182
220
        context = req.environ['nova.context']
183
221
        filters = self._get_filters(req)
184
 
        (marker, limit) = common.get_pagination_params(req)
185
 
        images = self._image_service.index(
186
 
            context, filters=filters, marker=marker, limit=limit)
 
222
        page_params = common.get_pagination_params(req)
 
223
        images = self._image_service.index(context, filters=filters,
 
224
                                           **page_params)
187
225
        builder = self.get_builder(req).build
188
226
        return dict(images=[builder(image, detail=False) for image in images])
189
227
 
195
233
        """
196
234
        context = req.environ['nova.context']
197
235
        filters = self._get_filters(req)
198
 
        (marker, limit) = common.get_pagination_params(req)
199
 
        images = self._image_service.detail(
200
 
            context, filters=filters, marker=marker, limit=limit)
 
236
        page_params = common.get_pagination_params(req)
 
237
        images = self._image_service.detail(context, filters=filters,
 
238
                                            **page_params)
201
239
        builder = self.get_builder(req).build
202
240
        return dict(images=[builder(image, detail=True) for image in images])
203
241
 
224
262
        return {'instance_ref': server_ref}
225
263
 
226
264
 
 
265
class ImageXMLSerializer(wsgi.XMLDictSerializer):
 
266
 
 
267
    metadata = {
 
268
        "attributes": {
 
269
            "image": ["id", "name", "updated", "created", "status",
 
270
                      "serverId", "progress", "serverRef"],
 
271
            "link": ["rel", "type", "href"],
 
272
        },
 
273
    }
 
274
 
 
275
    xmlns = wsgi.XMLNS_V11
 
276
 
 
277
    def __init__(self):
 
278
        self.metadata_serializer = image_metadata.ImageMetadataXMLSerializer()
 
279
 
 
280
    def _image_to_xml(self, xml_doc, image):
 
281
        try:
 
282
            metadata = image.pop('metadata').items()
 
283
        except Exception:
 
284
            LOG.debug(_("Image object missing metadata attribute"))
 
285
            metadata = {}
 
286
 
 
287
        node = self._to_xml_node(xml_doc, self.metadata, 'image', image)
 
288
        metadata_node = self.metadata_serializer.meta_list_to_xml(xml_doc,
 
289
                                                                  metadata)
 
290
        node.appendChild(metadata_node)
 
291
        return node
 
292
 
 
293
    def _image_list_to_xml(self, xml_doc, images):
 
294
        container_node = xml_doc.createElement('images')
 
295
        for image in images:
 
296
            item_node = self._image_to_xml(xml_doc, image)
 
297
            container_node.appendChild(item_node)
 
298
        return container_node
 
299
 
 
300
    def _image_to_xml_string(self, image):
 
301
        xml_doc = minidom.Document()
 
302
        item_node = self._image_to_xml(xml_doc, image)
 
303
        self._add_xmlns(item_node)
 
304
        return item_node.toprettyxml(indent='    ')
 
305
 
 
306
    def _image_list_to_xml_string(self, images):
 
307
        xml_doc = minidom.Document()
 
308
        container_node = self._image_list_to_xml(xml_doc, images)
 
309
        self._add_xmlns(container_node)
 
310
        return container_node.toprettyxml(indent='    ')
 
311
 
 
312
    def detail(self, images_dict):
 
313
        return self._image_list_to_xml_string(images_dict['images'])
 
314
 
 
315
    def show(self, image_dict):
 
316
        return self._image_to_xml_string(image_dict['image'])
 
317
 
 
318
    def create(self, image_dict):
 
319
        return self._image_to_xml_string(image_dict['image'])
 
320
 
 
321
 
227
322
def create_resource(version='1.0'):
228
323
    controller = {
229
324
        '1.0': ControllerV10,
230
325
        '1.1': ControllerV11,
231
326
    }[version]()
232
327
 
233
 
    xmlns = {
234
 
        '1.0': wsgi.XMLNS_V10,
235
 
        '1.1': wsgi.XMLNS_V11,
 
328
    metadata = {
 
329
        "attributes": {
 
330
            "image": ["id", "name", "updated", "created", "status",
 
331
                      "serverId", "progress", "serverRef"],
 
332
            "link": ["rel", "type", "href"],
 
333
        },
 
334
    }
 
335
 
 
336
    xml_serializer = {
 
337
        '1.0': wsgi.XMLDictSerializer(metadata, wsgi.XMLNS_V10),
 
338
        '1.1': ImageXMLSerializer(),
236
339
    }[version]
237
340
 
238
 
    metadata = {
239
 
        "attributes": {
240
 
            "image": ["id", "name", "updated", "created", "status",
241
 
                      "serverId", "progress", "serverRef"],
242
 
            "link": ["rel", "type", "href"],
243
 
        },
244
 
    }
245
 
 
246
341
    serializers = {
247
 
        'application/xml': wsgi.XMLDictSerializer(xmlns=xmlns,
248
 
                                                  metadata=metadata),
 
342
        'application/xml': xml_serializer,
249
343
    }
250
344
 
251
345
    return wsgi.Resource(controller, serializers=serializers)