diff -Nru gnocchi-4.2.4/ChangeLog gnocchi-4.2.5/ChangeLog --- gnocchi-4.2.4/ChangeLog 2018-04-25 15:27:07.000000000 +0000 +++ gnocchi-4.2.5/ChangeLog 2018-06-14 15:34:13.000000000 +0000 @@ -1,6 +1,13 @@ CHANGES ======= +4.2.5 +----- + +* api: remove parameter passing via Accept header +* Revert "Cap WebOb to <1.8.0" +* swift: avoid Connection aborted + 4.2.4 ----- @@ -67,6 +74,3 @@ * optimise percentile computation with pure numpy * fix median aggregation * service: fix utils.parallel\_map number of workers setting -* tests: Fix resource type with optional uuid -* simplify uncompressed serialization path -* declare expected array instead of insert diff -Nru gnocchi-4.2.4/debian/changelog gnocchi-4.2.5/debian/changelog --- gnocchi-4.2.4/debian/changelog 2018-06-08 02:08:16.000000000 +0000 +++ gnocchi-4.2.5/debian/changelog 2018-12-03 14:15:05.000000000 +0000 @@ -1,3 +1,9 @@ +gnocchi (4.2.5-0ubuntu1) bionic; urgency=medium + + * New stable point release for OpenStack Queens (LP: #1806043). + + -- Corey Bryant Mon, 03 Dec 2018 09:15:05 -0500 + gnocchi (4.2.4-0ubuntu1.1) bionic; urgency=medium * Enable alternative python2 dependencies for gnocchi-api (LP: #1746992): diff -Nru gnocchi-4.2.4/doc/source/rest.j2 gnocchi-4.2.5/doc/source/rest.j2 --- gnocchi-4.2.4/doc/source/rest.j2 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/doc/source/rest.j2 2018-06-14 15:32:08.000000000 +0000 @@ -667,10 +667,6 @@ {{ scenarios['search-resource-history']['doc'] }} -It is also possible to send the *history* parameter in the *Accept* header: - -{{ scenarios['search-resource-history-in-accept']['doc'] }} - Time range `````````` diff -Nru gnocchi-4.2.4/doc/source/rest.yaml gnocchi-4.2.5/doc/source/rest.yaml --- gnocchi-4.2.4/doc/source/rest.yaml 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/doc/source/rest.yaml 2018-06-14 15:32:08.000000000 +0000 @@ -522,19 +522,11 @@ {"=": {"id": "{{ scenarios['create-resource-instance']['response'].json['id'] }}"}} -- name: search-resource-history-in-accept - request: | - POST /v1/search/resource/instance HTTP/1.1 - Content-Type: application/json - Accept: application/json; history=true - - {"=": {"id": "{{ scenarios['create-resource-instance']['response'].json['id'] }}"}} - - name: search-resource-history-partial request: | - POST /v1/search/resource/instance HTTP/1.1 + POST /v1/search/resource/instance?history=true HTTP/1.1 Content-Type: application/json - Accept: application/json; history=true + Accept: application/json {"and": [ {"=": {"host": "compute1"}}, diff -Nru gnocchi-4.2.4/gnocchi/incoming/__init__.py gnocchi-4.2.5/gnocchi/incoming/__init__.py --- gnocchi-4.2.4/gnocchi/incoming/__init__.py 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/gnocchi/incoming/__init__.py 2018-06-14 15:32:08.000000000 +0000 @@ -43,6 +43,9 @@ SACK_PREFIX = "incoming" CFG_PREFIX = 'gnocchi-config' CFG_SACKS = 'sacks' + # NOTE(sileht): By default we use threads, but some driver can disable + # threads by setting this to utils.sequencial_map + MAP_METHOD = staticmethod(utils.parallel_map) @property def NUM_SACKS(self): @@ -122,11 +125,10 @@ and values are a list of :py:class:`gnocchi.incoming.Measure`. """ - utils.parallel_map( - self._store_new_measures, - ((metric_id, self._encode_measures(measures)) - for metric_id, measures - in six.iteritems(metrics_and_measures))) + self.MAP_METHOD(self._store_new_measures, + ((metric_id, self._encode_measures(measures)) + for metric_id, measures + in six.iteritems(metrics_and_measures))) @staticmethod def _store_new_measures(metric_id, data): diff -Nru gnocchi-4.2.4/gnocchi/incoming/swift.py gnocchi-4.2.5/gnocchi/incoming/swift.py --- gnocchi-4.2.4/gnocchi/incoming/swift.py 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/gnocchi/incoming/swift.py 2018-06-14 15:32:08.000000000 +0000 @@ -21,12 +21,17 @@ from gnocchi.common import swift from gnocchi import incoming +from gnocchi import utils swclient = swift.swclient swift_utils = swift.swift_utils class SwiftStorage(incoming.IncomingDriver): + # NOTE(sileht): Using threads with swiftclient doesn't work + # as expected, so disable it + MAP_METHOD = staticmethod(utils.sequencial_map) + def __init__(self, conf, greedy=True): super(SwiftStorage, self).__init__(conf) self.swift = swift.get_connection(conf) diff -Nru gnocchi-4.2.4/gnocchi/rest/aggregates/api.py gnocchi-4.2.5/gnocchi/rest/aggregates/api.py --- gnocchi-4.2.4/gnocchi/rest/aggregates/api.py 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/gnocchi/rest/aggregates/api.py 2018-06-14 15:32:08.000000000 +0000 @@ -196,7 +196,7 @@ @pecan.expose("json") def post(self, start=None, stop=None, granularity=None, needed_overlap=None, fill=None, groupby=None, **kwargs): - details = api.get_details(kwargs) + details = api.get_bool_param('details', kwargs) if fill is None and needed_overlap is None: fill = "dropna" diff -Nru gnocchi-4.2.4/gnocchi/rest/api.py gnocchi-4.2.5/gnocchi/rest/api.py --- gnocchi-4.2.4/gnocchi/rest/api.py 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/gnocchi/rest/api.py 2018-06-14 15:32:08.000000000 +0000 @@ -176,37 +176,8 @@ raise voluptuous.Invalid(e) -def get_header_option(name, params): - type, options = werkzeug.http.parse_options_header( - pecan.request.headers.get('Accept')) - return strtobool('Accept header' if name in options else name, - options.get(name, params.get(name, 'false'))) - - -def get_header_option_array(name, params): - type, options = werkzeug.http.parse_options_header( - pecan.request.headers.get('Accept')) - header_option = options.get(name, None) - post_option = params.get(name, None) - - if post_option: - return arg_to_list(post_option) - elif header_option: - return header_option.split('+') - else: - return None - - -def get_history(params): - return get_header_option('history', params) - - -def get_details(params): - return get_header_option('details', params) - - -def get_json_attrs(params): - return get_header_option_array('attrs', params) +def get_bool_param(name, params, default='false'): + return strtobool(name, params.get(name, default)) def strtobool(varname, v): @@ -799,7 +770,7 @@ @pecan.expose('json') def get(self, **kwargs): - details = get_details(kwargs) + details = get_bool_param('details', kwargs) pagination_opts = get_pagination_options( kwargs, RESOURCE_DEFAULT_PAGINATION) @@ -1147,11 +1118,11 @@ @pecan.expose('json') def get_all(self, **kwargs): - details = get_details(kwargs) - history = get_history(kwargs) + details = get_bool_param('details', kwargs) + history = get_bool_param('history', kwargs) pagination_opts = get_pagination_options( kwargs, RESOURCE_DEFAULT_PAGINATION) - json_attrs = get_json_attrs(kwargs) + json_attrs = arg_to_list(kwargs.get('attrs', None)) policy_filter = pecan.request.auth_helper.get_resource_policy_filter( pecan.request, "list resource", self._resource_type) @@ -1380,8 +1351,8 @@ else: attr_filter = None - details = get_details(kwargs) - history = get_history(kwargs) + details = get_bool_param('details', kwargs) + history = get_bool_param('history', kwargs) pagination_opts = get_pagination_options( kwargs, RESOURCE_DEFAULT_PAGINATION) @@ -1413,7 +1384,7 @@ @pecan.expose('json') def post(self, **kwargs): - json_attrs = get_json_attrs(kwargs) + json_attrs = arg_to_list(kwargs.get('attrs', None)) try: return [r.jsonify(json_attrs) for r in self._search(**kwargs)] except indexer.IndexerException as e: diff -Nru gnocchi-4.2.4/gnocchi/storage/__init__.py gnocchi-4.2.5/gnocchi/storage/__init__.py --- gnocchi-4.2.4/gnocchi/storage/__init__.py 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/gnocchi/storage/__init__.py 2018-06-14 15:32:08.000000000 +0000 @@ -119,6 +119,10 @@ class StorageDriver(object): + # NOTE(sileht): By default we use threads, but some driver can disable + # threads by setting this to utils.sequencial_map + MAP_METHOD = staticmethod(utils.parallel_map) + def __init__(self, conf, coord): self.coord = coord @@ -127,7 +131,7 @@ pass def _get_measures(self, metric, keys, aggregation, version=3): - return utils.parallel_map( + return self.MAP_METHOD( self._get_measures_unbatched, ((metric, key, aggregation, version) for key in keys)) @@ -217,7 +221,7 @@ raise AggregationDoesNotExist(metric, aggregation, g) aggregations.append(agg) - agg_timeseries = utils.parallel_map( + agg_timeseries = self.MAP_METHOD( self._get_measures_timeserie, ((metric, ag, from_timestamp, to_timestamp) for ag in aggregations)) @@ -568,7 +572,7 @@ d.granularity, carbonara.round_timestamp( tstamp, d.granularity)) - utils.parallel_map( + self.MAP_METHOD( self._add_measures, ((aggregation, d, metric, ts, current_first_block_timestamp, diff -Nru gnocchi-4.2.4/gnocchi/storage/swift.py gnocchi-4.2.5/gnocchi/storage/swift.py --- gnocchi-4.2.4/gnocchi/storage/swift.py 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/gnocchi/storage/swift.py 2018-06-14 15:32:08.000000000 +0000 @@ -82,6 +82,9 @@ class SwiftStorage(storage.StorageDriver): WRITE_FULL = True + # NOTE(sileht): Using threads with swiftclient doesn't work + # as expected, so disable it + MAP_METHOD = staticmethod(utils.sequencial_map) def __init__(self, conf, coord=None): super(SwiftStorage, self).__init__(conf, coord) diff -Nru gnocchi-4.2.4/gnocchi/tests/functional/gabbits/history.yaml gnocchi-4.2.5/gnocchi/tests/functional/gabbits/history.yaml --- gnocchi-4.2.4/gnocchi/tests/functional/gabbits/history.yaml 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/gnocchi/tests/functional/gabbits/history.yaml 2018-06-14 15:32:08.000000000 +0000 @@ -73,9 +73,7 @@ $[0].project_id: fe20a931-1012-4cc6-addc-39556ec60907 - name: list all resources with history - GET: $LAST_URL - request_headers: - accept: application/json; details=True; history=True + GET: $LAST_URL?details=true&history=true response_json_paths: $.`len`: 3 $[0].id: f93450f2-d8a5-4d67-9985-02511241e7d1 @@ -97,9 +95,7 @@ status: 200 - name: list all resources with history no change after metrics update - GET: /v1/resource/generic - request_headers: - accept: application/json; details=True; history=True + GET: /v1/resource/generic?details=true&history=true response_json_paths: $.`len`: 3 $[0].id: f93450f2-d8a5-4d67-9985-02511241e7d1 @@ -123,9 +119,7 @@ $[/name][1].resource_id: f93450f2-d8a5-4d67-9985-02511241e7d1 - name: list all resources with history no change after metrics creation - GET: /v1/resource/generic - request_headers: - accept: application/json; details=True; history=True + GET: /v1/resource/generic?history=true&details=true response_json_paths: $.`len`: 3 $[0].id: f93450f2-d8a5-4d67-9985-02511241e7d1 diff -Nru gnocchi-4.2.4/gnocchi/tests/functional/gabbits/resource.yaml gnocchi-4.2.5/gnocchi/tests/functional/gabbits/resource.yaml --- gnocchi-4.2.4/gnocchi/tests/functional/gabbits/resource.yaml 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/gnocchi/tests/functional/gabbits/resource.yaml 2018-06-14 15:32:08.000000000 +0000 @@ -378,26 +378,6 @@ $[0].`len`: 13 $[1].`len`: 13 - - name: list generic resources with attrs header - GET: /v1/resource/generic - request_headers: - Accept: "application/json; attrs=id+started_at+user_id" - response_json_paths: - $[0].`len`: 3 - $[0].id: $RESPONSE['$[0].id'] - $[0].started_at: $RESPONSE['$[0].started_at'] - $[0].user_id: $RESPONSE['$[0].user_id'] - $[1].`len`: 3 - - - name: list generic resources with invalid attrs header - GET: /v1/resource/generic - request_headers: - Accept: "application/json; attrs=id+foo+bar" - response_json_paths: - $[0].`len`: 1 - $[0].id: $RESPONSE['$[0].id'] - $[1].`len`: 1 - - name: list generic resources without attrs header GET: /v1/resource/generic request_headers: diff -Nru gnocchi-4.2.4/gnocchi/tests/functional/gabbits/search.yaml gnocchi-4.2.5/gnocchi/tests/functional/gabbits/search.yaml --- gnocchi-4.2.4/gnocchi/tests/functional/gabbits/search.yaml 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/gnocchi/tests/functional/gabbits/search.yaml 2018-06-14 15:32:08.000000000 +0000 @@ -232,28 +232,6 @@ $[0].`len`: 13 $[1].`len`: 13 - - name: search all resource with attrs header - POST: /v1/search/resource/generic - data: {} - request_headers: - Accept: "application/json; attrs=id+started_at+user_id" - response_json_paths: - $[0].`len`: 3 - $[0].id: $RESPONSE['$[0].id'] - $[0].started_at: $RESPONSE['$[0].started_at'] - $[0].user_id: $RESPONSE['$[0].user_id'] - $[1].`len`: 3 - - - name: search all resource with invalid attrs header - POST: /v1/search/resource/generic - data: {} - request_headers: - Accept: "application/json; attrs=id+foo+bar" - response_json_paths: - $[0].`len`: 1 - $[0].id: $RESPONSE['$[0].id'] - $[1].`len`: 1 - - name: search all resource without attrs header POST: /v1/search/resource/generic data: {} diff -Nru gnocchi-4.2.4/gnocchi/tests/test_rest.py gnocchi-4.2.5/gnocchi/tests/test_rest.py --- gnocchi-4.2.4/gnocchi/tests/test_rest.py 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/gnocchi/tests/test_rest.py 2018-06-14 15:32:08.000000000 +0000 @@ -1155,8 +1155,8 @@ # Check the history history = self.app.post_json( - "/v1/search/resource/" + self.resource_type, - headers={"Accept": "application/json; history=true"}, + "/v1/search/resource/" + self.resource_type + "?history=true", + headers={"Accept": "application/json"}, params={"=": {"id": result['id']}}, status=200) history = json.loads(history.text) @@ -1343,8 +1343,8 @@ self.assertEqual(result, resources[0]) resources = self.app.post_json( - "/v1/search/resource/" + self.resource_type, - headers={"Accept": "application/json; history=true"}, + "/v1/search/resource/" + self.resource_type + "?history=true", + headers={"Accept": "application/json"}, params={"and": [ {"=": {"id": result['id']}}, {"or": [{">=": {"revision_end": '2014-01-03T02:02:02'}}, @@ -1497,16 +1497,6 @@ b"Unable to parse `details': invalid truth value", result.body) - def test_list_resources_with_bad_details_in_accept(self): - result = self.app.get("/v1/resource/generic", - headers={ - "Accept": "application/json; details=foo", - }, - status=400) - self.assertIn( - b"Unable to parse `Accept header': invalid truth value", - result.body) - def _do_test_list_resources_with_detail(self, request): # NOTE(jd) So this test is a bit fuzzy right now as we uses the same # database for all tests and the tests are running concurrently, but @@ -1599,22 +1589,10 @@ self._do_test_list_resources_with_detail( lambda: self.app.get("/v1/resource/generic?details=true")) - def test_list_resources_with_details_via_accept(self): - self._do_test_list_resources_with_detail( - lambda: self.app.get( - "/v1/resource/generic", - headers={"Accept": "application/json; details=true"})) - def test_search_resources_with_details(self): self._do_test_list_resources_with_detail( lambda: self.app.post("/v1/search/resource/generic?details=true")) - def test_search_resources_with_details_via_accept(self): - self._do_test_list_resources_with_detail( - lambda: self.app.post( - "/v1/search/resource/generic", - headers={"Accept": "application/json; details=true"})) - def test_get_res_named_metric_measure_aggregated_policies_invalid(self): result = self.app.post_json("/v1/metric", params={"archive_policy_name": "low"}) diff -Nru gnocchi-4.2.4/gnocchi/utils.py gnocchi-4.2.5/gnocchi/utils.py --- gnocchi-4.2.4/gnocchi/utils.py 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/gnocchi/utils.py 2018-06-14 15:32:08.000000000 +0000 @@ -299,11 +299,15 @@ conf.driver).driver +def sequencial_map(fn, list_of_args): + return list(itertools.starmap(fn, list_of_args)) + + def parallel_map(fn, list_of_args): """Run a function in parallel.""" if parallel_map.MAX_WORKERS == 1: - return list(itertools.starmap(fn, list_of_args)) + return sequencial_map(fn, list_of_args) with futures.ThreadPoolExecutor( max_workers=parallel_map.MAX_WORKERS) as executor: diff -Nru gnocchi-4.2.4/gnocchi.egg-info/pbr.json gnocchi-4.2.5/gnocchi.egg-info/pbr.json --- gnocchi-4.2.4/gnocchi.egg-info/pbr.json 2018-04-25 15:27:07.000000000 +0000 +++ gnocchi-4.2.5/gnocchi.egg-info/pbr.json 2018-06-14 15:34:13.000000000 +0000 @@ -1 +1 @@ -{"git_version": "2632b6e", "is_release": true} \ No newline at end of file +{"git_version": "bc3b370", "is_release": false} \ No newline at end of file diff -Nru gnocchi-4.2.4/gnocchi.egg-info/PKG-INFO gnocchi-4.2.5/gnocchi.egg-info/PKG-INFO --- gnocchi-4.2.4/gnocchi.egg-info/PKG-INFO 2018-04-25 15:27:07.000000000 +0000 +++ gnocchi-4.2.5/gnocchi.egg-info/PKG-INFO 2018-06-14 15:34:13.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: gnocchi -Version: 4.2.4 +Version: 4.2.5 Summary: Metric as a Service Home-page: http://gnocchi.xyz Author: Gnocchi developers diff -Nru gnocchi-4.2.4/gnocchi.egg-info/requires.txt gnocchi-4.2.5/gnocchi.egg-info/requires.txt --- gnocchi-4.2.4/gnocchi.egg-info/requires.txt 2018-04-25 15:27:07.000000000 +0000 +++ gnocchi-4.2.5/gnocchi.egg-info/requires.txt 2018-06-14 15:34:13.000000000 +0000 @@ -14,7 +14,7 @@ voluptuous>=0.8.10 werkzeug tenacity>=4.6.0 -WebOb<1.8.0,>=1.4.1 +WebOb>=1.4.1 Paste PasteDeploy monotonic diff -Nru gnocchi-4.2.4/gnocchi.egg-info/SOURCES.txt gnocchi-4.2.5/gnocchi.egg-info/SOURCES.txt --- gnocchi-4.2.4/gnocchi.egg-info/SOURCES.txt 2018-04-25 15:27:07.000000000 +0000 +++ gnocchi-4.2.5/gnocchi.egg-info/SOURCES.txt 2018-06-14 15:34:13.000000000 +0000 @@ -252,6 +252,7 @@ releasenotes/notes/remoteuser-auth-plugin-00f0cefb6b003a6e.yaml releasenotes/notes/remove-deprecated-dynamic-aggregation-e14ece1d0fcaf313.yaml releasenotes/notes/remove-legacy-ceilometer-resources-16da2061d6d3f506.yaml +releasenotes/notes/remove-options-in-accept-header-7e5e074d8fccfb0f.yaml releasenotes/notes/removed-median-and-95pct-from-default-aggregation-methods-2f5ec059855e17f9.yaml releasenotes/notes/resource-type-patch-8b6a85009db0671c.yaml releasenotes/notes/resource-type-required-attributes-f446c220d54c8eb7.yaml diff -Nru gnocchi-4.2.4/PKG-INFO gnocchi-4.2.5/PKG-INFO --- gnocchi-4.2.4/PKG-INFO 2018-04-25 15:27:07.000000000 +0000 +++ gnocchi-4.2.5/PKG-INFO 2018-06-14 15:34:13.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: gnocchi -Version: 4.2.4 +Version: 4.2.5 Summary: Metric as a Service Home-page: http://gnocchi.xyz Author: Gnocchi developers diff -Nru gnocchi-4.2.4/releasenotes/notes/remove-options-in-accept-header-7e5e074d8fccfb0f.yaml gnocchi-4.2.5/releasenotes/notes/remove-options-in-accept-header-7e5e074d8fccfb0f.yaml --- gnocchi-4.2.4/releasenotes/notes/remove-options-in-accept-header-7e5e074d8fccfb0f.yaml 1970-01-01 00:00:00.000000000 +0000 +++ gnocchi-4.2.5/releasenotes/notes/remove-options-in-accept-header-7e5e074d8fccfb0f.yaml 2018-06-14 15:32:08.000000000 +0000 @@ -0,0 +1,7 @@ +--- +upgrade: + - | + The API offered several features that accepted option via the the use of + the `Accept` header. This usage was not compatible with the RFC7231 and has + therefore been removed. This created compatibility problem with WebOb 1.8.0 + and above. diff -Nru gnocchi-4.2.4/requirements.txt gnocchi-4.2.5/requirements.txt --- gnocchi-4.2.4/requirements.txt 2018-04-25 15:24:47.000000000 +0000 +++ gnocchi-4.2.5/requirements.txt 2018-06-14 15:32:08.000000000 +0000 @@ -16,7 +16,7 @@ werkzeug trollius; python_version < '3.4' tenacity>=4.6.0 -WebOb>=1.4.1,<1.8.0 +WebOb>=1.4.1 Paste PasteDeploy monotonic