diff options
Diffstat (limited to 'glanceclient/v2/images.py')
-rw-r--r-- | glanceclient/v2/images.py | 79 |
1 files changed, 57 insertions, 22 deletions
diff --git a/glanceclient/v2/images.py b/glanceclient/v2/images.py index f69fed5..38895b8 100644 --- a/glanceclient/v2/images.py +++ b/glanceclient/v2/images.py @@ -81,6 +81,7 @@ class Controller(object): raise exc.HTTPBadRequest(msg) return sort + @utils.add_req_id_to_generator() def list(self, **kwargs): """Retrieve a listing of Image objects. @@ -97,6 +98,7 @@ class Controller(object): def paginate(url, page_size, limit=None): next_url = url + req_id_hdr = {} while True: if limit and page_size > limit: @@ -105,7 +107,12 @@ class Controller(object): next_url = next_url.replace("limit=%s" % page_size, "limit=%s" % limit) - resp, body = self.http_client.get(next_url) + resp, body = self.http_client.get(next_url, headers=req_id_hdr) + # NOTE(rsjethani): Store curent request id so that it can be + # used in subsequent requests. Refer bug #1525259 + req_id_hdr['x-openstack-request-id'] = \ + utils._extract_request_id(resp) + for image in body['images']: # NOTE(bcwaldon): remove 'self' for now until we have # an elegant way to pass it into the model constructor @@ -114,7 +121,7 @@ class Controller(object): # We do not validate the model when listing. # This prevents side-effects of injecting invalid # schema values via v1. - yield self.unvalidated_model(**image) + yield self.unvalidated_model(**image), resp if limit: limit -= 1 if limit <= 0: @@ -173,17 +180,23 @@ class Controller(object): if isinstance(kwargs.get('marker'), six.string_types): url = '%s&marker=%s' % (url, kwargs['marker']) - for image in paginate(url, page_size, limit): - yield image + for image, resp in paginate(url, page_size, limit): + yield image, resp - def get(self, image_id): + @utils.add_req_id_to_object() + def _get(self, image_id, header=None): url = '/v2/images/%s' % image_id - resp, body = self.http_client.get(url) + header = header or {} + resp, body = self.http_client.get(url, headers=header) # NOTE(bcwaldon): remove 'self' for now until we have an elegant # way to pass it into the model constructor without conflict body.pop('self', None) - return self.unvalidated_model(**body) + return self.unvalidated_model(**body), resp + + def get(self, image_id): + return self._get(image_id) + @utils.add_req_id_to_object() def data(self, image_id, do_checksum=True): """Retrieve data of an image. @@ -194,7 +207,7 @@ class Controller(object): url = '/v2/images/%s/file' % image_id resp, body = self.http_client.get(url) if resp.status_code == codes.no_content: - return None + return None, resp checksum = resp.headers.get('content-md5', None) content_length = int(resp.headers.get('content-length', 0)) @@ -202,8 +215,9 @@ class Controller(object): if do_checksum and checksum is not None: body = utils.integrity_iter(body, checksum) - return utils.IterableWithLength(body, content_length) + return utils.IterableWithLength(body, content_length), resp + @utils.add_req_id_to_object() def upload(self, image_id, image_data, image_size=None): """Upload the data for an image. @@ -214,13 +228,17 @@ class Controller(object): url = '/v2/images/%s/file' % image_id hdrs = {'Content-Type': 'application/octet-stream'} body = image_data - self.http_client.put(url, headers=hdrs, data=body) + resp, body = self.http_client.put(url, headers=hdrs, data=body) + return (resp, body), resp + @utils.add_req_id_to_object() def delete(self, image_id): """Delete an image.""" url = '/v2/images/%s' % image_id - self.http_client.delete(url) + resp, body = self.http_client.delete(url) + return (resp, body), resp + @utils.add_req_id_to_object() def create(self, **kwargs): """Create an image.""" url = '/v2/images' @@ -236,17 +254,21 @@ class Controller(object): # NOTE(esheffield): remove 'self' for now until we have an elegant # way to pass it into the model constructor without conflict body.pop('self', None) - return self.model(**body) + return self.model(**body), resp + @utils.add_req_id_to_object() def deactivate(self, image_id): """Deactivate an image.""" url = '/v2/images/%s/actions/deactivate' % image_id - return self.http_client.post(url) + resp, body = self.http_client.post(url) + return (resp, body), resp + @utils.add_req_id_to_object() def reactivate(self, image_id): """Reactivate an image.""" url = '/v2/images/%s/actions/reactivate' % image_id - return self.http_client.post(url) + resp, body = self.http_client.post(url) + return (resp, body), resp def update(self, image_id, remove_props=None, **kwargs): """Update attributes of an image. @@ -276,12 +298,16 @@ class Controller(object): url = '/v2/images/%s' % image_id hdrs = {'Content-Type': 'application/openstack-images-v2.1-json-patch'} - self.http_client.patch(url, headers=hdrs, data=image.patch) + resp, _ = self.http_client.patch(url, headers=hdrs, data=image.patch) + # Get request id from `patch` request so it can be passed to the + # following `get` call + req_id_hdr = { + 'x-openstack-request-id': utils._extract_request_id(resp)} # NOTE(bcwaldon): calling image.patch doesn't clear the changes, so # we need to fetch the image again to get a clean history. This is # an obvious optimization for warlock - return self.get(image_id) + return self._get(image_id, req_id_hdr) def _get_image_with_locations_or_fail(self, image_id): image = self.get(image_id) @@ -290,10 +316,13 @@ class Controller(object): 'API access to image locations') return image + @utils.add_req_id_to_object() def _send_image_update_request(self, image_id, patch_body): url = '/v2/images/%s' % image_id hdrs = {'Content-Type': 'application/openstack-images-v2.1-json-patch'} - self.http_client.patch(url, headers=hdrs, data=json.dumps(patch_body)) + resp, body = self.http_client.patch(url, headers=hdrs, + data=json.dumps(patch_body)) + return (resp, body), resp def add_location(self, image_id, url, metadata): """Add a new location entry to an image's list of locations. @@ -308,8 +337,11 @@ class Controller(object): """ add_patch = [{'op': 'add', 'path': '/locations/-', 'value': {'url': url, 'metadata': metadata}}] - self._send_image_update_request(image_id, add_patch) - return self.get(image_id) + response = self._send_image_update_request(image_id, add_patch) + # Get request id from the above update request and pass the same to + # following get request + req_id_hdr = {'x-openstack-request-id': response.request_ids[0]} + return self._get(image_id, req_id_hdr) def delete_locations(self, image_id, url_set): """Remove one or more location entries of an image. @@ -332,7 +364,7 @@ class Controller(object): url_indices.sort(reverse=True) patches = [{'op': 'remove', 'path': '/locations/%s' % url_idx} for url_idx in url_indices] - self._send_image_update_request(image_id, patches) + return self._send_image_update_request(image_id, patches) def update_location(self, image_id, url, metadata): """Update an existing location entry in an image's list of locations. @@ -359,6 +391,9 @@ class Controller(object): patches = [{'op': 'replace', 'path': '/locations', 'value': list(url_map.values())}] - self._send_image_update_request(image_id, patches) + response = self._send_image_update_request(image_id, patches) + # Get request id from the above update request and pass the same to + # following get request + req_id_hdr = {'x-openstack-request-id': response.request_ids[0]} - return self.get(image_id) + return self._get(image_id, req_id_hdr) |