diff --git a/README.rst b/README.rst index 0fdd58b1..a595c007 100644 --- a/README.rst +++ b/README.rst @@ -144,6 +144,7 @@ about the referenced build task. "state": 5, "state_name": "ready", "state_reason": null, + "stream": "master", "tasks": { "rpms": { "cloud-init": { @@ -169,7 +170,8 @@ about the referenced build task. }, "time_completed": "2017-10-05T11:58:44Z", "time_modified": "2017-10-05T11:58:58Z", - "time_submitted": "2017-10-05T11:37:39Z" + "time_submitted": "2017-10-05T11:37:39Z", + "version": "20171005113458" } The response includes: @@ -180,14 +182,16 @@ The response includes: - ``owner`` - the username of the owner or person who submitted the module build. - ``scmurl`` - the source control URL used to build the module. - ``state`` - the numerical state of the module build. -- ``state_name`` - the named state of the module build. See the section called +- ``state_name`` - the named state of the module build. See the section called. "Module Build States" for more information. - ``state_reason`` - the reason why the module build is in this state. This is useful when the build fails. +- ``stream`` - the module's stream. - ``tasks`` - a dictionary of information about the individual component builds. - ``time_completed`` - Zulu ISO 8601 timestamp of when the module build completed. - ``time_modified`` - Zulu ISO 8601 timestamp of when the module build was last modified. - ``time_submitted`` - Zulu ISO 8601 timestamp of when the module build was submitted. +- ``version`` - the module build's version. Listing all module builds @@ -198,8 +202,8 @@ querying the "module-builds" resource. There are a number of configurable GET parameters to change how the module builds are displayed. These parameters are: -- ``verbose`` - Shows the builds with the same amount of detail as querying - them individually (i.e. ``verbose=True``). This value defaults to ``True``. +- ``verbose`` - Shows the builds with additional detail such as the modulemd + and state trace (i.e. ``verbose=True``). This value defaults to ``False``. - ``page`` - Specifies which page should be displayed (e.g. ``page=3``). This value defaults to 1. - ``per_page`` - Specifies how many items per page should be displayed @@ -217,6 +221,95 @@ parameters:: HTTP 200 OK +:: + + { + "items": [ + { + "id": 123, + "koji_tag": "module-de66baf89b40367c", + "name": "testmodule", + "owner": "mprahl", + "scmurl": "git://pkgs.fedoraproject.org/modules/testmodule?#86d9cfe53d20118d863ae051641fc3784d91d981", + "state": 5, + "state_name": "ready", + "state_reason": null, + "stream": "master", + "tasks": { + "rpms": { + "ed": { + "nvr": "ed-1.14.1-4.module_d2a2f5c8", + "state": 1, + "state_reason": "Reused component from previous module build", + "task_id": 22267993 + }, + "mksh": { + "nvr": "mksh-56b-1.module_d2a2f5c8", + "state": 1, + "state_reason": "Reused component from previous module build", + "task_id": 22268059 + } + } + }, + "time_completed": "2017-10-05T18:45:56Z", + "time_modified": "2017-10-05T18:46:10Z", + "time_submitted": "2017-10-05T18:34:39Z", + "version": "20171005183359" + }, + { + "id": 124, + "koji_tag": "module-4620ad476f3d2b5c", + "name": "testmodule", + "owner": "mprahl", + "scmurl": "git://pkgs.fedoraproject.org/modules/testmodule?#373bb6eccccbfebbcb222a2723e643e7095c7973", + "state": 5, + "state_name": "ready", + "state_reason": null, + "stream": "master", + "tasks": { + "rpms": { + "ed": { + "nvr": "ed-1.14.1-4.module_d2a2f5c8", + "state": 1, + "state_reason": "Reused component from previous module build", + "task_id": 22267993 + }, + "mksh": { + "nvr": "mksh-56b-1.module_d2a2f5c8", + "state": 1, + "state_reason": "Reused component from previous module build", + "task_id": 22268059 + } + } + }, + "time_completed": "2017-10-05T18:45:50Z", + "time_modified": "2017-10-05T18:46:01Z", + "time_submitted": "2017-10-05T18:24:09Z", + "version": "20171005182359" + } + ], + "meta": { + "first": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?per_page=2&page=1", + "last": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?per_page=2&page=340", + "next": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?per_page=2&page=2", + "page": 1, + "pages": 340, + "per_page": 2, + "prev": null, + "total": 1020 + } + } + + +An example of querying the "module-builds" resource with the "verbose", "per_page", and the "page" +parameters:: + + GET /module-build-service/1/module-builds/?per_page=2&page=1?verbose=true + +:: + + HTTP 200 OK + :: { @@ -315,9 +408,9 @@ parameters:: } ], "meta": { - "first": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?per_page=2&page=1", - "last": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?per_page=2&page=340", - "next": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?per_page=2&page=2", + "first": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?verbose=true&per_page=2&page=1", + "last": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?verbose=true&per_page=2&page=340", + "next": "http://mbs.fedoraproject.org/module-build-service/1/module-builds/?verbose=true&per_page=2&page=2", "page": 1, "pages": 340, "per_page": 2, @@ -326,73 +419,6 @@ parameters:: } } - -An example of querying the "module-builds" resource with minimal information:: - - GET /module-build-service/1/module-builds/?verbose=false - -:: - - HTTP 200 OK - -:: - - { - "items": [ - { - "id": 1, - "state": 3 - }, - { - "id": 2, - "state": 3 - }, - { - "id": 3, - "state": 3 - }, - { - "id": 4, - "state": 4 - }, - { - "id": 5, - "state": 4 - }, - { - "id": 6, - "state": 4 - }, - { - "id": 7, - "state": 4 - }, - { - "id": 8, - "state": 4 - }, - { - "id": 9, - "state": 4 - }, - { - "id": 10, - "state": 1 - } - ], - "meta": { - "first": "https://127.0.0.1:5000/module-build-service/1/module-builds/?per_page=10&page=1&verbose=false", - "last": "https://127.0.0.1:5000/module-build-service/1/module-builds/?per_page=10&page=3&verbose=false", - "next": "https://127.0.0.1:5000/module-build-service/1/module-builds/?per_page=10&page=2&verbose=false", - "page": 1, - "pages": 3, - "per_page": 10, - "total": 30 - } - } - - - Filtering module builds ----------------------- @@ -484,15 +510,6 @@ about the referenced component build. "state": 1, "state_name": "COMPLETE", "state_reason": "", - "state_trace": [ - { - "reason": "Submitted pth to Koji", - "state": 0, - "state_name": "init", - "time": "2017-03-14T00:07:43Z" - }, - ... - ], "task_id": 18367215 } @@ -507,8 +524,6 @@ The response includes: "FAILED", or "CANCELED". - ``state_reason`` - the reason why the component build is in this state. This is useful when the build fails. -- ``state_trace`` - a list of events the component build went through. This is useful for - debugging. - ``task_id`` - the related task ID in the backend buildsystem. diff --git a/module_build_service/models.py b/module_build_service/models.py index d94acc3b..b70ceab4 100644 --- a/module_build_service/models.py +++ b/module_build_service/models.py @@ -354,6 +354,8 @@ class ModuleBuild(MBSBase): 'state': self.state, 'state_name': INVERSE_BUILD_STATES[self.state], 'state_reason': self.state_reason, + 'stream': self.stream, + 'version': self.version, 'owner': self.owner, 'name': self.name, 'scmurl': self.scmurl, @@ -367,9 +369,6 @@ class ModuleBuild(MBSBase): def extended_json(self): json = self.json() json.update({ - 'stream': self.stream, - 'version': self.version, - 'state_url': get_url_for('module_build', id=self.id), # TODO, show their entire .json() ? 'component_builds': [build.id for build in self.component_builds], 'modulemd': self.modulemd, @@ -378,7 +377,8 @@ class ModuleBuild(MBSBase): 'state_name': INVERSE_BUILD_STATES[record.state], 'reason': record.state_reason} for record - in self.state_trace(self.id)] + in self.state_trace(self.id)], + 'state_url': get_url_for('module_build', id=self.id) }) return json diff --git a/module_build_service/views.py b/module_build_service/views.py index aa65a3ea..efd87dfd 100644 --- a/module_build_service/views.py +++ b/module_build_service/views.py @@ -85,7 +85,7 @@ class AbstractQueryableBuildAPI(MethodView): def get(self, id): - verbose_flag = request.args.get('verbose', 'true') + verbose_flag = request.args.get('verbose', 'false').lower() if id is None: # Lists all tracked builds @@ -95,18 +95,17 @@ class AbstractQueryableBuildAPI(MethodView): 'meta': pagination_metadata(p_query, request.args) } - if verbose_flag.lower() == 'true' or verbose_flag == '1': + if verbose_flag == 'true' or verbose_flag == '1': json_data['items'] = [item.extended_json() for item in p_query.items] else: - json_data['items'] = [{'id': item.id, 'state': item.state} for - item in p_query.items] + json_data['items'] = [item.json() for item in p_query.items] return jsonify(json_data), 200 else: # Lists details for the specified build instance = self.model.query.filter_by(id=id).first() if instance: - if verbose_flag.lower() == 'true' or verbose_flag == '1': + if verbose_flag == 'true' or verbose_flag == '1': return jsonify(instance.extended_json()), 200 else: return jsonify(instance.json()), 200 diff --git a/tests/test_views/test_views.py b/tests/test_views/test_views.py index e378689a..e043341c 100644 --- a/tests/test_views/test_views.py +++ b/tests/test_views/test_views.py @@ -156,7 +156,7 @@ class TestViews(unittest.TestCase): self.assertEquals(data['time_submitted'], '2016-09-03T11:23:20Z') def test_query_build_with_verbose_mode(self): - rv = self.client.get('/module-build-service/1/module-builds/1?verbose=1') + rv = self.client.get('/module-build-service/1/module-builds/1?verbose=true') data = json.loads(rv.data) self.assertEquals(data['component_builds'], [1, 2]) self.assertEquals(data['id'], 1) @@ -252,12 +252,90 @@ class TestViews(unittest.TestCase): self.assertEquals(item['time_submitted'], '2016-09-03T11:23:20Z') def test_query_builds_not_verbose(self): - rv = self.client.get('/module-build-service/1/module-builds/?per_page=2&verbose=false') + rv = self.client.get('/module-build-service/1/module-builds/?per_page=2') items = json.loads(rv.data)['items'] - self.assertEquals(items, [{u'state': 3, u'id': 1}, {u'state': 3, u'id': 2}]) + expected = [ + { + 'id': 1, + 'koji_tag': 'module-nginx-1.2', + 'name': 'nginx', + 'owner': 'Moe Szyslak', + 'scmurl': ('git://pkgs.domain.local/modules/nginx?#ba95886c7a443b36a9ce31abda1f9b' + 'ef22f2f8c9'), + 'state': 3, + 'state_name': 'done', + 'state_reason': None, + 'stream': '1', + 'tasks': { + 'rpms': { + 'module-build-macros': { + 'nvr': 'module-build-macros-01-1.module_nginx_1_2', + 'state': 1, + 'state_reason': None, + 'task_id': 12312321 + }, + 'nginx': { + 'nvr': 'nginx-1.10.1-2.module_nginx_1_2', + 'state': 1, + 'state_reason': None, + 'task_id': 12312345 + } + } + }, + 'time_completed': '2016-09-03T11:25:32Z', + 'time_modified': '2016-09-03T11:25:32Z', + 'time_submitted': '2016-09-03T11:23:20Z', + 'version': '2' + }, + { + 'id': 2, + 'koji_tag': 'module-postgressql-1.2', + 'name': 'postgressql', + 'owner': 'some_user', + 'scmurl': ('git://pkgs.domain.local/modules/postgressql?#aa95886c7a443b36a' + '9ce31abda1f9bef22f2f8c9'), + 'state': 3, + 'state_name': 'done', + 'state_reason': None, + 'stream': '1', + 'tasks': { + 'rpms': { + 'module-build-macros': { + 'nvr': 'module-build-macros-01-1.module_postgresql_1_2', + 'state': 1, + 'state_reason': None, + 'task_id': 47383993 + }, + 'postgresql': { + 'nvr': 'postgresql-9.5.3-4.module_postgresql_1_2', + 'state': 1, + 'state_reason': None, + 'task_id': 2433433 + } + } + }, + 'time_completed': '2016-09-03T11:27:19Z', + 'time_modified': '2016-09-03T12:27:19Z', + 'time_submitted': '2016-09-03T12:25:33Z', + 'version': '2' + } + ] + self.assertEquals(items, expected) def test_query_component_build(self): - rv = self.client.get('/module-build-service/1/component-builds/3') + rv = self.client.get('/module-build-service/1/component-builds/1') + data = json.loads(rv.data) + self.assertEquals(data['id'], 1) + self.assertEquals(data['format'], 'rpms') + self.assertEquals(data['module_build'], 1) + self.assertEquals(data['package'], 'nginx') + self.assertEquals(data['state'], 1) + self.assertEquals(data['state_name'], 'COMPLETE') + self.assertEquals(data['state_reason'], None) + self.assertEquals(data['task_id'], 12312345) + + def test_query_component_build_verbose(self): + rv = self.client.get('/module-build-service/1/component-builds/3?verbose=true') data = json.loads(rv.data) self.assertEquals(data['id'], 3) self.assertEquals(data['format'], 'rpms') @@ -272,18 +350,6 @@ class TestViews(unittest.TestCase): self.assertEquals(data['state_trace'][0]['state'], 1) self.assertEquals(data['state_trace'][0]['state_name'], 'wait') - def test_query_component_build_not_verbose(self): - rv = self.client.get('/module-build-service/1/component-builds/1?verbose=false') - data = json.loads(rv.data) - self.assertEquals(data['id'], 1) - self.assertEquals(data['format'], 'rpms') - self.assertEquals(data['module_build'], 1) - self.assertEquals(data['package'], 'nginx') - self.assertEquals(data['state'], 1) - self.assertEquals(data['state_name'], 'COMPLETE') - self.assertEquals(data['state_reason'], None) - self.assertEquals(data['task_id'], 12312345) - component_builds_filters = ['tagged', 'ref', 'format'] def test_query_component_builds_filter_format(self):