Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api: add stats endpoint (bug 1800074) #223

Open
wants to merge 4 commits into
base: zeid/bug-1744327-refactor-workers
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[flake8]
max-line-length = 88
select = C,E,F,W,B,B9
ignore = E203, E501, W503, B006
ignore = E203, E501, W503, B006, E712, E711
exclude =
.hg,
.git,
Expand Down
7 changes: 6 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,13 @@ RUN cd / && pip install --no-cache /app
ENV PYTHONPATH /app
RUN chown -R app:app /app

# Create repos directory for transplanting in landing-worker
# Create repos directory for landing-worker and revision worker.
RUN mkdir /repos
RUN chown -R app:app /repos

# Create patches directory to cache patches.
RUN mkdir /patches
RUN chown -R app:app /patches

# Run as a non-privileged user
USER app
Expand Down
6 changes: 6 additions & 0 deletions Dockerfile-dev
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ ENV PYTHONUNBUFFERED=1
ENV FLASK_RUN_PORT=9000
ENV FLASK_RUN_HOST=0.0.0.0
ENV FLASK_DEBUG=1
ENV HTTP_ALLOWED=1

ENTRYPOINT ["lando-cli"]
CMD ["run"]
Expand Down Expand Up @@ -48,9 +49,14 @@ RUN cd / && pip install --no-cache /app
ENV PYTHONPATH /app
RUN chown -R app:app /app

# Create repos directory for landing worker and revision worker.
RUN mkdir /repos
RUN chown -R app:app /repos

# Create patches directory to store cached patches.
RUN mkdir /patches
RUN chown -R app:app /patches

# Run as a non-privileged user
USER app

Expand Down
25 changes: 13 additions & 12 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,25 +131,24 @@ services:
- smtp
lando-api.landing-worker:
image: lando-api
command: ["landing-worker"]
command: ["start-landing-worker"]
environment:
- ENV=localdev
- DATABASE_URL=postgresql://postgres:[email protected]/lando_api_dev
- SENTRY_DSN=
# See http://docs.celeryproject.org/en/stable/getting-started/brokers/redis.html#configuration
# for the full URL format.
- CELERY_BROKER_URL=redis://redis.queue/0
- OIDC_IDENTIFIER=https://lando-api.test
- OIDC_DOMAIN=https://auth0.test
- LANDO_UI_URL=https://lando.test
- REPO_CLONES_PATH=/repos
- REPOS_TO_LAND=localdev
CELERY_BROKER_URL: "redis://redis.queue/0"
DATABASE_URL: "postgresql://postgres:[email protected]/lando_api_dev"
ENV: "localdev"
LANDO_UI_URL: "https://lando.test"
OIDC_DOMAIN: "https://auth0.test"
OIDC_IDENTIFIER: "https://lando-api.test"
REPOS_TO_LAND: "localdev"
REPO_CLONES_PATH: "/repos"
SENTRY_DSN: ""
user: root
volumes:
- ./:/app
- ./migrations/:/migrations/
# Prevent writing python cache to the host.
- caches_cache:/app/.cache/
- repos:/repos
depends_on:
- lando-api.db
- redis.queue
Expand Down Expand Up @@ -177,3 +176,5 @@ volumes:
caches_pycache:
caches_cache:
caches_pytest_cache:
repos:
patches:
42 changes: 42 additions & 0 deletions landoapi/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,49 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from landoapi.models.revisions import Revision, RevisionStatus as RS
from landoapi.models.landing_job import LandingJob, LandingJobStatus as LJS


def get():
"""Return a redirect repsonse to the swagger specification."""
return None, 302, {"Location": "/swagger.json"}


def get_stats():
"""Return some useful statistics about the Lando system."""
data = {}
data["landing_jobs"] = {
"SUBMITTED": LandingJob.query.filter(
LandingJob.status == LJS.SUBMITTED
).count(),
"DEFERRED": LandingJob.query.filter(LandingJob.status == LJS.DEFERRED).count(),
"FAILED": LandingJob.query.filter(LandingJob.status == LJS.FAILED).count(),
"CANCELLED": LandingJob.query.filter(
LandingJob.status == LJS.CANCELLED
).count(),
"IN_PROGRESS": LandingJob.query.filter(
LandingJob.status == LJS.IN_PROGRESS
).count(),
"LANDED": LandingJob.query.filter(LandingJob.status == LJS.LANDED).count(),
}

data["revisions"] = {
"NEW": Revision.query.filter(Revision.status == RS.NEW).count(),
"STALE": Revision.query.filter(Revision.status == RS.STALE).count(),
"PICKED_UP": Revision.query.filter(Revision.status == RS.PICKED_UP).count(),
"READY_FOR_PREPROCESSING": Revision.query.filter(
Revision.status == RS.READY_FOR_PREPROCESSING
).count(),
"PREPROCESSING": Revision.query.filter(
Revision.status == RS.PREPROCESSING
).count(),
"PROBLEM": Revision.query.filter(Revision.status == RS.PROBLEM).count(),
"READY": Revision.query.filter(Revision.status == RS.READY).count(),
"QUEUED": Revision.query.filter(Revision.status == RS.QUEUED).count(),
"LANDING": Revision.query.filter(Revision.status == RS.LANDING).count(),
"LANDED": Revision.query.filter(Revision.status == RS.LANDED).count(),
"FAILED": Revision.query.filter(Revision.status == RS.FAILED).count(),
}

return data, 200
3 changes: 1 addition & 2 deletions landoapi/api/landing_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ def put(landing_job_id, data):
)

if landing_job.status in (LandingJobStatus.SUBMITTED, LandingJobStatus.DEFERRED):
landing_job.transition_status(LandingJobAction.CANCEL)
db.session.commit()
landing_job.transition_status(LandingJobAction.CANCEL, commit=True, db=db)
return {"id": landing_job.id}, 200
else:
raise ProblemException(
Expand Down
13 changes: 13 additions & 0 deletions landoapi/api/revisions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from landoapi import auth
from landoapi.decorators import require_phabricator_api_key
from landoapi.models import SecApprovalRequest
from landoapi.models.revisions import Revision
from landoapi.projects import get_secure_project_phid
from landoapi.revisions import revision_is_secure
from landoapi.secapproval import send_sanitized_commit_message_for_review
Expand Down Expand Up @@ -90,3 +91,15 @@ def request_sec_approval(data=None):
db.session.commit()

return {}, 200


def get_stack_hashes(revision_id):
"""
Given a revision, returns revision stack hashes.

A stack hash is used to detect a change in a revision.
"""
revision = Revision.query.filter(Revision.id == revision_id).one_or_none()
if revision:
return revision.stack_hashes, 200
return {}, 404
40 changes: 22 additions & 18 deletions landoapi/api/stacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from flask import current_app, g
from landoapi.commit_message import format_commit_message
from landoapi.decorators import require_phabricator_api_key
from landoapi.phabricator import PhabricatorClient, PhabricatorAPIException
from landoapi.models.revisions import Revision
from landoapi.phabricator import PhabricatorClient
from landoapi.projects import (
get_sec_approval_project_phid,
get_secure_project_phid,
Expand Down Expand Up @@ -69,12 +70,7 @@ def get(revision_id):
if revision is None:
return not_found_problem

try:
nodes, edges = build_stack_graph(phab, phab.expect(revision, "phid"))
except PhabricatorAPIException:
# If a revision within the stack causes an API exception, treat the whole stack
# as not found.
return not_found_problem
nodes, edges = build_stack_graph(revision)
stack_data = request_extended_revision_data(phab, [phid for phid in nodes])

supported_repos = get_repos_for_env(current_app.config.get("ENVIRONMENT"))
Expand Down Expand Up @@ -111,20 +107,25 @@ def get(revision_id):
}

revisions_response = []
for _phid, revision in stack_data.revisions.items():
revision_phid = PhabricatorClient.expect(revision, "phid")
fields = PhabricatorClient.expect(revision, "fields")
for _phid, phab_revision in stack_data.revisions.items():
lando_revision = Revision.query.filter(
Revision.revision_id == phab_revision["id"]
).one_or_none()
revision_phid = PhabricatorClient.expect(phab_revision, "phid")
fields = PhabricatorClient.expect(phab_revision, "fields")
diff_phid = PhabricatorClient.expect(fields, "diffPHID")
repo_phid = PhabricatorClient.expect(fields, "repositoryPHID")
diff = stack_data.diffs[diff_phid]
human_revision_id = "D{}".format(PhabricatorClient.expect(revision, "id"))
human_revision_id = "D{}".format(PhabricatorClient.expect(phab_revision, "id"))
revision_url = urllib.parse.urljoin(
current_app.config["PHABRICATOR_URL"], human_revision_id
)
secure = revision_is_secure(revision, secure_project_phid)
commit_description = find_title_and_summary_for_display(phab, revision, secure)
bug_id = get_bugzilla_bug(revision)
reviewers = get_collated_reviewers(revision)
secure = revision_is_secure(phab_revision, secure_project_phid)
commit_description = find_title_and_summary_for_display(
phab, phab_revision, secure
)
bug_id = get_bugzilla_bug(phab_revision)
reviewers = get_collated_reviewers(phab_revision)
accepted_reviewers = reviewers_for_commit_message(
reviewers, users, projects, sec_approval_project_phid
)
Expand Down Expand Up @@ -159,16 +160,16 @@ def get(revision_id):
{
"id": human_revision_id,
"phid": revision_phid,
"status": serialize_status(revision),
"status": serialize_status(phab_revision),
"blocked_reason": blocked.get(revision_phid, ""),
"bug_id": bug_id,
"title": commit_description.title,
"url": revision_url,
"date_created": PhabricatorClient.to_datetime(
PhabricatorClient.expect(revision, "fields", "dateCreated")
PhabricatorClient.expect(phab_revision, "fields", "dateCreated")
).isoformat(),
"date_modified": PhabricatorClient.to_datetime(
PhabricatorClient.expect(revision, "fields", "dateModified")
PhabricatorClient.expect(phab_revision, "fields", "dateModified")
).isoformat(),
"summary": commit_description.summary,
"commit_message_title": commit_message_title,
Expand All @@ -179,6 +180,9 @@ def get(revision_id):
"reviewers": serialize_reviewers(reviewers, users, projects, diff_phid),
"is_secure": secure,
"is_using_secure_commit_message": commit_description.sanitized,
"lando_revision": lando_revision.serialize()
if lando_revision
else None,
}
)

Expand Down
Loading