[Notes] [Git][BuildGrid/buildgrid][master] cmd_bot.py: Allow separate CAS server for any bot



Title: GitLab

Martin Blanchard pushed to branch master at BuildGrid / buildgrid

Commits:

4 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.remote_cas_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/cli.py
    ... ... @@ -83,14 +83,22 @@ class Context:
    83 83
                 client_key_pem = read_file(client_key)
    
    84 84
             else:
    
    85 85
                 client_key_pem = None
    
    86
    +            client_key = None
    
    86 87
             if client_key_pem and client_cert and os.path.exists(client_cert):
    
    87 88
                 client_cert_pem = read_file(client_cert)
    
    88 89
             else:
    
    89 90
                 client_cert_pem = None
    
    91
    +            client_cert = None
    
    90 92
     
    
    91
    -        return grpc.ssl_channel_credentials(root_certificates=server_cert_pem,
    
    92
    -                                            private_key=client_key_pem,
    
    93
    -                                            certificate_chain=client_cert_pem)
    
    93
    +        credentials = grpc.ssl_channel_credentials(root_certificates=server_cert_pem,
    
    94
    +                                                   private_key=client_key_pem,
    
    95
    +                                                   certificate_chain=client_cert_pem)
    
    96
    +
    
    97
    +        credentials.client_key = client_key
    
    98
    +        credentials.client_cert = client_cert
    
    99
    +        credentials.server_cert = server_cert
    
    100
    +
    
    101
    +        return credentials
    
    94 102
     
    
    95 103
         def load_server_credentials(self, server_key=None, server_cert=None,
    
    96 104
                                     client_certs=None, use_default_client_certs=False):
    
    ... ... @@ -132,10 +140,17 @@ class Context:
    132 140
                 client_certs_pem = read_file(client_certs)
    
    133 141
             else:
    
    134 142
                 client_certs_pem = None
    
    143
    +            client_certs = None
    
    144
    +
    
    145
    +        credentials = grpc.ssl_server_credentials([(server_key_pem, server_cert_pem)],
    
    146
    +                                                  root_certificates=client_certs_pem,
    
    147
    +                                                  require_client_auth=bool(client_certs))
    
    148
    +
    
    149
    +        credentials.server_key = server_key
    
    150
    +        credentials.server_cert = server_cert
    
    151
    +        credentials.client_certs = client_certs
    
    135 152
     
    
    136
    -        return grpc.ssl_server_credentials([(server_key_pem, server_cert_pem)],
    
    137
    -                                           root_certificates=client_certs_pem,
    
    138
    -                                           require_client_auth=bool(client_certs))
    
    153
    +        return credentials
    
    139 154
     
    
    140 155
     
    
    141 156
     pass_context = click.make_pass_decorator(Context, ensure=True)
    

  • buildgrid/_app/commands/cmd_bot.py
    ... ... @@ -44,26 +44,79 @@ 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('--remote-cas', 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
    +        remote_cas, 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':
    
    57 68
             context.channel = grpc.insecure_channel(context.remote)
    
    69
    +
    
    70
    +        context.client_key = None
    
    71
    +        context.client_cert = None
    
    72
    +        context.server_cert = None
    
    58 73
         else:
    
    59 74
             credentials = context.load_client_credentials(client_key, client_cert, server_cert)
    
    60 75
             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)
    
    76
    +            click.echo("ERROR: no TLS keys were specified and no defaults could be found.", err=True)
    
    63 77
                 sys.exit(-1)
    
    64 78
     
    
    65 79
             context.channel = grpc.secure_channel(context.remote, credentials)
    
    66 80
     
    
    81
    +        context.client_key = credentials.client_key
    
    82
    +        context.client_cert = credentials.client_cert
    
    83
    +        context.server_cert = credentials.server_cert
    
    84
    +
    
    85
    +    # Setup the remote CAS server channel, if separated:
    
    86
    +    if remote_cas is not None and remote_cas != remote:
    
    87
    +        cas_url = urlparse(remote_cas)
    
    88
    +
    
    89
    +        context.remote_cas = '{}:{}'.format(cas_url.hostname, cas_url.port or 11001)
    
    90
    +        context.remote_cas_url = remote_cas
    
    91
    +
    
    92
    +        if cas_url.scheme == 'http':
    
    93
    +            context.cas_channel = grpc.insecure_channel(context.remote_cas)
    
    94
    +
    
    95
    +            context.cas_client_key = None
    
    96
    +            context.cas_client_cert = None
    
    97
    +            context.cas_server_cert = None
    
    98
    +        else:
    
    99
    +            cas_credentials = context.load_client_credentials(cas_client_key, cas_client_cert, cas_server_cert)
    
    100
    +            if not cas_credentials:
    
    101
    +                click.echo("ERROR: no TLS keys were specified and no defaults could be found.", err=True)
    
    102
    +                sys.exit(-1)
    
    103
    +
    
    104
    +            context.cas_channel = grpc.secure_channel(context.remote_cas, cas_credentials)
    
    105
    +
    
    106
    +            context.cas_client_key = cas_credentials.client_key
    
    107
    +            context.cas_client_cert = cas_credentials.client_cert
    
    108
    +            context.cas_server_cert = cas_credentials.server_cert
    
    109
    +
    
    110
    +    else:
    
    111
    +        context.remote_cas = context.remote
    
    112
    +        context.remote_cas_url = remote
    
    113
    +
    
    114
    +        context.cas_channel = context.channel
    
    115
    +
    
    116
    +        context.cas_client_key = context.client_key
    
    117
    +        context.cas_client_cert = context.client_cert
    
    118
    +        context.cas_server_cert = context.server_cert
    
    119
    +
    
    67 120
         context.logger = logging.getLogger(__name__)
    
    68 121
         context.logger.debug("Starting for remote {}".format(context.remote))
    
    69 122
     
    
    ... ... @@ -112,35 +165,17 @@ def run_temp_directory(context):
    112 165
                   help="Main mount-point location.")
    
    113 166
     @click.option('--local-cas', type=click.Path(readable=False), default=str(PurePath(Path.home(), 'cas')),
    
    114 167
                   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 168
     @pass_context
    
    126
    -def run_buildbox(context, remote, port, server_cert, client_key, client_cert, local_cas, fuse_dir):
    
    169
    +def run_buildbox(context, local_cas, fuse_dir):
    
    127 170
         """
    
    128 171
         Uses BuildBox to run commands.
    
    129 172
         """
    
    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 173
         context.local_cas = local_cas
    
    139 174
         context.fuse_dir = fuse_dir
    
    140 175
     
    
    141 176
         try:
    
    142 177
             b = bot.Bot(context.bot_session)
    
    143
    -        b.session(work=buildbox.work_buildbox,
    
    144
    -                  context=context)
    
    178
    +        b.session(buildbox.work_buildbox,
    
    179
    +                  context)
    
    145 180
         except KeyboardInterrupt:
    
    146 181
             pass



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