From 04fddfa508a17ca98a89e5938a84e482ebbcaec9 Mon Sep 17 00:00:00 2001 From: finn <finn.ball@codethink.com> Date: Tue, 31 Jul 2018 11:39:19 +0100 Subject: [PATCH] Update BuildGrid to Remote Execution API v2 --- app/commands/cmd_bot.py | 2 +- app/commands/cmd_execute.py | 35 ++++++------------- buildgrid/server/build_grid_server.py | 2 +- buildgrid/server/cas/bytestream_service.py | 2 +- .../content_addressable_storage_service.py | 6 ++-- .../server/execution/action_cache_service.py | 2 +- .../server/execution/execution_instance.py | 4 +-- .../server/execution/execution_service.py | 10 +++--- buildgrid/server/job.py | 4 +-- tests/cas/test_services.py | 18 +++++----- tests/cas/test_storage.py | 2 +- tests/integration/action_cache_service.py | 2 +- tests/integration/bots_service.py | 2 +- tests/integration/execution_service.py | 30 ++++++++-------- tests/integration/operations_service.py | 17 ++++----- 15 files changed, 62 insertions(+), 76 deletions(-) diff --git a/app/commands/cmd_bot.py b/app/commands/cmd_bot.py index 47176db30..c83d60ca2 100644 --- a/app/commands/cmd_bot.py +++ b/app/commands/cmd_bot.py @@ -39,7 +39,7 @@ from buildgrid._exceptions import BotError from ..cli import pass_context from buildgrid._protos.google.bytestream import bytestream_pb2, bytestream_pb2_grpc -from buildgrid._protos.google.devtools.remoteexecution.v1test import remote_execution_pb2, remote_execution_pb2_grpc +from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2, remote_execution_pb2_grpc from google.protobuf import any_pb2 @click.group(short_help = 'Create a bot client') diff --git a/app/commands/cmd_execute.py b/app/commands/cmd_execute.py index a31eca77a..196ea9d46 100644 --- a/app/commands/cmd_execute.py +++ b/app/commands/cmd_execute.py @@ -30,8 +30,8 @@ import time from ..cli import pass_context -from buildgrid._protos.google.devtools.remoteexecution.v1test import remote_execution_pb2, remote_execution_pb2_grpc -from buildgrid._protos.google.devtools.remoteexecution.v1test.remote_execution_pb2 import ExecuteOperationMetadata +from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2, remote_execution_pb2_grpc +from buildgrid._protos.build.bazel.remote.execution.v2.remote_execution_pb2 import ExecuteOperationMetadata from buildgrid._protos.google.longrunning import operations_pb2, operations_pb2_grpc from google.protobuf import any_pb2 @@ -52,25 +52,19 @@ def cli(context, host, port): @click.option('--wait-for-completion', is_flag=True) @pass_context def request(context, number, instance_name, wait_for_completion): + action_digest = remote_execution_pb2.Digest() + action_digest.hash = 'zhora' + context.logger.info("Sending execution request...\n") stub = remote_execution_pb2_grpc.ExecutionStub(context.channel) - action = remote_execution_pb2.Action(command_digest = None, - input_root_digest = None, - output_files = [], - output_directories = None, - platform = None, - timeout = None, - do_not_cache = True) - - action.command_digest.hash = 'foo' - request = remote_execution_pb2.ExecuteRequest(instance_name = instance_name, - action = action, + action_digest = action_digest, skip_cache_lookup = True) for i in range(0, number): response = stub.Execute(request) - context.logger.info("Response name: {}".format(response.name)) + for r in response: + context.logger.info(r) try: while wait_for_completion: @@ -96,7 +90,7 @@ def operation_status(context, operation_name): request = operations_pb2.GetOperationRequest(name=operation_name) response = stub.GetOperation(request) - _log_operation(context, response) + context.logger.info(response) @cli.command('list', short_help='List operations') @pass_context @@ -113,13 +107,4 @@ def list_operations(context): return for op in response.operations: - _log_operation(context, op) - -def _log_operation(context, operation): - op_meta = ExecuteOperationMetadata() - operation.metadata.Unpack(op_meta) - - context.logger.info("Name : {}".format(operation.name)) - context.logger.info("Done : {}".format(operation.done)) - context.logger.info("Stage : {}".format(ExecuteOperationMetadata.Stage.Name(op_meta.stage))) - context.logger.info("Key : {}".format(operation.response)) + context.logger.info(op) diff --git a/buildgrid/server/build_grid_server.py b/buildgrid/server/build_grid_server.py index 406fbb35d..73273778d 100644 --- a/buildgrid/server/build_grid_server.py +++ b/buildgrid/server/build_grid_server.py @@ -27,7 +27,7 @@ import grpc from concurrent import futures from buildgrid._protos.google.bytestream import bytestream_pb2_grpc -from buildgrid._protos.google.devtools.remoteexecution.v1test import remote_execution_pb2_grpc +from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2_grpc from buildgrid._protos.google.devtools.remoteworkers.v1test2 import bots_pb2_grpc from buildgrid._protos.google.longrunning import operations_pb2_grpc diff --git a/buildgrid/server/cas/bytestream_service.py b/buildgrid/server/cas/bytestream_service.py index 5b90bc4a5..adcd13545 100644 --- a/buildgrid/server/cas/bytestream_service.py +++ b/buildgrid/server/cas/bytestream_service.py @@ -25,7 +25,7 @@ CAS blobs. import grpc from buildgrid._protos.google.bytestream import bytestream_pb2, bytestream_pb2_grpc -from buildgrid._protos.google.devtools.remoteexecution.v1test import remote_execution_pb2 as re_pb2, remote_execution_pb2_grpc as re_pb2_grpc +from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2 as re_pb2, remote_execution_pb2_grpc as re_pb2_grpc from ...settings import HASH diff --git a/buildgrid/server/cas/content_addressable_storage_service.py b/buildgrid/server/cas/content_addressable_storage_service.py index ae2bcc250..5c8cddf64 100644 --- a/buildgrid/server/cas/content_addressable_storage_service.py +++ b/buildgrid/server/cas/content_addressable_storage_service.py @@ -24,7 +24,7 @@ to check for missing CAS blobs and update them in bulk. """ import grpc -from buildgrid._protos.google.devtools.remoteexecution.v1test import remote_execution_pb2 as re_pb2, remote_execution_pb2_grpc as re_pb2_grpc +from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2 as re_pb2, remote_execution_pb2_grpc as re_pb2_grpc class ContentAddressableStorageService(re_pb2_grpc.ContentAddressableStorageServicer): @@ -42,10 +42,10 @@ class ContentAddressableStorageService(re_pb2_grpc.ContentAddressableStorageServ storage = self._storage requests = [] for request_proto in request.requests: - requests.append((request_proto.content_digest, request_proto.data)) + requests.append((request_proto.digest, request_proto.data)) response = re_pb2.BatchUpdateBlobsResponse() for (digest, _), status in zip(requests, storage.bulk_update_blobs(requests)): response_proto = response.responses.add() - response_proto.blob_digest.CopyFrom(digest) + response_proto.digest.CopyFrom(digest) response_proto.status.CopyFrom(status) return response diff --git a/buildgrid/server/execution/action_cache_service.py b/buildgrid/server/execution/action_cache_service.py index 0f6f897fa..64fddbe9a 100644 --- a/buildgrid/server/execution/action_cache_service.py +++ b/buildgrid/server/execution/action_cache_service.py @@ -25,7 +25,7 @@ Action Cache currently not implemented. import logging import grpc -from buildgrid._protos.google.devtools.remoteexecution.v1test import remote_execution_pb2, remote_execution_pb2_grpc +from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2, remote_execution_pb2_grpc class ActionCacheService(remote_execution_pb2_grpc.ActionCacheServicer): diff --git a/buildgrid/server/execution/execution_instance.py b/buildgrid/server/execution/execution_instance.py index 0203e9af1..5dc486e4d 100644 --- a/buildgrid/server/execution/execution_instance.py +++ b/buildgrid/server/execution/execution_instance.py @@ -34,12 +34,12 @@ class ExecutionInstance(): self.logger = logging.getLogger(__name__) self._scheduler = scheduler - def execute(self, action, skip_cache_lookup): + def execute(self, action_digest, skip_cache_lookup): """ Sends a job for execution. Queues an action and creates an Operation instance to be associated with this action. """ - job = Job(action) + job = Job(action_digest) self.logger.info("Operation name: {}".format(job.name)) if not skip_cache_lookup: diff --git a/buildgrid/server/execution/execution_service.py b/buildgrid/server/execution/execution_service.py index 3e72787f7..af00a72bb 100644 --- a/buildgrid/server/execution/execution_service.py +++ b/buildgrid/server/execution/execution_service.py @@ -25,7 +25,7 @@ Serves remote execution requests. import grpc import logging -from buildgrid._protos.google.devtools.remoteexecution.v1test import remote_execution_pb2, remote_execution_pb2_grpc +from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2, remote_execution_pb2_grpc from buildgrid._protos.google.longrunning import operations_pb2_grpc, operations_pb2 from ._exceptions import InvalidArgumentError @@ -40,17 +40,17 @@ class ExecutionService(remote_execution_pb2_grpc.ExecutionServicer): # Ignore request.instance_name for now # Have only one instance try: - return self._instance.execute(request.action, - request.skip_cache_lookup) + yield self._instance.execute(request.action_digest, + request.skip_cache_lookup) except InvalidArgumentError as e: self.logger.error(e) context.set_details(str(e)) context.set_code(grpc.StatusCode.INVALID_ARGUMENT) - return operations_pb2.Operation() + yield operations_pb2.Operation() except NotImplementedError as e: self.logger.error(e) context.set_details(str(e)) context.set_code(grpc.StatusCode.UNIMPLEMENTED) - return operations_pb2.Operation() + yield operations_pb2.Operation() diff --git a/buildgrid/server/job.py b/buildgrid/server/job.py index 2a94baf79..8b5319cba 100644 --- a/buildgrid/server/job.py +++ b/buildgrid/server/job.py @@ -18,11 +18,11 @@ import logging import uuid -import buildgrid._protos.google.devtools.remoteexecution.v1test.remote_execution_pb2 +import buildgrid._protos.build.bazel.remote.execution.v2.remote_execution_pb2 from enum import Enum -from buildgrid._protos.google.devtools.remoteexecution.v1test.remote_execution_pb2 import ExecuteOperationMetadata, ExecuteResponse +from buildgrid._protos.build.bazel.remote.execution.v2.remote_execution_pb2 import ExecuteOperationMetadata, ExecuteResponse from buildgrid._protos.google.devtools.remoteworkers.v1test2 import bots_pb2, worker_pb2 from buildgrid._protos.google.longrunning import operations_pb2 from google.protobuf import any_pb2 diff --git a/tests/cas/test_services.py b/tests/cas/test_services.py index f28bb4afb..ad42d5b5c 100644 --- a/tests/cas/test_services.py +++ b/tests/cas/test_services.py @@ -18,7 +18,7 @@ import io from buildgrid._protos.google.bytestream import bytestream_pb2 -from buildgrid._protos.google.devtools.remoteexecution.v1test import remote_execution_pb2 as re_pb2 +from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2 as re_pb2 import pytest from buildgrid.server.cas.storage.storage_abc import StorageABC @@ -170,22 +170,22 @@ def test_cas_batch_update_blobs(instance): storage = SimpleStorage() servicer = ContentAddressableStorageService(storage) update_requests = [ - re_pb2.UpdateBlobRequest( - content_digest=re_pb2.Digest(hash=HASH(b'abc').hexdigest(), size_bytes=3), data=b'abc'), - re_pb2.UpdateBlobRequest( - content_digest=re_pb2.Digest(hash="invalid digest!", size_bytes=1000), + re_pb2.BatchUpdateBlobsRequest.Request( + digest=re_pb2.Digest(hash=HASH(b'abc').hexdigest(), size_bytes=3), data=b'abc'), + re_pb2.BatchUpdateBlobsRequest.Request( + digest=re_pb2.Digest(hash="invalid digest!", size_bytes=1000), data=b'wrong data') ] request = re_pb2.BatchUpdateBlobsRequest(instance_name=instance, requests=update_requests) response = servicer.BatchUpdateBlobs(request, None) assert len(response.responses) == 2 for blob_response in response.responses: - if blob_response.blob_digest == update_requests[0].content_digest: + if blob_response.digest == update_requests[0].digest: assert blob_response.status.code == 0 - elif blob_response.blob_digest == update_requests[1].content_digest: + elif blob_response.digest == update_requests[1].digest: assert blob_response.status.code != 0 else: raise Exception("Unexpected blob response") assert len(storage.data) == 1 - assert (update_requests[0].content_digest.hash, 3) in storage.data - assert storage.data[(update_requests[0].content_digest.hash, 3)] == b'abc' + assert (update_requests[0].digest.hash, 3) in storage.data + assert storage.data[(update_requests[0].digest.hash, 3)] == b'abc' diff --git a/tests/cas/test_storage.py b/tests/cas/test_storage.py index 576a6072b..3847d35a9 100644 --- a/tests/cas/test_storage.py +++ b/tests/cas/test_storage.py @@ -18,7 +18,7 @@ import tempfile import boto3 -from buildgrid._protos.google.devtools.remoteexecution.v1test.remote_execution_pb2 import Digest +from buildgrid._protos.build.bazel.remote.execution.v2.remote_execution_pb2 import Digest from moto import mock_s3 import pytest diff --git a/tests/integration/action_cache_service.py b/tests/integration/action_cache_service.py index afe8892a1..6ddd2f29b 100644 --- a/tests/integration/action_cache_service.py +++ b/tests/integration/action_cache_service.py @@ -21,7 +21,7 @@ import pytest from unittest import mock from grpc._server import _Context -from buildgrid._protos.google.devtools.remoteexecution.v1test import remote_execution_pb2 +from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2 from buildgrid.server import scheduler from buildgrid.server.execution import execution_instance, action_cache_service diff --git a/tests/integration/bots_service.py b/tests/integration/bots_service.py index 33655364f..836912395 100644 --- a/tests/integration/bots_service.py +++ b/tests/integration/bots_service.py @@ -23,7 +23,7 @@ import uuid from unittest import mock from grpc._server import _Context -from buildgrid._protos.google.devtools.remoteexecution.v1test import remote_execution_pb2 +from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2 from buildgrid._protos.google.devtools.remoteworkers.v1test2 import bots_pb2, worker_pb2 from google.protobuf import any_pb2 diff --git a/tests/integration/execution_service.py b/tests/integration/execution_service.py index 3672d244d..08d41231a 100644 --- a/tests/integration/execution_service.py +++ b/tests/integration/execution_service.py @@ -22,7 +22,7 @@ import uuid from unittest import mock from grpc._server import _Context -from buildgrid._protos.google.devtools.remoteexecution.v1test import remote_execution_pb2 +from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2 from buildgrid._protos.google.longrunning import operations_pb2 from google.protobuf import any_pb2 @@ -49,22 +49,22 @@ def instance(execution): @pytest.mark.parametrize("skip_cache_lookup", [True, False]) def test_execute(skip_cache_lookup, instance, context): - action = remote_execution_pb2.Action() - action.command_digest.hash = 'zhora' + action_digest = remote_execution_pb2.Digest() + action_digest.hash = 'zhora' request = remote_execution_pb2.ExecuteRequest(instance_name = '', - action = action, + action_digest = action_digest, skip_cache_lookup = skip_cache_lookup) + response = instance.Execute(request, context) - result = instance.Execute(request, context) + for result in response: + assert isinstance(result, operations_pb2.Operation) - assert isinstance(result, operations_pb2.Operation) - - if skip_cache_lookup is False: - context.set_code.assert_called_once_with(grpc.StatusCode.UNIMPLEMENTED) - else: - metadata = remote_execution_pb2.ExecuteOperationMetadata() - result.metadata.Unpack(metadata) - assert metadata.stage == job.ExecuteStage.QUEUED.value - assert uuid.UUID(result.name, version=4) - assert result.done is False + if skip_cache_lookup is False: + context.set_code.assert_called_once_with(grpc.StatusCode.UNIMPLEMENTED) + else: + metadata = remote_execution_pb2.ExecuteOperationMetadata() + result.metadata.Unpack(metadata) + assert metadata.stage == job.ExecuteStage.QUEUED.value + assert uuid.UUID(result.name, version=4) + assert result.done is False diff --git a/tests/integration/operations_service.py b/tests/integration/operations_service.py index aa8674fc1..246e354ed 100644 --- a/tests/integration/operations_service.py +++ b/tests/integration/operations_service.py @@ -21,7 +21,7 @@ import pytest from unittest import mock from grpc._server import _Context -from buildgrid._protos.google.devtools.remoteexecution.v1test import remote_execution_pb2 +from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2 from buildgrid._protos.google.longrunning import operations_pb2 from buildgrid.server import scheduler, job @@ -37,11 +37,11 @@ def context(): # Requests to make @pytest.fixture def execute_request(): - action = remote_execution_pb2.Action() - action.command_digest.hash = 'zhora' + action_digest = remote_execution_pb2.Digest() + action_digest.hash = 'zhora' yield remote_execution_pb2.ExecuteRequest(instance_name = '', - action = action, + action_digest = action_digest, skip_cache_lookup = True) @pytest.fixture @@ -59,10 +59,11 @@ def instance(execution): # Queue an execution, get operation corresponding to that request def test_get_operation(instance, execute_request, context): - response_execute = instance._instance.execute(execute_request.action, + response_execute = instance._instance.execute(execute_request.action_digest, execute_request.skip_cache_lookup) request = operations_pb2.GetOperationRequest() + request.name = response_execute.name response = instance.GetOperation(request, context) @@ -75,7 +76,7 @@ def test_get_operation_fail(instance, context): context.set_code.assert_called_once_with(grpc.StatusCode.INVALID_ARGUMENT) def test_list_operations(instance, execute_request, context): - response_execute = instance._instance.execute(execute_request.action, + response_execute = instance._instance.execute(execute_request.action_digest, execute_request.skip_cache_lookup) request = operations_pb2.ListOperationsRequest() @@ -84,7 +85,7 @@ def test_list_operations(instance, execute_request, context): assert response.operations[0].name == response_execute.name def test_list_operations_with_result(instance, execute_request, context): - response_execute = instance._instance.execute(execute_request.action, + response_execute = instance._instance.execute(execute_request.action_digest, execute_request.skip_cache_lookup) action_result = remote_execution_pb2.ActionResult() @@ -109,7 +110,7 @@ def test_list_operations_empty(instance, context): # Send execution off, delete, try to find operation should fail def test_delete_operation(instance, execute_request, context): - response_execute = instance._instance.execute(execute_request.action, + response_execute = instance._instance.execute(execute_request.action_digest, execute_request.skip_cache_lookup) request = operations_pb2.DeleteOperationRequest() request.name = response_execute.name -- GitLab