[Notes] [Git][BuildGrid/buildgrid][mablanch/68-bots-multi-endpoints] cmd_bot.py: Allow separate CAS server for any bot



Title: GitLab

Martin Blanchard pushed to branch mablanch/68-bots-multi-endpoints at BuildGrid / buildgrid

Commits:

3 changed files:

Changes:

  • buildgrid/_app/bots/buildbox.py
    ... ... @@ -16,13 +16,12 @@
    16 16
     import os
    
    17 17
     import subprocess
    
    18 18
     import tempfile
    
    19
    -import grpc
    
    20 19
     
    
    21 20
     from google.protobuf import any_pb2
    
    22 21
     
    
    23 22
     from buildgrid._protos.build.bazel.remote.execution.v2 import remote_execution_pb2
    
    24 23
     from buildgrid._protos.google.bytestream import bytestream_pb2_grpc
    
    25
    -from buildgrid.utils import read_file, parse_to_pb2_from_fetch
    
    24
    +from buildgrid.utils import parse_to_pb2_from_fetch
    
    26 25
     
    
    27 26
     
    
    28 27
     def work_buildbox(context, lease):
    
    ... ... @@ -32,18 +31,7 @@ def work_buildbox(context, lease):
    32 31
         action_digest = remote_execution_pb2.Digest()
    
    33 32
         action_digest_any.Unpack(action_digest)
    
    34 33
     
    
    35
    -    cert_server = read_file(context.server_cert)
    
    36
    -    cert_client = read_file(context.client_cert)
    
    37
    -    key_client = read_file(context.client_key)
    
    38
    -
    
    39
    -    # create server credentials
    
    40
    -    credentials = grpc.ssl_channel_credentials(root_certificates=cert_server,
    
    41
    -                                               private_key=key_client,
    
    42
    -                                               certificate_chain=cert_client)
    
    43
    -
    
    44
    -    channel = grpc.secure_channel('{}:{}'.format(context.remote, context.port), credentials)
    
    45
    -
    
    46
    -    stub = bytestream_pb2_grpc.ByteStreamStub(channel)
    
    34
    +    stub = bytestream_pb2_grpc.ByteStreamStub(context.cas_channel)
    
    47 35
     
    
    48 36
         action = remote_execution_pb2.Action()
    
    49 37
         parse_to_pb2_from_fetch(action, stub, action_digest)
    
    ... ... @@ -66,13 +54,18 @@ def work_buildbox(context, lease):
    66 54
     
    
    67 55
             with tempfile.NamedTemporaryFile(dir=os.path.join(casdir, 'tmp')) as output_digest_file:
    
    68 56
                 command = ['buildbox',
    
    69
    -                       '--remote={}'.format('https://{}:{}'.format(context.remote, context.port)),
    
    70
    -                       '--server-cert={}'.format(context.server_cert),
    
    71
    -                       '--client-key={}'.format(context.client_key),
    
    72
    -                       '--client-cert={}'.format(context.client_cert),
    
    57
    +                       '--remote={}'.format(context.cas_remote_url),
    
    73 58
                            '--input-digest={}'.format(input_digest_file.name),
    
    74 59
                            '--output-digest={}'.format(output_digest_file.name),
    
    75 60
                            '--local={}'.format(casdir)]
    
    61
    +
    
    62
    +            if context.cas_client_key:
    
    63
    +                command.append('--client-key={}'.format(context.cas_client_key))
    
    64
    +            if context.cas_client_cert:
    
    65
    +                command.append('--client-cert={}'.format(context.cas_client_cert))
    
    66
    +            if context.cas_server_cert:
    
    67
    +                command.append('--server-cert={}'.format(context.cas_server_cert))
    
    68
    +
    
    76 69
                 if 'PWD' in environment and environment['PWD']:
    
    77 70
                     command.append('--chdir={}'.format(environment['PWD']))
    
    78 71
     
    

  • buildgrid/_app/bots/temp_directory.py
    ... ... @@ -30,7 +30,7 @@ def work_temp_directory(context, lease):
    30 30
         """
    
    31 31
     
    
    32 32
         parent = context.parent
    
    33
    -    stub_bytestream = bytestream_pb2_grpc.ByteStreamStub(context.channel)
    
    33
    +    stub_bytestream = bytestream_pb2_grpc.ByteStreamStub(context.cas_channel)
    
    34 34
     
    
    35 35
         action_digest = remote_execution_pb2.Digest()
    
    36 36
         lease.payload.Unpack(action_digest)
    
    ... ... @@ -78,7 +78,7 @@ def work_temp_directory(context, lease):
    78 78
             request = remote_execution_pb2.BatchUpdateBlobsRequest(instance_name=parent,
    
    79 79
                                                                    requests=requests)
    
    80 80
     
    
    81
    -        stub_cas = remote_execution_pb2_grpc.ContentAddressableStorageStub(context.channel)
    
    81
    +        stub_cas = remote_execution_pb2_grpc.ContentAddressableStorageStub(context.cas_channel)
    
    82 82
             stub_cas.BatchUpdateBlobs(request)
    
    83 83
     
    
    84 84
             result_any = any_pb2.Any()
    

  • buildgrid/_app/commands/cmd_bot.py
    ... ... @@ -44,13 +44,24 @@ from ..cli import pass_context
    44 44
                   help="Public client certificate for TLS (PEM-encoded)")
    
    45 45
     @click.option('--server-cert', type=click.Path(exists=True, dir_okay=False), default=None,
    
    46 46
                   help="Public server certificate for TLS (PEM-encoded)")
    
    47
    +@click.option('--cas-remote', type=click.STRING, default=None, show_default=True,
    
    48
    +              help="Remote CAS server's URL (port defaults to 11001 if not specified).")
    
    49
    +@click.option('--cas-client-key', type=click.Path(exists=True, dir_okay=False), default=None,
    
    50
    +              help="Private CAS client key for TLS (PEM-encoded)")
    
    51
    +@click.option('--cas-client-cert', type=click.Path(exists=True, dir_okay=False), default=None,
    
    52
    +              help="Public CAS client certificate for TLS (PEM-encoded)")
    
    53
    +@click.option('--cas-server-cert', type=click.Path(exists=True, dir_okay=False), default=None,
    
    54
    +              help="Public CAS server certificate for TLS (PEM-encoded)")
    
    47 55
     @click.option('--parent', type=click.STRING, default='main', show_default=True,
    
    48 56
                   help="Targeted farm resource.")
    
    49 57
     @pass_context
    
    50
    -def cli(context, remote, parent, client_key, client_cert, server_cert):
    
    58
    +def cli(context, parent, remote, client_key, client_cert, server_cert,
    
    59
    +        cas_remote, cas_client_key, cas_client_cert, cas_server_cert):
    
    60
    +    # Setup the remote execution server channel:
    
    51 61
         url = urlparse(remote)
    
    52 62
     
    
    53 63
         context.remote = '{}:{}'.format(url.hostname, url.port or 50051)
    
    64
    +    context.remote_url = remote
    
    54 65
         context.parent = parent
    
    55 66
     
    
    56 67
         if url.scheme == 'http':
    
    ... ... @@ -58,12 +69,46 @@ def cli(context, remote, parent, client_key, client_cert, server_cert):
    58 69
         else:
    
    59 70
             credentials = context.load_client_credentials(client_key, client_cert, server_cert)
    
    60 71
             if not credentials:
    
    61
    -            click.echo("ERROR: no TLS keys were specified and no defaults could be found.\n" +
    
    62
    -                       "Use --allow-insecure in order to deactivate TLS encryption.\n", err=True)
    
    72
    +            click.echo("ERROR: no TLS keys were specified and no defaults could be found.", err=True)
    
    63 73
                 sys.exit(-1)
    
    64 74
     
    
    65 75
             context.channel = grpc.secure_channel(context.remote, credentials)
    
    66 76
     
    
    77
    +    context.client_key = client_key
    
    78
    +    context.client_cert = client_cert
    
    79
    +    context.server_cert = server_cert
    
    80
    +
    
    81
    +    # Setup the remote CAS server channel, if separated:
    
    82
    +    if cas_remote is not None and cas_remote != remote:
    
    83
    +        cas_url = urlparse(cas_remote)
    
    84
    +
    
    85
    +        context.cas_remote = '{}:{}'.format(cas_url.hostname, cas_url.port or 11001)
    
    86
    +        context.cas_remote_url = cas_remote
    
    87
    +
    
    88
    +        if cas_url.scheme == 'http':
    
    89
    +            context.cas_channel = grpc.insecure_channel(context.cas_remote)
    
    90
    +        else:
    
    91
    +            cas_credentials = context.load_client_credentials(cas_client_key, cas_client_cert, cas_server_cert)
    
    92
    +            if not cas_credentials:
    
    93
    +                click.echo("ERROR: no TLS keys were specified and no defaults could be found.", err=True)
    
    94
    +                sys.exit(-1)
    
    95
    +
    
    96
    +            context.cas_channel = grpc.secure_channel(context.cas_remote, cas_credentials)
    
    97
    +
    
    98
    +            context.cas_client_key = cas_client_key
    
    99
    +            context.cas_client_cert = cas_client_cert
    
    100
    +            context.cas_server_cert = cas_server_cert
    
    101
    +
    
    102
    +    else:
    
    103
    +        context.cas_remote = context.remote
    
    104
    +        context.cas_remote_url = remote
    
    105
    +
    
    106
    +        context.cas_channel = context.channel
    
    107
    +
    
    108
    +        context.cas_client_key = client_key
    
    109
    +        context.cas_client_cert = client_cert
    
    110
    +        context.cas_server_cert = server_cert
    
    111
    +
    
    67 112
         context.logger = logging.getLogger(__name__)
    
    68 113
         context.logger.debug("Starting for remote {}".format(context.remote))
    
    69 114
     
    
    ... ... @@ -112,35 +157,17 @@ def run_temp_directory(context):
    112 157
                   help="Main mount-point location.")
    
    113 158
     @click.option('--local-cas', type=click.Path(readable=False), default=str(PurePath(Path.home(), 'cas')),
    
    114 159
                   help="Local CAS cache directory.")
    
    115
    -@click.option('--client-cert', type=click.Path(readable=False), default=str(PurePath(Path.home(), 'client.crt')),
    
    116
    -              help="Public client certificate for TLS (PEM-encoded).")
    
    117
    -@click.option('--client-key', type=click.Path(readable=False), default=str(PurePath(Path.home(), 'client.key')),
    
    118
    -              help="Private client key for TLS (PEM-encoded).")
    
    119
    -@click.option('--server-cert', type=click.Path(readable=False), default=str(PurePath(Path.home(), 'server.crt')),
    
    120
    -              help="Public server certificate for TLS (PEM-encoded).")
    
    121
    -@click.option('--port', type=click.INT, default=11001, show_default=True,
    
    122
    -              help="Remote CAS server port.")
    
    123
    -@click.option('--remote', type=click.STRING, default='localhost', show_default=True,
    
    124
    -              help="Remote CAS server hostname.")
    
    125 160
     @pass_context
    
    126
    -def run_buildbox(context, remote, port, server_cert, client_key, client_cert, local_cas, fuse_dir):
    
    161
    +def run_buildbox(context, local_cas, fuse_dir):
    
    127 162
         """
    
    128 163
         Uses BuildBox to run commands.
    
    129 164
         """
    
    130
    -
    
    131
    -    context.logger.info("Creating a bot session")
    
    132
    -
    
    133
    -    context.remote = remote
    
    134
    -    context.port = port
    
    135
    -    context.server_cert = server_cert
    
    136
    -    context.client_key = client_key
    
    137
    -    context.client_cert = client_cert
    
    138 165
         context.local_cas = local_cas
    
    139 166
         context.fuse_dir = fuse_dir
    
    140 167
     
    
    141 168
         try:
    
    142 169
             b = bot.Bot(context.bot_session)
    
    143
    -        b.session(work=buildbox.work_buildbox,
    
    144
    -                  context=context)
    
    170
    +        b.session(buildbox.work_buildbox,
    
    171
    +                  context)
    
    145 172
         except KeyboardInterrupt:
    
    146 173
             pass



  • [Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]