| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import datetime | 5 import datetime |
| 6 import functools | 6 import functools |
| 7 import json | 7 import json |
| 8 import logging | 8 import logging |
| 9 | 9 |
| 10 from google.appengine.ext import ndb | 10 from google.appengine.ext import ndb |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 cancelation_reason = messages.EnumField(model.CancelationReason, 9) | 89 cancelation_reason = messages.EnumField(model.CancelationReason, 9) |
| 90 lease_expiration_ts = messages.IntegerField(10) | 90 lease_expiration_ts = messages.IntegerField(10) |
| 91 lease_key = messages.IntegerField(11) | 91 lease_key = messages.IntegerField(11) |
| 92 url = messages.StringField(12) | 92 url = messages.StringField(12) |
| 93 created_ts = messages.IntegerField(13) | 93 created_ts = messages.IntegerField(13) |
| 94 updated_ts = messages.IntegerField(14) | 94 updated_ts = messages.IntegerField(14) |
| 95 completed_ts = messages.IntegerField(15) | 95 completed_ts = messages.IntegerField(15) |
| 96 created_by = messages.StringField(16) | 96 created_by = messages.StringField(16) |
| 97 status_changed_ts = messages.IntegerField(17) | 97 status_changed_ts = messages.IntegerField(17) |
| 98 utcnow_ts = messages.IntegerField(18, required=True) | 98 utcnow_ts = messages.IntegerField(18, required=True) |
| 99 retry_of = messages.IntegerField(19) |
| 99 | 100 |
| 100 | 101 |
| 101 class BuildResponseMessage(messages.Message): | 102 class BuildResponseMessage(messages.Message): |
| 102 build = messages.MessageField(BuildMessage, 1) | 103 build = messages.MessageField(BuildMessage, 1) |
| 103 error = messages.MessageField(ErrorMessage, 2) | 104 error = messages.MessageField(ErrorMessage, 2) |
| 104 | 105 |
| 105 | 106 |
| 106 def build_to_message(build, include_lease_key=False): | 107 def build_to_message(build, include_lease_key=False): |
| 107 """Converts model.Build to BuildMessage.""" | 108 """Converts model.Build to BuildMessage.""" |
| 108 assert build | 109 assert build |
| (...skipping 11 matching lines...) Expand all Loading... |
| 120 cancelation_reason=build.cancelation_reason, | 121 cancelation_reason=build.cancelation_reason, |
| 121 failure_reason=build.failure_reason, | 122 failure_reason=build.failure_reason, |
| 122 lease_key=build.lease_key if include_lease_key else None, | 123 lease_key=build.lease_key if include_lease_key else None, |
| 123 url=build.url, | 124 url=build.url, |
| 124 created_ts=datetime_to_timestamp_safe(build.create_time), | 125 created_ts=datetime_to_timestamp_safe(build.create_time), |
| 125 updated_ts=datetime_to_timestamp_safe(build.update_time), | 126 updated_ts=datetime_to_timestamp_safe(build.update_time), |
| 126 completed_ts=datetime_to_timestamp_safe(build.complete_time), | 127 completed_ts=datetime_to_timestamp_safe(build.complete_time), |
| 127 created_by=build.created_by.to_bytes() if build.created_by else None, | 128 created_by=build.created_by.to_bytes() if build.created_by else None, |
| 128 status_changed_ts=datetime_to_timestamp_safe(build.status_changed_time), | 129 status_changed_ts=datetime_to_timestamp_safe(build.status_changed_time), |
| 129 utcnow_ts=datetime_to_timestamp_safe(utils.utcnow()), | 130 utcnow_ts=datetime_to_timestamp_safe(utils.utcnow()), |
| 131 retry_of=build.retry_of, |
| 130 ) | 132 ) |
| 131 if build.lease_expiration_date is not None: | 133 if build.lease_expiration_date is not None: |
| 132 msg.lease_expiration_ts = utils.datetime_to_timestamp( | 134 msg.lease_expiration_ts = utils.datetime_to_timestamp( |
| 133 build.lease_expiration_date) | 135 build.lease_expiration_date) |
| 134 return msg | 136 return msg |
| 135 | 137 |
| 136 | 138 |
| 137 def build_to_response_message(build, include_lease_key=False): | 139 def build_to_response_message(build, include_lease_key=False): |
| 138 return BuildResponseMessage(build=build_to_message(build, include_lease_key)) | 140 return BuildResponseMessage(build=build_to_message(build, include_lease_key)) |
| 139 | 141 |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 one_res.build = build_to_message(build, include_lease_key=True) | 282 one_res.build = build_to_message(build, include_lease_key=True) |
| 281 except errors.Error as ex: | 283 except errors.Error as ex: |
| 282 one_res.error = exception_to_error_message(ex) | 284 one_res.error = exception_to_error_message(ex) |
| 283 return one_res | 285 return one_res |
| 284 | 286 |
| 285 res.results = [ | 287 res.results = [ |
| 286 to_msg(req, build) | 288 to_msg(req, build) |
| 287 for req, build in zip(request.builds, build_futures)] | 289 for req, build in zip(request.builds, build_futures)] |
| 288 return res | 290 return res |
| 289 | 291 |
| 292 ################################## RETRY ################################## |
| 293 |
| 294 class RetryRequestMessage(messages.Message): |
| 295 client_operation_id = messages.StringField(1) |
| 296 lease_expiration_ts = messages.IntegerField(2) |
| 297 pubsub_callback = messages.MessageField(PubSubCallbackMessage, 3) |
| 298 |
| 299 @buildbucket_api_method( |
| 300 id_resource_container(RetryRequestMessage), |
| 301 BuildResponseMessage, |
| 302 path='builds/{id}/retry', http_method='PUT') |
| 303 @auth.public |
| 304 def retry(self, request): |
| 305 """Retries an existing build.""" |
| 306 build = service.retry( |
| 307 request.id, |
| 308 lease_expiration_date=parse_datetime(request.lease_expiration_ts), |
| 309 client_operation_id=request.client_operation_id, |
| 310 pubsub_callback=pubsub_callback_from_message(request.pubsub_callback), |
| 311 ) |
| 312 return build_to_response_message(build, include_lease_key=True) |
| 313 |
| 314 |
| 290 ################################## SEARCH ################################# | 315 ################################## SEARCH ################################# |
| 291 | 316 |
| 292 | 317 |
| 293 SEARCH_REQUEST_RESOURCE_CONTAINER = endpoints.ResourceContainer( | 318 SEARCH_REQUEST_RESOURCE_CONTAINER = endpoints.ResourceContainer( |
| 294 message_types.VoidMessage, | 319 message_types.VoidMessage, |
| 295 start_cursor=messages.StringField(1), | 320 start_cursor=messages.StringField(1), |
| 296 bucket=messages.StringField(2, repeated=True), | 321 bucket=messages.StringField(2, repeated=True), |
| 297 # All specified tags must be present in a build. | 322 # All specified tags must be present in a build. |
| 298 tag=messages.StringField(3, repeated=True), | 323 tag=messages.StringField(3, repeated=True), |
| 299 status=messages.EnumField(model.BuildStatus, 4), | 324 status=messages.EnumField(model.BuildStatus, 4), |
| 300 result=messages.EnumField(model.BuildResult, 5), | 325 result=messages.EnumField(model.BuildResult, 5), |
| 301 cancelation_reason=messages.EnumField(model.CancelationReason, 6), | 326 cancelation_reason=messages.EnumField(model.CancelationReason, 6), |
| 302 failure_reason=messages.EnumField(model.FailureReason, 7), | 327 failure_reason=messages.EnumField(model.FailureReason, 7), |
| 303 created_by=messages.StringField(8), | 328 created_by=messages.StringField(8), |
| 304 max_builds=messages.IntegerField(9, variant=messages.Variant.INT32), | 329 max_builds=messages.IntegerField(9, variant=messages.Variant.INT32), |
| 330 retry_of=messages.IntegerField(10), |
| 305 ) | 331 ) |
| 306 | 332 |
| 307 class SearchResponseMessage(messages.Message): | 333 class SearchResponseMessage(messages.Message): |
| 308 builds = messages.MessageField(BuildMessage, 1, repeated=True) | 334 builds = messages.MessageField(BuildMessage, 1, repeated=True) |
| 309 next_cursor = messages.StringField(2) | 335 next_cursor = messages.StringField(2) |
| 310 error = messages.MessageField(ErrorMessage, 3) | 336 error = messages.MessageField(ErrorMessage, 3) |
| 311 | 337 |
| 312 @buildbucket_api_method( | 338 @buildbucket_api_method( |
| 313 SEARCH_REQUEST_RESOURCE_CONTAINER, SearchResponseMessage, | 339 SEARCH_REQUEST_RESOURCE_CONTAINER, SearchResponseMessage, |
| 314 path='search', http_method='GET') | 340 path='search', http_method='GET') |
| 315 @auth.public | 341 @auth.public |
| 316 def search(self, request): | 342 def search(self, request): |
| 317 """Searches for builds.""" | 343 """Searches for builds.""" |
| 318 assert isinstance(request.tag, list) | 344 assert isinstance(request.tag, list) |
| 319 builds, next_cursor = service.search( | 345 builds, next_cursor = service.search( |
| 320 buckets=request.bucket, | 346 buckets=request.bucket, |
| 321 tags=request.tag, | 347 tags=request.tag, |
| 322 status=request.status, | 348 status=request.status, |
| 323 result=request.result, | 349 result=request.result, |
| 324 failure_reason=request.failure_reason, | 350 failure_reason=request.failure_reason, |
| 325 cancelation_reason=request.cancelation_reason, | 351 cancelation_reason=request.cancelation_reason, |
| 326 max_builds=request.max_builds, | 352 max_builds=request.max_builds, |
| 327 created_by=request.created_by, | 353 created_by=request.created_by, |
| 328 start_cursor=request.start_cursor) | 354 start_cursor=request.start_cursor, |
| 355 retry_of=request.retry_of, |
| 356 ) |
| 329 return self.SearchResponseMessage( | 357 return self.SearchResponseMessage( |
| 330 builds=map(build_to_message, builds), | 358 builds=map(build_to_message, builds), |
| 331 next_cursor=next_cursor, | 359 next_cursor=next_cursor, |
| 332 ) | 360 ) |
| 333 | 361 |
| 334 ################################### PEEK ################################### | 362 ################################### PEEK ################################### |
| 335 | 363 |
| 336 PEEK_REQUEST_RESOURCE_CONTAINER = endpoints.ResourceContainer( | 364 PEEK_REQUEST_RESOURCE_CONTAINER = endpoints.ResourceContainer( |
| 337 message_types.VoidMessage, | 365 message_types.VoidMessage, |
| 338 bucket=messages.StringField(1, repeated=True), | 366 bucket=messages.StringField(1, repeated=True), |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 ), | 607 ), |
| 580 DeleteManyBuildsResponse, | 608 DeleteManyBuildsResponse, |
| 581 path='bucket/{bucket}/delete', http_method='POST') | 609 path='bucket/{bucket}/delete', http_method='POST') |
| 582 @auth.public | 610 @auth.public |
| 583 def delete_many_builds(self, request): | 611 def delete_many_builds(self, request): |
| 584 """Deletes scheduled or started builds in a bucket.""" | 612 """Deletes scheduled or started builds in a bucket.""" |
| 585 service.delete_many_builds( | 613 service.delete_many_builds( |
| 586 request.bucket, request.status, | 614 request.bucket, request.status, |
| 587 tags=request.tag[:], created_by=request.created_by) | 615 tags=request.tag[:], created_by=request.created_by) |
| 588 return self.DeleteManyBuildsResponse() | 616 return self.DeleteManyBuildsResponse() |
| OLD | NEW |