~rlane/nova/lp773690

« back to all changes in this revision

Viewing changes to nova/image/service.py

  • Committer: rlane at wikimedia
  • Date: 2011-04-29 22:30:40 UTC
  • mfrom: (382.1.655 nova)
  • Revision ID: rlane@wikimedia.org-20110429223040-i0x3ds9eqwrabyru
MergeĀ fromĀ trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
 
22
22
class BaseImageService(object):
23
 
    """Base class for providing image search and retrieval services
 
23
    """Base class for providing image search and retrieval services.
24
24
 
25
25
    ImageService exposes two concepts of metadata:
26
26
 
35
35
    This means that ImageServices will return BASE_IMAGE_ATTRS as keys in the
36
36
    metadata dict, all other attributes will be returned as keys in the nested
37
37
    'properties' dict.
 
38
 
38
39
    """
 
40
 
39
41
    BASE_IMAGE_ATTRS = ['id', 'name', 'created_at', 'updated_at',
40
42
                        'deleted_at', 'deleted', 'status', 'is_public']
41
43
 
45
47
    SERVICE_IMAGE_ATTRS = []
46
48
 
47
49
    def index(self, context):
48
 
        """
49
 
        Returns a sequence of mappings of id and name information about
50
 
        images.
 
50
        """List images.
51
51
 
52
 
        :rtype: array
53
 
        :retval: a sequence of mappings with the following signature
54
 
                    {'id': opaque id of image, 'name': name of image}
 
52
        :returns: a sequence of mappings with the following signature
 
53
                  {'id': opaque id of image, 'name': name of image}
55
54
 
56
55
        """
57
56
        raise NotImplementedError
58
57
 
59
58
    def detail(self, context):
60
 
        """
61
 
        Returns a sequence of mappings of detailed information about images.
 
59
        """Detailed information about an images.
62
60
 
63
 
        :rtype: array
64
 
        :retval: a sequence of mappings with the following signature
 
61
        :returns: a sequence of mappings with the following signature
65
62
                    {'id': opaque id of image,
66
63
                     'name': name of image,
67
64
                     'created_at': creation datetime object,
77
74
        NotImplementedError, in which case Nova will emulate this method
78
75
        with repeated calls to show() for each image received from the
79
76
        index() method.
 
77
 
80
78
        """
81
79
        raise NotImplementedError
82
80
 
83
81
    def show(self, context, image_id):
84
 
        """
85
 
        Returns a dict containing image metadata for the given opaque image id.
86
 
 
87
 
        :retval a mapping with the following signature:
88
 
 
 
82
        """Detailed information about an image.
 
83
 
 
84
        :returns: a mapping with the following signature:
89
85
            {'id': opaque id of image,
90
86
             'name': name of image,
91
87
             'created_at': creation datetime object,
96
92
             'is_public': boolean indicating if image is public
97
93
             }, ...
98
94
 
99
 
        :raises NotFound if the image does not exist
 
95
        :raises: NotFound if the image does not exist
 
96
 
100
97
        """
101
98
        raise NotImplementedError
102
99
 
103
100
    def get(self, context, data):
104
 
        """
105
 
        Returns a dict containing image metadata and writes image data to data.
 
101
        """Get an image.
106
102
 
107
103
        :param data: a file-like object to hold binary image data
 
104
        :returns: a dict containing image metadata, writes image data to data.
 
105
        :raises: NotFound if the image does not exist
108
106
 
109
 
        :raises NotFound if the image does not exist
110
107
        """
111
108
        raise NotImplementedError
112
109
 
113
110
    def create(self, context, metadata, data=None):
114
 
        """
115
 
        Store the image metadata and data and return the new image metadata.
 
111
        """Store the image metadata and data.
116
112
 
117
 
        :raises AlreadyExists if the image already exist.
 
113
        :returns: the new image metadata.
 
114
        :raises: AlreadyExists if the image already exist.
118
115
 
119
116
        """
120
117
        raise NotImplementedError
121
118
 
122
119
    def update(self, context, image_id, metadata, data=None):
123
 
        """Update the given image metadata and data and return the metadata
 
120
        """Update the given image metadata and data and return the metadata.
124
121
 
125
 
        :raises NotFound if the image does not exist.
 
122
        :raises: NotFound if the image does not exist.
126
123
 
127
124
        """
128
125
        raise NotImplementedError
129
126
 
130
127
    def delete(self, context, image_id):
131
 
        """
132
 
        Delete the given image.
 
128
        """Delete the given image.
133
129
 
134
 
        :raises NotFound if the image does not exist.
 
130
        :raises: NotFound if the image does not exist.
135
131
 
136
132
        """
137
133
        raise NotImplementedError
138
134
 
139
135
    @staticmethod
140
136
    def _is_image_available(context, image_meta):
141
 
        """
 
137
        """Check image availability.
 
138
 
142
139
        Images are always available if they are public or if the user is an
143
140
        admin.
144
141
 
145
142
        Otherwise, we filter by project_id (if present) and then fall-back to
146
143
        images owned by user.
 
144
 
147
145
        """
148
146
        # FIXME(sirp): We should be filtering by user_id on the Glance side
149
147
        # for security; however, we can't do that until we get authn/authz
169
167
 
170
168
        This is used by subclasses to expose only a metadata dictionary that
171
169
        is the same across ImageService implementations.
 
170
 
172
171
        """
173
172
        return cls._propertify_metadata(metadata, cls.BASE_IMAGE_ATTRS)
174
173
 
175
174
    @classmethod
176
175
    def _translate_to_service(cls, metadata):
177
 
        """Return a metadata dictionary that is usable by the ImageService
178
 
        subclass.
 
176
        """Return a metadata dict that is usable by the ImageService subclass.
179
177
 
180
178
        As an example, Glance has additional attributes (like 'location'); the
181
179
        BaseImageService considers these properties, but we need to translate
182
180
        these back to first-class attrs for sending to Glance. This method
183
181
        handles this by allowing you to specify the attributes an ImageService
184
182
        considers first-class.
 
183
 
185
184
        """
186
185
        if not cls.SERVICE_IMAGE_ATTRS:
187
 
            raise NotImplementedError(_("Cannot use this without specifying "
188
 
                                        "SERVICE_IMAGE_ATTRS for subclass"))
 
186
            raise NotImplementedError(_('Cannot use this without specifying '
 
187
                                        'SERVICE_IMAGE_ATTRS for subclass'))
189
188
        return cls._propertify_metadata(metadata, cls.SERVICE_IMAGE_ATTRS)
190
189
 
191
190
    @staticmethod
192
191
    def _propertify_metadata(metadata, keys):
193
 
        """Return a dict with any unrecognized keys placed in the nested
194
 
        'properties' dict.
 
192
        """Move unknown keys to a nested 'properties' dict.
 
193
 
 
194
        :returns: a new dict with the keys moved.
 
195
 
195
196
        """
196
197
        flattened = utils.flatten_dict(metadata)
197
198
        attributes, properties = utils.partition_dict(flattened, keys)