-
Notifications
You must be signed in to change notification settings - Fork 22
Add pingback support (bug 1377305) #16
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,17 @@ | ||
| # This Source Code Form is subject to the terms of the Mozilla Public | ||
| # 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/. | ||
| import os | ||
|
|
||
| from landoapi.hgexportbuilder import build_patch_for_revision | ||
| from landoapi.models.storage import db | ||
| from landoapi.phabricator_client import PhabricatorClient | ||
| from landoapi.transplant_client import TransplantClient | ||
|
|
||
| TRANSPLANT_JOB_STARTING = 'pending' | ||
| TRANSPLANT_JOB_STARTED = 'started' | ||
| TRANSPLANT_JOB_FINISHED = 'finished' | ||
| TRANSPLANT_JOB_LANDED = 'landed' | ||
| TRANSPLANT_JOB_FAILED = 'failed' | ||
|
|
||
|
|
||
| class Landing(db.Model): | ||
|
|
@@ -17,16 +21,21 @@ class Landing(db.Model): | |
| request_id = db.Column(db.Integer, unique=True) | ||
| revision_id = db.Column(db.String(30)) | ||
| status = db.Column(db.Integer) | ||
| error = db.Column(db.String(128), default='') | ||
| result = db.Column(db.String(128)) | ||
|
|
||
| def __init__( | ||
| self, request_id=None, revision_id=None, status=TRANSPLANT_JOB_STARTED | ||
| self, | ||
| request_id=None, | ||
| revision_id=None, | ||
| status=TRANSPLANT_JOB_STARTING | ||
| ): | ||
| self.request_id = request_id | ||
| self.revision_id = revision_id | ||
| self.status = status | ||
|
|
||
| @classmethod | ||
| def create(cls, revision_id, phabricator_api_key=None, save=True): | ||
| def create(cls, revision_id, phabricator_api_key=None): | ||
| """ Land revision and create a Transplant item in storage. """ | ||
| phab = PhabricatorClient(phabricator_api_key) | ||
| revision = phab.get_revision(id=revision_id) | ||
|
|
@@ -40,39 +49,34 @@ def create(cls, revision_id, phabricator_api_key=None, save=True): | |
|
|
||
| repo = phab.get_revision_repo(revision) | ||
|
|
||
| # save landing to make sure we've got the callback | ||
| landing = cls( | ||
| revision_id=revision_id, | ||
| ).save() | ||
|
|
||
| trans = TransplantClient() | ||
| callback = '%s/landings/%s/update' % ( | ||
| os.getenv('HOST_URL'), landing.id | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This setting's name could be improved. I can't tell from the name alone that it is used for pingbacks. Maybe something like
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's the lando-api host url - I thought we might use it for something else. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Discussed on IRC, I'm fine with either keeping the variable as-is or with changing it.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think HOST_URL works well, imo. |
||
| ) | ||
| # The LDAP username used here has to be the username of the patch | ||
| # pusher. | ||
| # FIXME: what value do we use here? | ||
| # FIXME: This client, or the person who pushed the 'Land it!' button? | ||
| request_id = trans.land( | ||
| 'ldap_username@example.com', hgpatch, repo['uri'] | ||
| 'ldap_username@example.com', hgpatch, repo['uri'], callback | ||
| ) | ||
| if not request_id: | ||
| raise LandingNotCreatedException | ||
|
|
||
| landing = cls( | ||
| revision_id=revision_id, | ||
| request_id=request_id, | ||
| status=TRANSPLANT_JOB_STARTED | ||
| ) | ||
| if save: | ||
| landing.save(create=True) | ||
| landing.request_id = request_id | ||
| landing.status = TRANSPLANT_JOB_STARTED | ||
| landing.save() | ||
|
|
||
| return landing | ||
|
|
||
| @classmethod | ||
| def get(cls, landing_id): | ||
| """ Get Landing object from storage. """ | ||
| landing = cls.query.get(landing_id) | ||
| if not landing: | ||
| raise LandingNotFoundException() | ||
|
|
||
| return landing | ||
|
|
||
| def save(self, create=False): | ||
| def save(self): | ||
| """ Save objects in storage. """ | ||
| if create: | ||
| if not self.id: | ||
| db.session.add(self) | ||
|
|
||
| db.session.commit() | ||
|
|
@@ -87,7 +91,9 @@ def serialize(self): | |
| 'id': self.id, | ||
| 'revision_id': self.revision_id, | ||
| 'request_id': self.request_id, | ||
| 'status': self.status | ||
| 'status': self.status, | ||
| 'error_msg': self.error, | ||
| 'result': self.result | ||
| } | ||
|
|
||
|
|
||
|
|
@@ -96,11 +102,6 @@ class LandingNotCreatedException(Exception): | |
| pass | ||
|
|
||
|
|
||
| class LandingNotFoundException(Exception): | ||
| """ No specific Landing was found in database. """ | ||
| pass | ||
|
|
||
|
|
||
| class RevisionNotFoundException(Exception): | ||
| """ Phabricator returned 404 for a given revision id. """ | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -111,6 +111,13 @@ paths: | |
| responses: | ||
| 202: | ||
| description: OK | ||
| schema: | ||
| type: object | ||
| properties: | ||
| id: | ||
| type: integer | ||
| description: | | ||
| A newly created Landing id | ||
| 404: | ||
| description: Revision does not exist | ||
| schema: | ||
|
|
@@ -121,6 +128,60 @@ paths: | |
| schema: | ||
| allOf: | ||
| - $ref: '#/definitions/Error' | ||
| /landings/{landing_id}/update: | ||
| post: | ||
| operationId: landoapi.api.landings.update | ||
| description: | | ||
| Sends request to transplant service and responds with just the | ||
| status code | ||
| parameters: | ||
| - name: data | ||
| in: body | ||
| description: | | ||
| Retrieve status of the landing job | ||
| required: true | ||
| schema: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See https://docs.google.com/document/d/1cRIdpVqYcn0Mle7vyjJePNw5TcFoZ20N42dLVy5xVEk/edit# for the remaining data. |
||
| type: object | ||
| required: | ||
| - request_id | ||
| properties: | ||
| request_id: | ||
| type: integer | ||
| tree: | ||
| type: string | ||
| rev: | ||
| type: string | ||
| patch: | ||
| type: string | ||
| destination: | ||
| type: string | ||
| trysyntax: | ||
| type: string | ||
| landed: | ||
| type: boolean | ||
| error_msg: | ||
| type: string | ||
| result: | ||
| type: string | ||
| - name: landing_id | ||
| in: path | ||
| type: string | ||
| description: | | ||
| The id of the landing to return | ||
| required: true | ||
| responses: | ||
| 202: | ||
| description: OK | ||
| 404: | ||
| description: Landing does not exist | ||
| schema: | ||
| allOf: | ||
| - $ref: '#/definitions/Error' | ||
| default: | ||
| description: Unexpected error | ||
| schema: | ||
| allOf: | ||
| - $ref: '#/definitions/Error' | ||
| /landings/{landing_id}: | ||
| get: | ||
| description: | | ||
|
|
@@ -168,6 +229,14 @@ definitions: | |
| type: integer | ||
| description: | | ||
| The id of the Revision | ||
| result: | ||
| type: string | ||
| description: | | ||
| revision (sha) of push if landed == true | ||
| error: | ||
| type: string | ||
| description: | | ||
| Error message if landing failed | ||
| Revision: | ||
| type: object | ||
| properties: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| """Add error message and result to Landing | ||
|
|
||
| Revision ID: 67151bb74080 | ||
| Revises: ae9dd729e66c | ||
| Create Date: 2017-06-29 22:16:56.874034 | ||
|
|
||
| """ | ||
| from alembic import op | ||
| import sqlalchemy as sa | ||
|
|
||
| # revision identifiers, used by Alembic. | ||
| revision = '67151bb74080' | ||
| down_revision = 'ae9dd729e66c' | ||
| branch_labels = () | ||
| depends_on = None | ||
|
|
||
|
|
||
| def upgrade(): | ||
| # ### commands auto generated by Alembic - please adjust! ### | ||
| op.add_column( | ||
| 'landings', sa.Column('error', sa.String(length=128), nullable=True) | ||
| ) | ||
| op.add_column( | ||
| 'landings', sa.Column('result', sa.String(length=128), nullable=True) | ||
| ) | ||
| # ### end Alembic commands ### | ||
|
|
||
|
|
||
| def downgrade(): | ||
| # ### commands auto generated by Alembic - please adjust! ### | ||
| op.drop_column('landings', 'result') | ||
| op.drop_column('landings', 'error') | ||
| # ### end Alembic commands ### |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line confuses me. If the 'landed' field is present, regardless of value, everything is OK, and if an update is ever made with this field missing, it's a failure in the other system? I think there should be a comment or two in here to explain what the possible combinations of incoming values are, and to explain what they represent in the other system and in our system.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm adding description of fields which are received from Transplant (from Google doc)