Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : master
---------------------------------------------------------------
commit a61ba325517ffe0a15b4b72a387b1e48a16a113d
Author: Valentin Gologuzov <vgologuz(a)redhat.com>
Date: Tue Sep 8 18:15:14 2015 +0200
[frontend][API] replaced BuildChroot with BuildTask, tests are broken and
documentation should reflect this changes
---------------------------------------------------------------
.../coprs_frontend/coprs/logic/builds_logic.py | 30 ++++++
frontend/coprs_frontend/coprs/rest_api/__init__.py | 38 ++++---
frontend/coprs_frontend/coprs/rest_api/common.py | 10 +-
.../coprs/rest_api/resources/build.py | 31 +++---
.../coprs/rest_api/resources/build_chroot.py | 47 --------
.../coprs/rest_api/resources/build_task.py | 111 ++++++++++++++++++++
.../coprs/rest_api/resources/mock_chroot.py | 4 +-
.../coprs/rest_api/resources/project.py | 11 +-
frontend/coprs_frontend/coprs/rest_api/schemas.py | 5 +-
frontend/coprs_frontend/coprs/rest_api/util.py | 25 ++++-
.../Resources/{build_chroot.rst => build_task.rst} | 43 +++++---
frontend/docs/api_2/source/index.rst | 2 +-
12 files changed, 247 insertions(+), 110 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/logic/builds_logic.py
b/frontend/coprs_frontend/coprs/logic/builds_logic.py
index ace4bfa..3992ed0 100644
--- a/frontend/coprs_frontend/coprs/logic/builds_logic.py
+++ b/frontend/coprs_frontend/coprs/logic/builds_logic.py
@@ -9,6 +9,7 @@ import time
import flask
from sqlalchemy import or_
from sqlalchemy import and_
+from sqlalchemy.orm import joinedload
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.sql import false
from werkzeug.utils import secure_filename
@@ -37,6 +38,7 @@ class BuildsLogic(object):
def get(cls, build_id):
return models.Build.query.filter(models.Build.id == build_id)
+ # todo: move methods operating with BuildChroot to BuildChrootLogic
@classmethod
def get_build_tasks(cls, status):
return models.BuildChroot.query.filter(models.BuildChroot.status == status) \
@@ -521,6 +523,34 @@ class BuildChrootsLogic(object):
.filter(BuildChroot.mock_chroot_id == mc.id)
)
+ @classmethod
+ def get_multiply(cls):
+ query = (
+ models.BuildChroot.query
+ .join(models.BuildChroot.build)
+ .join(models.BuildChroot.mock_chroot)
+ .join(models.Build.copr)
+ .join(models.Copr.owner)
+
+ )
+ return query
+
+ @classmethod
+ def filter_by_build_id(cls, query, build_id):
+ return query.filter(models.Build.id == build_id)
+
+ @classmethod
+ def filter_by_project_id(cls, query, project_id):
+ return query.filter(models.Copr.id == project_id)
+
+ @classmethod
+ def filter_by_project_owner_name(cls, query, username):
+ return query.filter(models.User.username == username)
+
+ @classmethod
+ def filter_by_state(cls, query, state):
+ return query.filter(models.BuildChroot.status == StatusEnum(state))
+
class BuildsMonitorLogic(object):
@classmethod
diff --git a/frontend/coprs_frontend/coprs/rest_api/__init__.py
b/frontend/coprs_frontend/coprs/rest_api/__init__.py
index 7276c2f..0f87c4f 100644
--- a/frontend/coprs_frontend/coprs/rest_api/__init__.py
+++ b/frontend/coprs_frontend/coprs/rest_api/__init__.py
@@ -7,7 +7,7 @@ from coprs.exceptions import InsufficientRightsException
from coprs.rest_api.exceptions import ApiError
from coprs.rest_api.resources.build import BuildListR, BuildR
-from coprs.rest_api.resources.build_chroot import BuildChrootListR, BuildChrootR
+from coprs.rest_api.resources.build_task import BuildTaskListR, BuildTaskR
from coprs.rest_api.resources.mock_chroot import MockChrootListR, MockChrootR
from coprs.rest_api.resources.project import ProjectListR, ProjectR
from coprs.rest_api.resources.project_chroot import ProjectChrootListR, ProjectChrootR
@@ -20,9 +20,19 @@ class RootR(Resource):
return {
"_links": {
"self": {"href": url_for(".rootr")},
- "projects": {"href":
url_for(".projectlistr")},
+ "projects": {
+ "href": url_for(".projectlistr"),
+ "query_params": [
+ {
+ "name": u"owner",
+ "type": u"string",
+ "description": u"Select only project owned by
the user"
+ }
+ ]
+ },
"mock_chroots": {"href":
url_for(".mockchrootlistr")},
"builds": {"href":
url_for(".buildlistr")},
+ "build_tasks": {"href":
url_for(".buildtasklistr")},
}
}
@@ -30,14 +40,15 @@ class RootR(Resource):
class MyApi(Api):
# flask-restfull error handling quite buggy right now
def error_router(self, original_handler, e):
+ # import ipdb; ipdb.set_trace()
return original_handler(e)
- # def handle_error(self, e):
- #
- # if isinstance(e, sqlalchemy.orm.exc.NoResultFound):
- # return self.make_response(str(e), 404)
- #
- #
- # super(MyApi, self).handle_error(e)
+# # def handle_error(self, e):
+# #
+# # if isinstance(e, sqlalchemy.orm.exc.NoResultFound):
+# # return self.make_response(str(e), 404)
+# #
+# #
+# # super(MyApi, self).handle_error(e)
# def register_api(app, db):
@@ -59,11 +70,10 @@ api.add_resource(BuildR, "/builds/<int:build_id>")
api.add_resource(ProjectChrootListR,
"/projects/<int:project_id>/chroots")
api.add_resource(ProjectChrootR,
"/projects/<int:project_id>/chroots/<name>")
-api.add_resource(BuildChrootListR, "/builds/<int:build_id>/chroots")
-api.add_resource(BuildChrootR,
"/builds/<int:build_id>/chroots/<name>")
-
-# app.register_blueprint(rest_api_bp, url_prefix=URL_PREFIX)
+api.add_resource(BuildTaskListR, "/build_tasks")
+# todo: add redirect from /build_tasks/<int:build_id> ->
/build_tasks?build_id=<build_id>
+api.add_resource(BuildTaskR, "/build_tasks/<int:build_id>/<name>")
def register_api_error_handler(app):
@@ -72,7 +82,7 @@ def register_api_error_handler(app):
"""
:param ApiError error:
"""
-
+ # import ipdb; ipdb.set_trace()
content = {
"message": error.msg,
}
diff --git a/frontend/coprs_frontend/coprs/rest_api/common.py
b/frontend/coprs_frontend/coprs/rest_api/common.py
index 72c5eae..7bc9c81 100644
--- a/frontend/coprs_frontend/coprs/rest_api/common.py
+++ b/frontend/coprs_frontend/coprs/rest_api/common.py
@@ -5,7 +5,7 @@ import functools
from logging import getLogger
from coprs.logic.builds_logic import BuildsLogic
from coprs.logic.coprs_logic import CoprsLogic
-from coprs.rest_api.schemas import BuildChrootSchema
+from coprs.rest_api.schemas import BuildTaskSchema
from coprs.rest_api.util import mm_serialize_one, get_one_safe
log = getLogger(__name__)
@@ -41,7 +41,7 @@ def render_build(build, self_params=None):
"_links": {
"self": {"href": url_for(".buildr",
build_id=build.id, **self_params)},
"project": {"href": url_for(".projectr",
project_id=build.copr_id)},
- "chroots": {"href":
url_for(".buildchrootlistr", build_id=build.id)}
+ "tasks": {"href": url_for(".buildtasklistr",
build_id=build.id)}
}
}
@@ -60,15 +60,15 @@ def render_project(copr, self_params=None):
}
-def render_build_chroot(chroot):
+def render_build_task(chroot):
"""
:type chroot: models.BuildChroot
"""
return {
- "chroot": mm_serialize_one(BuildChrootSchema, chroot),
+ "task": mm_serialize_one(BuildTaskSchema, chroot),
"_links": {
"project": {"href": url_for(".projectr",
project_id=chroot.build.copr_id)},
- "self": {"href": url_for(".buildchrootr",
+ "self": {"href": url_for(".buildtaskr",
build_id=chroot.build.id,
name=chroot.name)},
}
diff --git a/frontend/coprs_frontend/coprs/rest_api/resources/build.py
b/frontend/coprs_frontend/coprs/rest_api/resources/build.py
index 6f4a792..7d31412 100644
--- a/frontend/coprs_frontend/coprs/rest_api/resources/build.py
+++ b/frontend/coprs_frontend/coprs/rest_api/resources/build.py
@@ -2,28 +2,24 @@
import flask
from flask import url_for, make_response
-
-# from flask_restful_swagger import swagger
-
-from coprs import db
-from coprs.exceptions import ActionInProgressException, InsufficientRightsException,
RequestCannotBeExecuted
-from coprs.logic.builds_logic import BuildsLogic
-from coprs.rest_api.common import get_project_safe
-from coprs.rest_api.exceptions import MalformedRequest, CannotProcessRequest,
AccessForbidden
-from ..common import render_build, rest_api_auth_required, render_build_chroot,
get_build_safe, get_user_safe
-
-from coprs.rest_api.schemas import BuildSchema, BuildCreateSchema,
BuildCreateFromUrlSchema
-
-from coprs.rest_api.util import mm_deserialize
-
from flask_restful import Resource, reqparse
+from ... import db
+from ...exceptions import ActionInProgressException, InsufficientRightsException,
RequestCannotBeExecuted
+from ...helpers import StatusEnum
+from ...logic.builds_logic import BuildsLogic
+from ..common import get_project_safe
+from ..exceptions import MalformedRequest, CannotProcessRequest, AccessForbidden
+from ..common import render_build, rest_api_auth_required, render_build_task,
get_build_safe, get_user_safe
+from ..schemas import BuildSchema, BuildCreateSchema, BuildCreateFromUrlSchema
+from ..util import mm_deserialize, get_request_parser
+
class BuildListR(Resource):
def get(self):
- parser = reqparse.RequestParser()
+ parser = get_request_parser()
parser.add_argument('owner', type=str,)
parser.add_argument('project_id', type=int)
@@ -31,6 +27,7 @@ class BuildListR(Resource):
parser.add_argument('limit', type=int)
parser.add_argument('offset', type=int)
+ parser.add_argument('state', type=str)
# parser.add_argument('package', type=str)
req_args = parser.parse_args()
@@ -158,7 +155,7 @@ class BuildListR(Resource):
class BuildR(Resource):
def get(self, build_id):
- parser = reqparse.RequestParser()
+ parser = get_request_parser()
parser.add_argument('show_chroots', type=bool, default=False)
req_args = parser.parse_args()
@@ -171,7 +168,7 @@ class BuildR(Resource):
result = render_build(build, self_params)
if req_args["show_chroots"]:
result["build_chroots"] = [
- render_build_chroot(chroot)
+ render_build_task(chroot)
for chroot in build.build_chroots
]
diff --git a/frontend/coprs_frontend/coprs/rest_api/resources/build_chroot.py
b/frontend/coprs_frontend/coprs/rest_api/resources/build_chroot.py
deleted file mode 100644
index 3f6da84..0000000
--- a/frontend/coprs_frontend/coprs/rest_api/resources/build_chroot.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# coding: utf-8
-
-from flask import url_for
-from flask_restful import Resource
-
-from coprs.rest_api.common import render_build_chroot
-from ...exceptions import MalformedArgumentException
-from ...logic.builds_logic import BuildsLogic, BuildChrootsLogic
-from ..exceptions import MalformedRequest
-from ..util import get_one_safe
-
-
-class BuildChrootListR(Resource):
- def get(self, build_id):
- build = get_one_safe(BuildsLogic.get(build_id),
- "Build {} Not found".format(build_id))
-
- return {
- "chroots": [
- render_build_chroot(chroot)
- for chroot in build.build_chroots
- ],
- "_links": {
- "self": {"href":
url_for(".buildchrootlistr", build_id=build_id)}
- }
- }
-
-
-class BuildChrootR(Resource):
-
- @staticmethod
- def _get_chroot_safe(build_id, name):
- try:
- chroot = get_one_safe(
- BuildChrootsLogic.get_by_build_id_and_name(build_id, name),
- "Build chroot {} for build {} not found"
- )
- except MalformedArgumentException as err:
- raise MalformedRequest("Bad mock chroot name: {}".format(err))
- return chroot
-
- def get(self, build_id, name):
- chroot = self._get_chroot_safe(build_id, name)
- return render_build_chroot(chroot)
-
- # todo: add put method: allows only to pass status: cancelled to cancel build
-
diff --git a/frontend/coprs_frontend/coprs/rest_api/resources/build_task.py
b/frontend/coprs_frontend/coprs/rest_api/resources/build_task.py
new file mode 100644
index 0000000..c17a1d1
--- /dev/null
+++ b/frontend/coprs_frontend/coprs/rest_api/resources/build_task.py
@@ -0,0 +1,111 @@
+# coding: utf-8
+
+from flask import url_for
+from flask_restful import Resource
+from flask_restful import Resource, reqparse
+from flask_restful.reqparse import Argument
+
+from marshmallow import pprint
+from marshmallow import Schema, fields
+from marshmallow import Schema, fields, validates_schema, ValidationError, validate
+
+from coprs.helpers import StatusEnum
+from coprs.rest_api.common import render_build_task
+from ...exceptions import MalformedArgumentException
+from ...logic.builds_logic import BuildsLogic, BuildChrootsLogic
+from ..exceptions import MalformedRequest
+from ..util import get_one_safe, get_request_parser
+
+
+# todo: add redirect from /build_tasks/<int:build_id> ->
/build_tasks?build_id=<build_id>
+# class BuildTaskListRedirectBuildIdR(Resource):
+# def get(self, build_id):
+# resp = make_response("", 302)
+# resp.headers["Location"] == url_for(".buildtasklistr",
build_id=build_id)
+
+
+class BuildTaskListQuerySchema(Schema):
+
+ build_id = fields.Int()
+
+
+class BuildTaskListR(Resource):
+ state_choices = StatusEnum.vals.keys()
+
+ def get(self):
+
+ parser = get_request_parser()
+
+ parser.add_argument('owner', type=str,)
+ parser.add_argument('project_id', type=int)
+ parser.add_argument('build_id', type=int)
+
+ parser.add_argument('limit', type=int)
+ parser.add_argument('offset', type=int)
+
+ parser.add_argument(
+ 'state', type=str, choices=self.state_choices,
+ help=u"allowed states: {}".format("
".join(self.state_choices)))
+
+ req_args = parser.parse_args()
+
+ self_params = dict(req_args)
+
+ query = BuildChrootsLogic.get_multiply()
+ if self_params.get("build_id") is not None:
+ query = BuildChrootsLogic.filter_by_build_id(
+ query, self_params["build_id"])
+ elif self_params.get("project_id") is not None:
+ query = BuildChrootsLogic.filter_by_project_id(
+ query, self_params["project_id"])
+ elif self_params.get("owner") is not None:
+ query = BuildChrootsLogic.filter_by_project_owner_name(
+ query, self_params["owner"])
+
+ state = self_params.get("state")
+ if state:
+ query = BuildChrootsLogic.filter_by_state(query, state)
+
+ if req_args["limit"] is not None:
+ limit = req_args["limit"]
+ if limit <= 0 or limit > 100:
+ limit = 100
+ else:
+ limit = 100
+ self_params["limit"] = limit
+ query = query.limit(limit)
+
+ if "offset" in self_params is not None:
+ query = query.offset(self_params["offset"])
+
+ build_chroots = query.all()
+ return {
+ "tasks": [
+ render_build_task(chroot)
+ for chroot in build_chroots
+ ],
+ "_links": {
+ "self": {"href": url_for(".buildtasklistr",
**self_params)}
+ }
+ }
+
+
+class BuildTaskR(Resource):
+
+ @staticmethod
+ def _get_chroot_safe(build_id, name):
+ try:
+ chroot = get_one_safe(
+ BuildChrootsLogic.get_by_build_id_and_name(build_id, name),
+ "Build task {} for build {} not found"
+ )
+ except MalformedArgumentException as err:
+ raise MalformedRequest("Bad mock chroot name: {}".format(err))
+ return chroot
+
+ def get(self, build_id, name):
+ chroot = self._get_chroot_safe(build_id, name)
+ return render_build_task(chroot)
+
+ # todo: add put method: allows only to pass status: cancelled to cancel build
+
diff --git a/frontend/coprs_frontend/coprs/rest_api/resources/mock_chroot.py
b/frontend/coprs_frontend/coprs/rest_api/resources/mock_chroot.py
index c7135de..a81569c 100644
--- a/frontend/coprs_frontend/coprs/rest_api/resources/mock_chroot.py
+++ b/frontend/coprs_frontend/coprs/rest_api/resources/mock_chroot.py
@@ -6,7 +6,7 @@ from flask_restful import Resource, reqparse
from ...logic.coprs_logic import MockChrootsLogic
from ..schemas import MockChrootSchema
-from ..util import get_one_safe
+from ..util import get_one_safe, get_request_parser
def render_mock_chroot(chroot):
@@ -21,7 +21,7 @@ def render_mock_chroot(chroot):
class MockChrootListR(Resource):
def get(self):
- parser = reqparse.RequestParser()
+ parser = get_request_parser()
parser.add_argument('active_only', type=bool)
req_args = parser.parse_args()
active_only = False
diff --git a/frontend/coprs_frontend/coprs/rest_api/resources/project.py
b/frontend/coprs_frontend/coprs/rest_api/resources/project.py
index 148891b..e3157b8 100644
--- a/frontend/coprs_frontend/coprs/rest_api/resources/project.py
+++ b/frontend/coprs_frontend/coprs/rest_api/resources/project.py
@@ -1,7 +1,4 @@
from logging import getLogger
-from coprs.rest_api.exceptions import MalformedRequest
-
-log = getLogger(__name__)
import flask
from flask import url_for, make_response
@@ -19,7 +16,9 @@ from ...exceptions import DuplicateException
from ..common import rest_api_auth_required, render_copr_chroot, render_build,
render_project, get_project_safe
from ..schemas import ProjectSchema, ProjectCreateSchema
from ..exceptions import ObjectAlreadyExists, CannotProcessRequest, AccessForbidden
-from ..util import mm_deserialize
+from ..util import mm_deserialize, get_request_parser
+
+log = getLogger(__name__)
class ProjectListR(Resource):
@@ -52,7 +51,7 @@ class ProjectListR(Resource):
return resp
def get(self):
- parser = reqparse.RequestParser()
+ parser = get_request_parser()
parser.add_argument('owner', type=str)
parser.add_argument('name', type=str)
parser.add_argument('limit', type=int)
@@ -111,7 +110,7 @@ class ProjectR(Resource):
return None, 204
def get(self, project_id):
- parser = reqparse.RequestParser()
+ parser = get_request_parser()
parser.add_argument('show_builds', type=bool, default=False)
parser.add_argument('show_chroots', type=bool, default=False)
req_args = parser.parse_args()
diff --git a/frontend/coprs_frontend/coprs/rest_api/schemas.py
b/frontend/coprs_frontend/coprs/rest_api/schemas.py
index cb6f867..b28d1c6 100644
--- a/frontend/coprs_frontend/coprs/rest_api/schemas.py
+++ b/frontend/coprs_frontend/coprs/rest_api/schemas.py
@@ -128,13 +128,14 @@ class CoprChrootCreateSchema(CoprChrootSchema):
name = fields.Str(required=True)
-class BuildChrootSchema(Schema):
+class BuildTaskSchema(Schema):
# used only for presentation
state = fields.Str()
started_on = fields.Int(dump_only=True)
ended_on = fields.Int(dump_only=True)
git_hash = fields.Str(dump_only=True)
- name = fields.Str(dump_only=True)
+ chroot_name = fields.Str(dump_only=True, attribute="name")
+ build_id = fields.Int(dump_only=True)
result_dir_url = fields.Str(dump_only=True)
diff --git a/frontend/coprs_frontend/coprs/rest_api/util.py
b/frontend/coprs_frontend/coprs/rest_api/util.py
index d937784..402edd1 100644
--- a/frontend/coprs_frontend/coprs/rest_api/util.py
+++ b/frontend/coprs_frontend/coprs/rest_api/util.py
@@ -1,10 +1,13 @@
# coding: utf-8
import json
+from flask import Response, url_for, Blueprint
import sqlalchemy.orm.exc
+
+from flask_restful.reqparse import Argument, RequestParser
+
from .exceptions import ObjectNotFoundError, MalformedRequest
-from schemas import AllowedMethodSchema
-from flask import Response, url_for, Blueprint
+from .schemas import AllowedMethodSchema
class AllowedMethod(object):
@@ -62,3 +65,21 @@ def mm_deserialize(schema, json_string):
def mm_serialize_one(schema, obj):
return schema().dump(obj)[0]
+
+
+class MyArg(Argument):
+ def handle_validation_error(self, error, bundle_errors):
+ # dirty monkey patching, better to switch to webargs
+ # bundle errors are ignored
+ data = {u"error": unicode(error)}
+ if self.help:
+ data["help"] = self.help
+ raise MalformedRequest(
+ "Failed to validate query parameter: {}".format(self.name),
+ data=data
+ )
+
+
+def get_request_parser():
+ return RequestParser(argument_class=MyArg)
+ #return RequestParser(bundle_errors=True)
diff --git a/frontend/docs/api_2/source/Resources/build_chroot.rst
b/frontend/docs/api_2/source/Resources/build_task.rst
similarity index 73%
rename from frontend/docs/api_2/source/Resources/build_chroot.rst
rename to frontend/docs/api_2/source/Resources/build_task.rst
index f767fbe..c5871a4 100644
--- a/frontend/docs/api_2/source/Resources/build_chroot.rst
+++ b/frontend/docs/api_2/source/Resources/build_task.rst
@@ -1,15 +1,16 @@
-Build Chroot
-============
+Build Task
+==========
-Build chroot represents information about individual build tasks for each chroot.
+Build task represents information about individual build tasks per each chroot.
-Structure of the build chroot entity
-------------------------------------
+Structure of the build task entity
+----------------------------------
.. code-block:: javascript
{
"name": "fedora-rawhide-x86_64",
+ "build_id": 12345,
"started_on": 1440753865,
"ended_on": 1440753919,
"state": "succeeded",
@@ -22,7 +23,8 @@ Build chroot fields
================== ==================== ===============
Field Type Description
================== ==================== ===============
-name str chroot name
+chroot_name str chroot name
+build_id int unique build identifier
state str current build state
started_on int(unixtime UTC) time when the build chroot started
ended_on int(unixtime UTC) time when the build chroot ended
@@ -38,11 +40,24 @@ result_dir_url str(URL) location of the build
results
List build chroots
------------------
-.. http:get:: /api_2/builds/(int:build_id)/chroots
+.. http:get:: /api_2/builds_tasks
- Returns list of build chroots contained in the one build
+ Returns list of build tasks according to the given query parameters
- :param int build_id: a unique identifier of the build
+ :query str owner: select build tasks from projects owned by this user
+ :query int project_id:
+ select build tasks from one project,
+ when used query parameter ``owner`` is ignored
+ :query int build_id:
+ select build tasks from one project,
+ when used query parameters ``owner`` and ``project_id`` are ignored
+
+ :query int offset: offset number, default value is 0
+ :query int limit: limit number, default value is 100
+ :query str state:
+ select builds in particular state, allowed values:
+ ``failed``, ``succeeded``, ``canceled``, ``running``,
+ ``pending``, ``starting``, ``importing``
:statuscode 200: no error
:statuscode 404: build not found
@@ -51,7 +66,7 @@ List build chroots
.. sourcecode:: http
- GET /api_2/builds/106882/chroots HTTP/1.1
+ GET /api_2/builds_tasks?build_id=106882 HTTP/1.1
Host:
copr.fedoraproject.org
**Response**
@@ -91,18 +106,18 @@ List build chroots
-Get build chroot details
-------------------------
+Get build task details
+----------------------
.. http:get:: /api_2/builds/(int:build_id)/chroots/(str:name)
- Returns details about one build chroot
+ Returns details about one build task
:param int build_id: a unique identifier of the build
:param str name: chroot name
:statuscode 200: no error
- :statuscode 404: build or build chroot not found
+ :statuscode 404: build or build task not found
**Example request**
diff --git a/frontend/docs/api_2/source/index.rst b/frontend/docs/api_2/source/index.rst
index d7dfcba..3ed6a68 100644
--- a/frontend/docs/api_2/source/index.rst
+++ b/frontend/docs/api_2/source/index.rst
@@ -22,7 +22,7 @@ Resources
Resources/project
Resources/project_chroot
Resources/build
- Resources/build_chroot
+ Resources/build_task
Resources/mock_chroot