Beispiel #1
0
    def cancel(self, build_id):
        """Cancels build. Does not require a lease key.

    The current user has to have a permission to cancel a build in the
    bucket.

    Returns:
      Canceled Build.
    """
        build = model.Build.get_by_id(build_id)
        if build is None:
            raise errors.BuildNotFoundError()
        if not acl.can_cancel_build(build):
            raise current_identity_cannot('cancel build %s', build.key.id())
        if build.status == model.BuildStatus.COMPLETED:
            if build.result == model.BuildResult.CANCELED:
                return build
            raise errors.BuildIsCompletedError(
                'Cannot cancel a completed build')
        build.status = model.BuildStatus.COMPLETED
        build.status_changed_time = utils.utcnow()
        build.result = model.BuildResult.CANCELED
        build.cancelation_reason = model.CancelationReason.CANCELED_EXPLICITLY
        self._clear_lease(build)
        build.put()
        logging.info('Build %s was cancelled by %s', build.key.id(),
                     auth.get_current_identity().to_bytes())
        return build
Beispiel #2
0
    def heartbeat_async(self, build_id, lease_key, lease_expiration_date):
        """Extends build lease.

    Args:
      build_id: id of the build.
      lease_key: current lease key.
      lease_expiration_date (datetime.timedelta): new lease expiration date.

    Returns:
      The updated Build as Future.
    """
        try:
            validate_lease_key(lease_key)
            if lease_expiration_date is None:
                raise errors.InvalidInputError(
                    'Lease expiration date not specified')
            validate_lease_expiration_date(lease_expiration_date)
            build = yield model.Build.get_by_id_async(build_id)
            if build is None:
                raise errors.BuildNotFoundError()
            if build.status == model.BuildStatus.COMPLETED:
                raise errors.BuildIsCompletedError()
            self._check_lease(build, lease_key)
            build.lease_expiration_date = lease_expiration_date
            yield build.put_async()
        except Exception as ex:
            logging.warning('Heartbeat for build %s failed: %s', build_id, ex)
            raise
        raise ndb.Return(build)
Beispiel #3
0
 def _get_leasable_build(self, build_id):
     build = model.Build.get_by_id(build_id)
     if build is None:
         raise errors.BuildNotFoundError()
     if not acl.can_lease_build(build):
         raise current_identity_cannot('lease build %s', build.key.id())
     return build
Beispiel #4
0
def _get_leasable_build(build_id):
    build = model.Build.get_by_id(build_id)
    if build is None:
        raise errors.BuildNotFoundError()
    if not user.can_lease_build_async(build).get_result():
        raise user.current_identity_cannot('lease build %s', build.key.id())
    if build.is_luci:
        raise errors.InvalidInputError('cannot lease a swarmbucket build')
    return build
Beispiel #5
0
 def get(self, request):
     """Returns a build by id."""
     try:
         build = service.get_async(request.id).get_result()
     except auth.AuthorizationError:
         build = None
     if build is None:
         raise errors.BuildNotFoundError()
     return build_to_response_message(build)
Beispiel #6
0
 def get_build_async(check_access):
     build = yield model.Build.get_by_id_async(build_id)
     if build is None:
         raise errors.BuildNotFoundError()
     if check_access and not (yield user.can_cancel_build_async(build)):
         raise user.current_identity_cannot('cancel build %s',
                                            build.key.id())
     if build.proto.status == common_pb2.CANCELED:
         raise ndb.Return(build, False)
     if build.is_ended:
         raise errors.BuildIsCompletedError(
             'Cannot cancel a completed build')
     raise ndb.Return(build, True)
Beispiel #7
0
    def retry(self, request):
        """Retries an existing build."""
        lease_expiration_date = parse_datetime(request.lease_expiration_ts)
        errors.validate_lease_expiration_date(lease_expiration_date)

        build = model.Build.get_by_id(request.id)
        if not build:
            raise errors.BuildNotFoundError('Build %s not found' % request.id)

        check_scheduling_permissions([build.bucket_id])

        # Prepare v2 request.
        sbr = rpc_pb2.ScheduleBuildRequest(
            builder=build.proto.builder,
            request_id=request.client_operation_id,
            canary=common_pb2.YES if build.canary else common_pb2.NO,
            properties=build.proto.input.properties,
            gerrit_changes=build.proto.input.gerrit_changes[:],
        )
        build.tags_to_protos(sbr.tags)
        if build.input_properties_bytes:  # pragma: no branch
            sbr.properties.ParseFromString(build.input_properties_bytes)
        if build.proto.input.HasField('gitiles_commit'):  # pragma: no branch
            sbr.gitiles_commit.CopyFrom(build.proto.input.gitiles_commit)

        # Read PubSub callback.
        pubsub_callback_auth_token = None
        if request.pubsub_callback:  # pragma: no branch
            pubsub_callback_auth_token = request.pubsub_callback.auth_token
            pubsub_callback_to_notification_config(request.pubsub_callback,
                                                   sbr.notify)
            with _wrap_validation_error():
                validation.validate_notification_config(sbr.notify)

        # Remove properties from parameters.
        params = build.parameters.copy()
        params.pop(model.PROPERTIES_PARAMETER, None)

        # Create the build.
        build_req = creation.BuildRequest(
            schedule_build_request=sbr,
            parameters=params,
            lease_expiration_date=lease_expiration_date,
            retry_of=request.id,
            pubsub_callback_auth_token=pubsub_callback_auth_token,
        )
        build = creation.add_async(build_req).get_result()
        return build_to_response_message(build, include_lease_key=True)
Beispiel #8
0
 def txn():
     validate_lease_key(lease_key)
     if lease_expiration_date is None:
         raise errors.InvalidInputError(
             'Lease expiration date not specified')
     errors.validate_lease_expiration_date(lease_expiration_date)
     build = yield model.Build.get_by_id_async(build_id)
     if build is None:
         raise errors.BuildNotFoundError()
     if build.is_ended:
         msg = ''
         if (build.result == model.BuildResult.CANCELED
                 and build.cancelation_reason
                 == model.CancelationReason.TIMEOUT):
             msg = ('Build was marked as timed out '
                    'because it did not complete for %s' %
                    model.BUILD_TIMEOUT)
         raise errors.BuildIsCompletedError(msg)
     _check_lease(build, lease_key)
     build.lease_expiration_date = lease_expiration_date
     yield build.put_async()
     raise ndb.Return(build)
Beispiel #9
0
 def get(self, request):
     """Returns a build by id."""
     build = service.get(request.id)
     if build is None:
         raise errors.BuildNotFoundError()
     return build_to_response_message(build)