Merge lp:~yolanda.robla/ubuntu/precise/glance/essex-sru into lp:ubuntu/precise-updates/glance
- Precise (12.04)
- essex-sru
- Merge into precise-updates
Status: | Superseded |
---|---|
Proposed branch: | lp:~yolanda.robla/ubuntu/precise/glance/essex-sru |
Merge into: | lp:ubuntu/precise-updates/glance |
Diff against target: |
1573 lines (+309/-1085) 21 files modified
.gitignore (+0/-11) .gitreview (+0/-5) .mailmap (+0/-19) .pc/CVE-2012-4573.patch/glance/api/v1/images.py (+0/-973) .pc/applied-patches (+0/-1) .pc/fix_migration_012_foreign_keys.patch/Authors (+1/-0) Authors (+1/-0) PKG-INFO (+15/-0) debian/changelog (+18/-0) debian/glance-api.logrotate (+1/-1) debian/glance-registry.logrotate (+1/-1) debian/patches/CVE-2012-4573.patch (+0/-35) debian/patches/fix_migration_012_foreign_keys.patch (+22/-26) debian/patches/series (+0/-1) glance.egg-info/PKG-INFO (+15/-0) glance.egg-info/SOURCES.txt (+217/-0) glance.egg-info/dependency_links.txt (+1/-0) glance.egg-info/top_level.txt (+1/-0) glance/vcsversion.py (+7/-0) setup.cfg (+8/-11) tools/pip-requires (+1/-1) |
To merge this branch: | bzr merge lp:~yolanda.robla/ubuntu/precise/glance/essex-sru |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Page | Needs Information | ||
Review via email: mp+140403@code.launchpad.net |
This proposal has been superseded by a proposal from 2012-12-18.
Commit message
Description of the change
- 53. By Yolanda Robla
-
removed skipping pep8 tests
fix typos in changelog
Unmerged revisions
- 53. By Yolanda Robla
-
removed skipping pep8 tests
fix typos in changelog - 52. By Yolanda Robla
-
[ Adam Gandelman ]
* debian/glance- {registry, api}.logrotate: Fix incorrect logfile
locations. (LP: #1049314)[ Yolanda Robla ]
* debian/rules: skipping pep8 tests to allow building[ Yolanda Robla Mota ]
* Resynchronize with stable/essex (efd7e75b):
- [efd7e75] Non-admin users can cause public glance images to be deleted
from the backend storage repository (CVE-2012-4573)
- [e6be061] Jenkins jobs fail because of incompatibility between sqlalchemy-
migrate and the newest sqlalchemy-0.8.0b1 (LP: #1073569)* Dropped patches, superseeded by snapshot:
- debian/patches/ CVE-2012- 4573.patch: [efd7e75] - 51. By Jamie Strandboge
-
* SECURITY UPDATE: deletion of arbitrary public and shared images via
authenticated user
- debian/patches/ CVE-2012- 4573.patch: adjust glance/ api/v1/ images. py to
ensure image is owned by user before delayed_deletion
- CVE-2012-4573
Preview Diff
1 | === removed file '.gitignore' |
2 | --- .gitignore 2012-06-24 03:14:33 +0000 |
3 | +++ .gitignore 1970-01-01 00:00:00 +0000 |
4 | @@ -1,11 +0,0 @@ |
5 | -*.pyc |
6 | -*.swp |
7 | -*.log |
8 | -.glance-venv |
9 | -.venv |
10 | -.tox |
11 | -build |
12 | -dist |
13 | -glance.egg-info |
14 | -glance/vcsversion.py |
15 | -tests.sqlite |
16 | |
17 | === removed file '.gitreview' |
18 | --- .gitreview 2012-06-24 03:14:33 +0000 |
19 | +++ .gitreview 1970-01-01 00:00:00 +0000 |
20 | @@ -1,5 +0,0 @@ |
21 | -[gerrit] |
22 | -host=review.openstack.org |
23 | -port=29418 |
24 | -project=openstack/glance.git |
25 | -defaultbranch=stable/essex |
26 | |
27 | === removed file '.mailmap' |
28 | --- .mailmap 2012-06-24 03:14:33 +0000 |
29 | +++ .mailmap 1970-01-01 00:00:00 +0000 |
30 | @@ -1,19 +0,0 @@ |
31 | -# Format is: |
32 | -# <preferred e-mail> <other e-mail 1> |
33 | -# <preferred e-mail> <other e-mail 2> |
34 | -<adam.gandelman@canonical.com> <adamg@canonical.com> |
35 | -<brian.waldon@rackspace.com> <bcwaldon@gmail.com> |
36 | -<corywright@gmail.com> <cory.wright@rackspace.com> |
37 | -<dprince@redhat.com> <dan.prince@rackspace.com> |
38 | -<jsuh@isi.edu> <jsuh@bespin> |
39 | -<josh@jk0.org> <josh.kearney@rackspace.com> |
40 | -<rconradharris@gmail.com> <rick.harris@rackspace.com> |
41 | -<rconradharris@gmail.com> <rick@quasar.racklabs.com> |
42 | -<rick@openstack.org> <rclark@chat-blanc> |
43 | -<soren.hansen@rackspace.com> <soren@linux2go.dk> |
44 | -<soren.hansen@rackspace.com> <soren@openstack.org> |
45 | -<jeblair@hp.com> <corvus@gnu.org> |
46 | -<jeblair@hp.com> <james.blair@rackspace.com> |
47 | -<chris@pistoncloud.com> <chris@slicehost.com> |
48 | -<ken.pepple@gmail.com> <ken.pepple@rabbityard.com> |
49 | -<P@draigBrady.com> <pbrady@redhat.com> |
50 | |
51 | === removed directory '.pc/CVE-2012-4573.patch' |
52 | === removed directory '.pc/CVE-2012-4573.patch/glance' |
53 | === removed directory '.pc/CVE-2012-4573.patch/glance/api' |
54 | === removed directory '.pc/CVE-2012-4573.patch/glance/api/v1' |
55 | === removed file '.pc/CVE-2012-4573.patch/glance/api/v1/images.py' |
56 | --- .pc/CVE-2012-4573.patch/glance/api/v1/images.py 2012-11-08 07:19:39 +0000 |
57 | +++ .pc/CVE-2012-4573.patch/glance/api/v1/images.py 1970-01-01 00:00:00 +0000 |
58 | @@ -1,973 +0,0 @@ |
59 | -# vim: tabstop=4 shiftwidth=4 softtabstop=4 |
60 | - |
61 | -# Copyright 2010 OpenStack LLC. |
62 | -# All Rights Reserved. |
63 | -# |
64 | -# Licensed under the Apache License, Version 2.0 (the "License"); you may |
65 | -# not use this file except in compliance with the License. You may obtain |
66 | -# a copy of the License at |
67 | -# |
68 | -# http://www.apache.org/licenses/LICENSE-2.0 |
69 | -# |
70 | -# Unless required by applicable law or agreed to in writing, software |
71 | -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
72 | -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
73 | -# License for the specific language governing permissions and limitations |
74 | -# under the License. |
75 | - |
76 | -""" |
77 | -/images endpoint for Glance v1 API |
78 | -""" |
79 | - |
80 | -import errno |
81 | -import logging |
82 | -import sys |
83 | -import traceback |
84 | - |
85 | -from webob.exc import (HTTPError, |
86 | - HTTPNotFound, |
87 | - HTTPConflict, |
88 | - HTTPBadRequest, |
89 | - HTTPForbidden, |
90 | - HTTPRequestEntityTooLarge, |
91 | - HTTPServiceUnavailable, |
92 | - ) |
93 | - |
94 | -from glance.api import policy |
95 | -import glance.api.v1 |
96 | -from glance.api.v1 import controller |
97 | -from glance.api.v1 import filters |
98 | -from glance.common import cfg |
99 | -from glance.common import exception |
100 | -from glance.common import wsgi |
101 | -from glance.common import utils |
102 | -import glance.store |
103 | -import glance.store.filesystem |
104 | -import glance.store.http |
105 | -import glance.store.rbd |
106 | -import glance.store.s3 |
107 | -import glance.store.swift |
108 | -from glance.store import (get_from_backend, |
109 | - get_size_from_backend, |
110 | - schedule_delete_from_backend, |
111 | - get_store_from_location, |
112 | - get_store_from_scheme) |
113 | -from glance import registry |
114 | -from glance import notifier |
115 | - |
116 | - |
117 | -logger = logging.getLogger(__name__) |
118 | -SUPPORTED_PARAMS = glance.api.v1.SUPPORTED_PARAMS |
119 | -SUPPORTED_FILTERS = glance.api.v1.SUPPORTED_FILTERS |
120 | - |
121 | - |
122 | -# 1 PiB, which is a *huge* image by anyone's measure. This is just to protect |
123 | -# against client programming errors (or DoS attacks) in the image metadata. |
124 | -# We have a known limit of 1 << 63 in the database -- images.size is declared |
125 | -# as a BigInteger. |
126 | -IMAGE_SIZE_CAP = 1 << 50 |
127 | - |
128 | - |
129 | -class Controller(controller.BaseController): |
130 | - """ |
131 | - WSGI controller for images resource in Glance v1 API |
132 | - |
133 | - The images resource API is a RESTful web service for image data. The API |
134 | - is as follows:: |
135 | - |
136 | - GET /images -- Returns a set of brief metadata about images |
137 | - GET /images/detail -- Returns a set of detailed metadata about |
138 | - images |
139 | - HEAD /images/<ID> -- Return metadata about an image with id <ID> |
140 | - GET /images/<ID> -- Return image data for image with id <ID> |
141 | - POST /images -- Store image data and return metadata about the |
142 | - newly-stored image |
143 | - PUT /images/<ID> -- Update image metadata and/or upload image |
144 | - data for a previously-reserved image |
145 | - DELETE /images/<ID> -- Delete the image with id <ID> |
146 | - """ |
147 | - |
148 | - default_store_opt = cfg.StrOpt('default_store', default='file') |
149 | - |
150 | - def __init__(self, conf): |
151 | - self.conf = conf |
152 | - self.conf.register_opt(self.default_store_opt) |
153 | - glance.store.create_stores(conf) |
154 | - self.verify_store_or_exit(self.conf.default_store) |
155 | - self.notifier = notifier.Notifier(conf) |
156 | - registry.configure_registry_client(conf) |
157 | - self.policy = policy.Enforcer(conf) |
158 | - |
159 | - def _enforce(self, req, action): |
160 | - """Authorize an action against our policies""" |
161 | - try: |
162 | - self.policy.enforce(req.context, action, {}) |
163 | - except exception.Forbidden: |
164 | - raise HTTPForbidden() |
165 | - |
166 | - def index(self, req): |
167 | - """ |
168 | - Returns the following information for all public, available images: |
169 | - |
170 | - * id -- The opaque image identifier |
171 | - * name -- The name of the image |
172 | - * disk_format -- The disk image format |
173 | - * container_format -- The "container" format of the image |
174 | - * checksum -- MD5 checksum of the image data |
175 | - * size -- Size of image data in bytes |
176 | - |
177 | - :param req: The WSGI/Webob Request object |
178 | - :retval The response body is a mapping of the following form:: |
179 | - |
180 | - {'images': [ |
181 | - {'id': <ID>, |
182 | - 'name': <NAME>, |
183 | - 'disk_format': <DISK_FORMAT>, |
184 | - 'container_format': <DISK_FORMAT>, |
185 | - 'checksum': <CHECKSUM> |
186 | - 'size': <SIZE>}, ... |
187 | - ]} |
188 | - """ |
189 | - self._enforce(req, 'get_images') |
190 | - params = self._get_query_params(req) |
191 | - try: |
192 | - images = registry.get_images_list(req.context, **params) |
193 | - except exception.Invalid, e: |
194 | - raise HTTPBadRequest(explanation="%s" % e) |
195 | - |
196 | - return dict(images=images) |
197 | - |
198 | - def detail(self, req): |
199 | - """ |
200 | - Returns detailed information for all public, available images |
201 | - |
202 | - :param req: The WSGI/Webob Request object |
203 | - :retval The response body is a mapping of the following form:: |
204 | - |
205 | - {'images': [ |
206 | - {'id': <ID>, |
207 | - 'name': <NAME>, |
208 | - 'size': <SIZE>, |
209 | - 'disk_format': <DISK_FORMAT>, |
210 | - 'container_format': <CONTAINER_FORMAT>, |
211 | - 'checksum': <CHECKSUM>, |
212 | - 'min_disk': <MIN_DISK>, |
213 | - 'min_ram': <MIN_RAM>, |
214 | - 'store': <STORE>, |
215 | - 'status': <STATUS>, |
216 | - 'created_at': <TIMESTAMP>, |
217 | - 'updated_at': <TIMESTAMP>, |
218 | - 'deleted_at': <TIMESTAMP>|<NONE>, |
219 | - 'properties': {'distro': 'Ubuntu 10.04 LTS', ...}}, ... |
220 | - ]} |
221 | - """ |
222 | - self._enforce(req, 'get_images') |
223 | - params = self._get_query_params(req) |
224 | - try: |
225 | - images = registry.get_images_detail(req.context, **params) |
226 | - # Strip out the Location attribute. Temporary fix for |
227 | - # LP Bug #755916. This information is still coming back |
228 | - # from the registry, since the API server still needs access |
229 | - # to it, however we do not return this potential security |
230 | - # information to the API end user... |
231 | - for image in images: |
232 | - del image['location'] |
233 | - except exception.Invalid, e: |
234 | - raise HTTPBadRequest(explanation="%s" % e) |
235 | - return dict(images=images) |
236 | - |
237 | - def _get_query_params(self, req): |
238 | - """ |
239 | - Extracts necessary query params from request. |
240 | - |
241 | - :param req: the WSGI Request object |
242 | - :retval dict of parameters that can be used by registry client |
243 | - """ |
244 | - params = {'filters': self._get_filters(req)} |
245 | - |
246 | - for PARAM in SUPPORTED_PARAMS: |
247 | - if PARAM in req.params: |
248 | - params[PARAM] = req.params.get(PARAM) |
249 | - return params |
250 | - |
251 | - def _get_filters(self, req): |
252 | - """ |
253 | - Return a dictionary of query param filters from the request |
254 | - |
255 | - :param req: the Request object coming from the wsgi layer |
256 | - :retval a dict of key/value filters |
257 | - """ |
258 | - query_filters = {} |
259 | - for param in req.params: |
260 | - if param in SUPPORTED_FILTERS or param.startswith('property-'): |
261 | - query_filters[param] = req.params.get(param) |
262 | - if not filters.validate(param, query_filters[param]): |
263 | - raise HTTPBadRequest('Bad value passed to filter %s ' |
264 | - 'got %s' % (param, |
265 | - query_filters[param])) |
266 | - return query_filters |
267 | - |
268 | - def meta(self, req, id): |
269 | - """ |
270 | - Returns metadata about an image in the HTTP headers of the |
271 | - response object |
272 | - |
273 | - :param req: The WSGI/Webob Request object |
274 | - :param id: The opaque image identifier |
275 | - :retval similar to 'show' method but without image_data |
276 | - |
277 | - :raises HTTPNotFound if image metadata is not available to user |
278 | - """ |
279 | - self._enforce(req, 'get_image') |
280 | - image_meta = self.get_image_meta_or_404(req, id) |
281 | - del image_meta['location'] |
282 | - return { |
283 | - 'image_meta': image_meta |
284 | - } |
285 | - |
286 | - @staticmethod |
287 | - def _validate_source(source, req): |
288 | - """ |
289 | - External sources (as specified via the location or copy-from headers) |
290 | - are supported only over non-local store types, i.e. S3, Swift, HTTP. |
291 | - Note the absence of file:// for security reasons, see LP bug #942118. |
292 | - If the above constraint is violated, we reject with 400 "Bad Request". |
293 | - """ |
294 | - if source: |
295 | - for scheme in ['s3', 'swift', 'http']: |
296 | - if source.lower().startswith(scheme): |
297 | - return source |
298 | - msg = _("External sourcing not supported for store %s") % source |
299 | - logger.error(msg) |
300 | - raise HTTPBadRequest(msg, request=req, content_type="text/plain") |
301 | - |
302 | - @staticmethod |
303 | - def _copy_from(req): |
304 | - return req.headers.get('x-glance-api-copy-from') |
305 | - |
306 | - @staticmethod |
307 | - def _external_source(image_meta, req): |
308 | - source = image_meta.get('location', Controller._copy_from(req)) |
309 | - return Controller._validate_source(source, req) |
310 | - |
311 | - @staticmethod |
312 | - def _get_from_store(where): |
313 | - try: |
314 | - image_data, image_size = get_from_backend(where) |
315 | - except exception.NotFound, e: |
316 | - raise HTTPNotFound(explanation="%s" % e) |
317 | - image_size = int(image_size) if image_size else None |
318 | - return image_data, image_size |
319 | - |
320 | - def show(self, req, id): |
321 | - """ |
322 | - Returns an iterator that can be used to retrieve an image's |
323 | - data along with the image metadata. |
324 | - |
325 | - :param req: The WSGI/Webob Request object |
326 | - :param id: The opaque image identifier |
327 | - |
328 | - :raises HTTPNotFound if image is not available to user |
329 | - """ |
330 | - self._enforce(req, 'get_image') |
331 | - image_meta = self.get_active_image_meta_or_404(req, id) |
332 | - |
333 | - if image_meta.get('size') == 0: |
334 | - image_iterator = iter([]) |
335 | - else: |
336 | - image_iterator, size = self._get_from_store(image_meta['location']) |
337 | - image_meta['size'] = size or image_meta['size'] |
338 | - |
339 | - del image_meta['location'] |
340 | - return { |
341 | - 'image_iterator': image_iterator, |
342 | - 'image_meta': image_meta, |
343 | - } |
344 | - |
345 | - def _reserve(self, req, image_meta): |
346 | - """ |
347 | - Adds the image metadata to the registry and assigns |
348 | - an image identifier if one is not supplied in the request |
349 | - headers. Sets the image's status to `queued`. |
350 | - |
351 | - :param req: The WSGI/Webob Request object |
352 | - :param id: The opaque image identifier |
353 | - :param image_meta: The image metadata |
354 | - |
355 | - :raises HTTPConflict if image already exists |
356 | - :raises HTTPBadRequest if image metadata is not valid |
357 | - """ |
358 | - location = self._external_source(image_meta, req) |
359 | - |
360 | - image_meta['status'] = ('active' if image_meta.get('size') == 0 |
361 | - else 'queued') |
362 | - |
363 | - if location: |
364 | - store = get_store_from_location(location) |
365 | - # check the store exists before we hit the registry, but we |
366 | - # don't actually care what it is at this point |
367 | - self.get_store_or_400(req, store) |
368 | - |
369 | - # retrieve the image size from remote store (if not provided) |
370 | - image_meta['size'] = self._get_size(image_meta, location) |
371 | - else: |
372 | - # Ensure that the size attribute is set to zero for directly |
373 | - # uploadable images (if not provided). The size will be set |
374 | - # to a non-zero value during upload |
375 | - image_meta['size'] = image_meta.get('size', 0) |
376 | - |
377 | - try: |
378 | - image_meta = registry.add_image_metadata(req.context, image_meta) |
379 | - return image_meta |
380 | - except exception.Duplicate: |
381 | - msg = (_("An image with identifier %s already exists") |
382 | - % image_meta['id']) |
383 | - logger.error(msg) |
384 | - raise HTTPConflict(msg, request=req, content_type="text/plain") |
385 | - except exception.Invalid, e: |
386 | - msg = (_("Failed to reserve image. Got error: %(e)s") % locals()) |
387 | - for line in msg.split('\n'): |
388 | - logger.error(line) |
389 | - raise HTTPBadRequest(msg, request=req, content_type="text/plain") |
390 | - except exception.Forbidden: |
391 | - msg = _("Forbidden to reserve image.") |
392 | - logger.error(msg) |
393 | - raise HTTPForbidden(msg, request=req, content_type="text/plain") |
394 | - |
395 | - def _upload(self, req, image_meta): |
396 | - """ |
397 | - Uploads the payload of the request to a backend store in |
398 | - Glance. If the `x-image-meta-store` header is set, Glance |
399 | - will attempt to use that store, if not, Glance will use the |
400 | - store set by the flag `default_store`. |
401 | - |
402 | - :param req: The WSGI/Webob Request object |
403 | - :param image_meta: Mapping of metadata about image |
404 | - |
405 | - :raises HTTPConflict if image already exists |
406 | - :retval The location where the image was stored |
407 | - """ |
408 | - |
409 | - copy_from = self._copy_from(req) |
410 | - if copy_from: |
411 | - image_data, image_size = self._get_from_store(copy_from) |
412 | - image_meta['size'] = image_size or image_meta['size'] |
413 | - else: |
414 | - try: |
415 | - req.get_content_type('application/octet-stream') |
416 | - except exception.InvalidContentType: |
417 | - self._safe_kill(req, image_meta['id']) |
418 | - msg = _("Content-Type must be application/octet-stream") |
419 | - logger.error(msg) |
420 | - raise HTTPBadRequest(explanation=msg) |
421 | - |
422 | - image_data = req.body_file |
423 | - |
424 | - if req.content_length: |
425 | - image_size = int(req.content_length) |
426 | - elif 'x-image-meta-size' in req.headers: |
427 | - image_size = int(req.headers['x-image-meta-size']) |
428 | - else: |
429 | - logger.debug(_("Got request with no content-length and no " |
430 | - "x-image-meta-size header")) |
431 | - image_size = 0 |
432 | - |
433 | - store_name = req.headers.get('x-image-meta-store', |
434 | - self.conf.default_store) |
435 | - |
436 | - store = self.get_store_or_400(req, store_name) |
437 | - |
438 | - image_id = image_meta['id'] |
439 | - logger.debug(_("Setting image %s to status 'saving'"), image_id) |
440 | - registry.update_image_metadata(req.context, image_id, |
441 | - {'status': 'saving'}) |
442 | - try: |
443 | - logger.debug(_("Uploading image data for image %(image_id)s " |
444 | - "to %(store_name)s store"), locals()) |
445 | - |
446 | - if image_size > IMAGE_SIZE_CAP: |
447 | - max_image_size = IMAGE_SIZE_CAP |
448 | - msg = _("Denying attempt to upload image larger than " |
449 | - "%(max_image_size)d. Supplied image size was " |
450 | - "%(image_size)d") % locals() |
451 | - logger.warn(msg) |
452 | - raise HTTPBadRequest(msg, request=req) |
453 | - |
454 | - location, size, checksum = store.add(image_meta['id'], |
455 | - image_data, |
456 | - image_size) |
457 | - |
458 | - # Verify any supplied checksum value matches checksum |
459 | - # returned from store when adding image |
460 | - supplied_checksum = image_meta.get('checksum') |
461 | - if supplied_checksum and supplied_checksum != checksum: |
462 | - msg = _("Supplied checksum (%(supplied_checksum)s) and " |
463 | - "checksum generated from uploaded image " |
464 | - "(%(checksum)s) did not match. Setting image " |
465 | - "status to 'killed'.") % locals() |
466 | - logger.error(msg) |
467 | - self._safe_kill(req, image_id) |
468 | - raise HTTPBadRequest(msg, content_type="text/plain", |
469 | - request=req) |
470 | - |
471 | - # Update the database with the checksum returned |
472 | - # from the backend store |
473 | - logger.debug(_("Updating image %(image_id)s data. " |
474 | - "Checksum set to %(checksum)s, size set " |
475 | - "to %(size)d"), locals()) |
476 | - update_data = {'checksum': checksum, |
477 | - 'size': size} |
478 | - image_meta = registry.update_image_metadata(req.context, |
479 | - image_id, |
480 | - update_data) |
481 | - self.notifier.info('image.upload', image_meta) |
482 | - |
483 | - return location |
484 | - |
485 | - except exception.Duplicate, e: |
486 | - msg = _("Attempt to upload duplicate image: %s") % e |
487 | - logger.error(msg) |
488 | - self._safe_kill(req, image_id) |
489 | - self.notifier.error('image.upload', msg) |
490 | - raise HTTPConflict(msg, request=req) |
491 | - |
492 | - except exception.Forbidden, e: |
493 | - msg = _("Forbidden upload attempt: %s") % e |
494 | - logger.error(msg) |
495 | - self._safe_kill(req, image_id) |
496 | - self.notifier.error('image.upload', msg) |
497 | - raise HTTPForbidden(msg, request=req, content_type="text/plain") |
498 | - |
499 | - except exception.StorageFull, e: |
500 | - msg = _("Image storage media is full: %s") % e |
501 | - logger.error(msg) |
502 | - self._safe_kill(req, image_id) |
503 | - self.notifier.error('image.upload', msg) |
504 | - raise HTTPRequestEntityTooLarge(msg, request=req, |
505 | - content_type='text/plain') |
506 | - |
507 | - except exception.StorageWriteDenied, e: |
508 | - msg = _("Insufficient permissions on image storage media: %s") % e |
509 | - logger.error(msg) |
510 | - self._safe_kill(req, image_id) |
511 | - self.notifier.error('image.upload', msg) |
512 | - raise HTTPServiceUnavailable(msg, request=req, |
513 | - content_type='text/plain') |
514 | - |
515 | - except HTTPError, e: |
516 | - self._safe_kill(req, image_id) |
517 | - self.notifier.error('image.upload', e.explanation) |
518 | - raise |
519 | - |
520 | - except Exception, e: |
521 | - tb_info = traceback.format_exc() |
522 | - logger.error(tb_info) |
523 | - |
524 | - self._safe_kill(req, image_id) |
525 | - |
526 | - msg = _("Error uploading image: (%(class_name)s): " |
527 | - "%(exc)s") % ({'class_name': e.__class__.__name__, |
528 | - 'exc': str(e)}) |
529 | - |
530 | - self.notifier.error('image.upload', msg) |
531 | - raise HTTPBadRequest(msg, request=req) |
532 | - |
533 | - def _activate(self, req, image_id, location): |
534 | - """ |
535 | - Sets the image status to `active` and the image's location |
536 | - attribute. |
537 | - |
538 | - :param req: The WSGI/Webob Request object |
539 | - :param image_id: Opaque image identifier |
540 | - :param location: Location of where Glance stored this image |
541 | - """ |
542 | - image_meta = {} |
543 | - image_meta['location'] = location |
544 | - image_meta['status'] = 'active' |
545 | - |
546 | - try: |
547 | - return registry.update_image_metadata(req.context, |
548 | - image_id, |
549 | - image_meta) |
550 | - except exception.Invalid, e: |
551 | - msg = (_("Failed to activate image. Got error: %(e)s") |
552 | - % locals()) |
553 | - for line in msg.split('\n'): |
554 | - logger.error(line) |
555 | - self.notifier.error('image.update', msg) |
556 | - raise HTTPBadRequest(msg, request=req, content_type="text/plain") |
557 | - |
558 | - def _kill(self, req, image_id): |
559 | - """ |
560 | - Marks the image status to `killed`. |
561 | - |
562 | - :param req: The WSGI/Webob Request object |
563 | - :param image_id: Opaque image identifier |
564 | - """ |
565 | - registry.update_image_metadata(req.context, image_id, |
566 | - {'status': 'killed'}) |
567 | - |
568 | - def _safe_kill(self, req, image_id): |
569 | - """ |
570 | - Mark image killed without raising exceptions if it fails. |
571 | - |
572 | - Since _kill is meant to be called from exceptions handlers, it should |
573 | - not raise itself, rather it should just log its error. |
574 | - |
575 | - :param req: The WSGI/Webob Request object |
576 | - :param image_id: Opaque image identifier |
577 | - """ |
578 | - try: |
579 | - self._kill(req, image_id) |
580 | - except Exception, e: |
581 | - logger.error(_("Unable to kill image %(id)s: " |
582 | - "%(exc)s") % ({'id': image_id, |
583 | - 'exc': repr(e)})) |
584 | - |
585 | - def _upload_and_activate(self, req, image_meta): |
586 | - """ |
587 | - Safely uploads the image data in the request payload |
588 | - and activates the image in the registry after a successful |
589 | - upload. |
590 | - |
591 | - :param req: The WSGI/Webob Request object |
592 | - :param image_meta: Mapping of metadata about image |
593 | - |
594 | - :retval Mapping of updated image data |
595 | - """ |
596 | - image_id = image_meta['id'] |
597 | - # This is necessary because of a bug in Webob 1.0.2 - 1.0.7 |
598 | - # See: https://bitbucket.org/ianb/webob/ |
599 | - # issue/12/fix-for-issue-6-broke-chunked-transfer |
600 | - req.is_body_readable = True |
601 | - location = self._upload(req, image_meta) |
602 | - return self._activate(req, image_id, location) |
603 | - |
604 | - def _get_size(self, image_meta, location): |
605 | - # retrieve the image size from remote store (if not provided) |
606 | - return image_meta.get('size', 0) or get_size_from_backend(location) |
607 | - |
608 | - def _handle_source(self, req, image_id, image_meta, image_data): |
609 | - if image_data or self._copy_from(req): |
610 | - image_meta = self._upload_and_activate(req, image_meta) |
611 | - else: |
612 | - location = image_meta.get('location') |
613 | - if location: |
614 | - image_meta = self._activate(req, image_id, location) |
615 | - return image_meta |
616 | - |
617 | - def create(self, req, image_meta, image_data): |
618 | - """ |
619 | - Adds a new image to Glance. Four scenarios exist when creating an |
620 | - image: |
621 | - |
622 | - 1. If the image data is available directly for upload, create can be |
623 | - passed the image data as the request body and the metadata as the |
624 | - request headers. The image will initially be 'queued', during |
625 | - upload it will be in the 'saving' status, and then 'killed' or |
626 | - 'active' depending on whether the upload completed successfully. |
627 | - |
628 | - 2. If the image data exists somewhere else, you can upload indirectly |
629 | - from the external source using the x-glance-api-copy-from header. |
630 | - Once the image is uploaded, the external store is not subsequently |
631 | - consulted, i.e. the image content is served out from the configured |
632 | - glance image store. State transitions are as for option #1. |
633 | - |
634 | - 3. If the image data exists somewhere else, you can reference the |
635 | - source using the x-image-meta-location header. The image content |
636 | - will be served out from the external store, i.e. is never uploaded |
637 | - to the configured glance image store. |
638 | - |
639 | - 4. If the image data is not available yet, but you'd like reserve a |
640 | - spot for it, you can omit the data and a record will be created in |
641 | - the 'queued' state. This exists primarily to maintain backwards |
642 | - compatibility with OpenStack/Rackspace API semantics. |
643 | - |
644 | - The request body *must* be encoded as application/octet-stream, |
645 | - otherwise an HTTPBadRequest is returned. |
646 | - |
647 | - Upon a successful save of the image data and metadata, a response |
648 | - containing metadata about the image is returned, including its |
649 | - opaque identifier. |
650 | - |
651 | - :param req: The WSGI/Webob Request object |
652 | - :param image_meta: Mapping of metadata about image |
653 | - :param image_data: Actual image data that is to be stored |
654 | - |
655 | - :raises HTTPBadRequest if x-image-meta-location is missing |
656 | - and the request body is not application/octet-stream |
657 | - image data. |
658 | - """ |
659 | - self._enforce(req, 'add_image') |
660 | - if image_meta.get('is_public'): |
661 | - self._enforce(req, 'publicize_image') |
662 | - if req.context.read_only: |
663 | - msg = _("Read-only access") |
664 | - logger.debug(msg) |
665 | - raise HTTPForbidden(msg, request=req, |
666 | - content_type="text/plain") |
667 | - |
668 | - image_meta = self._reserve(req, image_meta) |
669 | - id = image_meta['id'] |
670 | - |
671 | - image_meta = self._handle_source(req, id, image_meta, image_data) |
672 | - |
673 | - # Prevent client from learning the location, as it |
674 | - # could contain security credentials |
675 | - image_meta.pop('location', None) |
676 | - |
677 | - return {'image_meta': image_meta} |
678 | - |
679 | - def update(self, req, id, image_meta, image_data): |
680 | - """ |
681 | - Updates an existing image with the registry. |
682 | - |
683 | - :param request: The WSGI/Webob Request object |
684 | - :param id: The opaque image identifier |
685 | - |
686 | - :retval Returns the updated image information as a mapping |
687 | - """ |
688 | - self._enforce(req, 'modify_image') |
689 | - if image_meta.get('is_public'): |
690 | - self._enforce(req, 'publicize_image') |
691 | - if req.context.read_only: |
692 | - msg = _("Read-only access") |
693 | - logger.debug(msg) |
694 | - raise HTTPForbidden(msg, request=req, |
695 | - content_type="text/plain") |
696 | - |
697 | - orig_image_meta = self.get_image_meta_or_404(req, id) |
698 | - orig_status = orig_image_meta['status'] |
699 | - |
700 | - # The default behaviour for a PUT /images/<IMAGE_ID> is to |
701 | - # override any properties that were previously set. This, however, |
702 | - # leads to a number of issues for the common use case where a caller |
703 | - # registers an image with some properties and then almost immediately |
704 | - # uploads an image file along with some more properties. Here, we |
705 | - # check for a special header value to be false in order to force |
706 | - # properties NOT to be purged. However we also disable purging of |
707 | - # properties if an image file is being uploaded... |
708 | - purge_props = req.headers.get('x-glance-registry-purge-props', True) |
709 | - purge_props = (utils.bool_from_string(purge_props) and |
710 | - image_data is None) |
711 | - |
712 | - if image_data is not None and orig_status != 'queued': |
713 | - raise HTTPConflict(_("Cannot upload to an unqueued image")) |
714 | - |
715 | - # Only allow the Location|Copy-From fields to be modified if the |
716 | - # image is in queued status, which indicates that the user called |
717 | - # POST /images but originally supply neither a Location|Copy-From |
718 | - # field NOR image data |
719 | - location = self._external_source(image_meta, req) |
720 | - reactivating = orig_status != 'queued' and location |
721 | - activating = orig_status == 'queued' and (location or image_data) |
722 | - |
723 | - if reactivating: |
724 | - msg = _("Attempted to update Location field for an image " |
725 | - "not in queued status.") |
726 | - raise HTTPBadRequest(msg, request=req, content_type="text/plain") |
727 | - |
728 | - try: |
729 | - if location: |
730 | - image_meta['size'] = self._get_size(image_meta, location) |
731 | - |
732 | - image_meta = registry.update_image_metadata(req.context, |
733 | - id, |
734 | - image_meta, |
735 | - purge_props) |
736 | - |
737 | - if activating: |
738 | - image_meta = self._handle_source(req, id, image_meta, |
739 | - image_data) |
740 | - except exception.Invalid, e: |
741 | - msg = (_("Failed to update image metadata. Got error: %(e)s") |
742 | - % locals()) |
743 | - for line in msg.split('\n'): |
744 | - logger.error(line) |
745 | - self.notifier.error('image.update', msg) |
746 | - raise HTTPBadRequest(msg, request=req, content_type="text/plain") |
747 | - except exception.NotFound, e: |
748 | - msg = ("Failed to find image to update: %(e)s" % locals()) |
749 | - for line in msg.split('\n'): |
750 | - logger.info(line) |
751 | - self.notifier.info('image.update', msg) |
752 | - raise HTTPNotFound(msg, request=req, content_type="text/plain") |
753 | - except exception.Forbidden, e: |
754 | - msg = ("Forbidden to update image: %(e)s" % locals()) |
755 | - for line in msg.split('\n'): |
756 | - logger.info(line) |
757 | - self.notifier.info('image.update', msg) |
758 | - raise HTTPForbidden(msg, request=req, content_type="text/plain") |
759 | - else: |
760 | - self.notifier.info('image.update', image_meta) |
761 | - |
762 | - # Prevent client from learning the location, as it |
763 | - # could contain security credentials |
764 | - image_meta.pop('location', None) |
765 | - |
766 | - return {'image_meta': image_meta} |
767 | - |
768 | - def delete(self, req, id): |
769 | - """ |
770 | - Deletes the image and all its chunks from the Glance |
771 | - |
772 | - :param req: The WSGI/Webob Request object |
773 | - :param id: The opaque image identifier |
774 | - |
775 | - :raises HttpBadRequest if image registry is invalid |
776 | - :raises HttpNotFound if image or any chunk is not available |
777 | - :raises HttpUnauthorized if image or any chunk is not |
778 | - deleteable by the requesting user |
779 | - """ |
780 | - self._enforce(req, 'delete_image') |
781 | - if req.context.read_only: |
782 | - msg = _("Read-only access") |
783 | - logger.debug(msg) |
784 | - raise HTTPForbidden(msg, request=req, |
785 | - content_type="text/plain") |
786 | - |
787 | - image = self.get_image_meta_or_404(req, id) |
788 | - if image['protected']: |
789 | - msg = _("Image is protected") |
790 | - logger.debug(msg) |
791 | - raise HTTPForbidden(msg, request=req, |
792 | - content_type="text/plain") |
793 | - |
794 | - # The image's location field may be None in the case |
795 | - # of a saving or queued image, therefore don't ask a backend |
796 | - # to delete the image if the backend doesn't yet store it. |
797 | - # See https://bugs.launchpad.net/glance/+bug/747799 |
798 | - try: |
799 | - if image['location']: |
800 | - schedule_delete_from_backend(image['location'], self.conf, |
801 | - req.context, id) |
802 | - registry.delete_image_metadata(req.context, id) |
803 | - except exception.NotFound, e: |
804 | - msg = ("Failed to find image to delete: %(e)s" % locals()) |
805 | - for line in msg.split('\n'): |
806 | - logger.info(line) |
807 | - self.notifier.info('image.delete', msg) |
808 | - raise HTTPNotFound(msg, request=req, content_type="text/plain") |
809 | - except exception.Forbidden, e: |
810 | - msg = ("Forbidden to delete image: %(e)s" % locals()) |
811 | - for line in msg.split('\n'): |
812 | - logger.info(line) |
813 | - self.notifier.info('image.delete', msg) |
814 | - raise HTTPForbidden(msg, request=req, content_type="text/plain") |
815 | - else: |
816 | - self.notifier.info('image.delete', id) |
817 | - |
818 | - def get_store_or_400(self, request, store_name): |
819 | - """ |
820 | - Grabs the storage backend for the supplied store name |
821 | - or raises an HTTPBadRequest (400) response |
822 | - |
823 | - :param request: The WSGI/Webob Request object |
824 | - :param store_name: The backend store name |
825 | - |
826 | - :raises HTTPNotFound if store does not exist |
827 | - """ |
828 | - try: |
829 | - return get_store_from_scheme(store_name) |
830 | - except exception.UnknownScheme: |
831 | - msg = (_("Requested store %s not available on this Glance server") |
832 | - % store_name) |
833 | - logger.error(msg) |
834 | - raise HTTPBadRequest(msg, request=request, |
835 | - content_type='text/plain') |
836 | - |
837 | - def verify_store_or_exit(self, store_name): |
838 | - """ |
839 | - Verifies availability of the storage backend for the |
840 | - given store name or exits |
841 | - |
842 | - :param store_name: The backend store name |
843 | - """ |
844 | - try: |
845 | - get_store_from_scheme(store_name) |
846 | - except exception.UnknownScheme: |
847 | - msg = (_("Default store %s not available on this Glance server\n") |
848 | - % store_name) |
849 | - logger.error(msg) |
850 | - # message on stderr will only be visible if started directly via |
851 | - # bin/glance-api, as opposed to being daemonized by glance-control |
852 | - sys.stderr.write(msg) |
853 | - sys.exit(255) |
854 | - |
855 | - |
856 | -class ImageDeserializer(wsgi.JSONRequestDeserializer): |
857 | - """Handles deserialization of specific controller method requests.""" |
858 | - |
859 | - def _deserialize(self, request): |
860 | - result = {} |
861 | - try: |
862 | - result['image_meta'] = utils.get_image_meta_from_headers(request) |
863 | - except exception.Invalid: |
864 | - image_size_str = request.headers['x-image-meta-size'] |
865 | - msg = _("Incoming image size of %s was not convertible to " |
866 | - "an integer.") % image_size_str |
867 | - raise HTTPBadRequest(msg, request=request) |
868 | - |
869 | - image_meta = result['image_meta'] |
870 | - if 'size' in image_meta: |
871 | - incoming_image_size = image_meta['size'] |
872 | - if incoming_image_size > IMAGE_SIZE_CAP: |
873 | - max_image_size = IMAGE_SIZE_CAP |
874 | - msg = _("Denying attempt to upload image larger than " |
875 | - "%(max_image_size)d. Supplied image size was " |
876 | - "%(incoming_image_size)d") % locals() |
877 | - logger.warn(msg) |
878 | - raise HTTPBadRequest(msg, request=request) |
879 | - |
880 | - data = request.body_file if self.has_body(request) else None |
881 | - result['image_data'] = data |
882 | - return result |
883 | - |
884 | - def create(self, request): |
885 | - return self._deserialize(request) |
886 | - |
887 | - def update(self, request): |
888 | - return self._deserialize(request) |
889 | - |
890 | - |
891 | -class ImageSerializer(wsgi.JSONResponseSerializer): |
892 | - """Handles serialization of specific controller method responses.""" |
893 | - |
894 | - def __init__(self, conf): |
895 | - self.conf = conf |
896 | - self.notifier = notifier.Notifier(conf) |
897 | - |
898 | - def _inject_location_header(self, response, image_meta): |
899 | - location = self._get_image_location(image_meta) |
900 | - response.headers['Location'] = location |
901 | - |
902 | - def _inject_checksum_header(self, response, image_meta): |
903 | - response.headers['ETag'] = image_meta['checksum'] |
904 | - |
905 | - def _inject_image_meta_headers(self, response, image_meta): |
906 | - """ |
907 | - Given a response and mapping of image metadata, injects |
908 | - the Response with a set of HTTP headers for the image |
909 | - metadata. Each main image metadata field is injected |
910 | - as a HTTP header with key 'x-image-meta-<FIELD>' except |
911 | - for the properties field, which is further broken out |
912 | - into a set of 'x-image-meta-property-<KEY>' headers |
913 | - |
914 | - :param response: The Webob Response object |
915 | - :param image_meta: Mapping of image metadata |
916 | - """ |
917 | - headers = utils.image_meta_to_http_headers(image_meta) |
918 | - |
919 | - for k, v in headers.items(): |
920 | - response.headers[k] = v |
921 | - |
922 | - def _get_image_location(self, image_meta): |
923 | - """Build a relative url to reach the image defined by image_meta.""" |
924 | - return "/v1/images/%s" % image_meta['id'] |
925 | - |
926 | - def meta(self, response, result): |
927 | - image_meta = result['image_meta'] |
928 | - self._inject_image_meta_headers(response, image_meta) |
929 | - self._inject_location_header(response, image_meta) |
930 | - self._inject_checksum_header(response, image_meta) |
931 | - return response |
932 | - |
933 | - def image_send_notification(self, bytes_written, expected_size, |
934 | - image_meta, request): |
935 | - """Send an image.send message to the notifier.""" |
936 | - try: |
937 | - context = request.context |
938 | - payload = { |
939 | - 'bytes_sent': bytes_written, |
940 | - 'image_id': image_meta['id'], |
941 | - 'owner_id': image_meta['owner'], |
942 | - 'receiver_tenant_id': context.tenant, |
943 | - 'receiver_user_id': context.user, |
944 | - 'destination_ip': request.remote_addr, |
945 | - } |
946 | - if bytes_written != expected_size: |
947 | - self.notifier.error('image.send', payload) |
948 | - else: |
949 | - self.notifier.info('image.send', payload) |
950 | - except Exception, err: |
951 | - msg = _("An error occurred during image.send" |
952 | - " notification: %(err)s") % locals() |
953 | - logger.error(msg) |
954 | - |
955 | - def show(self, response, result): |
956 | - image_meta = result['image_meta'] |
957 | - image_id = image_meta['id'] |
958 | - |
959 | - # We use a secondary iterator here to wrap the |
960 | - # iterator coming back from the store driver in |
961 | - # order to check for disconnections from the backend |
962 | - # storage connections and log an error if the size of |
963 | - # the transferred image is not the same as the expected |
964 | - # size of the image file. See LP Bug #882585. |
965 | - def checked_iter(image_id, expected_size, image_iter): |
966 | - bytes_written = 0 |
967 | - |
968 | - def notify_image_sent_hook(env): |
969 | - self.image_send_notification(bytes_written, expected_size, |
970 | - image_meta, response.request) |
971 | - |
972 | - # Add hook to process after response is fully sent |
973 | - if 'eventlet.posthooks' in response.request.environ: |
974 | - response.request.environ['eventlet.posthooks'].append( |
975 | - (notify_image_sent_hook, (), {})) |
976 | - |
977 | - try: |
978 | - for chunk in image_iter: |
979 | - yield chunk |
980 | - bytes_written += len(chunk) |
981 | - except Exception, err: |
982 | - msg = _("An error occurred reading from backend storage " |
983 | - "for image %(image_id): %(err)s") % locals() |
984 | - logger.error(msg) |
985 | - raise |
986 | - |
987 | - if expected_size != bytes_written: |
988 | - msg = _("Backend storage for image %(image_id)s " |
989 | - "disconnected after writing only %(bytes_written)d " |
990 | - "bytes") % locals() |
991 | - logger.error(msg) |
992 | - raise IOError(errno.EPIPE, _("Corrupt image download for " |
993 | - "image %(image_id)s") % locals()) |
994 | - |
995 | - image_iter = result['image_iterator'] |
996 | - # image_meta['size'] is a str |
997 | - expected_size = int(image_meta['size']) |
998 | - response.app_iter = checked_iter(image_id, expected_size, image_iter) |
999 | - # Using app_iter blanks content-length, so we set it here... |
1000 | - response.headers['Content-Length'] = image_meta['size'] |
1001 | - response.headers['Content-Type'] = 'application/octet-stream' |
1002 | - |
1003 | - self._inject_image_meta_headers(response, image_meta) |
1004 | - self._inject_location_header(response, image_meta) |
1005 | - self._inject_checksum_header(response, image_meta) |
1006 | - |
1007 | - return response |
1008 | - |
1009 | - def update(self, response, result): |
1010 | - image_meta = result['image_meta'] |
1011 | - response.body = self.to_json(dict(image=image_meta)) |
1012 | - response.headers['Content-Type'] = 'application/json' |
1013 | - self._inject_location_header(response, image_meta) |
1014 | - self._inject_checksum_header(response, image_meta) |
1015 | - return response |
1016 | - |
1017 | - def create(self, response, result): |
1018 | - image_meta = result['image_meta'] |
1019 | - response.status = 201 |
1020 | - response.headers['Content-Type'] = 'application/json' |
1021 | - response.body = self.to_json(dict(image=image_meta)) |
1022 | - self._inject_location_header(response, image_meta) |
1023 | - self._inject_checksum_header(response, image_meta) |
1024 | - return response |
1025 | - |
1026 | - |
1027 | -def create_resource(conf): |
1028 | - """Images resource factory method""" |
1029 | - deserializer = ImageDeserializer() |
1030 | - serializer = ImageSerializer(conf) |
1031 | - return wsgi.Resource(Controller(conf), deserializer, serializer) |
1032 | |
1033 | === modified file '.pc/applied-patches' |
1034 | --- .pc/applied-patches 2012-11-08 07:19:39 +0000 |
1035 | +++ .pc/applied-patches 2012-12-18 14:13:22 +0000 |
1036 | @@ -3,4 +3,3 @@ |
1037 | disable-network-for-docs.patch |
1038 | disable_db_table_auto_create.patch |
1039 | fix_migration_012_foreign_keys.patch |
1040 | -CVE-2012-4573.patch |
1041 | |
1042 | === modified file '.pc/fix_migration_012_foreign_keys.patch/Authors' |
1043 | --- .pc/fix_migration_012_foreign_keys.patch/Authors 2012-06-24 03:14:33 +0000 |
1044 | +++ .pc/fix_migration_012_foreign_keys.patch/Authors 2012-12-18 14:13:22 +0000 |
1045 | @@ -54,6 +54,7 @@ |
1046 | Rick Harris <rconradharris@gmail.com> |
1047 | Reynolds Chin <benzwt@gmail.com> |
1048 | Russell Bryant <rbryant@redhat.com> |
1049 | +Sean Dague <sdague@linux.vnet.ibm.com> |
1050 | Soren Hansen <soren.hansen@rackspace.com> |
1051 | Stuart McLaren <stuart.mclaren@hp.com> |
1052 | Taku Fukushima <tfukushima@dcl.info.waseda.ac.jp> |
1053 | |
1054 | === modified file 'Authors' |
1055 | --- Authors 2012-06-24 03:14:33 +0000 |
1056 | +++ Authors 2012-12-18 14:13:22 +0000 |
1057 | @@ -55,6 +55,7 @@ |
1058 | Reynolds Chin <benzwt@gmail.com> |
1059 | Russell Bryant <rbryant@redhat.com> |
1060 | Sam Morrison <sorrison@gmail.com> |
1061 | +Sean Dague <sdague@linux.vnet.ibm.com> |
1062 | Soren Hansen <soren.hansen@rackspace.com> |
1063 | Stuart McLaren <stuart.mclaren@hp.com> |
1064 | Taku Fukushima <tfukushima@dcl.info.waseda.ac.jp> |
1065 | |
1066 | === added file 'PKG-INFO' |
1067 | --- PKG-INFO 1970-01-01 00:00:00 +0000 |
1068 | +++ PKG-INFO 2012-12-18 14:13:22 +0000 |
1069 | @@ -0,0 +1,15 @@ |
1070 | +Metadata-Version: 1.1 |
1071 | +Name: glance |
1072 | +Version: 2012.1.3 |
1073 | +Summary: The Glance project provides services for discovering, registering, and retrieving virtual machine images |
1074 | +Home-page: http://glance.openstack.org/ |
1075 | +Author: OpenStack |
1076 | +Author-email: openstack@lists.launchpad.net |
1077 | +License: Apache License (2.0) |
1078 | +Description: UNKNOWN |
1079 | +Platform: UNKNOWN |
1080 | +Classifier: Development Status :: 4 - Beta |
1081 | +Classifier: License :: OSI Approved :: Apache Software License |
1082 | +Classifier: Operating System :: POSIX :: Linux |
1083 | +Classifier: Programming Language :: Python :: 2.6 |
1084 | +Classifier: Environment :: No Input/Output (Daemon) |
1085 | |
1086 | === modified file 'debian/changelog' |
1087 | --- debian/changelog 2012-11-08 07:19:39 +0000 |
1088 | +++ debian/changelog 2012-12-18 14:13:22 +0000 |
1089 | @@ -1,3 +1,21 @@ |
1090 | +glance (2012.1.4+stable-20121217-efd7e75b-0ubuntu1) precise-proposed; urgency=low |
1091 | + |
1092 | + [ Adam Gandelman ] |
1093 | + * debian/glance-{registry, api}.logrotate: Fix incorrect logfile |
1094 | + locations. (LP: #1049314) |
1095 | + |
1096 | + [ Yolanda Robla Mota ] |
1097 | + * Resynchronize with stable/essex (efd7e75b): |
1098 | + - [efd7e75] Non-admin users can cause public glance images to be deleted |
1099 | + from the backend storage repository (CVE-2012-4573) |
1100 | + - [e6be061] Jenkins jobs fail because of incompatibility between sqlalchemy- |
1101 | + migrate and the newest sqlalchemy-0.8.0b1 (LP: #1073569) |
1102 | + |
1103 | + * Dropped patches, superseeded by snapshot: |
1104 | + - debian/patches/CVE-2012-4573.patch: [efd7e75] |
1105 | + |
1106 | + -- Yolanda Robla Mota <yolanda.robla@canonical.com> Mon, 17 Dec 2012 10:56:46 +0000 |
1107 | + |
1108 | glance (2012.1.3+stable~20120821-120fcf-0ubuntu1.2) precise-security; urgency=low |
1109 | |
1110 | * SECURITY UPDATE: deletion of arbitrary public and shared images via |
1111 | |
1112 | === modified file 'debian/glance-api.logrotate' |
1113 | --- debian/glance-api.logrotate 2012-01-13 10:50:40 +0000 |
1114 | +++ debian/glance-api.logrotate 2012-12-18 14:13:22 +0000 |
1115 | @@ -1,4 +1,4 @@ |
1116 | -/var/log/glance/glance-api.log { |
1117 | +/var/log/glance/api.log { |
1118 | daily |
1119 | missingok |
1120 | compress |
1121 | |
1122 | === modified file 'debian/glance-registry.logrotate' |
1123 | --- debian/glance-registry.logrotate 2012-01-13 10:50:40 +0000 |
1124 | +++ debian/glance-registry.logrotate 2012-12-18 14:13:22 +0000 |
1125 | @@ -1,4 +1,4 @@ |
1126 | -/var/log/glance/glance-api.log { |
1127 | +/var/log/glance/registry.log { |
1128 | daily |
1129 | missingok |
1130 | compress |
1131 | |
1132 | === removed file 'debian/patches/CVE-2012-4573.patch' |
1133 | --- debian/patches/CVE-2012-4573.patch 2012-11-08 07:19:39 +0000 |
1134 | +++ debian/patches/CVE-2012-4573.patch 1970-01-01 00:00:00 +0000 |
1135 | @@ -1,35 +0,0 @@ |
1136 | -From efd7e75b1f419a52c7103c7840e24af8e5deb29d Mon Sep 17 00:00:00 2001 |
1137 | -From: Brian Waldon <bcwaldon@gmail.com> |
1138 | -Date: Wed, 7 Nov 2012 10:06:43 -0500 |
1139 | -Subject: [PATCH] Ensure image owned by user before delayed_deletion |
1140 | - |
1141 | -Fixes bug 1065187. |
1142 | - |
1143 | -Change-Id: Icf2f117a094c712bad645ef5f297e9f7da994c84 |
1144 | ---- |
1145 | - glance/api/v1/images.py | 9 +++++++++ |
1146 | - 1 file changed, 9 insertions(+) |
1147 | - |
1148 | -diff --git a/glance/api/v1/images.py b/glance/api/v1/images.py |
1149 | -index 9bedf20..1a8eac8 100644 |
1150 | ---- a/glance/api/v1/images.py |
1151 | -+++ b/glance/api/v1/images.py |
1152 | -@@ -727,6 +727,15 @@ class Controller(controller.BaseController): |
1153 | - content_type="text/plain") |
1154 | - |
1155 | - image = self.get_image_meta_or_404(req, id) |
1156 | -+ |
1157 | -+ if not (req.context.is_admin |
1158 | -+ or image['owner'] == None |
1159 | -+ or image['owner'] == req.context.owner): |
1160 | -+ msg = _("Unable to delete image you do not own") |
1161 | -+ logger.debug(msg) |
1162 | -+ raise HTTPForbidden(msg, request=req, |
1163 | -+ content_type="text/plain") |
1164 | -+ |
1165 | - if image['protected']: |
1166 | - msg = _("Image is protected") |
1167 | - logger.debug(msg) |
1168 | --- |
1169 | -1.7.9.5 |
1170 | - |
1171 | |
1172 | === modified file 'debian/patches/fix_migration_012_foreign_keys.patch' |
1173 | --- debian/patches/fix_migration_012_foreign_keys.patch 2012-04-12 15:02:08 +0000 |
1174 | +++ debian/patches/fix_migration_012_foreign_keys.patch 2012-12-18 14:13:22 +0000 |
1175 | @@ -1,5 +1,3 @@ |
1176 | -From: 4e35808f94db8c17a20608e137e2940195821fac |
1177 | -Author: Sam Morrison <sorrison@gmail.com> |
1178 | Date: Mon Apr 2 11:22:10 2012 +1000 |
1179 | Bug: https://bugs.launchpad.net/glance/+bug/976908 |
1180 | Origin, upstream: https://review.openstack.org/#change,6061 |
1181 | @@ -8,25 +6,21 @@ |
1182 | |
1183 | * fix bug 976908 |
1184 | |
1185 | -Change-Id: I0248f825396d08688238e6d2ef37c8fcb49e8c9d |
1186 | - |
1187 | - |
1188 | -diff --git a/Authors b/Authors |
1189 | -index 8158c2a..d9c9302 100644 |
1190 | ---- a/Authors |
1191 | -+++ b/Authors |
1192 | -@@ -52,6 +52,7 @@ Rick Clark <rick@openstack.org> |
1193 | +Change-Id: I0248f825396d08688238e6d2ef37c8fcb49e8c9 |
1194 | +diff -Naurp glance-2012.1.3.orig/Authors glance-2012.1.3/Authors |
1195 | +--- glance-2012.1.3.orig/Authors 2012-11-26 15:19:40.000000000 -0600 |
1196 | ++++ glance-2012.1.3/Authors 2012-11-26 15:42:42.691087411 -0600 |
1197 | +@@ -54,6 +54,7 @@ Rick Clark <rick@openstack.org> |
1198 | Rick Harris <rconradharris@gmail.com> |
1199 | Reynolds Chin <benzwt@gmail.com> |
1200 | Russell Bryant <rbryant@redhat.com> |
1201 | +Sam Morrison <sorrison@gmail.com> |
1202 | + Sean Dague <sdague@linux.vnet.ibm.com> |
1203 | Soren Hansen <soren.hansen@rackspace.com> |
1204 | Stuart McLaren <stuart.mclaren@hp.com> |
1205 | - Taku Fukushima <tfukushima@dcl.info.waseda.ac.jp> |
1206 | -diff --git a/glance/registry/db/migrate_repo/versions/012_id_to_uuid.py b/glance/registry/db/migrate_repo/versions/012_id_to_uuid.py |
1207 | -index fe6bf86..8db18c1 100644 |
1208 | ---- a/glance/registry/db/migrate_repo/versions/012_id_to_uuid.py |
1209 | -+++ b/glance/registry/db/migrate_repo/versions/012_id_to_uuid.py |
1210 | +diff -Naurp glance-2012.1.3.orig/glance/registry/db/migrate_repo/versions/012_id_to_uuid.py glance-2012.1.3/glance/registry/db/migrate_repo/versions/012_id_to_uuid.py |
1211 | +--- glance-2012.1.3.orig/glance/registry/db/migrate_repo/versions/012_id_to_uuid.py 2012-11-26 15:19:40.000000000 -0600 |
1212 | ++++ glance-2012.1.3/glance/registry/db/migrate_repo/versions/012_id_to_uuid.py 2012-11-26 15:41:59.231087390 -0600 |
1213 | @@ -225,18 +225,24 @@ def _get_table(table_name, metadata): |
1214 | |
1215 | def _get_foreign_keys(t_images, t_image_members, t_image_properties): |
1216 | @@ -36,27 +30,29 @@ |
1217 | + foreign_keys = [] |
1218 | + if t_image_members.foreign_keys: |
1219 | + img_members_fk_name = list(t_image_members.foreign_keys)[0].name |
1220 | - |
1221 | -- fk1 = migrate.ForeignKeyConstraint([t_image_members.c.image_id], |
1222 | -- [t_images.c.id], |
1223 | -- name=image_members_fk_name) |
1224 | ++ |
1225 | + fk1 = migrate.ForeignKeyConstraint([t_image_members.c.image_id], |
1226 | + [t_images.c.id], |
1227 | + name=img_members_fk_name) |
1228 | + foreign_keys.append(fk1) |
1229 | - |
1230 | -- fk2 = migrate.ForeignKeyConstraint([t_image_properties.c.image_id], |
1231 | -- [t_images.c.id], |
1232 | -- name=image_properties_fk_name) |
1233 | ++ |
1234 | + if t_image_properties.foreign_keys: |
1235 | + img_properties_fk_name = list(t_image_properties.foreign_keys)[0].name |
1236 | - |
1237 | -- return fk1, fk2 |
1238 | ++ |
1239 | + fk2 = migrate.ForeignKeyConstraint([t_image_properties.c.image_id], |
1240 | + [t_images.c.id], |
1241 | + name=img_properties_fk_name) |
1242 | + foreign_keys.append(fk2) |
1243 | -+ |
1244 | + |
1245 | +- fk1 = migrate.ForeignKeyConstraint([t_image_members.c.image_id], |
1246 | +- [t_images.c.id], |
1247 | +- name=image_members_fk_name) |
1248 | +- |
1249 | +- fk2 = migrate.ForeignKeyConstraint([t_image_properties.c.image_id], |
1250 | +- [t_images.c.id], |
1251 | +- name=image_properties_fk_name) |
1252 | +- |
1253 | +- return fk1, fk2 |
1254 | + return foreign_keys |
1255 | |
1256 | |
1257 | |
1258 | === modified file 'debian/patches/series' |
1259 | --- debian/patches/series 2012-11-08 07:19:39 +0000 |
1260 | +++ debian/patches/series 2012-12-18 14:13:22 +0000 |
1261 | @@ -3,4 +3,3 @@ |
1262 | disable-network-for-docs.patch |
1263 | disable_db_table_auto_create.patch |
1264 | fix_migration_012_foreign_keys.patch |
1265 | -CVE-2012-4573.patch |
1266 | |
1267 | === added directory 'glance.egg-info' |
1268 | === added file 'glance.egg-info/PKG-INFO' |
1269 | --- glance.egg-info/PKG-INFO 1970-01-01 00:00:00 +0000 |
1270 | +++ glance.egg-info/PKG-INFO 2012-12-18 14:13:22 +0000 |
1271 | @@ -0,0 +1,15 @@ |
1272 | +Metadata-Version: 1.1 |
1273 | +Name: glance |
1274 | +Version: 2012.1.3 |
1275 | +Summary: The Glance project provides services for discovering, registering, and retrieving virtual machine images |
1276 | +Home-page: http://glance.openstack.org/ |
1277 | +Author: OpenStack |
1278 | +Author-email: openstack@lists.launchpad.net |
1279 | +License: Apache License (2.0) |
1280 | +Description: UNKNOWN |
1281 | +Platform: UNKNOWN |
1282 | +Classifier: Development Status :: 4 - Beta |
1283 | +Classifier: License :: OSI Approved :: Apache Software License |
1284 | +Classifier: Operating System :: POSIX :: Linux |
1285 | +Classifier: Programming Language :: Python :: 2.6 |
1286 | +Classifier: Environment :: No Input/Output (Daemon) |
1287 | |
1288 | === added file 'glance.egg-info/SOURCES.txt' |
1289 | --- glance.egg-info/SOURCES.txt 1970-01-01 00:00:00 +0000 |
1290 | +++ glance.egg-info/SOURCES.txt 2012-12-18 14:13:22 +0000 |
1291 | @@ -0,0 +1,217 @@ |
1292 | +Authors |
1293 | +HACKING.rst |
1294 | +LICENSE |
1295 | +MANIFEST.in |
1296 | +README.rst |
1297 | +babel.cfg |
1298 | +pylintrc |
1299 | +run_tests.py |
1300 | +run_tests.sh |
1301 | +setup.cfg |
1302 | +setup.py |
1303 | +tox.ini |
1304 | +bin/glance |
1305 | +bin/glance-api |
1306 | +bin/glance-cache-cleaner |
1307 | +bin/glance-cache-manage |
1308 | +bin/glance-cache-prefetcher |
1309 | +bin/glance-cache-pruner |
1310 | +bin/glance-control |
1311 | +bin/glance-manage |
1312 | +bin/glance-registry |
1313 | +bin/glance-scrubber |
1314 | +doc/source/architecture.rst |
1315 | +doc/source/authentication.rst |
1316 | +doc/source/cache.rst |
1317 | +doc/source/client.rst |
1318 | +doc/source/conf.py |
1319 | +doc/source/configuring.rst |
1320 | +doc/source/controllingservers.rst |
1321 | +doc/source/formats.rst |
1322 | +doc/source/glance.rst |
1323 | +doc/source/glanceapi.rst |
1324 | +doc/source/identifiers.rst |
1325 | +doc/source/index.rst |
1326 | +doc/source/installing.rst |
1327 | +doc/source/notifications.rst |
1328 | +doc/source/policies.rst |
1329 | +doc/source/statuses.rst |
1330 | +doc/source/_static/basic.css |
1331 | +doc/source/_static/default.css |
1332 | +doc/source/_static/jquery.tweet.js |
1333 | +doc/source/_static/tweaks.css |
1334 | +doc/source/_templates/.placeholder |
1335 | +doc/source/_theme/layout.html |
1336 | +doc/source/_theme/theme.conf |
1337 | +doc/source/man/glance.rst |
1338 | +doc/source/man/glanceapi.rst |
1339 | +doc/source/man/glancecachecleaner.rst |
1340 | +doc/source/man/glancecachemanage.rst |
1341 | +doc/source/man/glancecacheprefetcher.rst |
1342 | +doc/source/man/glancecachepruner.rst |
1343 | +doc/source/man/glancecontrol.rst |
1344 | +doc/source/man/glancemanage.rst |
1345 | +doc/source/man/glanceregistry.rst |
1346 | +doc/source/man/glancescrubber.rst |
1347 | +etc/glance-api-paste.ini |
1348 | +etc/glance-api.conf |
1349 | +etc/glance-cache-paste.ini |
1350 | +etc/glance-cache.conf |
1351 | +etc/glance-registry-paste.ini |
1352 | +etc/glance-registry.conf |
1353 | +etc/glance-scrubber-paste.ini |
1354 | +etc/glance-scrubber.conf |
1355 | +etc/logging.cnf.sample |
1356 | +etc/policy.json |
1357 | +glance/__init__.py |
1358 | +glance/client.py |
1359 | +glance/vcsversion.py |
1360 | +glance/version.py |
1361 | +glance.egg-info/PKG-INFO |
1362 | +glance.egg-info/SOURCES.txt |
1363 | +glance.egg-info/dependency_links.txt |
1364 | +glance.egg-info/top_level.txt |
1365 | +glance/api/__init__.py |
1366 | +glance/api/cached_images.py |
1367 | +glance/api/policy.py |
1368 | +glance/api/versions.py |
1369 | +glance/api/middleware/__init__.py |
1370 | +glance/api/middleware/cache.py |
1371 | +glance/api/middleware/cache_manage.py |
1372 | +glance/api/middleware/version_negotiation.py |
1373 | +glance/api/v1/__init__.py |
1374 | +glance/api/v1/controller.py |
1375 | +glance/api/v1/filters.py |
1376 | +glance/api/v1/images.py |
1377 | +glance/api/v1/members.py |
1378 | +glance/api/v1/router.py |
1379 | +glance/common/__init__.py |
1380 | +glance/common/animation.py |
1381 | +glance/common/auth.py |
1382 | +glance/common/cfg.py |
1383 | +glance/common/client.py |
1384 | +glance/common/config.py |
1385 | +glance/common/context.py |
1386 | +glance/common/crypt.py |
1387 | +glance/common/exception.py |
1388 | +glance/common/policy.py |
1389 | +glance/common/utils.py |
1390 | +glance/common/wsgi.py |
1391 | +glance/image_cache/__init__.py |
1392 | +glance/image_cache/cleaner.py |
1393 | +glance/image_cache/prefetcher.py |
1394 | +glance/image_cache/pruner.py |
1395 | +glance/image_cache/queue_image.py |
1396 | +glance/image_cache/drivers/__init__.py |
1397 | +glance/image_cache/drivers/base.py |
1398 | +glance/image_cache/drivers/sqlite.py |
1399 | +glance/image_cache/drivers/xattr.py |
1400 | +glance/locale/__init__.py |
1401 | +glance/locale/glance.pot |
1402 | +glance/notifier/__init__.py |
1403 | +glance/notifier/notify_kombu.py |
1404 | +glance/notifier/notify_log.py |
1405 | +glance/notifier/notify_noop.py |
1406 | +glance/notifier/notify_qpid.py |
1407 | +glance/notifier/strategy.py |
1408 | +glance/registry/__init__.py |
1409 | +glance/registry/client.py |
1410 | +glance/registry/context.py |
1411 | +glance/registry/api/__init__.py |
1412 | +glance/registry/api/v1/__init__.py |
1413 | +glance/registry/api/v1/images.py |
1414 | +glance/registry/api/v1/members.py |
1415 | +glance/registry/db/__init__.py |
1416 | +glance/registry/db/api.py |
1417 | +glance/registry/db/migration.py |
1418 | +glance/registry/db/models.py |
1419 | +glance/registry/db/migrate_repo/README |
1420 | +glance/registry/db/migrate_repo/__init__.py |
1421 | +glance/registry/db/migrate_repo/manage.py |
1422 | +glance/registry/db/migrate_repo/migrate.cfg |
1423 | +glance/registry/db/migrate_repo/schema.py |
1424 | +glance/registry/db/migrate_repo/versions/001_add_images_table.py |
1425 | +glance/registry/db/migrate_repo/versions/002_add_image_properties_table.py |
1426 | +glance/registry/db/migrate_repo/versions/003_add_disk_format.py |
1427 | +glance/registry/db/migrate_repo/versions/003_sqlite_downgrade.sql |
1428 | +glance/registry/db/migrate_repo/versions/003_sqlite_upgrade.sql |
1429 | +glance/registry/db/migrate_repo/versions/004_add_checksum.py |
1430 | +glance/registry/db/migrate_repo/versions/005_size_big_integer.py |
1431 | +glance/registry/db/migrate_repo/versions/006_key_to_name.py |
1432 | +glance/registry/db/migrate_repo/versions/006_mysql_downgrade.sql |
1433 | +glance/registry/db/migrate_repo/versions/006_mysql_upgrade.sql |
1434 | +glance/registry/db/migrate_repo/versions/006_sqlite_downgrade.sql |
1435 | +glance/registry/db/migrate_repo/versions/006_sqlite_upgrade.sql |
1436 | +glance/registry/db/migrate_repo/versions/007_add_owner.py |
1437 | +glance/registry/db/migrate_repo/versions/008_add_image_members_table.py |
1438 | +glance/registry/db/migrate_repo/versions/009_add_mindisk_and_minram.py |
1439 | +glance/registry/db/migrate_repo/versions/010_default_update_at.py |
1440 | +glance/registry/db/migrate_repo/versions/011_make_mindisk_and_minram_notnull.py |
1441 | +glance/registry/db/migrate_repo/versions/012_id_to_uuid.py |
1442 | +glance/registry/db/migrate_repo/versions/013_add_protected.py |
1443 | +glance/registry/db/migrate_repo/versions/013_sqlite_downgrade.sql |
1444 | +glance/registry/db/migrate_repo/versions/__init__.py |
1445 | +glance/store/__init__.py |
1446 | +glance/store/base.py |
1447 | +glance/store/filesystem.py |
1448 | +glance/store/http.py |
1449 | +glance/store/location.py |
1450 | +glance/store/rbd.py |
1451 | +glance/store/s3.py |
1452 | +glance/store/scrubber.py |
1453 | +glance/store/swift.py |
1454 | +glance/tests/__init__.py |
1455 | +glance/tests/logcapture.py |
1456 | +glance/tests/stubs.py |
1457 | +glance/tests/utils.py |
1458 | +glance/tests/etc/policy.json |
1459 | +glance/tests/functional/__init__.py |
1460 | +glance/tests/functional/store_utils.py |
1461 | +glance/tests/functional/test_api.py |
1462 | +glance/tests/functional/test_bin_glance.py |
1463 | +glance/tests/functional/test_bin_glance_cache_manage.py |
1464 | +glance/tests/functional/test_cache_middleware.py |
1465 | +glance/tests/functional/test_client_exceptions.py |
1466 | +glance/tests/functional/test_client_redirects.py |
1467 | +glance/tests/functional/test_copy_to_file.py |
1468 | +glance/tests/functional/test_logging.py |
1469 | +glance/tests/functional/test_misc.py |
1470 | +glance/tests/functional/test_multiprocessing.py |
1471 | +glance/tests/functional/test_rbd.py |
1472 | +glance/tests/functional/test_respawn.py |
1473 | +glance/tests/functional/test_s3.py |
1474 | +glance/tests/functional/test_scrubber.py |
1475 | +glance/tests/functional/test_sqlite.py |
1476 | +glance/tests/functional/test_ssl.py |
1477 | +glance/tests/functional/test_swift.py |
1478 | +glance/tests/unit/__init__.py |
1479 | +glance/tests/unit/base.py |
1480 | +glance/tests/unit/test_api.py |
1481 | +glance/tests/unit/test_auth.py |
1482 | +glance/tests/unit/test_cfg.py |
1483 | +glance/tests/unit/test_clients.py |
1484 | +glance/tests/unit/test_config.py |
1485 | +glance/tests/unit/test_context.py |
1486 | +glance/tests/unit/test_db.py |
1487 | +glance/tests/unit/test_filesystem_store.py |
1488 | +glance/tests/unit/test_http_store.py |
1489 | +glance/tests/unit/test_image_cache.py |
1490 | +glance/tests/unit/test_migrations.conf |
1491 | +glance/tests/unit/test_migrations.py |
1492 | +glance/tests/unit/test_misc.py |
1493 | +glance/tests/unit/test_notifier.py |
1494 | +glance/tests/unit/test_s3_store.py |
1495 | +glance/tests/unit/test_skip_examples.py |
1496 | +glance/tests/unit/test_store_location.py |
1497 | +glance/tests/unit/test_swift_store.py |
1498 | +glance/tests/unit/test_utils.py |
1499 | +glance/tests/unit/test_versions.py |
1500 | +glance/tests/unit/test_wsgi.py |
1501 | +glance/tests/var/ca.crt |
1502 | +glance/tests/var/certificate.crt |
1503 | +glance/tests/var/privatekey.key |
1504 | +tools/install_venv.py |
1505 | +tools/migrate_image_owners.py |
1506 | +tools/pip-requires |
1507 | +tools/test-requires |
1508 | +tools/with_venv.sh |
1509 | \ No newline at end of file |
1510 | |
1511 | === added file 'glance.egg-info/dependency_links.txt' |
1512 | --- glance.egg-info/dependency_links.txt 1970-01-01 00:00:00 +0000 |
1513 | +++ glance.egg-info/dependency_links.txt 2012-12-18 14:13:22 +0000 |
1514 | @@ -0,0 +1,1 @@ |
1515 | + |
1516 | |
1517 | === added file 'glance.egg-info/top_level.txt' |
1518 | --- glance.egg-info/top_level.txt 1970-01-01 00:00:00 +0000 |
1519 | +++ glance.egg-info/top_level.txt 2012-12-18 14:13:22 +0000 |
1520 | @@ -0,0 +1,1 @@ |
1521 | +glance |
1522 | |
1523 | === added file 'glance/vcsversion.py' |
1524 | --- glance/vcsversion.py 1970-01-01 00:00:00 +0000 |
1525 | +++ glance/vcsversion.py 2012-12-18 14:13:22 +0000 |
1526 | @@ -0,0 +1,7 @@ |
1527 | + |
1528 | +# This file is automatically generated by setup.py, So don't edit it. :) |
1529 | +version_info = { |
1530 | + 'branch_nick': 'stable/essex', |
1531 | + 'revision_id': 'efd7e75b1f419a52c7103c7840e24af8e5deb29d', |
1532 | + 'revno': 1464 |
1533 | +} |
1534 | |
1535 | === modified file 'setup.cfg' |
1536 | --- setup.cfg 2012-06-24 03:14:33 +0000 |
1537 | +++ setup.cfg 2012-12-18 14:13:22 +0000 |
1538 | @@ -23,14 +23,11 @@ |
1539 | output_file = glance/locale/glance.pot |
1540 | |
1541 | [nosetests] |
1542 | -# NOTE(jkoelker) To run the test suite under nose install the following |
1543 | -# coverage http://pypi.python.org/pypi/coverage |
1544 | -# tissue http://pypi.python.org/pypi/tissue (pep8 checker) |
1545 | -# openstack-nose https://github.com/jkoelker/openstack-nose |
1546 | -verbosity=2 |
1547 | -detailed-errors=1 |
1548 | -with-openstack=1 |
1549 | -openstack-red=0.05 |
1550 | -openstack-yellow=0.025 |
1551 | -openstack-show-elapsed=1 |
1552 | -openstack-color=1 |
1553 | +verbosity = 2 |
1554 | +detailed-errors = 1 |
1555 | +with-openstack = 1 |
1556 | +openstack-red = 0.05 |
1557 | +openstack-yellow = 0.025 |
1558 | +openstack-show-elapsed = 1 |
1559 | +openstack-color = 1 |
1560 | + |
1561 | |
1562 | === modified file 'tools/pip-requires' |
1563 | --- tools/pip-requires 2012-06-24 03:14:33 +0000 |
1564 | +++ tools/pip-requires 2012-12-18 14:13:22 +0000 |
1565 | @@ -3,7 +3,7 @@ |
1566 | # package to get the right headers... |
1567 | greenlet>=0.3.1 |
1568 | |
1569 | -SQLAlchemy>=0.7 |
1570 | +SQLAlchemy>=0.7,<=0.7.9 |
1571 | anyjson |
1572 | eventlet>=0.9.12 |
1573 | PasteDeploy |
Yolanda
Specifically what was the pep8 issue that was causing the build to fail?
[ Yolanda Robla ]
* debian/rules: skipping pep8 tests to allow building