|
1
|
+# Copyright (C) 2018 Bloomberg LP
|
|
2
|
+#
|
|
3
|
+# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+# you may not use this file except in compliance with the License.
|
|
5
|
+# You may obtain a copy of the License at
|
|
6
|
+#
|
|
7
|
+# <http://www.apache.org/licenses/LICENSE-2.0>
|
|
8
|
+#
|
|
9
|
+# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+# See the License for the specific language governing permissions and
|
|
13
|
+# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+"""
|
|
17
|
+Operations command
|
|
18
|
+=================
|
|
19
|
+
|
|
20
|
+Check the status of operations
|
|
21
|
+"""
|
|
22
|
+
|
|
23
|
+import logging
|
|
24
|
+from urllib.parse import urlparse
|
|
25
|
+import sys
|
|
26
|
+
|
|
27
|
+import click
|
|
28
|
+import grpc
|
|
29
|
+
|
|
30
|
+from buildgrid._protos.google.longrunning import operations_pb2, operations_pb2_grpc
|
|
31
|
+
|
|
32
|
+from ..cli import pass_context
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+@click.group(name='operation', short_help="Long running operations commands")
|
|
36
|
+@click.option('--remote', type=click.STRING, default='http://localhost:50051', show_default=True,
|
|
37
|
+ help="Remote execution server's URL (port defaults to 50051 if no specified).")
|
|
38
|
+@click.option('--client-key', type=click.Path(exists=True, dir_okay=False), default=None,
|
|
39
|
+ help="Private client key for TLS (PEM-encoded)")
|
|
40
|
+@click.option('--client-cert', type=click.Path(exists=True, dir_okay=False), default=None,
|
|
41
|
+ help="Public client certificate for TLS (PEM-encoded)")
|
|
42
|
+@click.option('--server-cert', type=click.Path(exists=True, dir_okay=False), default=None,
|
|
43
|
+ help="Public server certificate for TLS (PEM-encoded)")
|
|
44
|
+@click.option('--instance-name', type=click.STRING, default='main', show_default=True,
|
|
45
|
+ help="Targeted farm instance name.")
|
|
46
|
+@pass_context
|
|
47
|
+def cli(context, remote, instance_name, client_key, client_cert, server_cert):
|
|
48
|
+ url = urlparse(remote)
|
|
49
|
+
|
|
50
|
+ context.remote = '{}:{}'.format(url.hostname, url.port or 50051)
|
|
51
|
+ context.instance_name = instance_name
|
|
52
|
+
|
|
53
|
+ if url.scheme == 'http':
|
|
54
|
+ context.channel = grpc.insecure_channel(context.remote)
|
|
55
|
+ else:
|
|
56
|
+ credentials = context.load_client_credentials(client_key, client_cert, server_cert)
|
|
57
|
+ if not credentials:
|
|
58
|
+ click.echo("ERROR: no TLS keys were specified and no defaults could be found.\n" +
|
|
59
|
+ "Use `insecure-mode: false` in order to deactivate TLS encryption.\n", err=True)
|
|
60
|
+ sys.exit(-1)
|
|
61
|
+
|
|
62
|
+ context.channel = grpc.secure_channel(context.remote, credentials)
|
|
63
|
+
|
|
64
|
+ context.logger = logging.getLogger(__name__)
|
|
65
|
+ context.logger.debug("Starting for remote {}".format(context.remote))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+@cli.command('status', short_help="Get the status of an operation.")
|
|
69
|
+@click.argument('operation-name', nargs=1, type=click.STRING, required=True)
|
|
70
|
+@pass_context
|
|
71
|
+def status(context, operation_name):
|
|
72
|
+ context.logger.info("Getting operation status...")
|
|
73
|
+ stub = operations_pb2_grpc.OperationsStub(context.channel)
|
|
74
|
+
|
|
75
|
+ request = operations_pb2.GetOperationRequest(name=operation_name)
|
|
76
|
+
|
|
77
|
+ response = stub.GetOperation(request)
|
|
78
|
+ context.logger.info(response)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+@cli.command('list', short_help="List operations.")
|
|
82
|
+@pass_context
|
|
83
|
+def lists(context):
|
|
84
|
+ context.logger.info("Getting list of operations")
|
|
85
|
+ stub = operations_pb2_grpc.OperationsStub(context.channel)
|
|
86
|
+
|
|
87
|
+ request = operations_pb2.ListOperationsRequest(name=context.instance_name)
|
|
88
|
+
|
|
89
|
+ response = stub.ListOperations(request)
|
|
90
|
+
|
|
91
|
+ if not response.operations:
|
|
92
|
+ context.logger.warning("No operations to list")
|
|
93
|
+ return
|
|
94
|
+
|
|
95
|
+ for op in response.operations:
|
|
96
|
+ context.logger.info(op)
|